revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / vusbhc / vusbhci_commands.c
blobbb63cb1b402e1bc571da233471027523fd44d3fc
1 /*
2 Copyright © 2015-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: VUSBHCI 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/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"
30 Our iorequests are divided into many different queus or dispatched immediatly (cannot be aborted)
31 Libusb handler task blocks us from the queue whenever it dispatches an iorequest
32 cmdAbortIO also blocks the libusb handler from accessing the queue
33 Which ever comes first gets the change to access the queue
34 Libusb handler task removes the iorequest from the queue before unblocking the queue
36 BOOL cmdAbortIO(struct IOUsbHWReq *ioreq) {
37 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
39 struct IOUsbHWReq *ioreq_tmp;
40 BOOL ret = FALSE;
42 switch (ioreq->iouh_Req.io_Command) {
43 case UHCMD_CONTROLXFER:
44 mybug_unit(-1, ("Aborting cmdControlXFer ioreq\n"));
45 /* We need to block the libusb handler task from messing up with our queue */
46 ObtainSemaphore(&unit->ctrlxfer_queue_lock); {
47 } ReleaseSemaphore(&unit->ctrlxfer_queue_lock);
48 break;
50 case UHCMD_INTXFER:
51 mybug_unit(-1, ("Aborting cmdIntXFer ioreq %lx\n", ioreq));
52 /* We need to block the libusb handler task from messing up with our queue */
53 ObtainSemaphore(&unit->intrxfer_queue_lock); {
54 mybug_unit(-1, (" Semaphore accuired\n"));
55 ForeachNode(&unit->intrxfer_queue, ioreq_tmp) {
56 mybug_unit(-1, (" %lx == %lx\n", ioreq_tmp, ioreq));
57 /* Found the iorequest from our queue */
58 if(ioreq_tmp == ioreq) {
59 /* Remove it from our queue */
60 ioreq_tmp->iouh_Req.io_Error = IOERR_ABORTED;
61 ioreq_tmp->iouh_Req.io_Message.mn_Node.ln_Type = NT_FREEMSG;
62 Remove(&ioreq_tmp->iouh_Req.io_Message.mn_Node);
63 ReplyMsg(&ioreq->iouh_Req.io_Message);
64 mybug_unit(-1, (" removed\n"));
65 ret = TRUE;
68 } ReleaseSemaphore(&unit->intrxfer_queue_lock);
71 Must have been a request for the roothub intr queue or not...
72 When a device gets unbind we get an iorequest followed by an abort command
73 can't find the request... Maybe the roothub intr code is broken
75 if(ret == FALSE) {
76 ObtainSemaphore(&unit->roothub.intrxfer_queue_lock); {
77 ioreq->iouh_Req.io_Error = IOERR_ABORTED;
78 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_FREEMSG;
79 ReplyMsg(&ioreq->iouh_Req.io_Message);
80 mybug_unit(-1, (" removed\n"));
81 ret = TRUE;
82 } ReleaseSemaphore(&unit->roothub.intrxfer_queue_lock);
84 break;
86 case UHCMD_BULKXFER:
87 mybug_unit(-1, ("Aborting cmdBulkXFer ioreq\n"));
88 ObtainSemaphore(&unit->bulkxfer_queue_lock); {
89 } ReleaseSemaphore(&unit->bulkxfer_queue_lock);
90 break;
92 case UHCMD_ISOXFER:
93 mybug_unit(-1, ("Aborting cmdISOXFer ioreq\n"));
94 ObtainSemaphore(&unit->isocxfer_queue_lock); {
95 } ReleaseSemaphore(&unit->isocxfer_queue_lock);
96 break;
98 default:
99 mybug_unit(-1, ("Aborting default ioreq ?!?\n"));
100 break;
103 mybug_unit(-1, ("Returning %s\n", ((ret) ? "TRUE":"FALSE")));
105 return ret;
108 WORD cmdFlush(struct IOUsbHWReq *ioreq) {
109 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
111 mybug_unit(-1, ("Entering function\n"));
113 return RC_OK;
116 WORD cmdUsbReset(struct IOUsbHWReq *ioreq) {
117 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
119 mybug_unit(-1, ("Entering function\n"));
121 /* We should do a proper reset sequence with a real driver */
122 unit->state = UHSF_RESET;
123 unit->roothub.addr = 0;
124 unit->state = UHSF_OPERATIONAL;
125 mybug_unit(0, ("Done\n\n"));
126 return RC_OK;
129 /* Standard Requests */
132 GetStatus:
133 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 10000000B
134 bRequest USR_GET_STATUS
135 wValue Zero
136 wIndex Zero
137 wLength Two
138 Data Device Status
140 CHECKME: U_GSB_SELF_POWERED=8 and U_GSB_REMOTE_WAKEUP=9, should they be 0 and 1?
143 UWORD GetStatus(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
144 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
145 mybug_unit(-1, ("Entering function\n"));
147 UWORD *devicestatus;
148 devicestatus = ioreq->iouh_Data;
150 *devicestatus = (U_GSF_SELF_POWERED & (~U_GSF_REMOTE_WAKEUP));
152 ioreq->iouh_Actual = wLength;
154 mybug_unit(-1, ("GetStatus(%ld) %02x\n", wLength, *devicestatus));
156 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
157 return UHIOERR_NO_ERROR;
161 ClearFeature:
162 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 00000000B
163 bRequest CLEAR_FEATURE
164 wValue Feature Selector
165 wIndex Zero
166 wLength Zero
167 Data None
169 UWORD ClearFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
170 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
171 mybug_unit(-1, ("Entering function\n"));
173 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
174 return UHIOERR_NO_ERROR;
178 SetFeature:
179 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 00000000B
180 bRequest SET_FEATURE
181 wValue Feature Selector
182 wIndex Zero
183 wLength Zero
184 Data None
186 UWORD SetFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
187 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
188 mybug_unit(-1, ("Entering function\n"));
190 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
191 return UHIOERR_NO_ERROR;
195 SetAddress:
196 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
197 bRequest USR_SET_ADDRESS
198 wValue Device Address
199 wIndex Zero
200 wLength Zero
201 Data None
203 UWORD SetAddress(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
204 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
205 mybug_unit(-1, ("Entering function\n"));
207 mybug_unit(-1, ("SetAddress (address %d)\n", wValue));
209 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
210 if( (wValue) && (!(wIndex)) && (!(wLength)) ) {
212 unit->roothub.addr = wValue;
213 ioreq->iouh_Actual = wLength;
215 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
216 return UHIOERR_NO_ERROR;
219 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
220 return UHIOERR_BADPARAMS;
224 GetDescriptor:
225 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 10000000B
226 bRequest GET_DESCRIPTOR
227 wValue Descriptor Type & Index
228 wIndex Zero or Language ID
229 wLength Descriptor Length
230 Data Descriptor
232 UWORD GetDescriptor(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
233 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
234 mybug_unit(-1, ("Entering function\n"));
236 CONST_STRPTR roothubstring = NULL;
237 CONST_STRPTR roothubstrings[] = {"The AROS Development Team.", "VUSBHCI root hub (USB2.00)", "VUSBHCI root hub (USB3.00)", "Standard Config", "Hub interface" };
238 UBYTE index;
240 switch((wValue>>8)) {
241 case UDT_DEVICE:
242 mybug_unit(-1, ("GetDeviceDescriptor UDT_DEVICE (length %ld)\n", wLength));
244 ioreq->iouh_Actual = (wLength > sizeof(struct UsbStdDevDesc)) ? sizeof(struct UsbStdDevDesc) : wLength;
245 CopyMem((APTR) &unit->roothub.devdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
247 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
248 return UHIOERR_NO_ERROR;
249 break;
251 case UDT_CONFIGURATION:
252 index = (wValue & 0xff);
254 mybug_unit(-1, ("GetDeviceDescriptor UDT_CONFIGURATION (configuration %d, length %ld)\n",index, wLength));
256 if(index == 0) {
258 ioreq->iouh_Actual = (wLength > sizeof(struct RHConfig)) ? sizeof(struct RHConfig) : wLength;
259 CopyMem((APTR) &unit->roothub.config, ioreq->iouh_Data, ioreq->iouh_Actual);
261 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
262 return UHIOERR_NO_ERROR;
265 mybug_unit(-1, ("Our roothub supports only one configuration\n"));
266 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
267 return UHIOERR_BADPARAMS;
268 break;
270 case UDT_STRING:
271 index = (wValue & 0xff);
273 mybug_unit(-1, ("GetStringDescriptor UDT_STRING (index %d)\n", index));
275 struct UsbStdStrDesc *strdesc = (struct UsbStdStrDesc *) ioreq->iouh_Data;
277 switch(index) {
278 case 0:
279 if(wLength > 1) {
280 strdesc->bLength = sizeof(struct UsbStdStrDesc);
281 strdesc->bDescriptorType = UDT_STRING;
282 ioreq->iouh_Actual = 2;
284 if(wLength > 3) {
285 strdesc->bString[0] = AROS_WORD2LE(0x0409); // English (Yankee)
286 ioreq->iouh_Actual = sizeof(struct UsbStdStrDesc);
289 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
290 return UHIOERR_NO_ERROR;
293 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
294 return UHIOERR_BADPARAMS; //CHECKME: Should we return stall?
295 break;
297 case 1:
298 roothubstring = roothubstrings[0];
299 break;
301 case 2:
302 if(unit->roothub.devdesc.bcdUSB == AROS_WORD2LE(0x0200)) {
303 roothubstring = roothubstrings[1];
304 } else {
305 roothubstring = roothubstrings[2];
307 break;
309 case 3:
310 roothubstring = roothubstrings[3];
311 break;
313 case 4:
314 roothubstring = roothubstrings[4];
315 break;
317 default:
318 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
319 return UHIOERR_BADPARAMS; //CHECKME: Should we return stall?
322 if(wLength > 1) {
323 UBYTE i = strlen(roothubstring);
325 strdesc->bLength = (i*sizeof(strdesc->bString))+sizeof(strdesc->bLength)+sizeof(strdesc->bDescriptorType);
326 strdesc->bDescriptorType = UDT_STRING;
327 ioreq->iouh_Actual = 2;
329 if(wLength > 3) {
330 for(i=0; i<wLength; i++) {
331 strdesc->bString[i] = AROS_WORD2LE((UWORD)roothubstring[i]);
335 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
336 return UHIOERR_NO_ERROR;
339 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
340 return UHIOERR_BADPARAMS; //CHECKME: Should we return stall?
341 break;
345 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
346 return UHIOERR_BADPARAMS; //CHECKME: Should we return stall?
350 SetDescriptor:
351 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
352 bRequest SET_DESCRIPTOR
353 wValue Descriptor Type & Index
354 wIndex Zero or Language ID
355 wLength Descriptor Length
356 Data Descriptor
358 UWORD SetDescriptor(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
359 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
360 mybug_unit(-1, ("Entering function\n"));
362 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
363 return UHIOERR_NO_ERROR;
367 GetConfiguration:
368 bmRequestType (URTF_IN|URTF_STANDARD|URTF_DEVICE) 10000000B
369 bRequest USR_GET_CONFIGURATION
370 wValue Zero
371 wIndex Zero
372 wLength 1
373 Data Configuration Value
375 UWORD GetConfiguration(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
376 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
377 mybug_unit(-1, ("Entering function\n"));
379 UWORD *configurationvalue;
380 configurationvalue = ioreq->iouh_Data;
382 *configurationvalue = unit->roothub.config.cfgdesc.bConfigurationValue;
384 ioreq->iouh_Actual = wLength;
386 mybug_unit(-1, ("GetConfiguration() %ld\n", configurationvalue));
388 return UHIOERR_NO_ERROR;
392 SetConfiguration:
393 bmRequestType (URTF_OUT|URTF_STANDARD|URTF_DEVICE) 00000000B
394 bRequest USR_SET_CONFIGURATION
395 wValue Configuration Value
396 wIndex Zero
397 wLength Zero
398 Data None
400 Note:
401 We have only one configuration, but implement some sanity still
402 If more than one configuration is specified we ignore the rest in GetDescriptor(UDT_CONFIGURATION)
405 UWORD SetConfiguration(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
406 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
407 mybug_unit(-1, ("Entering function\n"));
409 mybug_unit(-1, ("SetConfiguration (configuration %d)\n", wValue));
411 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
412 if( (wValue == unit->roothub.config.cfgdesc.bConfigurationValue) && (!(wIndex)) && (!(wLength)) ) {
414 ioreq->iouh_Actual = wLength;
416 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
417 return UHIOERR_NO_ERROR;
420 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
421 return UHIOERR_BADPARAMS;
424 /* Hub Class Requests */
427 ClearHubFeature:
428 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
429 bRequest USR_CLEAR_FEATURE
430 wValue Feature Selector
431 wIndex Zero
432 wLength Zero
433 Data None
435 UWORD ClearHubFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
436 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
437 mybug_unit(-1, ("Entering function\n"));
439 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
440 return UHIOERR_NO_ERROR;
444 ClearPortFeature:
445 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
446 bRequest USR_CLEAR_FEATURE
447 wValue Feature Selector
448 wIndex (Selector|Port)
449 wLength Zero
450 Data None
452 FIXME: Check what flags to set and clear on this and SetPortFeature
455 UWORD ClearPortFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
456 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
457 mybug_unit(-1, ("Entering function\n"));
459 mybug_unit(-1, ("Clearing feature 0x%02x on port %d\n",wValue, (wIndex & 0xff)));
461 if( ((!(wIndex & 0xff)) || ((wIndex & 0xff) > unit->roothub.hubdesc.bNbrPorts)) ) {
462 mybug_unit(-1, ("Port %ld out of range\n", (wIndex & 0xff)));
463 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
464 return UHIOERR_BADPARAMS;
467 switch(wValue) {
468 case UFS_PORT_ENABLE:
469 mybug_unit(-1, ("UFS_PORT_ENABLE\n"));
470 unit->roothub.portstatus.wPortStatus &= ~UPSF_PORT_ENABLE;
471 break;
473 case UFS_PORT_SUSPEND:
474 mybug_unit(-1, ("UFS_PORT_SUSPEND\n"));
475 break;
477 case UFS_PORT_POWER:
478 mybug_unit(-1, ("UFS_PORT_POWER\n"));
479 unit->roothub.portstatus.wPortStatus &= ~UPSF_PORT_POWER;
480 break;
482 case UFS_PORT_INDICATOR:
483 mybug_unit(-1, ("UFS_PORT_INDICATOR\n"));
484 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_INDICATOR;
485 break;
487 case UFS_C_PORT_CONNECTION:
488 mybug_unit(-1, ("UFS_C_PORT_CONNECTION\n"));
489 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_CONNECTION;
490 break;
492 case UFS_C_PORT_RESET:
493 mybug_unit(-1, ("UFS_C_PORT_RESET\n"));
494 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_RESET;
495 break;
497 case UFS_C_PORT_ENABLE:
498 mybug_unit(-1, ("UFS_C_PORT_ENABLE\n"));
499 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_ENABLE;
500 break;
502 case UFS_C_PORT_SUSPEND:
503 mybug_unit(-1, ("UFS_C_PORT_SUSPEND\n"));
504 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_SUSPEND;
505 break;
507 case UFS_C_PORT_OVER_CURRENT:
508 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT\n"));
509 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_OVER_CURRENT;
510 break;
513 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
514 return UHIOERR_NO_ERROR;
519 ClearTTBuffer:
520 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
521 bRequest USR_CLEAR_TT_BUFFER
522 wValue Dev_Addr, EP_Num
523 wIndex TT_port
524 wLength Zero
525 Data None
527 Not for USB3
530 UWORD ClearTTBuffer(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
531 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
532 mybug_unit(-1, ("Entering function\n"));
534 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
535 return UHIOERR_NO_ERROR;
539 GetHubDescriptor:
540 bmRequestType (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
541 bRequest USR_GET_DESCRIPTOR
542 wValue Descriptor Type and Descriptor Index
543 wIndex Zero (or language ID)
544 wLength Descriptor Length
545 Data Descriptor
547 UWORD GetHubDescriptor(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
548 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
549 mybug_unit(-1, ("Entering function\n"));
551 switch((wValue>>8)) {
552 case UDT_HUB:
553 mybug_unit(-1, ("GetHubDescriptor UDT_HUB (length %ld)\n", wLength));
555 ioreq->iouh_Actual = (wLength > sizeof(struct UsbHubDesc)) ? sizeof(struct UsbHubDesc) : wLength;
556 CopyMem((APTR) &unit->roothub.hubdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
558 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
559 return UHIOERR_NO_ERROR;
560 break;
562 case UDT_SSHUB:
563 mybug_unit(-1, ("GetHubDescriptor UDT_SSHUB (length %ld)\n", wLength));
565 ioreq->iouh_Actual = (wLength > sizeof(struct UsbSSHubDesc)) ? sizeof(struct UsbSSHubDesc) : wLength;
566 CopyMem((APTR) &unit->roothub.hubdesc, ioreq->iouh_Data, ioreq->iouh_Actual);
568 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
569 return UHIOERR_NO_ERROR;
570 break;
573 return UHIOERR_BADPARAMS;
577 GetHubStatus:
578 bmRequestType (URTF_IN|URTF_CLASS|URTF_DEVICE) 10100000B
579 bRequest USR_GET_STATUS
580 wValue Zero
581 wIndex Zero
582 wLength Four
583 Data Hub Status and Change Status
585 UWORD GetHubStatus(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
586 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
587 mybug_unit(-1, ("Entering function\n"));
589 /* It is a Request Error if wValue, wIndex, or wLength are other than as specified above. */
590 if( (!(wValue)) && (!(wIndex)) && (wLength == 4) ) {
592 struct UsbHubStatus *usbhubstatus = (struct UsbHubStatus *) ioreq->iouh_Data;
594 usbhubstatus->wHubStatus = unit->roothub.hubstatus.wHubStatus;
595 usbhubstatus->wHubChange = unit->roothub.hubstatus.wHubChange;
597 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
598 return UHIOERR_NO_ERROR;
601 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
602 return UHIOERR_BADPARAMS;
606 GetPortStatus:
607 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
608 bRequest USR_GET_STATUS
609 wValue Zero
610 wIndex Port
611 wLength Four
612 Data Port Status and Change Status
614 UWORD GetPortStatus(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
615 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
616 mybug_unit(-1, ("Entering function\n"));
618 mybug_unit(-1, ("Port #%ld\n", wIndex));
620 if( (wValue) || (wLength != 4) || (!wIndex) || (wIndex > unit->roothub.hubdesc.bNbrPorts) ) {
621 mybug_unit(-1, ("Port %ld out of range\n", wIndex));
622 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
623 return UHIOERR_BADPARAMS;
626 struct UsbPortStatus *usbportstatus = (struct UsbPortStatus *) ioreq->iouh_Data;
628 /* We have only one port per 'controller' */
629 usbportstatus->wPortStatus = unit->roothub.portstatus.wPortStatus;
630 usbportstatus->wPortChange = unit->roothub.portstatus.wPortChange;
632 mybug_unit(-1, ("usbportstatus->wPortStatus %01x\n", usbportstatus->wPortStatus));
633 mybug_unit(-1, ("usbportstatus->wPortChange %01x\n", usbportstatus->wPortChange));
635 if(usbportstatus->wPortStatus&UPSF_PORT_CONNECTION) {
636 mybug_unit(-1, (" - UPSF_PORT_CONNECTION\n"));
639 if(usbportstatus->wPortStatus&UPSF_PORT_ENABLE) {
640 mybug_unit(-1, (" - UPSF_PORT_ENABLE\n"));
643 if(usbportstatus->wPortStatus&UPSF_PORT_SUSPEND) {
644 mybug_unit(-1, (" - UPSF_PORT_SUSPEND\n"));
647 if(usbportstatus->wPortStatus&UPSF_PORT_OVER_CURRENT) {
648 mybug_unit(-1, (" - UPSF_PORT_OVER_CURRENT\n"));
651 if(usbportstatus->wPortStatus&UPSF_PORT_RESET) {
652 mybug_unit(-1, (" - UPSF_PORT_RESET\n"));
655 if(usbportstatus->wPortStatus&UPSF_PORT_POWER) {
656 mybug_unit(-1, (" - UPSF_PORT_POWER\n"));
659 if(usbportstatus->wPortStatus&UPSF_PORT_LOW_SPEED) {
660 mybug_unit(-1, (" - UPSF_PORT_LOW_SPEED\n"));
663 if(usbportstatus->wPortStatus&UPSF_PORT_HIGH_SPEED) {
664 mybug_unit(-1, (" - UPSF_PORT_HIGH_SPEED\n"));
667 if(usbportstatus->wPortStatus&UPSF_PORT_TEST_MODE) {
668 mybug_unit(-1, (" - UPSF_PORT_TEST_MODE\n"));
671 if(usbportstatus->wPortStatus&UPSF_PORT_INDICATOR) {
672 mybug_unit(-1, (" - UPSF_PORT_INDICATOR\n"));
675 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
676 return UHIOERR_NO_ERROR;
680 GetPortErrorCount:
681 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
682 bRequest USR_PORT_ERR_COUNT (Check: Has it been defined?)
683 wValue Zero
684 wIndex Port
685 wLength Two
686 Data Number of link errors on this port
688 UWORD GetPortErrorCount(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
689 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
690 mybug_unit(-1, ("Entering function\n"));
692 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
693 return UHIOERR_NO_ERROR;
697 ResetTT:
698 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
699 bRequest USR_RESET_TT
700 wValue Zero
701 wIndex Port
702 wLength Zero
703 Data None
705 Not for USB3
707 UWORD ResetTT(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
708 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
709 mybug_unit(-1, ("Entering function\n"));
711 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
712 return UHIOERR_NO_ERROR;
716 SetHubDescriptor:
717 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
718 bRequest USR_SET_DESCRIPTOR
719 wValue Descriptor Type and Descriptor Index
720 wIndex Zero or Language ID
721 wLength Descriptor Length
722 Data Descriptor
724 UWORD SetHubDescriptor(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
725 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
726 mybug_unit(-1, ("Entering function\n"));
728 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
729 return UHIOERR_NO_ERROR;
733 SetHubFeature:
734 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
735 bRequest USR_SET_FEATURE
736 wValue Feature Selector
737 wIndex Zero
738 wLength Zero
739 Data None
741 UWORD SetHubFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
742 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
743 mybug_unit(-1, ("Entering function\n"));
745 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
746 return UHIOERR_NO_ERROR;
750 SetHubDescriptor:
751 bmRequestType (URTF_OUT|URTF_CLASS|URTF_DEVICE) 00100000B
752 bRequest USR_SET_HUB_DEPTH (Check: Has it been defined?)
753 wValue Hub Depth
754 wIndex Zero
755 wLength Zero
756 Data None
758 UWORD SetHubDepth(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
759 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
760 mybug_unit(-1, ("Entering function\n"));
762 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
763 return UHIOERR_NO_ERROR;
767 SetPortFeature:
768 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
769 bRequest USR_SET_FEATURE
770 wValue Feature Selector
771 wIndex (Selector|Port)
772 wLength Zero
773 Data None
774 FIXME: Check what flags to set and clear on this and ClearPortFeature
777 UWORD SetPortFeature(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
778 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
779 mybug_unit(-1, ("Entering function\n"));
781 mybug_unit(-1, ("Setting feature 0x%02x on port %d\n",wValue, (wIndex & 0xff)));
783 if( ((!(wIndex & 0xff)) || ((wIndex & 0xff) > unit->roothub.hubdesc.bNbrPorts)) ) {
784 mybug_unit(-1, ("Port %ld out of range\n", (wIndex & 0xff)));
785 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
786 return UHIOERR_BADPARAMS;
789 switch(wValue) {
791 /* Features that can be set with this request */
792 case UFS_PORT_RESET:
793 mybug_unit(-1, ("UFS_PORT_RESET\n"));
794 unit->roothub.portstatus.wPortStatus |= (UPSF_PORT_ENABLE|UPSF_PORT_POWER);
795 break;
797 case UFS_PORT_SUSPEND:
798 mybug_unit(-1, ("UFS_PORT_SUSPEND\n"));
799 break;
801 case UFS_PORT_POWER:
802 mybug_unit(-1, ("UFS_PORT_POWER\n"));
803 unit->roothub.portstatus.wPortStatus |= UPSF_PORT_POWER;
804 break;
806 case UFS_PORT_TEST:
807 mybug_unit(-1, ("UFS_PORT_TEST\n"));
808 break;
810 case UFS_PORT_INDICATOR:
811 mybug_unit(-1, ("UFS_PORT_INDICATOR\n"));
812 break;
814 /* Features that can be set with this request but are not required */
815 case UFS_C_PORT_CONNECTION:
816 mybug_unit(-1, ("UFS_C_PORT_CONNECTION\n"));
817 break;
819 case UFS_C_PORT_RESET:
820 mybug_unit(-1, ("UFS_C_PORT_RESET\n"));
821 break;
823 case UFS_C_PORT_ENABLE:
824 mybug_unit(-1, ("UFS_C_PORT_ENABLE\n"));
825 break;
827 case UFS_C_PORT_SUSPEND:
828 mybug_unit(-1, ("UFS_C_PORT_SUSPEND\n"));
829 break;
831 case UFS_C_PORT_OVER_CURRENT:
832 mybug_unit(-1, ("UFS_C_PORT_OVER_CURRENT\n"));
833 break;
835 default:
836 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
837 return UHIOERR_BADPARAMS;
838 break;
842 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
843 return UHIOERR_NO_ERROR;
847 GetTTState:
848 bmRequestType (URTF_IN|URTF_CLASS|URTF_OTHER) 10100011B
849 bRequest USR_GET_TT_STATE
850 wValue TT_Flags
851 wIndex Port
852 wLength TT State Length
853 Data TT State
855 Not for USB3
857 UWORD GetTTState(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
858 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
859 mybug_unit(-1, ("Entering function\n"));
861 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
862 return UHIOERR_NO_ERROR;
866 StopTT:
867 bmRequestType (URTF_OUT|URTF_CLASS|URTF_OTHER) 00100011B
868 bRequest USR_STOP_TT
869 wValue Zero
870 wIndex Port
871 wLength Zero
872 Data None
874 Not for USB3
876 UWORD StopTT(struct IOUsbHWReq *ioreq, UWORD wValue, UWORD wIndex, UWORD wLength) {
877 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
878 mybug_unit(-1, ("Entering function\n"));
880 mybug_unit(-1, ("return UHIOERR_NO_ERROR\n\n"));
881 return UHIOERR_NO_ERROR;
884 WORD cmdControlXFerRootHub(struct IOUsbHWReq *ioreq) {
886 UWORD bmRequestType = (ioreq->iouh_SetupData.bmRequestType) & (URTF_STANDARD | URTF_CLASS | URTF_VENDOR);
887 UWORD bmRequestDirection = (ioreq->iouh_SetupData.bmRequestType) & (URTF_IN | URTF_OUT);
888 UWORD bmRequestRecipient = (ioreq->iouh_SetupData.bmRequestType) & (URTF_DEVICE | URTF_INTERFACE | URTF_ENDPOINT | URTF_OTHER);
890 UWORD bRequest = (ioreq->iouh_SetupData.bRequest);
891 UWORD wValue = AROS_WORD2LE(ioreq->iouh_SetupData.wValue);
892 UWORD wIndex = AROS_WORD2LE(ioreq->iouh_SetupData.wIndex);
893 UWORD wLength = AROS_WORD2LE(ioreq->iouh_SetupData.wLength);
895 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
897 /* Endpoint 0 is used for control transfers only and can not be assigned to any other function. */
898 if(ioreq->iouh_Endpoint != 0) {
899 mybug_unit(-1, ("Wrong endpoint number! %ld\n", ioreq->iouh_Endpoint));
900 mybug_unit(-1, ("return UHIOERR_BADPARAMS\n\n"));
901 return UHIOERR_BADPARAMS;
904 switch(((ULONG)ioreq->iouh_SetupData.bmRequestType<<16)|((ULONG)ioreq->iouh_SetupData.bRequest)) {
906 /* Standard Requests */
907 case (((URTF_IN|URTF_STANDARD|URTF_DEVICE)<<16)|(USR_GET_STATUS)):
908 return(GetStatus(ioreq, wValue, wIndex, wLength));
910 case (((URTF_IN|URTF_STANDARD|URTF_DEVICE)<<16)|(USR_CLEAR_FEATURE)):
911 return(ClearFeature(ioreq, wValue, wIndex, wLength));
913 case (((URTF_IN|URTF_STANDARD|URTF_DEVICE)<<16)|(USR_SET_FEATURE)):
914 return(SetFeature(ioreq, wValue, wIndex, wLength));
916 case ((((URTF_OUT|URTF_STANDARD|URTF_DEVICE))<<16)|(USR_SET_ADDRESS)):
917 return(SetAddress(ioreq, wValue, wIndex, wLength));
919 case (((URTF_IN|URTF_STANDARD|URTF_DEVICE)<<16)|(USR_GET_DESCRIPTOR)):
920 return(GetDescriptor(ioreq, wValue, wIndex, wLength));
922 case (((URTF_OUT|URTF_STANDARD|URTF_DEVICE)<<16)|(USR_SET_DESCRIPTOR)):
923 return(SetDescriptor(ioreq, wValue, wIndex, wLength));
925 case ((((URTF_OUT|URTF_STANDARD|URTF_DEVICE))<<16)|(USR_GET_CONFIGURATION)):
926 return(GetConfiguration(ioreq, wValue, wIndex, wLength));
928 case ((((URTF_OUT|URTF_STANDARD|URTF_DEVICE))<<16)|(USR_SET_CONFIGURATION)):
929 return(SetConfiguration(ioreq, wValue, wIndex, wLength));
931 /* Hub Class Requests. Check here if the command is for USB2 or USB3 hub... */
932 case (((URTF_OUT|URTF_CLASS|URTF_DEVICE)<<16)|(USR_CLEAR_FEATURE)):
933 return(ClearHubFeature(ioreq, wValue, wIndex, wLength));
935 case (((URTF_OUT|URTF_CLASS|URTF_OTHER)<<16)|(USR_CLEAR_FEATURE)):
936 return(ClearPortFeature(ioreq, wValue, wIndex, wLength));
938 case (((URTF_OUT|URTF_CLASS|URTF_DEVICE)<<16)|(USR_SET_FEATURE)):
939 return(SetHubFeature(ioreq, wValue, wIndex, wLength));
941 case (((URTF_OUT|URTF_CLASS|URTF_OTHER)<<16)|(USR_SET_FEATURE)):
942 return(SetPortFeature(ioreq, wValue, wIndex, wLength));
944 case (((URTF_IN|URTF_CLASS|URTF_DEVICE)<<16)|(USR_GET_DESCRIPTOR)):
945 return(GetHubDescriptor(ioreq, wValue, wIndex, wLength));
947 case ((((URTF_IN|URTF_CLASS|URTF_DEVICE))<<16)|(USR_GET_STATUS)):
948 return(GetHubStatus(ioreq, wValue, wIndex, wLength));
950 case ((((URTF_IN|URTF_CLASS|URTF_OTHER))<<16)|(USR_GET_STATUS)):
951 return(GetPortStatus(ioreq, wValue, wIndex, wLength));
953 // case (((( X ))<<16)|( X )):
954 // return( X (ioreq));
956 default:
957 mybug_unit(-1, ("ATTENTION! Unhandled!\n"));
958 mybug_unit(-1, ("ioreq->iouh_SetupData.bmRequestType %x\n", ioreq->iouh_SetupData.bmRequestType));
959 mybug_unit(-1, ("ioreq->iouh_SetupData.bRequest %x\n", ioreq->iouh_SetupData.bRequest));
960 mybug_unit(-1, ("ioreq->iouh_SetupData.wValue %x\n", ioreq->iouh_SetupData.wValue));
961 mybug_unit(-1, ("ioreq->iouh_SetupData.wIndex %x\n", ioreq->iouh_SetupData.wIndex));
962 mybug_unit(-1, ("ioreq->iouh_SetupData.wLength %x\n", ioreq->iouh_SetupData.wLength));
963 break;
966 mybug_unit(-1, ("Nothing done!\n\n"));
967 return UHIOERR_BADPARAMS;
970 WORD cmdIntXFerRootHub(struct IOUsbHWReq *ioreq) {
971 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
973 mybug_unit(-1, ("Entering function\n"));
975 if((ioreq->iouh_Endpoint != 1) || (!ioreq->iouh_Length)) {
976 mybug_unit(-1, ("UHIOERR_BADPARAMS\n"));
977 return(UHIOERR_BADPARAMS); // was UHIOERR_STALL
980 #if 0
981 if(unit->roothub.portstatus.wPortChange) {
982 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit->roothub.portstatus.wPortChange));
983 *((UBYTE *) ioreq->iouh_Data) = unit->roothub.portstatus.wPortChange;
984 ioreq->iouh_Actual = 1;
985 unit->roothub.portstatus.wPortChange &= ~UPSF_PORT_CONNECTION;
986 mybug_unit(-1, ("unit->roothub.portstatus.wPortChange = %02x\n", unit->roothub.portstatus.wPortChange));
987 return(0);
989 #endif
991 mybug_unit(-1, ("ioreq added to roothub intrxfer_queue\n"));
993 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
994 ObtainSemaphore(&unit->roothub.intrxfer_queue_lock);
995 AddTail(&unit->roothub.intrxfer_queue, (struct Node *) ioreq);
996 ReleaseSemaphore(&unit->roothub.intrxfer_queue_lock);
998 return(RC_DONTREPLY);
1002 WORD cmdControlXFer(struct IOUsbHWReq *ioreq) {
1003 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1005 mybug_unit(-1, ("Entering function\n"));
1007 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1008 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1011 Check the status of the controller
1012 We might encounter these states:
1013 UHSB_OPERATIONAL USB can be used for transfers
1014 UHSB_RESUMING USB is currently resuming
1015 UHSB_SUSPENDED USB is in suspended state
1016 UHSB_RESET USB is just inside a reset phase
1019 if(unit->state == UHSF_OPERATIONAL) {
1020 mybug_unit(0, ("Unit state is operational\n"));
1021 } else {
1022 mybug_unit(-1, ("Unit state is not operational!\n"));
1023 return UHIOERR_USBOFFLINE;
1026 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
1027 return(cmdControlXFerRootHub(ioreq));
1030 mybug_unit(-1, ("Sending transfer request to libusb ->\n"));
1031 return(do_libusb_ctrl_transfer(ioreq));
1035 WORD cmdControlXFer(struct IOUsbHWReq *ioreq) {
1036 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1038 mybug_unit(0, ("Entering function\n"));
1040 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1041 mybug_unit(0, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1044 Check the status of the controller
1045 We might encounter these states:
1046 UHSB_OPERATIONAL USB can be used for transfers
1047 UHSB_RESUMING USB is currently resuming
1048 UHSB_SUSPENDED USB is in suspended state
1049 UHSB_RESET USB is just inside a reset phase
1052 if(unit->state == UHSF_OPERATIONAL) {
1053 mybug_unit(0, ("Unit state is operational\n"));
1054 } else {
1055 mybug_unit(-1, ("Unit state is not operational!\n"));
1056 return UHIOERR_USBOFFLINE;
1059 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
1060 return(cmdControlXFerRootHub(ioreq));
1063 mybug_unit(-1, ("Adding CNTR transfer request to queue\n"));
1064 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
1065 ioreq->iouh_Actual = 0;
1067 ObtainSemaphore(&unit->ctrlxfer_queue_lock);
1068 AddTail(&unit->ctrlxfer_queue, (struct Node *) ioreq);
1069 ReleaseSemaphore(&unit->ctrlxfer_queue_lock);
1071 return(RC_DONTREPLY);
1074 WORD cmdIntXFer(struct IOUsbHWReq *ioreq) {
1075 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1077 mybug_unit(-1, ("Entering function\n"));
1079 mybug_unit(-1, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1080 mybug_unit(-1, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1083 Check the status of the controller
1084 We might encounter these states:
1085 UHSB_OPERATIONAL USB can be used for transfers
1086 UHSB_RESUMING USB is currently resuming
1087 UHSB_SUSPENDED USB is in suspended state
1088 UHSB_RESET USB is just inside a reset phase
1091 if(unit->state == UHSF_OPERATIONAL) {
1092 mybug_unit(0, ("Unit state is operational\n"));
1093 } else {
1094 mybug_unit(-1, ("Unit state is not operational!\n"));
1095 return UHIOERR_USBOFFLINE;
1098 if(ioreq->iouh_DevAddr == unit->roothub.addr) {
1099 return(cmdIntXFerRootHub(ioreq));
1102 mybug_unit(-1, ("Adding INTR transfer request to queue\n"));
1103 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
1104 ioreq->iouh_Actual = 0;
1106 ObtainSemaphore(&unit->intrxfer_queue_lock);
1107 AddTail(&unit->intrxfer_queue, (struct Node *) ioreq);
1108 ReleaseSemaphore(&unit->intrxfer_queue_lock);
1110 return(RC_DONTREPLY);
1113 WORD cmdBulkXFer(struct IOUsbHWReq *ioreq) {
1114 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1116 mybug_unit(0, ("Entering function\n"));
1118 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1119 mybug_unit(0, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1122 Check the status of the controller
1123 We might encounter these states:
1124 UHSB_OPERATIONAL USB can be used for transfers
1125 UHSB_RESUMING USB is currently resuming
1126 UHSB_SUSPENDED USB is in suspended state
1127 UHSB_RESET USB is just inside a reset phase
1130 if(unit->state == UHSF_OPERATIONAL) {
1131 mybug_unit(0, ("Unit state is operational\n"));
1132 } else {
1133 mybug_unit(-1, ("Unit state is not operational!\n"));
1134 return UHIOERR_USBOFFLINE;
1137 mybug_unit(0, ("Adding BULK transfer request to queue\n"));
1138 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
1139 ioreq->iouh_Actual = 0;
1141 ObtainSemaphore(&unit->bulkxfer_queue_lock);
1142 AddTail(&unit->bulkxfer_queue, (struct Node *) ioreq);
1143 ReleaseSemaphore(&unit->bulkxfer_queue_lock);
1145 return(RC_DONTREPLY);
1148 WORD cmdISOXFer(struct IOUsbHWReq *ioreq) {
1149 struct VUSBHCIUnit *unit = (struct VUSBHCIUnit *) ioreq->iouh_Req.io_Unit;
1151 mybug_unit(0, ("Entering function\n"));
1153 mybug_unit(0, ("ioreq->iouh_DevAddr %lx\n", ioreq->iouh_DevAddr));
1154 mybug_unit(0, ("unit->roothub.addr %lx\n", unit->roothub.addr));
1157 Check the status of the controller
1158 We might encounter these states:
1159 UHSB_OPERATIONAL USB can be used for transfers
1160 UHSB_RESUMING USB is currently resuming
1161 UHSB_SUSPENDED USB is in suspended state
1162 UHSB_RESET USB is just inside a reset phase
1165 if(unit->state == UHSF_OPERATIONAL) {
1166 mybug_unit(0, ("Unit state is operational\n"));
1167 } else {
1168 mybug_unit(-1, ("Unit state is not operational!\n"));
1169 return UHIOERR_USBOFFLINE;
1172 mybug_unit(0, ("Adding ISOC transfer request to queue\n"));
1173 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
1174 ioreq->iouh_Actual = 0;
1176 ObtainSemaphore(&unit->isocxfer_queue_lock);
1177 AddTail(&unit->isocxfer_queue, (struct Node *) ioreq);
1178 ReleaseSemaphore(&unit->isocxfer_queue_lock);
1180 return(RC_DONTREPLY);
1183 void uhwCheckRootHubChanges(struct VUSBHCIUnit *unit) {
1184 mybug_unit(0, ("Entering function\n"));
1186 mybug_unit(0, ("usbportstatus->wPortStatus %01x\n", unit->roothub.portstatus.wPortStatus));
1187 mybug_unit(0, ("usbportstatus->wPortChange %01x\n", unit->roothub.portstatus.wPortChange));
1189 struct IOUsbHWReq *ioreq;
1191 ObtainSemaphore(&unit->roothub.intrxfer_queue_lock);
1192 if(unit->roothub.portstatus.wPortChange && unit->roothub.intrxfer_queue.lh_Head->ln_Succ) {
1193 ioreq = (struct IOUsbHWReq *) unit->roothub.intrxfer_queue.lh_Head;
1194 while(((struct Node *) ioreq)->ln_Succ) {
1195 Remove(&ioreq->iouh_Req.io_Message.mn_Node);
1197 *((UBYTE *) ioreq->iouh_Data) = (1<<1);
1198 ioreq->iouh_Actual = 1;
1200 ReplyMsg(&ioreq->iouh_Req.io_Message);
1201 ioreq = (struct IOUsbHWReq *) unit->roothub.intrxfer_queue.lh_Head;
1205 ReleaseSemaphore(&unit->roothub.intrxfer_queue_lock);