gadgetfs & 2.6.29: clients always returns EAGAIN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux