use the soc family name, not specific chip name(s)
[AROS.git] / arch / arm-native / soc / broadcom / 2708 / usb / usb2otg / usb2otg_core.c
blob0701623644e333d1c5e8f5ef9b588557a56044b9
1 /*
2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/kernel.h>
11 #include <proto/utility.h>
13 #include "usb2otg_intern.h"
15 static const UWORD __suported_cmds[] =
17 CMD_FLUSH,
18 CMD_RESET,
19 UHCMD_QUERYDEVICE,
20 UHCMD_USBRESET,
21 UHCMD_USBRESUME,
22 UHCMD_USBSUSPEND,
23 UHCMD_USBOPER,
24 UHCMD_CONTROLXFER,
25 UHCMD_ISOXFER,
26 UHCMD_INTXFER,
27 UHCMD_BULKXFER,
28 NSCMD_DEVICEQUERY,
32 struct Unit * FNAME_DEV(OpenUnit)(struct IOUsbHWReq *ioreq,
33 LONG unitnr,
34 LIBBASETYPEPTR USB2OTGBase)
36 struct USB2OTGUnit *otg_Unit = NULL;
37 volatile unsigned int otg_RegVal;
38 unsigned int chan, ns;
40 D(bug("[USB2OTG] %s(ioreq:0x%p, unit#%d)\n",
41 __PRETTY_FUNCTION__, ioreq, unitnr));
43 // We only support a single unit presently
44 if ((unitnr == 0) && (USB2OTGBase->hd_Unit))
46 otg_Unit = USB2OTGBase->hd_Unit;
47 if (!(otg_Unit->hu_UnitAllocated))
49 otg_Unit->hu_UnitAllocated = TRUE;
51 D(bug("[USB2OTG] %s: Enabling Power ..\n", __PRETTY_FUNCTION__));
52 *((volatile unsigned int *)USB2OTG_POWER) = 0;
53 #if (0)
54 D(bug("[USB2OTG] %s: Preparing Controller (non HSIC mode) ..\n", __PRETTY_FUNCTION__));
55 *((volatile unsigned int *)USB2OTG_USB) = USB2OTG_USB_MODESELECT|USB2OTG_USB_USBTRDTIM(5)|(USB2OTGBase->hd_Unit->hu_OperatingMode << 29);
56 *((volatile unsigned int *)USB2OTG_OTGCTRL) = 0;
58 otg_RegVal = *((volatile unsigned int *)USB2OTG_LPMCONFIG);
59 otg_RegVal &= ~USB2OTG_LPMCONFIG_HSICCONNECT;
60 *((volatile unsigned int *)USB2OTG_LPMCONFIG) = otg_RegVal;
62 D(bug("[USB2OTG] %s: Clearing Global NAK ..\n", __PRETTY_FUNCTION__));
63 *((volatile unsigned int *)USB2OTG_DEVCTRL) = (1 << 10) | (1 << 8);
64 #endif
65 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
66 if (((otg_RegVal & (3 << 6) >> 6) == 2) && ((otg_RegVal & (3 << 8) >> 8) == 1))
68 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
69 if (otg_RegVal & USB2OTG_USB_ULPIFSLS)
71 D(bug("[USB2OTG] %s: Host clock: 48Mhz\n", __PRETTY_FUNCTION__));
72 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTCFG);
73 otg_RegVal &= ~3;
74 otg_RegVal |= 1;
75 *((volatile unsigned int *)USB2OTG_HOSTCFG) = otg_RegVal;
77 else
79 D(bug("[USB2OTG] %s: Host clock: 30-60Mhz\n", __PRETTY_FUNCTION__));
80 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTCFG);
81 otg_RegVal &= ~3;
82 *((volatile unsigned int *)USB2OTG_HOSTCFG) = otg_RegVal;
84 } else {
85 D(bug("[USB2OTG] %s: Host clock: 30-60Mhz\n", __PRETTY_FUNCTION__));
86 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTCFG);
87 otg_RegVal &= ~3;
88 *((volatile unsigned int *)USB2OTG_HOSTCFG) = otg_RegVal;
90 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTCFG);
91 otg_RegVal |= (1 << 2);
92 *((volatile unsigned int *)USB2OTG_HOSTCFG) = otg_RegVal;
94 D(bug("[USB2OTG] %s: Enabling HNP...\n", __PRETTY_FUNCTION__));
95 otg_RegVal = *((volatile unsigned int *)USB2OTG_OTGCTRL);
96 otg_RegVal |= USB2OTG_OTGCTRL_HOSTSETHNPENABLE;
97 *((volatile unsigned int *)USB2OTG_OTGCTRL) = otg_RegVal;
99 D(bug("[USB2OTG] %s: Flushing Tx Fifo's...\n", __PRETTY_FUNCTION__));
100 *((volatile unsigned int *)USB2OTG_RESET) = USB2OTG_RESET_TXFIFOFLUSH|(16 << 6);
101 for (ns = 0; ns < 10000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
102 if ((*((volatile unsigned int *)USB2OTG_RESET) & USB2OTG_RESET_TXFIFOFLUSH) != 0)
103 bug("[USB2OTG] %s: Tx Flush Timed-Out!\n", __PRETTY_FUNCTION__);
105 D(bug("[USB2OTG] %s: Flushing Rx Fifo's...\n", __PRETTY_FUNCTION__));
106 *((volatile unsigned int *)USB2OTG_RESET) = USB2OTG_RESET_RXFIFOFLUSH;
107 for (ns = 0; ns < 10000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
108 if ((*((volatile unsigned int *)USB2OTG_RESET) & USB2OTG_RESET_RXFIFOFLUSH) != 0)
109 bug("[USB2OTG] %s: Rx Flush Timed-Out!\n", __PRETTY_FUNCTION__);
111 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE3);
112 D(bug("[USB2OTG] %s: Queue Depths:\n",
113 __PRETTY_FUNCTION__));
114 D(bug("[USB2OTG] %s: Periodic Transmit: 0x%0x\n",
115 __PRETTY_FUNCTION__, ((otg_RegVal & (0x3 << 24)) >> 24)));
116 D(bug("[USB2OTG] %s: Non-Periodic Transmit: 0x%0x\n",
117 __PRETTY_FUNCTION__, ((otg_RegVal & (0x3 << 22)) >> 22)));
118 #if (0)
119 D(bug("[USB2OTG] %s: Device Tokens: 0x%0x\n",
120 __PRETTY_FUNCTION__, ((otg_RegVal & (0x1F << 26)) >> 26)));
121 #endif
122 D(bug("[USB2OTG] %s: FIFO: %ld bytes\n",
123 __PRETTY_FUNCTION__, ((otg_RegVal & (0xFFFF << 16)) >> 16) << 2));
124 #if (0)
125 D(bug("[USB2OTG] %s: Xfer Size: %ld\n",
126 __PRETTY_FUNCTION__, (otg_RegVal & 0xF)));
127 #endif
129 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
130 if ((otg_Unit->hu_HostChans = ((otg_RegVal & (0xF << 14)) >> 14) + 1) > EPSCHANS_MAX)
131 otg_Unit->hu_HostChans = EPSCHANS_MAX;
133 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTCFG);
134 if ((otg_RegVal & (1 << 23)) == 0)
136 D(bug("[USB2OTG] %s: Host Channels: %d\n",
137 __PRETTY_FUNCTION__, otg_Unit->hu_HostChans));
139 for (chan = 0; chan < otg_Unit->hu_HostChans; chan++) {
140 #if (0)
141 *((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_INTRMASK)) =
142 (USB2OTG_INTRCHAN_STALL|USB2OTG_INTRCHAN_BABBLEERROR|USB2OTG_INTRCHAN_TRANSACTIONERROR) |
143 (USB2OTG_INTRCHAN_NEGATIVEACKNOWLEDGE|USB2OTG_INTRCHAN_ACKNOWLEDGE|USB2OTG_INTRCHAN_NOTREADY) |
144 (USB2OTG_INTRCHAN_HALT|USB2OTG_INTRCHAN_FRAMEOVERRUN|USB2OTG_INTRCHAN_DATATOGGLEERROR);
145 #endif
146 otg_RegVal = *((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_CHARBASE));
147 D(bug("[USB2OTG] %s: Chan #%d FIFO @ 0x%p, Characteristics: %08x -> %08x\n",
148 __PRETTY_FUNCTION__,
149 chan, USB2OTG_FIFOBASE + (chan * USB2OTG_FIFOSIZE), otg_RegVal, (otg_RegVal & ~USB2OTG_HOSTCHAR_ENABLE) | (USB2OTG_HOSTCHAR_DISABLE | (1 << USB2OTG_HOSTCHAR_EPDIR))
151 otg_RegVal &= ~USB2OTG_HOSTCHAR_ENABLE;
152 otg_RegVal |= USB2OTG_HOSTCHAR_DISABLE | (1 << USB2OTG_HOSTCHAR_EPDIR);
153 *((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_CHARBASE)) = otg_RegVal;
156 for (chan = 0; chan < otg_Unit->hu_HostChans; chan++) {
157 otg_RegVal = *((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_CHARBASE));
158 otg_RegVal |= USB2OTG_HOSTCHAR_ENABLE|USB2OTG_HOSTCHAR_DISABLE|(1 << USB2OTG_HOSTCHAR_EPDIR);
159 *((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_CHARBASE)) = otg_RegVal;
160 for (ns = 0; ns < 100000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 100ms
161 if ((*((volatile unsigned int *)(USB2OTG_HOST_CHANBASE + (chan * USB2OTG_HOST_CHANREGSIZE) + USB2OTG_HOSTCHAN_CHARBASE)) & USB2OTG_HOSTCHAR_ENABLE) != 0)
162 bug("[USB2OTG] %s: Unable to clear Halt on channel #%d\n", __PRETTY_FUNCTION__, chan);
165 #if (0)
166 D(bug("[USB2OTG] %s: Enabling HOST Channel Interrupts ...\n",
167 __PRETTY_FUNCTION__));
168 *((volatile unsigned int *)USB2OTG_HOSTINTRMASK) = (1U << otg_Unit->hu_HostChans) - 1U;
169 #endif
171 #if (0)
172 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
174 if (!(otg_Unit->hu_OperatingMode) || (otg_Unit->hu_OperatingMode == USB2OTG_USBDEVICEMODE))
176 D(bug("[USB2OTG] %s: Configuring USB Core DEVICE mode -:\n",
177 __PRETTY_FUNCTION__));
179 if ((otg_Unit->hu_DevEPs = ((otg_RegVal & (0xF << 10)) >> 10) + 1) > EPSCHANS_MAX)
180 otg_Unit->hu_DevEPs = EPSCHANS_MAX;
182 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE4);
183 otg_Unit->hu_DevInEPs = ((otg_RegVal & (0xF << 26)) >> 26) + 1;
185 D(bug("[USB2OTG] %s: Endpoints: %d/%d\n",
186 __PRETTY_FUNCTION__, otg_Unit->hu_DevInEPs, otg_Unit->hu_DevEPs));
188 for (chan = 0; chan < otg_Unit->hu_DevEPs; chan++) {
189 D(bug("[USB2OTG] %s: Endpoint #%d ", __PRETTY_FUNCTION__, chan));
190 if (chan < otg_Unit->hu_DevInEPs)
192 D(bug("IN_CTL: %08x, ", *((volatile unsigned int *)(USB2OTG_DEV_INEP_BASE + (chan * USB2OTG_DEV_EPSIZE) + USB2OTG_DEV_INEP_DIEPCTL))));
194 D(bug("OUT_CTL: %08x\n", *((volatile unsigned int *)(USB2OTG_DEV_OUTEP_BASE + (chan * USB2OTG_DEV_EPSIZE) + USB2OTG_DEV_OUTEP_DOEPCTL))));
197 #endif
199 #if (0)
200 D(bug("[USB2OTG] %s: Pulling-Up D+ ..\n", __PRETTY_FUNCTION__));
201 otg_RegVal = *((volatile unsigned int *)USB2OTG_DEVCTRL);
202 otg_RegVal &= ~(1 << 1);
203 *((volatile unsigned int *)USB2OTG_DEVCTRL) = otg_RegVal;
204 #endif
206 otg_RegVal = *((volatile unsigned int *)USB2OTG_HOSTPORT);
207 if (!(otg_RegVal & USB2OTG_HOSTPORT_PRTPWR))
209 D(bug("[USB2OTG] %s: Powering On Host Port ..\n", __PRETTY_FUNCTION__));
210 otg_RegVal |= USB2OTG_HOSTPORT_PRTPWR;
211 *((volatile unsigned int *)USB2OTG_HOSTPORT) = otg_RegVal;
214 D(bug("[USB2OTG] %s: Reseting Host Port ..\n", __PRETTY_FUNCTION__));
215 otg_RegVal |= USB2OTG_HOSTPORT_PRTRST;
216 *((volatile unsigned int *)USB2OTG_HOSTPORT) = otg_RegVal;
217 for (ns = 0; ns < 10000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
218 otg_RegVal &= ~USB2OTG_HOSTPORT_PRTRST;
219 *((volatile unsigned int *)USB2OTG_HOSTPORT) = otg_RegVal;
221 #if (0)
222 D(bug("[USB2OTG] %s: Configuring Interrupts ...\n",
223 __PRETTY_FUNCTION__));
225 *((volatile unsigned int *)USB2OTG_INTRMASK) =
226 (USB2OTG_INTRCORE_ENUMERATIONDONE|USB2OTG_INTRCORE_USBRESET|USB2OTG_INTRCORE_USBSUSPEND) |
227 (USB2OTG_INTRCORE_INENDPOINT|USB2OTG_INTRCORE_RECEIVESTATUSLEVEL|USB2OTG_INTRCORE_SESSIONREQUEST|USB2OTG_INTRCORE_OTG|USB2OTG_INTRCORE_HOSTCHANNEL|USB2OTG_INTRCORE_PORT);
229 if (!(otg_Unit->hu_OperatingMode) || (otg_Unit->hu_OperatingMode == USB2OTG_USBDEVICEMODE))
231 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
232 if (otg_RegVal & (1 << 20))
234 D(bug("[USB2OTG] %s: Multi-Process Interrupts ...\n",
235 __PRETTY_FUNCTION__));
236 for (chan = 0; chan < otg_Unit->hu_DevInEPs; chan++) {
237 // *((volatile unsigned int *)(USB2OTG_DEV_INEP_BASE + (chan * USB2OTG_DEV_EPSIZE) + USB2OTG_DEV_INEP_DIEPCTL)) = (1 << 0);
238 // *((volatile unsigned int *)(USB2OTG_DEV_INEP_BASE + (chan * USB2OTG_DEV_EPSIZE) + USB2OTG_DEV_INEP_DIEPCTL)) = 0;
239 *((volatile unsigned int *)USB2OTG_DEVEACHINTMSK) = 0xFFFF;
242 else
244 *((volatile unsigned int *)USB2OTG_DEVINEPMASK) = (1 << 0);
245 *((volatile unsigned int *)USB2OTG_DEVOUTEPMASK) = 0;
246 *((volatile unsigned int *)USB2OTG_DEVINTRMASK) = 0xFFFF;
250 D(bug("[USB2OTG] %s: Enabling Global Interrupts ...\n",
251 __PRETTY_FUNCTION__));
252 *((volatile unsigned int *)USB2OTG_AHB) = USB2OTG_AHB_INTENABLE;
253 #endif
255 D(bug("[USB2OTG] %s: Initialising NakTimeout (intr @ 0x%p) ...\n",
256 __PRETTY_FUNCTION__, &otg_Unit->hu_NakTimeoutInt));
258 Cause(&otg_Unit->hu_NakTimeoutInt);
261 otg_RegVal = *((volatile unsigned int *)USB2OTG_OTGCTRL);
262 D(bug("[USB2OTG] %s: OTG Control: %08x\n",
263 __PRETTY_FUNCTION__, otg_RegVal));
265 return (&otg_Unit->hu_Unit);
268 return (NULL);
271 void FNAME_DEV(CloseUnit)(struct IOUsbHWReq *ioreq, struct USB2OTGUnit *otg_Unit, LIBBASETYPEPTR USB2OTGBase)
273 D(bug("[USB2OTG] %s(unit:0x%p, ioreq:0x%p)\n",
274 __PRETTY_FUNCTION__, otg_Unit, ioreq));
276 otg_Unit->hu_UnitAllocated = FALSE;
279 void FNAME_DEV(TermIO)(struct IOUsbHWReq *ioreq,
280 LIBBASETYPEPTR USB2OTGBase)
282 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_FREEMSG;
284 if (!(ioreq->iouh_Req.io_Flags & IOF_QUICK))
286 ReplyMsg(&ioreq->iouh_Req.io_Message);
290 WORD FNAME_DEV(cmdNSDeviceQuery)(struct IOStdReq *ioreq,
291 struct USB2OTGUnit *otg_Unit,
292 LIBBASETYPEPTR USB2OTGBase)
294 struct USBNSDeviceQueryResult *query = (struct USBNSDeviceQueryResult *)ioreq->io_Data;
296 D(bug("[USB2OTG] NSCMD_DEVICEQUERY(unit:0x%p, ioreq:0x%p)\n",
297 otg_Unit, ioreq));
299 if ((!query) ||
300 (ioreq->io_Length < sizeof(struct USBNSDeviceQueryResult)) ||
301 (query->DevQueryFormat != 0) ||
302 (query->SizeAvailable != 0))
304 ioreq->io_Error = IOERR_NOCMD;
305 FNAME_DEV(TermIO)((struct IOUsbHWReq *) ioreq, USB2OTGBase);
307 return RC_DONTREPLY;
310 ioreq->io_Actual = query->SizeAvailable
311 = sizeof(struct USBNSDeviceQueryResult);
312 query->DeviceType = NSDEVTYPE_USBHARDWARE;
313 query->DeviceSubType = 0;
314 query->SupportedCommands = __suported_cmds;
316 return RC_OK;
319 WORD FNAME_DEV(cmdQueryDevice)(struct IOUsbHWReq *ioreq,
320 struct USB2OTGUnit *otg_Unit,
321 LIBBASETYPEPTR USB2OTGBase)
323 struct TagItem *taglist = (struct TagItem *) ioreq->iouh_Data;
324 struct TagItem *tag;
325 ULONG count = 0;
327 D(bug("[USB2OTG] UHCMD_QUERYDEVICE(unit:0x%p, ioreq:0x%p)\n",
328 otg_Unit, ioreq));
330 if (((tag = FindTagItem(UHA_State, taglist)) != NULL) && (tag->ti_Data))
332 *((IPTR *) tag->ti_Data) = (IPTR)UHSF_OPERATIONAL;
333 count++;
336 if (((tag = FindTagItem(UHA_Manufacturer, taglist)) != NULL) && (tag->ti_Data))
338 *((STRPTR *) tag->ti_Data) = "The AROS Dev Team";
339 count++;
342 if (((tag = FindTagItem(UHA_ProductName, taglist)) != NULL) && (tag->ti_Data))
344 *((STRPTR *) tag->ti_Data) = "HS USB 2.0 OTG Controller";
345 count++;
348 if (((tag = FindTagItem(UHA_Description, taglist)) != NULL) && (tag->ti_Data))
350 *((STRPTR *) tag->ti_Data) = "Synopsys/DesignWare USB 2.0 OTG Controller for Raspberry Pi";
351 count++;
354 if (((tag = FindTagItem(UHA_Copyright, taglist)) != NULL) && (tag->ti_Data))
356 *((STRPTR *) tag->ti_Data) ="©2013 The AROS Dev Team";
357 count++;
360 if (((tag = FindTagItem(UHA_Version, taglist)) != NULL) && (tag->ti_Data))
362 *((IPTR *) tag->ti_Data) = VERSION_NUMBER;
363 count++;
366 if (((tag = FindTagItem(UHA_Revision, taglist)) != NULL) && (tag->ti_Data))
368 *((IPTR *) tag->ti_Data) = REVISION_NUMBER;
369 count++;
372 if (((tag = FindTagItem(UHA_DriverVersion, taglist)) != NULL) && (tag->ti_Data))
374 *((IPTR *) tag->ti_Data) = 0x100;
375 count++;
378 if (((tag = FindTagItem(UHA_Capabilities, taglist)) != NULL) && (tag->ti_Data))
380 *((IPTR *) tag->ti_Data) = UHCF_USB20;
381 count++;
383 ioreq->iouh_Actual = count;
385 return RC_OK;
388 WORD FNAME_DEV(cmdReset)(struct IOUsbHWReq *ioreq,
389 struct USB2OTGUnit *otg_Unit,
390 LIBBASETYPEPTR USB2OTGBase)
392 D(bug("[USB2OTG] CMD_RESET(unit:0x%p, ioreq:0x%p)\n",
393 otg_Unit, ioreq));
395 if (ioreq->iouh_State & UHSF_OPERATIONAL)
397 return RC_OK;
400 return (WORD)UHIOERR_USBOFFLINE;
403 WORD FNAME_DEV(cmdFlush)(struct IOUsbHWReq *ioreq,
404 struct USB2OTGUnit *otg_Unit,
405 LIBBASETYPEPTR USB2OTGBase)
407 D(bug("[USB2OTG] CMD_FLUSH(unit:0x%p, ioreq:0x%p)\n",
408 otg_Unit, ioreq));
410 return RC_OK;
413 WORD FNAME_DEV(cmdUsbReset)(struct IOUsbHWReq *ioreq,
414 struct USB2OTGUnit *otg_Unit,
415 LIBBASETYPEPTR USB2OTGBase)
417 D(bug("[USB2OTG] UHCMD_USBRESET(unit:0x%p, ioreq:0x%p)\n",
418 otg_Unit, ioreq));
420 if (ioreq->iouh_State & UHSF_OPERATIONAL)
422 return RC_OK;
424 return (WORD)UHIOERR_USBOFFLINE;
427 WORD FNAME_DEV(cmdUsbResume)(struct IOUsbHWReq *ioreq,
428 struct USB2OTGUnit *otg_Unit,
429 LIBBASETYPEPTR USB2OTGBase)
431 D(bug("[USB2OTG] UHCMD_USBRESUME(unit:0x%p, ioreq:0x%p)\n",
432 otg_Unit, ioreq));
434 if (ioreq->iouh_State & UHSF_OPERATIONAL)
436 return RC_OK;
438 return (WORD)UHIOERR_USBOFFLINE;
441 WORD FNAME_DEV(cmdUsbSuspend)(struct IOUsbHWReq *ioreq,
442 struct USB2OTGUnit *otg_Unit,
443 LIBBASETYPEPTR USB2OTGBase)
445 D(bug("[USB2OTG] UHCMD_USBSUSPEND(unit:0x%p, ioreq:0x%p)\n",
446 otg_Unit, ioreq));
448 if (ioreq->iouh_State & UHSF_SUSPENDED)
450 return RC_OK;
452 return UHIOERR_USBOFFLINE;
455 WORD FNAME_DEV(cmdUsbOper)(struct IOUsbHWReq *ioreq,
456 struct USB2OTGUnit *otg_Unit,
457 LIBBASETYPEPTR USB2OTGBase)
459 D(bug("[USB2OTG] UHCMD_USBOPER(unit:0x%p, ioreq:0x%p)\n",
460 otg_Unit, ioreq));
462 if (ioreq->iouh_State & UHSF_OPERATIONAL)
464 return RC_OK;
466 return UHIOERR_USBOFFLINE;
469 WORD FNAME_DEV(cmdControlXFer)(struct IOUsbHWReq *ioreq,
470 struct USB2OTGUnit *otg_Unit,
471 LIBBASETYPEPTR USB2OTGBase)
473 D(bug("[USB2OTG] UHCMD_CONTROLXFER(unit:0x%p, ioreq:0x%p)\n",
474 otg_Unit, ioreq));
476 #if (0)
477 if (!(ioreq->iouh_State & UHSF_OPERATIONAL))
479 return (UHIOERR_USBOFFLINE);
481 #endif
483 if (ioreq->iouh_DevAddr == otg_Unit->hu_HubAddr)
485 return (FNAME_ROOTHUB(cmdControlXFer)(ioreq, otg_Unit, USB2OTGBase));
488 D(bug("[USB2OTG] UHCMD_CONTROLXFER: DevAddr #%ld\n",
489 ioreq->iouh_DevAddr));
491 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
492 ioreq->iouh_Actual = 0;
494 Disable();
495 AddTail(&otg_Unit->hu_CtrlXFerQueue, (struct Node *) ioreq);
496 Enable();
497 FNAME_DEV(Cause)(USB2OTGBase, &otg_Unit->hu_PendingInt);
499 D(bug("[USB2OTG] UHCMD_CONTROLXFER: handled ioreq @ 0x%p\n", ioreq));
501 return (RC_DONTREPLY);
504 WORD FNAME_DEV(cmdBulkXFer)(struct IOUsbHWReq *ioreq,
505 struct USB2OTGUnit *otg_Unit,
506 LIBBASETYPEPTR USB2OTGBase)
508 D(bug("[USB2OTG] UHCMD_BULKXFER(unit:0x%p, ioreq:0x%p)\n",
509 otg_Unit, ioreq));
511 #if (0)
512 if(!(ioreq->iouh_State & UHSF_OPERATIONAL))
514 return(UHIOERR_USBOFFLINE);
516 #endif
518 if (ioreq->iouh_Flags & UHFF_LOWSPEED)
520 return(UHIOERR_BADPARAMS);
523 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
524 ioreq->iouh_Actual = 0;
526 Disable();
527 AddTail(&otg_Unit->hu_BulkXFerQueue, (struct Node *) ioreq);
528 Enable();
529 FNAME_DEV(Cause)(USB2OTGBase, &otg_Unit->hu_PendingInt);
531 D(bug("[USB2OTG] UHCMD_BULKXFER: handled ioreq @ 0x%p\n", ioreq));
533 return (RC_DONTREPLY);
536 WORD FNAME_DEV(cmdIntXFer)(struct IOUsbHWReq *ioreq,
537 struct USB2OTGUnit *otg_Unit,
538 LIBBASETYPEPTR USB2OTGBase)
540 D(bug("[USB2OTG] UHCMD_INTXFER(unit:0x%p, ioreq:0x%p)\n",
541 otg_Unit, ioreq));
543 #if (0)
544 if(!(ioreq->iouh_State & UHSF_OPERATIONAL))
546 return (UHIOERR_USBOFFLINE);
548 #endif
550 if (ioreq->iouh_DevAddr == otg_Unit->hu_HubAddr)
552 return (FNAME_ROOTHUB(cmdIntXFer)(ioreq, otg_Unit, USB2OTGBase));
555 D(bug("[USB2OTG] UHCMD_INTXFER: DevAddr #%ld\n",
556 ioreq->iouh_DevAddr));
558 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
559 ioreq->iouh_Actual = 0;
561 Disable();
562 AddTail(&otg_Unit->hu_IntXFerQueue, (struct Node *) ioreq);
563 Enable();
564 FNAME_DEV(Cause)(USB2OTGBase, &otg_Unit->hu_PendingInt);
566 D(bug("[USB2OTG] UHCMD_INTXFER: handled ioreq @ 0x%p\n", ioreq));
568 return (RC_DONTREPLY);
571 WORD FNAME_DEV(cmdIsoXFer)(struct IOUsbHWReq *ioreq,
572 struct USB2OTGUnit *otg_Unit,
573 LIBBASETYPEPTR USB2OTGBase)
575 D(bug("[USB2OTG] UHCMD_ISOXFER(unit:0x%p, ioreq:0x%p)\n",
576 otg_Unit, ioreq));
578 #if (0)
579 if(!(ioreq->iouh_State & UHSF_OPERATIONAL))
581 return(UHIOERR_USBOFFLINE);
583 #endif
584 if(ioreq->iouh_Flags & UHFF_LOWSPEED)
586 return(UHIOERR_BADPARAMS);
589 ioreq->iouh_Req.io_Flags &= ~IOF_QUICK;
590 ioreq->iouh_Actual = 0;
592 Disable();
593 AddTail(&otg_Unit->hu_IsoXFerQueue, (struct Node *) ioreq);
594 Enable();
595 FNAME_DEV(Cause)(USB2OTGBase, &otg_Unit->hu_PendingInt);
597 D(bug("[USB2OTG] UHCMD_ISOXFER: handled ioreq @ 0x%p\n", ioreq));
598 return(RC_DONTREPLY);