Hi all,

Here's a patch against 2.5.5-pre1 that finishes up the urb reference
counting logic, by implementing usb_get_urb() and usb_put_urb() in the
uhci, usb-uhci, and usb-ohci drivers (currently it's only in the
ehci-hcd and ohci-hcd drivers.)

I've been running with this patch for a while now and it seems to work
correctly for me :)

If no one has any objections to this, I'll send it on to Linus.

thanks,

greg k-h


diff -Nru a/drivers/usb/uhci.c b/drivers/usb/uhci.c
--- a/drivers/usb/uhci.c        Tue Feb 19 13:00:22 2002
+++ b/drivers/usb/uhci.c        Tue Feb 19 13:00:22 2002
@@ -1492,6 +1492,9 @@
                return -ENODEV;
        }
 
+       /* increment the reference count of the urb, as we now also control it */
+       urb = usb_get_urb(urb);
+
        uhci = (struct uhci *)urb->dev->bus->hcpriv;
 
        INIT_LIST_HEAD(&urb->urb_list);
@@ -1505,6 +1508,7 @@
                /* Since we can have problems on the out path */
                spin_unlock_irqrestore(&urb->lock, flags);
                usb_dec_dev_use(urb->dev);
+               usb_put_urb(urb);
 
                return ret;
        }
@@ -2299,6 +2303,7 @@
                        /* We decrement the usage count after we're done */
                        /*  with everything */
                        usb_dec_dev_use(dev);
+                       usb_put_urb(urb);
                }
        }
 }
diff -Nru a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
--- a/drivers/usb/usb-ohci.c    Tue Feb 19 13:00:22 2002
+++ b/drivers/usb/usb-ohci.c    Tue Feb 19 13:00:22 2002
@@ -205,6 +205,7 @@
                urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
                usb_dec_dev_use (urb->dev);
                urb->dev = NULL;
+               usb_put_urb (urb);
        }
 }
 
@@ -553,6 +554,9 @@
 //     if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout 
(pipe))) 
 //             return -EPIPE;
        
+       /* increment the reference count of the urb, as we now also control it */
+       urb = usb_get_urb (urb);
+
        usb_inc_dev_use (urb->dev);
        ohci = (ohci_t *) urb->dev->bus->hcpriv;
        
@@ -568,12 +572,14 @@
         * such as powering down ports */
        if (ohci->disabled) {
                usb_dec_dev_use (urb->dev);     
+               usb_put_urb (urb);
                return -ESHUTDOWN;
        }
 
        /* every endpoint has a ed, locate and fill it */
        if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
                usb_dec_dev_use (urb->dev);     
+               usb_put_urb (urb);
                return -ENOMEM;
        }
 
@@ -595,6 +601,7 @@
                        size = urb->number_of_packets;
                        if (size <= 0) {
                                usb_dec_dev_use (urb->dev);     
+                               usb_put_urb (urb);
                                return -EINVAL;
                        }
                        for (i = 0; i < urb->number_of_packets; i++) {
@@ -615,6 +622,7 @@
        urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
        if (!urb_priv) {
                usb_dec_dev_use (urb->dev);     
+               usb_put_urb (urb);
                return -ENOMEM;
        }
        memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
@@ -632,6 +640,7 @@
                        urb_free_priv (ohci, urb_priv);
                        spin_unlock_irqrestore (&usb_ed_lock, flags);
                        usb_dec_dev_use (urb->dev);     
+                       usb_put_urb (urb);
                        return -ENOMEM;
                }
        }       
@@ -640,6 +649,7 @@
                urb_free_priv (ohci, urb_priv);
                spin_unlock_irqrestore (&usb_ed_lock, flags);
                usb_dec_dev_use (urb->dev);     
+               usb_put_urb (urb);
                return -EINVAL;
        }
        
@@ -662,6 +672,7 @@
                                urb_free_priv (ohci, urb_priv);
                                spin_unlock_irqrestore (&usb_ed_lock, flags);
                                usb_dec_dev_use (urb->dev);     
+                               usb_put_urb (urb);
                                return bustime;
                        }
                        usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc 
(urb->pipe));
@@ -2100,6 +2111,7 @@
        urb->dev = NULL;
        if (urb->complete)
                urb->complete (urb);
+       usb_put_urb (urb);
        return 0;
 }
 
@@ -2123,6 +2135,7 @@
                                urb->complete (urb);
                } else
                        urb->status = -ENOENT;
+               usb_put_urb (urb);
        }
        return 0;
 }
diff -Nru a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
--- a/drivers/usb/usb-uhci.c    Tue Feb 19 13:00:22 2002
+++ b/drivers/usb/usb-uhci.c    Tue Feb 19 13:00:22 2002
@@ -1217,6 +1217,7 @@
                        urb->complete ((struct urb *) urb);
                }
                usb_dec_dev_use (usb_dev);
+               usb_put_urb (urb);
        }
        else
                spin_unlock_irqrestore (&s->urb_list_lock, flags);
@@ -1305,7 +1306,7 @@
 #else
                        kfree (urb_priv);
 #endif
-
+                       usb_put_urb (urb);
                }
        }
 }
@@ -1650,6 +1651,9 @@
                return -EINVAL;
        }
 
+       /* increment the reference count of the urb, as we now also control it */
+       urb = usb_get_urb (urb);
+
        usb_inc_dev_use (urb->dev);
 
        spin_lock_irqsave (&s->urb_list_lock, flags);
@@ -1665,6 +1669,7 @@
                     (!(urb->transfer_flags & USB_QUEUE_BULK) || 
!(queued_urb->transfer_flags & USB_QUEUE_BULK)))) {
                        spin_unlock_irqrestore (&s->urb_list_lock, flags);
                        usb_dec_dev_use (urb->dev);
+                       usb_put_urb (urb);
                        err("ENXIO %08x, flags %x, urb %p, burb 
%p",urb->pipe,urb->transfer_flags,urb,queued_urb);
                        return -ENXIO;  // urb already queued
                }
@@ -1678,6 +1683,7 @@
        if (!urb_priv) {
                usb_dec_dev_use (urb->dev);
                spin_unlock_irqrestore (&s->urb_list_lock, flags);
+               usb_put_urb (urb);
                return -ENOMEM;
        }
 
@@ -1766,6 +1772,7 @@
 #else
                kfree (urb_priv);
 #endif
+               usb_put_urb (urb);
                return ret;
        }
 
@@ -2730,6 +2737,7 @@
                        }
                        
                        usb_dec_dev_use (usb_dev);
+                       usb_put_urb (urb);
                }
        }
 

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to