mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-05 10:52:15 +02:00
usbComms: Auto allocate interface number.
This commit is contained in:
parent
7a4757ca67
commit
7871ecbc33
@ -214,7 +214,8 @@ Result usbDsGetDsInterface(UsbDsInterface** out, struct usb_interface_descriptor
|
|||||||
Result usbDsSetVidPidBcd(const UsbDsDeviceInfo* deviceinfo);
|
Result usbDsSetVidPidBcd(const UsbDsDeviceInfo* deviceinfo);
|
||||||
|
|
||||||
/// Added in 5.0.0
|
/// Added in 5.0.0
|
||||||
Result usbDsRegisterInterface(UsbDsInterface** out, u32 intf_num);
|
Result usbDsRegisterInterface(UsbDsInterface** out);
|
||||||
|
Result usbDsRegisterInterfaceEx(UsbDsInterface** out, u32 intf_num);
|
||||||
Result usbDsClearDeviceData(void);
|
Result usbDsClearDeviceData(void);
|
||||||
Result usbDsAddUsbStringDescriptor(u8* out_index, const char* string);
|
Result usbDsAddUsbStringDescriptor(u8* out_index, const char* string);
|
||||||
Result usbDsAddUsbLanguageStringDescriptor(u8* out_index, const u16* lang_ids, u16 num_langs);
|
Result usbDsAddUsbLanguageStringDescriptor(u8* out_index, const u16* lang_ids, u16 num_langs);
|
||||||
|
@ -212,13 +212,12 @@ static Result _usbCommsInterfaceInit(u32 intf_ind, const UsbCommsInterfaceInfo *
|
|||||||
static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo *info)
|
static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo *info)
|
||||||
{
|
{
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
u32 ep_num = intf_ind + 1;
|
|
||||||
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
||||||
|
|
||||||
struct usb_interface_descriptor interface_descriptor = {
|
struct usb_interface_descriptor interface_descriptor = {
|
||||||
.bLength = USB_DT_INTERFACE_SIZE,
|
.bLength = USB_DT_INTERFACE_SIZE,
|
||||||
.bDescriptorType = USB_DT_INTERFACE,
|
.bDescriptorType = USB_DT_INTERFACE,
|
||||||
.bInterfaceNumber = intf_ind,
|
.bInterfaceNumber = 4,
|
||||||
.bNumEndpoints = 2,
|
.bNumEndpoints = 2,
|
||||||
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
|
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
|
||||||
.bInterfaceSubClass = USB_CLASS_VENDOR_SPEC,
|
.bInterfaceSubClass = USB_CLASS_VENDOR_SPEC,
|
||||||
@ -229,7 +228,7 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
struct usb_endpoint_descriptor endpoint_descriptor_in = {
|
struct usb_endpoint_descriptor endpoint_descriptor_in = {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = USB_ENDPOINT_IN + ep_num,
|
.bEndpointAddress = USB_ENDPOINT_IN,
|
||||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||||
.wMaxPacketSize = 0x40,
|
.wMaxPacketSize = 0x40,
|
||||||
};
|
};
|
||||||
@ -237,7 +236,7 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = USB_ENDPOINT_OUT + ep_num,
|
.bEndpointAddress = USB_ENDPOINT_OUT,
|
||||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||||
.wMaxPacketSize = 0x40,
|
.wMaxPacketSize = 0x40,
|
||||||
};
|
};
|
||||||
@ -268,9 +267,13 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
|
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc)) return rc;
|
||||||
|
|
||||||
rc = usbDsRegisterInterface(&interface->interface, interface_descriptor.bInterfaceNumber);
|
rc = usbDsRegisterInterface(&interface->interface);
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc)) return rc;
|
||||||
|
|
||||||
|
interface_descriptor.bInterfaceNumber = interface->interface->interface_index;
|
||||||
|
endpoint_descriptor_in.bEndpointAddress += interface_descriptor.bInterfaceNumber + 1;
|
||||||
|
endpoint_descriptor_out.bEndpointAddress += interface_descriptor.bInterfaceNumber + 1;
|
||||||
|
|
||||||
// Full Speed Config
|
// Full Speed Config
|
||||||
rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &interface_descriptor, USB_DT_INTERFACE_SIZE);
|
rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &interface_descriptor, USB_DT_INTERFACE_SIZE);
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc)) return rc;
|
||||||
@ -320,7 +323,6 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
static Result _usbCommsInterfaceInit1x(u32 intf_ind, const UsbCommsInterfaceInfo *info)
|
static Result _usbCommsInterfaceInit1x(u32 intf_ind, const UsbCommsInterfaceInfo *info)
|
||||||
{
|
{
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
u32 ep_num = intf_ind + 1;
|
|
||||||
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
||||||
|
|
||||||
struct usb_interface_descriptor interface_descriptor = {
|
struct usb_interface_descriptor interface_descriptor = {
|
||||||
@ -336,7 +338,7 @@ static Result _usbCommsInterfaceInit1x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
struct usb_endpoint_descriptor endpoint_descriptor_in = {
|
struct usb_endpoint_descriptor endpoint_descriptor_in = {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = USB_ENDPOINT_IN + ep_num,
|
.bEndpointAddress = USB_ENDPOINT_IN,
|
||||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||||
.wMaxPacketSize = 0x200,
|
.wMaxPacketSize = 0x200,
|
||||||
};
|
};
|
||||||
@ -344,7 +346,7 @@ static Result _usbCommsInterfaceInit1x(u32 intf_ind, const UsbCommsInterfaceInfo
|
|||||||
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
||||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||||
.bDescriptorType = USB_DT_ENDPOINT,
|
.bDescriptorType = USB_DT_ENDPOINT,
|
||||||
.bEndpointAddress = USB_ENDPOINT_OUT + ep_num,
|
.bEndpointAddress = USB_ENDPOINT_OUT,
|
||||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||||
.wMaxPacketSize = 0x200,
|
.wMaxPacketSize = 0x200,
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@ Result usbDsInitialize(void)
|
|||||||
rc = _usbDsGetEvent(&g_usbDsSrv, &g_usbDsStateChangeEvent, 3);
|
rc = _usbDsGetEvent(&g_usbDsSrv, &g_usbDsStateChangeEvent, 3);
|
||||||
|
|
||||||
// Result code doesn't matter here, users can call themselves later, too. This prevents foot shooting.
|
// Result code doesn't matter here, users can call themselves later, too. This prevents foot shooting.
|
||||||
if (R_SUCCEEDED(rc))
|
if (R_SUCCEEDED(rc) && kernelAbove500())
|
||||||
usbDsClearDeviceData();
|
usbDsClearDeviceData();
|
||||||
|
|
||||||
if (R_FAILED(rc))
|
if (R_FAILED(rc))
|
||||||
@ -88,24 +88,6 @@ static UsbDsInterface* _usbDsTryAllocateInterface(u32 num) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UsbDsInterface* _usbDsAllocateInterface(void)
|
|
||||||
{
|
|
||||||
u32 pos;
|
|
||||||
UsbDsInterface* ptr = NULL;
|
|
||||||
|
|
||||||
for(pos=0; pos<TOTAL_INTERFACES; pos++)
|
|
||||||
{
|
|
||||||
ptr = &g_usbDsInterfaceTable[pos];
|
|
||||||
if(ptr->initialized)continue;
|
|
||||||
memset(ptr, 0, sizeof(UsbDsInterface));
|
|
||||||
ptr->initialized = true;
|
|
||||||
ptr->interface_index = pos;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UsbDsEndpoint* _usbDsAllocateEndpoint(UsbDsInterface* interface)
|
static UsbDsEndpoint* _usbDsAllocateEndpoint(UsbDsInterface* interface)
|
||||||
{
|
{
|
||||||
u32 pos;
|
u32 pos;
|
||||||
@ -540,13 +522,31 @@ static Result _usbDsGetReport(Service* srv, u64 cmd_id, UsbDsReportData *out) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result usbDsGetDsInterface(UsbDsInterface** interface, struct usb_interface_descriptor* descriptor, const char *interface_name)
|
Result usbDsGetDsInterface(UsbDsInterface** interface, struct usb_interface_descriptor* _descriptor, const char *interface_name)
|
||||||
{
|
{
|
||||||
UsbDsInterface* ptr = _usbDsAllocateInterface();
|
struct usb_interface_descriptor send_desc = *_descriptor;
|
||||||
if(ptr == NULL)
|
Service srv;
|
||||||
|
Result rc;
|
||||||
|
for (unsigned int i = 0; i < TOTAL_INTERFACES; i++) {
|
||||||
|
send_desc.bInterfaceNumber = i;
|
||||||
|
rc = _usbDsGetSession(&g_usbDsSrv, &srv, 2, &send_desc, USB_DT_INTERFACE_SIZE, interface_name, strlen(interface_name)+1);
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbDsInterface* ptr = _usbDsTryAllocateInterface(send_desc.bInterfaceNumber);
|
||||||
|
if(ptr == NULL) {
|
||||||
|
serviceClose(&srv);
|
||||||
|
_usbDsFreeInterface(ptr);
|
||||||
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
}
|
||||||
Result rc = _usbDsGetSession(&g_usbDsSrv, &ptr->h, 2, descriptor, sizeof(struct usb_interface_descriptor), interface_name, strlen(interface_name)+1);
|
|
||||||
|
ptr->h = srv;
|
||||||
|
|
||||||
// GetSetupEvent
|
// GetSetupEvent
|
||||||
if (R_SUCCEEDED(rc))
|
if (R_SUCCEEDED(rc))
|
||||||
@ -567,7 +567,80 @@ Result usbDsGetDsInterface(UsbDsInterface** interface, struct usb_interface_desc
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result usbDsRegisterInterface(UsbDsInterface** interface, u32 intf_num)
|
Result usbDsRegisterInterface(UsbDsInterface** interface)
|
||||||
|
{
|
||||||
|
Service srv;
|
||||||
|
Result rc;
|
||||||
|
u32 intf_num;
|
||||||
|
for (intf_num = 0; intf_num < TOTAL_INTERFACES; intf_num++) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 intf_num;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 2;
|
||||||
|
raw->intf_num = intf_num;
|
||||||
|
|
||||||
|
rc = serviceIpcDispatch(&g_usbDsSrv);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcParsedCommand r;
|
||||||
|
ipcParse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
serviceCreate(&srv, r.Handles[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbDsInterface* ptr = _usbDsTryAllocateInterface(intf_num);
|
||||||
|
if(ptr == NULL) {
|
||||||
|
serviceClose(&srv);
|
||||||
|
_usbDsFreeInterface(ptr);
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr->h = srv;
|
||||||
|
|
||||||
|
// GetSetupEvent
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = _usbDsGetEvent(&ptr->h, &ptr->SetupEvent, 1);
|
||||||
|
// GetCtrlInCompletionEvent
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = _usbDsGetEvent(&ptr->h, &ptr->CtrlInCompletionEvent, 7);
|
||||||
|
// GetCtrlOutCompletionEvent
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = _usbDsGetEvent(&ptr->h, &ptr->CtrlOutCompletionEvent, 9);
|
||||||
|
|
||||||
|
if (R_FAILED(rc))
|
||||||
|
_usbDsFreeInterface(ptr);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
*interface = ptr;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result usbDsRegisterInterfaceEx(UsbDsInterface** interface, u32 intf_num)
|
||||||
{
|
{
|
||||||
UsbDsInterface* ptr = _usbDsTryAllocateInterface(intf_num);
|
UsbDsInterface* ptr = _usbDsTryAllocateInterface(intf_num);
|
||||||
if(ptr == NULL)
|
if(ptr == NULL)
|
||||||
@ -625,6 +698,7 @@ Result usbDsRegisterInterface(UsbDsInterface** interface, u32 intf_num)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result usbDsClearDeviceData(void) {
|
Result usbDsClearDeviceData(void) {
|
||||||
return _usbDsCmdNoParams(&g_usbDsSrv, 5);
|
return _usbDsCmdNoParams(&g_usbDsSrv, 5);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user