Commit 6428737c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[PATCH] USB: add "present" flag to usb_device structure.

This solves lots of races when drivers hold a reference to the usb_device
after the device is physically removed from the system (like when a user
has a open handle.)  This now prevents any new urbs being submitted or
canceled for the device.
parent ff95122b
......@@ -195,7 +195,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) || !dev->bus || dev->devnum <= 0)
if (!(dev = urb->dev) || !dev->present || !dev->bus || dev->devnum <= 0)
return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
......@@ -376,7 +376,7 @@ int usb_submit_urb(struct urb *urb, int mem_flags)
*/
int usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
if (urb && urb->dev && urb->dev->present && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
......
......@@ -679,6 +679,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
memset(dev, 0, sizeof(*dev));
device_initialize(&dev->dev);
dev->present = 1;
usb_bus_get(bus);
......@@ -854,6 +855,10 @@ void usb_disconnect(struct usb_device **pdev)
}
device_unregister(&dev->dev);
/* mark the device as not present so any further urb submissions for
* this device will fail. */
dev->present = 0;
/* Decrement the reference count, it'll auto free everything when */
/* it hits 0 which could very well be now */
usb_put_dev(dev);
......
......@@ -239,6 +239,7 @@ struct usb_device {
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */
int present; /* if device is present or not */
void *hcpriv; /* Host Controller private data */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment