From 761a397066b2a17a53d7c741067ba2673b354a3f Mon Sep 17 00:00:00 2001 From: Harrison <53527582+HTV04@users.noreply.github.com> Date: Mon, 30 May 2022 02:42:24 -0400 Subject: [PATCH] Implement retrieving the USB reportDescriptor & it's size Based on https://github.com/devkitPro/libogc/commit/b51c517423ea4418bb07a38bd9ee2e4880508b34 Co-Authored-By: DacoTaco <12701306+DacoTaco@users.noreply.github.com> --- gc/ogc/usb.h | 5 +++++ libogc/usb.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/gc/ogc/usb.h b/gc/ogc/usb.h index 264dff45..022dfe0b 100644 --- a/gc/ogc/usb.h +++ b/gc/ogc/usb.h @@ -12,7 +12,9 @@ #define USB_FAILED 1 #define USB_CLASS_HID 0x03 +#define USB_SUBCLASS_NONE 0x00 #define USB_SUBCLASS_BOOT 0x01 +#define USB_PROTOCOL_NONE 0x00 #define USB_PROTOCOL_KEYBOARD 0x01 #define USB_PROTOCOL_MOUSE 0x02 @@ -66,6 +68,7 @@ #define USB_DT_ENDPOINT_SIZE 7 #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ #define USB_DT_HID_SIZE 9 +#define USB_DT_MINREPORT_SIZE 8 #define USB_DT_HUB_NONVAR_SIZE 7 /* control message request type bitmask */ @@ -190,6 +193,8 @@ void USB_FreeDescriptors(usb_devdesc *udd); s32 USB_GetGenericDescriptor(s32 fd,u8 type,u8 index,u8 interface,void *data,u32 size); s32 USB_GetHIDDescriptor(s32 fd,u8 interface,usb_hiddesc *uhd,u32 size); +s32 USB_GetReportDescriptorSize(s32 fd, u8 interface); +s32 USB_GetReportDescriptor(s32 fd, u8 interface, void* data, u16 size); s32 USB_GetDeviceDescription(s32 fd,usb_devdesc *devdesc); s32 USB_DeviceRemovalNotifyAsync(s32 fd,usbcallback cb,void *userdata); diff --git a/libogc/usb.c b/libogc/usb.c index 211d50ef..33808e67 100644 --- a/libogc/usb.c +++ b/libogc/usb.c @@ -64,8 +64,10 @@ distribution. #define USBV0_IOCTL_DEVREMOVALHOOK 26 #define USBV0_IOCTL_DEVINSERTHOOK 27 #define USBV0_IOCTL_DEVICECLASSCHANGE 28 +#define USBV0_IOCTL_RESETDEVICE 29 #define USBV4_IOCTL_GETVERSION 6 // returns 0x40001 +#define USBV4_IOCTL_CANCELINTERRUPT 8 #define USBV5_IOCTL_GETVERSION 0 // should return 0x50001 #define USBV5_IOCTL_GETDEVICECHANGE 1 @@ -1083,6 +1085,41 @@ s32 USB_GetHIDDescriptor(s32 fd,u8 interface,usb_hiddesc *uhd,u32 size) return retval; } +s32 USB_GetReportDescriptorSize(s32 fd, u8 interface) +{ + //Retrieve complete HID descriptor + //in testing it was always 9 bytes, but in the HID specifications it says it can be more (if the device has more than 1 descriptor). + //currently we only support 1 thou + usb_hiddesc hiddesc; + s32 retval = USB_GetHIDDescriptor(fd, interface, &hiddesc, USB_DT_HID_SIZE); + + if(retval < 0) + return retval; + + if(hiddesc.bLength > USB_DT_HID_SIZE) + return -1; + + retval = -2; + for(int i = 0; i < hiddesc.bNumDescriptors; i++) + { + if(hiddesc.descr[i].bDescriptorType == USB_DT_REPORT) + { + retval = hiddesc.descr[i].wDescriptorLength; + break; + } + } + + return retval; +} + +s32 USB_GetReportDescriptor(s32 fd, u8 interface, void* data, u16 size) +{ + if (data == NULL || size < USB_DT_MINREPORT_SIZE) + return IPC_EINVAL; + + return USB_GetGenericDescriptor(fd, USB_DT_REPORT, 0, interface, data, size); +} + void USB_FreeDescriptors(usb_devdesc *udd) { int iConf, iInterface; @@ -1430,7 +1467,7 @@ s32 USB_SetAlternativeInterface(s32 fd, u8 interface, u8 alternateSetting) return __usb_control_message(fd, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_INTERFACE), USB_REQ_SETINTERFACE, alternateSetting, interface, 0, NULL, NULL, NULL); } -static s32 USBV5_CancelEndpoint(s32 device_id, u8 endpoint) +static s32 USBV5_CancelEndpoint(s32 device_id) { s32 ret; s32 fd; @@ -1446,19 +1483,35 @@ static s32 USBV5_CancelEndpoint(s32 device_id, u8 endpoint) if (buf==NULL) return IPC_ENOMEM; buf[0] = device_id; - buf[2] = endpoint; + + //Cancel all control messages + buf[2] = 0x00; ret = IOS_Ioctl(fd, USBV5_IOCTL_CANCELENDPOINT, buf, 32, NULL, 0); - iosFree(hId, buf); + if(ret < 0) + goto ret; + + //Cancel all incoming interrupts + buf[2] = 0x01 << 24; + ret = IOS_Ioctl(fd, USBV5_IOCTL_CANCELENDPOINT, buf, 32, NULL, 0); + if(ret < 0) + goto ret; + //Cancel all outgoing interrupts + buf[2] = 0x02 << 24; + ret = IOS_Ioctl(fd, USBV5_IOCTL_CANCELENDPOINT, buf, 32, NULL, 0); + if(ret < 0) + goto ret; + +ret: + iosFree(hId, buf); return ret; } s32 USB_ClearHalt(s32 fd, u8 endpoint) { if (fd>=0x20 || fd<-1) - return USBV5_CancelEndpoint(fd, endpoint); + return USBV5_CancelEndpoint(fd); return __usb_control_message(fd, (USB_CTRLTYPE_DIR_HOST2DEVICE | USB_CTRLTYPE_TYPE_STANDARD | USB_CTRLTYPE_REC_ENDPOINT), USB_REQ_CLEARFEATURE, USB_FEATURE_ENDPOINT_HALT, endpoint, 0, NULL, NULL, NULL); } #endif /* defined(HW_RVL) */ -