Subversion Repositories Kolibri OS

Rev

Rev 4423 | Rev 5565 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3908 Serge 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
593 mikedld 8
$Revision: 5201 $
9
 
10
 
472 serge 11
; Low-level driver for HDD access
346 diamond 12
; DMA support by Mario79
3725 Serge 13
; LBA48 support by Mario79
14
;-----------------------------------------------------------------------------
3908 Serge 15
struct HD_DATA
16
hdbase  dd      ?
17
hdid    dd      ?
18
hdpos   dd      ?
19
ends
5201 serge 20
;-----------------------------------------------------------------------------
3908 Serge 21
iglobal
160 diamond 22
align 4
3908 Serge 23
ide_callbacks:
24
        dd      ide_callbacks.end - ide_callbacks       ; strucsize
25
        dd      0       ; no close function
26
        dd      0       ; no closemedia function
27
        dd      ide_querymedia
28
        dd      ide_read
29
        dd      ide_write
30
        dd      0       ; no flush function
31
        dd      0       ; use default cache size
32
.end:
160 diamond 33
 
3908 Serge 34
hd0_data        HD_DATA         ?,    0, 1
35
hd1_data        HD_DATA         ?, 0x10, 2
36
hd2_data        HD_DATA         ?,    0, 3
37
hd3_data        HD_DATA         ?, 0x10, 4
5201 serge 38
hd4_data        HD_DATA         ?,    0, 5
39
hd5_data        HD_DATA         ?, 0x10, 6
40
hd6_data        HD_DATA         ?,    0, 7
41
hd7_data        HD_DATA         ?, 0x10, 8
42
hd8_data        HD_DATA         ?,    0, 9
43
hd9_data        HD_DATA         ?, 0x10, 10
44
hd10_data       HD_DATA         ?,    0, 11
45
hd11_data       HD_DATA         ?, 0x10, 12
4287 Serge 46
 
5201 serge 47
ide_mutex_table:
48
        dd ide_channel1_mutex
49
        dd ide_channel2_mutex
50
        dd ide_channel3_mutex
51
        dd ide_channel4_mutex
52
        dd ide_channel5_mutex
53
        dd ide_channel6_mutex
3908 Serge 54
endg
5201 serge 55
;-----------------------------------------------------------------------------
3908 Serge 56
uglobal
57
ide_mutex               MUTEX
58
ide_channel1_mutex      MUTEX
59
ide_channel2_mutex      MUTEX
5201 serge 60
ide_channel3_mutex      MUTEX
61
ide_channel4_mutex      MUTEX
62
ide_channel5_mutex      MUTEX
63
ide_channel6_mutex      MUTEX
3908 Serge 64
endg
5201 serge 65
;-----------------------------------------------------------------------------
3908 Serge 66
proc ide_read stdcall uses edi, \
67
        hd_data, buffer, startsector:qword, numsectors
68
        ; hd_data = pointer to hd*_data
69
        ; buffer = pointer to buffer for data
70
        ; startsector = 64-bit start sector
71
        ; numsectors = pointer to number of sectors on input,
72
        ;  must be filled with number of sectors really read
73
locals
74
sectors_todo    dd      ?
75
channel_lock    dd      ?
76
endl
77
; 1. Initialize number of sectors: get number of requested sectors
78
; and say that no sectors were read yet.
79
        mov     ecx, [numsectors]
80
        mov     eax, [ecx]
81
        mov     dword [ecx], 0
82
        mov     [sectors_todo], eax
83
; 2. Acquire the global lock.
84
        mov     ecx, ide_mutex
85
        call    mutex_lock
5201 serge 86
 
87
        mov     ecx, [hd_data]
88
        mov     ecx, [ecx+HD_DATA.hdpos]
89
        dec     ecx
90
        shr     ecx, 1
91
        shl     ecx, 2
92
        mov     ecx, [ecx + ide_mutex_table]
3908 Serge 93
        mov     [channel_lock], ecx
94
        call    mutex_lock
95
; 3. Convert parameters to the form suitable for worker procedures.
96
; Underlying procedures do not know about 64-bit sectors.
97
; Worker procedures use global variables and edi for [buffer].
98
        cmp     dword [startsector+4], 0
99
        jnz     .fail
5201 serge 100
 
3908 Serge 101
        and     [hd_error], 0
102
        mov     ecx, [hd_data]
103
        mov     eax, [ecx+HD_DATA.hdbase]
104
        mov     [hdbase], eax
105
        mov     eax, [ecx+HD_DATA.hdid]
106
        mov     [hdid], eax
107
        mov     eax, [ecx+HD_DATA.hdpos]
108
        mov     [hdpos], eax
109
        mov     eax, dword [startsector]
110
        mov     edi, [buffer]
111
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
112
.sectors_loop:
514 diamond 113
; DMA read is permitted if [allow_dma_access]=1 or 2
114
        cmp     [allow_dma_access], 2
115
        ja      .nodma
4423 Serge 116
 
5201 serge 117
        push    eax ecx
118
        mov     ecx, [hdpos]
119
        dec     ecx
120
        shr     ecx, 2
121
        imul    ecx, sizeof.IDE_DATA
122
        add     ecx, IDE_controller_1
123
        mov     [IDE_controller_pointer], ecx
124
 
125
        mov     eax, [hdpos]
126
        dec     eax
127
        and     eax, 11b
128
        shr     eax, 1
129
        add     eax, ecx
130
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
131
        pop     ecx eax
4423 Serge 132
        jnz     .nodma
133
 
160 diamond 134
        call    hd_read_dma
135
        jmp     @f
5201 serge 136
;--------------------------------------
160 diamond 137
.nodma:
138
        call    hd_read_pio
5201 serge 139
;--------------------------------------
160 diamond 140
@@:
725 diamond 141
        cmp     [hd_error], 0
3908 Serge 142
        jnz     .fail
5201 serge 143
 
3908 Serge 144
        mov     ecx, [numsectors]
145
        inc     dword [ecx]     ; one more sector is read
146
        dec     [sectors_todo]
147
        jz      .done
5201 serge 148
 
3908 Serge 149
        inc     eax
150
        jnz     .sectors_loop
5201 serge 151
;--------------------------------------
3908 Serge 152
; 5. Loop is done, either due to error or because everything is done.
153
; Release the global lock and return the corresponding status.
154
.fail:
155
        mov     ecx, [channel_lock]
156
        call    mutex_unlock
5201 serge 157
 
3908 Serge 158
        mov     ecx, ide_mutex
