Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement retrieving the USB reportDescriptor & it's size #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions gc/ogc/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
63 changes: 58 additions & 5 deletions libogc/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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) */