ChangeSet 1.1043.1.24, 2003/02/18 15:52:11-08:00, greg@kroah.com [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. diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c --- a/drivers/usb/core/urb.c Tue Feb 18 16:37:09 2003 +++ b/drivers/usb/core/urb.c Tue Feb 18 16:37:09 2003 @@ -195,7 +195,7 @@ 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_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; diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Tue Feb 18 16:37:09 2003 +++ b/drivers/usb/core/usb.c Tue Feb 18 16:37:09 2003 @@ -679,6 +679,7 @@ memset(dev, 0, sizeof(*dev)); device_initialize(&dev->dev); + dev->present = 1; usb_bus_get(bus); @@ -853,6 +854,10 @@ usbfs_remove_device(dev); } 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 */ diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Tue Feb 18 16:37:09 2003 +++ b/include/linux/usb.h Tue Feb 18 16:37:09 2003 @@ -239,6 +239,7 @@ 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 */