[kernel] r19350 - in dists/sid/linux/debian: . patches patches/bugfix/all patches/features/all

Ben Hutchings benh at alioth.debian.org
Tue Aug 21 03:51:01 UTC 2012


Author: benh
Date: Tue Aug 21 03:50:56 2012
New Revision: 19350

Log:
usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams (Closes: #668211)

Added:
   dists/sid/linux/debian/patches/bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch
   dists/sid/linux/debian/patches/bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
   dists/sid/linux/debian/patches/features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
Modified:
   dists/sid/linux/debian/changelog
   dists/sid/linux/debian/patches/series

Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog	Tue Aug 21 03:30:16 2012	(r19349)
+++ dists/sid/linux/debian/changelog	Tue Aug 21 03:50:56 2012	(r19350)
@@ -102,6 +102,8 @@
   * PCI/PM/Runtime: make PCI traces quieter (Closes: #684049)
   * rc: ite-cir: Initialise ite_dev::rdev earlier (Closes: #684441)
   * input: Enable TOUCHSCREEN_ATMEL_MXT as module (Closes: #685123)
+  * usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams
+    (Closes: #668211)
 
   [ Bastian Blank ]
   * Make xen-linux-system meta-packages depend on xen-system. This allows

Added: dists/sid/linux/debian/patches/bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch	Tue Aug 21 03:50:56 2012	(r19350)
@@ -0,0 +1,99 @@
+From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
+Date: Thu, 19 Jul 2012 12:39:14 +0200
+Subject: usb: Add USB_QUIRK_RESET_RESUME for all Logitech UVC webcams
+
+commit e387ef5c47ddeaeaa3cbdc54424cdb7a28dae2c0 upstream.
+
+Most Logitech UVC webcams (both early models that don't advertise UVC
+compatibility and newer UVC-advertised devices) require the RESET_RESUME
+quirk. Instead of listing each and every model, match the devices based
+on the UVC interface information.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/usb/core/quirks.c |   58 +++++++++++++--------------------------------
+ 1 file changed, 16 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index cbd15d1..f15501f4c 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -43,53 +43,23 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* Creative SB Audigy 2 NX */
+ 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam C200 */
+-	{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam Fusion */
++	{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam C250 */
+-	{ USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam Orbit MP */
++	{ USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam C300 */
+-	{ USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam Pro for Notebook */
++	{ USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam B/C500 */
+-	{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam Pro 5000 */
++	{ USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam C600 */
+-	{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam OEM Dell Notebook */
++	{ USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+-	/* Logitech Webcam Pro 9000 */
+-	{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C905 */
+-	{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C210 */
+-	{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C260 */
+-	{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C310 */
+-	{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C910 */
+-	{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C160 */
+-	{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Webcam C270 */
+-	{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Quickcam Pro 9000 */
+-	{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Quickcam E3500 */
+-	{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* Logitech Quickcam Vision Pro */
+-	{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
++	/* Logitech Quickcam OEM Cisco VT Camera II */
++	{ USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+ 	/* Logitech Harmony 700-series */
+ 	{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
+@@ -162,6 +132,10 @@ static const struct usb_device_id usb_quirk_list[] = {
+ };
+ 
+ static const struct usb_device_id usb_interface_quirk_list[] = {
++	/* Logitech UVC Cameras */
++	{ USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
++	  .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	{ }  /* terminating entry must be last */
+ };
+ 

Added: dists/sid/linux/debian/patches/bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch	Tue Aug 21 03:50:56 2012	(r19350)
@@ -0,0 +1,250 @@
+From: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
+Date: Thu, 19 Jul 2012 12:39:13 +0200
+Subject: usb: Add quirk detection based on interface information
+
+commit 80da2e0df5af700518611b7d1cc4fc9945bcaf95 upstream.
+
+When a whole class of devices (possibly from a specific vendor, or
+across multiple vendors) require a quirk, explictly listing all devices
+in the class make the quirks table unnecessarily large. Fix this by
+allowing matching devices based on interface information.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/usb/core/driver.c |   38 ++++++++++--------
+ drivers/usb/core/hub.c    |   10 +++--
+ drivers/usb/core/quirks.c |   93 +++++++++++++++++++++++++++++++++++----------
+ drivers/usb/core/usb.h    |    4 ++
+ 4 files changed, 106 insertions(+), 39 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -541,22 +541,10 @@ int usb_match_device(struct usb_device *
+ }
+ 
+ /* returns 0 if no match, 1 if match */
+-int usb_match_one_id(struct usb_interface *interface,
+-		     const struct usb_device_id *id)
++int usb_match_one_id_intf(struct usb_device *dev,
++			  struct usb_host_interface *intf,
++			  const struct usb_device_id *id)
+ {
+-	struct usb_host_interface *intf;
+-	struct usb_device *dev;
+-
+-	/* proc_connectinfo in devio.c may call us with id == NULL. */
+-	if (id == NULL)
+-		return 0;
+-
+-	intf = interface->cur_altsetting;
+-	dev = interface_to_usbdev(interface);
+-
+-	if (!usb_match_device(dev, id))
+-		return 0;
+-
+ 	/* The interface class, subclass, and protocol should never be
+ 	 * checked for a match if the device class is Vendor Specific,
+ 	 * unless the match record specifies the Vendor ID. */
+@@ -581,6 +569,26 @@ int usb_match_one_id(struct usb_interfac
+ 
+ 	return 1;
+ }
++
++/* returns 0 if no match, 1 if match */
++int usb_match_one_id(struct usb_interface *interface,
++		     const struct usb_device_id *id)
++{
++	struct usb_host_interface *intf;
++	struct usb_device *dev;
++
++	/* proc_connectinfo in devio.c may call us with id == NULL. */
++	if (id == NULL)
++		return 0;
++
++	intf = interface->cur_altsetting;
++	dev = interface_to_usbdev(interface);
++
++	if (!usb_match_device(dev, id))
++		return 0;
++
++	return usb_match_one_id_intf(dev, intf, id);
++}
+ EXPORT_SYMBOL_GPL(usb_match_one_id);
+ 
+ /**
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1821,7 +1821,7 @@ static int usb_enumerate_device(struct u
+ 		if (err < 0) {
+ 			dev_err(&udev->dev, "can't read configurations, error %d\n",
+ 				err);
+-			goto fail;
++			return err;
+ 		}
+ 	}
+ 	if (udev->wusb == 1 && udev->authorized == 0) {
+@@ -1837,8 +1837,12 @@ static int usb_enumerate_device(struct u
+ 		udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber);
+ 	}
+ 	err = usb_enumerate_device_otg(udev);
+-fail:
+-	return err;
++	if (err < 0)
++		return err;
++
++	usb_detect_interface_quirks(udev);
++
++	return 0;
+ }
+ 
+ 
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -15,17 +15,22 @@
+ #include <linux/usb/quirks.h>
+ #include "usb.h"
+ 
+-/* List of quirky USB devices.  Please keep this list ordered by:
++/* Lists of quirky USB devices, split in device quirks and interface quirks.
++ * Device quirks are applied at the very beginning of the enumeration process,
++ * right after reading the device descriptor. They can thus only match on device
++ * information.
++ *
++ * Interface quirks are applied after reading all the configuration descriptors.
++ * They can match on both device and interface information.
++ *
++ * Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as
++ * interface quirks, as they only influence the enumeration process which is run
++ * before processing the interface quirks.
++ *
++ * Please keep the lists ordered by:
+  * 	1) Vendor ID
+  * 	2) Product ID
+  * 	3) Class ID
+- *
+- * as we want specific devices to be overridden first, and only after that, any
+- * class specific quirks.
+- *
+- * Right now the logic aborts if it finds a valid device in the table, we might
+- * want to change that in the future if it turns out that a whole class of
+- * devices is broken...
+  */
+ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* CBM - Flash disk */
+@@ -156,16 +161,53 @@ static const struct usb_device_id usb_qu
+ 	{ }  /* terminating entry must be last */
+ };
+ 
+-static const struct usb_device_id *find_id(struct usb_device *udev)
++static const struct usb_device_id usb_interface_quirk_list[] = {
++	{ }  /* terminating entry must be last */
++};
++
++static bool usb_match_any_interface(struct usb_device *udev,
++				    const struct usb_device_id *id)
++{
++	unsigned int i;
++
++	for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) {
++		struct usb_host_config *cfg = &udev->config[i];
++		unsigned int j;
++
++		for (j = 0; j < cfg->desc.bNumInterfaces; ++j) {
++			struct usb_interface_cache *cache;
++			struct usb_host_interface *intf;
++
++			cache = cfg->intf_cache[j];
++			if (cache->num_altsetting == 0)
++				continue;
++
++			intf = &cache->altsetting[0];
++			if (usb_match_one_id_intf(udev, intf, id))
++				return true;
++		}
++	}
++
++	return false;
++}
++
++static u32 __usb_detect_quirks(struct usb_device *udev,
++			       const struct usb_device_id *id)
+ {
+-	const struct usb_device_id *id = usb_quirk_list;
++	u32 quirks = 0;
+ 
+-	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+-			id->driver_info; id++) {
+-		if (usb_match_device(udev, id))
+-			return id;
++	for (; id->match_flags; id++) {
++		if (!usb_match_device(udev, id))
++			continue;
++
++		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) &&
++		    !usb_match_any_interface(udev, id))
++			continue;
++
++		quirks |= (u32)(id->driver_info);
+ 	}
+-	return NULL;
++
++	return quirks;
+ }
+ 
+ /*
+@@ -173,14 +215,10 @@ static const struct usb_device_id *find_
+  */
+ void usb_detect_quirks(struct usb_device *udev)
+ {
+-	const struct usb_device_id *id = usb_quirk_list;
+-
+-	id = find_id(udev);
+-	if (id)
+-		udev->quirks = (u32)(id->driver_info);
++	udev->quirks = __usb_detect_quirks(udev, usb_quirk_list);
+ 	if (udev->quirks)
+ 		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
+-				udev->quirks);
++			udev->quirks);
+ 
+ 	/* For the present, all devices default to USB-PERSIST enabled */
+ #if 0		/* was: #ifdef CONFIG_PM */
+@@ -197,3 +235,16 @@ void usb_detect_quirks(struct usb_device
+ 		udev->persist_enabled = 1;
+ #endif	/* CONFIG_PM */
+ }
++
++void usb_detect_interface_quirks(struct usb_device *udev)
++{
++	u32 quirks;
++
++	quirks = __usb_detect_quirks(udev, usb_interface_quirk_list);
++	if (quirks == 0)
++		return;
++
++	dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n",
++		quirks);
++	udev->quirks |= quirks;
++}
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -24,6 +24,7 @@ extern void usb_disable_device(struct us
+ extern int usb_deauthorize_device(struct usb_device *);
+ extern int usb_authorize_device(struct usb_device *);
+ extern void usb_detect_quirks(struct usb_device *udev);
++extern void usb_detect_interface_quirks(struct usb_device *udev);
+ extern int usb_remove_device(struct usb_device *udev);
+ 
+ extern int usb_get_device_descriptor(struct usb_device *dev,
+@@ -35,6 +36,9 @@ extern int usb_set_configuration(struct
+ extern int usb_choose_configuration(struct usb_device *udev);
+ 
+ extern void usb_kick_khubd(struct usb_device *dev);
++extern int usb_match_one_id_intf(struct usb_device *dev,
++				 struct usb_host_interface *intf,
++				 const struct usb_device_id *id);
+ extern int usb_match_device(struct usb_device *dev,
+ 			    const struct usb_device_id *id);
+ extern void usb_forced_unbind_intf(struct usb_interface *intf);

Added: dists/sid/linux/debian/patches/features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch	Tue Aug 21 03:50:56 2012	(r19350)
@@ -0,0 +1,56 @@
+From: Gustavo Padovan <gustavo.padovan at collabora.co.uk>
+Date: Tue, 10 Jul 2012 19:10:06 -0300
+Subject: USB: add USB_VENDOR_AND_INTERFACE_INFO() macro
+
+commit d81a5d1956731c453b85c141458d4ff5d6cc5366 upstream.
+
+A lot of Broadcom Bluetooth devices provides vendor specific interface
+class and we are getting flooded by patches adding new device support.
+This change will help us enable support for any other Broadcom with vendor
+specific device that arrives in the future.
+
+Only the product id changes for those devices, so this macro would be
+perfect for us:
+
+{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }
+
+Signed-off-by: Marcel Holtmann <marcel at holtmann.org>
+Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.co.uk>
+Acked-by: Henrik Rydberg <rydberg at bitmath.se>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ include/linux/usb.h |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 873956b..30d1ae3 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -861,6 +861,27 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
+ 	.bInterfaceSubClass = (sc), \
+ 	.bInterfaceProtocol = (pr)
+ 
++/**
++ * USB_VENDOR_AND_INTERFACE_INFO - describe a specific usb vendor with a class of usb interfaces
++ * @vend: the 16 bit USB Vendor ID
++ * @cl: bInterfaceClass value
++ * @sc: bInterfaceSubClass value
++ * @pr: bInterfaceProtocol value
++ *
++ * This macro is used to create a struct usb_device_id that matches a
++ * specific vendor with a specific class of interfaces.
++ *
++ * This is especially useful when explicitly matching devices that have
++ * vendor specific bDeviceClass values, but standards-compliant interfaces.
++ */
++#define USB_VENDOR_AND_INTERFACE_INFO(vend, cl, sc, pr) \
++	.match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
++		| USB_DEVICE_ID_MATCH_VENDOR, \
++	.idVendor = (vend), \
++	.bInterfaceClass = (cl), \
++	.bInterfaceSubClass = (sc), \
++	.bInterfaceProtocol = (pr)
++
+ /* ----------------------------------------------------------------------- */
+ 
+ /* Stuff for dynamic usb ids */

Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series	Tue Aug 21 03:30:16 2012	(r19349)
+++ dists/sid/linux/debian/patches/series	Tue Aug 21 03:50:56 2012	(r19350)
@@ -389,3 +389,6 @@
 bugfix/all/rds-set-correct-msg_namelen.patch
 bugfix/all/PCI-PM-Runtime-make-PCI-traces-quieter.patch
 bugfix/all/media-rc-ite-cir-Initialise-ite_dev-rdev-earlier.patch
+features/all/USB-add-USB_VENDOR_AND_INTERFACE_INFO-macro.patch
+bugfix/all/usb-Add-quirk-detection-based-on-interface-informati.patch
+bugfix/all/usb-Add-USB_QUIRK_RESET_RESUME-for-all-Logitech-UVC-.patch



More information about the Kernel-svn-changes mailing list