Subversion Repositories Kolibri OS

Rev

Rev 5852 | Rev 6650 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5852 Rev 6015
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 5852 $
8
$Revision: 6015 $
9
 
9
 
10
; HDD driver
10
; HDD driver
11
 
11
 
12
struct HD_DATA
12
struct HD_DATA
13
hdbase  dw  ?
13
hdbase  dw  ?
14
hdid    dw  ?
14
hdid    dw  ?
15
hdpos   dw  ?
15
hdpos   dw  ?
16
hd48    dw  ?
16
hd48    dw  ?
17
ends
17
ends
18
;-----------------------------------------------------------------
18
;-----------------------------------------------------------------
19
iglobal
19
iglobal
20
align 4
20
align 4
21
ide_callbacks:
21
ide_callbacks:
22
    dd  ide_callbacks.end - ide_callbacks
22
    dd  ide_callbacks.end - ide_callbacks
23
    dd  0   ; no close function
23
    dd  0   ; no close function
24
    dd  0   ; no closemedia function
24
    dd  0   ; no closemedia function
25
    dd  ide_querymedia
25
    dd  ide_querymedia
26
    dd  ide_read
26
    dd  ide_read
27
    dd  ide_write
27
    dd  ide_write
28
    dd  0   ; no flush function
28
    dd  0   ; no flush function
29
    dd  0   ; use default cache size
29
    dd  0   ; use default cache size
30
.end:
30
.end:
31
 
31
 
32
hd0_data    HD_DATA     ?,  0,  1, 0
32
hd0_data    HD_DATA     ?,  0,  1, 0
33
hd1_data    HD_DATA     ?, 16,  2, 0
33
hd1_data    HD_DATA     ?, 16,  2, 0
34
hd2_data    HD_DATA     ?,  0,  3, 0
34
hd2_data    HD_DATA     ?,  0,  3, 0
35
hd3_data    HD_DATA     ?, 16,  4, 0
35
hd3_data    HD_DATA     ?, 16,  4, 0
36
hd4_data    HD_DATA     ?,  0,  5, 0
36
hd4_data    HD_DATA     ?,  0,  5, 0
37
hd5_data    HD_DATA     ?, 16,  6, 0
37
hd5_data    HD_DATA     ?, 16,  6, 0
38
hd6_data    HD_DATA     ?,  0,  7, 0
38
hd6_data    HD_DATA     ?,  0,  7, 0
39
hd7_data    HD_DATA     ?, 16,  8, 0
39
hd7_data    HD_DATA     ?, 16,  8, 0
40
hd8_data    HD_DATA     ?,  0,  9, 0
40
hd8_data    HD_DATA     ?,  0,  9, 0
41
hd9_data    HD_DATA     ?, 16, 10, 0
41
hd9_data    HD_DATA     ?, 16, 10, 0
42
hd10_data   HD_DATA     ?,  0, 11, 0
42
hd10_data   HD_DATA     ?,  0, 11, 0
43
hd11_data   HD_DATA     ?, 16, 12, 0
43
hd11_data   HD_DATA     ?, 16, 12, 0
44
 
44
 
45
ide_mutex_table:
45
ide_mutex_table:
46
    dd  ide_channel1_mutex
46
    dd  ide_channel1_mutex
47
    dd  ide_channel2_mutex
47
    dd  ide_channel2_mutex
48
    dd  ide_channel3_mutex
48
    dd  ide_channel3_mutex
49
    dd  ide_channel4_mutex
49
    dd  ide_channel4_mutex
50
    dd  ide_channel5_mutex
50
    dd  ide_channel5_mutex
51
    dd  ide_channel6_mutex
51
    dd  ide_channel6_mutex
52
endg
52
endg
53
;-----------------------------------------------------------------
53
;-----------------------------------------------------------------
54
uglobal
54
uglobal
55
ide_mutex               MUTEX
55
ide_mutex               MUTEX
56
ide_channel1_mutex      MUTEX
56
ide_channel1_mutex      MUTEX
57
ide_channel2_mutex      MUTEX
57
ide_channel2_mutex      MUTEX
58
ide_channel3_mutex      MUTEX
58
ide_channel3_mutex      MUTEX
59
ide_channel4_mutex      MUTEX
59
ide_channel4_mutex      MUTEX
60
ide_channel5_mutex      MUTEX
60
ide_channel5_mutex      MUTEX
61
ide_channel6_mutex      MUTEX
61
ide_channel6_mutex      MUTEX
62
blockSize:
62
blockSize:
63
rb 4
63
rb 4
64
sector:
64
sector:
65
rb 6
65
rb 6
66
allow_dma_access        db ?
66
allow_dma_access        db ?
67
IDE_common_irq_param    db ?
67
IDE_common_irq_param    db ?
68
eventPointer            dd ?
68
eventPointer            dd ?
69
eventID                 dd ?
69
eventID                 dd ?
70
endg
70
endg
71
;-----------------------------------------------------------------
71
;-----------------------------------------------------------------
72
ide_read:
72
ide_read:
73
        mov     al, 25h     ; READ DMA EXT
