Commit 79c36a70 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: idmouse: simplify disconnect handling

Since commit d4ead16f ("USB: prevent char device open/deregister
race") core prevents further calls to open() after usb_deregister_dev()
returns so there's no need to use the interface data for
synchronisation.

This effectively reverts commit 54d2bc06 ("USB: fix locking in
idmouse") with respect to the open-disconnect race.

Note that the driver already uses a present flag to suppress I/O post
disconnect (even if all USB I/O take place at open).
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20191105103638.4929-2-johan@kernel.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e76b3bf7
...@@ -60,7 +60,6 @@ static const struct usb_device_id idmouse_table[] = { ...@@ -60,7 +60,6 @@ static const struct usb_device_id idmouse_table[] = {
USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
MODULE_DEVICE_TABLE(usb, idmouse_table); MODULE_DEVICE_TABLE(usb, idmouse_table);
static DEFINE_MUTEX(open_disc_mutex);
/* structure to hold all of our device specific stuff */ /* structure to hold all of our device specific stuff */
struct usb_idmouse { struct usb_idmouse {
...@@ -227,17 +226,13 @@ static int idmouse_open(struct inode *inode, struct file *file) ...@@ -227,17 +226,13 @@ static int idmouse_open(struct inode *inode, struct file *file)
if (!interface) if (!interface)
return -ENODEV; return -ENODEV;
mutex_lock(&open_disc_mutex);
/* get the device information block from the interface */ /* get the device information block from the interface */
dev = usb_get_intfdata(interface); dev = usb_get_intfdata(interface);
if (!dev) { if (!dev)
mutex_unlock(&open_disc_mutex);
return -ENODEV; return -ENODEV;
}
/* lock this device */ /* lock this device */
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* check if already open */ /* check if already open */
if (dev->open) { if (dev->open) {
...@@ -280,14 +275,12 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -280,14 +275,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (dev == NULL) if (dev == NULL)
return -ENODEV; return -ENODEV;
mutex_lock(&open_disc_mutex);
/* lock our device */ /* lock our device */
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
/* are we really open? */ /* are we really open? */
if (dev->open <= 0) { if (dev->open <= 0) {
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -296,11 +289,9 @@ static int idmouse_release(struct inode *inode, struct file *file) ...@@ -296,11 +289,9 @@ static int idmouse_release(struct inode *inode, struct file *file)
if (!dev->present) { if (!dev->present) {
/* the device was unplugged before the file was released */ /* the device was unplugged before the file was released */
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
idmouse_delete(dev); idmouse_delete(dev);
} else { } else {
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
mutex_unlock(&open_disc_mutex);
} }
return 0; return 0;
} }
...@@ -379,7 +370,6 @@ static int idmouse_probe(struct usb_interface *interface, ...@@ -379,7 +370,6 @@ static int idmouse_probe(struct usb_interface *interface,
if (result) { if (result) {
/* something prevented us from registering this device */ /* something prevented us from registering this device */
dev_err(&interface->dev, "Unable to allocate minor number.\n"); dev_err(&interface->dev, "Unable to allocate minor number.\n");
usb_set_intfdata(interface, NULL);
idmouse_delete(dev); idmouse_delete(dev);
return result; return result;
} }
...@@ -392,19 +382,13 @@ static int idmouse_probe(struct usb_interface *interface, ...@@ -392,19 +382,13 @@ static int idmouse_probe(struct usb_interface *interface,
static void idmouse_disconnect(struct usb_interface *interface) static void idmouse_disconnect(struct usb_interface *interface)
{ {
struct usb_idmouse *dev; struct usb_idmouse *dev = usb_get_intfdata(interface);
/* get device structure */
dev = usb_get_intfdata(interface);
/* give back our minor */ /* give back our minor */
usb_deregister_dev(interface, &idmouse_class); usb_deregister_dev(interface, &idmouse_class);
mutex_lock(&open_disc_mutex);
usb_set_intfdata(interface, NULL);
/* lock the device */ /* lock the device */
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
mutex_unlock(&open_disc_mutex);
/* prevent device read, write and ioctl */ /* prevent device read, write and ioctl */
dev->present = 0; dev->present = 0;
......
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