mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Updated usbhs comments and store the interface ID in UsbHsClientIfSession. Added: usbHsIfSetInterface, usbHsIfGetInterface, usbHsIfGetAlternateInterface, usbHsIfGetCurrentFrame, and usbHsIfResetDevice.
This commit is contained in:
parent
83dfc58adb
commit
2049ff081d
@ -87,6 +87,7 @@ typedef struct {
|
|||||||
Service s;
|
Service s;
|
||||||
Event event0; ///< Unknown.
|
Event event0; ///< Unknown.
|
||||||
Event eventCtrlXfer; ///< [2.0.0+] Signaled when CtrlXferAsync finishes.
|
Event eventCtrlXfer; ///< [2.0.0+] Signaled when CtrlXferAsync finishes.
|
||||||
|
s32 ID;
|
||||||
|
|
||||||
UsbHsInterface inf; ///< Initialized with the input interface from \ref usbHsAcquireUsbIf, then the first 0x1B8-bytes are overwritten with the cmd output (data before pathstr).
|
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;
|
} UsbHsClientIfSession;
|
||||||
@ -105,7 +106,7 @@ void usbHsExit(void);
|
|||||||
Event* usbHsGetInterfaceStateChangeEvent(void);
|
Event* usbHsGetInterfaceStateChangeEvent(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns an array of all \ref UsbHsInterface. Internally this loads the same interfaces as \ref usbHsQueryAvailableInterfaces, followed by \ref usbHsQueryAcquiredInterfaces.
|
* @brief Returns an array of all \ref UsbHsInterface. Internally this loads the same interfaces as \ref usbHsQueryAvailableInterfaces, followed by \ref usbHsQueryAcquiredInterfaces. However, ID in \ref UsbHsInterface is set to -1, hence the output from this should not be used with \ref usbHsAcquireUsbIf.
|
||||||
* @param[in] filter \ref UsbHsInterfaceFilter.
|
* @param[in] filter \ref UsbHsInterfaceFilter.
|
||||||
* @param[out] interfaces Array of output interfaces.
|
* @param[out] interfaces Array of output interfaces.
|
||||||
* @param[in] interfaces_maxsize Max byte-size of the interfaces buffer.
|
* @param[in] interfaces_maxsize Max byte-size of the interfaces buffer.
|
||||||
@ -147,7 +148,7 @@ Result usbHsCreateInterfaceAvailableEvent(Event* event, bool autoclear, u8 index
|
|||||||
Result usbHsDestroyInterfaceAvailableEvent(Event* event, u8 index);
|
Result usbHsDestroyInterfaceAvailableEvent(Event* event, u8 index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Acquires/opens the specified interface.
|
* @brief Acquires/opens the specified interface. This returns an error if the interface was already acquired by another process.
|
||||||
* @param[in] s The service object.
|
* @param[in] s The service object.
|
||||||
* @param[in] interface Interface to use.
|
* @param[in] interface Interface to use.
|
||||||
*/
|
*/
|
||||||
@ -158,3 +159,32 @@ Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface);
|
|||||||
/// Closes the specified interface session.
|
/// Closes the specified interface session.
|
||||||
void usbHsIfClose(UsbHsClientIfSession* s);
|
void usbHsIfClose(UsbHsClientIfSession* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Selects an interface.
|
||||||
|
* @param[in] s The service object.
|
||||||
|
* @param[out] inf The output interface info. If NULL, the output is stored within s instead.
|
||||||
|
* @param[in] id ID
|
||||||
|
*/
|
||||||
|
Result usbHsIfSetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets an interface.
|
||||||
|
* @param[in] s The service object.
|
||||||
|
* @param[out] inf The output interface info. If NULL, the output is stored within s instead.
|
||||||
|
*/
|
||||||
|
Result usbHsIfGetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets an alternate interface.
|
||||||
|
* @param[in] s The service object.
|
||||||
|
* @param[out] inf The output interface info. If NULL, the output is stored within s instead.
|
||||||
|
* @param[in] id ID
|
||||||
|
*/
|
||||||
|
Result usbHsIfGetAlternateInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id);
|
||||||
|
|
||||||
|
/// On 1.0.0 this is stubbed, just returns 0 with out=0.
|
||||||
|
Result usbHsIfGetCurrentFrame(UsbHsClientIfSession* s, u32* out);
|
||||||
|
|
||||||
|
/// Resets the device: has the same affect as unplugging the device and plugging it back in.
|
||||||
|
Result usbHsIfResetDevice(UsbHsClientIfSession* s);
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface) {
|
|||||||
|
|
||||||
memset(s, 0, sizeof(UsbHsClientIfSession));
|
memset(s, 0, sizeof(UsbHsClientIfSession));
|
||||||
memcpy(&s->inf, interface, sizeof(UsbHsInterface));
|
memcpy(&s->inf, interface, sizeof(UsbHsInterface));
|
||||||
|
s->ID = interface->inf.ID;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -310,7 +311,7 @@ Result usbHsAcquireUsbIf(UsbHsClientIfSession* s, UsbHsInterface *interface) {
|
|||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = kernelAbove200() ? 7 : 6;
|
raw->cmd_id = kernelAbove200() ? 7 : 6;
|
||||||
raw->ID = interface->inf.ID;
|
raw->ID = s->ID;
|
||||||
|
|
||||||
Result rc = serviceIpcDispatch(&g_usbHsSrv);
|
Result rc = serviceIpcDispatch(&g_usbHsSrv);
|
||||||
|
|
||||||
@ -352,3 +353,152 @@ void usbHsIfClose(UsbHsClientIfSession* s) {
|
|||||||
memset(s, 0, sizeof(UsbHsClientIfSession));
|
memset(s, 0, sizeof(UsbHsClientIfSession));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result _usbHsIfGetInf(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id, u64 cmd_id) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
if (inf==NULL) inf = &s->inf.inf;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u8 id;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcAddRecvBuffer(&c, inf, sizeof(UsbHsInterfaceInfo), BufferType_Normal);
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = cmd_id;
|
||||||
|
raw->id = id;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&s->s);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(&s->s, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbHsIfSetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id) {
|
||||||
|
return _usbHsIfGetInf(s, inf, id, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbHsIfGetAlternateInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf, u8 id) {
|
||||||
|
return _usbHsIfGetInf(s, inf, id, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbHsIfGetInterface(UsbHsClientIfSession* s, UsbHsInterfaceInfo* inf) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
if (inf==NULL) inf = &s->inf.inf;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
ipcAddRecvBuffer(&c, inf, sizeof(UsbHsInterfaceInfo), BufferType_Normal);
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 2;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&s->s);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(&s->s, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbHsIfGetCurrentFrame(UsbHsClientIfSession* s, u32* out) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = kernelAbove200() ? 4 : 5;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&s->s);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u32 out;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(&s->s, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc) && out) *out = resp->out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbHsIfResetDevice(UsbHsClientIfSession* s) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = serviceIpcPrepareHeader(&s->s, &c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 8;
|
||||||
|
|
||||||
|
Result rc = serviceIpcDispatch(&s->s);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp;
|
||||||
|
|
||||||
|
serviceIpcParse(&s->s, &r, sizeof(*resp));
|
||||||
|
resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user