ChangeSet 1.1760.26.9, 2004/06/24 10:42:03-07:00, [EMAIL PROTECTED]

[PATCH] USB: Imiprove usb_device tracking in dummy_hcd

A tricky problem the dummy_hcd driver has to solve is keeping track of the
usb_device structure that corresponds to a registered gadget.  Right now
that's not done very robustly.  This patch stores the address of the
structure when a new URB is submitted and also acquires a reference to
make sure that completing the final URB won't deallocate the structure
before dummy_hcd is through with it.



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>


 drivers/usb/gadget/dummy_hcd.c |   38 ++++++++++++++++++++++++++------------
 1 files changed, 26 insertions(+), 12 deletions(-)


diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c    2004-06-29 16:26:11 -07:00
+++ b/drivers/usb/gadget/dummy_hcd.c    2004-06-29 16:26:11 -07:00
@@ -146,8 +146,6 @@
        u8                              fifo_buf [FIFO_SIZE];
        u16                             devstatus;
 
-       struct hcd_dev                  *hdev;
-
        /*
         * MASTER/HOST side support
         */
@@ -159,6 +157,8 @@
        struct completion               released;
        unsigned                        resuming:1;
        unsigned long                   re_timeout;
+
+       struct usb_device               *udev;
 };
 
 static struct dummy    *the_controller;
@@ -822,7 +822,12 @@
        dum = container_of (hcd, struct dummy, hcd);
        spin_lock_irqsave (&dum->lock, flags);
 
-       dum->hdev = urb->dev->hcpriv;
+       if (!dum->udev) {
+               dum->udev = urb->dev;
+               usb_get_dev (dum->udev);
+       } else if (unlikely (dum->udev != urb->dev))
+               dev_err (hardware, "usb_device address has changed!\n");
+
        urb->hcpriv = dum;
        if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
                urb->error_count = 1;           /* mark as a new urb */
@@ -1029,17 +1034,12 @@
 static void dummy_timer (unsigned long _dum)
 {
        struct dummy            *dum = (struct dummy *) _dum;
-       struct hcd_dev          *hdev = dum->hdev;
+       struct hcd_dev          *hdev;
        struct list_head        *entry, *tmp;
        unsigned long           flags;
        int                     limit, total;
        int                     i;
 
-       if (!hdev) {
-               dev_err (hardware, "timer fired with device gone?\n");
-               return;
-       }
-
        /* simplistic model for one frame's bandwidth */
        switch (dum->gadget.speed) {
        case USB_SPEED_LOW:
@@ -1060,6 +1060,14 @@
 
        /* look at each urb queued by the host side driver */
        spin_lock_irqsave (&dum->lock, flags);
+
+       if (!dum->udev) {
+               dev_err (hardware, "timer fired with no URBs pending?\n");
+               spin_unlock_irqrestore (&dum->lock, flags);
+               return;
+       }
+       hdev = dum->udev->hcpriv;
+
        for (i = 0; i < DUMMY_ENDPOINTS; i++) {
                if (!ep_name [i])
                        break;
@@ -1331,7 +1339,11 @@
 
        /* want a 1 msec delay here */
        if (!list_empty (&hdev->urb_list))
-               mod_timer (&dum->timer, jiffies + 1);
+               mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
+       else {
+               usb_put_dev (dum->udev);
+               dum->udev = NULL;
+       }
 
        spin_unlock_irqrestore (&dum->lock, flags);
 }
@@ -1568,10 +1580,12 @@
        struct urb              *urb;
        size_t                  size = 0;
        unsigned long           flags;
+       struct hcd_dev          *hdev;
 
        spin_lock_irqsave (&dum->lock, flags);
-       if (dum->hdev) {
-               list_for_each_entry (urb, &dum->hdev->urb_list, urb_list) {
+       if (dum->udev) {
+               hdev = dum->udev->hcpriv;
+               list_for_each_entry (urb, &hdev->urb_list, urb_list) {
                        size_t          temp;
 
                        temp = show_urb (buf, PAGE_SIZE - size, urb);



-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to