Rev 2434 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2434 | Rev 2465 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. 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 | ;driver sceletone |
8 | ;driver sceletone |
9 | 9 | ||
10 | format MS COFF |
10 | format MS COFF |
11 | 11 | ||
12 | API_VERSION equ 0 ;debug |
12 | API_VERSION equ 0 ;debug |
13 | 13 | ||
14 | include '../proc32.inc' |
14 | include '../proc32.inc' |
15 | include '../imports.inc' |
15 | include '../imports.inc' |
16 | include 'urb.inc' |
16 | include 'urb.inc' |
17 | 17 | ||
18 | struc UHCI |
18 | struc UHCI |
19 | { |
19 | { |
20 | .bus dd ? |
20 | .bus dd ? |
21 | .devfn dd ? |
21 | .devfn dd ? |
22 | .io_base dd ? |
22 | .io_base dd ? |
23 | .mm_base dd ? |
23 | .mm_base dd ? |
24 | .irq dd ? |
24 | .irq dd ? |
25 | .flags dd ? |
25 | .flags dd ? |
26 | .reset dd ? |
26 | .reset dd ? |
27 | .start dd ? |
27 | .start dd ? |
28 | .stop dd ? |
28 | .stop dd ? |
29 | 29 | ||
30 | .port_c_suspend dd ? |
30 | .port_c_suspend dd ? |
31 | .resuming_ports dd ? |
31 | .resuming_ports dd ? |
32 | .rh_state dd ? |
32 | .rh_state dd ? |
33 | .rh_numports dd ? |
33 | .rh_numports dd ? |
34 | .is_stopped dd ? |
34 | .is_stopped dd ? |
35 | .dead dd ? |
35 | .dead dd ? |
36 | 36 | ||
37 | .sizeof: |
37 | .sizeof: |
38 | } |
38 | } |
39 | 39 | ||
40 | virtual at 0 |
40 | virtual at 0 |
41 | UHCI UHCI |
41 | UHCI UHCI |
42 | end virtual |
42 | end virtual |
43 | 43 | ||
44 | struc IOCTL |
44 | struc IOCTL |
45 | { .handle dd ? |
45 | { .handle dd ? |
46 | .io_code dd ? |
46 | .io_code dd ? |
47 | .input dd ? |
47 | .input dd ? |
48 | .inp_size dd ? |
48 | .inp_size dd ? |
49 | .output dd ? |
49 | .output dd ? |
50 | .out_size dd ? |
50 | .out_size dd ? |
51 | } |
51 | } |
52 | 52 | ||
53 | virtual at 0 |
53 | virtual at 0 |
54 | IOCTL IOCTL |
54 | IOCTL IOCTL |
55 | end virtual |
55 | end virtual |
56 | 56 | ||
57 | struc TD ;transfer descriptor |
57 | struc TD ;transfer descriptor |
58 | { |
58 | { |
59 | .link dd ? |
59 | .link dd ? |
60 | .status dd ? |
60 | .status dd ? |
61 | .token dd ? |
61 | .token dd ? |
62 | .buffer dd ? |
62 | .buffer dd ? |
63 | 63 | ||
64 | .addr dd ? |
64 | .addr dd ? |
65 | .frame dd ? |
65 | .frame dd ? |
66 | .fd dd ? |
66 | .fd dd ? |
67 | .bk dd ? |
67 | .bk dd ? |
68 | .sizeof: |
68 | .sizeof: |
69 | } |
69 | } |
70 | 70 | ||
71 | virtual at 0 |
71 | virtual at 0 |
72 | TD TD |
72 | TD TD |
73 | end virtual |
73 | end virtual |
74 | 74 | ||
75 | public START |
75 | public START |
76 | public service_proc |
76 | public service_proc |
77 | public version |
77 | public version |
78 | 78 | ||
79 | DEBUG equ 1 |
79 | DEBUG equ 1 |
80 | 80 | ||
81 | DRV_ENTRY equ 1 |
81 | DRV_ENTRY equ 1 |
82 | DRV_EXIT equ -1 |
82 | DRV_EXIT equ -1 |
83 | STRIDE equ 4 ;size of row in devices table |
83 | STRIDE equ 4 ;size of row in devices table |
84 | 84 | ||
85 | SRV_GETVERSION equ 0 |
85 | SRV_GETVERSION equ 0 |
86 | 86 | ||
87 | section '.flat' code readable align 16 |
87 | section '.flat' code readable align 16 |
88 | 88 | ||
89 | proc START stdcall, state:dword |
89 | proc START stdcall, state:dword |
90 | 90 | ||
91 | cmp [state], 1 |
91 | cmp [state], 1 |
92 | jne .exit |
92 | jne .exit |
93 | .entry: |
93 | .entry: |
94 | 94 | ||
95 | if DEBUG |
95 | if DEBUG |
96 | mov esi, msgInit |
96 | mov esi, msgInit |
97 | call SysMsgBoardStr |
97 | call SysMsgBoardStr |
98 | end if |
98 | end if |
99 | 99 | ||
100 | call init |
100 | call init |
101 | 101 | ||
102 | stdcall RegService, my_service, service_proc |
102 | stdcall RegService, my_service, service_proc |
103 | ret |
103 | ret |
104 | .fail: |
104 | .fail: |
105 | .exit: |
105 | .exit: |
106 | xor eax, eax |
106 | xor eax, eax |
107 | ret |
107 | ret |
108 | endp |
108 | endp |
109 | 109 | ||
110 | handle equ IOCTL.handle |
110 | handle equ IOCTL.handle |
111 | io_code equ IOCTL.io_code |
111 | io_code equ IOCTL.io_code |
112 | input equ IOCTL.input |
112 | input equ IOCTL.input |
113 | inp_size equ IOCTL.inp_size |
113 | inp_size equ IOCTL.inp_size |
114 | output equ IOCTL.output |
114 | output equ IOCTL.output |
115 | out_size equ IOCTL.out_size |
115 | out_size equ IOCTL.out_size |
116 | 116 | ||
117 | align 4 |
117 | align 4 |
118 | proc service_proc stdcall, ioctl:dword |
118 | proc service_proc stdcall, ioctl:dword |
119 | 119 | ||
120 | mov ebx, [ioctl] |
120 | mov ebx, [ioctl] |
121 | mov eax, [ebx+io_code] |
121 | mov eax, [ebx+io_code] |
122 | cmp eax, SRV_GETVERSION |
122 | cmp eax, SRV_GETVERSION |
123 | jne @F |
123 | jne @F |
124 | 124 | ||
125 | mov eax, [ebx+output] |
125 | mov eax, [ebx+output] |
126 | cmp [ebx+out_size], 4 |
126 | cmp [ebx+out_size], 4 |
127 | jne .fail |
127 | jne .fail |
128 | mov [eax], dword API_VERSION |
128 | mov [eax], dword API_VERSION |
129 | xor eax, eax |
129 | xor eax, eax |
130 | ret |
130 | ret |
131 | @@: |
131 | @@: |
132 | .fail: |
132 | .fail: |
133 | or eax, -1 |
133 | or eax, -1 |
134 | ret |
134 | ret |
135 | endp |
135 | endp |
136 | 136 | ||
137 | restore handle |
137 | restore handle |
138 | restore io_code |
138 | restore io_code |
139 | restore input |
139 | restore input |
140 | restore inp_size |
140 | restore inp_size |
141 | restore output |
141 | restore output |
142 | restore out_size |
142 | restore out_size |
143 | 143 | ||
144 | align 4 |
144 | align 4 |
145 | proc detect |
145 | proc detect |
146 | locals |
146 | locals |
147 | last_bus dd ? |
147 | last_bus dd ? |
148 | bus dd ? |
148 | bus dd ? |
149 | devfn dd ? |
149 | devfn dd ? |
150 | endl |
150 | endl |
151 | 151 | ||
152 | xor eax, eax |
152 | xor eax, eax |
153 | mov [bus], eax |
153 | mov [bus], eax |
154 | inc eax |
154 | inc eax |
155 | call PciApi |
155 | call PciApi |
156 | cmp eax, -1 |
156 | cmp eax, -1 |
157 | je .err |
157 | je .err |
158 | 158 | ||
159 | mov [last_bus], eax |
159 | mov [last_bus], eax |
160 | 160 | ||
161 | .next_bus: |
161 | .next_bus: |
162 | and [devfn], 0 |
162 | and [devfn], 0 |
163 | .next_dev: |
163 | .next_dev: |
164 | stdcall PciRead32, [bus], [devfn], dword 0 |
164 | stdcall PciRead32, [bus], [devfn], dword 0 |
165 | test eax, eax |
165 | test eax, eax |
166 | jz .next |
166 | jz .next |
167 | cmp eax, -1 |
167 | cmp eax, -1 |
168 | je .next |
168 | je .next |
169 | 169 | ||
170 | mov edi, devices |
170 | mov edi, devices |
171 | @@: |
171 | @@: |
172 | mov ebx, [edi] |
172 | mov ebx, [edi] |
173 | test ebx, ebx |
173 | test ebx, ebx |
174 | jz .next |
174 | jz .next |
175 | 175 | ||
176 | cmp eax, ebx |
176 | cmp eax, ebx |
177 | je .found |
177 | je .found |
178 | 178 | ||
179 | add edi, STRIDE |
179 | add edi, STRIDE |
180 | jmp @B |
180 | jmp @B |
181 | .next: |
181 | .next: |
182 | inc [devfn] |
182 | inc [devfn] |
183 | cmp [devfn], 256 |
183 | cmp [devfn], 256 |
184 | jb .next_dev |
184 | jb .next_dev |
185 | mov eax, [bus] |
185 | mov eax, [bus] |
186 | inc eax |
186 | inc eax |
187 | mov [bus], eax |
187 | mov [bus], eax |
188 | cmp eax, [last_bus] |
188 | cmp eax, [last_bus] |
189 | jna .next_bus |
189 | jna .next_bus |
190 | xor eax, eax |
190 | xor eax, eax |
191 | ret |
191 | ret |
192 | .found: |
192 | .found: |
193 | mov eax, UHCI.sizeof |
193 | mov eax, UHCI.sizeof |
194 | call Kmalloc |
194 | call Kmalloc |
195 | test eax, eax |
195 | test eax, eax |
196 | jz .mem_fail |
196 | jz .mem_fail |
197 | 197 | ||
198 | mov ebx, [bus] |
198 | mov ebx, [bus] |
199 | mov [eax+UHCI.bus], ebx |
199 | mov [eax+UHCI.bus], ebx |
200 | 200 | ||
201 | mov ecx, [devfn] |
201 | mov ecx, [devfn] |
202 | mov [eax+UHCI.devfn], ecx |
202 | mov [eax+UHCI.devfn], ecx |
203 | ret |
203 | ret |
204 | .mem_fail: |
204 | .mem_fail: |
205 | if DEBUG |
205 | if DEBUG |
206 | mov esi, msgMemFail |
206 | mov esi, msgMemFail |
207 | call SysMsgBoardStr |
207 | call SysMsgBoardStr |
208 | end if |
208 | end if |
209 | .err: |
209 | .err: |
210 | xor eax, eax |
210 | xor eax, eax |
211 | ret |
211 | ret |
212 | endp |
212 | endp |
213 | 213 | ||
214 | PCI_BASE equ 0x20 |
214 | PCI_BASE equ 0x20 |
215 | USB_LEGKEY equ 0xC0 |
215 | USB_LEGKEY equ 0xC0 |
216 | 216 | ||
217 | align 4 |
217 | align 4 |
218 | proc init |
218 | proc init |
219 | locals |
219 | locals |
220 | uhci dd ? |
220 | uhci dd ? |
221 | endl |
221 | endl |
222 | 222 | ||
223 | call detect |
223 | call detect |
224 | test eax, eax |
224 | test eax, eax |
225 | jz .fail |
225 | jz .fail |
226 | 226 | ||
227 | mov [uhci], eax |
227 | mov [uhci], eax |
228 | 228 | ||
229 | stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE |
229 | stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE |
230 | and eax, 0xFFC0 |
230 | and eax, 0xFFC0 |
231 | mov esi, [uhci] |
231 | mov esi, [uhci] |
232 | mov [esi+UHCI.io_base], eax |
232 | mov [esi+UHCI.io_base], eax |
233 | 233 | ||
234 | stdcall uhci_reset, esi |
234 | stdcall uhci_reset, esi |
235 | 235 | ||
236 | stdcall finish_reset, [uhci] |
236 | stdcall finish_reset, [uhci] |
237 | 237 | ||
238 | .fail: |
238 | .fail: |
239 | if DEBUG |
239 | if DEBUG |
240 | mov esi, msgDevNotFound |
240 | mov esi, msgDevNotFound |
241 | call SysMsgBoardStr |
241 | call SysMsgBoardStr |
242 | end if |
242 | end if |
243 | ret |
243 | ret |
244 | endp |
244 | endp |
245 | 245 | ||
246 | UHCI_USBINTR equ 4 ; interrupt register |
246 | UHCI_USBINTR equ 4 ; interrupt register |
247 | 247 | ||
248 | UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits |
248 | UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits |
249 | UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits |
249 | UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits |
250 | 250 | ||
251 | UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit |
251 | UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit |
252 | UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset |
252 | UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset |
253 | UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode |
253 | UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode |
254 | UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag |
254 | UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag |
255 | UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable |
255 | UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable |
256 | 256 | ||
257 | PORTSC0 equ 0x10 |
257 | PORTSC0 equ 0x10 |
258 | PORTSC1 equ 0x12 |
258 | PORTSC1 equ 0x12 |
259 | 259 | ||
260 | 260 | ||
261 | UHCI_RH_RESET equ 0 |
261 | UHCI_RH_RESET equ 0 |
262 | UHCI_RH_SUSPENDED equ 1 |
262 | UHCI_RH_SUSPENDED equ 1 |
263 | UHCI_RH_AUTO_STOPPED equ 2 |
263 | UHCI_RH_AUTO_STOPPED equ 2 |
264 | UHCI_RH_RESUMING equ 3 |
264 | UHCI_RH_RESUMING equ 3 |
265 | 265 | ||
266 | ; In this state the HC changes from running to halted |
266 | ; In this state the HC changes from running to halted |
267 | ; so it can legally appear either way. |
267 | ; so it can legally appear either way. |
268 | UHCI_RH_SUSPENDING equ 4 |
268 | UHCI_RH_SUSPENDING equ 4 |
269 | 269 | ||
270 | ; In the following states it's an error if the HC is halted. |
270 | ; In the following states it's an error if the HC is halted. |
271 | ; These two must come last. |
271 | ; These two must come last. |
272 | UHCI_RH_RUNNING equ 5 ; The normal state |
272 | UHCI_RH_RUNNING equ 5 ; The normal state |
273 | UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices |
273 | UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices |
274 | 274 | ||
275 | UHCI_IS_STOPPED equ 9999 |
275 | UHCI_IS_STOPPED equ 9999 |
276 | 276 | ||
277 | align 4 |
277 | align 4 |
278 | proc uhci_reset stdcall, uhci:dword |
278 | proc uhci_reset stdcall, uhci:dword |
279 | mov esi, [uhci] |
279 | mov esi, [uhci] |
280 | stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY |
280 | stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY |
281 | test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC) |
281 | test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC) |
282 | jnz .reset |
282 | jnz .reset |
283 | 283 | ||
284 | mov edx, [esi+UHCI.io_base] |
284 | mov edx, [esi+UHCI.io_base] |
285 | in ax, dx |
285 | in ax, dx |
286 | test ax, UHCI_USBCMD_RUN |
286 | test ax, UHCI_USBCMD_RUN |
287 | jnz .reset |
287 | jnz .reset |
288 | 288 | ||
289 | test ax, UHCI_USBCMD_CONFIGURE |
289 | test ax, UHCI_USBCMD_CONFIGURE |
290 | jz .reset |
290 | jz .reset |
291 | 291 | ||
292 | test ax, UHCI_USBCMD_EGSM |
292 | test ax, UHCI_USBCMD_EGSM |
293 | jz .reset |
293 | jz .reset |
294 | 294 | ||
295 | add edx, UHCI_USBINTR |
295 | add edx, UHCI_USBINTR |
296 | in ax, dx |
296 | in ax, dx |
297 | test ax, not UHCI_USBINTR_RESUME |
297 | test ax, not UHCI_USBINTR_RESUME |
298 | jnz .reset |
298 | jnz .reset |
299 | ret |
299 | ret |
300 | .reset: |
300 | .reset: |
301 | stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC |
301 | stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC |
302 | 302 | ||
303 | mov edx, [esi+UHCI.io_base] |
303 | mov edx, [esi+UHCI.io_base] |
304 | mov ax, UHCI_USBCMD_HCRESET |
304 | mov ax, UHCI_USBCMD_HCRESET |
305 | out dx, ax |
305 | out dx, ax |
306 | 306 | ||
307 | xor eax, eax |
307 | xor eax, eax |
308 | out dx, ax |
308 | out dx, ax |
309 | add edx, UHCI_USBINTR |
309 | add edx, UHCI_USBINTR |
310 | out dx, ax |
310 | out dx, ax |
311 | ret |
311 | ret |
312 | endp |
312 | endp |
313 | 313 | ||
314 | proc finish_reset stdcall, uhci:dword |
314 | proc finish_reset stdcall, uhci:dword |
315 | 315 | ||
316 | mov esi, [uhci] |
316 | mov esi, [uhci] |
317 | mov edx, [esi+UHCI.io_base] |
317 | mov edx, [esi+UHCI.io_base] |
318 | add edx, PORTSC0 |
318 | add edx, PORTSC0 |
319 | xor eax, eax |
319 | xor eax, eax |
320 | out dx, ax |
320 | out dx, ax |
321 | add edx, (PORTSC1-PORTSC0) |
321 | add edx, (PORTSC1-PORTSC0) |
322 | out dx, ax |
322 | out dx, ax |
323 | 323 | ||
324 | mov [esi+UHCI.port_c_suspend], eax |
324 | mov [esi+UHCI.port_c_suspend], eax |
325 | mov [esi+UHCI.resuming_ports], eax |
325 | mov [esi+UHCI.resuming_ports], eax |
326 | mov [esi+UHCI.rh_state], UHCI_RH_RESET |
326 | mov [esi+UHCI.rh_state], UHCI_RH_RESET |
327 | mov [esi+UHCI.rh_numports], 2 |
327 | mov [esi+UHCI.rh_numports], 2 |
328 | 328 | ||
329 | mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED |
329 | mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED |
330 | ; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT; |
330 | ; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT; |
331 | ; uhci_to_hcd(uhci)->poll_rh = 0; |
331 | ; uhci_to_hcd(uhci)->poll_rh = 0; |
332 | 332 | ||
333 | mov [esi+UHCI.dead], eax ; Full reset resurrects the controller |
333 | mov [esi+UHCI.dead], eax ; Full reset resurrects the controller |
334 | 334 | ||
335 | ret |
335 | ret |
336 | endp |
336 | endp |
337 | 337 | ||
338 | proc insert_td stdcall, td:dword, frame:dword |
338 | proc insert_td stdcall, td:dword, frame:dword |
339 | 339 | ||
340 | mov edi, [td] |
340 | mov edi, [td] |
341 | mov eax, [frame] |
341 | mov eax, [frame] |
342 | and eax, -1024 |
342 | and eax, -1024 |
343 | mov [edi+TD.frame], eax |
343 | mov [edi+TD.frame], eax |
344 | 344 | ||
345 | mov ebx, [framelist] |
345 | mov ebx, [framelist] |
346 | mov edx, [dma_framelist] |
346 | mov edx, [dma_framelist] |
347 | shl eax, 5 |
347 | shl eax, 5 |
348 | 348 | ||
349 | mov ecx, [eax+ebx] |
349 | mov ecx, [eax+ebx] |
350 | test ecx, ecx |
350 | test ecx, ecx |
351 | jz .empty |
351 | jz .empty |
352 | 352 | ||
353 | mov ecx, [ecx+TD.bk] ;last TD |
353 | mov ecx, [ecx+TD.bk] ;last TD |
354 | 354 | ||
355 | mov edx, [ecx+TD.fd] |
355 | mov edx, [ecx+TD.fd] |
356 | mov [edi+TD.fd], edx |
356 | mov [edi+TD.fd], edx |
357 | mov [edi+TD.bk], ecx |
357 | mov [edi+TD.bk], ecx |
358 | mov [ecx+TD.fd], edi |
358 | mov [ecx+TD.fd], edi |
359 | mov [edx+TD.bk], edi |
359 | mov [edx+TD.bk], edi |
360 | 360 | ||
361 | mov eax, [ecx+TD.link] |
361 | mov eax, [ecx+TD.link] |
362 | mov [edi+TD.link], eax |
362 | mov [edi+TD.link], eax |
363 | mov ebx, [edi+TD.addr] |
363 | mov ebx, [edi+TD.addr] |
364 | mov [ecx+TD.link], ebx |
364 | mov [ecx+TD.link], ebx |
365 | ret |
365 | ret |
366 | .empty: |
366 | .empty: |
367 | mov ecx, [eax+edx] |
367 | mov ecx, [eax+edx] |
368 | mov [edi+TD.link], ecx |
368 | mov [edi+TD.link], ecx |
369 | mov [ebx+eax], edi |
369 | mov [ebx+eax], edi |
370 | mov ecx, [edi+TD.addr] |
370 | mov ecx, [edi+TD.addr] |
371 | mov [eax+edx], ecx |
371 | mov [eax+edx], ecx |
372 | ret |
372 | ret |
373 | endp |
373 | endp |
374 | 374 | ||
375 | 375 | ||
376 | align 4 |
376 | align 4 |
377 | proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\ |
377 | proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\ |
378 | buf:dword, size:dword |
378 | buf:dword, size:dword |
379 | 379 | ||
380 | locals |
380 | locals |
381 | count dd ? |
381 | count dd ? |
382 | endl |
382 | endl |
383 | 383 | ||
384 | mov esi, [buf] |
384 | mov esi, [buf] |
385 | mov ecx, [size] |
385 | mov ecx, [size] |
386 | xor eax, eax |
386 | xor eax, eax |
387 | cld |
387 | cld |
388 | rep stosb |
388 | rep stosb |
389 | 389 | ||
390 | mov [count], 3 |
390 | mov [count], 3 |
391 | @@: |
391 | @@: |
392 | mov eax, [type] |
392 | mov eax, [type] |
393 | shl eax, 8 |
393 | shl eax, 8 |
394 | add eax, [index] |
394 | add eax, [index] |
395 | stdcall usb_control_msg, [dev], pipe, USB_REQ_GET_DESCRIPTOR, \ |
395 | stdcall usb_control_msg, [dev], pipe, USB_REQ_GET_DESCRIPTOR, \ |
396 | USB_DIR_IN, eax,0,[buf], [size],\ |
396 | USB_DIR_IN, eax,0,[buf], [size],\ |
397 | USB_CTRL_GET_TIMEOUT |
397 | USB_CTRL_GET_TIMEOUT |
398 | test eax, eax |
398 | test eax, eax |
399 | jz .next |
399 | jz .next |
400 | cmp eax, -1 |
400 | cmp eax, -1 |
401 | je .next |
401 | je .next |
402 | jmp. ok |
402 | jmp. ok |
403 | .next: |
403 | .next: |
404 | dec [count] |
404 | dec [count] |
405 | jnz @B |
405 | jnz @B |
406 | mov eax, -1 |
406 | mov eax, -1 |
407 | .ok: |
407 | .ok: |
408 | ret |
408 | ret |
409 | endp |
409 | endp |
410 | 410 | ||
411 | DEVICE_ID equ 0x24D2 ; pci device id |
411 | DEVICE_ID equ 0x24D2 ; pci device id |
412 | VENDOR_ID equ 0x8086 ; device vendor id |
412 | VENDOR_ID equ 0x8086 ; device vendor id |
413 | QEMU_USB equ 0x7020 |
413 | QEMU_USB equ 0x7020 |
414 | 414 | ||
415 | ;all initialized data place here |
415 | ;all initialized data place here |
416 | 416 | ||
417 | align 4 |
417 | align 4 |
418 | devices dd (DEVICE_ID shl 16)+VENDOR_ID |
418 | devices dd (DEVICE_ID shl 16)+VENDOR_ID |
419 | dd (QEMU_USB shl 16)+VENDOR_ID |
419 | dd (QEMU_USB shl 16)+VENDOR_ID |
420 | dd 0 ;terminator |
420 | dd 0 ;terminator |
421 | 421 | ||
422 | version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
422 | version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
423 | 423 | ||
424 | my_service db 'UHCI',0 ;max 16 chars include zero |
424 | my_service db 'UHCI',0 ;max 16 chars include zero |
425 | 425 | ||
426 | msgInit db 'detect hardware...',13,10,0 |
426 | msgInit db 'detect hardware...',13,10,0 |
427 | msgPCI db 'PCI accsess not supported',13,10,0 |
427 | msgPCI db 'PCI accsess not supported',13,10,0 |
428 | msgDevNotFound db 'device not found',13,10,0 |
428 | msgDevNotFound db 'device not found',13,10,0 |
429 | msgMemFail db 'Kmalloc failed', 10,10,0 |
429 | msgMemFail db 'Kmalloc failed', 10,10,0 |
430 | ;msgFail db 'device not found',13,10,0 |
430 | ;msgFail db 'device not found',13,10,0 |
431 | 431 | ||
432 | section '.data' data readable writable align 16 |
432 | section '.data' data readable writable align 16 |
433 | 433 | ||
434 | ;all uninitialized data place here |
434 | ;all uninitialized data place here |