2 Copyright © 2014, The AROS Development Team. All rights reserved.
5 Desc: PCI XHCI USB host controller
15 #include <aros/debug.h>
16 #include <aros/macros.h>
17 #include <aros/asmcall.h>
18 #include <aros/symbolsets.h>
20 #include <proto/oop.h>
21 #include <proto/exec.h>
22 #include <proto/stdc.h>
23 #include <proto/arossupport.h>
25 #include <devices/usb.h>
26 #include <devices/usb_hub.h>
27 #include <devices/newstyle.h>
28 #include <devices/usbhardware.h>
34 #include <hidd/hidd.h>
36 #include "pcixhci_intern.h"
38 #include LC_LIBDEFS_FILE
40 WORD
cmdQueryDevice(struct IOUsbHWReq
*ioreq
) {
42 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
44 mybug_unit(0, ("Entering function\n"));
46 struct TagItem
*taglist
= (struct TagItem
*) ioreq
->iouh_Data
;
50 while((tag
= LibNextTagItem(&taglist
)) != NULL
) {
51 switch (tag
->ti_Tag
) {
52 case UHA_Manufacturer
:
53 *((STRPTR
*) tag
->ti_Data
) = "The AROS Development Team";
57 *((ULONG
*) tag
->ti_Data
) = VERSION_NUMBER
;
61 *((ULONG
*) tag
->ti_Data
) = REVISION_NUMBER
;
65 *((STRPTR
*) tag
->ti_Data
) ="©2014 The AROS Development Team";
69 *((STRPTR
*) tag
->ti_Data
) = "PCI XHCI USB 3.0 Host Controller Driver";
73 *((STRPTR
*) tag
->ti_Data
) = "PCI Extensible Host Controller Interface";
76 case UHA_Capabilities
:
79 - Guarantees access to bandwidth but a packet or frame maybe dropped now and then
80 - Isochronous transfers occur continuously and periodically.
81 - The maximum data payload size is specified in the endpoint descriptor of an Isochronous Endpoint
82 - Check if alternative interfaces with varying isochronous payload sizes exist.
83 - Data being sent on an isochronous endpoint can be less than the pre-negotiated size and may vary in length from transaction to transaction
85 *((ULONG
*) tag
->ti_Data
) = (UHCF_USB30
|UHCF_ISO
);
93 mybug_unit(0, ("Done\n\n"));
95 ioreq
->iouh_Actual
= count
;
99 BOOL
cmdAbortIO(struct IOUsbHWReq
*ioreq
) {
100 ioreq
->iouh_Req
.io_Error
= IOERR_ABORTED
;
101 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
103 /* If not quick I/O, reply the message */
104 if (!(ioreq
->iouh_Req
.io_Flags
& IOF_QUICK
)) {
105 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
113 Perform a hardware reset on the controller.
114 WORD cmdReset(struct IOUsbHWReq *ioreq) {
116 struct PCIXHCIUnit *unit = (struct PCIXHCIUnit *) ioreq->iouh_Req.io_Unit;
118 mybug_unit(-1, ("Entering function\n"));
120 if(PCIXHCI_HCReset(unit)) {
121 mybug_unit(-1, ("Done with OK\n\n"));
124 mybug_unit(-1, ("Done with not OK\n\n"));
125 return UHIOERR_HOSTERROR;
131 We get called when the driver is first added
132 Driver init code has already reseted the controller and set it in operational mode
133 The way things are implemented right now is a bit messy...
134 - psdAddHardware->pDeviceTask()->OpenDevice()->driver init code->hw reset
135 - psdEnumerateHardware(UHCMD_USBRESET)->cmdUsbReset
136 We can't do a squat without first halting and reseting the controller so we do it in the init code.
138 WORD
cmdUsbReset(struct IOUsbHWReq
*ioreq
) {
140 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
141 struct PCIXHCIPort
*port
= NULL
;
143 mybug_unit(-1, ("Entering function\n"));
145 /* (Re)build descriptors */
146 /* This is our root hub device descriptor */
147 unit
->roothub
.devdesc
.bLength
= sizeof(struct UsbStdDevDesc
);
148 unit
->roothub
.devdesc
.bDescriptorType
= UDT_DEVICE
;
149 unit
->roothub
.devdesc
.bcdUSB
= AROS_WORD2LE(0x0300);
150 unit
->roothub
.devdesc
.bDeviceClass
= HUB_CLASSCODE
;
151 unit
->roothub
.devdesc
.bDeviceSubClass
= 0;
152 unit
->roothub
.devdesc
.bDeviceProtocol
= 0;
153 unit
->roothub
.devdesc
.bMaxPacketSize0
= 9; // Valid values are 8, 9(SuperSpeed), 16, 32, 64
154 unit
->roothub
.devdesc
.idVendor
= AROS_WORD2LE(0x0000);
155 unit
->roothub
.devdesc
.idProduct
= AROS_WORD2LE(0x0000);
156 unit
->roothub
.devdesc
.bcdDevice
= AROS_WORD2LE(0x0300);
157 unit
->roothub
.devdesc
.iManufacturer
= 1;
158 unit
->roothub
.devdesc
.iProduct
= 2;
159 unit
->roothub
.devdesc
.iSerialNumber
= 0;
160 unit
->roothub
.devdesc
.bNumConfigurations
= 1;
162 /* This is our root hub config descriptor */
163 unit
->roothub
.config
.cfgdesc
.bLength
= sizeof(struct UsbStdCfgDesc
);
164 unit
->roothub
.config
.cfgdesc
.bDescriptorType
= UDT_CONFIGURATION
;
165 unit
->roothub
.config
.cfgdesc
.wTotalLength
= AROS_WORD2LE(sizeof(struct RHConfig
));
166 unit
->roothub
.config
.cfgdesc
.bNumInterfaces
= 1;
167 unit
->roothub
.config
.cfgdesc
.bConfigurationValue
= 1;
168 unit
->roothub
.config
.cfgdesc
.iConfiguration
= 3;
169 unit
->roothub
.config
.cfgdesc
.bmAttributes
= (USCAF_ONE
|USCAF_SELF_POWERED
);
170 unit
->roothub
.config
.cfgdesc
.bMaxPower
= 0;
172 unit
->roothub
.config
.ifdesc
.bLength
= sizeof(struct UsbStdIfDesc
);
173 unit
->roothub
.config
.ifdesc
.bDescriptorType
= UDT_INTERFACE
;
174 unit
->roothub
.config
.ifdesc
.bInterfaceNumber
= 0;
175 unit
->roothub
.config
.ifdesc
.bAlternateSetting
= 0;
176 unit
->roothub
.config
.ifdesc
.bNumEndpoints
= 1;
177 unit
->roothub
.config
.ifdesc
.bInterfaceClass
= HUB_CLASSCODE
;
178 unit
->roothub
.config
.ifdesc
.bInterfaceSubClass
= 0;
179 unit
->roothub
.config
.ifdesc
.bInterfaceProtocol
= 0;
180 unit
->roothub
.config
.ifdesc
.iInterface
= 4;
182 unit
->roothub
.config
.epdesc
.bLength
= sizeof(struct UsbStdEPDesc
);
183 unit
->roothub
.config
.epdesc
.bDescriptorType
= UDT_ENDPOINT
;
184 unit
->roothub
.config
.epdesc
.bEndpointAddress
= (URTF_IN
|1);
185 unit
->roothub
.config
.epdesc
.bmAttributes
= USEAF_INTERRUPT
;
186 unit
->roothub
.config
.epdesc
.wMaxPacketSize
= AROS_WORD2LE(8);
187 unit
->roothub
.config
.epdesc
.bInterval
= 12;
189 /* This is our root hub hub descriptor */
190 unit
->roothub
.hubdesc
.bLength
= sizeof(struct UsbSSHubDesc
);
191 unit
->roothub
.hubdesc
.bDescriptorType
= UDT_SSHUB
;
192 unit
->roothub
.hubdesc
.bNbrPorts
= 0;
193 ForeachNode(&unit
->roothub
.port_list
, port
) {
194 unit
->roothub
.hubdesc
.bNbrPorts
++;
196 unit
->roothub
.hubdesc
.wHubCharacteristics
= AROS_WORD2LE(UHCF_INDIVID_POWER
|UHCF_INDIVID_OVP
);
197 unit
->roothub
.hubdesc
.bPwrOn2PwrGood
= 0;
198 unit
->roothub
.hubdesc
.bHubContrCurrent
= 10;
199 unit
->roothub
.hubdesc
.bHubHdrDecLat
= 0;
200 unit
->roothub
.hubdesc
.wHubDelay
= 0;
201 unit
->roothub
.hubdesc
.DeviceRemovable
= 0;
202 unit
->roothub
.bosdesc
.bLength
= sizeof(struct UsbStdBOSDesc
);
203 unit
->roothub
.bosdesc
.bDescriptorType
= UDT_BOS
;
204 /* TODO: Arbitrary, set real values according to the host controller */
205 unit
->roothub
.bosdesc
.wTotalLength
= 16;
206 unit
->roothub
.bosdesc
.bNumDeviceCaps
= 2;
208 /* Reset the address */
209 unit
->roothub
.addr
= 0;
211 /* our unit is now in operational state */
212 unit
->state
= UHSF_OPERATIONAL
;
214 mybug_unit(0, ("Done\n\n"));
218 WORD
cmdControlXFer(struct IOUsbHWReq
*ioreq
) {
219 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
221 mybug_unit(0, ("Entering function\n"));
223 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
224 mybug_unit(0, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
227 Check the status of the controller
228 We might encounter these states:
229 UHSB_OPERATIONAL USB can be used for transfers
230 UHSB_RESUMING USB is currently resuming
231 UHSB_SUSPENDED USB is in suspended state
232 UHSB_RESET USB is just inside a reset phase
235 if(unit
->state
== UHSF_OPERATIONAL
) {
236 mybug_unit(0, ("Unit state is operational\n"));
238 mybug_unit(-1, ("Unit state is not operational!\n"));
239 return UHIOERR_USBOFFLINE
;
242 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
243 return(cmdControlXFerRootHub(ioreq
));
249 WORD
cmdControlXFerRootHub(struct IOUsbHWReq
*ioreq
) {
251 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
252 struct PCIXHCIPort
*port
= NULL
;
254 mybug_unit(0, ("Entering function\n"));
256 UWORD bmRequestType
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_STANDARD
| URTF_CLASS
| URTF_VENDOR
);
257 UWORD bmRequestDirection
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_IN
| URTF_OUT
);
258 UWORD bmRequestRecipient
= (ioreq
->iouh_SetupData
.bmRequestType
) & (URTF_DEVICE
| URTF_INTERFACE
| URTF_ENDPOINT
| URTF_OTHER
);
260 UWORD bRequest
= (ioreq
->iouh_SetupData
.bRequest
);
261 UWORD wIndex
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wIndex
);
262 UWORD wValue
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wValue
);
263 UWORD wLength
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wLength
);
265 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
266 if(ioreq
->iouh_Endpoint
!= 0) {
267 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq
->iouh_Endpoint
));
268 return UHIOERR_BADPARAMS
;
271 /* Check the request */
272 if(bmRequestDirection
) {
273 mybug_unit(0, ("Request direction is device to host\n"));
275 switch(bmRequestType
) {
277 mybug_unit(0, ("URTF_STANDARD\n"));
279 switch(bmRequestRecipient
) {
281 mybug_unit(0, ("URTF_DEVICE\n"));
284 case USR_GET_DESCRIPTOR
:
285 mybug_unit(0, ("USR_GET_DESCRIPTOR\n"));
287 switch( (wValue
>>8) ) {
289 mybug_unit(0, ("UDT_DEVICE\n"));
290 mybug_unit(0, ("GetDeviceDescriptor (%ld)\n", wLength
));
292 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbStdDevDesc
)) ? sizeof(struct UsbStdDevDesc
) : wLength
;
293 CopyMem((APTR
) &unit
->roothub
.devdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
295 mybug_unit(0, ("Done\n\n"));
296 return UHIOERR_NO_ERROR
;
299 case UDT_CONFIGURATION
:
300 mybug_unit(0, ("UDT_CONFIGURATION\n"));
301 mybug_unit(0, ("GetConfigDescriptor (%ld)\n", wLength
));
303 ioreq
->iouh_Actual
= (wLength
> sizeof(struct RHConfig
)) ? sizeof(struct RHConfig
) : wLength
;
304 CopyMem((APTR
) &unit
->roothub
.config
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
306 //bug("sizeof(struct RHConfig) = %ld (should be 25)\n", sizeof(struct RHConfig));
307 mybug_unit(0, ("Done\n\n"));
308 return UHIOERR_NO_ERROR
;
313 mybug_unit(0, ("UDT_STRING id %d\n", (wValue
& 0xff)));
316 switch( (wValue
& 0xff) ) {
318 mybug_unit(0, ("GetStringDescriptor (%ld)\n", wLength
));
320 /* This is our root hub string descriptor */
321 struct UsbStdStrDesc
*strdesc
= (struct UsbStdStrDesc
*) ioreq
->iouh_Data
;
323 strdesc
->bLength
= sizeof(struct UsbStdStrDesc
);
324 strdesc
->bDescriptorType
= UDT_STRING
;
327 strdesc
->bString
[0] = AROS_WORD2LE(0x0409); // English (Yankee)
328 ioreq
->iouh_Actual
= sizeof(struct UsbStdStrDesc
);
329 mybug_unit(0, ("Done\n\n"));
330 return UHIOERR_NO_ERROR
;
332 ioreq
->iouh_Actual
= wLength
;
333 mybug_unit(0, ("Done\n\n"));
334 return UHIOERR_NO_ERROR
;
340 return cmdGetString(ioreq
, "The AROS Development Team.");
344 char roothubname
[100];
345 snprintf(roothubname
, 99, "XHCI Root Hub Unit %d", unit
->number
);
346 return cmdGetString(ioreq
, roothubname
);
351 return cmdGetString(ioreq
, "Standard Config");
355 return cmdGetString(ioreq
, "Hub interface");
366 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE\n");
370 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_ENDPOINT\n");
373 case UDT_DEVICE_QUALIFIER
:
374 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEVICE_QUALIFIER\n");
377 case UDT_OTHERSPEED_QUALIFIER
:
378 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_OTHERSPEED_QUALIFIER\n");
381 case UDT_INTERFACE_POWER
:
382 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE_POWER\n");
386 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_OTG\n");
390 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEBUG\n");
393 case UDT_INTERFACE_ASSOCIATION
:
394 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE_ASSOCIATION\n");
398 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_SECURITY\n");
401 case UDT_ENCRYPTION_TYPE
:
402 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_ENCRYPTION_TYPE\n");
406 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_BOS\n");
408 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbStdBOSDesc
)) ? sizeof(struct UsbStdBOSDesc
) : wLength
;
409 CopyMem((APTR
) &unit
->roothub
.bosdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
411 mybug_unit(0, ("Done\n\n"));
412 return UHIOERR_NO_ERROR
;
415 case UDT_DEVICE_CAPABILITY
:
416 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEVICE_CAPABILITY\n");
419 case UDT_WIRELESS_EP_COMP
:
420 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_WIRELESS_EP_COMP\n");
424 bug("[PCIXHCI] cmdControlXFerRootHub: switch( (wValue>>8) ) %ld\n", (wValue
>>8));
427 } /* switch( (wValue>>8) ) */
428 break; /* case USR_GET_DESCRIPTOR */
431 mybug_unit(0, ("USR_GET_STATUS\n"));
432 ((UWORD
*) ioreq
->iouh_Data
)[0] = AROS_WORD2LE(U_GSF_SELF_POWERED
);
433 ioreq
->iouh_Actual
= wLength
;
434 mybug_unit(0, ("Done\n\n"));
435 return UHIOERR_NO_ERROR
;
438 } /* switch(bRequest) */
439 break; /* case URTF_DEVICE: */
441 /* switch(bmRequestRecipient) */
443 mybug_unit(0, ("URTF_INTERFACE\n"));
446 /* switch(bmRequestRecipient) */
448 mybug_unit(0, ("URTF_ENDPOINT\n"));
451 /* switch(bmRequestRecipient) */
453 mybug_unit(0, ("URTF_OTHER\n"));
456 /* switch(bmRequestRecipient) */
458 mybug_unit(0, ("Request defaulting %ld\n", bRequest
));
461 } /* switch(bmRequestRecipient) */
464 /* switch(bmRequestType) */
466 mybug_unit(0, ("URTF_CLASS\n"));
468 switch(bmRequestRecipient
) {
470 mybug_unit(0, ("URTF_DEVICE\n"));
474 mybug_unit(-1, ("USR_GET_STATUS\n"));
475 UWORD
*mptr
= ioreq
->iouh_Data
;
476 if(wLength
< sizeof(struct UsbHubStatus
)) {
481 ioreq
->iouh_Actual
= 4;
482 mybug_unit(-1, ("Something done, check me...\n\n"));
483 return UHIOERR_NO_ERROR
;
486 /* switch(bRequest) */
487 case USR_GET_DESCRIPTOR
:
488 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: USR_GET_DESCRIPTOR\n"));
490 switch( (wValue
>>8) ) {
492 mybug_unit(0, ("UDT_SSHUB\n"));
493 mybug_unit(0, ("GetRootHubDescriptor USB3.0 (%ld)\n", wLength
));
495 ioreq
->iouh_Actual
= (wLength
> sizeof(struct UsbSSHubDesc
)) ? sizeof(struct UsbSSHubDesc
) : wLength
;
496 CopyMem((APTR
) &unit
->roothub
.hubdesc
, ioreq
->iouh_Data
, ioreq
->iouh_Actual
);
498 mybug_unit(0, ("Done\n\n"));
499 return UHIOERR_NO_ERROR
;
502 } /* switch( (wValue>>8) ) */
504 mybug_unit(0, ("Done\n\n"));
505 return UHIOERR_NO_ERROR
;
508 } /* switch(bRequest) */
511 /* switch(bmRequestRecipient) */
513 mybug_unit(0, ("URTF_OTHER\n"));
517 mybug_unit(0, ("USR_GET_STATUS\n"));
518 if(wLength
!= sizeof(struct UsbPortStatus
)) {
519 mybug_unit(-1, ("Invalid port status structure!\n\n"));
523 ForeachNode(&unit
->roothub
.port_list
, port
) {
524 if(port
->number
== wIndex
) {
525 mybug_unit(0, ("Found port %d named %s\n", port
->number
, port
->name
));
527 struct UsbPortStatus
*usbportstatus
= (struct UsbPortStatus
*) ioreq
->iouh_Data
;
529 usbportstatus
->wPortStatus
= 0;
530 usbportstatus
->wPortChange
= 0;
532 mybug_unit(0, ("Done\n\n"));
533 return UHIOERR_NO_ERROR
;
537 mybug_unit(-1, ("Port not found!\n\n"));
540 } /* switch(bRequest) */
543 } /* case URTF_CLASS */
546 /* switch(bmRequestType) */
548 mybug_unit(0, ("URTF_VENDOR\n"));
551 } /* switch(bmRequestType) */
553 } else { /* if(bmRequestDirection) */
554 mybug_unit(0, ("Request direction is host to device\n"));
556 switch(bmRequestType
) {
558 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: URTF_STANDARD\n"));
560 switch(bmRequestRecipient
) {
562 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: URTF_DEVICE\n"));
565 case USR_SET_ADDRESS
:
566 mybug_unit(0, ("USR_SET_ADDRESS\n"));
567 unit
->roothub
.addr
= wValue
;
568 ioreq
->iouh_Actual
= wLength
;
569 mybug_unit(0, ("Done\n\n"));
570 return UHIOERR_NO_ERROR
;
573 case USR_SET_CONFIGURATION
:
574 /* We do not have alternative configuration err... set the device to D0 state = go ?*/
575 mybug_unit(0, ("USR_SET_CONFIGURATION\n"));
576 ioreq
->iouh_Actual
= wLength
;
577 mybug_unit(0, ("Done\n\n"));
578 return UHIOERR_NO_ERROR
;
581 } /* switch(bRequest) */
585 mybug_unit(0, ("URTF_INTERFACE\n"));
589 mybug_unit(0, ("URTF_ENDPOINT\n"));
593 mybug_unit(0, ("URTF_OTHER\n"));
596 } /* switch(bmRequestRecipient) */
600 mybug_unit(0, ("URTF_CLASS\n"));
601 switch(bmRequestRecipient
) {
603 mybug_unit(0, ("URTF_OTHER\n"));
606 case USR_CLEAR_FEATURE
:
607 mybug_unit(-1, ("USR_CLEAR_FEATURE\n"));
611 mybug_unit(-1, ("UFS_PORT_POWER\n"));
613 ForeachNode(&unit
->roothub
.port_list
, port
) {
614 if(port
->number
== wIndex
) {
615 mybug_unit(0, ("Found port %d named %s\n", port
->number
, port
->name
));
616 PCIXHCI_PortPower(unit
, port
->number
, FALSE
);
617 mybug_unit(0, ("Done\n\n"));
618 return UHIOERR_NO_ERROR
;
622 mybug_unit(-1, ("Port not found!\n\n"));
625 case UFS_PORT_CONNECTION
:
626 case UFS_PORT_ENABLE
:
627 case UFS_PORT_SUSPEND
:
628 case UFS_PORT_OVER_CURRENT
:
630 case UFS_PORT_LOW_SPEED
:
631 case UFS_C_PORT_CONNECTION
:
632 case UFS_C_PORT_ENABLE
:
633 case UFS_C_PORT_SUSPEND
:
634 case UFS_C_PORT_OVER_CURRENT
:
635 case UFS_C_PORT_RESET
:
637 } /* switch(wValue) */
640 case USR_SET_FEATURE
:
641 mybug_unit(-1, ("USR_SET_FEATURE\n"));
645 mybug_unit(-1, ("UFS_PORT_POWER\n"));
647 ForeachNode(&unit
->roothub
.port_list
, port
) {
648 if(port
->number
== wIndex
) {
649 mybug_unit(0, ("Found port %d named %s\n", port
->number
, port
->name
));
650 PCIXHCI_PortPower(unit
, port
->number
, TRUE
);
651 mybug_unit(0, ("Done\n\n"));
652 return UHIOERR_NO_ERROR
;
656 mybug_unit(-1, ("Port not found!\n\n"));
659 case UFS_PORT_CONNECTION
:
660 case UFS_PORT_ENABLE
:
661 case UFS_PORT_SUSPEND
:
662 case UFS_PORT_OVER_CURRENT
:
664 case UFS_PORT_LOW_SPEED
:
665 case UFS_C_PORT_CONNECTION
:
666 case UFS_C_PORT_ENABLE
:
667 case UFS_C_PORT_SUSPEND
:
668 case UFS_C_PORT_OVER_CURRENT
:
669 case UFS_C_PORT_RESET
:
671 } /* switch(wValue) */
673 } /* switch(bRequest) */
675 } /* switch(bmRequestRecipient) */
679 mybug_unit(0, ("URTF_VENDOR\n"));
682 } /* switch(bmRequestType) */
684 } /* if(bmRequestDirection) */
686 D( mybug_unit(-1, ("bmRequestDirection "));
687 switch (bmRequestDirection
) {
689 mybug(-1, ("URTF_IN\n"));
692 mybug(-1, ("URTF_OUT\n"));
696 mybug_unit(-1, ("bmRequestType "));
697 switch(bmRequestType
) {
699 mybug(-1, ("URTF_STANDARD\n"));
702 mybug(-1, ("URTF_CLASS\n"));
705 mybug(-1, ("URTF_VENDOR\n"));
709 mybug_unit(-1, ("bmRequestRecipient "));
710 switch (bmRequestRecipient
) {
712 mybug(-1, ("URTF_DEVICE\n"));
715 mybug(-1, ("URTF_INTERFACE\n"));
718 mybug(-1, ("URTF_ENDPOINT\n"));
721 mybug(-1, ("URTF_OTHER\n"));
725 mybug_unit(-1, ("bRequest "));
728 bug("USR_GET_STATUS\n");
730 case USR_CLEAR_FEATURE
:
731 mybug(-1, ("USR_CLEAR_FEATURE\n"));
733 case USR_SET_FEATURE
:
734 mybug(-1, ("USR_SET_FEATURE\n"));
736 case USR_SET_ADDRESS
:
737 mybug(-1, ("USR_SET_ADDRESS\n"));
739 case USR_GET_DESCRIPTOR
:
740 mybug(-1, ("USR_GET_DESCRIPTOR\n"));
742 case USR_SET_DESCRIPTOR
:
743 mybug(-1, ("USR_SET_DESCRIPTOR\n"));
745 case USR_GET_CONFIGURATION
:
746 mybug(-1, ("USR_GET_CONFIGURATION\n"););
748 case USR_SET_CONFIGURATION
:
749 mybug(-1, ("USR_SET_CONFIGURATION\n"));
751 case USR_GET_INTERFACE
:
752 mybug(-1, ("USR_GET_INTERFACE\n"));
754 case USR_SET_INTERFACE
:
755 mybug(-1, ("USR_SET_INTERFACE\n"));
757 case USR_SYNCH_FRAME
:
758 mybug(-1, ("USR_SYNCH_FRAME\n"));
762 mybug_unit(-1, ("wIndex %x\n", wIndex
));
763 mybug_unit(-1, ("wValue %x\n", wValue
));
764 mybug_unit(-1, ("wLength %d\n", wLength
));
766 mybug_unit(-1, ("Nothing done!\n\n")) );
767 return UHIOERR_BADPARAMS
;
770 WORD
cmdIntXFer(struct IOUsbHWReq
*ioreq
) {
772 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
774 mybug_unit(-1, ("Entering function\n"));
776 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq
->iouh_DevAddr
));
777 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit
->roothub
.addr
));
780 Check the status of the controller
781 We might encounter these states:
782 UHSB_OPERATIONAL USB can be used for transfers
783 UHSB_RESUMING USB is currently resuming
784 UHSB_SUSPENDED USB is in suspended state
785 UHSB_RESET USB is just inside a reset phase
788 if(unit
->state
== UHSF_OPERATIONAL
) {
789 mybug_unit(0, ("Unit state is operational\n"));
791 mybug_unit(-1, ("Unit state is not operational!\n"));
792 return UHIOERR_USBOFFLINE
;
795 if(ioreq
->iouh_DevAddr
== unit
->roothub
.addr
) {
796 mybug_unit(-1, ("Entering cmdIntXFerRootHub\n"));
797 return(cmdIntXFerRootHub(ioreq
));
800 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
801 ioreq
->iouh_Actual
= 0;
803 /* Don't send anything yeat to others, change Disable->ObtainSemaphore (=atomics) */
805 // AddTail(&hc->hc_CtrlXFerQueue, (struct Node *) ioreq);
807 // SureCause(base, &hc->hc_CompleteInt);
809 mybug_unit(-1, ("Processed ioreq: %p\n", ioreq
));
813 WORD
cmdIntXFerRootHub(struct IOUsbHWReq
*ioreq
) {
815 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
816 struct PCIXHCIPort
*port
= NULL
;
818 mybug_unit(-1, ("Entering function\n"));
820 if((ioreq
->iouh_Endpoint
!= 1) || (!ioreq
->iouh_Length
)) {
821 return(UHIOERR_STALL
);
825 What to do? I'd like to make use of this port list and send hubss.class something aquired with it
826 I would not like to define any maximum port numbers, we use dynamic lists (no shrinking though...)
828 ForeachNode(&unit
->roothub
.port_list
, port
) {
829 mybug_unit(-1, ("Port %d named %s at %p\n", port
->number
, port
->name
, port
));
830 // if(unit->hu_RootPortChanges) {
831 // unit->hu_RootPortChanges = 0;
837 mybug_unit(-1, ("Nothing done!\n\n"));
839 // ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
841 // AddTail(&unit->hu_RHIOQueue, (struct Node *) ioreq);
847 WORD
cmdGetString(struct IOUsbHWReq
*ioreq
, char *cstring
) {
849 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
851 mybug_unit(0, ("Entering function\n"));
853 UWORD wLength
= AROS_WORD2LE(ioreq
->iouh_SetupData
.wLength
);
855 struct UsbStdStrDesc
*strdesc
= (struct UsbStdStrDesc
*) ioreq
->iouh_Data
;
856 strdesc
->bDescriptorType
= UDT_STRING
;
857 strdesc
->bLength
= (strlen(cstring
)*sizeof(strdesc
->bString
))+sizeof(strdesc
->bLength
) + sizeof(strdesc
->bDescriptorType
);
860 ioreq
->iouh_Actual
= 2;
861 while(ioreq
->iouh_Actual
<wLength
) {
862 strdesc
->bString
[(ioreq
->iouh_Actual
-2)/sizeof(strdesc
->bString
)] = AROS_WORD2LE(*cstring
);
863 ioreq
->iouh_Actual
+= sizeof(strdesc
->bString
);
866 mybug_unit(0, ("Done\n\n"));
867 return UHIOERR_NO_ERROR
;
872 ioreq
->iouh_Actual
= wLength
;
873 mybug_unit(0, ("Done\n\n"));
874 return UHIOERR_NO_ERROR
;
877 return UHIOERR_BADPARAMS
;