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