2 Copyright © 2013-2019, 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 <proto/alib.h>
14 #include <proto/mbox.h>
15 #include <hardware/videocore.h>
17 #include "usb2otg_intern.h"
19 #define DEVNAME "usb2otg.device"
21 const char devname
[] = MOD_NAME_STRING
;
23 AROS_INTP(FNAME_DEV(PendingInt
));
24 AROS_INTP(FNAME_DEV(NakTimeoutInt
));
26 IPTR __arm_periiobase
__attribute__((used
)) = 0 ;
29 *===========================================================
31 *===========================================================
33 static int FNAME_DEV(Init
)(LIBBASETYPEPTR USB2OTGBase
)
35 void *MBoxBase
= NULL
;
36 volatile unsigned int otg_RegVal
;
37 unsigned int otg_OperatingMode
= 0;
38 ULONG
*PwrOnMsg
, *pwron
= NULL
;
40 KernelBase
= OpenResource("kernel.resource");
41 MBoxBase
= OpenResource("mbox.resource");
43 __arm_periiobase
= KrnGetSystemAttr(KATTR_PeripheralBase
);
45 D(bug("[USB2OTG] %s: USB2OTGBase @ 0x%p, SysBase @ 0x%p\n",
46 __PRETTY_FUNCTION__
, USB2OTGBase
, SysBase
));
48 otg_RegVal
= rd32le(USB2OTG_VENDORID
);
50 if ((otg_RegVal
& 0xFFFFF000) != 0x4F542000)
52 bug("[USB2OTG] Unsupported HS OTG USB Core Found\n");
53 bug("[USB2OTG] Hardware: %c%c%x.%x%x%x\n",
54 ((otg_RegVal
>> 24) & 0xFF), ((otg_RegVal
>> 16) & 0xFF),
55 ((otg_RegVal
>> 12) & 0xF), ((otg_RegVal
>> 8) & 0xF), ((otg_RegVal
>> 4) & 0xF), (otg_RegVal
& 0xF)
62 USB2OTGBase
->hd_KernelBase
= OpenResource("kernel.resource");
63 D(bug("[USB2OTG] %s: kernel.resource opened @ 0x%p\n",
64 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_KernelBase
));
66 if((USB2OTGBase
->hd_MsgPort
= CreateMsgPort()))
68 if((USB2OTGBase
->hd_TimerReq
= (struct timerequest
*) CreateIORequest(USB2OTGBase
->hd_MsgPort
, sizeof(struct timerequest
))))
70 if(!OpenDevice("timer.device", UNIT_MICROHZ
, (struct IORequest
*) USB2OTGBase
->hd_TimerReq
, 0))
72 USB2OTGBase
->hd_TimerReq
->tr_node
.io_Message
.mn_Node
.ln_Name
= "USB2OTG Timer";
73 USB2OTGBase
->hd_TimerReq
->tr_node
.io_Command
= TR_ADDREQUEST
;
74 D(bug("[USB2OTG] %s: timer.device opened\n",
75 __PRETTY_FUNCTION__
));
77 bug("[USB2OTG] HS OTG Core Release: %c%c%x.%x%x%x\n",
78 ((otg_RegVal
>> 24) & 0xFF), ((otg_RegVal
>> 16) & 0xFF),
79 ((otg_RegVal
>> 12) & 0xF), ((otg_RegVal
>> 8) & 0xF), ((otg_RegVal
>> 4) & 0xF), (otg_RegVal
& 0xF)
82 otg_RegVal
= rd32le(USB2OTG_HARDWARE2
);
83 bug("[USB2OTG] Architecture: %d - ", ((otg_RegVal
& (3 << 3)) >> 3));
84 switch (((otg_RegVal
& (3 << 3)) >> 3))
87 bug("Internal DMA\n");
90 bug("External DMA\n");
97 D(bug("[USB2OTG] %s: Disabling USB Interrupts (Globaly)..\n", __PRETTY_FUNCTION__
));
98 otg_RegVal
= rd32le(USB2OTG_AHB
);
99 otg_RegVal
&= ~USB2OTG_AHB_INTENABLE
;
100 wr32le(USB2OTG_INTRMASK
, 0);
101 wr32le(USB2OTG_AHB
, otg_RegVal
);
103 D(bug("[USB2OTG] Powering on USB controller\n"));
104 pwron
= AllocVec(9*sizeof(ULONG
), MEMF_CLEAR
);
105 PwrOnMsg
= (ULONG
*)(((IPTR
)pwron
+ 15) & ~15);
107 D(bug("[USB2OTG] pwron=%p, PwrOnMsg=%p\n", pwron
, PwrOnMsg
));
109 PwrOnMsg
[0] = AROS_LE2LONG(8 * sizeof(ULONG
));
110 PwrOnMsg
[1] = AROS_LE2LONG(VCTAG_REQ
);
111 PwrOnMsg
[2] = AROS_LE2LONG(VCTAG_SETPOWER
);
112 PwrOnMsg
[3] = AROS_LE2LONG(8);
113 PwrOnMsg
[4] = AROS_LE2LONG(0);
114 PwrOnMsg
[5] = AROS_LE2LONG(VCPOWER_USBHCD
);
115 PwrOnMsg
[6] = AROS_LE2LONG(VCPOWER_STATE_ON
| VCPOWER_STATE_WAIT
);
118 MBoxWrite((void*)VCMB_BASE
, VCMB_PROPCHAN
, PwrOnMsg
);
119 if (MBoxRead((void*)VCMB_BASE
, VCMB_PROPCHAN
) == PwrOnMsg
)
121 D(bug("[USB2OTG] Power on state: %08x\n", AROS_LE2LONG(PwrOnMsg
[6])));
122 if ((AROS_LE2LONG(PwrOnMsg
[6]) & 1) == 0)
124 bug("[USB2OTG] Failed to power on USB controller\n");
128 if ((AROS_LE2LONG(PwrOnMsg
[6]) & 2) != 0)
130 bug("[USB2OTG] USB HCD does not exist\n");
132 for (int i
=0; i
< 8; i
++)
133 bug("[USB2OTG] %08x\n", PwrOnMsg
[i
]);
146 if ((USB2OTGBase
->hd_UtilityBase
= (APTR
)OpenLibrary("utility.library", 39)) != NULL
)
148 USB2OTGBase
->hd_MemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
| MEMF_SEM_PROTECTED
, 16384, 4096);
149 if (USB2OTGBase
->hd_MemPool
)
153 D(bug("[USB2OTG] %s: Allocated MemPool @ 0x%p\n",
154 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_MemPool
));
159 otg_RegVal
= rd32le(USB2OTG_HARDWARE
);
160 bug("[USB2OTG] %s: HWConfig: %08x-", __PRETTY_FUNCTION__
, otg_RegVal
);
161 otg_RegVal
= rd32le(USB2OTG_HARDWARE2
);
162 bug("%08x-", otg_RegVal
);
163 otg_RegVal
= rd32le(USB2OTG_HARDWARE3
);
164 bug("%08x-", otg_RegVal
);
165 otg_RegVal
= rd32le(USB2OTG_HARDWARE4
);
166 bug("%08x\n", otg_RegVal
);
169 if ((USB2OTGBase
->hd_Unit
= AllocPooled(USB2OTGBase
->hd_MemPool
, sizeof(struct USB2OTGUnit
))) != NULL
)
173 D(bug("[USB2OTG] %s: Unit Allocated at 0x%p\n",
174 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
));
176 NewList(&USB2OTGBase
->hd_Unit
->hu_IOPendingQueue
);
178 NewList(&USB2OTGBase
->hd_Unit
->hu_CtrlXFerQueue
);
179 NewList(&USB2OTGBase
->hd_Unit
->hu_IntXFerQueue
);
180 NewList(&USB2OTGBase
->hd_Unit
->hu_IntXFerScheduled
);
181 NewList(&USB2OTGBase
->hd_Unit
->hu_IsoXFerQueue
);
182 NewList(&USB2OTGBase
->hd_Unit
->hu_BulkXFerQueue
);
183 NewList(&USB2OTGBase
->hd_Unit
->hu_TDQueue
);
184 NewList(&USB2OTGBase
->hd_Unit
->hu_AbortQueue
);
185 NewList(&USB2OTGBase
->hd_Unit
->hu_PeriodicTDQueue
);
186 NewList(&USB2OTGBase
->hd_Unit
->hu_FinishedXfers
);
188 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
189 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Name
= "OTG2USB Pending Work Interrupt";
190 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Pri
= 0;
191 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Data
= USB2OTGBase
->hd_Unit
;
192 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Code
= (VOID_FUNC
)FNAME_DEV(PendingInt
);
194 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
195 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Name
= "OTG2USB NakTimeout Interrupt";
196 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Pri
= -16;
197 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Data
= USB2OTGBase
->hd_Unit
;
198 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Code
= (VOID_FUNC
)FNAME_DEV(NakTimeoutInt
);
200 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
201 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_Flags
= PA_SOFTINT
;
202 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_SigTask
= &USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
;
203 NewList(&USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_MsgList
);
205 CopyMem(USB2OTGBase
->hd_TimerReq
, &USB2OTGBase
->hd_Unit
->hu_NakTimeoutReq
, sizeof(struct timerequest
));
206 USB2OTGBase
->hd_Unit
->hu_NakTimeoutReq
.tr_node
.io_Message
.mn_ReplyPort
= &USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
;
208 USB2OTGBase
->hd_Unit
->hu_HubPortChanged
= FALSE
;
210 USB2OTGBase
->hd_Unit
->hu_OperatingMode
= (otg_OperatingMode
== (USB2OTG_USBHOSTMODE
|USB2OTG_USBDEVICEMODE
)) ? 0 : otg_OperatingMode
;
212 for (i
=0; i
< 128; i
++)
213 USB2OTGBase
->hd_Unit
->hu_PIDBits
[i
] = 0;
216 D(bug("[USB2OTG] %s: Unit Mode %d\n",
217 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
->hu_OperatingMode
));
219 USB2OTGBase
->hd_Unit
->hu_GlobalIRQHandle
= KrnAddIRQHandler(IRQ_VC_USB
, FNAME_DEV(GlobalIRQHandler
), USB2OTGBase
->hd_Unit
, SysBase
);
221 USB2OTGBase
->hd_Unit
->hu_USB2OTGBase
= USB2OTGBase
;
223 D(bug("[USB2OTG] %s: Installed Global IRQ Handler [handle @ 0x%p] for IRQ #%ld\n",
224 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
->hu_GlobalIRQHandle
, IRQ_HOSTPORT
));
226 otg_RegVal
= rd32le(USB2OTG_USB
);
227 otg_RegVal
&= ~(USB2OTG_USB_ULPIDRIVEEXTERNALVBUS
|USB2OTG_USB_TSDLINEPULSEENABLE
);
228 wr32le(USB2OTG_USB
, otg_RegVal
);
230 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__
));
231 wr32le(USB2OTG_RESET
, USB2OTG_RESET_CORESOFT
);
232 for (ns
= 0; ns
< 10000; ns
++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
233 if ((rd32le(USB2OTG_RESET
) & USB2OTG_RESET_CORESOFT
) != 0)
234 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__
);
236 D(bug("[USB2OTG] %s: Initialising PHY ..\n", __PRETTY_FUNCTION__
));
237 otg_RegVal
= rd32le(USB2OTG_USB
);
238 otg_RegVal
&= ~USB2OTG_USB_PHYINTERFACE
;
239 otg_RegVal
&= ~USB2OTG_USB_MODESELECT_UTMI
;
240 wr32le(USB2OTG_USB
, otg_RegVal
);
243 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__
));
244 wr32le(USB2OTG_RESET
, USB2OTG_RESET_CORESOFT
);
245 for (ns
= 0; ns
< 10000; ns
++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
246 if ((rd32le(USB2OTG_RESET
) & USB2OTG_RESET_CORESOFT
) != 0)
247 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__
);
250 otg_RegVal
= rd32le(USB2OTG_HARDWARE2
);
251 if (((otg_RegVal
& (3 << 6) >> 6) == 2) && ((otg_RegVal
& (3 << 8) >> 8) == 1))
253 D(bug("[USB2OTG] %s: ULPI FSLS configuration: enabled.\n", __PRETTY_FUNCTION__
));
254 otg_RegVal
= rd32le(USB2OTG_USB
);
255 otg_RegVal
|= (USB2OTG_USB_ULPIFSLS
|USB2OTG_USB_ULPI_CLK_SUS_M
);
256 wr32le(USB2OTG_USB
, otg_RegVal
);
258 D(bug("[USB2OTG] %s: ULPI FSLS configuration: disabled.\n", __PRETTY_FUNCTION__
));
259 otg_RegVal
= rd32le(USB2OTG_USB
);
260 otg_RegVal
&= ~(USB2OTG_USB_ULPIFSLS
|USB2OTG_USB_ULPI_CLK_SUS_M
);
261 wr32le(USB2OTG_USB
, otg_RegVal
);
264 D(bug("[USB2OTG] %s: Enabling DMA configuration..\n", __PRETTY_FUNCTION__
));
265 otg_RegVal
= rd32le(USB2OTG_AHB
);
266 otg_RegVal
&= ~(1 << USB2OTG_AHB_DMAREMAINDERMODE
);
267 otg_RegVal
&= ~(0x1f);
268 otg_RegVal
|= (1 << 4) | (USB2OTG_AHB_DMAENABLE
|USB2OTG_AHB_DMAREMAINDERMODE_INCR
);
269 D(bug("[USB2OTG] %s: AHB reg: %08x..\n", __PRETTY_FUNCTION__
, otg_RegVal
));
270 wr32le(USB2OTG_AHB
, otg_RegVal
);
272 otg_RegVal
= rd32le(USB2OTG_HARDWARE3
);
273 USB2OTGBase
->hd_Unit
->hu_XferSizeWidth
= 11 + (otg_RegVal
& 0x0f);
274 USB2OTGBase
->hd_Unit
->hu_PktSizeWidth
= 4 + ((otg_RegVal
>> 4) & 0x07);
276 bug("[USB2OTG] %s: XferSizeWidth = %d, PktSizeWidth = %d\n", __PRETTY_FUNCTION__
,
277 USB2OTGBase
->hd_Unit
->hu_XferSizeWidth
, USB2OTGBase
->hd_Unit
->hu_PktSizeWidth
);
280 D(bug("[USB2OTG] %s: Operating Mode: ", __PRETTY_FUNCTION__
));
281 otg_RegVal
= rd32le(USB2OTG_HARDWARE2
);
282 switch (otg_RegVal
& 7)
286 otg_RegVal
= rd32le(USB2OTG_USB
);
287 otg_RegVal
|= (USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
288 wr32le(USB2OTG_USB
, otg_RegVal
);
294 otg_RegVal
= rd32le(USB2OTG_USB
);
295 otg_RegVal
&= ~USB2OTG_USB_HNPCAPABLE
;
296 otg_RegVal
|= USB2OTG_USB_SRPCAPABLE
;
297 wr32le(USB2OTG_USB
, otg_RegVal
);
302 D(bug("No HNP or SRP\n"));
303 otg_RegVal
= rd32le(USB2OTG_USB
);
304 otg_RegVal
&= ~(USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
305 wr32le(USB2OTG_USB
, otg_RegVal
);
309 D(bug("[USB2OTG] %s: Disable HNP/SRP\n", __PRETTY_FUNCTION__
));
310 otg_RegVal
= rd32le(USB2OTG_USB
);
311 otg_RegVal
&= ~(USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
312 wr32le(USB2OTG_USB
, otg_RegVal
);
315 D(bug("[USB2OTG] %s: Enabling Global Interrupts ...\n", __PRETTY_FUNCTION__
));
316 otg_RegVal
= rd32le(USB2OTG_INTR
);
318 wr32le(USB2OTG_INTR
, otg_RegVal
);
320 otg_RegVal
= rd32le(USB2OTG_INTRMASK
);
321 otg_RegVal
|= USB2OTG_INTRCORE_DMASTARTOFFRAME
;
322 wr32le(USB2OTG_INTRMASK
, otg_RegVal
);
324 otg_RegVal
= rd32le(USB2OTG_AHB
);
325 otg_RegVal
|= USB2OTG_AHB_INTENABLE
;
326 wr32le(USB2OTG_AHB
, otg_RegVal
);
328 bug("[USB2OTG] HS OTG USB Driver Initialised\n");
334 D(bug("[USB2OTG] %s: Failed to Create MemPool\n",
335 __PRETTY_FUNCTION__
));
337 CloseLibrary((struct Library
*) UtilityBase
);
343 D(bug("[USB2OTG] %s: OpenLibrary(\"utility.library\", 39) failed!\n",
344 __PRETTY_FUNCTION__
));
351 D(bug("[USB2OTG] %s: OpenDevice(\"timer.device\") failed!\n",
352 __PRETTY_FUNCTION__
));
359 D(bug("[USB2OTG] %s: Failed to allocate timer IORequest\n",
360 __PRETTY_FUNCTION__
));
367 D(bug("[USB2OTG] %s: Failed to create MsgPort\n",
368 __PRETTY_FUNCTION__
));
374 return USB2OTGBase
? TRUE
: FALSE
;
378 *===========================================================
379 * Open(ioreq, unit, flags, base)
380 *===========================================================
382 * This is the the DEV_OPEN function.
385 static int FNAME_DEV(Open
)(LIBBASETYPEPTR USB2OTGBase
, struct IOUsbHWReq
*ioreq
, ULONG otg_Unit
, ULONG flags
)
387 D(bug("[USB2OTG] %s: IOReq @ 0x%p, unit #%ld, flags = 0x%08lx, USB2OTGBase @ 0x%p\n",
388 __PRETTY_FUNCTION__
, ioreq
, otg_Unit
, flags
, USB2OTGBase
));
390 D(bug("[USB2OTG] %s: openCnt = %ld\n",
391 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Library
.lib_OpenCnt
));
393 if (ioreq
->iouh_Req
.io_Message
.mn_Length
< sizeof(struct IOUsbHWReq
))
395 D(bug("[USB2OTG] %s: invalid MN_LENGTH!\n",
396 __PRETTY_FUNCTION__
));
398 ioreq
->iouh_Req
.io_Error
= IOERR_BADLENGTH
;
402 ioreq
->iouh_Req
.io_Error
= IOERR_OPENFAIL
;
404 ioreq
->iouh_Req
.io_Unit
= FNAME_DEV(OpenUnit
)(ioreq
, otg_Unit
, USB2OTGBase
);
405 if (!(ioreq
->iouh_Req
.io_Unit
))
407 D(bug("[USB2OTG] %s: could not open unit!\n",
408 __PRETTY_FUNCTION__
));
413 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
414 ioreq
->iouh_Req
.io_Error
= 0;
425 *===========================================================
427 *===========================================================
429 * This is the the DEV_EXPUNGE function.
432 static int FNAME_DEV(Close
)(LIBBASETYPEPTR USB2OTGBase
, struct IOUsbHWReq
*ioreq
)
434 D(bug("[USB2OTG] %s: IOReq @ 0x%p, USB2OTGBase @ 0x%p\n",
435 __PRETTY_FUNCTION__
, ioreq
, USB2OTGBase
));
437 FNAME_DEV(CloseUnit
)(ioreq
, (struct USB2OTGUnit
*) ioreq
->iouh_Req
.io_Unit
, USB2OTGBase
);
439 ioreq
->iouh_Req
.io_Unit
= (APTR
) -1;
440 ioreq
->iouh_Req
.io_Device
= (APTR
) -1;
444 static int FNAME_DEV(Expunge
)(LIBBASETYPEPTR USB2OTGBase
)
446 DeletePool(USB2OTGBase
->hd_MemPool
);
448 D(bug("[USB2OTG] %s: closing utility.library @ 0x%p\n",
449 __PRETTY_FUNCTION__
, UtilityBase
));
451 CloseLibrary((struct Library
*) UtilityBase
);
455 ADD2INITLIB(FNAME_DEV(Init
), 0)
456 ADD2OPENDEV(FNAME_DEV(Open
), 0)
457 ADD2CLOSEDEV(FNAME_DEV(Close
), 0)
458 ADD2EXPUNGELIB(FNAME_DEV(Expunge
), 0)
461 *===========================================================
462 * BeginIO(ioreq, base)
463 *===========================================================
465 * This is the DEV_BEGINIO vector of the device.
468 AROS_LH1(void, FNAME_DEV(BeginIO
),
469 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
470 LIBBASETYPEPTR
, USB2OTGBase
, 5, usb2otg
)
474 struct USB2OTGUnit
*otg_Unit
= (struct USB2OTGUnit
*) ioreq
->iouh_Req
.io_Unit
;
477 D(bug("[USB2OTG] %s: IOReq @ 0x%08lx, USB2OTGBase @ 0x%08lx [cmd:%lu]\n",
478 __PRETTY_FUNCTION__
, ioreq
, USB2OTGBase
, ioreq
->iouh_Req
.io_Command
));
480 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
481 ioreq
->iouh_Req
.io_Error
= UHIOERR_NO_ERROR
;
483 if (ioreq
->iouh_Req
.io_Command
< NSCMD_DEVICEQUERY
)
485 switch (ioreq
->iouh_Req
.io_Command
)
488 ret
= FNAME_DEV(cmdReset
)(ioreq
, otg_Unit
, USB2OTGBase
);
492 ret
= FNAME_DEV(cmdFlush
)(ioreq
, otg_Unit
, USB2OTGBase
);
495 case UHCMD_QUERYDEVICE
:
496 ret
= FNAME_DEV(cmdQueryDevice
)(ioreq
, otg_Unit
, USB2OTGBase
);
500 ret
= FNAME_DEV(cmdUsbReset
)(ioreq
, otg_Unit
, USB2OTGBase
);
503 case UHCMD_USBRESUME
:
504 ret
= FNAME_DEV(cmdUsbResume
)(ioreq
, otg_Unit
, USB2OTGBase
);
507 case UHCMD_USBSUSPEND
:
508 ret
= FNAME_DEV(cmdUsbSuspend
)(ioreq
, otg_Unit
, USB2OTGBase
);
512 ret
= FNAME_DEV(cmdUsbOper
)(ioreq
, otg_Unit
, USB2OTGBase
);
515 case UHCMD_CONTROLXFER
:
516 ret
= FNAME_DEV(cmdControlXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
520 ret
= FNAME_DEV(cmdBulkXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
524 ret
= FNAME_DEV(cmdIntXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
528 ret
= FNAME_DEV(cmdIsoXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
538 switch(ioreq
->iouh_Req
.io_Command
)
540 case NSCMD_DEVICEQUERY
:
541 ret
= FNAME_DEV(cmdNSDeviceQuery
)((struct IOStdReq
*) ioreq
, otg_Unit
, USB2OTGBase
);
550 if (ret
!= RC_DONTREPLY
)
552 D(bug("[USB2OTG] %s: Terminating I/O..\n",
553 __PRETTY_FUNCTION__
));
557 ioreq
->iouh_Req
.io_Error
= ret
& 0xff;
559 FNAME_DEV(TermIO
)(ioreq
, USB2OTGBase
);
566 *===========================================================
567 * AbortIO(ioreq, base)
568 *===========================================================
570 * This is the DEV_ABORTIO vector of the device. It abort
571 * the given iorequest, and set
574 AROS_LH1(LONG
, FNAME_DEV(AbortIO
),
575 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
576 LIBBASETYPEPTR
, USB2OTGBase
, 6, usb2otg
)
580 D(bug("[USB2OTG] %s: IOReq @ 0x%p, command %ld, status %ld\n",
581 __PRETTY_FUNCTION__
, ioreq
, ioreq
->iouh_Req
.io_Command
, ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
));
584 if (ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
== NT_MESSAGE
)
587 if (FNAME_DEV(cmdAbortIO
)(ioreq
, USB2OTGBase
))
598 void FNAME_DEV(Cause
)(LIBBASETYPEPTR USB2OTGBase
, struct Interrupt
*interrupt
)
602 /* this is a workaround for the original Cause() function missing tailed calls */
605 if((interrupt
->is_Node
.ln_Type
== NT_SOFTINT
) || (interrupt
->is_Node
.ln_Type
== NT_USER
))
607 // signal tailed call
608 interrupt
->is_Node
.ln_Type
= NT_USER
;
612 interrupt
->is_Node
.ln_Type
= NT_SOFTINT
;
613 Forbid(); // make sure code is not interrupted by other tasks
615 AROS_INTC1(interrupt
->is_Code
, interrupt
->is_Data
);
618 } while(interrupt
->is_Node
.ln_Type
!= NT_SOFTINT
);
619 interrupt
->is_Node
.ln_Type
= NT_INTERRUPT
;