revert between 56095 -> 55830 in arch
[AROS.git] / arch / arm-native / soc / broadcom / 2708 / usb / usb2otg / usb2otg_device.c
blob60b3c35f3f50af15a1f488ad7599241c25d3e6a2
1 /*
2 Copyright © 2013-2019, 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 <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 *===========================================================
30 * Init(base)
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)
58 USB2OTGBase = NULL;
60 else
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))
86 case 2:
87 bug("Internal DMA\n");
88 break;
89 case 1:
90 bug("External DMA\n");
91 break;
92 default:
93 bug("Slave Only\n");
94 break;
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);
116 PwrOnMsg[7] = 0;
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");
125 USB2OTGBase = NULL;
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]);
135 USB2OTGBase = NULL;
138 FreeVec(pwron);
139 PwrOnMsg = NULL;
141 if (!USB2OTGBase)
143 return FALSE;
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)
151 int ns;
153 D(bug("[USB2OTG] %s: Allocated MemPool @ 0x%p\n",
154 __PRETTY_FUNCTION__, USB2OTGBase->hd_MemPool));
156 if (USB2OTGBase)
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)
171 int i;
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;
215 #if (0)
216 D(bug("[USB2OTG] %s: Unit Mode %d\n",
217 __PRETTY_FUNCTION__, USB2OTGBase->hd_Unit->hu_OperatingMode));
218 #endif
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);
242 #if (0)
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__);
248 #endif
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);
257 } else {
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);
279 #if (0)
280 D(bug("[USB2OTG] %s: Operating Mode: ", __PRETTY_FUNCTION__));
281 otg_RegVal = rd32le(USB2OTG_HARDWARE2);
282 switch (otg_RegVal & 7)
284 case 0:
285 D(bug("HNP/SRP\n"));
286 otg_RegVal = rd32le(USB2OTG_USB);
287 otg_RegVal |= (USB2OTG_USB_HNPCAPABLE|USB2OTG_USB_SRPCAPABLE);
288 wr32le(USB2OTG_USB, otg_RegVal);
289 break;
290 case 1:
291 case 3:
292 case 5:
293 D(bug("SRP\n"));
294 otg_RegVal = rd32le(USB2OTG_USB);
295 otg_RegVal &= ~USB2OTG_USB_HNPCAPABLE;
296 otg_RegVal |= USB2OTG_USB_SRPCAPABLE;
297 wr32le(USB2OTG_USB, otg_RegVal);
298 break;
299 case 2:
300 case 4:
301 case 6:
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);
306 break;
308 #else
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);
313 #endif
315 D(bug("[USB2OTG] %s: Enabling Global Interrupts ...\n", __PRETTY_FUNCTION__));
316 otg_RegVal = rd32le(USB2OTG_INTR);
317 otg_RegVal = ~0UL;
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");
332 else
334 D(bug("[USB2OTG] %s: Failed to Create MemPool\n",
335 __PRETTY_FUNCTION__));
337 CloseLibrary((struct Library *) UtilityBase);
338 USB2OTGBase = NULL;
341 else
343 D(bug("[USB2OTG] %s: OpenLibrary(\"utility.library\", 39) failed!\n",
344 __PRETTY_FUNCTION__));
346 USB2OTGBase = NULL;
349 else
351 D(bug("[USB2OTG] %s: OpenDevice(\"timer.device\") failed!\n",
352 __PRETTY_FUNCTION__));
354 USB2OTGBase = NULL;
357 else
359 D(bug("[USB2OTG] %s: Failed to allocate timer IORequest\n",
360 __PRETTY_FUNCTION__));
362 USB2OTGBase = NULL;
365 else
367 D(bug("[USB2OTG] %s: Failed to create MsgPort\n",
368 __PRETTY_FUNCTION__));
370 USB2OTGBase = NULL;
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;
400 else
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__));
411 else
413 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
414 ioreq->iouh_Req.io_Error = 0;
416 return TRUE;
420 return FALSE;
425 *===========================================================
426 * Close(ioreq, base)
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;
441 return TRUE;
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);
452 return TRUE;
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)
472 AROS_LIBFUNC_INIT
474 struct USB2OTGUnit *otg_Unit = (struct USB2OTGUnit *) ioreq->iouh_Req.io_Unit;
475 WORD ret;
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)
487 case CMD_RESET:
488 ret = FNAME_DEV(cmdReset)(ioreq, otg_Unit, USB2OTGBase);
489 break;
491 case CMD_FLUSH:
492 ret = FNAME_DEV(cmdFlush)(ioreq, otg_Unit, USB2OTGBase);
493 break;
495 case UHCMD_QUERYDEVICE:
496 ret = FNAME_DEV(cmdQueryDevice)(ioreq, otg_Unit, USB2OTGBase);
497 break;
499 case UHCMD_USBRESET:
500 ret = FNAME_DEV(cmdUsbReset)(ioreq, otg_Unit, USB2OTGBase);
501 break;
503 case UHCMD_USBRESUME:
504 ret = FNAME_DEV(cmdUsbResume)(ioreq, otg_Unit, USB2OTGBase);
505 break;
507 case UHCMD_USBSUSPEND:
508 ret = FNAME_DEV(cmdUsbSuspend)(ioreq, otg_Unit, USB2OTGBase);
509 break;
511 case UHCMD_USBOPER:
512 ret = FNAME_DEV(cmdUsbOper)(ioreq, otg_Unit, USB2OTGBase);
513 break;
515 case UHCMD_CONTROLXFER:
516 ret = FNAME_DEV(cmdControlXFer)(ioreq, otg_Unit, USB2OTGBase);
517 break;
519 case UHCMD_BULKXFER:
520 ret = FNAME_DEV(cmdBulkXFer)(ioreq, otg_Unit, USB2OTGBase);
521 break;
523 case UHCMD_INTXFER:
524 ret = FNAME_DEV(cmdIntXFer)(ioreq, otg_Unit, USB2OTGBase);
525 break;
527 case UHCMD_ISOXFER:
528 ret = FNAME_DEV(cmdIsoXFer)(ioreq, otg_Unit, USB2OTGBase);
529 break;
531 default:
532 ret = IOERR_NOCMD;
533 break;
536 else
538 switch(ioreq->iouh_Req.io_Command)
540 case NSCMD_DEVICEQUERY:
541 ret = FNAME_DEV(cmdNSDeviceQuery)((struct IOStdReq *) ioreq, otg_Unit, USB2OTGBase);
542 break;
544 default:
545 ret = IOERR_NOCMD;
546 break;
550 if (ret != RC_DONTREPLY)
552 D(bug("[USB2OTG] %s: Terminating I/O..\n",
553 __PRETTY_FUNCTION__));
555 if (ret != RC_OK)
557 ioreq->iouh_Req.io_Error = ret & 0xff;
559 FNAME_DEV(TermIO)(ioreq, USB2OTGBase);
562 AROS_LIBFUNC_EXIT
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)
578 AROS_LIBFUNC_INIT
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));
583 /* Is it pending? */
584 if (ioreq->iouh_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE)
586 #if (0)
587 if (FNAME_DEV(cmdAbortIO)(ioreq, USB2OTGBase))
589 return(0);
591 #endif
593 return(-1);
595 AROS_LIBFUNC_EXIT
598 void FNAME_DEV(Cause)(LIBBASETYPEPTR USB2OTGBase, struct Interrupt *interrupt)
600 Cause(interrupt);
601 #if 0
602 /* this is a workaround for the original Cause() function missing tailed calls */
603 Disable();
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;
609 } else {
612 interrupt->is_Node.ln_Type = NT_SOFTINT;
613 Forbid(); // make sure code is not interrupted by other tasks
614 Enable();
615 AROS_INTC1(interrupt->is_Code, interrupt->is_Data);
616 Disable();
617 Permit();
618 } while(interrupt->is_Node.ln_Type != NT_SOFTINT);
619 interrupt->is_Node.ln_Type = NT_INTERRUPT;
621 Enable();
622 #endif