From ff231db811803ef3292532d1d87eaf6882a26cc4 Mon Sep 17 00:00:00 2001 From: Josua Dietze <digidietze@draisberghof.de> Date: Sun, 23 Oct 2011 14:22:29 +0200 Subject: 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> --- drivers/usb/core/driver.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/usb/core/driver.c') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 45887a0ff87..73abd8a0647 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -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); -- cgit v1.2.3-70-g09d2 From e78832cdca2ddd23c15abaed642cad1a39b3e122 Mon Sep 17 00:00:00 2001 From: Oliver Neukum <oliver@neukum.org> Date: Mon, 2 Jan 2012 15:11:48 +0100 Subject: USB: remove dead code from suspend/resume path If a driver does not support the suspend/resume callbacks it will be forcibly disconnected. There is no reason to check for support of the callbacks after that. Signed-off-by: Oliver Neukum <oneukum@suse.de> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- drivers/usb/core/driver.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers/usb/core/driver.c') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 73abd8a0647..d40ff956881 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1079,17 +1079,10 @@ static int usb_suspend_interface(struct usb_device *udev, goto done; driver = to_usb_driver(intf->dev.driver); - if (driver->suspend) { - status = driver->suspend(intf, msg); - if (status && !PMSG_IS_AUTO(msg)) - dev_err(&intf->dev, "%s error %d\n", - "suspend", status); - } else { - /* Later we will unbind the driver and reprobe */ - intf->needs_binding = 1; - dev_warn(&intf->dev, "no %s for driver %s?\n", - "suspend", driver->name); - } + /* at this time we know the driver supports suspend */ + status = driver->suspend(intf, msg); + if (status && !PMSG_IS_AUTO(msg)) + dev_err(&intf->dev, "suspend error %d\n", status); done: dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); @@ -1138,16 +1131,9 @@ static int usb_resume_interface(struct usb_device *udev, "reset_resume", driver->name); } } else { - if (driver->resume) { - status = driver->resume(intf); - if (status) - dev_err(&intf->dev, "%s error %d\n", - "resume", status); - } else { - intf->needs_binding = 1; - dev_warn(&intf->dev, "no %s for driver %s?\n", - "resume", driver->name); - } + status = driver->resume(intf); + if (status) + dev_err(&intf->dev, "resume error %d\n", status); } done: -- cgit v1.2.3-70-g09d2