Moved interface-specific data from UsbHsInterface into UsbHsInterfaceInfo. Added usbHsAcquireUsbIf/usbHsIfClose and the related structs.

This commit is contained in:
yellows8 2018-11-29 19:19:27 -05:00
parent f1ba199d1c
commit 83dfc58adb
2 changed files with 94 additions and 1 deletions

View File

@ -41,7 +41,7 @@ typedef struct {
u8 bInterfaceProtocol;
} UsbHsInterfaceFilter;
/// Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface. Descriptors which are not available are set to all-zero.
/// Descriptors which are not available are set to all-zero.
typedef struct {
s32 ID;
u32 deviceID_2;
@ -57,6 +57,11 @@ typedef struct {
u8 pad_x155[0x6];
struct usb_ss_endpoint_companion_descriptor input_ss_endpoint_companion_descs[15]; ///< ?
u8 pad_x1b5[0x3];
} PACKED UsbHsInterfaceInfo;
/// Interface struct. Note that devices have a seperate \ref UsbHsInterface for each interface.
typedef struct {
UsbHsInterfaceInfo inf;
char pathstr[0x40];
u32 busID;
@ -77,6 +82,21 @@ typedef struct {
u64 unk_x10;
} UsbHsXferReport;
/// The interface service object. These Events have autoclear=false.
typedef struct {
Service s;
Event event0; ///< Unknown.
Event eventCtrlXfer; ///< [2.0.0+] Signaled when CtrlXferAsync finishes.
UsbHsInterface inf; ///< Initialized with the input interface from \ref usbHsAcquireUsbIf, then the first 0x1B8-bytes are overwritten with the cmd output (data before pathstr).
} UsbHsClientIfSession;
typedef struct {
Service s;
struct usb_endpoint_descriptor desc;
} UsbHsClientEpSession;
/// Initialize/exit usb:hs.
Result usbHsInitialize(void);
void usbHsExit(void);
@ -126,3 +146,15 @@ Result usbHsCreateInterfaceAvailableEvent(Event* event, bool autoclear, u8 index
*/
Result usbHsDestroyInterfaceAvailableEvent(Event* event, u8 index);
/**
* @brief Acquires/opens the specified interface.
* @param[in] s The service object.
* @param[in] interface Interface to use.
*/
Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface);
/// UsbHsClientIfSession
/// Closes the specified interface session.
void usbHsIfClose(UsbHsClientIfSession* s);

View File

@ -291,3 +291,64 @@ Result usbHsDestroyInterfaceAvailableEvent(Event* event, u8 index) {
return rc;
}
Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface) {
IpcCommand c;
ipcInitialize(&c);
memset(s, 0, sizeof(UsbHsClientIfSession));
memcpy(&s->inf, interface, sizeof(UsbHsInterface));
struct {
u64 magic;
u64 cmd_id;
s32 ID;
} *raw;
ipcAddRecvBuffer(&c, &s->inf.inf, sizeof(UsbHsInterfaceInfo), BufferType_Normal);
raw = serviceIpcPrepareHeader(&g_usbHsSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = kernelAbove200() ? 7 : 6;
raw->ID = interface->inf.ID;
Result rc = serviceIpcDispatch(&g_usbHsSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_usbHsSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreateSubservice(&s->s, &g_usbHsSrv, &r, 0);
}
}
if (R_SUCCEEDED(rc)) {
rc = _usbHsGetEvent(&s->s, &s->event0, 0);
if (kernelAbove200()) rc = _usbHsGetEvent(&s->s, &s->event0, 6);
if (R_FAILED(rc)) {
serviceClose(&s->s);
eventClose(&s->event0);
eventClose(&s->eventCtrlXfer);
}
}
return rc;
}
void usbHsIfClose(UsbHsClientIfSession* s) {
serviceClose(&s->s);
eventClose(&s->event0);
eventClose(&s->eventCtrlXfer);
memset(s, 0, sizeof(UsbHsClientIfSession));
}