Commit ff231db8 authored by Josua Dietze's avatar Josua Dietze Committed by Greg Kroah-Hartman

USB: Add optional match for interface class to dynamic ID facility

When adding the ID of a composite device dynamically to a driver, all
hitherto unbound interfaces are bound to this driver regardless of their
class, which may not be intended.
The patch adds the option to tell the targeted interface class to a driver
via the "new_id" attribute, in addition to the device ID.
Also, it appends the ABI documentation accordingly.

Example:
$ echo "1234 2a2a ff" >/sys/bus/usb-serial/drivers/option1/new_id
will bind only vendor-specific interfaces to the 3G driver.
Signed-off-by: default avatarJosua Dietze <digidietze@draisberghof.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 332960bd
......@@ -119,6 +119,31 @@ Description:
Write a 1 to force the device to disconnect
(equivalent to unplugging a wired USB device).
What: /sys/bus/usb/drivers/.../new_id
Date: October 2011
Contact: linux-usb@vger.kernel.org
Description:
Writing a device ID to this file will attempt to
dynamically add a new device ID to a USB device driver.
This may allow the driver to support more hardware than
was included in the driver's static device ID support
table at compile time. The format for the device ID is:
idVendor idProduct bInterfaceClass.
The vendor ID and device ID fields are required, the
interface class is optional.
Upon successfully adding an ID, the driver will probe
for the device and attempt to bind to it. For example:
# echo "8086 10f5" > /sys/bus/usb/drivers/foo/new_id
What: /sys/bus/usb-serial/drivers/.../new_id
Date: October 2011
Contact: linux-usb@vger.kernel.org
Description:
For serial USB drivers, this attribute appears under the
extra bus folder "usb-serial" in sysfs; apart from that
difference, all descriptions from the entry
"/sys/bus/usb/drivers/.../new_id" apply.
What: /sys/bus/usb/drivers/.../remove_id
Date: November 2009
Contact: CHENG Renquan <rqcheng@smu.edu.sg>
......
......@@ -45,10 +45,12 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
struct usb_dynid *dynid;
u32 idVendor = 0;
u32 idProduct = 0;
unsigned int bInterfaceClass = 0;
int fields = 0;
int retval = 0;
fields = sscanf(buf, "%x %x", &idVendor, &idProduct);
fields = sscanf(buf, "%x %x %x", &idVendor, &idProduct,
&bInterfaceClass);
if (fields < 2)
return -EINVAL;
......@@ -60,6 +62,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
dynid->id.idVendor = idVendor;
dynid->id.idProduct = idProduct;
dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
if (fields == 3) {
dynid->id.bInterfaceClass = (u8)bInterfaceClass;
dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
}
spin_lock(&dynids->lock);
list_add_tail(&dynid->node, &dynids->list);
......
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