Hi, Since years now I have tried to find out what's wrong with Mustek USB scanners like the ScanExpress 1200 CU. I would like to know if someone else made similar experience or knows what may be going on here.
Short description: ------------------ I can open the USB device, bulk_read, bulk_write, whatever, do a normal scan without problems. Then I close the device. Under special circumstances after the next open, the first bulk_read (and every bulk_read after that) runs into the timeout (no data transferred). Writing does work, however. Longer description: ------------------- I'm talking about USB scanners like the Mustek ScanExpress 1200 CU, 1200 UB, 600 CU which use the Mustek MA1017 ASIC. This ASIC provides one bulk-in, one bulk-out and an interrupt endpoint: T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 26 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=055f ProdID=0001 Rev= 1.00 C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 64mA I: If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=(none) E: Ad=01(O) Atr=02(Bulk) MxPS= 2 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 1 Ivl=1ms The ASIC communicates by setting registers. Writing to a register just means sending two bytes (byte 1: value, byte 2: register number). Reading is similar: write two bytes (byte 1: ignored, byte 2: register number) and then read the value (one byte). The problem first occured on FreeBSD with the FreeBSD scanner driver (see http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/41281). Basically, you can scan once without problems. The second time the scanner device is opened, the first bulk_read doesn't get any data. Further investigation showed that this happens with FreeBSD, OpenBSD, and NetBSD with libusb or the uscanner (linux-like) kernel scanner driver. It didn't happen with Linux (neither libusb/usbfs nor kernel scanner driver). So I thought it's a BSD USB core bug. Now I found out that I can provoke the problem also with Linux. If I use libusb in it's most basic way, there is no problem. But if I use any of the functions usb_set_configuration(), usb_resetep(), usb_clear_halt(), I get the same problem. The first bulk access after plugging in the device always works. The second always doesn't work. The third sometimes work, the forth may work. And so on. I'll append a test program /for libusb 0.1.6 or later) that just opens the device and tries to read register 2. If I use it unchanged, it works. If I change *any* of the #if 0 to #if 1, the second run of the program runs into the timeout (5 s) of bulk_read. Example (resetep is enabled): :plugging in the scanner : 1. run: usb_init ... done usb_find_busses ... done (result = 2) usb_find_devices ... done (result = 4) checking for devices ... done (device = 0x804f518) usb_open ... done (handle = 0x8050548) usb_claim_interface ... done (result = 0) usb_bulk_write ... done (result = 2) usb_bulk_read ... done (result = 1, read = 128) usb_resetep ... done (result = 0) usb_close ... done :2. run usb_init ... done usb_find_busses ... done (result = 2) usb_find_devices ... done (result = 4) checking for devices ... done (device = 0x804f518) usb_open ... done (handle = 0x8050548) usb_claim_interface ... done (result = 0) usb_bulk_write ... done (result = 2) usb_bulk_read ... :hangs for 5 seconds here done (result = -1, read = 0) :3. run, 4. run both works, 5. run runs into timeout again. This is on Linux 2.4.21-pre3, but I don't think it depend on the kernel. No problems when using the kernel scanner driver. This is with the ohci driver. Also tested on a completely different system (2.4.20) with usb-uhci: similar behaviour. However, in this case, once the error occurs, it will occur with every run after the first one. The Windows 98 driver works without major problems, but I can't test the details like with Linux. Anyone any ideas? Just crappy hardware? But why is the error triggered by a simple function like resetep? Bye, Henning ----------------------- test program: link with -lusb ----------------------- #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <usb.h> int main (int argc, char ** argv) { int n; unsigned char data_field[2]; int result = 0; struct usb_bus *bus; struct usb_device *dev, *device = 0; struct usb_interface_descriptor *interface; usb_dev_handle *handle; fprintf (stderr, "usb_init ... "); usb_init (); fprintf (stderr, "done\n"); fprintf (stderr, "usb_find_busses ... "); result = usb_find_busses (); fprintf (stderr, "done (result = %d)\n", result); fprintf (stderr, "usb_find_devices ... "); result = usb_find_devices (); fprintf (stderr, "done (result = %d)\n", result); fprintf (stderr, "checking for devices ... "); for (bus = usb_busses; bus && !device; bus = bus->next) { for (dev = bus->devices; dev && !device; dev = dev->next) { if (dev->descriptor.idVendor == 0x055f && dev->descriptor.idProduct == 0x0001) device = dev; } } fprintf (stderr, "done (device = %p)\n", device); if (!device) exit (1); fprintf (stderr, "usb_open ... "); handle = usb_open (device); fprintf (stderr, "done (handle = %p)\n", handle); if (!handle) exit (1); #if 0 /* first run works, all later runs don't */ fprintf (stderr, "usb_set_configuration ... "); result = usb_set_configuration (handle, 1); fprintf (stderr, "done (result = %d)\n", result); if (result != 0) exit (1); #endif interface = &device->config[0].interface[0].altsetting[0]; fprintf (stderr, "usb_claim_interface ... "); result = usb_claim_interface (handle, interface->bInterfaceNumber); fprintf (stderr, "done (result = %d)\n", result); if (result != 0) exit (1); /* read register 0x02 */ n = 2; data_field[0] = 0x00; data_field[1] = 0x2 | 0x20; fprintf (stderr, "usb_bulk_write ... "); result = usb_bulk_write (handle, interface->endpoint[0].bEndpointAddress, data_field, n, 5000); fprintf (stderr, "done (result = %d)\n", result); if (result != n) exit (1); n = 1; fprintf (stderr, "usb_bulk_read ... "); result = usb_bulk_read (handle, interface->endpoint[1].bEndpointAddress, data_field, n, 5000); fprintf (stderr, "done (result = %d, read = %d)\n", result, data_field[0]); if (result != n) exit (1); #if 0 /* first run works, second doesn't, third works, forth works, fifth doesn't ... */ fprintf (stderr, "usb_resetep ... "); result = usb_resetep (handle, interface->endpoint[0].bEndpointAddress); fprintf (stderr, "done (result = %d)\n", result); if (result != 0) exit (1); #endif #if 0 /* same as resetep */ fprintf (stderr, "usb_clearhalt ... "); result = usb_clear_halt (handle, interface->endpoint[0].bEndpointAddress); fprintf (stderr, "done (result = %d)\n", result); if (result != 0) exit (1); #endif fprintf (stderr, "usb_close ... "); usb_close (handle); fprintf (stderr, "done\n"); exit (0); } ------------------------------------------------------- This SF.NET email is sponsored by: SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See! http://www.vasoftware.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