159
        call    mutex_unlock
5201 serge 160
 
3908 Serge 161
        or      eax, -1
162
        ret
5201 serge 163
;--------------------------------------
3908 Serge 164
.done:
165
        mov     ecx, [channel_lock]
166
        call    mutex_unlock
5201 serge 167
 
3908 Serge 168
        mov     ecx, ide_mutex
169
        call    mutex_unlock
5201 serge 170
 
3908 Serge 171
        xor     eax, eax
172
        ret
173
endp
5201 serge 174
;-----------------------------------------------------------------------------
3908 Serge 175
proc ide_write stdcall uses esi edi, \
176
        hd_data, buffer, startsector:qword, numsectors
177
        ; hd_data = pointer to hd*_data
178
        ; buffer = pointer to buffer with data
179
        ; startsector = 64-bit start sector
180
        ; numsectors = pointer to number of sectors on input,
181
        ;  must be filled with number of sectors really written
182
locals
183
sectors_todo    dd      ?
184
channel_lock    dd      ?
185
endl
186
; 1. Initialize number of sectors: get number of requested sectors
187
; and say that no sectors were read yet.
188
        mov     ecx, [numsectors]
189
        mov     eax, [ecx]
190
        mov     dword [ecx], 0
191
        mov     [sectors_todo], eax
192
; 2. Acquire the global lock.
193
        mov     ecx, ide_mutex
194
        call    mutex_lock
5201 serge 195
 
196
        mov     ecx, [hd_data]
197
        mov     ecx, [ecx+HD_DATA.hdpos]
198
        dec     ecx
199
        shr     ecx, 1
200
        shl     ecx, 2
201
        mov     ecx, [ecx + ide_mutex_table]
3908 Serge 202
        mov     [channel_lock], ecx
203
        call    mutex_lock
204
; 3. Convert parameters to the form suitable for worker procedures.
205
; Underlying procedures do not know about 64-bit sectors.
206
; Worker procedures use global variables and esi for [buffer].
207
        cmp     dword [startsector+4], 0
208
        jnz     .fail
5201 serge 209
 
3908 Serge 210
        and     [hd_error], 0
211
        mov     ecx, [hd_data]
212
        mov     eax, [ecx+HD_DATA.hdbase]
213
        mov     [hdbase], eax
214
        mov     eax, [ecx+HD_DATA.hdid]
215
        mov     [hdid], eax
216
        mov     eax, [ecx+HD_DATA.hdpos]
217
        mov     [hdpos], eax
218
        mov     esi, [buffer]
219
        lea     edi, [startsector]
220
        mov     [cache_chain_ptr], edi
221
; 4. Worker procedures take max 16 sectors per time,
222
; loop until all sectors will be processed.
223
.sectors_loop:
224
        mov     ecx, 16
225
        cmp     ecx, [sectors_todo]
226
        jbe     @f
5201 serge 227
 
3908 Serge 228
        mov     ecx, [sectors_todo]
5201 serge 229
;--------------------------------------
3908 Serge 230
@@:
231
        mov     [cache_chain_size], cl
232
; DMA write is permitted only if [allow_dma_access]=1
233
        cmp     [allow_dma_access], 2
234
        jae     .nodma
4423 Serge 235
 
5201 serge 236
        push    eax ecx
237
        mov     ecx, [hdpos]
238
        dec     ecx
239
        shr     ecx, 2
240
        imul    ecx, sizeof.IDE_DATA
241
        add     ecx, IDE_controller_1
242
        mov     [IDE_controller_pointer], ecx
243
 
244
        mov     eax, [hdpos]
245
        dec     eax
246
        and     eax, 11b
247
        shr     eax, 1
248
        add     eax, ecx
249
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
250
        pop     ecx eax
4423 Serge 251
        jnz     .nodma
252
 
3908 Serge 253
        call    cache_write_dma
254
        jmp     .common
5201 serge 255
;--------------------------------------
3908 Serge 256
.nodma:
257
        mov     [cache_chain_size], 1
258
        call    cache_write_pio
5201 serge 259
;--------------------------------------
3908 Serge 260
.common:
261
        cmp     [hd_error], 0
262
        jnz     .fail
5201 serge 263
 
3908 Serge 264
        movzx   ecx, [cache_chain_size]
265
        mov     eax, [numsectors]
266
        add     [eax], ecx
267
        sub     [sectors_todo], ecx
268
        jz      .done
5201 serge 269
 
3908 Serge 270
        add     [edi], ecx
271
        jc      .fail
5201 serge 272
 
3908 Serge 273
        shl     ecx, 9
274
        add     esi, ecx
275
        jmp     .sectors_loop
5201 serge 276
;--------------------------------------
3908 Serge 277
; 5. Loop is done, either due to error or because everything is done.
278
; Release the global lock and return the corresponding status.
279
.fail:
280
        mov     ecx, [channel_lock]
281
        call    mutex_unlock
5201 serge 282
 
3908 Serge 283
        mov     ecx, ide_mutex
284
        call    mutex_unlock
5201 serge 285
 
3908 Serge 286
        or      eax, -1
287
        ret
5201 serge 288
;--------------------------------------
3908 Serge 289
.done:
290
        mov     ecx, [channel_lock]
291
        call    mutex_unlock
5201 serge 292
 
3908 Serge 293
        mov     ecx, ide_mutex
294
        call    mutex_unlock
5201 serge 295
 
3908 Serge 296
        xor     eax, eax
297
        ret
298
endp
5201 serge 299
;-----------------------------------------------------------------------------
3908 Serge 300
; This is a stub.
301
proc ide_querymedia stdcall, hd_data, mediainfo
302
        mov     eax, [mediainfo]
303
        mov     [eax+DISKMEDIAINFO.Flags], 0
304
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
305
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
306
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
307
        xor     eax, eax
308
        ret
309
endp
3725 Serge 310
;-----------------------------------------------------------------------------
160 diamond 311
align 4
3908 Serge 312
; input: eax = sector, edi -> buffer
313
; output: edi = edi + 512
160 diamond 314
hd_read_pio:
3555 Serge 315
        push    eax edx
3725 Serge 316
; Select the desired drive
317
        mov     edx, [hdbase]
318
        add     edx, 6   ;адрес регистра головок
319
        mov     al, byte [hdid]
320
        add     al, 128+64+32
321
        out     dx, al; номер головки/номер диска
322
 
3555 Serge 323
        call    wait_for_hd_idle
5201 serge 324
 
2434 Serge 325
        cmp     [hd_error], 0
