diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-10-19 07:54:24 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-10-19 07:55:09 -0700 |
commit | 4533d86270d7986e00594495dde9a109d6be27ae (patch) | |
tree | c2473cac653f7b98e5bd5e6475e63734be4b7644 /drivers/usb/core/devio.c | |
parent | 21c5e50e15b1abd797e62f18fd7f90b9cc004cbd (diff) | |
parent | 5bc66170dc486556a1e36fd384463536573f4b82 (diff) |
Merge commit '5bc66170dc486556a1e36fd384463536573f4b82' into x86/urgent
From Borislav Petkov <bp@amd64.org>:
Below is a RAS fix which reverts the addition of a sysfs attribute
which we agreed is not needed, post-factum. And this should go in now
because that sysfs attribute is going to end up in 3.7 otherwise and
thus exposed to userspace; removing it then would be a lot harder.
This is done as a merge rather than a simple patch/cherry-pick since
the baseline for this patch was not in the previous x86/urgent.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r-- | drivers/usb/core/devio.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ebb8a9de8b5..e0356cb859b 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1928,6 +1928,38 @@ static int proc_get_capabilities(struct dev_state *ps, void __user *arg) return 0; } +static int proc_disconnect_claim(struct dev_state *ps, void __user *arg) +{ + struct usbdevfs_disconnect_claim dc; + struct usb_interface *intf; + + if (copy_from_user(&dc, arg, sizeof(dc))) + return -EFAULT; + + intf = usb_ifnum_to_if(ps->dev, dc.interface); + if (!intf) + return -EINVAL; + + if (intf->dev.driver) { + struct usb_driver *driver = to_usb_driver(intf->dev.driver); + + if ((dc.flags & USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER) && + strncmp(dc.driver, intf->dev.driver->name, + sizeof(dc.driver)) != 0) + return -EBUSY; + + if ((dc.flags & USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER) && + strncmp(dc.driver, intf->dev.driver->name, + sizeof(dc.driver)) == 0) + return -EBUSY; + + dev_dbg(&intf->dev, "disconnect by usbfs\n"); + usb_driver_release_interface(driver, intf); + } + + return claimintf(ps, dc.interface); +} + /* * NOTE: All requests here that have interface numbers as parameters * are assuming that somehow the configuration has been prevented from @@ -2101,6 +2133,9 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd, case USBDEVFS_GET_CAPABILITIES: ret = proc_get_capabilities(ps, p); break; + case USBDEVFS_DISCONNECT_CLAIM: + ret = proc_disconnect_claim(ps, p); + break; } usb_unlock_device(dev); if (ret >= 0) |