73
        mov     al, 25h     ; READ DMA EXT
74
        jmp     ide_read_write
74
        jmp     ide_read_write
75
 
75
 
76
ide_write:
76
ide_write:
77
        mov     al, 35h     ; WRITE DMA EXT
77
        mov     al, 35h     ; WRITE DMA EXT
78
 
78
 
79
proc ide_read_write stdcall uses esi edi ebx, \
79
proc ide_read_write stdcall uses esi edi ebx, \
80
        hd_data, buffer, startsector:qword, numsectors
80
        hd_data, buffer, startsector:qword, numsectors
81
        ; hd_data = pointer to hd*_data
81
        ; hd_data = pointer to hd*_data
82
        ; buffer = pointer to buffer with/for data
82
        ; buffer = pointer to buffer with/for data
83
        ; startsector = 64-bit start sector
83
        ; startsector = 64-bit start sector
84
        ; numsectors = pointer to number of sectors on input,
84
        ; numsectors = pointer to number of sectors on input,
85
        ;  must be filled with number of sectors really read/written
85
        ;  must be filled with number of sectors really read/written
86
locals
86
locals
87
sectors_todo    dd      ?
87
sectors_todo    dd      ?
88
channel_lock    dd      ?
88
channel_lock    dd      ?
89
endl
89
endl
90
        mov     bl, al
90
        mov     bl, al
91
; get number of requested sectors and say that no sectors were read yet
91
; get number of requested sectors and say that no sectors were read yet
92
        mov     ecx, [numsectors]
92
        mov     ecx, [numsectors]
93
        mov     eax, [ecx]
93
        mov     eax, [ecx]
94
        mov     dword [ecx], 0
94
        mov     dword [ecx], 0
95
        mov     [sectors_todo], eax
95
        mov     [sectors_todo], eax
96
; acquire the global lock
96
; acquire the global lock
97
        mov     ecx, ide_mutex
97
        mov     ecx, ide_mutex
98
        call    mutex_lock
98
        call    mutex_lock
99
        mov     ecx, [hd_data]
99
        mov     ecx, [hd_data]
100
        movzx   ecx, [ecx+HD_DATA.hdpos]
100
        movzx   ecx, [ecx+HD_DATA.hdpos]
101
        dec     ecx
101
        dec     ecx
102
        shr     ecx, 1
102
        shr     ecx, 1
103
        shl     ecx, 2
103
        shl     ecx, 2
104
        mov     ecx, [ecx + ide_mutex_table]
104
        mov     ecx, [ecx + ide_mutex_table]
105
        mov     [channel_lock], ecx
105
        mov     [channel_lock], ecx
106
        call    mutex_lock
106
        call    mutex_lock
107
; prepare worker procedures variables
107
; prepare worker procedures variables
108
        mov     esi, [buffer]
108
        mov     esi, [buffer]
109
        mov     edi, esi
109
        mov     edi, esi
110
        mov     ecx, [hd_data]
110
        mov     ecx, [hd_data]
111
        movzx   eax, [ecx+HD_DATA.hdbase]
111
        movzx   eax, [ecx+HD_DATA.hdbase]
112
        mov     [hdbase], eax
112
        mov     [hdbase], eax
113
        mov     ax, [ecx+HD_DATA.hdid]
113
        mov     ax, [ecx+HD_DATA.hdid]
114
        mov     [hdid], eax
114
        mov     [hdid], eax
115
        mov     eax, dword [startsector]
115
        mov     eax, dword [startsector]
116
        mov     [sector], eax
116
        mov     [sector], eax
117
        cmp     [ecx+HD_DATA.hd48], 0
117
        cmp     [ecx+HD_DATA.hd48], 0
118
        jz      .LBA28
118
        jz      .LBA28
119
        mov     ax, word [startsector+4]
119
        mov     ax, word [startsector+4]
120
        mov     [sector+4], ax
120
        mov     [sector+4], ax
121
        movzx   ecx, [ecx+HD_DATA.hdpos]
121
        movzx   ecx, [ecx+HD_DATA.hdpos]
122
        mov     [hdpos], ecx
122
        mov     [hdpos], ecx
123
        dec     ecx
123
        dec     ecx
124
        shr     ecx, 2
124
        shr     ecx, 2
125
        imul    ecx, sizeof.IDE_DATA
125
        imul    ecx, sizeof.IDE_DATA
126
        add     ecx, IDE_controller_1
126
        add     ecx, IDE_controller_1
127
        mov     [IDE_controller_pointer], ecx
127
        mov     [IDE_controller_pointer], ecx
128
        mov     eax, [hdpos]
128
        mov     eax, [hdpos]
129
        dec     eax
129
        dec     eax
130
        and     eax, 11b
130
        and     eax, 11b
131
        shr     eax, 1
131
        shr     eax, 1
132
        add     eax, ecx
132
        add     eax, ecx
133
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
133
        cmp     [eax+IDE_DATA.dma_hdd_channel_1], 1
134
        jz      .next
134
        jz      .next
135
        dec     ebx     ; READ/WRITE SECTOR(S) EXT