3555 Serge 326
        jne     hd_read_error
3725 Serge 327
; ATA with 28 or 48 bit for sector number?
328
        mov     eax, [esp+4]
329
        cmp     eax, 0x10000000
330
        jae     .lba48
331
;--------------------------------------
332
.lba28:
333
        pushfd
3555 Serge 334
        cli
2434 Serge 335
        xor     eax, eax
336
        mov     edx, [hdbase]
3555 Serge 337
        inc     edx
3725 Serge 338
        out     dx, al ; ATA Features регистр "особенностей"
3555 Serge 339
        inc     edx
340
        inc     eax
3725 Serge 341
        out     dx, al ; ATA Sector Counter счётчик секторов
3555 Serge 342
        inc     edx
3725 Serge 343
        mov     eax, [esp+4+4]
344
        out     dx, al ; LBA Low LBA (7:0)
2434 Serge 345
        shr     eax, 8
3555 Serge 346
        inc     edx
3725 Serge 347
        out     dx, al ; LBA Mid LBA (15:8)
2434 Serge 348
        shr     eax, 8
3555 Serge 349
        inc     edx
3725 Serge 350
        out     dx, al ; LBA High LBA (23:16)
2434 Serge 351
        shr     eax, 8
3555 Serge 352
        inc     edx
3725 Serge 353
        and     al, 1+2+4+8 ; LBA (27:24)
2434 Serge 354
        add     al, byte [hdid]
355
        add     al, 128+64+32
3725 Serge 356
        out     dx, al ; номер головки/номер диска
3555 Serge 357
        inc     edx
3725 Serge 358
        mov     al, 20h ; READ SECTOR(S)
359
        out     dx, al ; ATACommand регистр команд
360
        popfd
361
        jmp     .continue
362
;--------------------------------------
363
.lba48:
364
        pushfd
365
        cli
366
        xor     eax, eax
367
        mov     edx, [hdbase]
368
        inc     edx
369
        out     dx, al ; Features Previous Reserved
370
        out     dx, al ; Features Current Reserved
371
        inc     edx
372
        out     dx, al ; Sector Count Previous Sector count (15:8)
373
        inc     eax
374
        out     dx, al ; Sector Count Current Sector count (7:0)
375
        inc     edx
376
        mov     eax, [esp+4+4]
377
        rol     eax, 8
378
        out     dx, al ; LBA Low Previous LBA (31:24)
379
        xor     eax, eax ; because only 32 bit cache
380
        inc     edx
381
        out     dx, al ; LBA Mid Previous LBA (39:32)
382
        inc     edx
383
        out     dx, al ; LBA High Previous LBA (47:40)
384
        sub     edx, 2
385
        mov     eax, [esp+4+4]
386
        out     dx, al ; LBA Low Current LBA (7:0)
387
        shr     eax, 8
388
        inc     edx
389
        out     dx, al ; LBA Mid Current LBA (15:8)
390
        shr     eax, 8
391
        inc     edx
392
        out     dx, al ; LBA High Current LBA (23:16)
393
        inc     edx
394
        mov     al, byte [hdid]
395
        add     al, 128+64+32
396
        out     dx, al ; номер головки/номер диска
397
        inc     edx
398
        mov     al, 24h ; READ SECTOR(S) EXT
399
        out     dx, al ; ATACommand регистр команд
400
        popfd
401
;--------------------------------------
402
.continue:
3555 Serge 403
        call    wait_for_sector_buffer
160 diamond 404
 
2434 Serge 405
        cmp     [hd_error], 0
3555 Serge 406
        jne     hd_read_error
160 diamond 407
 
3725 Serge 408
        pushfd
3555 Serge 409
        cli
2434 Serge 410
        mov     ecx, 256
411
        mov     edx, [hdbase]
3555 Serge 412
        cld
413
        rep insw
3725 Serge 414
        popfd
160 diamond 415
 
3555 Serge 416
        pop     edx eax
417
        ret
3725 Serge 418
;-----------------------------------------------------------------------------
160 diamond 419
align 4
3908 Serge 420
; edi -> sector, esi -> data
160 diamond 421
cache_write_pio:
3725 Serge 422
; Select the desired drive
423
        mov     edx, [hdbase]
424
        add     edx, 6   ;адрес регистра головок
425
        mov     al, byte [hdid]
426
        add     al, 128+64+32
427
        out     dx, al ; номер головки/номер диска
581 serge 428
 
3555 Serge 429
        call    wait_for_hd_idle
5201 serge 430
 
2434 Serge 431
        cmp     [hd_error], 0
3555 Serge 432
        jne     hd_write_error
160 diamond 433
 
3725 Serge 434
; ATA with 28 or 48 bit for sector number?
3908 Serge 435
        mov     eax, [edi]
3725 Serge 436
        cmp     eax, 0x10000000
437
        jae     .lba48
438
;--------------------------------------
439
.lba28:
440
        pushfd
3555 Serge 441
        cli
2434 Serge 442
        xor     eax, eax
443
        mov     edx, [hdbase]
3555 Serge 444
        inc     edx
3725 Serge 445
        out     dx, al ; ATA Features регистр "особенностей"
3555 Serge 446
        inc     edx
447
        inc     eax
3725 Serge 448
        out     dx, al ; ATA Sector Counter счётчик секторов
3555 Serge 449
        inc     edx
3908 Serge 450
        mov     eax, [edi]      ; eax = sector to write
3725 Serge 451
        out     dx, al ; LBA Low LBA (7:0)
2434 Serge 452
        shr     eax, 8
3555 Serge 453
        inc     edx
3725 Serge 454
        out     dx, al ; LBA Mid LBA (15:8)
2434 Serge 455
        shr     eax, 8
3555 Serge 456
        inc     edx
3725 Serge 457
        out     dx, al ; LBA High LBA (23:16)
2434 Serge 458
        shr     eax, 8
3555 Serge 459
        inc     edx
3725 Serge 460
        and     al, 1+2+4+8 ; LBA (27:24)
2434 Serge 461
        add     al, byte [hdid]
462
        add     al, 128+64+32
3725 Serge 463
        out     dx, al ; номер головки/номер диска
3555 Serge 464
        inc     edx
3725 Serge 465
        mov     al, 30h ; WRITE SECTOR(S)
466
        out     dx, al ; ATACommand регистр команд
467
        jmp     .continue
468
;--------------------------------------
469
.lba48:
470
        pushfd
471
        cli
472
        xor     eax, eax
