Rev 4265 | Rev 5201 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4265 | Rev 4423 | ||
---|---|---|---|
Line 217... | Line 217... | ||
217 | dd ? ; return address |
217 | dd ? ; return address |
218 | .pipe dd ? ; handle of the config pipe |
218 | .pipe dd ? ; handle of the config pipe |
219 | .config dd ? ; pointer to usb_config_descr |
219 | .config dd ? ; pointer to usb_config_descr |
220 | .interface dd ? ; pointer to usb_interface_descr |
220 | .interface dd ? ; pointer to usb_interface_descr |
221 | end virtual |
221 | end virtual |
- | 222 | ; 1. Check that the maximal nesting is not exceeded: |
|
- | 223 | ; 5 non-root hubs is the maximum according to the spec. |
|
- | 224 | mov ebx, [.pipe] |
|
- | 225 | push 5 |
|
- | 226 | mov eax, ebx |
|
- | 227 | .count_parents: |
|
- | 228 | mov eax, [eax+usb_pipe.DeviceData] |
|
- | 229 | mov eax, [eax+usb_device_data.Hub] |
|
- | 230 | test eax, eax |
|
- | 231 | jz .depth_ok |
|
- | 232 | mov eax, [eax+usb_hub.ConfigPipe] |
|
- | 233 | dec dword [esp] |
|
- | 234 | jnz .count_parents |
|
- | 235 | pop eax |
|
- | 236 | dbgstr 'Hub chain is too long' |
|
- | 237 | jmp .return0 |
|
- | 238 | .depth_ok: |
|
- | 239 | pop eax |
|
222 | ; Hubs use one IN interrupt endpoint for polling the device |
240 | ; Hubs use one IN interrupt endpoint for polling the device |
223 | ; 1. Locate the descriptor of the interrupt endpoint. |
241 | ; 2. Locate the descriptor of the interrupt endpoint. |
224 | ; Loop over all descriptors owned by this interface. |
242 | ; Loop over all descriptors owned by this interface. |
225 | .lookep: |
243 | .lookep: |
226 | ; 1a. Skip the current descriptor. |
244 | ; 2a. Skip the current descriptor. |
227 | movzx eax, [edx+usb_descr.bLength] |
245 | movzx eax, [edx+usb_descr.bLength] |
228 | add edx, eax |
246 | add edx, eax |
229 | sub ecx, eax |
247 | sub ecx, eax |
230 | jb .errorep |
248 | jb .errorep |
231 | ; 1b. Length of data left must be at least sizeof.usb_endpoint_descr. |
249 | ; 2b. Length of data left must be at least sizeof.usb_endpoint_descr. |
232 | cmp ecx, sizeof.usb_endpoint_descr |
250 | cmp ecx, sizeof.usb_endpoint_descr |
233 | jb .errorep |
251 | jb .errorep |
234 | ; 1c. If we have found another interface descriptor but not found our endpoint, |
252 | ; 2c. If we have found another interface descriptor but not found our endpoint, |
235 | ; this is an error: all subsequent descriptors belong to that interface |
253 | ; this is an error: all subsequent descriptors belong to that interface |
236 | ; (or further interfaces). |
254 | ; (or further interfaces). |
237 | cmp [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR |
255 | cmp [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR |
238 | jz .errorep |
256 | jz .errorep |
239 | ; 1d. Ignore all interface-related descriptors except endpoint descriptor. |
257 | ; 2d. Ignore all interface-related descriptors except endpoint descriptor. |
240 | cmp [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR |
258 | cmp [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR |
241 | jnz .lookep |
259 | jnz .lookep |
242 | ; 1e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr. |
260 | ; 2e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr. |
243 | cmp [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr |
261 | cmp [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr |
244 | jb .errorep |
262 | jb .errorep |
245 | ; 1f. Ignore all endpoints except for INTERRUPT IN. |
263 | ; 2f. Ignore all endpoints except for INTERRUPT IN. |
246 | cmp [edx+usb_endpoint_descr.bEndpointAddress], 0 |
264 | cmp [edx+usb_endpoint_descr.bEndpointAddress], 0 |
247 | jge .lookep |
265 | jge .lookep |
248 | mov al, [edx+usb_endpoint_descr.bmAttributes] |
266 | mov al, [edx+usb_endpoint_descr.bmAttributes] |
249 | and al, 3 |
267 | and al, 3 |
250 | cmp al, INTERRUPT_PIPE |
268 | cmp al, INTERRUPT_PIPE |
251 | jnz .lookep |
269 | jnz .lookep |
252 | ; We have located the descriptor for INTERRUPT IN endpoint, |
270 | ; We have located the descriptor for INTERRUPT IN endpoint, |
253 | ; the pointer is in edx. |
271 | ; the pointer is in edx. |
254 | ; 2. Allocate memory for the hub descriptor. |
272 | ; 3. Allocate memory for the hub descriptor. |
255 | ; Maximum length (assuming 255 downstream ports) is 40 bytes. |
273 | ; Maximum length (assuming 255 downstream ports) is 40 bytes. |
256 | ; Allocate 4 extra bytes to keep wMaxPacketSize. |
274 | ; Allocate 4 extra bytes to keep wMaxPacketSize. |
257 | ; 2a. Save registers. |
275 | ; 3a. Save registers. |
258 | push edx |
276 | push edx |
259 | ; 2b. Call the allocator. |
277 | ; 3b. Call the allocator. |
260 | movi eax, 44 |
278 | movi eax, 44 |
261 | call malloc |
279 | call malloc |
262 | ; 2c. Restore registers. |
280 | ; 3c. Restore registers. |
263 | pop ecx |
281 | pop ecx |
264 | ; 2d. If failed, say something to the debug board and return error. |
282 | ; 3d. If failed, say something to the debug board and return error. |
265 | test eax, eax |
283 | test eax, eax |
266 | jz .nomemory |
284 | jz .nomemory |
267 | ; 2e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov. |
285 | ; 3e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov. |
268 | xchg esi, eax |
286 | xchg esi, eax |
269 | ; 3. Open a pipe for the status endpoint with descriptor found in step 1. |
287 | ; 4. Open a pipe for the status endpoint with descriptor found in step 1. |
270 | mov ebx, [.pipe] |
- | |
271 | movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress] |
288 | movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress] |
272 | movzx edx, [ecx+usb_endpoint_descr.bInterval] |
289 | movzx edx, [ecx+usb_endpoint_descr.bInterval] |
273 | movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize] |
290 | movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize] |
274 | test ecx, (1 shl 11) - 1 |
291 | test ecx, (1 shl 11) - 1 |
275 | jz .free |
292 | jz .free |
276 | push ecx |
293 | push ecx |
277 | stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx |
294 | stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx |
278 | pop ecx |
295 | pop ecx |
279 | ; If failed, free the memory allocated in step 2, |
296 | ; If failed, free the memory allocated in step 3, |
280 | ; say something to the debug board and return error. |
297 | ; say something to the debug board and return error. |
281 | test eax, eax |
298 | test eax, eax |
282 | jz .free |
299 | jz .free |
283 | ; 4. Send control query for the hub descriptor, |
300 | ; 5. Send control query for the hub descriptor, |
284 | ; pass status pipe as a callback parameter, |
301 | ; pass status pipe as a callback parameter, |
285 | ; allow short packets. |
302 | ; allow short packets. |
286 | and ecx, (1 shl 11) - 1 |
303 | and ecx, (1 shl 11) - 1 |
287 | mov [esi+40], ecx |
304 | mov [esi+40], ecx |
288 | mov dword [esi], 0xA0 + \ ; class-specific request |
305 | mov dword [esi], 0xA0 + \ ; class-specific request |
289 | (USB_GET_DESCRIPTOR shl 8) + \ |
306 | (USB_GET_DESCRIPTOR shl 8) + \ |
290 | (0 shl 16) + \ ; descriptor index 0 |
307 | (0 shl 16) + \ ; descriptor index 0 |
291 | (USB_HUB_DESCRIPTOR shl 24) |
308 | (USB_HUB_DESCRIPTOR shl 24) |
292 | mov dword [esi+4], 40 shl 16 |
309 | mov dword [esi+4], 40 shl 16 |
293 | stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1 |
310 | stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1 |
294 | ; 5. If failed, free the memory allocated in step 2, |
311 | ; 6. If failed, free the memory allocated in step 3, |
295 | ; say something to the debug board and return error. |
312 | ; say something to the debug board and return error. |
296 | test eax, eax |
313 | test eax, eax |
297 | jz .free |
314 | jz .free |
298 | ; Otherwise, return 1. usb_hub_got_config will overwrite it later. |
315 | ; Otherwise, return 1. usb_hub_got_config will overwrite it later. |
299 | xor eax, eax |
316 | xor eax, eax |
Line 1243... | Line 1260... | ||
1243 | call free |
1260 | call free |
1244 | pop ebx |
1261 | pop ebx |
1245 | .nothing: |
1262 | .nothing: |
1246 | retn 4 |
1263 | retn 4 |
1247 | endp>=> |
1264 | endp |
- | 1265 | ||
- | 1266 | ; Helper function for USB2 scheduler. |
|
- | 1267 | ; in: eax -> usb_hub |
|
- | 1268 | ; out: ecx = TT think time for the hub in FS-bytes |
|
- | 1269 | proc usb_get_tt_think_time |
|
- | 1270 | movzx ecx, [eax+usb_hub.HubCharacteristics] |
|
- | 1271 | shr ecx, 5 |
|
- | 1272 | and ecx, 3 |
|
- | 1273 | inc ecx |
|
- | 1274 | ret |
|
- | 1275 | endp>=> |