135
        dec     ebx     ; READ/WRITE SECTOR(S) EXT
136
; LBA48 supports max 10000h sectors per time
136
; LBA48 supports max 10000h sectors per time
137
; loop until all sectors will be processed
137
; loop until all sectors will be processed
138
.next:
138
.next:
139
        mov     ecx, 8000h
139
        mov     ecx, 8000h
140
        cmp     ecx, [sectors_todo]
140
        cmp     ecx, [sectors_todo]
141
        jbe     @f
141
        jbe     @f
142
        mov     ecx, [sectors_todo]
142
        mov     ecx, [sectors_todo]
143
@@:
143
@@:
144
        mov     [blockSize], ecx
144
        mov     [blockSize], ecx
145
        push    ecx
145
        push    ecx
146
        call    IDE_transfer
146
        call    IDE_transfer
147
        pop     ecx
147
        pop     ecx
148
        jc      .out
148
        jc      .out
149
        mov     eax, [numsectors]
149
        mov     eax, [numsectors]
150
        add     [eax], ecx
150
        add     [eax], ecx
151
        sub     [sectors_todo], ecx
151
        sub     [sectors_todo], ecx
152
        jz      .out
152
        jz      .out
153
        add     [sector], ecx
153
        add     [sector], ecx
154
        adc     word [sector+4], 0
154
        adc     word [sector+4], 0
155
        jmp     .next
155
        jmp     .next
156
.LBA28:
156
.LBA28:
157
        add     eax, [sectors_todo]
157
        add     eax, [sectors_todo]
158
        add     eax, 0xF0000000
158
        add     eax, 0xF0000000
159
        jc      .out
159
        jc      .out
160
        sub     bl, 5   ; READ/WRITE SECTOR(S)
160
        sub     bl, 5   ; READ/WRITE SECTOR(S)
161
; LBA28 supports max 256 sectors per time
161
; LBA28 supports max 256 sectors per time
162
; loop until all sectors will be processed
162
; loop until all sectors will be processed
163
.next28:
163
.next28:
164
        mov     ecx, 256
164
        mov     ecx, 256
165
        cmp     ecx, [sectors_todo]
165
        cmp     ecx, [sectors_todo]
166
        jbe     @f
166
        jbe     @f
167
        mov     ecx, [sectors_todo]
167
        mov     ecx, [sectors_todo]
168
@@:
168
@@:
169
        mov     [blockSize], ecx
169
        mov     [blockSize], ecx
170
        push    ecx
170
        push    ecx
171
        call    IDE_transfer.LBA28
171
        call    IDE_transfer.LBA28
172
        pop     ecx
172
        pop     ecx
173
        jc      .out
173
        jc      .out
174
        mov     eax, [numsectors]
174
        mov     eax, [numsectors]
175
        add     [eax], ecx
175
        add     [eax], ecx
176
        sub     [sectors_todo], ecx
176
        sub     [sectors_todo], ecx
177
        jz      .out
177
        jz      .out
178
        add     [sector], ecx
178
        add     [sector], ecx
179
        jmp     .next28
179
        jmp     .next28
180
; loop is done, either due to error or because everything is done
180
; loop is done, either due to error or because everything is done
181
; release the global lock and return the corresponding status
181
; release the global lock and return the corresponding status
182
.out:
182
.out:
183
        sbb     eax, eax
183
        sbb     eax, eax
184
        push    eax
184
        push    eax
185
        mov     ecx, [channel_lock]
185
        mov     ecx, [channel_lock]
186
        call    mutex_unlock
186
        call    mutex_unlock
187
        mov     ecx, ide_mutex
187
        mov     ecx, ide_mutex
188
        call    mutex_unlock
188
        call    mutex_unlock
189
        pop     eax
189
        pop     eax
190
        ret
190
        ret
191
endp
191
endp
192
;-----------------------------------------------------------------
192
;-----------------------------------------------------------------
193
; this is a stub
193
; this is a stub
194
proc ide_querymedia stdcall, hd_data, mediainfo
194
proc ide_querymedia stdcall, hd_data, mediainfo
195
        mov     eax, [mediainfo]
195
        mov     eax, [mediainfo]
196
        mov     [eax+DISKMEDIAINFO.Flags], 0
196
        mov     [eax+DISKMEDIAINFO.Flags], 0
197
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
197
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
198
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
198
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
199
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
199
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
200
        xor     eax, eax
200
        xor     eax, eax
201
        ret
201
        ret
202
endp
202
endp
203
;-----------------------------------------------------------------
203
;-----------------------------------------------------------------
204
; input: esi -> buffer, bl = command, [sector], [blockSize]
204
; input: esi -> buffer, bl = command, [sector], [blockSize]
205
; output: esi -> next block in buffer
205
; output: esi -> next block in buffer
206
; for pio read esi equal edi
206
; for pio read esi equal edi
207
IDE_transfer:
207
IDE_transfer:
208
        mov     edx, [hdbase]
208
        mov     edx, [hdbase]
209
        add     edx, 6
209
        add     edx, 6
210
        mov     al, byte [hdid]
210
        mov     al, byte [hdid]
