[PATCH <resend>] usb: Add a new quirk: USB_QUIRK_HONOR_BNUMINTERFACES

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

As I've not heared anything about this patch, since it last revision, I'm
hereby resending it. Please let me know if any more changes are needed to
make this patch acceptable for inclusion.

In the mean time I've finished a libgphoto2 driver for the device in question,
but it needs this quirk to work.

On 03/16/2010 03:17 PM, Alan Stern wrote:

<snip>

s/then/than/


<snip>


After these spelling changes are included,


Both fixed, and I also rebased the patch to 2.6.34-rc1-git1 (it did not
apply there as that already has another new quirk compared to 2.6.33).

New version attached.

Thanks,

Hans
>From d74a88942159f16f597d13bbdb748959a5b9c0fb Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@xxxxxxxxxx>
Date: Wed, 17 Mar 2010 14:32:51 +0100
Subject: [PATCH 1/2] usb: Add a new quirk: USB_QUIRK_HONOR_BNUMINTERFACES

Add a new quirk USB_QUIRK_HONOR_BNUMINTERFACES, when this quirk is
set and a device has more interface descriptors in a configuration
then it claims to have in config->bNumInterfaces, ignore all additional
interfaces.

This is needed for devices which try to hide unused interfaces by only
lowering config->bNumInterfaces, and which can't handle if you try to talk
to the "hidden" interfaces.

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
---
 drivers/usb/core/config.c  |   16 ++++++++++++++--
 drivers/usb/core/quirks.c  |    4 ++++
 include/linux/usb/quirks.h |    4 ++++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 0d3af6a..5cc44a7 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1,5 +1,6 @@
 #include <linux/usb.h>
 #include <linux/usb/ch9.h>
+#include <linux/usb/quirks.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -478,9 +479,10 @@ skip_to_next_interface_descriptor:
 	return buffer - buffer0 + i;
 }
 
-static int usb_parse_configuration(struct device *ddev, int cfgidx,
+static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
     struct usb_host_config *config, unsigned char *buffer, int size)
 {
+	struct device *ddev = &dev->dev;
 	unsigned char *buffer0 = buffer;
 	int cfgno;
 	int nintf, nintf_orig;
@@ -549,6 +551,16 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx,
 			}
 
 			inum = d->bInterfaceNumber;
+
+			if ((dev->quirks & USB_QUIRK_HONOR_BNUMINTERFACES) &&
+			    n >= nintf_orig) {
+				dev_warn(ddev, "config %d has more interface "
+				    "descriptors, than it declares in "
+				    "bNumInterfaces, ignoring interface "
+				    "number: %d\n", cfgno, inum);
+				continue;
+			}
+
 			if (inum >= nintf_orig)
 				dev_warn(ddev, "config %d has an invalid "
 				    "interface number: %d but max is %d\n",
@@ -800,7 +812,7 @@ int usb_get_configuration(struct usb_device *dev)
 
 		dev->rawdescriptors[cfgno] = bigbuffer;
 
-		result = usb_parse_configuration(&dev->dev, cfgno,
+		result = usb_parse_configuration(dev, cfgno,
 		    &dev->config[cfgno], bigbuffer, length);
 		if (result < 0) {
 			++cfgno;
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index f073c5c..f22d03d 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* SKYMEDI USB_DRIVE */
 	{ USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* BUILDWIN Photo Frame */
+	{ USB_DEVICE(0x1908, 0x1315), .driver_info =
+			USB_QUIRK_HONOR_BNUMINTERFACES },
+
 	/* INTEL VALUE SSD */
 	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 0a555dd..16b7f33 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -22,4 +22,8 @@
 /*device will morph if reset, don't use reset for handling errors */
 #define USB_QUIRK_RESET_MORPHS		0x00000010
 
+/* device has more interface descriptions than the bNumInterfaces count,
+   and can't handle talking to these interfaces */
+#define USB_QUIRK_HONOR_BNUMINTERFACES	0x00000020
+
 #endif /* __LINUX_USB_QUIRKS_H */
-- 
1.7.0



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux