For every VXHCI controller create only one roothub (and only one unit per controller...
[AROS.git] / rom / usb / vusbhc / vxhci / vxhci_commands.c
blob43ea125627a322c4e278b8eaa599aa1a2545899d
1 /*
2 Copyright © 2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Virtual XHCI USB host controller
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 #define DEBUG 1
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/stdc.h>
21 #include <proto/arossupport.h>
23 #include <devices/usb.h>
24 #include <devices/usb_hub.h>
25 #include <devices/newstyle.h>
26 #include <devices/usbhardware.h>
28 #include "vxhci_device.h"
30 #include LC_LIBDEFS_FILE
32 WORD cmdQueryDevice(struct IOUsbHWReq *ioreq) {
33 mybug(0, ("[VXHCI] cmdQueryDevice: Entering function\n"));
35 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
37 struct TagItem *taglist = (struct TagItem *) ioreq->iouh_Data;
38 struct TagItem *tag;
39 ULONG count = 0;
41 while((tag = LibNextTagItem(&taglist)) != NULL) {
42 switch (tag->ti_Tag) {
43 case UHA_Manufacturer:
44 *((STRPTR *) tag->ti_Data) = "The AROS Development Team";
45 count++;
46 break;
47 case UHA_Version:
48 *((ULONG *) tag->ti_Data) = VERSION_NUMBER;
49 count++;
50 break;
51 case UHA_Revision:
52 *((ULONG *) tag->ti_Data) = REVISION_NUMBER;
53 count++;
54 break;
55 case UHA_Copyright:
56 *((STRPTR *) tag->ti_Data) ="©2014 The AROS Development Team";
57 count++;
58 break;
59 case UHA_ProductName:
61 static char productname[100];
62 sprintf(productname, "VXHCI (USB%x.%x ports)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
63 *((STRPTR *) tag->ti_Data) = productname;
64 count++;
66 break;
67 case UHA_Description:
69 static char description[100];
70 sprintf(description, "Virtual XHCI (USB%x.%x ports)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
71 *((STRPTR *) tag->ti_Data) = description;
73 count++;
74 break;
75 case UHA_Capabilities:
76 #if(1)
77 if( (AROS_LE2WORD(unit->roothub.devdesc.bcdUSB) >= 0x200) && (AROS_LE2WORD(unit->roothub.devdesc.bcdUSB) < 0x300)) {
78 *((ULONG *) tag->ti_Data) = (UHCF_USB20);
79 } else {
80 *((ULONG *) tag->ti_Data) = (UHCF_USB30);
82 #else
83 *((ULONG *) tag->ti_Data) = (UHCF_USB20|UHCF_USB30);
84 #endif
85 count++;
86 break;
87 default:
88 break;
92 mybug_unit(0, ("Done\n\n"));
94 ioreq->iouh_Actual = count;
95 return RC_OK;
98 BOOL cmdAbortIO(struct IOUsbHWReq *ioreq) {
99 ioreq->iouh_Req.io_Error = IOERR_ABORTED;
100 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_FREEMSG;
102 /* If not quick I/O, reply the message */
103 if (!(ioreq->iouh_Req.io_Flags & IOF_QUICK)) {
104 ReplyMsg(&ioreq->iouh_Req.io_Message);
107 return TRUE;
110 WORD cmdUsbReset(struct IOUsbHWReq *ioreq) {
111 mybug(0, ("[VXHCI] cmdUsbReset: Entering function\n"));
113 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
115 /* We should do a proper reset sequence with a real driver */
116 unit->state = UHSF_RESET;
117 unit->roothub.addr = 0;
118 unit->state = UHSF_OPERATIONAL;
119 mybug_unit(0, ("Done\n\n"));
120 return RC_OK;
123 WORD cmdControlXFer(struct IOUsbHWReq *ioreq) {
124 mybug(0, ("[VXHCI] cmdControlXFer: Entering function\n"));
126 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
128 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
129 mybug_unit(0, ("unit->roothub.addr %lx\n", unit->roothub.addr));
132 Check the status of the controller
133 We might encounter these states:
134 UHSB_OPERATIONAL USB can be used for transfers
135 UHSB_RESUMING USB is currently resuming
136 UHSB_SUSPENDED USB is in suspended state
137 UHSB_RESET USB is just inside a reset phase
140 if(unit->state == UHSF_OPERATIONAL) {
141 mybug_unit(0, ("Unit state is operational\n"));
142 } else {
143 mybug_unit(-1, ("Unit state is not operational!\n"));
144 return UHIOERR_USBOFFLINE;
147 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
148 return(cmdControlXFerRootHub(ioreq));
151 return RC_DONTREPLY;
154 WORD cmdControlXFerRootHub(struct IOUsbHWReq *ioreq) {
155 mybug(0, ("[VXHCI] cmdControlXFerRootHub: Entering function\n"));
157 UWORD bmRequestType = (ioreq->iouh_SetupData.bmRequestType) & (URTF_STANDARD | URTF_CLASS | URTF_VENDOR);
158 UWORD bmRequestDirection = (ioreq->iouh_SetupData.bmRequestType) & (URTF_IN | URTF_OUT);
159 UWORD bmRequestRecipient = (ioreq->iouh_SetupData.bmRequestType) & (URTF_DEVICE | URTF_INTERFACE | URTF_ENDPOINT | URTF_OTHER);
161 UWORD bRequest = (ioreq->iouh_SetupData.bRequest);
162 UWORD wIndex = AROS_WORD2LE(ioreq->iouh_SetupData.wIndex);
163 UWORD wValue = AROS_WORD2LE(ioreq->iouh_SetupData.wValue);
164 UWORD wLength = AROS_WORD2LE(ioreq->iouh_SetupData.wLength);
166 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
167 struct VXHCIPort *port = NULL;
169 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
170 if(ioreq->iouh_Endpoint != 0) {
171 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq->iouh_Endpoint));
172 return UHIOERR_BADPARAMS;
175 /* Check the request */
176 if(bmRequestDirection) {
177 mybug_unit(0, ("Request direction is device to host\n"));
179 switch(bmRequestType) {
180 case URTF_STANDARD:
181 mybug_unit(0, ("URTF_STANDARD\n"));
183 switch(bmRequestRecipient) {
184 case URTF_DEVICE:
185 mybug_unit(0, ("URTF_DEVICE\n"));
187 switch(bRequest) {
188 case USR_GET_DESCRIPTOR:
189 mybug_unit(0, ("USR_GET_DESCRIPTOR\n"));
191 switch( (wValue>>8) ) {
192 case UDT_DEVICE:
193 mybug_unit(0, ("UDT_DEVICE\n"));
194 mybug_unit(0, ("GetDeviceDescriptor (%ld)\n", wLength));
196 ioreq->iouh_Actual = (wLength > sizeof(struct UsbStdDevDesc)) ? sizeof(struct UsbStdDevDesc) : wLength;
197 CopyMem((APTR) &unit->roothub.devdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
199 mybug_unit(0, ("Done\n\n"));
200 return UHIOERR_NO_ERROR;
201 break;
203 case UDT_CONFIGURATION:
204 mybug_unit(0, ("UDT_CONFIGURATION\n"));
205 mybug_unit(0, ("GetConfigDescriptor (%ld)\n", wLength));
207 ioreq->iouh_Actual = (wLength > sizeof(struct RHConfig)) ? sizeof(struct RHConfig) : wLength;
208 CopyMem((APTR) &unit->roothub.config, ioreq->iouh_Data, ioreq->iouh_Actual);
210 //bug("sizeof(struct RHConfig) = %ld (should be 25)\n", sizeof(struct RHConfig));
211 mybug_unit(0, ("Done\n\n"));
212 return UHIOERR_NO_ERROR;
214 break;
216 case UDT_STRING:
217 mybug_unit(0, ("UDT_STRING id %d\n", (wValue & 0xff)));
219 if(wLength > 1) {
220 switch( (wValue & 0xff) ) {
221 case 0:
222 mybug_unit(0, ("GetStringDescriptor (%ld)\n", wLength));
224 /* This is our root hub string descriptor */
225 struct UsbStdStrDesc *strdesc = (struct UsbStdStrDesc *) ioreq->iouh_Data;
227 strdesc->bLength = sizeof(struct UsbStdStrDesc);
228 strdesc->bDescriptorType = UDT_STRING;
230 if(wLength > 3) {
231 strdesc->bString[0] = AROS_WORD2LE(0x0409); // English (Yankee)
232 ioreq->iouh_Actual = sizeof(struct UsbStdStrDesc);
233 mybug_unit(0, ("Done\n\n"));
234 return UHIOERR_NO_ERROR;
235 } else {
236 ioreq->iouh_Actual = wLength;
237 mybug_unit(0, ("Done\n\n"));
238 return UHIOERR_NO_ERROR;
241 break;
243 case 1:
244 return cmdGetString(ioreq, "The AROS Development Team.");
245 break;
247 case 2: {
248 char roothubname[100];
249 sprintf(roothubname, "VXHCI root hub (USB%x.%x)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
250 return cmdGetString(ioreq, roothubname);
251 break;
254 case 3:
255 return cmdGetString(ioreq, "Standard Config");
256 break;
258 case 4:
259 return cmdGetString(ioreq, "Hub interface");
260 break;
262 default:
263 break;
267 break;
269 case UDT_INTERFACE:
270 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE\n");
271 break;
273 case UDT_ENDPOINT:
274 bug("[VXHCI] cmdControlXFerRootHub: UDT_ENDPOINT\n");
275 break;
277 case UDT_DEVICE_QUALIFIER:
278 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEVICE_QUALIFIER\n");
279 break;
281 case UDT_OTHERSPEED_QUALIFIER:
282 bug("[VXHCI] cmdControlXFerRootHub: UDT_OTHERSPEED_QUALIFIER\n");
283 break;
285 case UDT_INTERFACE_POWER:
286 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE_POWER\n");
287 break;
289 case UDT_OTG:
290 bug("[VXHCI] cmdControlXFerRootHub: UDT_OTG\n");
291 break;
293 case UDT_DEBUG:
294 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEBUG\n");
295 break;
297 case UDT_INTERFACE_ASSOCIATION:
298 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE_ASSOCIATION\n");
299 break;
301 case UDT_SECURITY:
302 bug("[VXHCI] cmdControlXFerRootHub: UDT_SECURITY\n");
303 break;
305 case UDT_ENCRYPTION_TYPE:
306 bug("[VXHCI] cmdControlXFerRootHub: UDT_ENCRYPTION_TYPE\n");
307 break;
309 case UDT_BOS:
310 bug("[VXHCI] cmdControlXFerRootHub: UDT_BOS\n");
311 /* TODO: Arbitrary, set real values according to the host controller */
312 unit->roothub.bosdesc.wTotalLength = 16;
313 unit->roothub.bosdesc.bNumDeviceCaps = 2;
315 ioreq->iouh_Actual = (wLength > sizeof(struct UsbStdBOSDesc)) ? sizeof(struct UsbStdBOSDesc) : wLength;
316 CopyMem((APTR) &unit->roothub.bosdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
318 mybug_unit(0, ("Done\n\n"));
319 return UHIOERR_NO_ERROR;
320 break;
322 case UDT_DEVICE_CAPABILITY:
323 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEVICE_CAPABILITY\n");
324 break;
326 case UDT_WIRELESS_EP_COMP:
327 bug("[VXHCI] cmdControlXFerRootHub: UDT_WIRELESS_EP_COMP\n");
328 break;
330 default:
331 bug("[VXHCI] cmdControlXFerRootHub: switch( (wValue>>8) ) %ld\n", (wValue>>8));
332 break;
334 } /* switch( (wValue>>8) ) */
335 break; /* case USR_GET_DESCRIPTOR */
337 case USR_GET_STATUS:
338 mybug_unit(0, ("USR_GET_STATUS\n"));
339 ((UWORD *) ioreq->iouh_Data)[0] = AROS_WORD2LE(U_GSF_SELF_POWERED);
340 ioreq->iouh_Actual = wLength;
341 mybug_unit(0, ("Done\n\n"));
342 return UHIOERR_NO_ERROR;
343 break;
345 //case USR_GET_INTERFACE: //Undefined. Hubs are allowed to support only one interface.
347 } /* switch(bRequest) */
348 break; /* case URTF_DEVICE: */
350 /* switch(bmRequestRecipient) */
351 case URTF_INTERFACE:
352 mybug_unit(0, ("URTF_INTERFACE\n"));
353 break;
355 /* switch(bmRequestRecipient) */
356 case URTF_ENDPOINT:
357 mybug_unit(0, ("URTF_ENDPOINT\n"));
358 break;
360 /* switch(bmRequestRecipient) */
361 case URTF_OTHER:
362 mybug_unit(0, ("URTF_OTHER\n"));
363 break;
365 /* switch(bmRequestRecipient) */
366 default:
367 mybug_unit(0, ("Request defaulting %ld\n", bRequest));
368 break;
370 } /* switch(bmRequestRecipient) */
371 break;
373 /* switch(bmRequestType) */
374 case URTF_CLASS:
375 mybug_unit(0, ("URTF_CLASS\n"));
377 switch(bmRequestRecipient) {
378 case URTF_DEVICE:
379 mybug_unit(0, ("URTF_DEVICE\n"));
381 switch(bRequest) {
382 case USR_GET_STATUS:
383 mybug_unit(-1, ("USR_GET_STATUS\n"));
384 UWORD *mptr = ioreq->iouh_Data;
385 if(wLength < sizeof(struct UsbHubStatus)) {
386 break;
388 *mptr++ = 0;
389 *mptr++ = 0;
390 ioreq->iouh_Actual = 4;
391 mybug_unit(-1, ("Something done, check me...\n\n"));
392 return UHIOERR_NO_ERROR;
393 break;
395 /* switch(bRequest) */
396 case USR_GET_DESCRIPTOR:
397 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: USR_GET_DESCRIPTOR\n"));
399 switch( (wValue>>8) ) {
400 case UDT_SSHUB:
401 mybug_unit(0, ("UDT_SSHUB\n"));
402 mybug_unit(0, ("GetRootHubDescriptor USB3.0 (%ld)\n", wLength));
404 ioreq->iouh_Actual = (wLength > sizeof(struct UsbSSHubDesc)) ? sizeof(struct UsbSSHubDesc) : wLength;
405 CopyMem((APTR) &unit->roothub.hubdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
407 mybug_unit(0, ("Done\n\n"));
408 return UHIOERR_NO_ERROR;
409 break;
411 } /* switch( (wValue>>8) ) */
413 mybug_unit(0, ("Done\n\n"));
414 return UHIOERR_NO_ERROR;
415 break;
417 } /* switch(bRequest) */
418 break;
420 /* switch(bmRequestRecipient) */
421 case URTF_OTHER:
422 mybug_unit(0, ("URTF_OTHER\n"));
424 switch(bRequest) {
425 case USR_GET_STATUS:
426 mybug_unit(0, ("USR_GET_STATUS\n"));
427 if(wLength != sizeof(struct UsbPortStatus)) {
428 mybug_unit(-1, ("Invalid port status structure!\n\n"));
429 break;
432 ForeachNode(&unit->roothub.port_list, port) {
433 if(port->number == wIndex) {
434 mybug_unit(0, ("Found port %d named %s\n", port->number, port->name));
436 struct UsbPortStatus *usbportstatus = (struct UsbPortStatus *) ioreq->iouh_Data;
438 usbportstatus->wPortStatus = 0;
439 usbportstatus->wPortChange = 0;
441 mybug_unit(0, ("Done\n\n"));
442 return UHIOERR_NO_ERROR;
446 mybug_unit(-1, ("Port not found!\n\n"));
447 break;
449 } /* switch(bRequest) */
450 break;
452 } /* case URTF_CLASS */
453 break;
455 /* switch(bmRequestType) */
456 case URTF_VENDOR:
457 mybug_unit(0, ("URTF_VENDOR\n"));
458 break;
460 } /* switch(bmRequestType) */
462 } else { /* if(bmRequestDirection) */
463 mybug_unit(0, ("Request direction is host to device\n"));
465 switch(bmRequestType) {
466 case URTF_STANDARD:
467 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: URTF_STANDARD\n"));
469 switch(bmRequestRecipient) {
470 case URTF_DEVICE:
471 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: URTF_DEVICE\n"));
473 switch(bRequest) {
474 case USR_SET_ADDRESS:
475 mybug_unit(0, ("USR_SET_ADDRESS\n"));
476 unit->roothub.addr = wValue;
477 ioreq->iouh_Actual = wLength;
478 mybug_unit(0, ("Done\n\n"));
479 return UHIOERR_NO_ERROR;
480 break;
482 case USR_SET_CONFIGURATION:
483 /* We do not have alternative configuration */
484 mybug_unit(0, ("USR_SET_CONFIGURATION\n"));
485 ioreq->iouh_Actual = wLength;
486 mybug_unit(0, ("Done\n\n"));
487 return UHIOERR_NO_ERROR;
488 break;
490 //case USR_SET_INTERFACE: //Undefined. Hubs are allowed to support only one interface.
492 } /* switch(bRequest) */
493 break;
495 case URTF_INTERFACE:
496 mybug_unit(0, ("URTF_INTERFACE\n"));
497 break;
499 case URTF_ENDPOINT:
500 mybug_unit(0, ("URTF_ENDPOINT\n"));
501 break;
503 case URTF_OTHER:
504 mybug_unit(0, ("URTF_OTHER\n"));
505 break;
507 } /* switch(bmRequestRecipient) */
508 break;
510 case URTF_CLASS:
511 mybug_unit(0, ("URTF_CLASS\n"));
512 switch(bmRequestRecipient) {
513 case URTF_OTHER:
514 mybug_unit(0, ("URTF_OTHER\n"));
516 switch(bRequest) {
517 case USR_SET_FEATURE:
518 mybug_unit(0, ("USR_SET_FEATURE\n"));
520 switch(wValue) {
521 case UFS_PORT_POWER:
522 mybug_unit(0, ("UFS_PORT_POWER\n"));
524 ForeachNode(&unit->roothub.port_list, port) {
525 if(port->number == wIndex) {
526 mybug_unit(0, ("Found port %d named %s\n", port->number, port->name));
527 mybug_unit(0, ("Done\n\n"));
528 return UHIOERR_NO_ERROR;
532 mybug_unit(-1, ("Port not found!\n\n"));
533 break;
535 case UFS_PORT_CONNECTION:
536 case UFS_PORT_ENABLE:
537 case UFS_PORT_SUSPEND:
538 case UFS_PORT_OVER_CURRENT:
539 case UFS_PORT_RESET:
540 case UFS_PORT_LOW_SPEED:
541 case UFS_C_PORT_CONNECTION:
542 case UFS_C_PORT_ENABLE:
543 case UFS_C_PORT_SUSPEND:
544 case UFS_C_PORT_OVER_CURRENT:
545 case UFS_C_PORT_RESET:
546 break;
547 } /* switch(wValue) */
548 break;
549 } /* switch(bRequest) */
550 break;
551 } /* switch(bmRequestRecipient) */
552 break;
554 case URTF_VENDOR:
555 mybug_unit(0, ("URTF_VENDOR\n"));
556 break;
558 } /* switch(bmRequestType) */
560 } /* if(bmRequestDirection) */
562 D( mybug_unit(-1, ("bmRequestDirection "));
563 switch (bmRequestDirection) {
564 case URTF_IN:
565 mybug(-1, ("URTF_IN\n"));
566 break;
567 case URTF_OUT:
568 mybug(-1, ("URTF_OUT\n"));
569 break;
572 mybug_unit(-1, ("bmRequestType "));
573 switch(bmRequestType) {
574 case URTF_STANDARD:
575 mybug(-1, ("URTF_STANDARD\n"));
576 break;
577 case URTF_CLASS:
578 mybug(-1, ("URTF_CLASS\n"));
579 break;
580 case URTF_VENDOR:
581 mybug(-1, ("URTF_VENDOR\n"));
582 break;
585 mybug_unit(-1, ("bmRequestRecipient "));
586 switch (bmRequestRecipient) {
587 case URTF_DEVICE:
588 mybug(-1, ("URTF_DEVICE\n"));
589 break;
590 case URTF_INTERFACE:
591 mybug(-1, ("URTF_INTERFACE\n"));
592 break;
593 case URTF_ENDPOINT:
594 mybug(-1, ("URTF_ENDPOINT\n"));
595 break;
596 case URTF_OTHER:
597 mybug(-1, ("URTF_OTHER\n"));
598 break;
601 mybug_unit(-1, ("bRequest "));
602 switch(bRequest) {
603 case USR_GET_STATUS:
604 bug("USR_GET_STATUS\n");
605 break;
606 case USR_CLEAR_FEATURE:
607 mybug(-1, ("USR_CLEAR_FEATURE\n"));
608 break;
609 case USR_SET_FEATURE:
610 mybug(-1, ("USR_SET_FEATURE\n"));
611 break;
612 case USR_SET_ADDRESS:
613 mybug(-1, ("USR_SET_ADDRESS\n"));
614 break;
615 case USR_GET_DESCRIPTOR:
616 mybug(-1, ("USR_GET_DESCRIPTOR\n"));
617 break;
618 case USR_SET_DESCRIPTOR:
619 mybug(-1, ("USR_SET_DESCRIPTOR\n"));
620 break;
621 case USR_GET_CONFIGURATION:
622 mybug(-1, ("USR_GET_CONFIGURATION\n"););
623 break;
624 case USR_SET_CONFIGURATION:
625 mybug(-1, ("USR_SET_CONFIGURATION\n"));
626 break;
627 case USR_GET_INTERFACE:
628 mybug(-1, ("USR_GET_INTERFACE\n"));
629 break;
630 case USR_SET_INTERFACE:
631 mybug(-1, ("USR_SET_INTERFACE\n"));
632 break;
633 case USR_SYNCH_FRAME:
634 mybug(-1, ("USR_SYNCH_FRAME\n"));
635 break;
638 mybug_unit(-1, ("wIndex %x\n", wIndex));
639 mybug_unit(-1, ("wValue %x\n", wValue));
640 mybug_unit(-1, ("wLength %d\n", wLength));
642 mybug_unit(-1, ("Nothing done!\n\n")) );
643 return UHIOERR_BADPARAMS;
646 WORD cmdIntXFer(struct IOUsbHWReq *ioreq) {
647 mybug(-1, ("[VXHCI] cmdIntXFer: Entering function\n"));
649 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
651 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
652 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit->roothub.addr));
655 Check the status of the controller
656 We might encounter these states:
657 UHSB_OPERATIONAL USB can be used for transfers
658 UHSB_RESUMING USB is currently resuming
659 UHSB_SUSPENDED USB is in suspended state
660 UHSB_RESET USB is just inside a reset phase
663 if(unit->state == UHSF_OPERATIONAL) {
664 mybug_unit(0, ("Unit state is operational\n"));
665 } else {
666 mybug_unit(-1, ("Unit state is not operational!\n"));
667 return UHIOERR_USBOFFLINE;
670 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
671 mybug_unit(-1, ("Entering cmdIntXFerRootHub\n"));
672 return(cmdIntXFerRootHub(ioreq));
675 mybug_unit(-1, ("Nothing done!\n\n"));
676 return RC_DONTREPLY;
679 WORD cmdIntXFerRootHub(struct IOUsbHWReq *ioreq) {
680 mybug(-1, ("[VXHCI] cmdIntXFerRootHub: Entering function\n"));
681 D(struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit);
683 mybug_unit(-1, ("Nothing done!\n\n"));
684 return RC_DONTREPLY;
687 WORD cmdGetString(struct IOUsbHWReq *ioreq, char *cstring) {
688 mybug(0, ("[VXHCI] cmdGetString: Entering function\n"));
690 UWORD wLength = AROS_WORD2LE(ioreq->iouh_SetupData.wLength);
692 struct UsbStdStrDesc *strdesc = (struct UsbStdStrDesc *) ioreq->iouh_Data;
693 strdesc->bDescriptorType = UDT_STRING;
694 strdesc->bLength = (strlen(cstring)*sizeof(strdesc->bString))+sizeof(strdesc->bLength) + sizeof(strdesc->bDescriptorType);
696 if(wLength > 2) {
697 ioreq->iouh_Actual = 2;
698 while(ioreq->iouh_Actual<wLength) {
699 strdesc->bString[(ioreq->iouh_Actual-2)/sizeof(strdesc->bString)] = AROS_WORD2LE(*cstring);
700 ioreq->iouh_Actual += sizeof(strdesc->bString);
701 cstring++;
702 if(*cstring == 0) {
703 mybug(0, ("[VXHCI] cmdGetString: Done\n\n"));
704 return UHIOERR_NO_ERROR;
708 } else {
709 ioreq->iouh_Actual = wLength;
710 mybug(0, ("[VXHCI] cmdGetString: Done\n\n"));
711 return UHIOERR_NO_ERROR;
714 return UHIOERR_BADPARAMS;