211
        add     al, 224
211
        add     al, 224
212
        out     dx, al  ; select the desired drive
212
        out     dx, al  ; select the desired drive
213
        call    save_hd_wait_timeout
213
        call    save_hd_wait_timeout
214
        inc     edx
214
        inc     edx
215
@@:
215
@@:
216
        call    check_hd_wait_timeout
216
        call    check_hd_wait_timeout
217
        jc      .hd_error
217
        jc      .hd_error
218
        in      al, dx
218
        in      al, dx
219
        test    al, 128 ; ready for command?
219
        test    al, 128 ; ready for command?
220
        jnz     @b
220
        jnz     @b
221
        pushfd          ; fill the ports
221
        pushfd          ; fill the ports
222
        cli
222
        cli
223
        mov     edx, [hdbase]
223
        mov     edx, [hdbase]
224
        inc     edx
224
        inc     edx
225
        inc     edx
225
        inc     edx
226
        mov     al, [blockSize+1]
226
        mov     al, [blockSize+1]
227
        out     dx, al  ; Sector count (15:8)
227
        out     dx, al  ; Sector count (15:8)
228
        inc     edx
228
        inc     edx
229
        mov     eax, [sector+3]
229
        mov     eax, [sector+3]
230
        out     dx, al  ; LBA (31:24)
230
        out     dx, al  ; LBA (31:24)
231
        inc     edx
231
        inc     edx
232
        shr     eax, 8
232
        shr     eax, 8
233
        out     dx, al  ; LBA (39:32)
233
        out     dx, al  ; LBA (39:32)
234
        inc     edx
234
        inc     edx
235
        shr     eax, 8
235
        shr     eax, 8
236
        out     dx, al  ; LBA (47:40)
236
        out     dx, al  ; LBA (47:40)
237
        sub     edx, 3
237
        sub     edx, 3
238
        mov     al, [blockSize]
238
        mov     al, [blockSize]
239
        out     dx, al  ; Sector count (7:0)
239
        out     dx, al  ; Sector count (7:0)
240
        inc     edx
240
        inc     edx
241
        mov     eax, [sector]
241
        mov     eax, [sector]
242
        out     dx, al  ; LBA (7:0)
242
        out     dx, al  ; LBA (7:0)
243
        inc     edx
243
        inc     edx
244
        shr     eax, 8
244
        shr     eax, 8
245
        out     dx, al  ; LBA (15:8)
245
        out     dx, al  ; LBA (15:8)
246
        inc     edx
246
        inc     edx
247
        shr     eax, 8
247
        shr     eax, 8
248
        out     dx, al  ; LBA (23:16)
248
        out     dx, al  ; LBA (23:16)
249
        inc     edx
249
        inc     edx
250
        mov     al, byte [hdid]
250
        mov     al, byte [hdid]
251
        add     al, 224
251
        add     al, 224
252
        out     dx, al
252
        out     dx, al
253
        test    bl, 1
253
        test    bl, 1
254
        jz      .PIO
254
        jz      .PIO
255
; DMA
255
; DMA
256
        mov     dword [esp], 0x1000
256
        mov     dword [esp], 0x1000
257
        call    kernel_alloc
257
        call    kernel_alloc
258
        mov     edi, eax
258
        mov     edi, eax
259
        push    eax
259
        push    eax
260
        shl     dword [blockSize], 9
260
        shl     dword [blockSize], 9
261
        mov     eax, esi
261
        mov     eax, esi
262
        add     eax, [blockSize]
262
        add     eax, [blockSize]
263
        push    eax
263
        push    eax
264
; check buffer pages physical addresses and fill the scatter-gather list
264
; check buffer pages physical addresses and fill the scatter-gather list
265
; buffer may be not aligned and may have size not divisible by page size
265
; buffer may be not aligned and may have size not divisible by page size
266
; [edi] = block physical address, [edi+4] = block size in bytes
266
; [edi] = block physical address, [edi+4] = block size in bytes
267
; block addresses can not cross 10000h borders
267
; block addresses can not cross 10000h borders
268
        mov     ecx, esi
268
        mov     ecx, esi
269
        and     ecx, 0xFFF
269
        and     ecx, 0xFFF
270
        jz      .aligned
270
        jz      .aligned
271
        mov     eax, esi
271
        mov     eax, esi
272
        call    get_pg_addr
272
        call    get_pg_addr
273
        add     eax, ecx
273
        add     eax, ecx
274
        neg     ecx
274
        neg     ecx
275
        add     ecx, 0x1000
275
        add     ecx, 0x1000
276
        mov     [edi], eax
276
        mov     [edi], eax
277
        cmp     ecx, [blockSize]
277
        cmp     ecx, [blockSize]
278
        jnc     .end
278
        jnc     .end
279
        mov     [edi+4], ecx
279
        mov     [edi+4], ecx
280
        add     esi, 0x1000
280
        add     esi, 0x1000
281
        add     edi, 8
281
        add     edi, 8
282
        sub     [blockSize], ecx
282
        sub     [blockSize], ecx
283
.aligned:
283
.aligned:
284
        mov     eax, esi
