usbComms: Auto allocate interface number.

This commit is contained in:
Michael Scire 2018-10-11 02:16:11 -07:00
parent 7a4757ca67
commit 7871ecbc33
3 changed files with 112 additions and 35 deletions

View File

@ -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);

View File

@ -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,
}; };

View File

@ -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);
} }