2 Copyright © 2015-2017, The AROS Development Team. All rights reserved.
5 Desc: VUSBHCI USB host controller
14 #include <aros/debug.h>
15 #include <aros/macros.h>
16 #include <aros/asmcall.h>
17 #include <aros/symbolsets.h>
19 #include <proto/exec.h>
20 #include <proto/arossupport.h>
22 #include <devices/usb.h>
23 #include <devices/usb_hub.h>
24 #include <devices/newstyle.h>
25 #include <devices/usbhardware.h>
27 #include "vusbhci_device.h"
30 Our iorequests are divided into many different queus or dispatched immediatly (cannot be aborted)
31 Libusb handler task blocks us from the queue whenever it dispatches an iorequest
32 cmdAbortIO also blocks the libusb handler from accessing the queue
33 Which ever comes first gets the change to access the queue
34 Libusb handler task removes the iorequest from the queue before unblocking the queue
36 BOOL
cmdAbortIO(struct IOUsbHWReq
*ioreq
) {
37 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
39 struct IOUsbHWReq
*ioreq_tmp
;
42 switch (ioreq
->iouh_Req
.io_Command
) {
43 case UHCMD_CONTROLXFER
:
44 mybug_unit(-1, ("Aborting cmdControlXFer ioreq\n"));
45 /* We need to block the libusb handler task from messing up with our queue */
46 ObtainSemaphore(&unit
->ctrlxfer_queue_lock
); {
47 } ReleaseSemaphore(&unit
->ctrlxfer_queue_lock
);
51 mybug_unit(-1, ("Aborting cmdIntXFer ioreq %lx\n", ioreq
));
52 /* We need to block the libusb handler task from messing up with our queue */
53 ObtainSemaphore(&unit
->intrxfer_queue_lock
); {
54 mybug_unit(-1, (" Semaphore accuired\n"));
55 ForeachNode(&unit
->intrxfer_queue
, ioreq_tmp
) {
56 mybug_unit(-1, (" %lx == %lx\n", ioreq_tmp
, ioreq
));
57 /* Found the iorequest from our queue */
58 if(ioreq_tmp
== ioreq
) {
59 /* Remove it from our queue */
60 ioreq_tmp
->iouh_Req
.io_Error
= IOERR_ABORTED
;
61 ioreq_tmp
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
62 Remove(&ioreq_tmp
->iouh_Req
.io_Message
.mn_Node
);
63 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
64 mybug_unit(-1, (" removed\n"));
68 } ReleaseSemaphore(&unit
->intrxfer_queue_lock
);
71 Must have been a request for the roothub intr queue or not...
72 When a device gets unbind we get an iorequest followed by an abort command
73 can't find the request... Maybe the roothub intr code is broken
76 ObtainSemaphore(&unit
->roothub
.intrxfer_queue_lock
); {
77 ioreq
->iouh_Req
.io_Error
= IOERR_ABORTED
;
78 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
79 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
80 mybug_unit(-1, (" removed\n"));
82 } ReleaseSemaphore(&unit
->roothub
.intrxfer_queue_lock
);
87 mybug_unit(-1, ("Aborting cmdBulkXFer ioreq\n"));
88 ObtainSemaphore(&unit
->bulkxfer_queue_lock
); {
89 } ReleaseSemaphore(&unit
->bulkxfer_queue_lock
);
93 mybug_unit(-1, ("Aborting cmdISOXFer ioreq\n"));
94 ObtainSemaphore(&unit
->isocxfer_queue_lock
); {
95 } ReleaseSemaphore(&unit
->isocxfer_queue_lock
);
99 mybug_unit(-1, ("Aborting default ioreq ?!?\n"));
103 mybug_unit(-1, ("Returning %s\n", ((ret
) ? "TRUE":"FALSE")));
108 WORD
cmdFlush(struct IOUsbHWReq
*ioreq
) {
109 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
111 mybug_unit(-1, ("Entering function\n"));
116 WORD
cmdUsbReset(struct IOUsbHWReq
*ioreq
) {
117 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
119 mybug_unit(-1, ("Entering function\n"));
121 /* We should do a proper reset sequence with a real driver */
122 unit
->state
= UHSF_RESET
;
123 unit
->roothub
.addr
= 0;
124 unit
->state
= UHSF_OPERATIONAL
;
125 mybug_unit(0, ("Done\n\n"));
129 /* Standard Requests */
133 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 10000000B
134 bRequest USR_GET_STATUS
140 CHECKME: U_GSB_SELF_POWERED=8 and U_GSB_REMOTE_WAKEUP=9, should they be 0 and 1?
143 UWORD
GetStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
144 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
145 mybug_unit(-1, ("Entering function\n"));
148 devicestatus
= ioreq
->iouh_Data
;
150 *devicestatus
= (U_GSF_SELF_POWERED
& (~U_GSF_REMOTE_WAKEUP
));
152 ioreq
->iouh_Actual
= wLength
;
154 mybug_unit(-1, ("GetStatus(%ld) %02x\n", wLength
, *devicestatus
));
156 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
157 return UHIOERR_NO_ERROR
;
162 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 00000000B
163 bRequest CLEAR_FEATURE
164 wValue Feature Selector
169 UWORD
ClearFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
170 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
171 mybug_unit(-1, ("Entering function\n"));
173 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
174 return UHIOERR_NO_ERROR
;
179 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 00000000B
181 wValue Feature Selector
186 UWORD
SetFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
187 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
188 mybug_unit(-1, ("Entering function\n"));
190 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
191 return UHIOERR_NO_ERROR
;
196 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
197 bRequest USR_SET_ADDRESS
198 wValue Device Address
203 UWORD
SetAddress(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
204 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
205 mybug_unit(-1, ("Entering function\n"));
207 mybug_unit(-1, ("SetAddress (address %d)\n", wValue
));
209 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
210 if( (wValue
) && (!(wIndex
)) && (!(wLength
)) ) {
212 unit
->roothub
.addr
= wValue
;
213 ioreq
->iouh_Actual
= wLength
;
215 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
216 return UHIOERR_NO_ERROR
;
219 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
220 return UHIOERR_BADPARAMS
;
225 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 10000000B
226 bRequest GET_DESCRIPTOR
227 wValue Descriptor Type & Index
228 wIndex Zero or Language ID
229 wLength Descriptor Length
232 UWORD
GetDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
233 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
234 mybug_unit(-1, ("Entering function\n"));
236 CONST_STRPTR roothubstring
= NULL
;
237 CONST_STRPTR roothubstrings
[] = {"The AROS Development Team.", "VUSBHCI root hub (USB2.00)", "VUSBHCI root hub (USB3.00)", "Standard Config", "Hub interface" };
240 switch((wValue
>>8)) {
242 mybug_unit(-1, ("GetDeviceDescriptor UDT_DEVICE (length %ld)\n", wLength
));
244 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbStdDevDesc
)) ? sizeof(struct UsbStdDevDesc
) : wLength
;
245 CopyMem((APTR
) &unit
->roothub
.devdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
247 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
248 return UHIOERR_NO_ERROR
;
251 case UDT_CONFIGURATION
:
252 index
= (wValue
& 0xff);
254 mybug_unit(-1, ("GetDeviceDescriptor UDT_CONFIGURATION (configuration %d, length %ld)\n",index
, wLength
));
258 ioreq
->iouh_Actual
= (wLength
> sizeof(struct RHConfig
)) ? sizeof(struct RHConfig
) : wLength
;
259 CopyMem((APTR
) &unit
->roothub
.config
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
261 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
262 return UHIOERR_NO_ERROR
;
265 mybug_unit(-1, ("Our roothub supports only one configuration\n"));
266 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
267 return UHIOERR_BADPARAMS
;
271 index
= (wValue
& 0xff);
273 mybug_unit(-1, ("GetStringDescriptor UDT_STRING (index %d)\n", index
));
275 struct UsbStdStrDesc
*strdesc
= (struct UsbStdStrDesc
*) ioreq
->iouh_Data
;
280 strdesc
->bLength
= sizeof(struct UsbStdStrDesc
);
281 strdesc
->bDescriptorType
= UDT_STRING
;
282 ioreq
->iouh_Actual
= 2;
285 strdesc
->bString
[0] = AROS_WORD2LE(0x0409); // English (Yankee)
286 ioreq
->iouh_Actual
= sizeof(struct UsbStdStrDesc
);
289 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
290 return UHIOERR_NO_ERROR
;
293 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
294 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
298 roothubstring
= roothubstrings
[0];
302 if(unit
->roothub
.devdesc
.bcdUSB
== AROS_WORD2LE(0x0200)) {
303 roothubstring
= roothubstrings
[1];
305 roothubstring
= roothubstrings
[2];
310 roothubstring
= roothubstrings
[3];
314 roothubstring
= roothubstrings
[4];
318 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
319 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
323 UBYTE i
= strlen(roothubstring
);
325 strdesc
->bLength
= (i
*sizeof(strdesc
->bString
))+sizeof(strdesc
->bLength
)+sizeof(strdesc
->bDescriptorType
);
326 strdesc
->bDescriptorType
= UDT_STRING
;
327 ioreq
->iouh_Actual
= 2;
330 for(i
=0; i
<wLength
; i
++) {
331 strdesc
->bString
[i
] = AROS_WORD2LE((UWORD
)roothubstring
[i
]);
335 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
336 return UHIOERR_NO_ERROR
;
339 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
340 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
345 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
346 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
351 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
352 bRequest SET_DESCRIPTOR
353 wValue Descriptor Type & Index
354 wIndex Zero or Language ID
355 wLength Descriptor Length
358 UWORD
SetDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
359 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
360 mybug_unit(-1, ("Entering function\n"));
362 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
363 return UHIOERR_NO_ERROR
;
368 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 10000000B
369 bRequest USR_GET_CONFIGURATION
373 Data Configuration Value
375 UWORD
GetConfiguration(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
376 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
377 mybug_unit(-1, ("Entering function\n"));
379 UWORD
*configurationvalue
;
380 configurationvalue
= ioreq
->iouh_Data
;
382 *configurationvalue
= unit
->roothub
.config
.cfgdesc
.bConfigurationValue
;
384 ioreq
->iouh_Actual
= wLength
;
386 mybug_unit(-1, ("GetConfiguration() %ld\n", configurationvalue
));
388 return UHIOERR_NO_ERROR
;
393 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
394 bRequest USR_SET_CONFIGURATION
395 wValue Configuration Value
401 We have only one configuration, but implement some sanity still
402 If more than one configuration is specified we ignore the rest in GetDescriptor(UDT_CONFIGURATION)
405 UWORD
SetConfiguration(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
406 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
407 mybug_unit(-1, ("Entering function\n"));
409 mybug_unit(-1, ("SetConfiguration (configuration %d)\n", wValue
));
411 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
412 if( (wValue
== unit
->roothub
.config
.cfgdesc
.bConfigurationValue
) && (!(wIndex
)) && (!(wLength
)) ) {
414 ioreq
->iouh_Actual
= wLength
;
416 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
417 return UHIOERR_NO_ERROR
;
420 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
421 return UHIOERR_BADPARAMS
;
424 /* Hub Class Requests */
428 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
429 bRequest USR_CLEAR_FEATURE
430 wValue Feature Selector
435 UWORD
ClearHubFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
436 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
437 mybug_unit(-1, ("Entering function\n"));
439 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
440 return UHIOERR_NO_ERROR
;
445 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
446 bRequest USR_CLEAR_FEATURE
447 wValue Feature Selector
448 wIndex (Selector|Port)
452 FIXME: Check what flags to set and clear on this and SetPortFeature
455 UWORD
ClearPortFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
456 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
457 mybug_unit(-1, ("Entering function\n"));
459 mybug_unit(-1, ("Clearing feature 0x%02x on port %d\n",wValue
, (wIndex
& 0xff)));
461 if( ((!(wIndex
& 0xff)) || ((wIndex
& 0xff) > unit
->roothub
.hubdesc
.bNbrPorts
)) ) {
462 mybug_unit(-1, ("Port %ld out of range\n", (wIndex
& 0xff)));
463 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
464 return UHIOERR_BADPARAMS
;
468 case UFS_PORT_ENABLE
:
469 mybug_unit(-1, ("UFS_PORT_ENABLE\n"));
470 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_ENABLE
;
473 case UFS_PORT_SUSPEND
:
474 mybug_unit(-1, ("UFS_PORT_SUSPEND\n"));
478 mybug_unit(-1, ("UFS_PORT_POWER\n"));
479 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_POWER
;
482 case UFS_PORT_INDICATOR
:
483 mybug_unit(-1, ("UFS_PORT_INDICATOR\n"));
484 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_INDICATOR
;
487 case UFS_C_PORT_CONNECTION
:
488 mybug_unit(-1, ("UFS_C_PORT_CONNECTION\n"));
489 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_CONNECTION
;
492 case UFS_C_PORT_RESET
:
493 mybug_unit(-1, ("UFS_C_PORT_RESET\n"));
494 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_RESET
;
497 case UFS_C_PORT_ENABLE
:
498 mybug_unit(-1, ("UFS_C_PORT_ENABLE\n"));
499 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_ENABLE
;
502 case UFS_C_PORT_SUSPEND
:
503 mybug_unit(-1, ("UFS_C_PORT_SUSPEND\n"));
504 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_SUSPEND
;
507 case UFS_C_PORT_OVER_CURRENT
:
508 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT\n"));
509 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_OVER_CURRENT
;
513 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
514 return UHIOERR_NO_ERROR
;
520 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
521 bRequest USR_CLEAR_TT_BUFFER
522 wValue Dev_Addr, EP_Num
530 UWORD
ClearTTBuffer(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
531 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
532 mybug_unit(-1, ("Entering function\n"));
534 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
535 return UHIOERR_NO_ERROR
;
540 bmRequestType (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
541 bRequest USR_GET_DESCRIPTOR
542 wValue Descriptor Type and Descriptor Index
543 wIndex Zero (or language ID)
544 wLength Descriptor Length
547 UWORD
GetHubDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
548 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
549 mybug_unit(-1, ("Entering function\n"));
551 switch((wValue
>>8)) {
553 mybug_unit(-1, ("GetHubDescriptor UDT_HUB (length %ld)\n", wLength
));
555 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbHubDesc
)) ? sizeof(struct UsbHubDesc
) : wLength
;
556 CopyMem((APTR
) &unit
->roothub
.hubdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
558 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
559 return UHIOERR_NO_ERROR
;
563 mybug_unit(-1, ("GetHubDescriptor UDT_SSHUB (length %ld)\n", wLength
));
565 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbSSHubDesc
)) ? sizeof(struct UsbSSHubDesc
) : wLength
;
566 CopyMem((APTR
) &unit
->roothub
.hubdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
568 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
569 return UHIOERR_NO_ERROR
;
573 return UHIOERR_BADPARAMS
;
578 bmRequestType (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
579 bRequest USR_GET_STATUS
583 Data Hub Status and Change Status
585 UWORD
GetHubStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
586 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
587 mybug_unit(-1, ("Entering function\n"));
589 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
590 if( (!(wValue
)) && (!(wIndex
)) && (wLength
== 4) ) {
592 struct UsbHubStatus
*usbhubstatus
= (struct UsbHubStatus
*) ioreq
->iouh_Data
;
594 usbhubstatus
->wHubStatus
= unit
->roothub
.hubstatus
.wHubStatus
;
595 usbhubstatus
->wHubChange
= unit
->roothub
.hubstatus
.wHubChange
;
597 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
598 return UHIOERR_NO_ERROR
;
601 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
602 return UHIOERR_BADPARAMS
;
607 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
608 bRequest USR_GET_STATUS
612 Data Port Status and Change Status
614 UWORD
GetPortStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
615 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
616 mybug_unit(-1, ("Entering function\n"));
618 mybug_unit(-1, ("Port #%ld\n", wIndex
));
620 if( (wValue
) || (wLength
!= 4) || (!wIndex
) || (wIndex
> unit
->roothub
.hubdesc
.bNbrPorts
) ) {
621 mybug_unit(-1, ("Port %ld out of range\n", wIndex
));
622 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
623 return UHIOERR_BADPARAMS
;
626 struct UsbPortStatus
*usbportstatus
= (struct UsbPortStatus
*) ioreq
->iouh_Data
;
628 /* We have only one port per 'controller' */
629 usbportstatus
->wPortStatus
= unit
->roothub
.portstatus
.wPortStatus
;
630 usbportstatus
->wPortChange
= unit
->roothub
.portstatus
.wPortChange
;
632 mybug_unit(-1, ("usbportstatus->wPortStatus %01x\n", usbportstatus
->wPortStatus
));
633 mybug_unit(-1, ("usbportstatus->wPortChange %01x\n", usbportstatus
->wPortChange
));
635 if(usbportstatus
->wPortStatus
&UPSF_PORT_CONNECTION
) {
636 mybug_unit(-1, (" - UPSF_PORT_CONNECTION\n"));
639 if(usbportstatus
->wPortStatus
&UPSF_PORT_ENABLE
) {
640 mybug_unit(-1, (" - UPSF_PORT_ENABLE\n"));
643 if(usbportstatus
->wPortStatus
&UPSF_PORT_SUSPEND
) {
644 mybug_unit(-1, (" - UPSF_PORT_SUSPEND\n"));
647 if(usbportstatus
->wPortStatus
&UPSF_PORT_OVER_CURRENT
) {
648 mybug_unit(-1, (" - UPSF_PORT_OVER_CURRENT\n"));
651 if(usbportstatus
->wPortStatus
&UPSF_PORT_RESET
) {
652 mybug_unit(-1, (" - UPSF_PORT_RESET\n"));
655 if(usbportstatus
->wPortStatus
&UPSF_PORT_POWER
) {
656 mybug_unit(-1, (" - UPSF_PORT_POWER\n"));
659 if(usbportstatus
->wPortStatus
&UPSF_PORT_LOW_SPEED
) {
660 mybug_unit(-1, (" - UPSF_PORT_LOW_SPEED\n"));
663 if(usbportstatus
->wPortStatus
&UPSF_PORT_HIGH_SPEED
) {
664 mybug_unit(-1, (" - UPSF_PORT_HIGH_SPEED\n"));
667 if(usbportstatus
->wPortStatus
&UPSF_PORT_TEST_MODE
) {
668 mybug_unit(-1, (" - UPSF_PORT_TEST_MODE\n"));
671 if(usbportstatus
->wPortStatus
&UPSF_PORT_INDICATOR
) {
672 mybug_unit(-1, (" - UPSF_PORT_INDICATOR\n"));
675 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
676 return UHIOERR_NO_ERROR
;
681 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
682 bRequest USR_PORT_ERR_COUNT (Check: Has it been defined?)
686 Data Number of link errors on this port
688 UWORD
GetPortErrorCount(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
689 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
690 mybug_unit(-1, ("Entering function\n"));
692 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
693 return UHIOERR_NO_ERROR
;
698 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
699 bRequest USR_RESET_TT
707 UWORD
ResetTT(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
708 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
709 mybug_unit(-1, ("Entering function\n"));
711 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
712 return UHIOERR_NO_ERROR
;
717 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
718 bRequest USR_SET_DESCRIPTOR
719 wValue Descriptor Type and Descriptor Index
720 wIndex Zero or Language ID
721 wLength Descriptor Length
724 UWORD
SetHubDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
725 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
726 mybug_unit(-1, ("Entering function\n"));
728 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
729 return UHIOERR_NO_ERROR
;
734 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
735 bRequest USR_SET_FEATURE
736 wValue Feature Selector
741 UWORD
SetHubFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
742 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
743 mybug_unit(-1, ("Entering function\n"));
745 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
746 return UHIOERR_NO_ERROR
;
751 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
752 bRequest USR_SET_HUB_DEPTH (Check: Has it been defined?)
758 UWORD
SetHubDepth(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
759 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
760 mybug_unit(-1, ("Entering function\n"));
762 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
763 return UHIOERR_NO_ERROR
;
768 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
769 bRequest USR_SET_FEATURE
770 wValue Feature Selector
771 wIndex (Selector|Port)
774 FIXME: Check what flags to set and clear on this and ClearPortFeature
777 UWORD
SetPortFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
778 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
779 mybug_unit(-1, ("Entering function\n"));
781 mybug_unit(-1, ("Setting feature 0x%02x on port %d\n",wValue
, (wIndex
& 0xff)));
783 if( ((!(wIndex
& 0xff)) || ((wIndex
& 0xff) > unit
->roothub
.hubdesc
.bNbrPorts
)) ) {
784 mybug_unit(-1, ("Port %ld out of range\n", (wIndex
& 0xff)));
785 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
786 return UHIOERR_BADPARAMS
;
791 /* Features that can be set with this request */
793 mybug_unit(-1, ("UFS_PORT_RESET\n"));
794 unit
->roothub
.portstatus
.wPortStatus
|= (UPSF_PORT_ENABLE
|UPSF_PORT_POWER
);
797 case UFS_PORT_SUSPEND
:
798 mybug_unit(-1, ("UFS_PORT_SUSPEND\n"));
802 mybug_unit(-1, ("UFS_PORT_POWER\n"));
803 unit
->roothub
.portstatus
.wPortStatus
|= UPSF_PORT_POWER
;
807 mybug_unit(-1, ("UFS_PORT_TEST\n"));
810 case UFS_PORT_INDICATOR
:
811 mybug_unit(-1, ("UFS_PORT_INDICATOR\n"));
814 /* Features that can be set with this request but are not required */
815 case UFS_C_PORT_CONNECTION
:
816 mybug_unit(-1, ("UFS_C_PORT_CONNECTION\n"));
819 case UFS_C_PORT_RESET
:
820 mybug_unit(-1, ("UFS_C_PORT_RESET\n"));
823 case UFS_C_PORT_ENABLE
:
824 mybug_unit(-1, ("UFS_C_PORT_ENABLE\n"));
827 case UFS_C_PORT_SUSPEND
:
828 mybug_unit(-1, ("UFS_C_PORT_SUSPEND\n"));
831 case UFS_C_PORT_OVER_CURRENT
:
832 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT\n"));
836 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
837 return UHIOERR_BADPARAMS
;
842 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
843 return UHIOERR_NO_ERROR
;
848 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
849 bRequest USR_GET_TT_STATE
852 wLength TT State Length
857 UWORD
GetTTState(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
858 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
859 mybug_unit(-1, ("Entering function\n"));
861 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
862 return UHIOERR_NO_ERROR
;
867 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
876 UWORD
StopTT(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
877 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
878 mybug_unit(-1, ("Entering function\n"));
880 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
881 return UHIOERR_NO_ERROR
;
884 WORD
cmdControlXFerRootHub(struct IOUsbHWReq
*ioreq
) {
886 UWORD bmRequestType
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_STANDARD
| URTF_CLASS
| URTF_VENDOR
);
887 UWORD bmRequestDirection
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_IN
| URTF_OUT
);
888 UWORD bmRequestRecipient
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_DEVICE
| URTF_INTERFACE
| URTF_ENDPOINT
| URTF_OTHER
);
890 UWORD bRequest
= (ioreq
->iouh_SetupData
.bRequest
);
891 UWORD wValue
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wValue
);
892 UWORD wIndex
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wIndex
);
893 UWORD wLength
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wLength
);
895 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
897 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
898 if(ioreq
->iouh_Endpoint
!= 0) {
899 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq
->iouh_Endpoint
));
900 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
901 return UHIOERR_BADPARAMS
;
904 switch(((ULONG
)ioreq
->iouh_SetupData
.bmRequestType
<<16)|((ULONG
)ioreq
->iouh_SetupData
.bRequest
)) {
906 /* Standard Requests */
907 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_GET_STATUS
)):
908 return(GetStatus(ioreq
, wValue
, wIndex
, wLength
));
910 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_CLEAR_FEATURE
)):
911 return(ClearFeature(ioreq
, wValue
, wIndex
, wLength
));
913 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_SET_FEATURE
)):
914 return(SetFeature(ioreq
, wValue
, wIndex
, wLength
));
916 case ((((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
))<<16)|(USR_SET_ADDRESS
)):
917 return(SetAddress(ioreq
, wValue
, wIndex
, wLength
));
919 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_GET_DESCRIPTOR
)):
920 return(GetDescriptor(ioreq
, wValue
, wIndex
, wLength
));
922 case (((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_SET_DESCRIPTOR
)):
923 return(SetDescriptor(ioreq
, wValue
, wIndex
, wLength
));
925 case ((((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
))<<16)|(USR_GET_CONFIGURATION
)):
926 return(GetConfiguration(ioreq
, wValue
, wIndex
, wLength
));
928 case ((((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
))<<16)|(USR_SET_CONFIGURATION
)):
929 return(SetConfiguration(ioreq
, wValue
, wIndex
, wLength
));
931 /* Hub Class Requests. Check here if the command is for USB2 or USB3 hub... */
932 case (((URTF_OUT
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_CLEAR_FEATURE
)):
933 return(ClearHubFeature(ioreq
, wValue
, wIndex
, wLength
));
935 case (((URTF_OUT
|URTF_CLASS
|URTF_OTHER
)<<16)|(USR_CLEAR_FEATURE
)):
936 return(ClearPortFeature(ioreq
, wValue
, wIndex
, wLength
));
938 case (((URTF_OUT
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_SET_FEATURE
)):
939 return(SetHubFeature(ioreq
, wValue
, wIndex
, wLength
));
941 case (((URTF_OUT
|URTF_CLASS
|URTF_OTHER
)<<16)|(USR_SET_FEATURE
)):
942 return(SetPortFeature(ioreq
, wValue
, wIndex
, wLength
));
944 case (((URTF_IN
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_GET_DESCRIPTOR
)):
945 return(GetHubDescriptor(ioreq
, wValue
, wIndex
, wLength
));
947 case ((((URTF_IN
|URTF_CLASS
|URTF_DEVICE
))<<16)|(USR_GET_STATUS
)):
948 return(GetHubStatus(ioreq
, wValue
, wIndex
, wLength
));
950 case ((((URTF_IN
|URTF_CLASS
|URTF_OTHER
))<<16)|(USR_GET_STATUS
)):
951 return(GetPortStatus(ioreq
, wValue
, wIndex
, wLength
));
953 // case (((( X ))<<16)|( X )):
954 // return( X (ioreq));
957 mybug_unit(-1, ("ATTENTION! Unhandled!\n"));
958 mybug_unit(-1, ("ioreq->iouh_SetupData.bmRequestType %x\n", ioreq
->iouh_SetupData
.bmRequestType
));
959 mybug_unit(-1, ("ioreq->iouh_SetupData.bRequest %x\n", ioreq
->iouh_SetupData
.bRequest
));
960 mybug_unit(-1, ("ioreq->iouh_SetupData.wValue %x\n", ioreq
->iouh_SetupData
.wValue
));
961 mybug_unit(-1, ("ioreq->iouh_SetupData.wIndex %x\n", ioreq
->iouh_SetupData
.wIndex
));
962 mybug_unit(-1, ("ioreq->iouh_SetupData.wLength %x\n", ioreq
->iouh_SetupData
.wLength
));
966 mybug_unit(-1, ("Nothing done!\n\n"));
967 return UHIOERR_BADPARAMS
;
970 WORD
cmdIntXFerRootHub(struct IOUsbHWReq
*ioreq
) {
971 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
973 mybug_unit(-1, ("Entering function\n"));
975 if((ioreq
->iouh_Endpoint
!= 1) || (!ioreq
->iouh_Length
)) {
976 mybug_unit(-1, ("UHIOERR_BADPARAMS\n"));
977 return(UHIOERR_BADPARAMS
); // was UHIOERR_STALL
981 if(unit
->roothub
.portstatus
.wPortChange
) {
982 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit
->roothub
.portstatus
.wPortChange
));
983 *((UBYTE
*) ioreq
->iouh_Data
) = unit
->roothub
.portstatus
.wPortChange
;
984 ioreq
->iouh_Actual
= 1;
985 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_CONNECTION
;
986 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit
->roothub
.portstatus
.wPortChange
));
991 mybug_unit(-1, ("ioreq added to roothub intrxfer_queue\n"));
993 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
994 ObtainSemaphore(&unit
->roothub
.intrxfer_queue_lock
);
995 AddTail(&unit
->roothub
.intrxfer_queue
, (struct Node
*) ioreq
);
996 ReleaseSemaphore(&unit
->roothub
.intrxfer_queue_lock
);
998 return(RC_DONTREPLY
);
1002 WORD cmdControlXFer(struct IOUsbHWReq *ioreq) {
1003 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1005 mybug_unit(-1, ("Entering function\n"));
1007 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1008 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1011 Check the status of the controller
1012 We might encounter these states:
1013 UHSB_OPERATIONAL USB can be used for transfers
1014 UHSB_RESUMING USB is currently resuming
1015 UHSB_SUSPENDED USB is in suspended state
1016 UHSB_RESET USB is just inside a reset phase
1019 if(unit->state == UHSF_OPERATIONAL) {
1020 mybug_unit(0, ("Unit state is operational\n"));
1022 mybug_unit(-1, ("Unit state is not operational!\n"));
1023 return UHIOERR_USBOFFLINE;
1026 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
1027 return(cmdControlXFerRootHub(ioreq));
1030 mybug_unit(-1, ("Sending transfer request to libusb ->\n"));
1031 return(do_libusb_ctrl_transfer(ioreq));
1035 WORD
cmdControlXFer(struct IOUsbHWReq
*ioreq
) {
1036 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
1038 mybug_unit(0, ("Entering function\n"));
1040 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
1041 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
1044 Check the status of the controller
1045 We might encounter these states:
1046 UHSB_OPERATIONAL USB can be used for transfers
1047 UHSB_RESUMING USB is currently resuming
1048 UHSB_SUSPENDED USB is in suspended state
1049 UHSB_RESET USB is just inside a reset phase
1052 if(unit
->state
== UHSF_OPERATIONAL
) {
1053 mybug_unit(0, ("Unit state is operational\n"));
1055 mybug_unit(-1, ("Unit state is not operational!\n"));
1056 return UHIOERR_USBOFFLINE
;
1059 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
1060 return(cmdControlXFerRootHub(ioreq
));
1063 mybug_unit(-1, ("Adding CNTR transfer request to queue\n"));
1064 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
1065 ioreq
->iouh_Actual
= 0;
1067 ObtainSemaphore(&unit
->ctrlxfer_queue_lock
);
1068 AddTail(&unit
->ctrlxfer_queue
, (struct Node
*) ioreq
);
1069 ReleaseSemaphore(&unit
->ctrlxfer_queue_lock
);
1071 return(RC_DONTREPLY
);
1074 WORD
cmdIntXFer(struct IOUsbHWReq
*ioreq
) {
1075 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
1077 mybug_unit(-1, ("Entering function\n"));
1079 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
1080 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
1083 Check the status of the controller
1084 We might encounter these states:
1085 UHSB_OPERATIONAL USB can be used for transfers
1086 UHSB_RESUMING USB is currently resuming
1087 UHSB_SUSPENDED USB is in suspended state
1088 UHSB_RESET USB is just inside a reset phase
1091 if(unit
->state
== UHSF_OPERATIONAL
) {
1092 mybug_unit(0, ("Unit state is operational\n"));
1094 mybug_unit(-1, ("Unit state is not operational!\n"));
1095 return UHIOERR_USBOFFLINE
;
1098 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
1099 return(cmdIntXFerRootHub(ioreq
));
1102 mybug_unit(-1, ("Adding INTR transfer request to queue\n"));
1103 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
1104 ioreq
->iouh_Actual
= 0;
1106 ObtainSemaphore(&unit
->intrxfer_queue_lock
);
1107 AddTail(&unit
->intrxfer_queue
, (struct Node
*) ioreq
);
1108 ReleaseSemaphore(&unit
->intrxfer_queue_lock
);
1110 return(RC_DONTREPLY
);
1113 WORD
cmdBulkXFer(struct IOUsbHWReq
*ioreq
) {
1114 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
1116 mybug_unit(0, ("Entering function\n"));
1118 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
1119 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
1122 Check the status of the controller
1123 We might encounter these states:
1124 UHSB_OPERATIONAL USB can be used for transfers
1125 UHSB_RESUMING USB is currently resuming
1126 UHSB_SUSPENDED USB is in suspended state
1127 UHSB_RESET USB is just inside a reset phase
1130 if(unit
->state
== UHSF_OPERATIONAL
) {
1131 mybug_unit(0, ("Unit state is operational\n"));
1133 mybug_unit(-1, ("Unit state is not operational!\n"));
1134 return UHIOERR_USBOFFLINE
;
1137 mybug_unit(0, ("Adding BULK transfer request to queue\n"));
1138 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
1139 ioreq
->iouh_Actual
= 0;
1141 ObtainSemaphore(&unit
->bulkxfer_queue_lock
);
1142 AddTail(&unit
->bulkxfer_queue
, (struct Node
*) ioreq
);
1143 ReleaseSemaphore(&unit
->bulkxfer_queue_lock
);
1145 return(RC_DONTREPLY
);
1148 WORD
cmdISOXFer(struct IOUsbHWReq
*ioreq
) {
1149 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
1151 mybug_unit(0, ("Entering function\n"));
1153 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
1154 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
1157 Check the status of the controller
1158 We might encounter these states:
1159 UHSB_OPERATIONAL USB can be used for transfers
1160 UHSB_RESUMING USB is currently resuming
1161 UHSB_SUSPENDED USB is in suspended state
1162 UHSB_RESET USB is just inside a reset phase
1165 if(unit
->state
== UHSF_OPERATIONAL
) {
1166 mybug_unit(0, ("Unit state is operational\n"));
1168 mybug_unit(-1, ("Unit state is not operational!\n"));
1169 return UHIOERR_USBOFFLINE
;
1172 mybug_unit(0, ("Adding ISOC transfer request to queue\n"));
1173 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
1174 ioreq
->iouh_Actual
= 0;
1176 ObtainSemaphore(&unit
->isocxfer_queue_lock
);
1177 AddTail(&unit
->isocxfer_queue
, (struct Node
*) ioreq
);
1178 ReleaseSemaphore(&unit
->isocxfer_queue_lock
);
1180 return(RC_DONTREPLY
);
1183 void uhwCheckRootHubChanges(struct VUSBHCIUnit
*unit
) {
1184 mybug_unit(0, ("Entering function\n"));
1186 mybug_unit(0, ("usbportstatus->wPortStatus %01x\n", unit
->roothub
.portstatus
.wPortStatus
));
1187 mybug_unit(0, ("usbportstatus->wPortChange %01x\n", unit
->roothub
.portstatus
.wPortChange
));
1189 struct IOUsbHWReq
*ioreq
;
1191 ObtainSemaphore(&unit
->roothub
.intrxfer_queue_lock
);
1192 if(unit
->roothub
.portstatus
.wPortChange
&& unit
->roothub
.intrxfer_queue
.lh_Head
->ln_Succ
) {
1193 ioreq
= (struct IOUsbHWReq
*) unit
->roothub
.intrxfer_queue
.lh_Head
;
1194 while(((struct Node
*) ioreq
)->ln_Succ
) {
1195 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
1197 *((UBYTE
*) ioreq
->iouh_Data
) = (1<<1);
1198 ioreq
->iouh_Actual
= 1;
1200 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
1201 ioreq
= (struct IOUsbHWReq
*) unit
->roothub
.intrxfer_queue
.lh_Head
;
1205 ReleaseSemaphore(&unit
->roothub
.intrxfer_queue_lock
);