aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/inode.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-06-24 14:47:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-21 18:16:40 -0400
commitcd9f03759d3eb588e185b04e1854c778b050833e (patch)
treec4d3ad70cec5c77569c05d6e657b253b2b6253c9 /drivers/usb/core/inode.c
parent78d9a487ee961c356e1a934d9a92eca38ffb3a70 (diff)
usbfs: send disconnect signals when device is unregistered
USB device files are accessible in two ways: as files in usbfs and as character device nodes. The two paths are supposed to behave identically, but they don't. When the underlying USB device is unplugged, disconnect signals are sent to processes with open usbfs files (if they requested these signals) but not to processes with open device node files. This patch (as1104) fixes the bug by moving the disconnect-signalling code into a common subroutine which is called from both paths. Putting this subroutine in devio.c removes the only out-of-file reference to struct dev_state, and so the structure's declaration can be moved from usb.h into devio.c. Finally, the new subroutine performs one extra action: It kills all the outstanding async URBs. (I'd kill the outstanding synchronous URBs too, if there was any way to do it.) In the past this hasn't mattered much, because devices were unregistered from usbfs only when they were disconnected. But now the unregistration can also occur whenever devices are unbound from the usb_generic driver. At any rate, killing URBs when a device is unregistered from usbfs seems like a good thing to do. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/inode.c')
-rw-r--r--drivers/usb/core/inode.c16
1 files changed, 1 insertions, 15 deletions
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 1d253dd4ea81..db410e92c80d 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -712,25 +712,11 @@ static void usbfs_add_device(struct usb_device *dev)
712 712
713static void usbfs_remove_device(struct usb_device *dev) 713static void usbfs_remove_device(struct usb_device *dev)
714{ 714{
715 struct dev_state *ds;
716 struct siginfo sinfo;
717
718 if (dev->usbfs_dentry) { 715 if (dev->usbfs_dentry) {
719 fs_remove_file (dev->usbfs_dentry); 716 fs_remove_file (dev->usbfs_dentry);
720 dev->usbfs_dentry = NULL; 717 dev->usbfs_dentry = NULL;
721 } 718 }
722 while (!list_empty(&dev->filelist)) { 719 usb_fs_classdev_common_remove(dev);
723 ds = list_entry(dev->filelist.next, struct dev_state, list);
724 wake_up_all(&ds->wait);
725 list_del_init(&ds->list);
726 if (ds->discsignr) {
727 sinfo.si_signo = ds->discsignr;
728 sinfo.si_errno = EPIPE;
729 sinfo.si_code = SI_ASYNCIO;
730 sinfo.si_addr = ds->disccontext;
731 kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
732 }
733 }
734} 720}
735 721
736static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) 722static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)