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: Josua Dietze <digidietze@draisberghof.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Josua Dietze 2011-10-23 14:22:29 +02:00 committed by Greg Kroah-Hartman
parent 332960bd7e
commit ff231db811
2 changed files with 32 additions and 1 deletions

View File

@ -119,6 +119,31 @@ Description:
Write a 1 to force the device to disconnect Write a 1 to force the device to disconnect
(equivalent to unplugging a wired USB device). (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 What: /sys/bus/usb/drivers/.../remove_id
Date: November 2009 Date: November 2009
Contact: CHENG Renquan <rqcheng@smu.edu.sg> Contact: CHENG Renquan <rqcheng@smu.edu.sg>

View File

@ -45,10 +45,12 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
struct usb_dynid *dynid; struct usb_dynid *dynid;
u32 idVendor = 0; u32 idVendor = 0;
u32 idProduct = 0; u32 idProduct = 0;
unsigned int bInterfaceClass = 0;
int fields = 0; int fields = 0;
int retval = 0; int retval = 0;
fields = sscanf(buf, "%x %x", &idVendor, &idProduct); fields = sscanf(buf, "%x %x %x", &idVendor, &idProduct,
&bInterfaceClass);
if (fields < 2) if (fields < 2)
return -EINVAL; return -EINVAL;
@ -60,6 +62,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
dynid->id.idVendor = idVendor; dynid->id.idVendor = idVendor;
dynid->id.idProduct = idProduct; dynid->id.idProduct = idProduct;
dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; 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); spin_lock(&dynids->lock);
list_add_tail(&dynid->node, &dynids->list); list_add_tail(&dynid->node, &dynids->list);