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);
|
||||
|
||||
/// 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 usbDsAddUsbStringDescriptor(u8* out_index, const char* string);
|
||||
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)
|
||||
{
|
||||
Result rc = 0;
|
||||
u32 ep_num = intf_ind + 1;
|
||||
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
||||
|
||||
struct usb_interface_descriptor interface_descriptor = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = intf_ind,
|
||||
.bInterfaceNumber = 4,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = 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 = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_ENDPOINT_IN + ep_num,
|
||||
.bEndpointAddress = USB_ENDPOINT_IN,
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 0x40,
|
||||
};
|
||||
@ -237,7 +236,7 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
||||
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_ENDPOINT_OUT + ep_num,
|
||||
.bEndpointAddress = USB_ENDPOINT_OUT,
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 0x40,
|
||||
};
|
||||
@ -268,9 +267,13 @@ static Result _usbCommsInterfaceInit5x(u32 intf_ind, const UsbCommsInterfaceInfo
|
||||
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
rc = usbDsRegisterInterface(&interface->interface, interface_descriptor.bInterfaceNumber);
|
||||
rc = usbDsRegisterInterface(&interface->interface);
|
||||
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
|
||||
rc = usbDsInterface_AppendConfigurationData(interface->interface, UsbDeviceSpeed_Full, &interface_descriptor, USB_DT_INTERFACE_SIZE);
|
||||
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)
|
||||
{
|
||||
Result rc = 0;
|
||||
u32 ep_num = intf_ind + 1;
|
||||
usbCommsInterface *interface = &g_usbCommsInterfaces[intf_ind];
|
||||
|
||||
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 = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_ENDPOINT_IN + ep_num,
|
||||
.bEndpointAddress = USB_ENDPOINT_IN,
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 0x200,
|
||||
};
|
||||
@ -344,7 +346,7 @@ static Result _usbCommsInterfaceInit1x(u32 intf_ind, const UsbCommsInterfaceInfo
|
||||
struct usb_endpoint_descriptor endpoint_descriptor_out = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = USB_ENDPOINT_OUT + ep_num,
|
||||
.bEndpointAddress = USB_ENDPOINT_OUT,
|
||||
.bmAttributes = USB_TRANSFER_TYPE_BULK,
|
||||
.wMaxPacketSize = 0x200,
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ Result usbDsInitialize(void)
|
||||
rc = _usbDsGetEvent(&g_usbDsSrv, &g_usbDsStateChangeEvent, 3);
|
||||
|
||||
// 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();
|
||||
|
||||
if (R_FAILED(rc))
|
||||
@ -88,24 +88,6 @@ static UsbDsInterface* _usbDsTryAllocateInterface(u32 num) {
|
||||
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)
|
||||
{
|
||||
u32 pos;
|
||||
@ -540,13 +522,31 @@ static Result _usbDsGetReport(Service* srv, u64 cmd_id, UsbDsReportData *out) {
|
||||
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();
|
||||
if(ptr == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
|
||||
struct usb_interface_descriptor send_desc = *_descriptor;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Result rc = _usbDsGetSession(&g_usbDsSrv, &ptr->h, 2, descriptor, sizeof(struct usb_interface_descriptor), interface_name, strlen(interface_name)+1);
|
||||
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);
|
||||
}
|
||||
|
||||
ptr->h = srv;
|
||||
|
||||
// GetSetupEvent
|
||||
if (R_SUCCEEDED(rc))
|
||||
@ -567,7 +567,80 @@ Result usbDsGetDsInterface(UsbDsInterface** interface, struct usb_interface_desc
|
||||
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);
|
||||
if(ptr == NULL)
|
||||
@ -625,6 +698,7 @@ Result usbDsRegisterInterface(UsbDsInterface** interface, u32 intf_num)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Result usbDsClearDeviceData(void) {
|
||||
return _usbDsCmdNoParams(&g_usbDsSrv, 5);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user