2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
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
[] =
32 struct Unit
* FNAME_DEV(OpenUnit
)(struct IOUsbHWReq
*ioreq
,
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;
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);
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
);
75 *((volatile unsigned int *)USB2OTG_HOSTCFG
) = otg_RegVal
;
79 D(bug("[USB2OTG] %s: Host clock: 30-60Mhz\n", __PRETTY_FUNCTION__
));
80 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HOSTCFG
);
82 *((volatile unsigned int *)USB2OTG_HOSTCFG
) = otg_RegVal
;
85 D(bug("[USB2OTG] %s: Host clock: 30-60Mhz\n", __PRETTY_FUNCTION__
));
86 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HOSTCFG
);
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)));
119 D(bug("[USB2OTG] %s: Device Tokens: 0x%0x\n",
120 __PRETTY_FUNCTION__
, ((otg_RegVal
& (0x1F << 26)) >> 26)));
122 D(bug("[USB2OTG] %s: FIFO: %ld bytes\n",
123 __PRETTY_FUNCTION__
, ((otg_RegVal
& (0xFFFF << 16)) >> 16) << 2));
125 D(bug("[USB2OTG] %s: Xfer Size: %ld\n",
126 __PRETTY_FUNCTION__
, (otg_RegVal
& 0xF)));
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
++) {
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
);
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",
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
);
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;
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
))));
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
;
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
;
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;
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
;
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
);
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",
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
);
310 ioreq
->io_Actual
= query
->SizeAvailable
311 = sizeof(struct USBNSDeviceQueryResult
);
312 query
->DeviceType
= NSDEVTYPE_USBHARDWARE
;
313 query
->DeviceSubType
= 0;
314 query
->SupportedCommands
= __suported_cmds
;
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
;
327 D(bug("[USB2OTG] UHCMD_QUERYDEVICE(unit:0x%p, ioreq:0x%p)\n",
330 if (((tag
= FindTagItem(UHA_State
, taglist
)) != NULL
) && (tag
->ti_Data
))
332 *((IPTR
*) tag
->ti_Data
) = (IPTR
)UHSF_OPERATIONAL
;
336 if (((tag
= FindTagItem(UHA_Manufacturer
, taglist
)) != NULL
) && (tag
->ti_Data
))
338 *((STRPTR
*) tag
->ti_Data
) = "The AROS Dev Team";
342 if (((tag
= FindTagItem(UHA_ProductName
, taglist
)) != NULL
) && (tag
->ti_Data
))
344 *((STRPTR
*) tag
->ti_Data
) = "HS USB 2.0 OTG Controller";
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";
354 if (((tag
= FindTagItem(UHA_Copyright
, taglist
)) != NULL
) && (tag
->ti_Data
))
356 *((STRPTR
*) tag
->ti_Data
) ="©2013 The AROS Dev Team";
360 if (((tag
= FindTagItem(UHA_Version
, taglist
)) != NULL
) && (tag
->ti_Data
))
362 *((IPTR
*) tag
->ti_Data
) = VERSION_NUMBER
;
366 if (((tag
= FindTagItem(UHA_Revision
, taglist
)) != NULL
) && (tag
->ti_Data
))
368 *((IPTR
*) tag
->ti_Data
) = REVISION_NUMBER
;
372 if (((tag
= FindTagItem(UHA_DriverVersion
, taglist
)) != NULL
) && (tag
->ti_Data
))
374 *((IPTR
*) tag
->ti_Data
) = 0x100;
378 if (((tag
= FindTagItem(UHA_Capabilities
, taglist
)) != NULL
) && (tag
->ti_Data
))
380 *((IPTR
*) tag
->ti_Data
) = UHCF_USB20
;
383 ioreq
->iouh_Actual
= count
;
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",
395 if (ioreq
->iouh_State
& UHSF_OPERATIONAL
)
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",
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",
420 if (ioreq
->iouh_State
& UHSF_OPERATIONAL
)
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",
434 if (ioreq
->iouh_State
& UHSF_OPERATIONAL
)
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",
448 if (ioreq
->iouh_State
& UHSF_SUSPENDED
)
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",
462 if (ioreq
->iouh_State
& UHSF_OPERATIONAL
)
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",
477 if (!(ioreq
->iouh_State
& UHSF_OPERATIONAL
))
479 return (UHIOERR_USBOFFLINE
);
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;
495 AddTail(&otg_Unit
->hu_CtrlXFerQueue
, (struct Node
*) ioreq
);
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",
512 if(!(ioreq
->iouh_State
& UHSF_OPERATIONAL
))
514 return(UHIOERR_USBOFFLINE
);
518 if (ioreq
->iouh_Flags
& UHFF_LOWSPEED
)
520 return(UHIOERR_BADPARAMS
);
523 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
524 ioreq
->iouh_Actual
= 0;
527 AddTail(&otg_Unit
->hu_BulkXFerQueue
, (struct Node
*) ioreq
);
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",
544 if(!(ioreq
->iouh_State
& UHSF_OPERATIONAL
))
546 return (UHIOERR_USBOFFLINE
);
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;
562 AddTail(&otg_Unit
->hu_IntXFerQueue
, (struct Node
*) ioreq
);
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",
579 if(!(ioreq
->iouh_State
& UHSF_OPERATIONAL
))
581 return(UHIOERR_USBOFFLINE
);
584 if(ioreq
->iouh_Flags
& UHFF_LOWSPEED
)
586 return(UHIOERR_BADPARAMS
);
589 ioreq
->iouh_Req
.io_Flags
&= ~IOF_QUICK
;
590 ioreq
->iouh_Actual
= 0;
593 AddTail(&otg_Unit
->hu_IsoXFerQueue
, (struct Node
*) ioreq
);
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
);