284
        mov     eax, esi
285
        call    get_pg_addr
285
        call    get_pg_addr
286
        mov     ecx, eax
286
        mov     ecx, eax
287
        mov     [edi], eax
287
        mov     [edi], eax
288
        and     ecx, 0xFFFF
288
        and     ecx, 0xFFFF
289
        neg     ecx
289
        neg     ecx
290
        add     ecx, 0x10000
290
        add     ecx, 0x10000
291
        cmp     [blockSize], ecx
291
        cmp     [blockSize], ecx
292
        jnc     @f
292
        jnc     @f
293
        mov     ecx, [blockSize]
293
        mov     ecx, [blockSize]
294
        and     ecx, 0xF000
294
        and     ecx, 0xF000
295
        jz      .end
295
        jz      .end
296
@@:
296
@@:
297
        push    ecx
297
        push    ecx
298
@@:
298
@@:
299
        add     esi, 0x1000
299
        add     esi, 0x1000
300
        add     eax, 0x1000
300
        add     eax, 0x1000
301
        sub     ecx, 0x1000
301
        sub     ecx, 0x1000
302
        jz      @f
302
        jz      @f
303
        mov     edx, eax
303
        mov     edx, eax
304
        mov     eax, esi
304
        mov     eax, esi
305
        call    get_pg_addr
305
        call    get_pg_addr
306
        cmp     eax, edx
306
        cmp     eax, edx
307
        jz      @b
307
        jz      @b
308
@@:
308
@@:
309
        pop     edx
309
        pop     edx
310
        sub     edx, ecx
310
        sub     edx, ecx
311
        mov     [edi+4], edx
311
        mov     [edi+4], edx
312
        add     edi, 8
312
        add     edi, 8
313
        sub     [blockSize], edx
313
        sub     [blockSize], edx
314
        jnz     .aligned
314
        jnz     .aligned
315
        sub     edi, 8
315
        sub     edi, 8
316
        jmp     @f
316
        jmp     @f
317
.end:
317
.end:
318
        mov     ecx, [blockSize]
318
        mov     ecx, [blockSize]
319
        mov     [edi+4], ecx
319
        mov     [edi+4], ecx
320
@@:
320
@@:
321
        mov     byte [edi+7], 80h   ; list end
321
        mov     byte [edi+7], 80h   ; list end
322
        pop     esi
322
        pop     esi
323
        pop     edi
323
        pop     edi
324
; select controller Primary or Secondary
324
; select controller Primary or Secondary
325
        mov     ecx, [IDE_controller_pointer]
325
        mov     ecx, [IDE_controller_pointer]
326
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
326
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
327
        mov     eax, [hdpos]
327
        mov     eax, [hdpos]
328
        dec     eax
328
        dec     eax
329
        test    eax, 10b
329
        test    eax, 10b
330
        jz      @f
330
        jz      @f
331
        add     edx, 8
331
        add     edx, 8
332
@@:
332
@@:
333
        add     edx, 2      ; Bus Master IDE Status register
333
        add     edx, 2      ; Bus Master IDE Status register
334
        mov     al, 6
334
        mov     al, 6
335
        out     dx, al      ; clear Error bit and Interrupt bit
335
        out     dx, al      ; clear Error bit and Interrupt bit
336
 
336
 
337
        add     edx, 2      ; Bus Master IDE PRD Table Address
337
        add     edx, 2      ; Bus Master IDE PRD Table Address
338
        mov     eax, edi
338
        mov     eax, edi
339
        call    get_pg_addr
339
        call    get_pg_addr
340
        out     dx, eax     ; send scatter-gather list physical address
340
        out     dx, eax     ; send scatter-gather list physical address
341
 
341
 
342
        push    edx
342
        push    edx
343
        mov     edx, [hdbase]
343
        mov     edx, [hdbase]
344
        add     edx, 7      ; ATACommand
344
        add     edx, 7      ; ATACommand
345
        mov     al, bl
345
        mov     al, bl
346
        out     dx, al      ; Start hard drive
346
        out     dx, al      ; Start hard drive
347
        pop     edx
347
        pop     edx
348
 
348
 
349
        sub     edx, 4      ; Bus Master IDE Command register
349
        sub     edx, 4      ; Bus Master IDE Command register
350
        mov     al, 1       ; set direction
350
        mov     al, 1       ; set direction
351
        cmp     bl, 35h     ; write
351
        cmp     bl, 35h     ; write
352
        jz      @f
352
        jz      @f
353
        add     al, 8       ; read
353
        add     al, 8       ; read
354
@@:
354
@@:
355
        out     dx, al      ; Start Bus Master
355
        out     dx, al      ; Start Bus Master
356
        mov     [IDE_common_irq_param], 14
356
        mov     [IDE_common_irq_param], 14
357
        mov     eax, [hdpos]
357
        mov     eax, [hdpos]
358
        dec     eax
358
        dec     eax
359
        test    eax, 10b
359
        test    eax, 10b
360
        jz      @f
360
        jz      @f
361
        inc     [IDE_common_irq_param]
