quirks.c 5.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 * USB device quirk handling logic and table
 *
 * Copyright (c) 2007 Oliver Neukum
 * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 2.
 *
 *
 */

#include <linux/usb.h>
#include <linux/usb/quirks.h>
#include "usb.h"

/* List of quirky USB devices.  Please keep this list 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[] = {
	/* HP 5300/5370C scanner */
	{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
O
Oliver Neukum 已提交
33 34
	/* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */
	{ USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
35 36 37 38

	/* SGS Thomson Microelectronics 4in1 card reader */
	{ USB_DEVICE(0x0483, 0x0321), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

O
Oliver Neukum 已提交
39 40
	/* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */
	{ USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
41 42
	/* Benq S2W 3300U */
	{ USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
43 44
	/* Canon, Inc. CanoScan N1240U/LiDE30 */
	{ USB_DEVICE(0x04a9, 0x220e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
45 46
	/* Canon, Inc. CanoScan N650U/N656U */
	{ USB_DEVICE(0x04a9, 0x2206), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
47 48
	/* Canon, Inc. CanoScan 1220U */
	{ USB_DEVICE(0x04a9, 0x2207), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
49 50 51 52
	/* Canon, Inc. CanoScan N670U/N676U/LiDE 20 */
	{ USB_DEVICE(0x04a9, 0x220d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
	/* old Cannon scanner */
	{ USB_DEVICE(0x04a9, 0x2220), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
53 54
	/* Seiko Epson Corp. Perfection 1200 */
	{ USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
55 56
	/* Seiko Epson Corp. Perfection 660 */
	{ USB_DEVICE(0x04b8, 0x0114), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
57 58
	/* Epson Perfection 1260 Photo */
	{ USB_DEVICE(0x04b8, 0x011d), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
59 60
	/* Seiko Epson Corp - Perfection 1670 */
	{ USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
61 62
	/* EPSON Perfection 2480 */
	{ USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
63 64
	/* Seiko Epson Corp.*/
	{ USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
65 66
	/* Samsung ML-2010 printer */
	{ USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
67 68
	/* Samsung ML-2510 Series printer */
	{ USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
69 70
	/* Elsa MicroLink 56k (V.250) */
	{ USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
71 72
	/* Ultima Electronics Corp.*/
	{ USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
73 74 75 76

	/* Genesys USB-to-IDE */
	{ USB_DEVICE(0x0503, 0x0702), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

O
Oliver Neukum 已提交
77 78
	/* Agfa Snapscan1212u */
	{ USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
79 80
	/* Seagate RSS LLC */
	{ USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
O
Oliver Neukum 已提交
81 82
	/* Umax [hex] Astra 3400U */
	{ USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
A
Alan Stern 已提交
83 84 85

	/* Philips PSC805 audio device */
	{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
86

87 88 89
	/* Alcor multi-card reader */
	{ USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

90 91 92
	/* Canon EOS 5D in PC Connection mode */
	{ USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },

93 94 95 96
	/* RIM Blackberry */
	{ USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
	{ USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
	{ USB_DEVICE(0x0fca, 0x0006), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
97 98 99

	/* Apple iPhone */
	{ USB_DEVICE(0x05ac, 0x1290), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
100 101 102 103 104 105

	{ }  /* terminating entry must be last */
};

static void usb_autosuspend_quirk(struct usb_device *udev)
{
106 107
#ifdef	CONFIG_USB_SUSPEND
	/* disable autosuspend, but allow the user to re-enable it via sysfs */
108
	udev->autosuspend_disabled = 1;
109
#endif
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
}

static const struct usb_device_id *find_id(struct usb_device *udev)
{
	const struct usb_device_id *id = usb_quirk_list;

	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
			id->driver_info; id++) {
		if (usb_match_device(udev, id))
			return id;
	}
	return NULL;
}

/*
 * Detect any quirks the device has, and do any housekeeping for it if needed.
 */
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);
	if (udev->quirks)
		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
				udev->quirks);

	/* do any special quirk handling here if needed */
	if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND)
		usb_autosuspend_quirk(udev);
}