473
        mov     edx, [hdbase]
474
        inc     edx
475
        out     dx, al ; Features Previous Reserved
476
        out     dx, al ; Features Current Reserved
477
        inc     edx
478
        out     dx, al ; Sector Count Previous Sector count (15:8)
479
        inc     eax
480
        out     dx, al ; Sector Count Current Sector count (7:0)
481
        inc     edx
3908 Serge 482
        mov     eax, [edi]
3725 Serge 483
        rol     eax, 8
484
        out     dx, al ; LBA Low Previous LBA (31:24)
485
        xor     eax, eax ; because only 32 bit cache
486
        inc     edx
487
        out     dx, al ; LBA Mid Previous LBA (39:32)
488
        inc     edx
489
        out     dx, al ; LBA High Previous LBA (47:40)
490
        sub     edx, 2
3908 Serge 491
        mov     eax, [edi]
3725 Serge 492
        out     dx, al ; LBA Low Current LBA (7:0)
493
        shr     eax, 8
494
        inc     edx
495
        out     dx, al ; LBA Mid Current LBA (15:8)
496
        shr     eax, 8
497
        inc     edx
498
        out     dx, al ; LBA High Current LBA (23:16)
499
        inc     edx
500
        mov     al, byte [hdid]
501
        add     al, 128+64+32
502
        out     dx, al ; номер головки/номер диска
503
        inc     edx
504
        mov     al, 34h ; WRITE SECTOR(S) EXT
505
        out     dx, al ; ATACommand регистр команд
506
;--------------------------------------
507
.continue:
3908 Serge 508
        popfd
3555 Serge 509
        call    wait_for_sector_buffer
160 diamond 510
 
2434 Serge 511
        cmp     [hd_error], 0
3555 Serge 512
        jne     hd_write_error
160 diamond 513
 
3555 Serge 514
        push    ecx esi
160 diamond 515
 
3725 Serge 516
        pushfd
3555 Serge 517
        cli
2434 Serge 518
        mov     ecx, 256
519
        mov     edx, [hdbase]
3555 Serge 520
        cld
521
        rep outsw
3725 Serge 522
        popfd
160 diamond 523
 
3555 Serge 524
        pop     esi ecx
525
        ret
3725 Serge 526
;-----------------------------------------------------------------------------
527
align 4
160 diamond 528
save_hd_wait_timeout:
3555 Serge 529
        push    eax
2434 Serge 530
        mov     eax, [timer_ticks]
531
        add     eax, 300        ; 3 sec timeout
532
        mov     [hd_wait_timeout], eax
3555 Serge 533
        pop     eax
534
        ret
3725 Serge 535
;-----------------------------------------------------------------------------
160 diamond 536
align 4
537
check_hd_wait_timeout:
3555 Serge 538
        push    eax
2434 Serge 539
        mov     eax, [hd_wait_timeout]
3555 Serge 540
        cmp     [timer_ticks], eax
541
        jg      hd_timeout_error
3725 Serge 542
 
3555 Serge 543
        pop     eax
2434 Serge 544
        mov     [hd_error], 0
3555 Serge 545
        ret
3725 Serge 546
;-----------------------------------------------------------------------------
160 diamond 547
hd_timeout_error:
3908 Serge 548
        if lang eq sp
549
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
550
        else
551
        DEBUGF 1,"K : FS - HD timeout\n"
552
        end if
2434 Serge 553
        mov     [hd_error], 1
3555 Serge 554
        pop     eax
555
        ret
3725 Serge 556
;-----------------------------------------------------------------------------
160 diamond 557
hd_read_error:
3908 Serge 558
        if lang eq sp
559
        DEBUGF 1,"K : FS - HD error de lectura\n"
560
        else
561
        DEBUGF 1,"K : FS - HD read error\n"
562
        end if
3555 Serge 563
        pop     edx eax
564
        ret
3725 Serge 565
;-----------------------------------------------------------------------------
566
hd_write_error_dma:
567
        pop     esi
160 diamond 568
hd_write_error:
3908 Serge 569
        if lang eq sp
570
        DEBUGF 1,"K : FS - HD error de escritura\n"
571
        else
572
        DEBUGF 1,"K : FS - HD write error\n"
573
        end if
3555 Serge 574
        ret
3725 Serge 575
;-----------------------------------------------------------------------------
160 diamond 576
align 4
577
wait_for_hd_idle:
3555 Serge 578
        push    eax edx
160 diamond 579
 
3555 Serge 580
        call    save_hd_wait_timeout
160 diamond 581
 
2434 Serge 582
        mov     edx, [hdbase]
583
        add     edx, 0x7
3725 Serge 584
;--------------------------------------
585
align 4
586
wfhil1:
3555 Serge 587
        call    check_hd_wait_timeout
5201 serge 588
 
2434 Serge 589
        cmp     [hd_error], 0
3555 Serge 590
        jne     @f
160 diamond 591
 
2434 Serge 592
        in      al, dx
593
        test    al, 128
3555 Serge 594
        jnz     wfhil1
5201 serge 595
;--------------------------------------
3725 Serge 596
@@:
3555 Serge 597
        pop     edx eax
598
        ret
3725 Serge 599
;-----------------------------------------------------------------------------
160 diamond 600
align 4
601
wait_for_sector_buffer:
3555 Serge 602
        push    eax edx
160 diamond 603
 
2434 Serge 604
        mov     edx, [hdbase]
605
        add     edx, 0x7
160 diamond 606
 
3555 Serge 607
        call    save_hd_wait_timeout
3725 Serge 608
;--------------------------------------
609
align 4
610
hdwait_sbuf:                  ; wait for sector buffer to be ready
3555 Serge 611
        call    check_hd_wait_timeout
5201 serge 612
 
2434 Serge 613
        cmp     [hd_error], 0
3555 Serge 614
        jne     @f
160 diamond 615
 
2434 Serge 616
        in      al, dx
617
        test    al, 8
3555 Serge 618
        jz      hdwait_sbuf
160 diamond 619
 
2434 Serge 620
        mov     [hd_error], 0
160 diamond 621
 
2434 Serge 622
        cmp     [hd_setup], 1   ; do not mark error for setup request
3555 Serge 623
        je      buf_wait_ok
160 diamond 624
 
2434 Serge 625
        test    al, 1           ; previous command ended up with an error
3555 Serge 626
        jz      buf_wait_ok
5201 serge 627
;--------------------------------------
3725 Serge 628
@@:
2434 Serge 629
        mov     [hd_error], 1
