Hi,
this is the newest version of the patch to introduce a blacklist.
- It handles autosuspend oddities and problems with string descriptors
- It exports the detected quirks through sysfs
It compiles and detects quirky devices.
Regards
Oliver
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
----
--- /dev/null 2007-01-15 18:37:01.000000000 +0100
+++ linux-blacklist/include/linux/usb/quirks.h 2007-01-26 13:49:08.000000000
+0100
@@ -0,0 +1,8 @@
+/*
+ * This file holds the definitions of quirks found in devices
+ * Only quirks that affect the whole device, not an interface,
+ * belong here
+ */
+
+#define USB_QUIRK_NO_AUTOSUSPEND 1 /* devices which must not be
autosuspended */
+#define USB_QUIRK_STRING_FETCH 2 /* devices which crash when
string descriptors are fetched */
--- linux-2.6.20-rc6/include/linux/usb.h 2007-01-25 11:37:53.000000000
+0100
+++ linux-blacklist/include/linux/usb.h 2007-01-26 09:02:37.000000000 +0100
@@ -387,6 +387,7 @@
struct usb_device *children[USB_MAXCHILDREN];
int pm_usage_cnt; /* usage counter for autosuspend */
+ int quirks; /* quirks of the whole device */
#ifdef CONFIG_PM
struct delayed_work autosuspend; /* for delayed autosuspends */
struct mutex pm_mutex; /* protects PM operations */
@@ -1460,3 +1461,4 @@
#endif /* __KERNEL__ */
#endif
+
--- linux-2.6.20-rc6/drivers/usb/core/hub.c 2007-01-25 11:37:42.000000000
+0100
+++ linux-blacklist/drivers/usb/core/hub.c 2007-01-26 09:02:37.000000000
+0100
@@ -1267,6 +1267,9 @@
if (!try_module_get(THIS_MODULE))
return -EINVAL;
+ /* Determine quirks */
+ usb_detect_quirks(udev);
+
err = usb_get_configuration(udev);
if (err < 0) {
dev_err(&udev->dev, "can't read configurations, error %d\n",
--- linux-2.6.20-rc6/drivers/usb/core/message.c 2007-01-25 11:37:42.000000000
+0100
+++ linux-blacklist/drivers/usb/core/message.c 2007-01-26 09:42:15.000000000
+0100
@@ -11,6 +11,7 @@
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/device.h>
+#include <linux/usb/quirks.h>
#include <asm/byteorder.h>
#include <asm/scatterlist.h>
@@ -810,6 +811,8 @@
char *smallbuf = NULL;
int len;
+ if (udev->quirks & USB_QUIRK_STRING_FETCH)
+ return NULL;
if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) {
if ((len = usb_string(udev, index, buf, 256)) > 0) {
if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL)
--- linux-2.6.20-rc6/drivers/usb/core/sysfs.c 2007-01-25 11:36:31.000000000
+0100
+++ linux-blacklist/drivers/usb/core/sysfs.c 2007-01-26 09:36:23.000000000
+0100
@@ -148,6 +148,16 @@
}
static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
+static ssize_t
+show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct usb_device *udev;
+
+ udev = to_usb_device(dev);
+ return sprintf(buf, "%d\n", udev->quirks);
+}
+static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
+
/* Descriptor fields */
#define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
@@ -204,6 +214,7 @@
&dev_attr_devnum.attr,
&dev_attr_version.attr,
&dev_attr_maxchild.attr,
+ &dev_attr_quirks.attr,
NULL,
};
static struct attribute_group dev_attr_grp = {
--- linux-2.6.20-rc6/drivers/usb/core/usb.h 2007-01-25 11:37:42.000000000
+0100
+++ linux-blacklist/drivers/usb/core/usb.h 2007-01-26 09:02:37.000000000
+0100
@@ -13,6 +13,7 @@
struct usb_interface *intf);
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
+extern void usb_detect_quirks(struct usb_device *udev);
extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
--- linux-2.6.20-rc6/drivers/usb/core/Makefile 2007-01-25 11:36:31.000000000
+0100
+++ linux-blacklist/drivers/usb/core/Makefile 2007-01-26 09:02:37.000000000
+0100
@@ -4,7 +4,7 @@
usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \
config.o file.o buffer.o sysfs.o endpoint.o \
- devio.o notify.o generic.o
+ devio.o notify.o generic.o quirks.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
--- /dev/null 2007-01-15 18:37:01.000000000 +0100
+++ linux-blacklist/drivers/usb/core/quirks.c 2007-01-26 09:41:28.000000000
+0100
@@ -0,0 +1,45 @@
+/*
+ * drivers/usb/core/quirks.c
+ *
+ * (c) Copyright Oliver Neukum 2007
+ */
+
+#include <linux/usb.h>
+#include <linux/usb/quirks.h>
+#include "usb.h"
+#include "quirky_devices.h"
+
+static int usb_autosuspend_search_quirk(struct usb_device *udev)
+{
+ u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
+ u16 product = le16_to_cpu(udev->descriptor.idProduct);
+ u16 version = le16_to_cpu(udev->descriptor.bcdDevice);
+
+ const struct usb_blacklist *blentry = usb_blacklist;
+
+ while (blentry->idVendor) {
+ if (blentry->idVendor == vendor &&
+ blentry->idProduct == product &&
+ blentry->bcdVersionMin <= version &&
+ blentry->bcdVersionMax >= version)
+ return blentry->quirks;
+ blentry++;
+ }
+
+ return 0;
+}
+
+/*
+ * detect any quirks the device as opposed to the interfaces the device has
+ */
+
+void usb_detect_quirks(struct usb_device *udev)
+{
+ udev->quirks = usb_autosuspend_search_quirk(udev);
+
+ if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND) {
+ /* unbalanced resume that'll prevent autosuspension */
+ usb_autoresume_device(udev);
+ dev_dbg(&udev->dev, "USB power management quirks: %d\n",
udev->quirks);
+ }
+}
--- /dev/null 2007-01-15 18:37:01.000000000 +0100
+++ linux-blacklist/drivers/usb/core/quirky_devices.h 2007-01-26
10:02:45.000000000 +0100
@@ -0,0 +1,29 @@
+/*
+ * This is a list of USB devices which are quirky
+ * Keep this list ordered by
+ * 1. Vendor
+ * 2. Product
+ * 3. Version, the most specific first
+ */
+
+static const struct usb_blacklist {
+ u16 idVendor; /* vendor id of the quirky device */
+ u16 idProduct; /* product id of the quirky device */
+ u16 bcdVersionMin; /* minimum version id of the afflicted devices */
+ u16 bcdVersionMax; /* maximum version id of the afflicted devices */
+ int quirks; /* the actual qirks, several to be joined with binary
or */
+
+} usb_blacklist[] = {
+
+ /* HP 5300/5370C scanner */
+ {0x03f0, 0x0701, 0x0001, 0x0001, USB_QUIRK_STRING_FETCH},
+
+ /* Seiko Epson Corp. Perfection 1250 */
+ {0x04b8, 0x010f, 0x0100, 0x0100, USB_QUIRK_NO_AUTOSUSPEND},
+
+ /* Elsa MicroLink 56k (V.250) */
+ {0x05cc, 0x2267, 0x0100, 0x0100, USB_QUIRK_NO_AUTOSUSPEND},
+
+ {0, 0, 0, 0, 0} /* keep this last */
+};
+
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel