From: Johannes E. <joh...@er...> - 2002-01-06 17:33:42
|
On Sun, Jan 06, 2002, je...@un... <je...@un...> wrote: > I recently bought a SanDisk USB SmartMedia reader, model SDDR-55, thinking > it would "just work" under linux with the usb-storage support. Well, it > doesn't. > > So now I'm trying to get some use out of it by writing a libusb+nbd driver > so that I can eventually use it as a regular block device under Linux. I'm > using RedHat 7.2's vanilla kernel, and cvs libusb. (gphoto2 sees my camera > just fine with this kernel and libusb) > > I've dumped the interaction between the hardware and Windows using "usb > snoopy" and then tried to write a program using libusb to establish basic > communication with the reader. However, my program fails by reaching a > timeout in the first usb_bulk_write() call. > > I wonder whether I'm missing something about the first 3 URBs that I > haven't directly translated into libusb calls. The effect of those > URBs seemed to be to open the device, and set configuration/interfaces, > and I have code to do so... Here, I'll annotate the log the best I can (not too familiar with USB snoopy). > I've attached the code in the hopes that somebody can take a look at it and > quickly see what I've done incorrectly or completely failed to do. > > This is the start of the usbsnoopy log, incluing the first 5 URBs (all that > my program attempts to reproduce): > >>>>>>> URB 1 going down... > -- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: > TransferBufferLength = 00000012 > TransferBuffer = c1ab2630 > TransferBufferMDL = 00000000 > Index = 00 > DescriptorType = 01 (USB_DEVICE_DESCRIPTOR_TYPE) > LanguageId = 0000 > > <<<<<<< URB 1 coming back... > -- URB_FUNCTION_CONTROL_TRANSFER: > PipeHandle = c1ac2a7c > TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000012 > TransferBuffer = c1ab2630 > TransferBufferMDL = c1a9d6d0 > > 0000: > 12 01 10 01 ff 00 00 08 aa 55 03 a1 01 01 01 02 .........U...... > 0010: > 03 01 .. > UrbLink = 00000000 > SetupPacket : 80 06 00 01 00 00 12 00 > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB This looks like Windows doing the first part of the enumeration. > >>>>>>> URB 2 going down... > -- URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: > TransferBufferLength = 00000209 > TransferBuffer = c1abf060 > TransferBufferMDL = 00000000 > Index = 00 > DescriptorType = 02 (USB_CONFIGURATION_DESCRIPTOR_TYPE) > LanguageId = 0000 > > <<<<<<< URB 2 coming back... > -- URB_FUNCTION_CONTROL_TRANSFER: > PipeHandle = c1ac2a7c > TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000020 > TransferBuffer = c1abf060 > TransferBufferMDL = c1a9d6d0 > > 0000: > 09 02 20 00 01 01 00 80 32 09 04 00 00 02 ff 00 ........2....... > 0010: > 00 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 ......@......@.. > UrbLink = 00000000 > SetupPacket : 80 06 00 02 00 00 09 02 > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB This looks like Windows doing the second part of the enumeration. This is handled by Linux and libusb. You shouldn't need to worry about this. > >>>>>>> URB 3 going down... > -- URB_FUNCTION_SELECT_CONFIGURATION: > ConfigurationDescriptor = 0xc1abf060 (configure) > ConfigurationDescriptor : bLength = 0x09 > ConfigurationDescriptor : bDescriptorType = 0x02 > ConfigurationDescriptor : wTotalLength = 0x0020 > ConfigurationDescriptor : bNumInterfaces = 0x01 > ConfigurationDescriptor : bConfigurationValue = 0x01 > ConfigurationDescriptor : iConfiguration = 0x00 > ConfigurationDescriptor : bmAttributes = 0x80 > ConfigurationDescriptor : MaxPower = 0x32 > ConfigurationHandle = 0x00000003 > Interface[0]: Length = 0x00000038 > Interface[0]: InterfaceNumber = 0x00 > Interface[0]: AlternateSetting = 0x00 > > <<<<<<< URB 3 coming back... > -- URB_FUNCTION_SELECT_CONFIGURATION: > ConfigurationDescriptor = 0xc1abf060 (configure) > ConfigurationDescriptor : bLength = 0x09 > ConfigurationDescriptor : bDescriptorType = 0x02 > ConfigurationDescriptor : wTotalLength = 0x0020 > ConfigurationDescriptor : bNumInterfaces = 0x01 > ConfigurationDescriptor : bConfigurationValue = 0x01 > ConfigurationDescriptor : iConfiguration = 0x00 > ConfigurationDescriptor : bmAttributes = 0x80 > ConfigurationDescriptor : MaxPower = 0x32 > ConfigurationHandle = 0xc29aac00 > Interface[0]: Length = 0x00000038 > Interface[0]: InterfaceNumber = 0x00 > Interface[0]: AlternateSetting = 0x00 > Interface[0]: Class = 0xff > Interface[0]: SubClass = 0x00 > Interface[0]: Protocol = 0x00 > Interface[0]: InterfaceHandle = 0xc1ae2120 > Interface[0]: NumberOfPipes = 0x00000002 > Interface[0]: Pipes[0] : MaximumPacketSize = 0x0040 > Interface[0]: Pipes[0] : EndpointAddress = 0x01 > Interface[0]: Pipes[0] : Interval = 0x00 > Interface[0]: Pipes[0] : PipeType = 0x02 (UsbdPipeTypeBulk) > Interface[0]: Pipes[0] : PipeHandle = 0xc1ae2138 > Interface[0]: Pipes[0] : MaxTransferSize = 0x00010000 > Interface[0]: Pipes[0] : PipeFlags = 0x00 > Interface[0]: Pipes[1] : MaximumPacketSize = 0x0040 > Interface[0]: Pipes[1] : EndpointAddress = 0x82 > Interface[0]: Pipes[1] : Interval = 0x00 > Interface[0]: Pipes[1] : PipeType = 0x02 (UsbdPipeTypeBulk) > Interface[0]: Pipes[1] : PipeHandle = 0xc1ae214c > Interface[0]: Pipes[1] : MaxTransferSize = 0x00010000 > Interface[0]: Pipes[1] : PipeFlags = 0x00 > UsbSnoop - IRP_MJ_PNP (IRP_MN_QUERY_CAPABILITIES) > UsbSnoop - IRP_MJ_PNP (IRP_MN_QUERY_PNP_DEVICE_STATE) > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB This looks like either Windows or the driver selecting the config and interface/altsetting Looks like, config 1, interface 0, altsetting 0. > >>>>>>> URB 4 going down... > -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: > PipeHandle = c1ae2138 > TransferFlags = 00000002 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000008 > TransferBuffer = c1acdab6 > TransferBufferMDL = 00000000 > > 0000: > 00 00 00 00 00 b0 00 80 ........ > UrbLink = 00000000 > > <<<<<<< URB 4 coming back... > -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: > PipeHandle = c1ae2138 > TransferFlags = 00000002 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000008 > TransferBuffer = c1acdab6 > TransferBufferMDL = c1a8f9f0 > UrbLink = 00000000 > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB Sending 8 bytes. > >>>>>>> URB 5 going down... > -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: > PipeHandle = c1ae214c > TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000004 > TransferBuffer = c1acdb1d > TransferBufferMDL = 00000000 > UrbLink = 00000000 > > <<<<<<< URB 5 coming back... > -- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: > PipeHandle = c1ae214c > TransferFlags = 00000003 (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) > TransferBufferLength = 00000002 > TransferBuffer = c1acdb1d > TransferBufferMDL = c1a8f9f0 > > 0000: > ff 04 .. > UrbLink = 00000000 > ------------------------------------------------------------------------ Sending 2 bytes. > #include <usb.h> > #include <malloc.h> > #include <stdio.h> > #include <string.h> > #include <errno.h> > > struct usb_device *find_device(struct usb_device *d, int vendor, int product) { > struct usb_device * first; > if(!d) d = usb_busses->devices; > first = d; > > while(1) { > if (d->descriptor.idVendor == vendor > && d->descriptor.idProduct == product) > return d; > if (d->next) d = d->next; > else if (d->bus->next) d = d->bus->next->devices; > else d = usb_busses->devices; > if (d == first) break; > } > return NULL; > } > > #define VENDOR 0x55aa > #define PRODUCT 0xa103 > > int main(void) { > > int r, i; > > struct usb_dev_handle *h; > struct usb_device *dev; > unsigned char buf[0x201]; > usb_init(); > usb_find_busses(); > usb_find_devices(); > > usb_set_debug(2); > dev = find_device(NULL, VENDOR, PRODUCT); > > if(!dev) { > printf("not found"); > return 1; > } > > h = usb_open(dev); > > if(!h) printf("open failed\n"); > > r = usb_set_configuration(h, 1); > if(r<0) return 1; > > r = usb_claim_interface(h, 0); > if(r<0) return 1; > > r = usb_set_altinterface(h, 0); > if(r<0) return 1; > > r = usb_bulk_write(h, 0x1, "\x00\x00\x00\x00\x00\xb0\x00\x80", 8, 5000); > if(r<0) return 1; > > r = usb_bulk_read(h, 0x82, buf, 4, 5000); > if(r==-1) return 1; > > for(i=0; i<r; i++) { > printf("%02x", buf[i]); > if(i % 16 == 15) printf("\n"); > else printf(" "); > } > return 0; > } This all looks good, except you try to read 4 instead of 2, but that shouldn't be a problem. Do you have the same problem if you don't do the set_configuration and set_altinterface? JE |