5201 serge 630
;--------------------------------------
3725 Serge 631
buf_wait_ok:
3555 Serge 632
        pop     edx eax
633
        ret
3725 Serge 634
;-----------------------------------------------------------------------------
3908 Serge 635
irq14_num equ byte 14
636
irq15_num equ byte 15
637
;-----------------------------------------------------------------------------
160 diamond 638
align 4
639
wait_for_sector_dma_ide0:
640
        push    eax
641
        push    edx
642
        call    save_hd_wait_timeout
3725 Serge 643
;--------------------------------------
644
align 4
160 diamond 645
.wait:
646
        call    change_task
5201 serge 647
 
3908 Serge 648
        cmp     [IDE_common_irq_param], 0
649
        jz      .done
650
 
160 diamond 651
        call    check_hd_wait_timeout
5201 serge 652
 
160 diamond 653
        cmp     [hd_error], 0
654
        jz      .wait
5201 serge 655
 
3908 Serge 656
        mov     [IDE_common_irq_param], 0
657
;--------------------------------------
160 diamond 658
.done:
659
        pop     edx
660
        pop     eax
661
        ret
3725 Serge 662
;-----------------------------------------------------------------------------
160 diamond 663
align 4
664
wait_for_sector_dma_ide1:
665
        push    eax
666
        push    edx
667
        call    save_hd_wait_timeout
3725 Serge 668
;--------------------------------------
669
align 4
160 diamond 670
.wait:
671
        call    change_task
5201 serge 672
 
3908 Serge 673
        cmp     [IDE_common_irq_param], 0
674
        jz      .done
675
 
160 diamond 676
        call    check_hd_wait_timeout
5201 serge 677
 
160 diamond 678
        cmp     [hd_error], 0
679
        jz      .wait
5201 serge 680
 
3908 Serge 681
        mov     [IDE_common_irq_param], 0
682
;--------------------------------------
160 diamond 683
.done:
684
        pop     edx
685
        pop     eax
686
        ret
3725 Serge 687
;-----------------------------------------------------------------------------
160 diamond 688
iglobal
689
align 4
5201 serge 690
; note that IDE descriptor table must be 4-byte aligned
691
; and do not cross 4K boundary
160 diamond 692
IDE_descriptor_table:
3908 Serge 693
        dd IDE_DMA
694
        dw 0x2000
695
        dw 0x8000
160 diamond 696
 
3908 Serge 697
dma_cur_sector  dd not 40h
698
dma_hdpos       dd 0
699
IDE_common_irq_param db 0
160 diamond 700
endg
3725 Serge 701
;-----------------------------------------------------------------------------
160 diamond 702
uglobal
703
; all uglobals are zeroed at boot
3908 Serge 704
cache_chain_ptr     dd 0
705
cache_chain_size    db 0
706
allow_dma_access    db 0
160 diamond 707
endg
3725 Serge 708
;-----------------------------------------------------------------------------
160 diamond 709
align 4
3908 Serge 710
IDE_irq_14_handler:
5201 serge 711
;        DEBUGF  1, 'K : IDE_irq_14_handler %x\n', [IDE_common_irq_param]:2
3908 Serge 712
        cmp     [IDE_common_irq_param], irq14_num
713
        jne     .exit
714
 
160 diamond 715
        pushfd
716
        cli
717
        pushad
3908 Serge 718
        mov     [IDE_common_irq_param], 0
5201 serge 719
        mov     ecx, [IDE_controller_pointer]
720
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
4423 Serge 721
; test whether it is our interrupt?
722
        add     edx, 2
723
        in      al, dx
724
        test    al, 100b
725
        jz      @f
3908 Serge 726
; clear Bus Master IDE Status register
727
; clear Interrupt bit
728
        out     dx, al
4423 Serge 729
; clear Bus Master IDE Command register
730
        sub     edx, 2
731
        xor     eax, eax
732
        out     dx, al
733
; read status register and remove the interrupt request
734
        mov     edx, [hdbase]
735
        add     edx, 0x7
736
        in      al, dx
160 diamond 737
        popad
738
        popfd
4423 Serge 739
        mov     al, 1
740
        ret
3908 Serge 741
;--------------------------------------
4423 Serge 742
@@:
743
        popad
744
        popfd
745
;--------------------------------------
3908 Serge 746
.exit:
4423 Serge 747
        mov     al, 0
160 diamond 748
        ret
3725 Serge 749
;-----------------------------------------------------------------------------
160 diamond 750
align 4
3908 Serge 751
IDE_irq_15_handler:
5201 serge 752
;        DEBUGF  1, 'K : IDE_irq_15_handler %x\n', [IDE_common_irq_param]:2
3908 Serge 753
        cmp     [IDE_common_irq_param], irq15_num
754
        jne     .exit
755
 
160 diamond 756
        pushfd
757
        cli
758
        pushad
3908 Serge 759
        mov     [IDE_common_irq_param], 0
5201 serge 760
        mov     ecx, [IDE_controller_pointer]
761
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
160 diamond 762
        add     dx, 8
4423 Serge 763
; test whether it is our interrupt?
764
        add     edx, 2
765
        in      al, dx
766
        test    al, 100b
767
        jz      @f
3908 Serge 768
; clear Bus Master IDE Status register
769
; clear Interrupt bit
770
        out     dx, al
4423 Serge 771
; clear Bus Master IDE Command register
772
        sub     edx, 2
773
        mov     al, 0
774
        out     dx, al
775
; read status register and remove the interrupt request
776
        mov     edx, [hdbase]
777
        add     edx, 0x7
778
        in      al, dx
160 diamond 779
        popad
780
        popfd
4423 Serge 781
        mov     al, 1
782
        ret
3908 Serge 783
;--------------------------------------
4423 Serge 784
@@:
785
        popad
786
        popfd
787
;--------------------------------------
3908 Serge 788
.exit:
4423 Serge 789
        mov     al, 0
160 diamond 790
        ret
3725 Serge 791
;-----------------------------------------------------------------------------
160 diamond 792
align 4
3908 Serge 793
IDE_common_irq_handler:
5201 serge 794
;        DEBUGF  1, 'K : IDE_common_irq_handler %x\n', [IDE_common_irq_param]:2
795
        pushfd
796
        cli
3908 Serge 797
        cmp     [IDE_common_irq_param], 0
798
        je      .exit
799
 
800
        pushad
801
        xor     ebx, ebx
5201 serge 802
        mov     ecx, [IDE_controller_pointer]
