2 Copyright © 2015-2016, 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"
29 BOOL
cmdAbortIO(struct IOUsbHWReq
*ioreq
) {
30 ioreq
->iouh_Req
.io_Error
= IOERR_ABORTED
;
31 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
33 /* If not quick I/O, reply the message */
34 if (!(ioreq
->iouh_Req
.io_Flags
& IOF_QUICK
)) {
35 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
41 WORD
cmdUsbReset(struct IOUsbHWReq
*ioreq
) {
42 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
44 mybug_unit(0, ("Entering function\n"));
46 /* We should do a proper reset sequence with a real driver */
47 unit
->state
= UHSF_RESET
;
48 unit
->roothub
.addr
= 0;
49 unit
->state
= UHSF_OPERATIONAL
;
50 mybug_unit(0, ("Done\n\n"));
55 D7 Data Phase Transfer Direction
70 #define URTF_OUT 0x00 // direction: host to device
71 #define URTF_IN 0x80 // direction: device to host
73 #define URTF_STANDARD 0x00 // type: usb standard request
74 #define URTF_CLASS 0x20 // type: class request
75 #define URTF_VENDOR 0x40 // type: vendor specific request
77 #define URTF_DEVICE 0x00 // target: device
78 #define URTF_INTERFACE 0x01 // target: interface
79 #define URTF_ENDPOINT 0x02 // target: endpoint
80 #define URTF_OTHER 0x03 // target: other
83 /* Standard Requests */
86 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
87 bRequest USR_SET_ADDRESS
93 UWORD
SetAddress(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
94 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
95 mybug_unit(-1, ("Entering function\n"));
97 mybug_unit(-1, ("SetAddress (address %d)\n", wValue
));
99 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
100 if( (wValue
) && (!(wIndex
)) && (!(wLength
)) ) {
102 unit
->roothub
.addr
= wValue
;
103 ioreq
->iouh_Actual
= wLength
;
105 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
106 return UHIOERR_NO_ERROR
;
109 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
110 return UHIOERR_BADPARAMS
;
115 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
116 bRequest USR_SET_CONFIGURATION
117 wValue Configuration Value
123 We have only one configuration, but implement some sanity still
124 If more than one configuration is specified we ignore the rest in GetDescriptor(UDT_CONFIGURATION)
127 UWORD
SetConfiguration(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
128 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
129 mybug_unit(-1, ("Entering function\n"));
131 mybug_unit(-1, ("SetConfiguration (configuration %d)\n", wValue
));
133 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
134 if( (wValue
) && (wValue
<=unit
->roothub
.devdesc
.bNumConfigurations
) && (!(wIndex
)) && (!(wLength
)) ) {
136 ioreq
->iouh_Actual
= wLength
;
138 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
139 return UHIOERR_NO_ERROR
;
142 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
143 return UHIOERR_BADPARAMS
;
148 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 10000000B
149 bRequest USR_GET_STATUS
155 UWORD
GetStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
156 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
157 mybug_unit(-1, ("Entering function\n"));
159 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
160 return UHIOERR_NO_ERROR
;
166 UWORD
GetDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
167 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
168 mybug_unit(-1, ("Entering function\n"));
170 CONST_STRPTR roothubstring
= NULL
;
171 CONST_STRPTR roothubstrings
[] = {"The AROS Development Team.", "VUSBHCI root hub (USB2.00)", "VUSBHCI root hub (USB3.00)", "Standard Config", "Hub interface" };
174 switch((wValue
>>8)) {
176 mybug_unit(-1, ("GetDeviceDescriptor UDT_DEVICE (length %ld)\n", wLength
));
178 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbStdDevDesc
)) ? sizeof(struct UsbStdDevDesc
) : wLength
;
179 CopyMem((APTR
) &unit
->roothub
.devdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
181 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
182 return UHIOERR_NO_ERROR
;
185 case UDT_CONFIGURATION
:
186 index
= (wValue
& 0xff);
188 mybug_unit(-1, ("GetDeviceDescriptor UDT_CONFIGURATION (configuration %d, length %ld)\n",index
, wLength
));
192 ioreq
->iouh_Actual
= (wLength
> sizeof(struct RHConfig
)) ? sizeof(struct RHConfig
) : wLength
;
193 CopyMem((APTR
) &unit
->roothub
.config
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
195 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
196 return UHIOERR_NO_ERROR
;
199 mybug_unit(-1, ("Our roothub supports only one configuration\n"));
200 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
201 return UHIOERR_BADPARAMS
;
205 index
= (wValue
& 0xff);
207 mybug_unit(-1, ("GetStringDescriptor UDT_STRING (index %d)\n", index
));
209 struct UsbStdStrDesc
*strdesc
= (struct UsbStdStrDesc
*) ioreq
->iouh_Data
;
214 strdesc
->bLength
= sizeof(struct UsbStdStrDesc
);
215 strdesc
->bDescriptorType
= UDT_STRING
;
216 ioreq
->iouh_Actual
= 2;
219 strdesc
->bString
[0] = AROS_WORD2LE(0x0409); // English (Yankee)
220 ioreq
->iouh_Actual
= sizeof(struct UsbStdStrDesc
);
223 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
224 return UHIOERR_NO_ERROR
;
227 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
228 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
232 roothubstring
= roothubstrings
[0];
236 if(unit
->roothub
.devdesc
.bcdUSB
== AROS_WORD2LE(0x0200)) {
237 roothubstring
= roothubstrings
[1];
239 roothubstring
= roothubstrings
[2];
244 roothubstring
= roothubstrings
[3];
248 roothubstring
= roothubstrings
[4];
252 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
253 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
257 UBYTE i
= strlen(roothubstring
);
259 strdesc
->bLength
= (i
*sizeof(strdesc
->bString
))+sizeof(strdesc
->bLength
)+sizeof(strdesc
->bDescriptorType
);
260 strdesc
->bDescriptorType
= UDT_STRING
;
261 ioreq
->iouh_Actual
= 2;
264 for(i
=0; i
<wLength
; i
++) {
265 strdesc
->bString
[i
] = AROS_WORD2LE((UWORD
)roothubstring
[i
]);
269 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
270 return UHIOERR_NO_ERROR
;
273 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
274 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
279 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
280 return UHIOERR_BADPARAMS
; //CHECKME: Should we return stall?
286 UWORD
SetDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
287 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
288 mybug_unit(-1, ("Entering function\n"));
292 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
293 return UHIOERR_NO_ERROR
;
297 /* Hub Class Requests */
300 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
301 bRequest USR_CLEAR_FEATURE
302 wValue Feature Selector
307 Usb Hub Feature Selectors
308 #define UFS_C_HUB_LOCAL_POWER 0x00
309 #define UFS_C_HUB_OVER_CURRENT 0x01
310 #define UFS_PORT_CONNECTION 0x00
311 #define UFS_PORT_ENABLE 0x01
312 #define UFS_PORT_SUSPEND 0x02
313 #define UFS_PORT_OVER_CURRENT 0x03
314 #define UFS_PORT_RESET 0x04
315 #define UFS_PORT_POWER 0x08
316 #define UFS_PORT_LOW_SPEED 0x09
317 #define UFS_C_PORT_CONNECTION 0x10
318 #define UFS_C_PORT_ENABLE 0x11
319 #define UFS_C_PORT_SUSPEND 0x12
320 #define UFS_C_PORT_OVER_CURRENT 0x13
321 #define UFS_C_PORT_RESET 0x14
322 #define UFS_PORT_TEST 0x15
323 #define UFS_PORT_INDICATOR 0x16
326 UWORD
ClearHubFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
327 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
328 mybug_unit(-1, ("Entering function\n"));
330 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
331 return UHIOERR_NO_ERROR
;
336 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
337 bRequest USR_SET_FEATURE
338 wValue Feature Selector
343 UWORD
SetHubFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
344 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
345 mybug_unit(-1, ("Entering function\n"));
347 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
348 return UHIOERR_NO_ERROR
;
354 UWORD
ClearTTBuffer(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
355 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
356 mybug_unit(-1, ("Entering function\n"));
358 return UHIOERR_NO_ERROR
;
362 GetHubDescriptor: (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
364 UWORD
GetHubDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
365 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
366 mybug_unit(-1, ("Entering function\n"));
368 switch((wValue
>>8)) {
370 mybug_unit(-1, ("GetHubDescriptor UDT_HUB (length %ld)\n", wLength
));
372 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbHubDesc
)) ? sizeof(struct UsbHubDesc
) : wLength
;
373 CopyMem((APTR
) &unit
->roothub
.hubdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
375 //unit->roothub.hubdesc.PortPwrCtrlMask = (1<<1);
376 //unit->roothub.hubdesc.DeviceRemovable = 0;
377 //unit->roothub.hubdesc.PortPwrCtrlMask = (1<<(1+2))-2;
379 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
380 return UHIOERR_NO_ERROR
;
384 mybug_unit(-1, ("GetHubDescriptor UDT_SSHUB (length %ld)\n", wLength
));
386 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbHubDesc
)) ? sizeof(struct UsbHubDesc
) : wLength
;
387 CopyMem((APTR
) &unit
->roothub
.hubdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
389 //unit->roothub.hubdesc.PortPwrCtrlMask = (1<<1);
390 //unit->roothub.hubdesc.DeviceRemovable = 0;
391 //unit->roothub.hubdesc.PortPwrCtrlMask = (1<<(1+2))-2;
393 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
394 return UHIOERR_NO_ERROR
;
397 } /* switch( (wValue>>8) ) */
399 return UHIOERR_BADPARAMS
;
404 bmRequestType (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
405 bRequest USR_GET_STATUS
409 Data Hub Status and Change Status
411 UWORD
GetHubStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
412 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
413 mybug_unit(-1, ("Entering function\n"));
415 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
416 if( (!(wValue
)) && (!(wIndex
)) && (wLength
== 4) ) {
418 struct UsbHubStatus
*usbhubstatus
= (struct UsbHubStatus
*) ioreq
->iouh_Data
;
420 usbhubstatus
->wHubStatus
= unit
->roothub
.hubstatus
.wHubStatus
;
421 usbhubstatus
->wHubChange
= unit
->roothub
.hubstatus
.wHubChange
;
423 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
424 return UHIOERR_NO_ERROR
;
427 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
428 return UHIOERR_BADPARAMS
;
433 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
434 bRequest USR_GET_STATUS
438 Data Port Status and Change Status
440 UWORD
GetPortStatus(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
441 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
442 mybug_unit(-1, ("Entering function\n"));
444 if( (!wIndex
) || (wIndex
> unit
->roothub
.hubdesc
.bNbrPorts
) ) {
445 mybug_unit(-1, ("Port %ld out of range\n", wIndex
));
446 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
447 return UHIOERR_BADPARAMS
;
450 /* FIXME: Check wLength */
452 struct UsbPortStatus
*usbportstatus
= (struct UsbPortStatus
*) ioreq
->iouh_Data
;
454 /* Fake connection */
455 //unit->roothub.portstatus.wPortStatus |= AROS_WORD2LE(UPSF_PORT_CONNECTION);
456 //unit->roothub.portstatus.wPortChange |= AROS_WORD2LE(UPSF_PORT_CONNECTION);
458 /* We have only one port per 'controller' */
459 usbportstatus
->wPortStatus
= unit
->roothub
.portstatus
.wPortStatus
;
460 usbportstatus
->wPortChange
= unit
->roothub
.portstatus
.wPortChange
;
462 mybug_unit(-1, ("usbportstatus->wPortStatus %01x\n", usbportstatus
->wPortStatus
));
464 if(usbportstatus
->wPortStatus
&UPSF_PORT_CONNECTION
) {
465 mybug_unit(-1, (" - UPSF_PORT_CONNECTION\n"));
468 if(usbportstatus
->wPortStatus
&UPSF_PORT_ENABLE
) {
469 mybug_unit(-1, (" - UPSF_PORT_ENABLE\n"));
472 if(usbportstatus
->wPortStatus
&UPSF_PORT_SUSPEND
) {
473 mybug_unit(-1, (" - UPSF_PORT_SUSPEND\n"));
476 if(usbportstatus
->wPortStatus
&UPSF_PORT_OVER_CURRENT
) {
477 mybug_unit(-1, (" - UPSF_PORT_OVER_CURRENT\n"));
480 if(usbportstatus
->wPortStatus
&UPSF_PORT_RESET
) {
481 mybug_unit(-1, (" - UPSF_PORT_RESET\n"));
484 if(usbportstatus
->wPortStatus
&UPSF_PORT_POWER
) {
485 mybug_unit(-1, (" - UPSF_PORT_POWER\n"));
488 if(usbportstatus
->wPortStatus
&UPSF_PORT_LOW_SPEED
) {
489 mybug_unit(-1, (" - UPSF_PORT_LOW_SPEED\n"));
492 if(usbportstatus
->wPortStatus
&UPSF_PORT_HIGH_SPEED
) {
493 mybug_unit(-1, (" - UPSF_PORT_HIGH_SPEED\n"));
496 if(usbportstatus
->wPortStatus
&UPSF_PORT_TEST_MODE
) {
497 mybug_unit(-1, (" - UPSF_PORT_TEST_MODE\n"));
500 if(usbportstatus
->wPortStatus
&UPSF_PORT_INDICATOR
) {
501 mybug_unit(-1, (" - UPSF_PORT_INDICATOR\n"));
504 mybug_unit(-1, ("usbportstatus->wPortChange %01x\n", usbportstatus
->wPortChange
));
506 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
507 return UHIOERR_NO_ERROR
;
512 UWORD
ResetTT(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
513 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
514 mybug_unit(-1, ("Entering function\n"));
516 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
517 return UHIOERR_NO_ERROR
;
522 UWORD
SetHubDescriptor(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
523 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
524 mybug_unit(-1, ("Entering function\n"));
526 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
527 return UHIOERR_NO_ERROR
;
532 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
533 bRequest USR_SET_FEATURE
534 wValue Feature Selector
535 wIndex (Selector|Port)
540 FIXME: Check valid port range, remove some switches if needed (copy paste from definitions)
543 UWORD
SetPortFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
544 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
545 mybug_unit(-1, ("Entering function\n"));
549 port
= (wIndex
& 0xff);
551 mybug_unit(-1, ("Setting feature 0x%02x on port %d\n",wValue
, port
));
555 mybug_unit(-1, ("UFS_PORT_CONNECTION 0x00\n"));
558 mybug_unit(-1, ("UFS_PORT_ENABLE 0x01\n"));
559 unit
->roothub
.portstatus
.wPortStatus
|= UPSF_PORT_ENABLE
;
562 mybug_unit(-1, ("UFS_PORT_SUSPEND 0x02\n"));
565 mybug_unit(-1, ("UFS_PORT_OVER_CURRENT 0x03\n"));
568 mybug_unit(-1, ("UFS_PORT_RESET 0x04\n"));
569 unit
->roothub
.portstatus
.wPortStatus
|= (UPSF_PORT_ENABLE
|UPSF_PORT_POWER
);
572 mybug_unit(-1, ("UFS_PORT_POWER 0x08\n"));
573 unit
->roothub
.portstatus
.wPortStatus
|= UPSF_PORT_POWER
;
576 mybug_unit(-1, ("UFS_PORT_LOW_SPEED 0x09\n"));
579 mybug_unit(-1, ("UFS_C_PORT_CONNECTION 0x10\n"));
582 mybug_unit(-1, ("UFS_C_PORT_ENABLE 0x11\n"));
585 mybug_unit(-1, ("UFS_C_PORT_SUSPEND 0x12\n"));
588 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT 0x13\n"));
591 mybug_unit(-1, ("UFS_C_PORT_RESET 0x14\n"));
594 mybug_unit(-1, ("UFS_PORT_TEST 0x15\n"));
597 mybug_unit(-1, ("UFS_PORT_INDICATOR 0x16\n"));
601 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
602 return UHIOERR_NO_ERROR
;
607 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
608 bRequest USR_CLEAR_FEATURE
609 wValue Feature Selector
610 wIndex (Selector|Port)
615 FIXME: Check valid port range, remove some switches if needed (copy paste from definitions)
618 UWORD
ClearPortFeature(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
619 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
620 mybug_unit(-1, ("Entering function\n"));
624 port
= (wIndex
& 0xff);
626 mybug_unit(-1, ("Clearing feature 0x%02x on port %d\n",wValue
, port
));
629 #define UPSF_PORT_CONNECTION 0x0001
630 #define UPSF_PORT_ENABLE 0x0002
631 #define UPSF_PORT_SUSPEND 0x0004
632 #define UPSF_PORT_OVER_CURRENT 0x0008
633 #define UPSF_PORT_RESET 0x0010
634 #define UPSF_PORT_POWER 0x0100
635 #define UPSF_PORT_LOW_SPEED 0x0200
636 #define UPSF_PORT_HIGH_SPEED 0x0400
637 #define UPSF_PORT_TEST_MODE 0x0800
638 #define UPSF_PORT_INDICATOR 0x1000
642 mybug_unit(-1, ("UFS_PORT_CONNECTION 0x00\n"));
643 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_CONNECTION
;
646 mybug_unit(-1, ("UFS_PORT_ENABLE 0x01\n"));
647 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_ENABLE
;
650 mybug_unit(-1, ("UFS_PORT_SUSPEND 0x02\n"));
653 mybug_unit(-1, ("UFS_PORT_OVER_CURRENT 0x03\n"));
656 mybug_unit(-1, ("UFS_PORT_RESET 0x04\n"));
657 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_RESET
;
660 mybug_unit(-1, ("UFS_PORT_POWER 0x08\n"));
661 unit
->roothub
.portstatus
.wPortStatus
&= ~UPSF_PORT_POWER
;
664 mybug_unit(-1, ("UFS_PORT_LOW_SPEED 0x09\n"));
667 mybug_unit(-1, ("UFS_C_PORT_CONNECTION 0x10\n"));
668 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_CONNECTION
;
671 mybug_unit(-1, ("UFS_C_PORT_ENABLE 0x11\n"));
672 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_ENABLE
;
675 mybug_unit(-1, ("UFS_C_PORT_SUSPEND 0x12\n"));
676 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_SUSPEND
;
679 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT 0x13\n"));
680 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_OVER_CURRENT
;
683 mybug_unit(-1, ("UFS_C_PORT_RESET 0x14\n"));
684 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_RESET
;
687 mybug_unit(-1, ("UFS_PORT_TEST 0x15\n"));
688 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_TEST_MODE
;
691 mybug_unit(-1, ("UFS_PORT_INDICATOR 0x16\n"));
692 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_INDICATOR
;
696 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
697 return UHIOERR_NO_ERROR
;
702 UWORD
GetTTState(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
703 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
704 mybug_unit(-1, ("Entering function\n"));
706 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
707 return UHIOERR_NO_ERROR
;
712 UWORD
StopTT(struct IOUsbHWReq
*ioreq
, UWORD wValue
, UWORD wIndex
, UWORD wLength
) {
713 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
714 mybug_unit(-1, ("Entering function\n"));
716 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
717 return UHIOERR_NO_ERROR
;
721 WORD
cmdControlXFerRootHub(struct IOUsbHWReq
*ioreq
) {
723 UWORD bmRequestType
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_STANDARD
| URTF_CLASS
| URTF_VENDOR
);
724 UWORD bmRequestDirection
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_IN
| URTF_OUT
);
725 UWORD bmRequestRecipient
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_DEVICE
| URTF_INTERFACE
| URTF_ENDPOINT
| URTF_OTHER
);
727 UWORD bRequest
= (ioreq
->iouh_SetupData
.bRequest
);
728 UWORD wValue
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wValue
);
729 UWORD wIndex
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wIndex
);
730 UWORD wLength
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wLength
);
732 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
734 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
735 if(ioreq
->iouh_Endpoint
!= 0) {
736 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq
->iouh_Endpoint
));
737 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
738 return UHIOERR_BADPARAMS
;
741 switch(((ULONG
)ioreq
->iouh_SetupData
.bmRequestType
<<16)|((ULONG
)ioreq
->iouh_SetupData
.bRequest
)) {
743 /* Standard Requests */
744 case ((((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
))<<16)|(USR_SET_ADDRESS
)):
745 return(SetAddress(ioreq
, wValue
, wIndex
, wLength
));
747 case ((((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
))<<16)|(USR_SET_CONFIGURATION
)):
748 return(SetConfiguration(ioreq
, wValue
, wIndex
, wLength
));
750 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_GET_STATUS
)):
751 return(GetStatus(ioreq
, wValue
, wIndex
, wLength
));
753 case (((URTF_IN
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_GET_DESCRIPTOR
)):
754 return(GetDescriptor(ioreq
, wValue
, wIndex
, wLength
));
756 case (((URTF_OUT
|URTF_STANDARD
|URTF_DEVICE
)<<16)|(USR_SET_DESCRIPTOR
)):
757 return(SetDescriptor(ioreq
, wValue
, wIndex
, wLength
));
759 /* Hub Class Requests */
760 case (((URTF_OUT
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_CLEAR_FEATURE
)):
761 return(ClearHubFeature(ioreq
, wValue
, wIndex
, wLength
));
763 case (((URTF_OUT
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_SET_FEATURE
)):
764 return(SetHubFeature(ioreq
, wValue
, wIndex
, wLength
));
766 case (((URTF_OUT
|URTF_CLASS
|URTF_OTHER
)<<16)|(USR_CLEAR_FEATURE
)):
767 return(ClearPortFeature(ioreq
, wValue
, wIndex
, wLength
));
769 case (((URTF_OUT
|URTF_CLASS
|URTF_OTHER
)<<16)|(USR_SET_FEATURE
)):
770 return(SetPortFeature(ioreq
, wValue
, wIndex
, wLength
));
772 case (((URTF_IN
|URTF_CLASS
|URTF_DEVICE
)<<16)|(USR_GET_DESCRIPTOR
)):
773 return(GetHubDescriptor(ioreq
, wValue
, wIndex
, wLength
));
775 case ((((URTF_IN
|URTF_CLASS
|URTF_DEVICE
))<<16)|(USR_GET_STATUS
)):
776 return(GetHubStatus(ioreq
, wValue
, wIndex
, wLength
));
778 case ((((URTF_IN
|URTF_CLASS
|URTF_OTHER
))<<16)|(USR_GET_STATUS
)):
779 return(GetPortStatus(ioreq
, wValue
, wIndex
, wLength
));
781 // case (((( X ))<<16)|( X )):
782 // return( X (ioreq));
788 D( mybug_unit(-1, ("bmRequestDirection "));
789 switch (bmRequestDirection
) {
791 mybug(-1, ("URTF_IN\n"));
794 mybug(-1, ("URTF_OUT\n"));
798 mybug_unit(-1, ("bmRequestType "));
799 switch(bmRequestType
) {
801 mybug(-1, ("URTF_STANDARD\n"));
804 mybug(-1, ("URTF_CLASS\n"));
807 mybug(-1, ("URTF_VENDOR\n"));
811 mybug_unit(-1, ("bmRequestRecipient "));
812 switch (bmRequestRecipient
) {
814 mybug(-1, ("URTF_DEVICE\n"));
817 mybug(-1, ("URTF_INTERFACE\n"));
820 mybug(-1, ("URTF_ENDPOINT\n"));
823 mybug(-1, ("URTF_OTHER\n"));
827 mybug_unit(-1, ("bRequest "));
830 bug("USR_GET_STATUS\n");
832 case USR_CLEAR_FEATURE
:
833 mybug(-1, ("USR_CLEAR_FEATURE\n"));
835 case USR_SET_FEATURE
:
836 mybug(-1, ("USR_SET_FEATURE\n"));
838 case USR_SET_ADDRESS
:
839 mybug(-1, ("USR_SET_ADDRESS\n"));
841 case USR_GET_DESCRIPTOR
:
842 mybug(-1, ("USR_GET_DESCRIPTOR\n"));
844 case USR_SET_DESCRIPTOR
:
845 mybug(-1, ("USR_SET_DESCRIPTOR\n"));
847 case USR_GET_CONFIGURATION
:
848 mybug(-1, ("USR_GET_CONFIGURATION\n"););
850 case USR_SET_CONFIGURATION
:
851 mybug(-1, ("USR_SET_CONFIGURATION\n"));
853 case USR_GET_INTERFACE
:
854 mybug(-1, ("USR_GET_INTERFACE\n"));
856 case USR_SET_INTERFACE
:
857 mybug(-1, ("USR_SET_INTERFACE\n"));
859 case USR_SYNCH_FRAME
:
860 mybug(-1, ("USR_SYNCH_FRAME\n"));
864 mybug_unit(-1, ("wIndex %x\n", wIndex
));
865 mybug_unit(-1, ("wValue %x\n", wValue
));
866 mybug_unit(-1, ("wLength %d\n", wLength
));
868 mybug_unit(-1, ("Nothing done!\n\n")) );
869 return UHIOERR_BADPARAMS
;
872 WORD
cmdIntXFerRootHub(struct IOUsbHWReq
*ioreq
) {
873 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
875 mybug_unit(0, ("Entering function\n"));
877 if((ioreq
->iouh_Endpoint
!= 1) || (!ioreq
->iouh_Length
)) {
878 mybug_unit(-1, ("UHIOERR_BADPARAMS\n"));
879 return(UHIOERR_BADPARAMS
); // was UHIOERR_STALL
883 if(unit
->roothub
.portstatus
.wPortChange
) {
884 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit
->roothub
.portstatus
.wPortChange
));
885 *((UBYTE
*) ioreq
->iouh_Data
) = unit
->roothub
.portstatus
.wPortChange
;
886 ioreq
->iouh_Actual
= 1;
887 unit
->roothub
.portstatus
.wPortChange
&= ~UPSF_PORT_CONNECTION
;
888 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit
->roothub
.portstatus
.wPortChange
));
893 mybug_unit(0, ("ioreq added to roothub intrxfer_queue\n"));
895 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
897 AddTail(&unit
->roothub
.intrxfer_queue
, (struct Node
*) ioreq
);
899 return(RC_DONTREPLY
);
903 WORD
cmdControlXFer(struct IOUsbHWReq
*ioreq
) {
904 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
906 mybug_unit(-1, ("Entering function\n"));
908 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
909 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
912 Check the status of the controller
913 We might encounter these states:
914 UHSB_OPERATIONAL USB can be used for transfers
915 UHSB_RESUMING USB is currently resuming
916 UHSB_SUSPENDED USB is in suspended state
917 UHSB_RESET USB is just inside a reset phase
920 if(unit
->state
== UHSF_OPERATIONAL
) {
921 mybug_unit(0, ("Unit state is operational\n"));
923 mybug_unit(-1, ("Unit state is not operational!\n"));
924 return UHIOERR_USBOFFLINE
;
927 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
928 return(cmdControlXFerRootHub(ioreq
));
931 mybug_unit(-1, ("Sending transfer request to libusb\n\n"));
932 return(do_libusb_ctrl_transfer(ioreq
));
935 WORD
cmdIntXFer(struct IOUsbHWReq
*ioreq
) {
936 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
938 mybug_unit(0, ("Entering function\n"));
940 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
941 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
944 Check the status of the controller
945 We might encounter these states:
946 UHSB_OPERATIONAL USB can be used for transfers
947 UHSB_RESUMING USB is currently resuming
948 UHSB_SUSPENDED USB is in suspended state
949 UHSB_RESET USB is just inside a reset phase
952 if(unit
->state
== UHSF_OPERATIONAL
) {
953 mybug_unit(0, ("Unit state is operational\n"));
955 mybug_unit(-1, ("Unit state is not operational!\n"));
956 return UHIOERR_USBOFFLINE
;
959 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
960 return(cmdIntXFerRootHub(ioreq
));
963 mybug_unit(-1, ("Sending transfer request to libusb\n"));
964 return(do_libusb_intr_transfer(ioreq
));
967 WORD
cmdBulkXFer(struct IOUsbHWReq
*ioreq
) {
968 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
970 mybug_unit(0, ("Entering function\n"));
972 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
973 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
976 Check the status of the controller
977 We might encounter these states:
978 UHSB_OPERATIONAL USB can be used for transfers
979 UHSB_RESUMING USB is currently resuming
980 UHSB_SUSPENDED USB is in suspended state
981 UHSB_RESET USB is just inside a reset phase
984 if(unit
->state
== UHSF_OPERATIONAL
) {
985 mybug_unit(0, ("Unit state is operational\n"));
987 mybug_unit(-1, ("Unit state is not operational!\n"));
988 return UHIOERR_USBOFFLINE
;
991 mybug_unit(0, ("Sending transfer request to libusb\n"));
992 return(do_libusb_bulk_transfer(ioreq
));
995 WORD
cmdISOXFer(struct IOUsbHWReq
*ioreq
) {
996 struct VUSBHCIUnit
*unit
= (struct VUSBHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
998 mybug_unit(-1, ("Entering function\n"));
1000 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
1001 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
1004 Check the status of the controller
1005 We might encounter these states:
1006 UHSB_OPERATIONAL USB can be used for transfers
1007 UHSB_RESUMING USB is currently resuming
1008 UHSB_SUSPENDED USB is in suspended state
1009 UHSB_RESET USB is just inside a reset phase
1012 if(unit
->state
== UHSF_OPERATIONAL
) {
1013 mybug_unit(0, ("Unit state is operational\n"));
1015 mybug_unit(-1, ("Unit state is not operational!\n"));
1016 return UHIOERR_USBOFFLINE
;
1019 mybug_unit(-1, ("Sending transfer request to libusb\n"));
1020 do_libusb_isoc_transfer(ioreq
);
1022 return RC_DONTREPLY
;
1025 void uhwCheckRootHubChanges(struct VUSBHCIUnit
*unit
) {
1026 mybug_unit(0, ("Entering function\n"));
1028 mybug_unit(0, ("usbportstatus->wPortStatus %01x\n", unit
->roothub
.portstatus
.wPortStatus
));
1029 mybug_unit(0, ("usbportstatus->wPortChange %01x\n", unit
->roothub
.portstatus
.wPortChange
));
1031 struct IOUsbHWReq
*ioreq
;
1033 if(unit
->roothub
.portstatus
.wPortChange
&& unit
->roothub
.intrxfer_queue
.lh_Head
->ln_Succ
) {
1035 ioreq
= (struct IOUsbHWReq
*) unit
->roothub
.intrxfer_queue
.lh_Head
;
1036 while(((struct Node
*) ioreq
)->ln_Succ
) {
1037 Remove(&ioreq
->iouh_Req
.io_Message
.mn_Node
);
1039 *((UBYTE
*) ioreq
->iouh_Data
) = (1<<1);
1040 ioreq
->iouh_Actual
= 1;
1042 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
1043 ioreq
= (struct IOUsbHWReq
*) unit
->roothub
.intrxfer_queue
.lh_Head
;