Hi,
On 03/16/2010 03:17 PM, Alan Stern wrote:
On Tue, 16 Mar 2010, Hans de Goede wrote:
@@ -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, then it declares in "
s/, then/ than/
+ "bNumInterfaces, ignoring interface "
+ "number: %d\n", cfgno, inum);
+ continue;
+ }
+
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -19,4 +19,8 @@
/* device can't handle its Configuration or Interface strings */
#define USB_QUIRK_CONFIG_INTF_STRINGS 0x00000008
+/* device has more interface descriptions then the bNumInterfaces count,
s/then/than/
+ and can't handle talking to these interfaces */
+#define USB_QUIRK_HONOR_BNUMINTERFACES 0x00000010
+
#endif /* __LINUX_USB_QUIRKS_H */
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