From 3afa53272a6397b66a8128d409d692281213eb49 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Fri, 2 May 2008 14:16:26 +0200 Subject: [PATCH] actually parsing the device descriptors now --- usbstorage.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/usbstorage.c b/usbstorage.c index 8998fdd..ae70f81 100644 --- a/usbstorage.c +++ b/usbstorage.c @@ -31,24 +31,30 @@ distribution. #include "usbstorage.h" -#define HEAP_SIZE 4096 -#define TAG_START 0x0BADC0DE +#define HEAP_SIZE 4096 +#define TAG_START 0x0BADC0DE -#define CBW_SIZE 31 -#define CBW_SIGNATURE 0x43425355 -#define CBW_IN (1 << 7) -#define CBW_OUT 0 +#define CBW_SIZE 31 +#define CBW_SIGNATURE 0x43425355 +#define CBW_IN (1 << 7) +#define CBW_OUT 0 -#define CSW_SIZE 13 -#define CSW_SIGNATURE 0x53425355 +#define CSW_SIZE 13 +#define CSW_SIGNATURE 0x53425355 -#define SCSI_TEST_UNIT_READY 0x00 -#define SCSI_REQUEST_SENSE 0x03 -#define SCSI_READ_CAPACITY 0x25 -#define SCSI_READ_10 0x28 -#define SCSI_WRITE_10 0x2A +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_READ_CAPACITY 0x25 +#define SCSI_READ_10 0x28 +#define SCSI_WRITE_10 0x2A -#define SCSI_SENSE_REPLY_SIZE 18 +#define SCSI_SENSE_REPLY_SIZE 18 + +#define USB_CLASS_MASS_STORAGE 0x08 +#define MASS_STORAGE_SCSI_COMMANDS 0x06 +#define MASS_STORAGE_BULK_ONLY 0x50 + +#define USB_ENDPOINT_BULK 0x02 #ifdef DEBUG #include @@ -454,6 +460,12 @@ usbstorage_handle *USBStorage_Open(const char *bus, u16 vid, u16 pid) u8 status = 0; s32 retval = -1; + u32 iConf, iInterface, iEp; + _usb_devdesc udd; + usb_configurationdesc *ucd; + usb_interfacedesc *uid; + usb_endpointdesc *ued; + dev = calloc(1, sizeof(*dev)); if(dev == NULL) { @@ -473,13 +485,59 @@ usbstorage_handle *USBStorage_Open(const char *bus, u16 vid, u16 pid) sense = iosAlloc(hId, SCSI_SENSE_REPLY_SIZE); if(sense == NULL) goto free_and_return; - - // TODO: parse descriptors here - dev->ep_in = 0x81; - dev->ep_in_size = 64; - dev->ep_out = 0x02; - dev->ep_out_size = 64; + retval = USB_GetDescriptors(dev->usb_fd, &udd); + if(retval < 0) + goto free_and_return; + + for(iConf = 0; iConf < udd.bNumConfigurations; iConf++) + { + ucd = &udd.configurations[iConf]; + for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) + { + uid = &ucd->interfaces[iInterface]; + if(uid->bInterfaceClass == USB_CLASS_MASS_STORAGE && + uid->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS && + uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY) + { + if(uid->bNumEndpoints < 2) + continue; + + dev->ep_in = dev->ep_in_size = dev->ep_out = dev->ep_out_size = 0; + for(iEp = 0; iEp < uid->bNumEndpoints; iEp++) + { + ued = &uid->endpoints[iEp]; + if(ued->bmAttributes != USB_ENDPOINT_BULK) + continue; + + if(ued->bEndpointAddress & USB_ENDPOINT_IN) + { + dev->ep_in = ued->bEndpointAddress; + dev->ep_in_size = ued->wMaxPacketSize; + } + else + { + dev->ep_out = ued->bEndpointAddress; + dev->ep_out_size = ued->wMaxPacketSize; + } + } + if(dev->ep_in != 0 && dev->ep_out != 0) + { + dev->configuration = ucd->bConfigurationValue; + dev->interface = uid->bInterfaceNumber; + dev->altInterface = uid->bAlternateSetting; + goto found; + } + } + } + } + + USB_FreeDescriptors(&udd); + goto free_and_return; + + found: + USB_FreeDescriptors(&udd); + /* some devices needs this (TEST_UNIT_READY -> REQUEST_SENSE * to be working... */ memset(cmd, 0, sizeof(cmd)); -- 2.11.4.GIT