Most Logitech UVC webcams (both early models that don't advertise UVC compatibility and newer UVC-advertised devices) require the RESET_RESUME quirk. Instead of listing each and every model, match the devices based on the UVC interface information. Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> --- drivers/usb/core/quirks.c | 86 +++++++++++++-------------------------------- 1 files changed, 24 insertions(+), 61 deletions(-) Alan, what do you think about this approach ? I'm not sure whether we need to include the early UVC models that advertise a vendor-specific class in the list. diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 32d3adc..e99fbf9 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -22,10 +22,6 @@ * * 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[] = { /* CBM - Flash disk */ @@ -38,53 +34,20 @@ static const struct usb_device_id usb_quirk_list[] = { /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C200 */ - { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C250 */ - { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C300 */ - { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam B/C500 */ - { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C600 */ - { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam Pro 9000 */ - { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C905 */ - { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Quickcam Orbit MP */ + { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C210 */ - { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Quickcam Pro for Notebook */ + { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C260 */ - { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Quickcam Pro 5000 */ + { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C310 */ - { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Quickcam OEM Dell Notebook */ + { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C910 */ - { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C160 */ - { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C270 */ - { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam Pro 9000 */ - { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam E3500 */ - { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam Vision Pro */ - { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech Quickcam OEM Cisco VT Camera II */ + { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME }, /* Logitech Harmony 700-series */ { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, @@ -153,31 +116,31 @@ static const struct usb_device_id usb_quirk_list[] = { /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech UVC Cameras */ + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = USB_QUIRK_RESET_RESUME }, + { } /* terminating entry must be last */ }; -static const struct usb_device_id *find_id(struct usb_device *udev) +/* + * 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; for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || id->driver_info; id++) { if (usb_match_device(udev, id)) - return id; + udev->quirks |= (u32)(id->driver_info); } - 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); -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html