Keyboard simulation over gadgetfs freezes with Windows host

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

 



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


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

  Powered by Linux