make sure the arm implementation struct is aligned
[AROS.git] / arch / arm-native / soc / broadcom / 283x / usb / usb2otg / usb2otg_device.c
blob6dad3010565759d9ef719f4ae2875fe6e34e4613
1 /*
2 Copyright © 2013-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
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>
15 #include "usb2otg_intern.h"
17 #define DEVNAME "usb2otg.device"
19 const char devname[] = MOD_NAME_STRING;
21 AROS_INTP(FNAME_DEV(PendingInt));
22 AROS_INTP(FNAME_DEV(NakTimeoutInt));
24 IPTR __arm_periiobase __attribute__((used)) = 0 ;
26 static void GlobalIRQHandler(struct USB2OTGUnit *USBUnit, struct ExecBase *SysBase)
28 D(bug("[USB2OTG] %s: Received USB interrupt for Unit @ 0x%p\n",
29 __PRETTY_FUNCTION__, USBUnit));
33 *===========================================================
34 * Init(base)
35 *===========================================================
37 static int FNAME_DEV(Init)(LIBBASETYPEPTR USB2OTGBase)
39 volatile unsigned int *pmmailbox;
40 volatile unsigned int otg_RegVal;
41 unsigned int otg_OperatingMode = 0, pmres;
43 __arm_periiobase = KrnGetSystemAttr(KATTR_PeripheralBase);
45 pmmailbox = (volatile unsigned int *)(ARM_PERIIOBASE + 0xB880);
47 D(bug("[USB2OTG] %s: USB2OTGBase @ 0x%p, SysBase @ 0x%p\n",
48 __PRETTY_FUNCTION__, USB2OTGBase, SysBase));
50 otg_RegVal = *((volatile unsigned int *)USB2OTG_VENDORID);
52 if ((otg_RegVal & 0xFFFFF000) != 0x4F542000)
54 bug("[USB2OTG] Unsupported HS OTG USB Core Found\n");
55 bug("[USB2OTG] Hardware: %c%c%x.%x%x%x\n",
56 ((otg_RegVal >> 24) & 0xFF), ((otg_RegVal >> 16) & 0xFF),
57 ((otg_RegVal >> 12) & 0xF), ((otg_RegVal >> 8) & 0xF), ((otg_RegVal >> 4) & 0xF), (otg_RegVal & 0xF)
60 USB2OTGBase = NULL;
62 else
64 USB2OTGBase->hd_KernelBase = OpenResource("kernel.resource");
65 D(bug("[USB2OTG] %s: kernel.resource opened @ 0x%p\n",
66 __PRETTY_FUNCTION__, USB2OTGBase->hd_KernelBase));
68 if((USB2OTGBase->hd_MsgPort = CreateMsgPort()))
70 if((USB2OTGBase->hd_TimerReq = (struct timerequest *) CreateIORequest(USB2OTGBase->hd_MsgPort, sizeof(struct timerequest))))
72 if(!OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *) USB2OTGBase->hd_TimerReq, 0))
74 USB2OTGBase->hd_TimerReq->tr_node.io_Message.mn_Node.ln_Name = "USB2OTG Timer";
75 USB2OTGBase->hd_TimerReq->tr_node.io_Command = TR_ADDREQUEST;
76 D(bug("[USB2OTG] %s: timer.device opened\n",
77 __PRETTY_FUNCTION__));
79 bug("[USB2OTG] HS OTG Core Release: %c%c%x.%x%x%x\n",
80 ((otg_RegVal >> 24) & 0xFF), ((otg_RegVal >> 16) & 0xFF),
81 ((otg_RegVal >> 12) & 0xF), ((otg_RegVal >> 8) & 0xF), ((otg_RegVal >> 4) & 0xF), (otg_RegVal & 0xF)
84 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
85 bug("[USB2OTG] Architecture: %d - ", ((otg_RegVal & (3 << 3)) >> 3));
86 switch (((otg_RegVal & (3 << 3)) >> 3))
88 case 2:
89 bug("Internal DMA\n");
90 break;
91 case 1:
92 bug("External DMA\n");
93 break;
94 default:
95 bug("Slave Only\n");
96 break;
99 D(bug("[USB2OTG] %s: Disabling USB Interrupts (Globaly)..\n", __PRETTY_FUNCTION__));
100 otg_RegVal = *((volatile unsigned int *)USB2OTG_AHB);
101 otg_RegVal &= ~USB2OTG_AHB_INTENABLE;
102 *((volatile unsigned int *)USB2OTG_INTRMASK) = 0;
103 *((volatile unsigned int *)USB2OTG_AHB) = otg_RegVal;
105 while (pmmailbox[6] & 0x80000000);
106 pmmailbox[8] = 0x80;
107 do {
108 while (pmmailbox[6] & 0x40000000);
109 } while (((pmres = pmmailbox[0]) & 0xf) != 0);
110 if (pmres != 0x80)
112 bug("[USB2OTG] Failed to power on controller\n");
113 //USB2OTGBase->hd_TimerReq
114 //USB2OTGBase->hd_MsgPort
115 USB2OTGBase = NULL;
116 return FALSE;
119 if ((USB2OTGBase->hd_UtilityBase = (APTR)OpenLibrary("utility.library", 39)) != NULL)
121 USB2OTGBase->hd_MemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR | MEMF_SEM_PROTECTED, 16384, 4096);
122 if (USB2OTGBase->hd_MemPool)
124 int ns;
126 D(bug("[USB2OTG] %s: Allocated MemPool @ 0x%p\n",
127 __PRETTY_FUNCTION__, USB2OTGBase->hd_MemPool));
129 if (USB2OTGBase)
132 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE);
133 bug("[USB2OTG] %s: HWConfig: %08x-", __PRETTY_FUNCTION__, otg_RegVal);
134 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
135 bug("%08x-", otg_RegVal);
136 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE3);
137 bug("%08x-", otg_RegVal);
138 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE4);
139 bug("%08x\n", otg_RegVal);
142 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
143 otg_RegVal &= ~(USB2OTG_USB_ULPIDRIVEEXTERNALVBUS|USB2OTG_USB_TSDLINEPULSEENABLE);
144 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
146 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__));
147 *((volatile unsigned int *)USB2OTG_RESET) = USB2OTG_RESET_CORESOFT;
148 for (ns = 0; ns < 10000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
149 if ((*((volatile unsigned int *)USB2OTG_RESET) & USB2OTG_RESET_CORESOFT) != 0)
150 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__);
152 if ((USB2OTGBase->hd_Unit = AllocPooled(USB2OTGBase->hd_MemPool, sizeof(struct USB2OTGUnit))) != NULL)
154 D(bug("[USB2OTG] %s: Unit Allocated at 0x%p\n",
155 __PRETTY_FUNCTION__, USB2OTGBase->hd_Unit));
157 NewList(&USB2OTGBase->hd_Unit->hu_IOPendingQueue);
159 NewList(&USB2OTGBase->hd_Unit->hu_CtrlXFerQueue);
160 NewList(&USB2OTGBase->hd_Unit->hu_IntXFerQueue);
161 NewList(&USB2OTGBase->hd_Unit->hu_IsoXFerQueue);
162 NewList(&USB2OTGBase->hd_Unit->hu_BulkXFerQueue);
163 NewList(&USB2OTGBase->hd_Unit->hu_TDQueue);
164 NewList(&USB2OTGBase->hd_Unit->hu_AbortQueue);
165 NewList(&USB2OTGBase->hd_Unit->hu_PeriodicTDQueue);
167 USB2OTGBase->hd_Unit->hu_PendingInt.is_Node.ln_Type = NT_INTERRUPT;
168 USB2OTGBase->hd_Unit->hu_PendingInt.is_Node.ln_Name = "OTG2USB Pending Work Interrupt";
169 USB2OTGBase->hd_Unit->hu_PendingInt.is_Node.ln_Pri = 0;
170 USB2OTGBase->hd_Unit->hu_PendingInt.is_Data = USB2OTGBase->hd_Unit;
171 USB2OTGBase->hd_Unit->hu_PendingInt.is_Code = (VOID_FUNC)FNAME_DEV(PendingInt);
173 USB2OTGBase->hd_Unit->hu_NakTimeoutInt.is_Node.ln_Type = NT_INTERRUPT;
174 USB2OTGBase->hd_Unit->hu_NakTimeoutInt.is_Node.ln_Name = "OTG2USB NakTimeout Interrupt";
175 USB2OTGBase->hd_Unit->hu_NakTimeoutInt.is_Node.ln_Pri = -16;
176 USB2OTGBase->hd_Unit->hu_NakTimeoutInt.is_Data = USB2OTGBase->hd_Unit;
177 USB2OTGBase->hd_Unit->hu_NakTimeoutInt.is_Code = (VOID_FUNC)FNAME_DEV(NakTimeoutInt);
179 USB2OTGBase->hd_Unit->hu_NakTimeoutMsgPort.mp_Node.ln_Type = NT_MSGPORT;
180 USB2OTGBase->hd_Unit->hu_NakTimeoutMsgPort.mp_Flags = PA_SOFTINT;
181 USB2OTGBase->hd_Unit->hu_NakTimeoutMsgPort.mp_SigTask = &USB2OTGBase->hd_Unit->hu_NakTimeoutInt;
182 NewList(&USB2OTGBase->hd_Unit->hu_NakTimeoutMsgPort.mp_MsgList);
184 CopyMem(USB2OTGBase->hd_TimerReq, &USB2OTGBase->hd_Unit->hu_NakTimeoutReq, sizeof(struct timerequest));
185 USB2OTGBase->hd_Unit->hu_NakTimeoutReq.tr_node.io_Message.mn_ReplyPort = &USB2OTGBase->hd_Unit->hu_NakTimeoutMsgPort;
187 USB2OTGBase->hd_Unit->hu_HubPortChanged = FALSE;
189 USB2OTGBase->hd_Unit->hu_OperatingMode = (otg_OperatingMode == (USB2OTG_USBHOSTMODE|USB2OTG_USBDEVICEMODE)) ? 0 : otg_OperatingMode;
191 #if (0)
192 D(bug("[USB2OTG] %s: Unit Mode %d\n",
193 __PRETTY_FUNCTION__, USB2OTGBase->hd_Unit->hu_OperatingMode));
194 #endif
195 USB2OTGBase->hd_Unit->hu_GlobalIRQHandle = KrnAddIRQHandler(IRQ_HOSTPORT, GlobalIRQHandler, USB2OTGBase->hd_Unit, SysBase);
197 D(bug("[USB2OTG] %s: Installed Global IRQ Handler [handle @ 0x%p] for IRQ #%ld\n",
198 __PRETTY_FUNCTION__, USB2OTGBase->hd_Unit->hu_GlobalIRQHandle, IRQ_HOSTPORT));
200 D(bug("[USB2OTG] %s: Initialising PHY ..\n", __PRETTY_FUNCTION__));
201 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
202 otg_RegVal &= ~USB2OTG_USB_PHYINTERFACE;
203 otg_RegVal |= USB2OTG_USB_MODESELECT_UTMI;
204 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
206 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__));
207 *((volatile unsigned int *)USB2OTG_RESET) = USB2OTG_RESET_CORESOFT;
208 for (ns = 0; ns < 10000; ns++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
209 if ((*((volatile unsigned int *)USB2OTG_RESET) & USB2OTG_RESET_CORESOFT) != 0)
210 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__);
212 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
213 if (((otg_RegVal & (3 << 6) >> 6) == 2) && ((otg_RegVal & (3 << 8) >> 8) == 1))
215 D(bug("[USB2OTG] %s: ULPI FSLS configuration: enabled.\n", __PRETTY_FUNCTION__));
216 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
217 otg_RegVal |= (USB2OTG_USB_ULPIFSLS|USB2OTG_USB_ULPI_CLK_SUS_M);
218 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
219 } else {
220 D(bug("[USB2OTG] %s: ULPI FSLS configuration: disabled.\n", __PRETTY_FUNCTION__));
221 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
222 otg_RegVal &= ~(USB2OTG_USB_ULPIFSLS|USB2OTG_USB_ULPI_CLK_SUS_M);
223 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
226 D(bug("[USB2OTG] %s: Enabling DMA configuration..\n", __PRETTY_FUNCTION__));
227 otg_RegVal = *((volatile unsigned int *)USB2OTG_AHB);
228 otg_RegVal &= ~(1 << USB2OTG_AHB_DMAREMAINDERMODE);
229 otg_RegVal |= (USB2OTG_AHB_DMAENABLE|USB2OTG_AHB_DMAREMAINDERMODE_INCR);
230 *((volatile unsigned int *)USB2OTG_AHB) = otg_RegVal;
232 D(bug("[USB2OTG] %s: Operating Mode: ", __PRETTY_FUNCTION__));
233 otg_RegVal = *((volatile unsigned int *)USB2OTG_HARDWARE2);
234 switch (otg_RegVal & 7)
236 case 0:
237 D(bug("HNP/SRP\n"));
238 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
239 otg_RegVal |= (USB2OTG_USB_HNPCAPABLE|USB2OTG_USB_SRPCAPABLE);
240 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
241 break;
242 case 1:
243 case 3:
244 case 5:
245 D(bug("SRP\n"));
246 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
247 otg_RegVal &= ~USB2OTG_USB_HNPCAPABLE;
248 otg_RegVal |= USB2OTG_USB_SRPCAPABLE;
249 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
250 break;
251 case 2:
252 case 4:
253 case 6:
254 D(bug("No HNP or SRP\n"));
255 otg_RegVal = *((volatile unsigned int *)USB2OTG_USB);
256 otg_RegVal &= ~(USB2OTG_USB_HNPCAPABLE|USB2OTG_USB_SRPCAPABLE);
257 *((volatile unsigned int *)USB2OTG_USB) = otg_RegVal;
258 break;
261 bug("[USB2OTG] HS OTG USB Driver Initialised\n");
265 else
267 D(bug("[USB2OTG] %s: Failed to Create MemPool\n",
268 __PRETTY_FUNCTION__));
270 CloseLibrary((struct Library *) UtilityBase);
271 USB2OTGBase = NULL;
274 else
276 D(bug("[USB2OTG] %s: OpenLibrary(\"utility.library\", 39) failed!\n",
277 __PRETTY_FUNCTION__));
279 USB2OTGBase = NULL;
282 else
284 D(bug("[USB2OTG] %s: OpenDevice(\"timer.device\") failed!\n",
285 __PRETTY_FUNCTION__));
287 USB2OTGBase = NULL;
290 else
292 D(bug("[USB2OTG] %s: Failed to allocate timer IORequest\n",
293 __PRETTY_FUNCTION__));
295 USB2OTGBase = NULL;
298 else
300 D(bug("[USB2OTG] %s: Failed to create MsgPort\n",
301 __PRETTY_FUNCTION__));
303 USB2OTGBase = NULL;
307 return USB2OTGBase ? TRUE : FALSE;
311 *===========================================================
312 * Open(ioreq, unit, flags, base)
313 *===========================================================
315 * This is the the DEV_OPEN function.
318 static int FNAME_DEV(Open)(LIBBASETYPEPTR USB2OTGBase, struct IOUsbHWReq *ioreq, ULONG otg_Unit, ULONG flags)
320 D(bug("[USB2OTG] %s: IOReq @ 0x%p, unit #%ld, flags = 0x%08lx, USB2OTGBase @ 0x%p\n",
321 __PRETTY_FUNCTION__, ioreq, otg_Unit, flags, USB2OTGBase));
323 D(bug("[USB2OTG] %s: openCnt = %ld\n",
324 __PRETTY_FUNCTION__, USB2OTGBase->hd_Library.lib_OpenCnt));
326 if (ioreq->iouh_Req.io_Message.mn_Length < sizeof(struct IOUsbHWReq))
328 D(bug("[USB2OTG] %s: invalid MN_LENGTH!\n",
329 __PRETTY_FUNCTION__));
331 ioreq->iouh_Req.io_Error = IOERR_BADLENGTH;
333 else
335 ioreq->iouh_Req.io_Error = IOERR_OPENFAIL;
337 ioreq->iouh_Req.io_Unit = FNAME_DEV(OpenUnit)(ioreq, otg_Unit, USB2OTGBase);
338 if (!(ioreq->iouh_Req.io_Unit))
340 D(bug("[USB2OTG] %s: could not open unit!\n",
341 __PRETTY_FUNCTION__));
344 else
346 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
347 ioreq->iouh_Req.io_Error = 0;
349 return TRUE;
353 return FALSE;
358 *===========================================================
359 * Close(ioreq, base)
360 *===========================================================
362 * This is the the DEV_EXPUNGE function.
365 static int FNAME_DEV(Close)(LIBBASETYPEPTR USB2OTGBase, struct IOUsbHWReq *ioreq)
367 D(bug("[USB2OTG] %s: IOReq @ 0x%p, USB2OTGBase @ 0x%p\n",
368 __PRETTY_FUNCTION__, ioreq, USB2OTGBase));
370 FNAME_DEV(CloseUnit)(ioreq, (struct USB2OTGUnit *) ioreq->iouh_Req.io_Unit, USB2OTGBase);
372 ioreq->iouh_Req.io_Unit = (APTR) -1;
373 ioreq->iouh_Req.io_Device = (APTR) -1;
374 return TRUE;
377 static int FNAME_DEV(Expunge)(LIBBASETYPEPTR USB2OTGBase)
379 DeletePool(USB2OTGBase->hd_MemPool);
381 D(bug("[USB2OTG] %s: closing utility.library @ 0x%p\n",
382 __PRETTY_FUNCTION__, UtilityBase));
384 CloseLibrary((struct Library *) UtilityBase);
385 return TRUE;
388 ADD2INITLIB(FNAME_DEV(Init), 0)
389 ADD2OPENDEV(FNAME_DEV(Open), 0)
390 ADD2CLOSEDEV(FNAME_DEV(Close), 0)
391 ADD2EXPUNGELIB(FNAME_DEV(Expunge), 0)
394 *===========================================================
395 * BeginIO(ioreq, base)
396 *===========================================================
398 * This is the DEV_BEGINIO vector of the device.
401 AROS_LH1(void, FNAME_DEV(BeginIO),
402 AROS_LHA(struct IOUsbHWReq *, ioreq, A1),
403 LIBBASETYPEPTR, USB2OTGBase, 5, usb2otg)
405 AROS_LIBFUNC_INIT
407 struct USB2OTGUnit *otg_Unit = (struct USB2OTGUnit *) ioreq->iouh_Req.io_Unit;
408 WORD ret;
410 D(bug("[USB2OTG] %s: IOReq @ 0x%08lx, USB2OTGBase @ 0x%08lx [cmd:%lu]\n",
411 __PRETTY_FUNCTION__, ioreq, USB2OTGBase, ioreq->iouh_Req.io_Command));
413 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
414 ioreq->iouh_Req.io_Error = UHIOERR_NO_ERROR;
416 if (ioreq->iouh_Req.io_Command < NSCMD_DEVICEQUERY)
418 switch (ioreq->iouh_Req.io_Command)
420 case CMD_RESET:
421 ret = FNAME_DEV(cmdReset)(ioreq, otg_Unit, USB2OTGBase);
422 break;
424 case CMD_FLUSH:
425 ret = FNAME_DEV(cmdFlush)(ioreq, otg_Unit, USB2OTGBase);
426 break;
428 case UHCMD_QUERYDEVICE:
429 ret = FNAME_DEV(cmdQueryDevice)(ioreq, otg_Unit, USB2OTGBase);
430 break;
432 case UHCMD_USBRESET:
433 ret = FNAME_DEV(cmdUsbReset)(ioreq, otg_Unit, USB2OTGBase);
434 break;
436 case UHCMD_USBRESUME:
437 ret = FNAME_DEV(cmdUsbResume)(ioreq, otg_Unit, USB2OTGBase);
438 break;
440 case UHCMD_USBSUSPEND:
441 ret = FNAME_DEV(cmdUsbSuspend)(ioreq, otg_Unit, USB2OTGBase);
442 break;
444 case UHCMD_USBOPER:
445 ret = FNAME_DEV(cmdUsbOper)(ioreq, otg_Unit, USB2OTGBase);
446 break;
448 case UHCMD_CONTROLXFER:
449 ret = FNAME_DEV(cmdControlXFer)(ioreq, otg_Unit, USB2OTGBase);
450 break;
452 case UHCMD_BULKXFER:
453 ret = FNAME_DEV(cmdBulkXFer)(ioreq, otg_Unit, USB2OTGBase);
454 break;
456 case UHCMD_INTXFER:
457 ret = FNAME_DEV(cmdIntXFer)(ioreq, otg_Unit, USB2OTGBase);
458 break;
460 case UHCMD_ISOXFER:
461 ret = FNAME_DEV(cmdIsoXFer)(ioreq, otg_Unit, USB2OTGBase);
462 break;
464 default:
465 ret = IOERR_NOCMD;
466 break;
469 else
471 switch(ioreq->iouh_Req.io_Command)
473 case NSCMD_DEVICEQUERY:
474 ret = FNAME_DEV(cmdNSDeviceQuery)((struct IOStdReq *) ioreq, otg_Unit, USB2OTGBase);
475 break;
477 default:
478 ret = IOERR_NOCMD;
479 break;
483 if (ret != RC_DONTREPLY)
485 D(bug("[USB2OTG] %s: Terminating I/O..\n",
486 __PRETTY_FUNCTION__));
488 if (ret != RC_OK)
490 ioreq->iouh_Req.io_Error = ret & 0xff;
492 FNAME_DEV(TermIO)(ioreq, USB2OTGBase);
495 AROS_LIBFUNC_EXIT
499 *===========================================================
500 * AbortIO(ioreq, base)
501 *===========================================================
503 * This is the DEV_ABORTIO vector of the device. It abort
504 * the given iorequest, and set
507 AROS_LH1(LONG, FNAME_DEV(AbortIO),
508 AROS_LHA(struct IOUsbHWReq *, ioreq, A1),
509 LIBBASETYPEPTR, USB2OTGBase, 6, usb2otg)
511 AROS_LIBFUNC_INIT
513 D(bug("[USB2OTG] %s: IOReq @ 0x%p, command %ld, status %ld\n",
514 __PRETTY_FUNCTION__, ioreq, ioreq->iouh_Req.io_Command, ioreq->iouh_Req.io_Message.mn_Node.ln_Type));
516 /* Is it pending? */
517 if (ioreq->iouh_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE)
519 // if (FNAME_DEV(cmdAbortIO)(ioreq, USB2OTGBase))
520 // {
521 // return(0);
522 // }
524 return(-1);
526 AROS_LIBFUNC_EXIT
529 void FNAME_DEV(Cause)(LIBBASETYPEPTR USB2OTGBase, struct Interrupt *interrupt)
531 /* this is a workaround for the original Cause() function missing tailed calls */
532 Disable();
534 if((interrupt->is_Node.ln_Type == NT_SOFTINT) || (interrupt->is_Node.ln_Type == NT_USER))
536 // signal tailed call
537 interrupt->is_Node.ln_Type = NT_USER;
538 } else {
541 interrupt->is_Node.ln_Type = NT_SOFTINT;
542 Forbid(); // make sure code is not interrupted by other tasks
543 Enable();
544 AROS_INTC1(interrupt->is_Code, interrupt->is_Data);
545 Disable();
546 Permit();
547 } while(interrupt->is_Node.ln_Type != NT_SOFTINT);
548 interrupt->is_Node.ln_Type = NT_INTERRUPT;
550 Enable();