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 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel