revolution/usb matching for Wii+Shield (#3085)

This commit is contained in:
Max Roncace
2026-02-07 07:33:54 -05:00
committed by GitHub
parent 6ad0254bbc
commit 8609826deb
11 changed files with 714 additions and 9 deletions
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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:
+2 -2
View File
@@ -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
+6
View File
@@ -1880,6 +1880,12 @@ config.libs = [
Object(NonMatching, "revolution/euart/euart.c"),
],
),
RevolutionLib(
"usb",
[
Object(Matching, "revolution/usb/usb.c"),
],
),
RevolutionLib(
"gd",
[
+55
View File
@@ -0,0 +1,55 @@
#ifndef _REVOLUTION_USB_H_
#define _REVOLUTION_USB_H_
#include <revolution.h>
#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_
+42
View File
@@ -0,0 +1,42 @@
#ifndef _REVOLUTION_USB_PRIVATE_H_
#define _REVOLUTION_USB_PRIVATE_H_
#include <revolution/usb.h>
#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_ */
+602
View File
@@ -0,0 +1,602 @@
#include <revolution/usb.h>
#include <revolution/usb/__usb.h>
#include <private/iosrestypes.h>
#include <private/iostypes.h>
#include <revolution.h>
#include <revolution/ipc.h>
#include <revolution/mem.h>
#include <revolution/os/OSInterrupt.h>
#include <cstdio>
#include <cstring>
#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