803
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
3908 Serge 804
        mov     eax, IDE_common_irq_param
805
        cmp     [eax], irq14_num
806
        mov     [eax], bl
807
        je      @f
808
 
809
        add     dx, 8
810
;--------------------------------------
811
@@:
4423 Serge 812
; test whether it is our interrupt?
813
        add     edx, 2
814
        in      al, dx
815
        test    al, 100b
816
        jz      @f
3908 Serge 817
; clear Bus Master IDE Status register
818
; clear Interrupt bit
819
        out     dx, al
4423 Serge 820
; clear Bus Master IDE Command register
821
        sub     edx, 2
822
        xor     eax, eax
823
        out     dx, al
824
; read status register and remove the interrupt request
825
        mov     edx, [hdbase]
826
        add     edx, 0x7
827
        in      al, dx
3908 Serge 828
        popad
829
        popfd
4423 Serge 830
        mov     al, 1
831
        ret
3908 Serge 832
;--------------------------------------
4423 Serge 833
@@:
834
        popad
835
;--------------------------------------
3908 Serge 836
.exit:
5201 serge 837
        popfd
4423 Serge 838
        mov     al, 0
3908 Serge 839
        ret
840
;-----------------------------------------------------------------------------
841
align 4
160 diamond 842
hd_read_dma:
843
        push    eax
844
        push    edx
2434 Serge 845
        mov     edx, [dma_hdpos]
846
        cmp     edx, [hdpos]
597 mario79 847
        jne     .notread
5201 serge 848
 
160 diamond 849
        mov     edx, [dma_cur_sector]
850
        cmp     eax, edx
851
        jb      .notread
5201 serge 852
 
160 diamond 853
        add     edx, 15
854
        cmp     [esp+4], edx
855
        ja      .notread
5201 serge 856
 
160 diamond 857
        mov     eax, [esp+4]
858
        sub     eax, [dma_cur_sector]
859
        shl     eax, 9
581 serge 860
        add     eax, (OS_BASE+IDE_DMA)
5201 serge 861
 
3908 Serge 862
        push    ecx esi
160 diamond 863
        mov     esi, eax
864
        mov     ecx, 512/4
865
        cld
3555 Serge 866
        rep movsd
3908 Serge 867
        pop     esi ecx
5201 serge 868
 
160 diamond 869
        pop     edx
870
        pop     eax
871
        ret
5201 serge 872
;--------------------------------------
160 diamond 873
.notread:
3908 Serge 874
; set data for PRD Table
465 serge 875
        mov     eax, IDE_descriptor_table
3555 Serge 876
        mov     dword [eax], IDE_DMA
465 serge 877
        mov     word [eax+4], 0x2000
878
        sub     eax, OS_BASE
3908 Serge 879
; select controller Primary or Secondary
5201 serge 880
        mov     ecx, [IDE_controller_pointer]
881
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
882
 
3908 Serge 883
        push    eax
5201 serge 884
        mov     eax, [hdpos]
885
        dec     eax
886
        test    eax, 10b
3908 Serge 887
        pop     eax
160 diamond 888
        jz      @f
5201 serge 889
 
160 diamond 890
        add     edx, 8
5201 serge 891
;--------------------------------------
160 diamond 892
@@:
893
        push    edx
3908 Serge 894
; Bus Master IDE PRD Table Address
160 diamond 895
        add     edx, 4
3908 Serge 896
; save IDE_descriptor_table
160 diamond 897
        out     dx, eax
898
        pop     edx
3908 Serge 899
; clear Bus Master IDE Command register
160 diamond 900
        mov     al, 0
901
        out     dx, al
3908 Serge 902
; clear Bus Master IDE Status register
903
; clear Error bit and Interrupt bit
160 diamond 904
        add     edx, 2
3908 Serge 905
        mov     al, 6 ; 110b
160 diamond 906
        out     dx, al
3725 Serge 907
; Select the desired drive
908
        mov     edx, [hdbase]
909
        add     edx, 6   ; адрес регистра головок
910
        mov     al, byte [hdid]
911
        add     al, 128+64+32
912
        out     dx, al ; номер головки/номер диска
913
 
160 diamond 914
        call    wait_for_hd_idle
5201 serge 915
 
160 diamond 916
        cmp     [hd_error], 0
917
        jnz     hd_read_error
3725 Serge 918
; ATA with 28 or 48 bit for sector number?
919
        mov     eax, [esp+4]
920
; -10h because the PreCache hits the boundary between lba28 and lba48
921
; 10h = 16  - size of PreCache
922
        cmp     eax, 0x10000000-10h
923
        jae     .lba48
924
;--------------------------------------
925
.lba28:
926
        pushfd
927
        cli
160 diamond 928
        xor     eax, eax
929
        mov     edx, [hdbase]
930
        inc     edx
3725 Serge 931
        out     dx, al ; ATA Features регистр "особенностей"
160 diamond 932
        inc     edx
3725 Serge 933
        mov     eax, 10h ; Sector Counter = 16 ; PreCache
934
        out     dx, al ; ATA Sector Counter счётчик секторов
160 diamond 935
        inc     edx
3725 Serge 936
        mov     eax, [esp+4+4]
937
        out     dx, al ; LBA Low LBA (7:0)
160 diamond 938
        shr     eax, 8
939
        inc     edx
3725 Serge 940
        out     dx, al ; LBA Mid LBA (15:8)
160 diamond 941
        shr     eax, 8
942
        inc     edx
3725 Serge 943
        out     dx, al ; LBA High LBA (23:16)
160 diamond 944
        shr     eax, 8
945
        inc     edx
3725 Serge 946
        and     al, 0xF ; LBA (27:24)
160 diamond 947
        add     al, byte [hdid]
948
        add     al, 11100000b
3725 Serge 949
        out     dx, al ; номер головки/номер диска
160 diamond 950
        inc     edx
3725 Serge 951
        mov     al, 0xC8 ; READ DMA
952
        out     dx, al ; ATACommand регистр команд
953
        jmp     .continue
954
;--------------------------------------
955
.lba48:
956
        pushfd
957
        cli
958
        xor     eax, eax
959
        mov     edx, [hdbase]
960
        inc     edx
961
        out     dx, al ; Features Previous Reserved
962
        out     dx, al ; Features Current Reserved
963
        inc     edx
964
        out     dx, al ; Sector Count Previous Sector count (15:8)
965
        mov     eax, 10h ; Sector Counter = 16 PreCache
966
        out     dx, al ; Sector Count Current Sector count (7:0)
