diff --git a/config/DZDE01/symbols.txt b/config/DZDE01/symbols.txt index 6f767cf17a..e89a1f8710 100644 --- a/config/DZDE01/symbols.txt +++ b/config/DZDE01/symbols.txt @@ -27886,7 +27886,7 @@ __EUARTSendStop = .sbss:0x804FBA20; // type:object size:0x4 scope:global align:4 Enabled = .sbss:0x804FBA24; // type:object size:0x4 scope:local align:4 data:4byte lo = .sbss:0x804FBA28; // type:object size:0x4 scope:global align:4 data:4byte hi = .sbss:0x804FBA2C; // type:object size:0x4 scope:global align:4 data:4byte -lbl_804FBA30 = .sbss:0x804FBA30; // type:object size:0x1 data:byte +s_usb_err = .sbss:0x804FBA30; // type:object size:0x1 data:byte _initialized = .sbss:0x804FBA38; // type:object size:0x4 scope:global align:4 data:4byte __bte_trace_level = .sbss:0x804FBA3C; // type:object size:0x1 data:byte remove_patch = .sbss:0x804FBA40; // type:object size:0x1 scope:global align:4 diff --git a/config/RZDE01_00/symbols.txt b/config/RZDE01_00/symbols.txt index 1bea1133f8..69888bcfa4 100644 --- a/config/RZDE01_00/symbols.txt +++ b/config/RZDE01_00/symbols.txt @@ -29069,7 +29069,7 @@ __EUARTSendStop = .sbss:0x8053B8F8; // type:object size:0x4 scope:global align:4 Enabled = .sbss:0x8053B8FC; // type:object size:0x4 scope:local align:4 data:4byte lo = .sbss:0x8053B900; // type:object size:0x4 scope:global align:4 data:4byte hi = .sbss:0x8053B904; // type:object size:0x4 scope:global align:4 data:4byte -lbl_8053B908 = .sbss:0x8053B908; // type:object size:0x1 data:byte +s_usb_err = .sbss:0x8053B908; // type:object size:0x1 data:byte _initialized = .sbss:0x8053B910; // type:object size:0x4 scope:global align:4 data:4byte __bte_trace_level = .sbss:0x8053B914; // type:object size:0x1 data:byte remove_patch = .sbss:0x8053B918; // type:object size:0x1 scope:global align:4 diff --git a/config/RZDE01_02/symbols.txt b/config/RZDE01_02/symbols.txt index 02f2167bce..d75f75161d 100644 --- a/config/RZDE01_02/symbols.txt +++ b/config/RZDE01_02/symbols.txt @@ -28589,7 +28589,7 @@ __EUARTSendStop = .sbss:0x805218F0; // type:object size:0x4 scope:global align:4 Enabled = .sbss:0x805218F4; // type:object size:0x4 scope:local align:4 data:4byte lo = .sbss:0x805218F8; // type:object size:0x4 scope:global align:4 data:4byte hi = .sbss:0x805218FC; // type:object size:0x4 scope:global align:4 data:4byte -lbl_80521900 = .sbss:0x80521900; // type:object size:0x1 data:byte +s_usb_err = .sbss:0x80521900; // type:object size:0x1 data:byte _initialized = .sbss:0x80521908; // type:object size:0x4 scope:global align:4 data:4byte __bte_trace_level = .sbss:0x8052190C; // type:object size:0x1 data:byte remove_patch = .sbss:0x80521910; // type:object size:0x1 scope:global align:4 diff --git a/config/RZDJ01/symbols.txt b/config/RZDJ01/symbols.txt index 16964bc244..77fb7850ca 100644 --- a/config/RZDJ01/symbols.txt +++ b/config/RZDJ01/symbols.txt @@ -28593,7 +28593,7 @@ __EUARTSendStop = .sbss:0x8051F760; // type:object size:0x4 scope:global align:4 Enabled = .sbss:0x8051F764; // type:object size:0x4 scope:local align:4 data:4byte lo = .sbss:0x8051F768; // type:object size:0x4 scope:global align:4 data:4byte hi = .sbss:0x8051F76C; // type:object size:0x4 scope:global align:4 data:4byte -lbl_8051F770 = .sbss:0x8051F770; // type:object size:0x1 data:byte +s_usb_err = .sbss:0x8051F770; // type:object size:0x1 data:byte _initialized = .sbss:0x8051F778; // type:object size:0x4 scope:global align:4 data:4byte __bte_trace_level = .sbss:0x8051F77C; // type:object size:0x1 data:byte remove_patch = .sbss:0x8051F780; // type:object size:0x1 scope:global align:4 diff --git a/config/RZDP01/symbols.txt b/config/RZDP01/symbols.txt index df0ce09ebb..086364676b 100644 --- a/config/RZDP01/symbols.txt +++ b/config/RZDP01/symbols.txt @@ -28480,7 +28480,7 @@ __EUARTSendStop = .sbss:0x805220B0; // type:object size:0x4 scope:global align:4 Enabled = .sbss:0x805220B4; // type:object size:0x4 scope:local align:4 data:4byte lo = .sbss:0x805220B8; // type:object size:0x4 scope:global align:4 data:4byte hi = .sbss:0x805220BC; // type:object size:0x4 scope:global align:4 data:4byte -lbl_805220C0 = .sbss:0x805220C0; // type:object size:0x1 data:byte +s_usb_err = .sbss:0x805220C0; // type:object size:0x1 data:byte _initialized = .sbss:0x805220C8; // type:object size:0x4 scope:global align:4 data:4byte __bte_trace_level = .sbss:0x805220CC; // type:object size:0x1 data:byte remove_patch = .sbss:0x805220D0; // type:object size:0x1 scope:global align:4 diff --git a/config/Shield/splits.txt b/config/Shield/splits.txt index 2f53ff5207..394ecc2449 100644 --- a/config/Shield/splits.txt +++ b/config/Shield/splits.txt @@ -3763,7 +3763,7 @@ revolution/usb/usb.c: .text start:0x8044B0D0 end:0x8044C620 .data start:0x804FDE88 end:0x804FE6B8 .sdata start:0x80508828 end:0x80508838 - .sbss start:0x80509B28 end:0x80509B3C + .sbss start:0x80509B28 end:0x80509B38 revolution/bte/gki_buffer.c: .text start:0x8044C620 end:0x8044DAC0 @@ -3786,7 +3786,7 @@ revolution/bte/hcisu_h2.c: revolution/bte/uusb_ppc.c: .text start:0x8044EA20 end:0x8044F6A0 .sdata start:0x80508838 end:0x80508848 - .sbss start:0x80509B3C end:0x80509B50 + .sbss start:0x80509B38 end:0x80509B50 .bss start:0x805DA1C0 end:0x805DC220 revolution/bte/bta_dm_cfg.c: diff --git a/config/Shield/symbols.txt b/config/Shield/symbols.txt index 85a59bc3eb..d395c723a3 100644 --- a/config/Shield/symbols.txt +++ b/config/Shield/symbols.txt @@ -25092,7 +25092,7 @@ lbl_80508818 = .sdata:0x80508818; // type:object size:0x1 data:byte hash:0xA0909 kp_wbc_stable_count = .sdata:0x8050881C; // type:object size:0x6 scope:global hash:0x0F8EEE79 kp_fs_revise_deg = .sdata:0x80508824; // type:object size:0x4 scope:global align:4 data:float hash:0xE9F1DE6C hId = .sdata:0x80508828; // type:object size:0x4 scope:local data:4byte hash:0x0B8753C0 -lbl_8050882C = .sdata:0x8050882C; // type:object size:0x1 data:byte hash:0xE6DB76F7 +s_usb_err = .sdata:0x8050882C; // type:object size:0x1 data:byte hash:0xE6DB76F7 @2519 = .sdata:0x80508830; // type:object size:0x6 scope:local data:string hash:0x0CA0B80A wait4hci = .sdata:0x80508838; // type:object size:0x4 scope:global data:4byte hash:0xEC3BFFF8 __ntd_ios_file_descriptor = .sdata:0x8050883C; // type:object size:0x4 scope:global data:4byte hash:0xEF6A2964 @@ -26171,7 +26171,7 @@ __EUARTSendStop = .sbss:0x80509B20; // type:object size:0x4 scope:global data:4b Enabled = .sbss:0x80509B24; // type:object size:0x4 scope:local data:4byte hash:0x0028A000 lo = .sbss:0x80509B28; // type:object size:0x4 scope:global data:4byte hash:0x00596E86 hi = .sbss:0x80509B2C; // type:object size:0x4 scope:global data:4byte hash:0x00596F04 -lbl_80509B30 = .sbss:0x80509B30; // type:object size:0x1 data:byte hash:0xE6DB7C56 +s_usb_log = .sbss:0x80509B30; // type:object size:0x1 data:byte hash:0xE6DB7C56 lbl_80509B38 = .sbss:0x80509B38; // type:object size:0x1 data:byte hash:0x1A6D195B lbl_80509B39 = .sbss:0x80509B39; // type:object size:0x1 data:byte hash:0x9DACBE09 __ntd_ohci = .sbss:0x80509B3C; // type:object size:0x4 scope:global data:4byte hash:0x75432589 diff --git a/configure.py b/configure.py index 4f787ef7d3..cbc6bda07f 100755 --- a/configure.py +++ b/configure.py @@ -1880,6 +1880,12 @@ config.libs = [ Object(NonMatching, "revolution/euart/euart.c"), ], ), + RevolutionLib( + "usb", + [ + Object(Matching, "revolution/usb/usb.c"), + ], + ), RevolutionLib( "gd", [ diff --git a/include/revolution/usb.h b/include/revolution/usb.h new file mode 100644 index 0000000000..fcd8c3e28e --- /dev/null +++ b/include/revolution/usb.h @@ -0,0 +1,55 @@ +#ifndef _REVOLUTION_USB_H_ +#define _REVOLUTION_USB_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SWAP32(val) \ +((u32)((((u32)(val) & (u32)0x000000ffUL) << 24) | (((u32)(val) & (u32)0x0000ff00UL) << 8) | (((u32)(val) & (u32)0x00ff0000UL) >> 8) | \ +(((u32)(val) & (u32)0xff000000UL) >> 24))) + +#define SWAP16(val) ((u16)((((u16)(val) & (u16)0x00ffUL) << 8) | (((u16)(val) & (u16)0xff00) >> 8))) + +typedef struct { + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} USB_DevDescr; + +typedef struct IsoTransfer { + void* buf; + u8 numPackets; + u16* packets; +} IsoTransfer; + +typedef void (*USBCallbackFunc)(IOSError err, void* cbArg); +typedef void (*USBIsoCallbackFunc)(IOSError err, IsoTransfer* xfer, void* cbArg); + +IOSError IUSB_ReadIntrMsgAsync(IOSFd fd, u32 ep, u32 buflen, char* buf, USBCallbackFunc cb, void* cbArg); +IOSError IUSB_WriteCtrlMsgAsync(IOSFd fd, u8 reqType, u8 request, u16 value, u16 index, u16 buflen, char* buf, USBCallbackFunc cb, void* cbArg); +IOSError IUSB_WriteBlkMsgAsync(IOSFd fd, u32 ep, u32 buflen, char* buf, USBCallbackFunc cb, void* cbArg); +IOSError IUSB_OpenDeviceIds(const char* did, u16 vid, u16 pid, IOSFd* fd); +IOSError IUSB_ReadBlkMsgAsync(IOSFd fd, u32 ep, u32 buflen, char* buf, USBCallbackFunc cb, void* cbArg); +IOSError IUSB_OpenLib(void); +IOSError IUSB_CloseDeviceAsync(IOSFd fd, USBCallbackFunc cb, void* cbArg); +IOSError IUSB_CloseLib(void); + +#ifdef __cplusplus +} +#endif + +#endif // _REVOLUTION_USB_H_ diff --git a/src/revolution/usb/__usb.h b/src/revolution/usb/__usb.h new file mode 100644 index 0000000000..add2d6e3f1 --- /dev/null +++ b/src/revolution/usb/__usb.h @@ -0,0 +1,42 @@ +#ifndef _REVOLUTION_USB_PRIVATE_H_ +#define _REVOLUTION_USB_PRIVATE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ROUNDUP(sz) (((u32)(sz) + 32 - 1) & ~(u32)(32 - 1)) + +typedef struct { + char *data; + u16 wLength; +} IntBlkCtrlReq; + +typedef struct iusb_Ctxt { + USBCallbackFunc cb; +#if SDK_AUG2010 + USBIsoCallbackFunc icb; +#endif + void *cbArg; +#if SDK_AUG2010 + void *xfer; +#endif + void *spare; + void *clean[8]; + u32 nclean; + + union { + char path[ROUNDUP(64)]; + char des[ROUNDUP(sizeof(USB_DevDescr))]; + char reqBuf[ROUNDUP(sizeof(IntBlkCtrlReq))]; + } u __attribute__ ((aligned(32))); + +} iusb_ctxt; + +#ifdef __cplusplus +} +#endif + +#endif /* _REVOLUTION_USB_PRIVATE_H_ */ diff --git a/src/revolution/usb/usb.c b/src/revolution/usb/usb.c new file mode 100644 index 0000000000..822171d510 --- /dev/null +++ b/src/revolution/usb/usb.c @@ -0,0 +1,602 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if SDK_AUG2010 +#define IPC_ARENA_SIZE 0x4000 +#else +#define IPC_ARENA_SIZE 0x1000 +#endif + +static IOSHeapId hId = -1; +void *lo = NULL, *hi = NULL; + +#if SDK_AUG2010 +static u8 s_usb_log = 0; +static u8 s_usb_err = 1; +#else +static u8 s_usb_err; +#endif + +void USB_LOG(const char *str, ...) { + va_list vlist; +#if SDK_AUG2010 + if (s_usb_log) { +#else + if (s_usb_err) { +#endif + OSReport("USB: "); + va_start(vlist, str); + vprintf(str, vlist); + va_end(vlist); + } else { + (void)str; + } +} + +void USB_ERR(const char *str, ...) { + va_list vlist; + if (s_usb_err) { + OSReport("USB ERR: "); + va_start(vlist, str); + vprintf(str, vlist); + va_end(vlist); + } else { + (void)str; + } +} + +static void* IOSAlloc(u32 size) { + void *rv; + if ((rv = iosAllocAligned(hId, size, 32)) == NULL) { + USB_ERR("iosAllocAligned(%d, %u) failed: %d\n", hId, size, rv); + } + + return rv; +} + +static void IOSFree(void *addr) { + IOSError rv; + if (addr) { + if ((rv = iosFree(hId, addr)) < 0) { + USB_ERR("iosFree(%d, 0x%x) failed: %d\n", hId, addr, rv); + } + } + return; +} + +IOSError IUSB_OpenLib(void) { + IOSError rc = IOS_ERROR_OK; + u32 mask = (u32)OSDisableInterrupts(); + if (-1 != hId) { + USB_LOG("Library is already initialized. Heap Id = %d\n", hId); + goto out; + } + + if (NULL == lo) { + lo = IPCGetBufferLo(); + hi = IPCGetBufferHi(); + USB_LOG("iusb size: %d lo: %x hi: %x\n", sizeof(iusb_ctxt), lo, hi); + + if ((u32)lo + ROUNDUP(IPC_ARENA_SIZE) > (u32)hi) { + USB_ERR("Not enough IPC arena\n"); + rc = IOS_ERROR_FAIL_ALLOC; + goto out; + } + + IPCSetBufferLo((void*)((u32)lo + ROUNDUP(IPC_ARENA_SIZE))); + } + + hId = iosCreateHeap(lo, IPC_ARENA_SIZE); + + if (hId < 0) { + USB_ERR("Not enough heaps\n"); + rc = IOS_ERROR_FAIL_ALLOC; + goto out; + } + +out: + OSRestoreInterrupts((BOOL)mask); + return rc; +} + +IOSError IUSB_CloseLib(void) { + return IOS_ERROR_OK; +} + +#if SDK_AUG2010 +IOSError _intrBlkCtrlIsoCb(IOSError ret, void *ctxt) { + u32 i; + IOSError rv = ret; + iusb_ctxt *req = (iusb_ctxt*)ctxt; + + USB_LOG("_intrBlkCtrlIsoCb returned: %d\n", rv); + USB_LOG("_intrBlkCtrlIsoCb: nclean = %d\n", req->nclean); + + if (req->nclean != 7 && req->nclean != 3 && req->nclean != 0 && + req->nclean != 4 && req->nclean != 2) { + USB_ERR("__intrBlkCtrlIsoCb: got invalid nclean\n"); + } else { + for (i = 0; i < req->nclean; ++i) { + USB_LOG("Freeing clean[%d] = %x\n", i, req->clean[i]); + IOSFree(req->clean[i]); + } + req->nclean = 0; + } + + USB_LOG("cb = %x cbArg = %x\n", req->cb, req->cbArg); + + if (req->cb) { + req->cb(ret, req->cbArg); + } else if (req->icb) { + USB_LOG("calling iso callback\n"); + req->icb(ret, req->xfer, req->cbArg); + } + + IOSFree(req); + return rv; +} +#else +IOSError _intBlkCtrlCb(IOSError ret, void *ctxt) { + u32 i; + IOSError rv = ret; + iusb_ctxt *req = (iusb_ctxt*)ctxt; + + USB_LOG("_intrBlkCtrlCb returned: %d\n", rv); + USB_LOG("_intrBlkCtrlCb: nclean = %d\n", req->nclean); + + if (req->nclean != 7 && req->nclean != 3 && req->nclean != 0) { + USB_ERR("__intBlkCtrlCb: got invalid nclean\n"); + } else { + for (i = 0; i < req->nclean; ++i) { + USB_LOG("Freeing clean[%d] = %x\n", i, req->clean[i]); + IOSFree(req->clean[i]); + } + } + + USB_LOG("cb = %x cbArg = %x\n", req->cb, req->cbArg); + + if (req->cb) { + req->cb(ret, req->cbArg); + } + + IOSFree(req); + return rv; +} +#endif + +IOSError IUSB_OpenDeviceIds(const char *did, u16 vid, u16 pid, IOSFd *fd) { + IOSError rv = IOS_ERROR_OK; + iusb_ctxt *req = 0; + + if (fd == 0) { + rv = IOS_ERROR_INVALID; + goto out; + } + + req = IOSAlloc(ROUNDUP(sizeof(*req))); + if (req == 0) { + USB_ERR("OpenDeviceIds: Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto out; + } + +#if SDK_AUG2010 + memset(req, 0, sizeof(iusb_ctxt)); +#endif + snprintf(req->u.path, sizeof(req->u.path), "/dev/usb/%s/%x/%x", did, vid, pid); + USB_LOG("OpenDevice - %s\n", req->u.path); + rv = IOS_Open(req->u.path, 0); + USB_LOG("OpenDevice returned: %d\n", rv); + *fd = rv; + +out: + IOSFree(req); + return rv; +} + +void dummy_str_0() { + USB_LOG("OpenDevice\n"); + USB_LOG("OpenDeviceIdsAsync: Not enough memory\n"); + USB_LOG("CloseDevice\n"); + USB_LOG("CloseDevice returned: %d\n"); +} + +IOSError IUSB_CloseDeviceAsync(IOSFd fd, USBCallbackFunc cb, void *cbArg) { + IOSError rv = IOS_ERROR_OK; + iusb_ctxt *req; + + USB_LOG("CloseDevice\n"); + req = IOSAlloc(ROUNDUP(sizeof(*req))); + if (req == 0) { + USB_ERR("CloseDeviceAsync: Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto out; + } + +#if SDK_AUG2010 + memset(req, 0, sizeof(iusb_ctxt)); +#endif + + req->cb = cb; + req->cbArg = cbArg; + req->nclean = 0; + +#if SDK_AUG2010 + rv = IOS_CloseAsync(fd, _intrBlkCtrlIsoCb, req); +#else + rv = IOS_CloseAsync(fd, _intBlkCtrlCb, req); +#endif + USB_LOG("CloseDevice returned: %d\n", rv); + if (rv < 0) { + IOSFree(req); + goto out; + } +out: + return rv; +} + +void dummy_str_1() { + USB_LOG("openDevice: Not enough memory\n"); + USB_LOG("getDeviceList: Not enough memory\n"); +} + +#if SDK_AUG2010 +static IOSError __LongBlkMsgInt(IOSFd fd, u32 ep, u32 buflen, char *buf, USBCallbackFunc cb, + void *cbArg, u8 async) { + IOSError rv = IOS_ERROR_OK; + IOSIoVector *vector = IOSAlloc(0x60); + u8 *sep = IOSAlloc(0x20); + u32 *sbuflen = IOSAlloc(0x20); + + if (NULL == vector || NULL == sep || NULL == sbuflen) { + USB_ERR("__LongBlkMsgInt: Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + + *sep = (u8)ep; + *sbuflen = (u32)buflen; + vector[0].base = sep; + vector[0].length = sizeof(u8); + vector[1].base = (u8 *) sbuflen; + vector[1].length = sizeof(u32); + vector[2].base = (u8*) buf; + vector[2].length = buflen; + + DCFlushRange(sep, 0x20); + DCFlushRange(sbuflen, 0x20); + DCFlushRange(vector, 0x60); + + if (0 == async) { + rv = IOS_Ioctlv(fd, 10, 2, 1, vector); + USB_LOG("Long bulk ioctl returned: %d\n", rv); + goto clean; + } else { + iusb_ctxt *req = IOSAlloc(0x80); + if (NULL == req) { + USB_ERR("LongBlkMsgInt (async): Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + + memset(req, 0, sizeof(iusb_ctxt)); + req->cb = cb; + req->cbArg = cbArg; + USB_LOG("longblkmsg: cb = 0x%x cbArg = 0x%x\n", req->cb, req->cbArg); + req->nclean = 3; + req->clean[0] = sep; + req->clean[1] = sbuflen; + req->clean[2] = vector; + ((IntBlkCtrlReq *)req->u.reqBuf)->data = buf; + ((IntBlkCtrlReq *)req->u.reqBuf)->wLength = (u16) buflen; + + rv = IOS_IoctlvAsync(fd, 10, 2, 1, vector, _intrBlkCtrlIsoCb, req); + if (rv >= 0) { + goto out; + } + + if (rv == IOS_ERROR_FAIL_ALLOC) { + OSReport("%s: IoctlvAsync returned error %d\n", __FUNCTION__, rv); + } + + IOSFree(req); + goto clean; + } + clean: + IOSFree(sep); + IOSFree(sbuflen); + IOSFree(vector); + out: + return rv; +} +#endif + +static IOSError __IntrBlkMsgInt(IOSFd fd, u32 ep, u32 buflen, char *buf, u8 typ, USBCallbackFunc cb, + void *cbArg, u8 async) { + IOSError rv = IOS_ERROR_OK; + IOSIoVector *vector = IOSAlloc(0x60); + u8 *sep = IOSAlloc(0x20); + u16 *sbuflen = IOSAlloc(0x20); + + if (NULL == vector || NULL == sep || NULL == sbuflen) { + USB_ERR("__IntrBlkMsgInt: Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + + *sep = (u8)ep; + *sbuflen = (u16)buflen; + vector[0].base = sep; + vector[0].length = sizeof(u8); + vector[1].base = (u8 *) sbuflen; + vector[1].length = sizeof(u16); + vector[2].base = (u8*) buf; + vector[2].length = buflen; + + DCFlushRange(sep, 0x20); + DCFlushRange(sbuflen, 0x20); + DCFlushRange(vector, 0x60); + + if (0 == async) { + rv = IOS_Ioctlv(fd, typ, 2, 1, vector); + USB_LOG("intr/blk ioctl returned: %d\n", rv); + goto clean; + } else { + iusb_ctxt *req = IOSAlloc(0x80); + if (NULL == req) { + USB_ERR("IntBlkMsgInt (async): Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + +#if SDK_AUG2010 + memset(req, 0, sizeof(iusb_ctxt)); +#endif + req->cb = cb; + req->cbArg = cbArg; + USB_LOG("intrblkmsg: cb = 0x%x cbArg = 0x%x\n", req->cb, req->cbArg); + req->nclean = 3; + req->clean[0] = sep; + req->clean[1] = sbuflen; + req->clean[2] = vector; + ((IntBlkCtrlReq *)req->u.reqBuf)->data = buf; + ((IntBlkCtrlReq *)req->u.reqBuf)->wLength = (u16) buflen; + +#if SDK_AUG2010 + rv = IOS_IoctlvAsync(fd, typ, 2, 1, vector, _intrBlkCtrlIsoCb, req); +#else + rv = IOS_IoctlvAsync(fd, typ, 2, 1, vector, _intBlkCtrlCb, req); +#endif + if (rv >= 0) { + goto out; + } + +#if SDK_AUG2010 + if (rv == IOS_ERROR_FAIL_ALLOC) { + OSReport("%s: IoctlvAsync returned error %d\n", __FUNCTION__, rv); + } +#endif + + IOSFree(req); + goto clean; + } +clean: + IOSFree(sep); + IOSFree(sbuflen); + IOSFree(vector); +out: + return rv; +} + +#if SDK_AUG2010 +void dummy_str_2() { + USB_LOG("calling short blk transfer fn: buflen = %u limit = %u\n"); + USB_LOG("calling long blk transfer fn: buflen = %u limit = %u\n"); +} +#endif + +IOSError IUSB_ReadIntrMsgAsync(IOSFd fd, u32 ep, u32 buflen, char *buf, USBCallbackFunc cb, + void *cbArg) { + DCInvalidateRange(buf, buflen); + return __IntrBlkMsgInt(fd, ep, buflen, buf, 2, cb, cbArg, 1); +} + +IOSError IUSB_ReadBlkMsgAsync(IOSFd fd, u32 ep, u32 buflen, char *buf, USBCallbackFunc cb, + void *cbArg) { + IOSError rv; + + DCInvalidateRange(buf, buflen); + +#if SDK_AUG2010 + if (buflen <= 0xffff) { + rv = __IntrBlkMsgInt(fd, ep, buflen, buf, 1, cb, cbArg, 1); + } else { + rv = __LongBlkMsgInt(fd, ep, buflen, buf, cb, cbArg, 1); + } +#else + rv = __IntrBlkMsgInt(fd, ep, buflen, buf, 1, cb, cbArg, 1); +#endif + + return rv; +} + +IOSError IUSB_WriteBlkMsgAsync(IOSFd fd, u32 ep, u32 buflen, char *buf, USBCallbackFunc cb, + void *cbArg) { + IOSError rv; + + DCFlushRange((void*)buf, buflen); + +#if SDK_AUG2010 + if (buflen <= 0xffff) { + rv = __IntrBlkMsgInt(fd, ep, buflen, buf, 1, cb, cbArg, 1); + } else { + rv = __LongBlkMsgInt(fd, ep, buflen, buf, cb, cbArg, 1); + } +#else + rv = __IntrBlkMsgInt(fd, ep, buflen, buf, 1, cb, cbArg, 1); +#endif + + return rv; +} + +IOSError __CtrlMsgInt(IOSFd fd, u8 reqType, u8 request, u16 value, u16 index, u16 length, + char *data, USBCallbackFunc cb, void *cbArg, u8 async) { + IOSError rv = IOS_ERROR_OK; + IOSIoVector *vector; + u8 *sreqType, *srequest, *sep; + u16 *svalue, *sindex, *slength; + + if ((data == 0 && length != 0) || ((u32)data & (u32)(32 - 1))) { + rv = IOS_ERROR_INVALID; + USB_ERR("ctrlmsg: bad data buffer\n"); + goto out; + } + + vector = IOSAlloc(0x20*7); + sreqType = IOSAlloc(0x20); + srequest = IOSAlloc(0x20); + sep = IOSAlloc(0x20); + svalue = IOSAlloc(0x20); + sindex = IOSAlloc(0x20); + slength = IOSAlloc(0x20); + + if (NULL == sreqType || NULL == srequest || NULL == sep + || NULL == svalue || NULL == sindex || NULL == slength + || NULL == vector) { + USB_ERR("Ctrl Msg: Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + + *sreqType = reqType; + *srequest = request; + *svalue = SWAP16(value); + *sindex = SWAP16(index); + *slength = SWAP16(length); + *sep = 0; + + vector[0].base = sreqType; + vector[0].length = sizeof(u8); + vector[1].base = srequest; + vector[1].length = sizeof(u8); + vector[2].base = (u8 *) svalue; + vector[2].length = sizeof(u16); + vector[3].base = (u8 *) sindex; + vector[3].length = sizeof(u16); + vector[4].base = (u8 *) slength; + vector[4].length = sizeof(u16); + vector[5].base = sep; + vector[5].length = sizeof(u8); + vector[6].base = (u8 *)data; + vector[6].length = length; + + DCFlushRange(sreqType, 0x20); + DCFlushRange(srequest, 0x20); + DCFlushRange(sep, 0x20); + DCFlushRange(svalue, 0x20); + DCFlushRange(sindex, 0x20); + DCFlushRange(slength, 0x20); + DCFlushRange(vector, 0x20*7); + + if (0 == async) { + rv = IOS_Ioctlv(fd, 0, 6, 1, vector); + goto clean; + } else { + iusb_ctxt *req = IOSAlloc(0x80); + if (NULL == req) { + USB_ERR("CtrlMsgInt (async): Not enough memory\n"); + rv = IOS_ERROR_FAIL_ALLOC; + goto clean; + } + +#if SDK_AUG2010 + memset(req, 0, sizeof(iusb_ctxt)); +#endif + req->cb = cb; + req->cbArg = cbArg; + USB_LOG("ctrlmsgint: cb = 0x%x cbArg = 0x%x\n", req->cb, req->cbArg); + req->nclean = 7; + req->clean[0] = sreqType; + req->clean[1] = srequest; + req->clean[2] = svalue; + req->clean[3] = sindex; + req->clean[4] = slength; + req->clean[5] = sep; + req->clean[6] = vector; + ((IntBlkCtrlReq *)req->u.reqBuf)->data = data; + ((IntBlkCtrlReq *)req->u.reqBuf)->wLength = length; + +#if SDK_AUG2010 + rv = IOS_IoctlvAsync(fd, 0, 6, 1, vector, _intrBlkCtrlIsoCb, req); +#else + rv = IOS_IoctlvAsync(fd, 0, 6, 1, vector, _intBlkCtrlCb, req); +#endif + + USB_LOG("Ctrl Msg async returned: %d\n", rv); + + if (rv < 0) { + IOSFree(req); + goto clean; + } + + goto out; + } +clean: + IOSFree(sreqType); + IOSFree(srequest); + IOSFree(svalue); + IOSFree(sindex); + IOSFree(slength); + IOSFree(sep); + IOSFree(vector); +out: + return rv; +} + +IOSError IUSB_WriteCtrlMsgAsync(IOSFd fd, u8 reqType, u8 request, u16 value, u16 index, u16 buflen, + char *buf, USBCallbackFunc cb, void *cbArg) { + DCFlushRange((void*)buf, buflen); + return __CtrlMsgInt(fd, reqType, request, value, index, buflen, buf, cb, cbArg, 1); +} + +void dummy_str_3() { + USB_LOG("GetStrCb returned: %d\n"); + USB_LOG("GetStrCb: buf = 0x%x buflen = %u\n"); + USB_LOG("Failed to convert buffer from unicode 2 ascii\n"); + USB_LOG("calling cb 0x%x with arg 0x%x\n"); + USB_LOG("Failed __CtrlMsg: %d"); + USB_LOG("Failed to convert unicode 2 ascii\n"); + USB_LOG("GetStr - _GetStrCb\n"); + USB_LOG(" GetAsciiStrAsync: Not enough memory\n"); + USB_LOG("__CtrlMsgInt failed %d\n"); + USB_LOG("GetDescrCb returned: %d\n"); + USB_LOG("GetDevDescr\n"); + USB_LOG("GetDevDescr: Not enough memory\n"); + USB_LOG("GetDevDescr: %d\n"); + USB_LOG("GetDevDescr - _GetDescrCb\n"); + USB_LOG("GetDevDescrAsync: Not enough memory\n"); + USB_LOG("DeviceRemovalNotifyAsync\n"); +#if SDK_AUG2010 + USB_LOG("packet %u too big: %u\n"); + USB_LOG("Invalid parameters for ISO transfer request\n"); + USB_LOG("IUSB_IsoMsgAsync: Not enough memory\n"); + USB_LOG("Open(%s) failed\n"); + USB_LOG("Invalid path or devClass in insertion notification call\n"); +#endif +} + +#if SDK_AUG2010 +void IUSB_RegisterInsertionNotifyWithIdAsync() { + USB_LOG("%s: Not enough memory\n", __FUNCTION__); + USB_LOG("Failed to open %s: %d\n"); +} +#endif