Hello all: I am trying to develop a code that simulates keyboard over net chip 2280. I am doing this in user space using gadgetfs. My code works with Linux host; but, the gadget machine freezes if I interface it with Windows host. Any help in solving this problem is appreciated. First I have a question regarding developing code over gadgetfs (since there is no documentation other than usb.c), > What are the things, which if done or not done in user space code, can lead to a machine freeze? Now, my current problem. As told before, the code correctly works with Linux host but, freezes with Windows host. I am using Linux kernel version 2.6.28 with net chip 2280 controller. I have attached USB packets logs(and its xml equivalent) from Windows host(captured using SnoopyPro). Just after the gadget machine sends a report descriptor, It freezes on next read from endpoint 0. Btw, SnoopyPro correctly identifies it as a HID. While searching for the solution, I came across the post "Issues with simulating a keyboard device with gadgetfs" (http://markmail.org/message/l42axrhttw3lrg6o) which suggests to call spin_unlock_irq() just before usb_ep_queue() and spin_lock_irq() just after in ep0_read, ep0_write, and gadgetfs_setup. Well, I found that usb_ep_queue() is called from ep_io, ep_aio_rwtail as well. I made the change at all the places where I found the call. Here are the changes that I did in inode.c ep_io - spin_lock_irq (&epdata->dev->lock); if (likely (epdata->ep != NULL)) { struct usb_request *req = epdata->req; req->context = &done; req->complete = epio_complete; req->buf = buf; req->length = len; spin_unlock_irq (&epdata->dev->lock); // Mayuresh value = usb_ep_queue (epdata->ep, req, GFP_ATOMIC); spin_lock_irq (&epdata->dev->lock); // Mayuresh } else value = -ENODEV; spin_unlock_irq (&epdata->dev->lock); ep_aio_rwtail - spin_lock_irq(&epdata->dev->lock); if (likely(epdata->ep)) { req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); if (likely(req)) { priv->req = req; req->buf = buf; req->length = len; req->complete = ep_aio_complete; req->context = iocb; spin_unlock_irq(&epdata->dev->lock); // Mayuresh value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC); spin_lock_irq(&epdata->dev->lock); // Mayuresh if (unlikely(0 != value)) usb_ep_free_request(epdata->ep, req); } else value = -EAGAIN; } else value = -ENODEV; spin_unlock_irq(&epdata->dev->lock); ep0_read - if ((retval = setup_req (ep, req, 0)) == 0) { spin_unlock_irq(&dev->lock); // Mayuresh retval = usb_ep_queue (ep, req, GFP_ATOMIC); spin_lock_irq(&dev->lock); // Mayuresh } gadgetfs_setup - /* read DATA stage for OUT right away */ if (unlikely (!dev->setup_in && w_length)) { value = setup_req (gadget->ep0, dev->req, w_length); if (value < 0) break; spin_unlock (&dev->lock); // Mayuresh value = usb_ep_queue (gadget->ep0, dev->req, GFP_ATOMIC); spin_lock (&dev->lock); // Mayuresh if (value < 0) { clean_req (gadget->ep0, dev->req); break; } .... if (value >= 0 && dev->state != STATE_DEV_SETUP) { req->length = value; req->zero = value < w_length; spin_unlock (&dev->lock); //Mayuresh value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); spin_lock (&dev->lock); //Mayuresh if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); req->status = 0; } } I did not change anything in ep0_write since it is already implemented there. But, this also did not help me. The machine still freezes. Is this a gagdetfs bug? Is there some patch for gadgetfs after kernel 2.6.28 which is more stable? Thanks for your help in advance. - Mayuresh
Attachment:
USB_keyboard_Log.log
Description: Binary data
Attachment:
USB_keyboard_Log.usblog
Description: Binary data