Minor cleanup and fixing string descriptor for language
[AROS.git] / rom / usb / vusbhc / vxhci / vxhci_commands.c
blob90f370db4b4cb3f3e245f7b91f122258e54c48df
1 /*
2 Copyright © 2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 #define DEBUG 1
14 #include <aros/macros.h>
16 #include <proto/exec.h>
17 #include <proto/stdc.h>
18 #include <proto/arossupport.h>
20 #include <devices/usb.h>
21 #include <devices/usb_hub.h>
22 #include <devices/newstyle.h>
23 #include <devices/usbhardware.h>
25 #include "vxhci_device.h"
27 #include LC_LIBDEFS_FILE
29 WORD cmdQueryDevice(struct IOUsbHWReq *ioreq) {
30 mybug(0, ("[VXHCI] cmdQueryDevice: Entering function\n"));
32 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
34 struct TagItem *taglist = (struct TagItem *) ioreq->iouh_Data;
35 struct TagItem *tag;
36 ULONG count = 0;
38 while((tag = LibNextTagItem(&taglist)) != NULL) {
39 switch (tag->ti_Tag) {
40 case UHA_Manufacturer:
41 *((STRPTR *) tag->ti_Data) = "The AROS Development Team";
42 count++;
43 break;
44 case UHA_Version:
45 *((ULONG *) tag->ti_Data) = VERSION_NUMBER;
46 count++;
47 break;
48 case UHA_Revision:
49 *((ULONG *) tag->ti_Data) = REVISION_NUMBER;
50 count++;
51 break;
52 case UHA_Copyright:
53 *((STRPTR *) tag->ti_Data) ="©2014 The AROS Development Team";
54 count++;
55 break;
56 case UHA_ProductName:
58 static char productname[100];
59 sprintf(productname, "VXHCI (USB%x.%x ports)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
60 *((STRPTR *) tag->ti_Data) = productname;
61 count++;
63 break;
64 case UHA_Description:
66 static char description[100];
67 sprintf(description, "Virtual XHCI (USB%x.%x ports)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
68 *((STRPTR *) tag->ti_Data) = description;
70 count++;
71 break;
72 case UHA_Capabilities:
73 #if(1)
74 if( (AROS_LE2WORD(unit->roothub.devdesc.bcdUSB) >= 0x200) && (AROS_LE2WORD(unit->roothub.devdesc.bcdUSB) < 0x300)) {
75 *((ULONG *) tag->ti_Data) = (UHCF_USB20);
76 } else {
77 *((ULONG *) tag->ti_Data) = (UHCF_USB30);
79 #else
80 *((ULONG *) tag->ti_Data) = (UHCF_USB20|UHCF_USB30);
81 #endif
82 count++;
83 break;
84 default:
85 break;
89 mybug_unit(0, ("Done\n\n"));
91 ioreq->iouh_Actual = count;
92 return RC_OK;
95 WORD cmdUsbReset(struct IOUsbHWReq *ioreq) {
96 mybug(0, ("[VXHCI] cmdUsbReset: Entering function\n"));
98 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
100 /* We should do a proper reset sequence with a real driver */
101 unit->state = UHSF_RESET;
102 unit->roothub.addr = 0;
103 unit->state = UHSF_OPERATIONAL;
104 mybug_unit(0, ("Done\n\n"));
105 return RC_OK;
108 WORD cmdControlXFer(struct IOUsbHWReq *ioreq) {
109 mybug(0, ("[VXHCI] cmdControlXFer: Entering function\n"));
111 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
113 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
114 mybug_unit(0, ("unit->roothub.addr %lx\n", unit->roothub.addr));
117 Check the status of the controller
118 We might encounter these states:
119 UHSB_OPERATIONAL USB can be used for transfers
120 UHSB_RESUMING USB is currently resuming
121 UHSB_SUSPENDED USB is in suspended state
122 UHSB_RESET USB is just inside a reset phase
125 if(unit->state == UHSF_OPERATIONAL) {
126 mybug_unit(0, ("Unit state is operational\n"));
127 } else {
128 mybug_unit(-1, ("Unit state is not operational!\n"));
129 return UHIOERR_USBOFFLINE;
132 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
133 return(cmdControlXFerRootHub(ioreq));
136 return RC_DONTREPLY;
139 WORD cmdControlXFerRootHub(struct IOUsbHWReq *ioreq) {
140 mybug(0, ("[VXHCI] cmdControlXFerRootHub: Entering function\n"));
142 UWORD bmRequestType = (ioreq->iouh_SetupData.bmRequestType) & (URTF_STANDARD | URTF_CLASS | URTF_VENDOR);
143 UWORD bmRequestDirection = (ioreq->iouh_SetupData.bmRequestType) & (URTF_IN | URTF_OUT);
144 UWORD bmRequestRecipient = (ioreq->iouh_SetupData.bmRequestType) & (URTF_DEVICE | URTF_INTERFACE | URTF_ENDPOINT | URTF_OTHER);
146 UWORD bRequest = (ioreq->iouh_SetupData.bRequest);
147 D(UWORD wIndex = AROS_WORD2LE(ioreq->iouh_SetupData.wIndex));
148 UWORD wValue = AROS_WORD2LE(ioreq->iouh_SetupData.wValue);
149 UWORD wLength = AROS_WORD2LE(ioreq->iouh_SetupData.wLength);
151 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
153 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
154 if(ioreq->iouh_Endpoint != 0) {
155 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq->iouh_Endpoint));
156 return UHIOERR_BADPARAMS;
159 /* Check the request */
160 if(bmRequestDirection) {
161 mybug_unit(0, ("Request direction is device to host\n"));
163 switch(bmRequestType) {
164 case URTF_STANDARD:
165 mybug_unit(0, ("URTF_STANDARD\n"));
167 switch(bmRequestRecipient) {
168 case URTF_DEVICE:
169 mybug_unit(0, ("URTF_DEVICE\n"));
171 switch(bRequest) {
172 case USR_GET_DESCRIPTOR:
173 mybug_unit(0, ("USR_GET_DESCRIPTOR\n"));
175 switch( (wValue>>8) ) {
176 case UDT_DEVICE:
177 mybug_unit(0, ("UDT_DEVICE\n"));
178 mybug_unit(0, ("GetDeviceDescriptor (%ld)\n", wLength));
180 ioreq->iouh_Actual = (wLength > sizeof(struct UsbStdDevDesc)) ? sizeof(struct UsbStdDevDesc) : wLength;
181 CopyMem((APTR) &unit->roothub.devdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
183 mybug_unit(0, ("Done\n\n"));
184 return(0);
185 break;
187 case UDT_CONFIGURATION:
188 mybug_unit(0, ("UDT_CONFIGURATION\n"));
189 mybug_unit(0, ("GetConfigDescriptor (%ld)\n", wLength));
191 ioreq->iouh_Actual = (wLength > sizeof(struct RHConfig)) ? sizeof(struct RHConfig) : wLength;
192 CopyMem((APTR) &unit->roothub.config, ioreq->iouh_Data, ioreq->iouh_Actual);
194 //bug("sizeof(struct RHConfig) = %ld (should be 25)\n", sizeof(struct RHConfig));
195 mybug_unit(0, ("Done\n\n"));
196 return(0);
198 break;
200 case UDT_STRING:
201 mybug_unit(0, ("UDT_STRING id %d\n", (wValue & 0xff)));
203 if(wLength > 1) {
204 switch( (wValue & 0xff) ) {
205 case 0:
206 mybug_unit(0, ("GetStringDescriptor (%ld)\n", wLength));
208 /* This is our root hub string descriptor */
209 struct UsbStdStrDesc *strdesc = (struct UsbStdStrDesc *) ioreq->iouh_Data;
211 strdesc->bLength = sizeof(struct UsbStdStrDesc);
212 strdesc->bDescriptorType = UDT_STRING;
214 if(wLength > 3) {
215 strdesc->bString[0] = AROS_WORD2LE(0x0409); // English (Yankee)
216 ioreq->iouh_Actual = sizeof(struct UsbStdStrDesc);
217 mybug_unit(0, ("Done\n\n"));
218 return(0);
219 } else {
220 ioreq->iouh_Actual = wLength;
221 mybug_unit(0, ("Done\n\n"));
222 return(0);
225 break;
227 case 1:
228 return cmdGetString(ioreq, "The AROS Development Team.");
229 break;
231 case 2: {
232 char roothubname[100];
233 sprintf(roothubname, "VXHCI root hub (USB%x.%x)", AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>8)&0xf, AROS_LE2WORD(unit->roothub.devdesc.bcdUSB>>4)&0xf);
234 return cmdGetString(ioreq, roothubname);
235 break;
238 case 3:
239 return cmdGetString(ioreq, "Standard Config");
240 break;
242 case 4:
243 return cmdGetString(ioreq, "Hub interface");
244 break;
246 default:
247 break;
251 break;
253 case UDT_INTERFACE:
254 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE\n");
255 break;
257 case UDT_ENDPOINT:
258 bug("[VXHCI] cmdControlXFerRootHub: UDT_ENDPOINT\n");
259 break;
261 case UDT_DEVICE_QUALIFIER:
262 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEVICE_QUALIFIER\n");
263 break;
265 case UDT_OTHERSPEED_QUALIFIER:
266 bug("[VXHCI] cmdControlXFerRootHub: UDT_OTHERSPEED_QUALIFIER\n");
267 break;
269 case UDT_INTERFACE_POWER:
270 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE_POWER\n");
271 break;
273 case UDT_OTG:
274 bug("[VXHCI] cmdControlXFerRootHub: UDT_OTG\n");
275 break;
277 case UDT_DEBUG:
278 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEBUG\n");
279 break;
281 case UDT_INTERFACE_ASSOCIATION:
282 bug("[VXHCI] cmdControlXFerRootHub: UDT_INTERFACE_ASSOCIATION\n");
283 break;
285 case UDT_SECURITY:
286 bug("[VXHCI] cmdControlXFerRootHub: UDT_SECURITY\n");
287 break;
289 case UDT_ENCRYPTION_TYPE:
290 bug("[VXHCI] cmdControlXFerRootHub: UDT_ENCRYPTION_TYPE\n");
291 break;
293 case UDT_BOS:
294 bug("[VXHCI] cmdControlXFerRootHub: UDT_BOS\n");
295 break;
297 case UDT_DEVICE_CAPABILITY:
298 bug("[VXHCI] cmdControlXFerRootHub: UDT_DEVICE_CAPABILITY\n");
299 break;
301 case UDT_WIRELESS_EP_COMP:
302 bug("[VXHCI] cmdControlXFerRootHub: UDT_WIRELESS_EP_COMP\n");
303 break;
305 default:
306 bug("[VXHCI] cmdControlXFerRootHub: switch( (wValue>>8) ) %ld\n", (wValue>>8));
307 break;
309 } /* switch( (wValue>>8) ) */
310 break; /* case USR_GET_DESCRIPTOR */
312 case USR_GET_STATUS:
313 mybug_unit(0, ("USR_GET_STATUS\n"));
314 ((UWORD *) ioreq->iouh_Data)[0] = AROS_WORD2LE(U_GSF_SELF_POWERED);
315 ioreq->iouh_Actual = wLength;
316 mybug_unit(0, ("Done\n\n"));
317 return(0);
318 break;
320 } /* switch(bRequest) */
321 break; /* case URTF_DEVICE: */
323 case URTF_INTERFACE:
324 mybug_unit(0, ("URTF_INTERFACE\n"));
325 break;
327 case URTF_ENDPOINT:
328 mybug_unit(0, ("URTF_ENDPOINT\n"));
329 break;
331 case URTF_OTHER:
332 mybug_unit(0, ("URTF_OTHER\n"));
333 break;
335 default:
336 mybug_unit(0, ("Request defaulting %ld\n", bRequest));
337 break;
339 } /* switch(bmRequestRecipient) */
340 break;
342 case URTF_CLASS:
343 mybug_unit(0, ("URTF_CLASS\n"));
345 switch(bmRequestRecipient) {
346 case URTF_DEVICE:
347 mybug_unit(0, ("URTF_DEVICE\n"));
349 switch(bRequest) {
350 case USR_GET_STATUS:
351 mybug_unit(-1, ("USR_GET_STATUS\n"));
352 UWORD *mptr = ioreq->iouh_Data;
353 if(wLength < sizeof(struct UsbHubStatus)) {
354 return(UHIOERR_STALL);
356 *mptr++ = 0;
357 *mptr++ = 0;
358 ioreq->iouh_Actual = 4;
359 mybug_unit(-1, ("Something done, check me...\n\n"));
360 return(0);
361 break;
364 case USR_GET_DESCRIPTOR:
365 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: USR_GET_DESCRIPTOR\n"));
367 switch( (wValue>>8) ) {
368 case UDT_HUB:
369 mybug_unit(0, ("UDT_HUB\n"));
370 mybug_unit(0, ("GetRootHubDescriptor USB2.0 (%ld)\n", wLength));
372 ioreq->iouh_Actual = (wLength > sizeof(struct UsbHubDesc)) ? sizeof(struct UsbHubDesc) : wLength;
373 CopyMem((APTR) &unit->roothub.hubdesc.usb20, ioreq->iouh_Data, ioreq->iouh_Actual);
375 mybug_unit(0, ("Done\n\n"));
376 return(0);
377 break;
379 case UDT_SSHUB:
380 mybug_unit(0, ("UDT_SSHUB\n"));
381 mybug_unit(0, ("GetRootHubDescriptor USB3.0 (%ld)\n", wLength));
383 ioreq->iouh_Actual = (wLength > sizeof(struct UsbSSHubDesc)) ? sizeof(struct UsbSSHubDesc) : wLength;
384 CopyMem((APTR) &unit->roothub.hubdesc.usb30, ioreq->iouh_Data, ioreq->iouh_Actual);
386 mybug_unit(0, ("Done\n\n"));
387 return(0);
388 break;
391 mybug_unit(0, ("Done\n\n"));
392 return(0);
393 break;
395 break;
397 } /* case URTF_CLASS */
398 break;
400 case URTF_VENDOR:
401 mybug_unit(0, ("URTF_VENDOR\n"));
402 break;
403 } /* switch(bmRequestType) */
405 } else { /* if(bmRequestDirection) */
406 mybug_unit(0, ("Request direction is host to device\n"));
408 switch(bmRequestType) {
409 case URTF_STANDARD:
410 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: URTF_STANDARD\n"));
412 switch(bmRequestRecipient) {
413 case URTF_DEVICE:
414 mybug_unit(0, ("[VXHCI] cmdControlXFerRootHub: URTF_DEVICE\n"));
416 switch(bRequest) {
417 case USR_SET_ADDRESS:
418 mybug_unit(0, ("USR_SET_ADDRESS\n"));
419 unit->roothub.addr = wValue;
420 ioreq->iouh_Actual = wLength;
421 mybug_unit(0, ("Done\n\n"));
422 return(0);
423 break;
425 case USR_SET_CONFIGURATION:
426 /* We do not have alternative configuration */
427 mybug_unit(0, ("USR_SET_CONFIGURATION\n"));
428 ioreq->iouh_Actual = wLength;
429 mybug_unit(0, ("Done\n\n"));
430 return(0);
431 break;
433 } /* switch(bRequest) */
434 break;
436 case URTF_INTERFACE:
437 mybug_unit(0, ("URTF_INTERFACE\n"));
438 break;
440 case URTF_ENDPOINT:
441 mybug_unit(0, ("URTF_ENDPOINT\n"));
442 break;
444 case URTF_OTHER:
445 mybug_unit(0, ("URTF_OTHER\n"));
446 break;
448 } /* switch(bmRequestRecipient) */
449 break;
451 case URTF_CLASS:
452 mybug_unit(0, ("URTF_CLASS\n"));
453 break;
455 case URTF_VENDOR:
456 mybug_unit(0, ("URTF_VENDOR\n"));
457 break;
459 } /* switch(bmRequestType) */
461 } /* if(bmRequestDirection) */
463 D( mybug_unit(-1, ("bmRequestDirection "));
464 switch (bmRequestDirection) {
465 case URTF_IN:
466 mybug(-1, ("URTF_IN\n"));
467 break;
468 case URTF_OUT:
469 mybug(-1, ("URTF_OUT\n"));
470 break;
473 mybug_unit(-1, ("bmRequestType "));
474 switch(bmRequestType) {
475 case URTF_STANDARD:
476 mybug(-1, ("URTF_STANDARD\n"));
477 break;
478 case URTF_CLASS:
479 mybug(-1, ("URTF_CLASS\n"));
480 break;
481 case URTF_VENDOR:
482 mybug(-1, ("URTF_VENDOR\n"));
483 break;
486 mybug_unit(-1, ("bmRequestRecipient "));
487 switch (bmRequestRecipient) {
488 case URTF_DEVICE:
489 mybug(-1, ("URTF_DEVICE\n"));
490 break;
491 case URTF_INTERFACE:
492 mybug(-1, ("URTF_INTERFACE\n"));
493 break;
494 case URTF_ENDPOINT:
495 mybug(-1, ("URTF_ENDPOINT\n"));
496 break;
497 case URTF_OTHER:
498 mybug(-1, ("URTF_OTHER\n"));
499 break;
502 mybug_unit(-1, ("bRequest "));
503 switch(bRequest) {
504 case USR_GET_STATUS:
505 bug("USR_GET_STATUS\n");
506 break;
507 case USR_CLEAR_FEATURE:
508 mybug(-1, ("USR_CLEAR_FEATURE\n"));
509 break;
510 case USR_SET_FEATURE:
511 mybug(-1, ("USR_SET_FEATURE\n"));
512 break;
513 case USR_SET_ADDRESS:
514 mybug(-1, ("USR_SET_ADDRESS\n"));
515 break;
516 case USR_GET_DESCRIPTOR:
517 mybug(-1, ("USR_GET_DESCRIPTOR\n"));
518 break;
519 case USR_SET_DESCRIPTOR:
520 mybug(-1, ("USR_SET_DESCRIPTOR\n"));
521 break;
522 case USR_GET_CONFIGURATION:
523 mybug(-1, ("USR_GET_CONFIGURATION\n"););
524 break;
525 case USR_SET_CONFIGURATION:
526 mybug(-1, ("USR_SET_CONFIGURATION\n"));
527 break;
528 case USR_GET_INTERFACE:
529 mybug(-1, ("USR_GET_INTERFACE\n"));
530 break;
531 case USR_SET_INTERFACE:
532 mybug(-1, ("USR_SET_INTERFACE\n"));
533 break;
534 case USR_SYNCH_FRAME:
535 mybug(-1, ("USR_SYNCH_FRAME\n"));
536 break;
539 mybug_unit(-1, ("wIndex %x\n", wIndex));
540 mybug_unit(-1, ("wValue %x\n", wValue));
541 mybug_unit(-1, ("wLength %d\n", wLength));
543 mybug_unit(-1, ("Nothing done!\n\n")) );
546 return UHIOERR_BADPARAMS;
549 WORD cmdIntXFer(struct IOUsbHWReq *ioreq) {
550 mybug(-1, ("[VXHCI] cmdIntXFer: Entering function\n"));
552 struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit;
554 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
555 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit->roothub.addr));
558 Check the status of the controller
559 We might encounter these states:
560 UHSB_OPERATIONAL USB can be used for transfers
561 UHSB_RESUMING USB is currently resuming
562 UHSB_SUSPENDED USB is in suspended state
563 UHSB_RESET USB is just inside a reset phase
566 if(unit->state == UHSF_OPERATIONAL) {
567 mybug_unit(0, ("Unit state is operational\n"));
568 } else {
569 mybug_unit(-1, ("Unit state is not operational!\n"));
570 return UHIOERR_USBOFFLINE;
573 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
574 mybug_unit(-1, ("Entering cmdIntXFerRootHub\n"));
575 return(cmdIntXFerRootHub(ioreq));
578 mybug_unit(-1, ("Nothing done!\n\n"));
579 return RC_DONTREPLY;
582 WORD cmdIntXFerRootHub(struct IOUsbHWReq *ioreq) {
583 mybug(-1, ("[VXHCI] cmdIntXFerRootHub: Entering function\n"));
584 D(struct VXHCIUnit *unit = (struct VXHCIUnit *) ioreq->iouh_Req.io_Unit);
586 mybug_unit(-1, ("Nothing done!\n\n"));
587 return RC_DONTREPLY;
590 WORD cmdGetString(struct IOUsbHWReq *ioreq, char *cstring) {
591 mybug(0, ("[VXHCI] cmdGetString: Entering function\n"));
593 UWORD wLength = AROS_WORD2LE(ioreq->iouh_SetupData.wLength);
595 struct UsbStdStrDesc *strdesc = (struct UsbStdStrDesc *) ioreq->iouh_Data;
596 strdesc->bDescriptorType = UDT_STRING;
597 strdesc->bLength = (strlen(cstring)*sizeof(strdesc->bString))+sizeof(strdesc->bLength) + sizeof(strdesc->bDescriptorType);
599 if(wLength > 2) {
600 ioreq->iouh_Actual = 2;
601 while(ioreq->iouh_Actual<wLength) {
602 strdesc->bString[(ioreq->iouh_Actual-2)/sizeof(strdesc->bString)] = AROS_WORD2LE(*cstring);
603 ioreq->iouh_Actual += sizeof(strdesc->bString);
604 cstring++;
605 if(*cstring == 0) {
606 mybug(0, ("[VXHCI] cmdGetString: Done\n\n"));
607 return(0);
611 } else {
612 ioreq->iouh_Actual = wLength;
613 mybug(0, ("[VXHCI] cmdGetString: Done\n\n"));
614 return(0);
617 return UHIOERR_BADPARAMS;