361
        inc     [IDE_common_irq_param]
362
@@:
362
@@:
363
        push    edi esi ebx
363
        push    edi esi ebx
364
        xor     ecx, ecx
364
        xor     ecx, ecx
365
        xor     esi, esi
365
        xor     esi, esi
366
        call    create_event
366
        call    create_event
367
        mov     [eventPointer], eax
367
        mov     [eventPointer], eax
368
        mov     [eventID], edx
368
        mov     [eventID], edx
369
        sti
369
        sti
370
        mov     ebx, edx
370
        mov     ebx, edx
371
        mov     ecx, 300
371
        mov     ecx, 300
372
        call    wait_event_timeout
372
        call    wait_event_timeout
373
        test    eax, eax
373
        test    eax, eax
374
        jnz     @f
374
        jnz     @f
375
        mov     [IDE_common_irq_param], 0
375
        mov     [IDE_common_irq_param], 0
376
        mov     eax, [eventPointer]
376
        mov     eax, [eventPointer]
377
        mov     ebx, [eventID]
377
        mov     ebx, [eventID]
378
        call    destroy_event
378
        call    destroy_event
379
        mov     [eventPointer], 0
379
        mov     [eventPointer], 0
380
@@:
380
@@:
381
        pop     ebx esi
381
        pop     ebx esi
382
        call    kernel_free
382
        call    kernel_free
383
        cmp     [eventPointer], 0
383
        cmp     [eventPointer], 0
384
        jz      .hd_error
384
        jz      .hd_error
385
        ret
385
        ret
386
 
386
 
387
.LBA28:
387
.LBA28:
388
        mov     edx, [hdbase]
388
        mov     edx, [hdbase]
389
        add     edx, 6
389
        add     edx, 6
390
        mov     al, byte [hdid]
390
        mov     al, byte [hdid]
391
        add     al, 224
391
        add     al, 224
392
        out     dx, al  ; select the desired drive
392
        out     dx, al  ; select the desired drive
393
        call    save_hd_wait_timeout
393
        call    save_hd_wait_timeout
394
        inc     edx
394
        inc     edx
395
@@:
395
@@:
396
        call    check_hd_wait_timeout
396
        call    check_hd_wait_timeout
397
        jc      .hd_error
397
        jc      .hd_error
398
        in      al, dx
398
        in      al, dx
399
        test    al, 128 ; ready for command?
399
        test    al, 128 ; ready for command?
400
        jnz     @b
400
        jnz     @b
401
        pushfd          ; fill the ports
401
        pushfd          ; fill the ports
402
        cli
402
        cli
403
        mov     edx, [hdbase]
403
        mov     edx, [hdbase]
404
        inc     edx
404
        inc     edx
405
        inc     edx
405
        inc     edx
406
        mov     al, [blockSize]
406
        mov     al, [blockSize]
407
        out     dx, al  ; Sector count (7:0)
407
        out     dx, al  ; Sector count (7:0)
408
        inc     edx
408
        inc     edx
409
        mov     eax, [sector]
409
        mov     eax, [sector]
410
        out     dx, al  ; LBA (7:0)
410
        out     dx, al  ; LBA (7:0)
411
        inc     edx
411
        inc     edx
412
        shr     eax, 8
412
        shr     eax, 8
413
        out     dx, al  ; LBA (15:8)
413
        out     dx, al  ; LBA (15:8)
414
        inc     edx
414
        inc     edx
415
        shr     eax, 8
415
        shr     eax, 8
416
        out     dx, al  ; LBA (23:16)
416
        out     dx, al  ; LBA (23:16)
417
        inc     edx
417
        inc     edx
418
        shr     eax, 8
418
        shr     eax, 8
419
        add     al, byte [hdid]
419
        add     al, byte [hdid]
420
        add     al, 224
420
        add     al, 224
421
        out     dx, al  ; LBA (27:24)
421
        out     dx, al  ; LBA (27:24)
422
.PIO:
422
.PIO:
423
        inc     edx     ; ATACommand
423
        inc     edx     ; ATACommand
424
        mov     al, bl
424
        mov     al, bl
425
        out     dx, al  ; Start hard drive
425
        out     dx, al  ; Start hard drive
426
        popfd
426
        popfd
427
.sectorTransfer:
427
.sectorTransfer:
428
        call    save_hd_wait_timeout
428
        call    save_hd_wait_timeout
429
        in      al, dx
429
        in      al, dx
430
        in      al, dx
430
        in      al, dx
431
        in      al, dx
431
        in      al, dx
432
        in      al, dx
432
        in      al, dx
433
@@:
433
@@:
434
        call    check_hd_wait_timeout
434
        call    check_hd_wait_timeout
435
        jc      .hd_error
435
        jc      .hd_error
436
        in      al, dx
436
        in      al, dx
437
        test    al, 8   ; ready for transfer?
437
        test    al, 8   ; ready for transfer?
438
        jz      @b
438
        jz      @b
439
        cmp     [hd_setup], 1   ; do not mark error for setup request
439
        cmp     [hd_setup], 1   ; do not mark error for setup request
440
        jz      @f