967
        inc     edx
968
        mov     eax, [esp+4+4]
969
        rol     eax, 8
970
        out     dx, al ; LBA Low Previous LBA (31:24)
971
        xor     eax, eax ; because only 32 bit cache
972
        inc     edx
973
        out     dx, al ; LBA Mid Previous LBA (39:32)
974
        inc     edx
975
        out     dx, al ; LBA High Previous LBA (47:40)
976
        sub     edx, 2
977
        mov     eax, [esp+4+4]
978
        out     dx, al ; LBA Low Current LBA (7:0)
979
        shr     eax, 8
980
        inc     edx
981
        out     dx, al ; LBA Mid Current LBA (15:8)
982
        shr     eax, 8
983
        inc     edx
984
        out     dx, al ; LBA High Current LBA (23:16)
985
        inc     edx
986
        mov     al, byte [hdid]
987
        add     al, 128+64+32
988
        out     dx, al ; номер головки/номер диска
989
        inc     edx
990
        mov     al, 25h ; READ DMA EXT
991
        out     dx, al ; ATACommand регистр команд
992
;--------------------------------------
993
.continue:
3908 Serge 994
; select controller Primary or Secondary
5201 serge 995
        mov     ecx, [IDE_controller_pointer]
996
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
997
 
998
        mov     eax, [hdpos]
999
        dec     eax
1000
        test    eax, 10b
160 diamond 1001
        jz      @f
5201 serge 1002
 
160 diamond 1003
        add     dx, 8
5201 serge 1004
;--------------------------------------
160 diamond 1005
@@:
3908 Serge 1006
; set write to memory and Start Bus Master
160 diamond 1007
        mov     al, 9
1008
        out     dx, al
3908 Serge 1009
 
5201 serge 1010
        mov     eax, [hdpos]
1011
        dec     eax
1012
        test    eax, 10b
160 diamond 1013
        jnz     .ide1
3908 Serge 1014
 
1015
        mov     [IDE_common_irq_param], irq14_num
160 diamond 1016
        jmp     @f
5201 serge 1017
;--------------------------------------
160 diamond 1018
.ide1:
3908 Serge 1019
        mov     [IDE_common_irq_param], irq15_num
5201 serge 1020
;--------------------------------------
160 diamond 1021
@@:
3725 Serge 1022
        popfd
3908 Serge 1023
; wait for interrupt
5201 serge 1024
        mov     eax, [hdpos]
1025
        dec     eax
1026
        test    eax, 10b
160 diamond 1027
        jnz     .wait_ide1
5201 serge 1028
 
160 diamond 1029
        call    wait_for_sector_dma_ide0
1030
        jmp     @f
5201 serge 1031
;--------------------------------------
160 diamond 1032
.wait_ide1:
1033
        call    wait_for_sector_dma_ide1
5201 serge 1034
;--------------------------------------
160 diamond 1035
@@:
1036
        cmp     [hd_error], 0
1037
        jnz     hd_read_error
5201 serge 1038
 
2434 Serge 1039
        mov     eax, [hdpos]
1040
        mov     [dma_hdpos], eax
160 diamond 1041
        pop     edx
1042
        pop     eax
5201 serge 1043
 
160 diamond 1044
        mov     [dma_cur_sector], eax
1045
        jmp     hd_read_dma
3725 Serge 1046
;-----------------------------------------------------------------------------
3908 Serge 1047
cache_write_dma:
1048
        mov     eax, [cache_chain_ptr] ; for what?
160 diamond 1049
        push    esi
3908 Serge 1050
; set data for PRD Table
160 diamond 1051
        mov     eax, IDE_descriptor_table
2434 Serge 1052
        mov     edx, eax
5201 serge 1053
 
580 mario79 1054
        pusha
581 serge 1055
        mov     edi, (OS_BASE+IDE_DMA)
1056
        mov     dword [edx], IDE_DMA
580 mario79 1057
        movzx   ecx, [cache_chain_size]
1058
        shl     ecx, 9
1059
        mov     word [edx+4], cx
2434 Serge 1060
        shr     ecx, 2
580 mario79 1061
        cld
1062
        rep movsd
1063
        popa
5201 serge 1064
 
465 serge 1065
        sub     eax, OS_BASE
3908 Serge 1066
; select controller Primary or Secondary
5201 serge 1067
        mov     ecx, [IDE_controller_pointer]
1068
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
1069
 
3908 Serge 1070
        push    eax
5201 serge 1071
        mov     eax, [hdpos]
1072
        dec     eax
1073
        test    eax, 10b
3908 Serge 1074
        pop     eax
160 diamond 1075
        jz      @f
5201 serge 1076
 
160 diamond 1077
        add     edx, 8
5201 serge 1078
;--------------------------------------
160 diamond 1079
@@:
1080
        push    edx
3908 Serge 1081
; Bus Master IDE PRD Table Address
160 diamond 1082
        add     edx, 4
3908 Serge 1083
; save IDE_descriptor_table
160 diamond 1084
        out     dx, eax
1085
        pop     edx
3908 Serge 1086
; clear Bus Master IDE Command register
160 diamond 1087
        mov     al, 0
1088
        out     dx, al
3908 Serge 1089
; clear Bus Master IDE Status register
1090
; clear Error bit and Interrupt bit
160 diamond 1091
        add     edx, 2
1092
        mov     al, 6
1093
        out     dx, al
3725 Serge 1094
; Select the desired drive
1095
        mov     edx, [hdbase]
1096
        add     edx, 6   ; адрес регистра головок
1097
        mov     al, byte [hdid]
1098
        add     al, 128+64+32
1099
        out     dx, al ; номер головки/номер диска
1100
 
160 diamond 1101
        call    wait_for_hd_idle
5201 serge 1102
 
160 diamond 1103
        cmp     [hd_error], 0
1104
        jnz     hd_write_error_dma
3725 Serge 1105
; ATA with 28 or 48 bit for sector number?
1106
        mov     esi, [cache_chain_ptr]
1107
        mov     eax, [esi]
1108
; -40h because the PreCache hits the boundary between lba28 and lba48
1109
; 40h = 64  - the maximum number of sectors to be written for one command
1110
        cmp     eax, 0x10000000-40h
1111
        jae     .lba48
1112
;--------------------------------------
1113
.lba28:
1114
        pushfd
1115
        cli
160 diamond 1116
        xor     eax, eax
1117
        mov     edx, [hdbase]
1118
        inc     edx
3725 Serge 1119
        out     dx, al ; ATA Features регистр "особенностей"
