revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / pciusbhc / xhci / pcixhci_commands.c
blob61a659b2ceef13fb60e5e7882fa0accd58f89362
1 /*
2 Copyright © 2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PCI XHCI USB host controller
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 #define DEBUG 1
14 #include <aros/io.h>
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>
30 #include <asm/io.h>
31 #include <inttypes.h>
33 #include <hidd/pci.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;
47 struct TagItem *tag;
48 ULONG count = 0;
50 while((tag = LibNextTagItem(&taglist)) != NULL) {
51 switch (tag->ti_Tag) {
52 case UHA_Manufacturer:
53 *((STRPTR *) tag->ti_Data) = "The AROS Development Team";
54 count++;
55 break;
56 case UHA_Version:
57 *((ULONG *) tag->ti_Data) = VERSION_NUMBER;
58 count++;
59 break;
60 case UHA_Revision:
61 *((ULONG *) tag->ti_Data) = REVISION_NUMBER;
62 count++;
63 break;
64 case UHA_Copyright:
65 *((STRPTR *) tag->ti_Data) ="©2014 The AROS Development Team";
66 count++;
67 break;
68 case UHA_ProductName:
69 *((STRPTR *) tag->ti_Data) = "PCI XHCI USB 3.0 Host Controller Driver";
70 count++;
71 break;
72 case UHA_Description:
73 *((STRPTR *) tag->ti_Data) = "PCI Extensible Host Controller Interface";
74 count++;
75 break;
76 case UHA_Capabilities:
78 ISOCHRONOUS:
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);
86 count++;
87 break;
88 default:
89 break;
93 mybug_unit(0, ("Done\n\n"));
95 ioreq->iouh_Actual = count;
96 return RC_OK;
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);
108 return TRUE;
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"));
122 return RC_OK;
123 } else {
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"));
215 return RC_OK;
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"));
237 } else {
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));
246 return RC_DONTREPLY;
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) {
276 case URTF_STANDARD:
277 mybug_unit(0, ("URTF_STANDARD\n"));
279 switch(bmRequestRecipient) {
280 case URTF_DEVICE:
281 mybug_unit(0, ("URTF_DEVICE\n"));
283 switch(bRequest) {
284 case USR_GET_DESCRIPTOR:
285 mybug_unit(0, ("USR_GET_DESCRIPTOR\n"));
287 switch( (wValue>>8) ) {
288 case UDT_DEVICE:
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;
297 break;
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;
310 break;
312 case UDT_STRING:
313 mybug_unit(0, ("UDT_STRING id %d\n", (wValue & 0xff)));
315 if(wLength > 1) {
316 switch( (wValue & 0xff) ) {
317 case 0:
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;
326 if(wLength > 3) {
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;
331 } else {
332 ioreq->iouh_Actual = wLength;
333 mybug_unit(0, ("Done\n\n"));
334 return UHIOERR_NO_ERROR;
337 break;
339 case 1:
340 return cmdGetString(ioreq, "The AROS Development Team.");
341 break;
343 case 2: {
344 char roothubname[100];
345 snprintf(roothubname, 99, "XHCI Root Hub Unit %d", unit->number);
346 return cmdGetString(ioreq, roothubname);
347 break;
350 case 3:
351 return cmdGetString(ioreq, "Standard Config");
352 break;
354 case 4:
355 return cmdGetString(ioreq, "Hub interface");
356 break;
358 default:
359 break;
363 break;
365 case UDT_INTERFACE:
366 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE\n");
367 break;
369 case UDT_ENDPOINT:
370 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_ENDPOINT\n");
371 break;
373 case UDT_DEVICE_QUALIFIER:
374 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEVICE_QUALIFIER\n");
375 break;
377 case UDT_OTHERSPEED_QUALIFIER:
378 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_OTHERSPEED_QUALIFIER\n");
379 break;
381 case UDT_INTERFACE_POWER:
382 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE_POWER\n");
383 break;
385 case UDT_OTG:
386 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_OTG\n");
387 break;
389 case UDT_DEBUG:
390 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEBUG\n");
391 break;
393 case UDT_INTERFACE_ASSOCIATION:
394 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_INTERFACE_ASSOCIATION\n");
395 break;
397 case UDT_SECURITY:
398 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_SECURITY\n");
399 break;
401 case UDT_ENCRYPTION_TYPE:
402 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_ENCRYPTION_TYPE\n");
403 break;
405 case UDT_BOS:
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;
413 break;
415 case UDT_DEVICE_CAPABILITY:
416 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_DEVICE_CAPABILITY\n");
417 break;
419 case UDT_WIRELESS_EP_COMP:
420 bug("[PCIXHCI] cmdControlXFerRootHub: UDT_WIRELESS_EP_COMP\n");
421 break;
423 default:
424 bug("[PCIXHCI] cmdControlXFerRootHub: switch( (wValue>>8) ) %ld\n", (wValue>>8));
425 break;
427 } /* switch( (wValue>>8) ) */
428 break; /* case USR_GET_DESCRIPTOR */
430 case USR_GET_STATUS:
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;
436 break;
438 } /* switch(bRequest) */
439 break; /* case URTF_DEVICE: */
441 /* switch(bmRequestRecipient) */
442 case URTF_INTERFACE:
443 mybug_unit(0, ("URTF_INTERFACE\n"));
444 break;
446 /* switch(bmRequestRecipient) */
447 case URTF_ENDPOINT:
448 mybug_unit(0, ("URTF_ENDPOINT\n"));
449 break;
451 /* switch(bmRequestRecipient) */
452 case URTF_OTHER:
453 mybug_unit(0, ("URTF_OTHER\n"));
454 break;
456 /* switch(bmRequestRecipient) */
457 default:
458 mybug_unit(0, ("Request defaulting %ld\n", bRequest));
459 break;
461 } /* switch(bmRequestRecipient) */
462 break;
464 /* switch(bmRequestType) */
465 case URTF_CLASS:
466 mybug_unit(0, ("URTF_CLASS\n"));
468 switch(bmRequestRecipient) {
469 case URTF_DEVICE:
470 mybug_unit(0, ("URTF_DEVICE\n"));
472 switch(bRequest) {
473 case USR_GET_STATUS:
474 mybug_unit(-1, ("USR_GET_STATUS\n"));
475 UWORD *mptr = ioreq->iouh_Data;
476 if(wLength < sizeof(struct UsbHubStatus)) {
477 break;
479 *mptr++ = 0;
480 *mptr++ = 0;
481 ioreq->iouh_Actual = 4;
482 mybug_unit(-1, ("Something done, check me...\n\n"));
483 return UHIOERR_NO_ERROR;
484 break;
486 /* switch(bRequest) */
487 case USR_GET_DESCRIPTOR:
488 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: USR_GET_DESCRIPTOR\n"));
490 switch( (wValue>>8) ) {
491 case UDT_SSHUB:
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;
500 break;
502 } /* switch( (wValue>>8) ) */
504 mybug_unit(0, ("Done\n\n"));
505 return UHIOERR_NO_ERROR;
506 break;
508 } /* switch(bRequest) */
509 break;
511 /* switch(bmRequestRecipient) */
512 case URTF_OTHER:
513 mybug_unit(0, ("URTF_OTHER\n"));
515 switch(bRequest) {
516 case USR_GET_STATUS:
517 mybug_unit(0, ("USR_GET_STATUS\n"));
518 if(wLength != sizeof(struct UsbPortStatus)) {
519 mybug_unit(-1, ("Invalid port status structure!\n\n"));
520 break;
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"));
538 break;
540 } /* switch(bRequest) */
541 break;
543 } /* case URTF_CLASS */
544 break;
546 /* switch(bmRequestType) */
547 case URTF_VENDOR:
548 mybug_unit(0, ("URTF_VENDOR\n"));
549 break;
551 } /* switch(bmRequestType) */
553 } else { /* if(bmRequestDirection) */
554 mybug_unit(0, ("Request direction is host to device\n"));
556 switch(bmRequestType) {
557 case URTF_STANDARD:
558 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: URTF_STANDARD\n"));
560 switch(bmRequestRecipient) {
561 case URTF_DEVICE:
562 mybug_unit(0, ("[PCIXHCI] cmdControlXFerRootHub: URTF_DEVICE\n"));
564 switch(bRequest) {
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;
571 break;
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;
579 break;
581 } /* switch(bRequest) */
582 break;
584 case URTF_INTERFACE:
585 mybug_unit(0, ("URTF_INTERFACE\n"));
586 break;
588 case URTF_ENDPOINT:
589 mybug_unit(0, ("URTF_ENDPOINT\n"));
590 break;
592 case URTF_OTHER:
593 mybug_unit(0, ("URTF_OTHER\n"));
594 break;
596 } /* switch(bmRequestRecipient) */
597 break;
599 case URTF_CLASS:
600 mybug_unit(0, ("URTF_CLASS\n"));
601 switch(bmRequestRecipient) {
602 case URTF_OTHER:
603 mybug_unit(0, ("URTF_OTHER\n"));
605 switch(bRequest) {
606 case USR_CLEAR_FEATURE:
607 mybug_unit(-1, ("USR_CLEAR_FEATURE\n"));
609 switch(wValue) {
610 case UFS_PORT_POWER:
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"));
623 break;
625 case UFS_PORT_CONNECTION:
626 case UFS_PORT_ENABLE:
627 case UFS_PORT_SUSPEND:
628 case UFS_PORT_OVER_CURRENT:
629 case UFS_PORT_RESET:
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:
636 break;
637 } /* switch(wValue) */
638 break;
640 case USR_SET_FEATURE:
641 mybug_unit(-1, ("USR_SET_FEATURE\n"));
643 switch(wValue) {
644 case UFS_PORT_POWER:
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"));
657 break;
659 case UFS_PORT_CONNECTION:
660 case UFS_PORT_ENABLE:
661 case UFS_PORT_SUSPEND:
662 case UFS_PORT_OVER_CURRENT:
663 case UFS_PORT_RESET:
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:
670 break;
671 } /* switch(wValue) */
672 break;
673 } /* switch(bRequest) */
674 break;
675 } /* switch(bmRequestRecipient) */
676 break;
678 case URTF_VENDOR:
679 mybug_unit(0, ("URTF_VENDOR\n"));
680 break;
682 } /* switch(bmRequestType) */
684 } /* if(bmRequestDirection) */
686 D( mybug_unit(-1, ("bmRequestDirection "));
687 switch (bmRequestDirection) {
688 case URTF_IN:
689 mybug(-1, ("URTF_IN\n"));
690 break;
691 case URTF_OUT:
692 mybug(-1, ("URTF_OUT\n"));
693 break;
696 mybug_unit(-1, ("bmRequestType "));
697 switch(bmRequestType) {
698 case URTF_STANDARD:
699 mybug(-1, ("URTF_STANDARD\n"));
700 break;
701 case URTF_CLASS:
702 mybug(-1, ("URTF_CLASS\n"));
703 break;
704 case URTF_VENDOR:
705 mybug(-1, ("URTF_VENDOR\n"));
706 break;
709 mybug_unit(-1, ("bmRequestRecipient "));
710 switch (bmRequestRecipient) {
711 case URTF_DEVICE:
712 mybug(-1, ("URTF_DEVICE\n"));
713 break;
714 case URTF_INTERFACE:
715 mybug(-1, ("URTF_INTERFACE\n"));
716 break;
717 case URTF_ENDPOINT:
718 mybug(-1, ("URTF_ENDPOINT\n"));
719 break;
720 case URTF_OTHER:
721 mybug(-1, ("URTF_OTHER\n"));
722 break;
725 mybug_unit(-1, ("bRequest "));
726 switch(bRequest) {
727 case USR_GET_STATUS:
728 bug("USR_GET_STATUS\n");
729 break;
730 case USR_CLEAR_FEATURE:
731 mybug(-1, ("USR_CLEAR_FEATURE\n"));
732 break;
733 case USR_SET_FEATURE:
734 mybug(-1, ("USR_SET_FEATURE\n"));
735 break;
736 case USR_SET_ADDRESS:
737 mybug(-1, ("USR_SET_ADDRESS\n"));
738 break;
739 case USR_GET_DESCRIPTOR:
740 mybug(-1, ("USR_GET_DESCRIPTOR\n"));
741 break;
742 case USR_SET_DESCRIPTOR:
743 mybug(-1, ("USR_SET_DESCRIPTOR\n"));
744 break;
745 case USR_GET_CONFIGURATION:
746 mybug(-1, ("USR_GET_CONFIGURATION\n"););
747 break;
748 case USR_SET_CONFIGURATION:
749 mybug(-1, ("USR_SET_CONFIGURATION\n"));
750 break;
751 case USR_GET_INTERFACE:
752 mybug(-1, ("USR_GET_INTERFACE\n"));
753 break;
754 case USR_SET_INTERFACE:
755 mybug(-1, ("USR_SET_INTERFACE\n"));
756 break;
757 case USR_SYNCH_FRAME:
758 mybug(-1, ("USR_SYNCH_FRAME\n"));
759 break;
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"));
790 } else {
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) */
804 // Disable();
805 // AddTail(&hc->hc_CtrlXFerQueue, (struct Node *) ioreq);
806 // Enable();
807 // SureCause(base, &hc->hc_CompleteInt);
809 mybug_unit(-1, ("Processed ioreq: %p\n", ioreq));
810 return RC_DONTREPLY;
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;
832 // return(0);
833 // }
837 mybug_unit(-1, ("Nothing done!\n\n"));
839 // ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
840 // Disable();
841 // AddTail(&unit->hu_RHIOQueue, (struct Node *) ioreq);
842 // Enable();
844 return RC_DONTREPLY;
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);
859 if(wLength > 2) {
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);
864 cstring++;
865 if(*cstring == 0) {
866 mybug_unit(0, ("Done\n\n"));
867 return UHIOERR_NO_ERROR;
871 } else {
872 ioreq->iouh_Actual = wLength;
873 mybug_unit(0, ("Done\n\n"));
874 return UHIOERR_NO_ERROR;
877 return UHIOERR_BADPARAMS;