440
        jz      @f
441
        test    al, 1   ; previous command ended up with an error
441
        test    al, 1   ; previous command ended up with an error
442
        jnz     .hd_error
442
        jnz     .hd_error
443
@@:
443
@@:
444
        pushfd
444
        pushfd
445
        cli
445
        cli
446
        cld
446
        cld
447
        mov     ecx, 256
447
        mov     ecx, 256
448
        mov     edx, [hdbase]
448
        mov     edx, [hdbase]
449
        cmp     bl, 30h
449
        cmp     bl, 30h
450
        jnc     .write
450
        jnc     .write
451
        rep insw
451
        rep insw
452
        jmp     @f
452
        jmp     @f
453
.write:
453
.write:
454
        rep outsw
454
        rep outsw
455
@@:
455
@@:
456
        popfd
456
        popfd
457
        add     edx, 7
457
        add     edx, 7
458
        dec     dword [blockSize]
458
        dec     dword [blockSize]
459
        jnz     .sectorTransfer
459
        jnz     .sectorTransfer
460
        ret
460
        ret
461
.hd_error:
461
.hd_error:
462
        cmp     bl, 30h
462
        cmp     bl, 30h
463
        jnc     hd_write_error
463
        jnc     hd_write_error
464
;-----------------------------------------------------------------
464
;-----------------------------------------------------------------
465
hd_read_error:
465
hd_read_error:
466
        if lang eq sp
466
        if lang eq sp
467
        DEBUGF 1,"K : FS - HD error de lectura\n"
467
        DEBUGF 1,"K : FS - HD error de lectura\n"
468
        else
468
        else
469
        DEBUGF 1,"K : FS - HD read error\n"
469
        DEBUGF 1,"K : FS - HD read error\n"
470
        end if
470
        end if
471
        stc
471
        stc
472
        ret
472
        ret
473
;-----------------------------------------------------------------
473
;-----------------------------------------------------------------
474
hd_write_error:
474
hd_write_error:
475
        if lang eq sp
475
        if lang eq sp
476
        DEBUGF 1,"K : FS - HD error de escritura\n"
476
        DEBUGF 1,"K : FS - HD error de escritura\n"
477
        else
477
        else
478
        DEBUGF 1,"K : FS - HD write error\n"
478
        DEBUGF 1,"K : FS - HD write error\n"
479
        end if
479
        end if
480
        stc
480
        stc
481
        ret
481
        ret
482
;-----------------------------------------------------------------
482
;-----------------------------------------------------------------
483
save_hd_wait_timeout:
483
save_hd_wait_timeout:
484
        mov     eax, [timer_ticks]
484
        mov     eax, [timer_ticks]
485
        add     eax, 300        ; 3 sec timeout
485
        add     eax, 300        ; 3 sec timeout
486
        mov     [hd_wait_timeout], eax
486
        mov     [hd_wait_timeout], eax
487
        ret
487
        ret
488
;-----------------------------------------------------------------
488
;-----------------------------------------------------------------
489
check_hd_wait_timeout:
489
check_hd_wait_timeout:
490
        mov     eax, [timer_ticks]
490
        mov     eax, [timer_ticks]
491
        cmp     [hd_wait_timeout], eax
491
        cmp     [hd_wait_timeout], eax
492
        jc      @f
492
        jc      @f
493
        ret
493
        ret
494
@@:
494
@@:
495
        if lang eq sp
495
        if lang eq sp
496
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
496
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
497
        else
497
        else
498
        DEBUGF 1,"K : FS - HD timeout\n"
498
        DEBUGF 1,"K : FS - HD timeout\n"
499
        end if
499
        end if
500
        stc
500
        stc
501
        ret
501
        ret
502
;-----------------------------------------------------------------
502
;-----------------------------------------------------------------
503
align 4
503
align 4
504
IDE_irq_14_handler:
504
IDE_irq_14_handler:
505
IDE_irq_15_handler:
505
IDE_irq_15_handler:
506
IDE_common_irq_handler:
506
IDE_common_irq_handler:
-
 
507
; Most of the time, we are here because we have requested
-
 
508
; a DMA transfer for the corresponding drive.
-
 
509
; However,
-
 
510
; a) we can be here because IDE IRQ is shared with some other device,
-
 
511
;    that device has actually raised IRQ,
-
 
512
;    it has nothing to do with IDE;
-
 
513
; b) we can be here because IDE controller just does not want
-
 
514
;    to be silent and reacts to something even though
-
 
515
;    we have, in theory, disabled IRQs.
-
 
516
; If the interrupt corresponds to our current request,
-
 
517
; remove the interrupt request and raise the event for the waiting code.
-
 
518
; In the case a), just return zero - not our interrupt.
-
 
519
; In the case b), remove the interrupt request and hope for the best.
507
; DEBUGF  1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2
520
; DEBUGF  1, 'K : IDE_irq_handler %x\n', [IDE_common_irq_param]:2
508
        cmp     [IDE_common_irq_param], 0
-
 
509
        jz      .exit
521
        mov     ecx, [esp+4]
510
        pushfd
-
 
511
        cli