160 diamond 1120
        inc     edx
3725 Serge 1121
        mov     al, [cache_chain_size] ; Sector Counter
1122
        out     dx, al ; ATA Sector Counter счётчик секторов
160 diamond 1123
        inc     edx
1124
        mov     eax, [esi]
3725 Serge 1125
        out     dx, al ; LBA Low LBA (7:0)
160 diamond 1126
        shr     eax, 8
1127
        inc     edx
3725 Serge 1128
        out     dx, al ; LBA Mid LBA (15:8)
160 diamond 1129
        shr     eax, 8
1130
        inc     edx
3725 Serge 1131
        out     dx, al ; LBA High LBA (23:16)
160 diamond 1132
        shr     eax, 8
1133
        inc     edx
3725 Serge 1134
        and     al, 0xF ; LBA (27:24)
160 diamond 1135
        add     al, byte [hdid]
1136
        add     al, 11100000b
3725 Serge 1137
        out     dx, al ; номер головки/номер диска
160 diamond 1138
        inc     edx
3725 Serge 1139
        mov     al, 0xCA ; WRITE DMA
1140
        out     dx, al ; ATACommand регистр команд
1141
        jmp     .continue
1142
;--------------------------------------
1143
.lba48:
1144
        pushfd
1145
        cli
1146
        xor     eax, eax
1147
        mov     edx, [hdbase]
1148
        inc     edx
1149
        out     dx, al ; Features Previous Reserved
1150
        out     dx, al ; Features Current Reserved
1151
        inc     edx
1152
        out     dx, al ; Sector Count Previous Sector count (15:8)
1153
        mov     al, [cache_chain_size] ; Sector Counter
1154
        out     dx, al ; Sector Count Current Sector count (7:0)
1155
        inc     edx
1156
        mov     eax, [esi]
1157
        rol     eax, 8
1158
        out     dx, al ; LBA Low Previous LBA (31:24)
1159
        xor     eax, eax ; because only 32 bit cache
1160
        inc     edx
1161
        out     dx, al ; LBA Mid Previous LBA (39:32)
1162
        inc     edx
1163
        out     dx, al ; LBA High Previous LBA (47:40)
1164
        sub     edx, 2
1165
        mov     eax, [esi]
1166
        out     dx, al ; LBA Low Current LBA (7:0)
1167
        shr     eax, 8
1168
        inc     edx
1169
        out     dx, al ; LBA Mid Current LBA (15:8)
1170
        shr     eax, 8
1171
        inc     edx
1172
        out     dx, al ; LBA High Current LBA (23:16)
1173
        inc     edx
1174
        mov     al, byte [hdid]
1175
        add     al, 128+64+32
1176
        out     dx, al ; номер головки/номер диска
1177
        inc     edx
1178
        mov     al, 35h ; WRITE DMA EXT
1179
        out     dx, al ; ATACommand регистр команд
1180
;--------------------------------------
1181
.continue:
3908 Serge 1182
; select controller Primary or Secondary
5201 serge 1183
        mov     ecx, [IDE_controller_pointer]
1184
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
1185
 
1186
        mov     eax, [hdpos]
1187
        dec     eax
1188
        test    eax, 10b
160 diamond 1189
        jz      @f
5201 serge 1190
 
160 diamond 1191
        add     dx, 8
5201 serge 1192
;--------------------------------------
160 diamond 1193
@@:
3908 Serge 1194
; set write to device and Start Bus Master
160 diamond 1195
        mov     al, 1
1196
        out     dx, al
5201 serge 1197
 
1198
        mov     eax, [hdpos]
1199
        dec     eax
1200
        test    eax, 10b
160 diamond 1201
        jnz     .ide1
3908 Serge 1202
 
1203
        mov     [IDE_common_irq_param], irq14_num
160 diamond 1204
        jmp     @f
5201 serge 1205
;--------------------------------------
160 diamond 1206
.ide1:
3908 Serge 1207
        mov     [IDE_common_irq_param], irq15_num
5201 serge 1208
;--------------------------------------
160 diamond 1209
@@:
3725 Serge 1210
        popfd
3908 Serge 1211
; wait for interrupt
160 diamond 1212
        mov     [dma_cur_sector], not 0x40
5201 serge 1213
 
1214
        mov     eax, [hdpos]
1215
        dec     eax
1216
        test    eax, 10b
160 diamond 1217
        jnz     .wait_ide1
5201 serge 1218
 
160 diamond 1219
        call    wait_for_sector_dma_ide0
5201 serge 1220
 
160 diamond 1221
        jmp     @f
5201 serge 1222
;--------------------------------------
160 diamond 1223
.wait_ide1:
1224
        call    wait_for_sector_dma_ide1
5201 serge 1225
;--------------------------------------
160 diamond 1226
@@:
1227
        cmp     [hd_error], 0
1228
        jnz     hd_write_error_dma
1229
        pop     esi
1230
        ret
3725 Serge 1231
;-----------------------------------------------------------------------------
5201 serge 1232
proc clear_pci_ide_interrupts
1233
        mov     esi, pcidev_list
1234
;--------------------------------------
3908 Serge 1235
align 4
5201 serge 1236
.loop:
1237
        mov     esi, [esi+PCIDEV.fd]
1238
        cmp     esi, pcidev_list
1239
        jz      .done
1240
 
1241
;        cmp     [esi+PCIDEV.class], 0x01018F
1242
        mov     eax, [esi+PCIDEV.class]
1243
        shr     eax, 4
1244
        cmp     eax, 0x01018
1245
        jnz     .loop
1246
 
1247
        mov     ah, [esi+PCIDEV.bus]
1248
        mov     al, 2
1249
        mov     bh, [esi+PCIDEV.devfn]
1250
        mov     bl, 0x20
1251
        call    pci_read_reg
1252
 
1253
        and     eax, 0FFFCh
1254
        mov     edx, eax
1255
        add     edx, 2
1256
        in      al, dx
1257
        DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
1258
        out     dx, al
1259
        in      al, dx
1260
        DEBUGF 1,'-> %x; ',al
1261
        add     edx, 8
1262
        in      al, dx
1263
        DEBUGF 1,'port[%x] = %x ',dx,al
1264
        out     dx, al
1265
        in      al, dx
1266
        DEBUGF 1,'-> %x\n',al
1267
        jmp     .loop
1268
;--------------------------------------
1269
.done:
1270
        ret
1271
endp
3725 Serge 1272
;-----------------------------------------------------------------------------