Hello, I have used gadgetfs to develop USB gadgets and am mostly happy with it. However, after I upgraded the kernel from 2.6.26 to 2.6.29, my gadget stops working; the client always returns EAGAIN when writing to an endpoint the gadget opens. To see what's going wrong, I tried the original sample http://www.linux-usb.org/gadget/usb.c, and I see the same symptom. Here is a recipe to reproduce: (1) Modify DRIVER_VENDOR_NUM / DRIVER_PRODUCT_NUM to 00FF / 00FF in usb.c to prevent the usbtest driver from being loaded. (2) Compile usb.c with "gcc -o usb usb.c usbstring.c -lpthread", and run it. (3) Compile the attached code with "gcc -o sink-test sink-test.c -lusb", and run it with "sink-test 00FF:00FF". On 2.6.29, sink-test exits with: usb_bulk_write: Resource temporarily unavailable usb_bulk_write: Resource temporarily unavailable usb_bulk_write: Resource temporarily unavailable On 2.6.26, sink-test exits normally.
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <usb.h> int main (int argc, char **argv) { struct usb_device *dev = NULL; struct usb_bus *bus; usb_dev_handle *handle; int vendor_id, product_id, retry = 2; char data[16]; if (argc != 2 || sscanf (argv[1], "%X:%X", &vendor_id, &product_id) < 2) { fprintf (stderr, "Usage: %s VEND:PROD\n", argv[0]); return 1; } usb_init (); usb_set_debug (2); usb_find_busses (); usb_find_devices (); for (bus = usb_busses; bus && !dev; bus = bus->next) for (dev = bus->devices; dev; dev = dev->next) if (dev->descriptor.idVendor == vendor_id && dev->descriptor.idProduct == product_id) break; if (!dev) { fprintf (stderr, "Can't find device %04X:%04X\n", vendor_id, product_id); return 1; } handle = usb_open (dev); if (!handle) { fprintf (stderr, "Can't open device.\n"); return 1; } if (usb_claim_interface (handle, 0) < 0) { perror ("usb_claim_interface"); usb_close (handle); return 1; } memset (data, 0, sizeof(data)); retry: if (usb_bulk_write (handle, 3, data, sizeof(data), -1) < 0) { perror ("usb_bulk_write"); if (errno == EAGAIN && retry > 0) { retry--; goto retry; } usb_release_interface (handle, 0); usb_close (handle); return 1; } return 0; }
Regards, -- Daiki Ueno