-
 
512
        pushad
-
 
513
        mov     ecx, [IDE_controller_pointer]
-
 
514
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
522
        mov     dx, [ecx+IDE_DATA.RegsBaseAddres]
515
        cmp     [IDE_common_irq_param], 14
-
 
516
        jz      @f
-
 
517
        add     dx, 8
-
 
518
@@:
-
 
519
        add     edx, 2  ; Bus Master IDE Status register
523
        add     edx, 2  ; Bus Master IDE Status register
520
        in      al, dx
524
        in      al, dx
521
        test    al, 4
525
        test    al, 4
-
 
526
        jnz     .interrupt_from_primary
-
 
527
        add     edx, 8
522
        jz      @f
528
        in      al, dx
-
 
529
        test    al, 4
523
        mov     [IDE_common_irq_param], 0
530
        jnz     .interrupt_from_secondary
-
 
531
.exit_notour:
-
 
532
        xor     eax, eax ; not our interrupt
-
 
533
        ret
-
 
534
.interrupt_from_primary:
524
        out     dx, al  ; clear Interrupt bit
535
        out     dx, al  ; clear Interrupt bit
525
        sub     edx, 2
536
        sub     edx, 2
526
        xor     eax, eax
537
        xor     eax, eax
527
        out     dx, al  ; clear Bus Master IDE Command register
538
        out     dx, al  ; clear Bus Master IDE Command register
-
 
539
        mov     dx, [ecx+IDE_DATA.BAR0_val]
-
 
540
        add     edx, 7
-
 
541
        in      al, dx ; read status register
-
 
542
        cmp     [IDE_common_irq_param], 14
-
 
543
        jz      .raise
-
 
544
.exit_our:
-
 
545
        mov     al, 1
-
 
546
        ret
-
 
547
.interrupt_from_secondary:
-
 
548
        out     dx, al  ; clear Interrupt bit
-
 
549
        sub     edx, 2
528
        mov     edx, [hdbase]
550
        xor     eax, eax
-
 
551
        out     dx, al  ; clear Bus Master IDE Command register
-
 
552
        mov     dx, [ecx+IDE_DATA.BAR2_val]
529
        add     edx, 7
553
        add     edx, 7
530
        in      al, dx  ; read status register
554
        in      al, dx ; read status register
-
 
555
        cmp     [IDE_common_irq_param], 15
-
 
556
        jnz     .exit_our
-
 
557
.raise:
-
 
558
        cmp     ecx, [IDE_controller_pointer]
-
 
559
        jnz     .exit_our
-
 
560
        pushad
531
        mov     eax, [eventPointer]
561
        mov     eax, [eventPointer]
532
        mov     ebx, [eventID]
562
        mov     ebx, [eventID]
533
        xor     edx, edx
563
        xor     edx, edx
534
        xor     esi, esi
564
        xor     esi, esi
535
        call    raise_event
565
        call    raise_event
536
        popad
566
        popad
537
        popfd
-
 
538
        mov     al, 1   ; remove the interrupt request
567
        mov     al, 1   ; remove the interrupt request
539
        ret
568
        ret
540
@@:
-
 
541
        popad
-
 
542
        popfd
-
 
543
.exit:
-
 
544
        xor     eax, eax    ; not our interrupt
-
 
545
        ret
-
 
546
;-----------------------------------------------------------------
569
;-----------------------------------------------------------------
547
proc clear_pci_ide_interrupts
-
 
548
        mov     esi, pcidev_list
-
 
549
align 4
-
 
550
.loop:
-
 
551
        mov     esi, [esi+PCIDEV.fd]
-
 
552
        cmp     esi, pcidev_list
-
 
553
        jz      .done
-
 
554
 
-
 
555
;        cmp     [esi+PCIDEV.class], 0x01018F
-
 
556
        mov     eax, [esi+PCIDEV.class]
-
 
557
        shr     eax, 4
-
 
558
        cmp     eax, 0x01018
-
 
559
        jnz     .loop
-
 
560
 
-
 
561
        mov     ah, [esi+PCIDEV.bus]
-
 
562
        mov     al, 2
-
 
563
        mov     bh, [esi+PCIDEV.devfn]
-
 
564
        mov     bl, 0x20
-
 
565
        call    pci_read_reg
-
 
566
 
-
 
567
        and     eax, 0FFFCh
-
 
568
        mov     edx, eax
-
 
569
        add     edx, 2
-
 
570
        in      al, dx
-
 
571
        DEBUGF 1,'K : clear_pci_ide_interrupts: port[%x] = %x ',dx,al
-
 
572
        out     dx, al
-
 
573
        in      al, dx
-
 
574
        DEBUGF 1,'-> %x; ',al
-
 
575
        add     edx, 8
-
 
576
        in      al, dx
-
 
577
        DEBUGF 1,'port[%x] = %x ',dx,al
-
 
578
        out     dx, al
-
 
579
        in      al, dx
-
 
580
        DEBUGF 1,'-> %x\n',al
-
 
581
        jmp     .loop
-
 
582
.done:
-
 
583
        ret
-
 
584
endp
-