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