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 <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 volatile unsigned int otg_RegVal
;
30 D(bug("[USB2OTG] %s: Received USB interrupt for Unit @ 0x%p\n",
31 __PRETTY_FUNCTION__
, USBUnit
));
33 otg_RegVal
= *((volatile unsigned int *)USB2OTG_INTR
);
35 if (otg_RegVal
& USB2OTG_INTRCORE_HOSTCHANNEL
)
37 volatile unsigned int otg_ChanVal
;
38 otg_ChanVal
= *((volatile unsigned int *)USB2OTG_HOSTINTR
);
39 *((volatile unsigned int *)USB2OTG_HOSTINTR
) = otg_ChanVal
;
41 for (chan
= 0; chan
< ... ; chan
++)
43 if (otg_ChanVal
& (1 << chan
))
45 *((volatile unsigned int *)USB2OTG_HOST_CHANBASE
+ (chan
* USB2OTG_HOST_CHANREGSIZE
) + 0x0c) = 0;
46 D(bug("[USB2OTG] %s: Host Channel #%d Interrupt\n",
47 __PRETTY_FUNCTION__
, chan
));
53 *((volatile unsigned int *)USB2OTG_INTR
) = otg_RegVal
;
57 *===========================================================
59 *===========================================================
61 static int FNAME_DEV(Init
)(LIBBASETYPEPTR USB2OTGBase
)
63 volatile unsigned int *pmmailbox
;
64 volatile unsigned int otg_RegVal
;
65 unsigned int otg_OperatingMode
= 0, pmres
;
67 KernelBase
= OpenResource("kernel.resource");
69 __arm_periiobase
= KrnGetSystemAttr(KATTR_PeripheralBase
);
71 pmmailbox
= (volatile unsigned int *)(ARM_PERIIOBASE
+ 0xB880);
73 D(bug("[USB2OTG] %s: USB2OTGBase @ 0x%p, SysBase @ 0x%p\n",
74 __PRETTY_FUNCTION__
, USB2OTGBase
, SysBase
));
76 otg_RegVal
= *((volatile unsigned int *)USB2OTG_VENDORID
);
78 if ((otg_RegVal
& 0xFFFFF000) != 0x4F542000)
80 bug("[USB2OTG] Unsupported HS OTG USB Core Found\n");
81 bug("[USB2OTG] Hardware: %c%c%x.%x%x%x\n",
82 ((otg_RegVal
>> 24) & 0xFF), ((otg_RegVal
>> 16) & 0xFF),
83 ((otg_RegVal
>> 12) & 0xF), ((otg_RegVal
>> 8) & 0xF), ((otg_RegVal
>> 4) & 0xF), (otg_RegVal
& 0xF)
90 USB2OTGBase
->hd_KernelBase
= OpenResource("kernel.resource");
91 D(bug("[USB2OTG] %s: kernel.resource opened @ 0x%p\n",
92 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_KernelBase
));
94 if((USB2OTGBase
->hd_MsgPort
= CreateMsgPort()))
96 if((USB2OTGBase
->hd_TimerReq
= (struct timerequest
*) CreateIORequest(USB2OTGBase
->hd_MsgPort
, sizeof(struct timerequest
))))
98 if(!OpenDevice("timer.device", UNIT_MICROHZ
, (struct IORequest
*) USB2OTGBase
->hd_TimerReq
, 0))
100 USB2OTGBase
->hd_TimerReq
->tr_node
.io_Message
.mn_Node
.ln_Name
= "USB2OTG Timer";
101 USB2OTGBase
->hd_TimerReq
->tr_node
.io_Command
= TR_ADDREQUEST
;
102 D(bug("[USB2OTG] %s: timer.device opened\n",
103 __PRETTY_FUNCTION__
));
105 bug("[USB2OTG] HS OTG Core Release: %c%c%x.%x%x%x\n",
106 ((otg_RegVal
>> 24) & 0xFF), ((otg_RegVal
>> 16) & 0xFF),
107 ((otg_RegVal
>> 12) & 0xF), ((otg_RegVal
>> 8) & 0xF), ((otg_RegVal
>> 4) & 0xF), (otg_RegVal
& 0xF)
110 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE2
);
111 bug("[USB2OTG] Architecture: %d - ", ((otg_RegVal
& (3 << 3)) >> 3));
112 switch (((otg_RegVal
& (3 << 3)) >> 3))
115 bug("Internal DMA\n");
118 bug("External DMA\n");
125 D(bug("[USB2OTG] %s: Disabling USB Interrupts (Globaly)..\n", __PRETTY_FUNCTION__
));
126 otg_RegVal
= *((volatile unsigned int *)USB2OTG_AHB
);
127 otg_RegVal
&= ~USB2OTG_AHB_INTENABLE
;
128 *((volatile unsigned int *)USB2OTG_INTRMASK
) = 0;
129 *((volatile unsigned int *)USB2OTG_AHB
) = otg_RegVal
;
131 while (pmmailbox
[6] & 0x80000000);
134 while (pmmailbox
[6] & 0x40000000);
135 } while (((pmres
= pmmailbox
[0]) & 0xf) != 0);
138 bug("[USB2OTG] Failed to power on controller\n");
139 //USB2OTGBase->hd_TimerReq
140 //USB2OTGBase->hd_MsgPort
145 if ((USB2OTGBase
->hd_UtilityBase
= (APTR
)OpenLibrary("utility.library", 39)) != NULL
)
147 USB2OTGBase
->hd_MemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
| MEMF_SEM_PROTECTED
, 16384, 4096);
148 if (USB2OTGBase
->hd_MemPool
)
152 D(bug("[USB2OTG] %s: Allocated MemPool @ 0x%p\n",
153 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_MemPool
));
158 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE
);
159 bug("[USB2OTG] %s: HWConfig: %08x-", __PRETTY_FUNCTION__
, otg_RegVal
);
160 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE2
);
161 bug("%08x-", otg_RegVal
);
162 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE3
);
163 bug("%08x-", otg_RegVal
);
164 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE4
);
165 bug("%08x\n", otg_RegVal
);
168 if ((USB2OTGBase
->hd_Unit
= AllocPooled(USB2OTGBase
->hd_MemPool
, sizeof(struct USB2OTGUnit
))) != NULL
)
170 D(bug("[USB2OTG] %s: Unit Allocated at 0x%p\n",
171 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
));
173 NewList(&USB2OTGBase
->hd_Unit
->hu_IOPendingQueue
);
175 NewList(&USB2OTGBase
->hd_Unit
->hu_CtrlXFerQueue
);
176 NewList(&USB2OTGBase
->hd_Unit
->hu_IntXFerQueue
);
177 NewList(&USB2OTGBase
->hd_Unit
->hu_IsoXFerQueue
);
178 NewList(&USB2OTGBase
->hd_Unit
->hu_BulkXFerQueue
);
179 NewList(&USB2OTGBase
->hd_Unit
->hu_TDQueue
);
180 NewList(&USB2OTGBase
->hd_Unit
->hu_AbortQueue
);
181 NewList(&USB2OTGBase
->hd_Unit
->hu_PeriodicTDQueue
);
183 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
184 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Name
= "OTG2USB Pending Work Interrupt";
185 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Node
.ln_Pri
= 0;
186 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Data
= USB2OTGBase
->hd_Unit
;
187 USB2OTGBase
->hd_Unit
->hu_PendingInt
.is_Code
= (VOID_FUNC
)FNAME_DEV(PendingInt
);
189 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
190 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Name
= "OTG2USB NakTimeout Interrupt";
191 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Node
.ln_Pri
= -16;
192 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Data
= USB2OTGBase
->hd_Unit
;
193 USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
.is_Code
= (VOID_FUNC
)FNAME_DEV(NakTimeoutInt
);
195 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
196 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_Flags
= PA_SOFTINT
;
197 USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_SigTask
= &USB2OTGBase
->hd_Unit
->hu_NakTimeoutInt
;
198 NewList(&USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
.mp_MsgList
);
200 CopyMem(USB2OTGBase
->hd_TimerReq
, &USB2OTGBase
->hd_Unit
->hu_NakTimeoutReq
, sizeof(struct timerequest
));
201 USB2OTGBase
->hd_Unit
->hu_NakTimeoutReq
.tr_node
.io_Message
.mn_ReplyPort
= &USB2OTGBase
->hd_Unit
->hu_NakTimeoutMsgPort
;
203 USB2OTGBase
->hd_Unit
->hu_HubPortChanged
= FALSE
;
205 USB2OTGBase
->hd_Unit
->hu_OperatingMode
= (otg_OperatingMode
== (USB2OTG_USBHOSTMODE
|USB2OTG_USBDEVICEMODE
)) ? 0 : otg_OperatingMode
;
208 D(bug("[USB2OTG] %s: Unit Mode %d\n",
209 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
->hu_OperatingMode
));
211 USB2OTGBase
->hd_Unit
->hu_GlobalIRQHandle
= KrnAddIRQHandler(IRQ_VC_USB
, GlobalIRQHandler
, USB2OTGBase
->hd_Unit
, SysBase
);
213 D(bug("[USB2OTG] %s: Installed Global IRQ Handler [handle @ 0x%p] for IRQ #%ld\n",
214 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Unit
->hu_GlobalIRQHandle
, IRQ_HOSTPORT
));
216 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
217 otg_RegVal
&= ~(USB2OTG_USB_ULPIDRIVEEXTERNALVBUS
|USB2OTG_USB_TSDLINEPULSEENABLE
);
218 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
220 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__
));
221 *((volatile unsigned int *)USB2OTG_RESET
) = USB2OTG_RESET_CORESOFT
;
222 for (ns
= 0; ns
< 10000; ns
++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
223 if ((*((volatile unsigned int *)USB2OTG_RESET
) & USB2OTG_RESET_CORESOFT
) != 0)
224 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__
);
226 D(bug("[USB2OTG] %s: Initialising PHY ..\n", __PRETTY_FUNCTION__
));
227 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
228 otg_RegVal
&= ~USB2OTG_USB_PHYINTERFACE
;
229 otg_RegVal
&= ~USB2OTG_USB_MODESELECT_UTMI
;
230 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
233 D(bug("[USB2OTG] %s: Reseting Controller ..\n", __PRETTY_FUNCTION__
));
234 *((volatile unsigned int *)USB2OTG_RESET
) = USB2OTG_RESET_CORESOFT
;
235 for (ns
= 0; ns
< 10000; ns
++) { asm volatile("mov r0, r0\n"); } // Wait 10ms
236 if ((*((volatile unsigned int *)USB2OTG_RESET
) & USB2OTG_RESET_CORESOFT
) != 0)
237 bug("[USB2OTG] %s: Reset Timed-Out!\n", __PRETTY_FUNCTION__
);
240 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE2
);
241 if (((otg_RegVal
& (3 << 6) >> 6) == 2) && ((otg_RegVal
& (3 << 8) >> 8) == 1))
243 D(bug("[USB2OTG] %s: ULPI FSLS configuration: enabled.\n", __PRETTY_FUNCTION__
));
244 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
245 otg_RegVal
|= (USB2OTG_USB_ULPIFSLS
|USB2OTG_USB_ULPI_CLK_SUS_M
);
246 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
248 D(bug("[USB2OTG] %s: ULPI FSLS configuration: disabled.\n", __PRETTY_FUNCTION__
));
249 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
250 otg_RegVal
&= ~(USB2OTG_USB_ULPIFSLS
|USB2OTG_USB_ULPI_CLK_SUS_M
);
251 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
254 D(bug("[USB2OTG] %s: Enabling DMA configuration..\n", __PRETTY_FUNCTION__
));
255 otg_RegVal
= *((volatile unsigned int *)USB2OTG_AHB
);
256 otg_RegVal
&= ~(1 << USB2OTG_AHB_DMAREMAINDERMODE
);
257 otg_RegVal
|= (USB2OTG_AHB_DMAENABLE
|USB2OTG_AHB_DMAREMAINDERMODE_INCR
);
258 *((volatile unsigned int *)USB2OTG_AHB
) = otg_RegVal
;
261 D(bug("[USB2OTG] %s: Operating Mode: ", __PRETTY_FUNCTION__
));
262 otg_RegVal
= *((volatile unsigned int *)USB2OTG_HARDWARE2
);
263 switch (otg_RegVal
& 7)
267 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
268 otg_RegVal
|= (USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
269 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
275 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
276 otg_RegVal
&= ~USB2OTG_USB_HNPCAPABLE
;
277 otg_RegVal
|= USB2OTG_USB_SRPCAPABLE
;
278 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
283 D(bug("No HNP or SRP\n"));
284 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
285 otg_RegVal
&= ~(USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
286 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
290 D(bug("[USB2OTG] %s: Disable HNP/SRP\n", __PRETTY_FUNCTION__
));
291 otg_RegVal
= *((volatile unsigned int *)USB2OTG_USB
);
292 otg_RegVal
&= ~(USB2OTG_USB_HNPCAPABLE
|USB2OTG_USB_SRPCAPABLE
);
293 *((volatile unsigned int *)USB2OTG_USB
) = otg_RegVal
;
296 D(bug("[USB2OTG] %s: Enabling Global Interrupts ...\n", __PRETTY_FUNCTION__
));
297 otg_RegVal
= *((volatile unsigned int *)USB2OTG_INTR
);
299 *((volatile unsigned int *)USB2OTG_INTR
) = otg_RegVal
;
301 bug("[USB2OTG] HS OTG USB Driver Initialised\n");
307 D(bug("[USB2OTG] %s: Failed to Create MemPool\n",
308 __PRETTY_FUNCTION__
));
310 CloseLibrary((struct Library
*) UtilityBase
);
316 D(bug("[USB2OTG] %s: OpenLibrary(\"utility.library\", 39) failed!\n",
317 __PRETTY_FUNCTION__
));
324 D(bug("[USB2OTG] %s: OpenDevice(\"timer.device\") failed!\n",
325 __PRETTY_FUNCTION__
));
332 D(bug("[USB2OTG] %s: Failed to allocate timer IORequest\n",
333 __PRETTY_FUNCTION__
));
340 D(bug("[USB2OTG] %s: Failed to create MsgPort\n",
341 __PRETTY_FUNCTION__
));
347 return USB2OTGBase
? TRUE
: FALSE
;
351 *===========================================================
352 * Open(ioreq, unit, flags, base)
353 *===========================================================
355 * This is the the DEV_OPEN function.
358 static int FNAME_DEV(Open
)(LIBBASETYPEPTR USB2OTGBase
, struct IOUsbHWReq
*ioreq
, ULONG otg_Unit
, ULONG flags
)
360 D(bug("[USB2OTG] %s: IOReq @ 0x%p, unit #%ld, flags = 0x%08lx, USB2OTGBase @ 0x%p\n",
361 __PRETTY_FUNCTION__
, ioreq
, otg_Unit
, flags
, USB2OTGBase
));
363 D(bug("[USB2OTG] %s: openCnt = %ld\n",
364 __PRETTY_FUNCTION__
, USB2OTGBase
->hd_Library
.lib_OpenCnt
));
366 if (ioreq
->iouh_Req
.io_Message
.mn_Length
< sizeof(struct IOUsbHWReq
))
368 D(bug("[USB2OTG] %s: invalid MN_LENGTH!\n",
369 __PRETTY_FUNCTION__
));
371 ioreq
->iouh_Req
.io_Error
= IOERR_BADLENGTH
;
375 ioreq
->iouh_Req
.io_Error
= IOERR_OPENFAIL
;
377 ioreq
->iouh_Req
.io_Unit
= FNAME_DEV(OpenUnit
)(ioreq
, otg_Unit
, USB2OTGBase
);
378 if (!(ioreq
->iouh_Req
.io_Unit
))
380 D(bug("[USB2OTG] %s: could not open unit!\n",
381 __PRETTY_FUNCTION__
));
386 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
387 ioreq
->iouh_Req
.io_Error
= 0;
398 *===========================================================
400 *===========================================================
402 * This is the the DEV_EXPUNGE function.
405 static int FNAME_DEV(Close
)(LIBBASETYPEPTR USB2OTGBase
, struct IOUsbHWReq
*ioreq
)
407 D(bug("[USB2OTG] %s: IOReq @ 0x%p, USB2OTGBase @ 0x%p\n",
408 __PRETTY_FUNCTION__
, ioreq
, USB2OTGBase
));
410 FNAME_DEV(CloseUnit
)(ioreq
, (struct USB2OTGUnit
*) ioreq
->iouh_Req
.io_Unit
, USB2OTGBase
);
412 ioreq
->iouh_Req
.io_Unit
= (APTR
) -1;
413 ioreq
->iouh_Req
.io_Device
= (APTR
) -1;
417 static int FNAME_DEV(Expunge
)(LIBBASETYPEPTR USB2OTGBase
)
419 DeletePool(USB2OTGBase
->hd_MemPool
);
421 D(bug("[USB2OTG] %s: closing utility.library @ 0x%p\n",
422 __PRETTY_FUNCTION__
, UtilityBase
));
424 CloseLibrary((struct Library
*) UtilityBase
);
428 ADD2INITLIB(FNAME_DEV(Init
), 0)
429 ADD2OPENDEV(FNAME_DEV(Open
), 0)
430 ADD2CLOSEDEV(FNAME_DEV(Close
), 0)
431 ADD2EXPUNGELIB(FNAME_DEV(Expunge
), 0)
434 *===========================================================
435 * BeginIO(ioreq, base)
436 *===========================================================
438 * This is the DEV_BEGINIO vector of the device.
441 AROS_LH1(void, FNAME_DEV(BeginIO
),
442 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
443 LIBBASETYPEPTR
, USB2OTGBase
, 5, usb2otg
)
447 struct USB2OTGUnit
*otg_Unit
= (struct USB2OTGUnit
*) ioreq
->iouh_Req
.io_Unit
;
450 D(bug("[USB2OTG] %s: IOReq @ 0x%08lx, USB2OTGBase @ 0x%08lx [cmd:%lu]\n",
451 __PRETTY_FUNCTION__
, ioreq
, USB2OTGBase
, ioreq
->iouh_Req
.io_Command
));
453 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
454 ioreq
->iouh_Req
.io_Error
= UHIOERR_NO_ERROR
;
456 if (ioreq
->iouh_Req
.io_Command
< NSCMD_DEVICEQUERY
)
458 switch (ioreq
->iouh_Req
.io_Command
)
461 ret
= FNAME_DEV(cmdReset
)(ioreq
, otg_Unit
, USB2OTGBase
);
465 ret
= FNAME_DEV(cmdFlush
)(ioreq
, otg_Unit
, USB2OTGBase
);
468 case UHCMD_QUERYDEVICE
:
469 ret
= FNAME_DEV(cmdQueryDevice
)(ioreq
, otg_Unit
, USB2OTGBase
);
473 ret
= FNAME_DEV(cmdUsbReset
)(ioreq
, otg_Unit
, USB2OTGBase
);
476 case UHCMD_USBRESUME
:
477 ret
= FNAME_DEV(cmdUsbResume
)(ioreq
, otg_Unit
, USB2OTGBase
);
480 case UHCMD_USBSUSPEND
:
481 ret
= FNAME_DEV(cmdUsbSuspend
)(ioreq
, otg_Unit
, USB2OTGBase
);
485 ret
= FNAME_DEV(cmdUsbOper
)(ioreq
, otg_Unit
, USB2OTGBase
);
488 case UHCMD_CONTROLXFER
:
489 ret
= FNAME_DEV(cmdControlXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
493 ret
= FNAME_DEV(cmdBulkXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
497 ret
= FNAME_DEV(cmdIntXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
501 ret
= FNAME_DEV(cmdIsoXFer
)(ioreq
, otg_Unit
, USB2OTGBase
);
511 switch(ioreq
->iouh_Req
.io_Command
)
513 case NSCMD_DEVICEQUERY
:
514 ret
= FNAME_DEV(cmdNSDeviceQuery
)((struct IOStdReq
*) ioreq
, otg_Unit
, USB2OTGBase
);
523 if (ret
!= RC_DONTREPLY
)
525 D(bug("[USB2OTG] %s: Terminating I/O..\n",
526 __PRETTY_FUNCTION__
));
530 ioreq
->iouh_Req
.io_Error
= ret
& 0xff;
532 FNAME_DEV(TermIO
)(ioreq
, USB2OTGBase
);
539 *===========================================================
540 * AbortIO(ioreq, base)
541 *===========================================================
543 * This is the DEV_ABORTIO vector of the device. It abort
544 * the given iorequest, and set
547 AROS_LH1(LONG
, FNAME_DEV(AbortIO
),
548 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
549 LIBBASETYPEPTR
, USB2OTGBase
, 6, usb2otg
)
553 D(bug("[USB2OTG] %s: IOReq @ 0x%p, command %ld, status %ld\n",
554 __PRETTY_FUNCTION__
, ioreq
, ioreq
->iouh_Req
.io_Command
, ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
));
557 if (ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
== NT_MESSAGE
)
560 if (FNAME_DEV(cmdAbortIO
)(ioreq
, USB2OTGBase
))
571 void FNAME_DEV(Cause
)(LIBBASETYPEPTR USB2OTGBase
, struct Interrupt
*interrupt
)
573 /* this is a workaround for the original Cause() function missing tailed calls */
576 if((interrupt
->is_Node
.ln_Type
== NT_SOFTINT
) || (interrupt
->is_Node
.ln_Type
== NT_USER
))
578 // signal tailed call
579 interrupt
->is_Node
.ln_Type
= NT_USER
;
583 interrupt
->is_Node
.ln_Type
= NT_SOFTINT
;
584 Forbid(); // make sure code is not interrupted by other tasks
586 AROS_INTC1(interrupt
->is_Code
, interrupt
->is_Data
);
589 } while(interrupt
->is_Node
.ln_Type
!= NT_SOFTINT
);
590 interrupt
->is_Node
.ln_Type
= NT_INTERRUPT
;