Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 325855
b: refs/heads/master
c: 0837e7e
h: refs/heads/master
i:
  325853: 0825cef
  325851: 22d6221
  325847: 9e5df37
  325839: 77e0262
  325823: 03fb2b4
v: v3
  • Loading branch information
Hans de Goede authored and Greg Kroah-Hartman committed Sep 10, 2012
1 parent a85a679 commit 602bfb8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ba2f9dff6c914b91005f687a9d75c8eac110d323
refs/heads/master: 0837e7e5270bd5547ba5763f11611dc43f677b3d
35 changes: 35 additions & 0 deletions trunk/drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 14 additions & 0 deletions trunk/include/linux/usbdevice_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@ struct usbdevfs_hub_portinfo {
#define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04
#define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08

/* USBDEVFS_DISCONNECT_CLAIM flags & struct */

/* disconnect-and-claim if the driver matches the driver field */
#define USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
/* disconnect-and-claim except when the driver matches the driver field */
#define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02

struct usbdevfs_disconnect_claim {
unsigned int interface;
unsigned int flags;
char driver[USBDEVFS_MAXDRIVERNAME + 1];
};

#ifdef __KERNEL__
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
Expand Down Expand Up @@ -211,5 +224,6 @@ struct usbdevfs_ioctl32 {
#define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int)
#define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int)
#define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32)
#define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim)

#endif /* _LINUX_USBDEVICE_FS_H */

0 comments on commit 602bfb8

Please sign in to comment.