浏览代码

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  Revert "USB: EHCI: fix performance regression"
  USB: fsl_usb2_udc: fix recursive lock
  USB: usb-serial: option: Don't match Huawei driver CD images
  USB: pl2303: another product ID
  USB: add another scanner quirk
  USB: Add support for ROKR W5 in unusual_devs.h
  USB: Fix M600i unusual_devs entry
  USB: usb-storage: unusual_devs update for Cypress ATACB
  USB: EHCI: fix performance regression
  USB: EHCI: fix bug in Iso scheduling
  USB: EHCI: fix remote-wakeup regression
  USB: EHCI: suppress unwanted error messages
  USB: EHCI: fix up root-hub TT mess
  USB: add all configs to the "descriptors" attribute
  USB: fix possible deadlock involving sysfs attributes
  USB: Firmware loader driver for USB Apple iSight camera
  USB: FTDI_SIO : Add support for Matrix Orbital PID Range
Linus Torvalds 17 年之前
父节点
当前提交
fbf4d7ffda

+ 0 - 5
drivers/usb/core/generic.c

@@ -155,9 +155,6 @@ static int generic_probe(struct usb_device *udev)
 {
 	int err, c;
 
-	/* put device-specific files into sysfs */
-	usb_create_sysfs_dev_files(udev);
-
 	/* Choose and set the configuration.  This registers the interfaces
 	 * with the driver core and lets interface drivers bind to them.
 	 */
@@ -189,8 +186,6 @@ static void generic_disconnect(struct usb_device *udev)
 	 * unconfigure the device */
 	if (udev->actconfig)
 		usb_set_configuration(udev, -1);
-
-	usb_remove_sysfs_dev_files(udev);
 }
 
 #ifdef	CONFIG_PM

+ 2 - 0
drivers/usb/core/hcd.h

@@ -213,6 +213,8 @@ struct hc_driver {
 
 		/* force handover of high-speed port to full-speed companion */
 	void	(*relinquish_port)(struct usb_hcd *, int);
+		/* has a port been handed over to a companion? */
+	int	(*port_handed_over)(struct usb_hcd *, int);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);

+ 14 - 1
drivers/usb/core/hub.c

@@ -1326,6 +1326,12 @@ void usb_disconnect(struct usb_device **pdev)
 
 	usb_unlock_device(udev);
 
+	/* Remove the device-specific files from sysfs.  This must be
+	 * done with udev unlocked, because some of the attribute
+	 * routines try to acquire the device lock.
+	 */
+	usb_remove_sysfs_dev_files(udev);
+
 	/* Unregister the device.  The device driver is responsible
 	 * for removing the device files from usbfs and sysfs and for
 	 * de-configuring the device.
@@ -1541,6 +1547,9 @@ int usb_new_device(struct usb_device *udev)
 		goto fail;
 	}
 
+	/* put device-specific files into sysfs */
+	usb_create_sysfs_dev_files(udev);
+
 	/* Tell the world! */
 	announce_device(udev);
 	return err;
@@ -2744,7 +2753,11 @@ loop:
 		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
 			break;
 	}
-	dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1);
+	if (hub->hdev->parent ||
+			!hcd->driver->port_handed_over ||
+			!(hcd->driver->port_handed_over)(hcd, port1))
+		dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
+				port1);
  
 done:
 	hub_port_disable(hub, port1, 1);

+ 4 - 0
drivers/usb/core/quirks.c

@@ -47,6 +47,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Edirol SD-20 */
 	{ USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Avision AV600U */
+	{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
+	  USB_QUIRK_STRING_FETCH_255 },
+
 	/* M-Systems Flash Disk Pioneers */
 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 

+ 21 - 23
drivers/usb/core/sysfs.c

@@ -588,35 +588,33 @@ read_descriptors(struct kobject *kobj, struct bin_attribute *attr,
 			container_of(kobj, struct device, kobj));
 	size_t nleft = count;
 	size_t srclen, n;
+	int cfgno;
+	void *src;
 
-	usb_lock_device(udev);
-
-	/* The binary attribute begins with the device descriptor */
-	srclen = sizeof(struct usb_device_descriptor);
-	if (off < srclen) {
-		n = min_t(size_t, nleft, srclen - off);
-		memcpy(buf, off + (char *) &udev->descriptor, n);
-		nleft -= n;
-		buf += n;
-		off = 0;
-	} else {
-		off -= srclen;
-	}
-
-	/* Then follows the raw descriptor entry for the current
-	 * configuration (config plus subsidiary descriptors).
+	/* The binary attribute begins with the device descriptor.
+	 * Following that are the raw descriptor entries for all the
+	 * configurations (config plus subsidiary descriptors).
 	 */
-	if (udev->actconfig) {
-		int cfgno = udev->actconfig - udev->config;
-
-		srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength);
+	for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations &&
+			nleft > 0; ++cfgno) {
+		if (cfgno < 0) {
+			src = &udev->descriptor;
+			srclen = sizeof(struct usb_device_descriptor);
+		} else {
+			src = udev->rawdescriptors[cfgno];
+			srclen = __le16_to_cpu(udev->config[cfgno].desc.
+					wTotalLength);
+		}
 		if (off < srclen) {
-			n = min_t(size_t, nleft, srclen - off);
-			memcpy(buf, off + udev->rawdescriptors[cfgno], n);
+			n = min(nleft, srclen - (size_t) off);
+			memcpy(buf, src + off, n);
 			nleft -= n;
+			buf += n;
+			off = 0;
+		} else {
+			off -= srclen;
 		}
 	}
-	usb_unlock_device(udev);
 	return count - nleft;
 }
 

+ 2 - 0
drivers/usb/gadget/fsl_usb2_udc.c

@@ -1627,7 +1627,9 @@ static int reset_queues(struct fsl_udc *udc)
 		udc_reset_ep_queue(udc, pipe);
 
 	/* report disconnect; the driver is already quiesced */
+	spin_unlock(&udc->lock);
 	udc->driver->disconnect(&udc->gadget);
+	spin_lock(&udc->lock);
 
 	return 0;
 }

+ 1 - 0
drivers/usb/host/ehci-au1xxx.c

@@ -223,6 +223,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
 	.bus_suspend = ehci_bus_suspend,
 	.bus_resume = ehci_bus_resume,
 	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
 };
 
 /*-------------------------------------------------------------------------*/

+ 2 - 5
drivers/usb/host/ehci-fsl.c

@@ -269,7 +269,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
 	if (retval)
 		return retval;
 
-	ehci->is_tdi_rh_tt = 1;
+	hcd->has_tt = 1;
 
 	ehci->sbrn = 0x20;
 
@@ -295,10 +295,6 @@ static const struct hc_driver ehci_fsl_hc_driver = {
 	 */
 	.reset = ehci_fsl_setup,
 	.start = ehci_run,
-#ifdef	CONFIG_PM
-	.suspend = ehci_bus_suspend,
-	.resume = ehci_bus_resume,
-#endif
 	.stop = ehci_stop,
 	.shutdown = ehci_shutdown,
 
@@ -322,6 +318,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
 	.bus_suspend = ehci_bus_suspend,
 	.bus_resume = ehci_bus_resume,
 	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
 };
 
 static int ehci_fsl_drv_probe(struct platform_device *pdev)

+ 14 - 2
drivers/usb/host/ehci-hub.c

@@ -609,7 +609,7 @@ static int ehci_hub_control (
 			}
 			break;
 		case USB_PORT_FEAT_C_SUSPEND:
-			/* we auto-clear this feature */
+			clear_bit(wIndex, &ehci->port_c_suspend);
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
@@ -688,7 +688,7 @@ static int ehci_hub_control (
 			/* resume completed? */
 			else if (time_after_eq(jiffies,
 					ehci->reset_done[wIndex])) {
-				status |= 1 << USB_PORT_FEAT_C_SUSPEND;
+				set_bit(wIndex, &ehci->port_c_suspend);
 				ehci->reset_done[wIndex] = 0;
 
 				/* stop resume signaling */
@@ -765,6 +765,8 @@ static int ehci_hub_control (
 			status |= 1 << USB_PORT_FEAT_RESET;
 		if (temp & PORT_POWER)
 			status |= 1 << USB_PORT_FEAT_POWER;
+		if (test_bit(wIndex, &ehci->port_c_suspend))
+			status |= 1 << USB_PORT_FEAT_C_SUSPEND;
 
 #ifndef	VERBOSE_DEBUG
 	if (status & ~0xffff)	/* only if wPortChange is interesting */
@@ -875,3 +877,13 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
 	set_owner(ehci, --portnum, PORT_OWNER);
 }
 
+static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
+	u32 __iomem		*reg;
+
+	if (ehci_is_TDI(ehci))
+		return 0;
+	reg = &ehci->regs->port_status[portnum - 1];
+	return ehci_readl(ehci, reg) & PORT_OWNER;
+}

+ 3 - 1
drivers/usb/host/ehci-ixp4xx.c

@@ -26,7 +26,7 @@ static int ixp4xx_ehci_init(struct usb_hcd *hcd)
 		+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
-	ehci->is_tdi_rh_tt = 1;
+	hcd->has_tt = 1;
 	ehci_reset(ehci);
 
 	retval = ehci_init(hcd);
@@ -58,6 +58,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
 	.bus_suspend		= ehci_bus_suspend,
 	.bus_resume		= ehci_bus_resume,
 #endif
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
 };
 
 static int ixp4xx_ehci_probe(struct platform_device *pdev)

+ 3 - 5
drivers/usb/host/ehci-orion.c

@@ -139,10 +139,6 @@ static const struct hc_driver ehci_orion_hc_driver = {
 	 */
 	.reset = ehci_orion_setup,
 	.start = ehci_run,
-#ifdef CONFIG_PM
-	.suspend = ehci_bus_suspend,
-	.resume = ehci_bus_resume,
-#endif
 	.stop = ehci_stop,
 	.shutdown = ehci_shutdown,
 
@@ -165,6 +161,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
 	.hub_control = ehci_hub_control,
 	.bus_suspend = ehci_bus_suspend,
 	.bus_resume = ehci_bus_resume,
+	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
 };
 
 static void __init
@@ -250,7 +248,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev)
 	ehci->regs = hcd->regs + 0x100 +
 		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
-	ehci->is_tdi_rh_tt = 1;
+	hcd->has_tt = 1;
 	ehci->sbrn = 0x20;
 
 	/*

+ 2 - 2
drivers/usb/host/ehci-pci.c

@@ -129,7 +129,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 	switch (pdev->vendor) {
 	case PCI_VENDOR_ID_TDI:
 		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
-			ehci->is_tdi_rh_tt = 1;
 			hcd->has_tt = 1;
 			tdi_reset(ehci);
 		}
@@ -379,7 +378,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
 	.hub_control =		ehci_hub_control,
 	.bus_suspend =		ehci_bus_suspend,
 	.bus_resume =		ehci_bus_resume,
-	.relinquish_port = 	ehci_relinquish_port,
+	.relinquish_port =	ehci_relinquish_port,
+	.port_handed_over =	ehci_port_handed_over,
 };
 
 /*-------------------------------------------------------------------------*/

+ 2 - 0
drivers/usb/host/ehci-ppc-of.c

@@ -76,6 +76,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
 	.bus_suspend		= ehci_bus_suspend,
 	.bus_resume		= ehci_bus_resume,
 #endif
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
 };
 
 

+ 1 - 0
drivers/usb/host/ehci-ppc-soc.c

@@ -163,6 +163,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = {
 	.bus_suspend = ehci_bus_suspend,
 	.bus_resume = ehci_bus_resume,
 	.relinquish_port = ehci_relinquish_port,
+	.port_handed_over = ehci_port_handed_over,
 };
 
 static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)

+ 1 - 0
drivers/usb/host/ehci-ps3.c

@@ -73,6 +73,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 	.bus_resume		= ehci_bus_resume,
 #endif
 	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
 };
 
 static int ps3_ehci_probe(struct ps3_system_bus_device *dev)

+ 44 - 23
drivers/usb/host/ehci-sched.c

@@ -1349,18 +1349,27 @@ iso_stream_schedule (
 	/* when's the last uframe this urb could start? */
 	max = now + mod;
 
-	/* typical case: reuse current schedule. stream is still active,
-	 * and no gaps from host falling behind (irq delays etc)
+	/* Typical case: reuse current schedule, stream is still active.
+	 * Hopefully there are no gaps from the host falling behind
+	 * (irq delays etc), but if there are we'll take the next
+	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	if (likely (!list_empty (&stream->td_list))) {
 		start = stream->next_uframe;
 		if (start < now)
 			start += mod;
-		if (likely ((start + sched->span) < max))
-			goto ready;
-		/* else fell behind; someday, try to reschedule */
-		status = -EL2NSYNC;
-		goto fail;
+
+		/* Fell behind (by up to twice the slop amount)? */
+		if (start >= max - 2 * 8 * SCHEDULE_SLOP)
+			start += stream->interval * DIV_ROUND_UP(
+					max - start, stream->interval) - mod;
+
+		/* Tried to schedule too far into the future? */
+		if (unlikely((start + sched->span) >= max)) {
+			status = -EFBIG;
+			goto fail;
+		}
+		goto ready;
 	}
 
 	/* need to schedule; when's the next (u)frame we could start?
@@ -1613,6 +1622,9 @@ itd_complete (
 		} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
 			desc->status = 0;
 			desc->actual_length = EHCI_ITD_LENGTH (t);
+		} else {
+			/* URB was too late */
+			desc->status = -EXDEV;
 		}
 	}
 
@@ -2095,7 +2107,7 @@ done:
 static void
 scan_periodic (struct ehci_hcd *ehci)
 {
-	unsigned	frame, clock, now_uframe, mod;
+	unsigned	now_uframe, frame, clock, clock_frame, mod;
 	unsigned	modified;
 
 	mod = ehci->periodic_size << 3;
@@ -2111,6 +2123,7 @@ scan_periodic (struct ehci_hcd *ehci)
 	else
 		clock = now_uframe + mod - 1;
 	clock %= mod;
+	clock_frame = clock >> 3;
 
 	for (;;) {
 		union ehci_shadow	q, *q_p;
@@ -2157,22 +2170,26 @@ restart:
 			case Q_TYPE_ITD:
 				/* If this ITD is still active, leave it for
 				 * later processing ... check the next entry.
+				 * No need to check for activity unless the
+				 * frame is current.
 				 */
-				rmb ();
-				for (uf = 0; uf < 8 && live; uf++) {
-					if (0 == (q.itd->hw_transaction [uf]
-							& ITD_ACTIVE(ehci)))
-						continue;
-					incomplete = true;
-					q_p = &q.itd->itd_next;
-					hw_p = &q.itd->hw_next;
-					type = Q_NEXT_TYPE(ehci,
+				if (frame == clock_frame && live) {
+					rmb();
+					for (uf = 0; uf < 8; uf++) {
+						if (q.itd->hw_transaction[uf] &
+							    ITD_ACTIVE(ehci))
+							break;
+					}
+					if (uf < 8) {
+						incomplete = true;
+						q_p = &q.itd->itd_next;
+						hw_p = &q.itd->hw_next;
+						type = Q_NEXT_TYPE(ehci,
 							q.itd->hw_next);
-					q = *q_p;
-					break;
+						q = *q_p;
+						break;
+					}
 				}
-				if (uf < 8 && live)
-					break;
 
 				/* Take finished ITDs out of the schedule
 				 * and process them:  recycle, maybe report
@@ -2189,9 +2206,12 @@ restart:
 			case Q_TYPE_SITD:
 				/* If this SITD is still active, leave it for
 				 * later processing ... check the next entry.
+				 * No need to check for activity unless the
+				 * frame is current.
 				 */
-				if ((q.sitd->hw_results & SITD_ACTIVE(ehci))
-						&& live) {
+				if (frame == clock_frame && live &&
+						(q.sitd->hw_results &
+							SITD_ACTIVE(ehci))) {
 					incomplete = true;
 					q_p = &q.sitd->sitd_next;
 					hw_p = &q.sitd->hw_next;
@@ -2260,6 +2280,7 @@ restart:
 
 			/* rescan the rest of this frame, then ... */
 			clock = now;
+			clock_frame = clock >> 3;
 		} else {
 			now_uframe++;
 			now_uframe %= mod;

+ 3 - 2
drivers/usb/host/ehci.h

@@ -97,6 +97,8 @@ struct ehci_hcd {			/* one per controller */
 			dedicated to the companion controller */
 	unsigned long		owned_ports;		/* which ports are
 			owned by the companion during a bus suspend */
+	unsigned long		port_c_suspend;		/* which ports have
+			the change-suspend feature turned on */
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -112,7 +114,6 @@ struct ehci_hcd {			/* one per controller */
 	u32			command;
 
 	/* SILICON QUIRKS */
-	unsigned		is_tdi_rh_tt:1;	/* TDI roothub with TT */
 	unsigned		no_selective_suspend:1;
 	unsigned		has_fsl_port_bug:1; /* FreeScale */
 	unsigned		big_endian_mmio:1;
@@ -678,7 +679,7 @@ struct ehci_fstn {
  * needed (mostly in root hub code).
  */
 
-#define	ehci_is_TDI(e)			((e)->is_tdi_rh_tt)
+#define	ehci_is_TDI(e)			(ehci_to_hcd(e)->has_tt)
 
 /* Returns the speed of a device attached to a port on the root hub. */
 static inline unsigned int

+ 11 - 0
drivers/usb/misc/Kconfig

@@ -269,3 +269,14 @@ config USB_TEST
 	  See <http://www.linux-usb.org/usbtest/> for more information,
 	  including sample test device firmware and "how to use it".
 
+config USB_ISIGHTFW
+	tristate "iSight firmware loading support"
+	depends on USB
+	help
+	  This driver loads firmware for USB Apple iSight cameras, allowing
+	  them to be driven by the USB video class driver available at
+	  http://linux-uvc.berlios.de
+
+	  The firmware for this driver must be extracted from the MacOS
+	  driver beforehand. Tools for doing so are available at
+	  http://bersace03.free.fr

+ 1 - 0
drivers/usb/misc/Makefile

@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_EMI62)		+= emi62.o
 obj-$(CONFIG_USB_FTDI_ELAN)	+= ftdi-elan.o
 obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
 obj-$(CONFIG_USB_IOWARRIOR)	+= iowarrior.o
+obj-$(CONFIG_USB_ISIGHTFW)	+= isight_firmware.o
 obj-$(CONFIG_USB_LCD)		+= usblcd.o
 obj-$(CONFIG_USB_LD)		+= ldusb.o
 obj-$(CONFIG_USB_LED)		+= usbled.o

+ 131 - 0
drivers/usb/misc/isight_firmware.c

@@ -0,0 +1,131 @@
+/*
+ * Driver for loading USB isight firmware
+ *
+ * Copyright (C) 2008 Matthew Garrett <mjg@redhat.com>
+ *
+ * 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.
+ *
+ * The USB isight cameras in recent Apples are roughly compatible with the USB
+ * video class specification, and can be driven by uvcvideo. However, they
+ * need firmware to be loaded beforehand. After firmware loading, the device
+ * detaches from the USB bus and reattaches with a new device ID. It can then
+ * be claimed by the uvc driver.
+ *
+ * The firmware is non-free and must be extracted by the user. Tools to do this
+ * are available at http://bersace03.free.fr/ift/
+ *
+ * The isight firmware loading was reverse engineered by Johannes Berg
+ * <johannes@sipsolutions.de>, and this driver is based on code by Ronald
+ * Bultje <rbultje@ronald.bitfreak.net>
+ */
+
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+static struct usb_device_id id_table[] = {
+	{USB_DEVICE(0x05ac, 0x8300)},
+	{},
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static int isight_firmware_load(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	int llen, len, req, ret = 0;
+	const struct firmware *firmware;
+	unsigned char *buf;
+	unsigned char data[4];
+	char *ptr;
+
+	if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
+		printk(KERN_ERR "Unable to load isight firmware\n");
+		return -ENODEV;
+	}
+
+	ptr = firmware->data;
+
+	if (usb_control_msg
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
+	     300) != 1) {
+		printk(KERN_ERR
+		       "Failed to initialise isight firmware loader\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	while (1) {
+		memcpy(data, ptr, 4);
+		len = (data[0] << 8 | data[1]);
+		req = (data[2] << 8 | data[3]);
+		ptr += 4;
+
+		if (len == 0x8001)
+			break;	/* success */
+		else if (len == 0)
+			continue;
+
+		for (; len > 0; req += 50) {
+			llen = len > 50 ? 50 : len;
+			len -= llen;
+
+			buf = kmalloc(llen, GFP_KERNEL);
+			memcpy(buf, ptr, llen);
+
+			ptr += llen;
+
+			if (usb_control_msg
+			    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0,
+			     buf, llen, 300) != llen) {
+				printk(KERN_ERR
+				       "Failed to load isight firmware\n");
+				kfree(buf);
+				ret = -ENODEV;
+				goto out;
+			}
+
+			kfree(buf);
+		}
+	}
+	if (usb_control_msg
+	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
+	     300) != 1) {
+		printk(KERN_ERR "isight firmware loading completion failed\n");
+		ret = -ENODEV;
+	}
+out:
+	release_firmware(firmware);
+	return ret;
+}
+
+static void isight_firmware_disconnect(struct usb_interface *intf)
+{
+}
+
+static struct usb_driver isight_firmware_driver = {
+	.name = "isight_firmware",
+	.probe = isight_firmware_load,
+	.disconnect = isight_firmware_disconnect,
+	.id_table = id_table,
+};
+
+static int __init isight_firmware_init(void)
+{
+	return usb_register(&isight_firmware_driver);
+}
+
+static void __exit isight_firmware_exit(void)
+{
+	usb_deregister(&isight_firmware_driver);
+}
+
+module_init(isight_firmware_init);
+module_exit(isight_firmware_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");

+ 263 - 1
drivers/usb/serial/ftdi_sio.c

@@ -174,8 +174,270 @@ static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
-	{ USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID),
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) },
+	{ USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },

+ 262 - 5
drivers/usb/serial/ftdi_sio.h

@@ -114,11 +114,268 @@
 #define FTDI_OOCDLINK_PID	0xbaf8	/* Amontec JTAGkey */
 
 /*
- * The following are the values for the Matrix Orbital VK204-25-USB
- * display, which use the FT232RL.
- */
-#define MTXORB_VK_VID		0x1b3d
-#define MTXORB_VK_PID		0x0158
+ * The following are the values for the Matrix Orbital FTDI Range
+ * Anything in this range will use an FT232RL.
+ */
+#define MTXORB_VID			0x1B3D
+#define MTXORB_FTDI_RANGE_0100_PID	0x0100
+#define MTXORB_FTDI_RANGE_0101_PID	0x0101
+#define MTXORB_FTDI_RANGE_0102_PID	0x0102
+#define MTXORB_FTDI_RANGE_0103_PID	0x0103
+#define MTXORB_FTDI_RANGE_0104_PID	0x0104
+#define MTXORB_FTDI_RANGE_0105_PID	0x0105
+#define MTXORB_FTDI_RANGE_0106_PID	0x0106
+#define MTXORB_FTDI_RANGE_0107_PID	0x0107
+#define MTXORB_FTDI_RANGE_0108_PID	0x0108
+#define MTXORB_FTDI_RANGE_0109_PID	0x0109
+#define MTXORB_FTDI_RANGE_010A_PID	0x010A
+#define MTXORB_FTDI_RANGE_010B_PID	0x010B
+#define MTXORB_FTDI_RANGE_010C_PID	0x010C
+#define MTXORB_FTDI_RANGE_010D_PID	0x010D
+#define MTXORB_FTDI_RANGE_010E_PID	0x010E
+#define MTXORB_FTDI_RANGE_010F_PID	0x010F
+#define MTXORB_FTDI_RANGE_0110_PID	0x0110
+#define MTXORB_FTDI_RANGE_0111_PID	0x0111
+#define MTXORB_FTDI_RANGE_0112_PID	0x0112
+#define MTXORB_FTDI_RANGE_0113_PID	0x0113
+#define MTXORB_FTDI_RANGE_0114_PID	0x0114
+#define MTXORB_FTDI_RANGE_0115_PID	0x0115
+#define MTXORB_FTDI_RANGE_0116_PID	0x0116
+#define MTXORB_FTDI_RANGE_0117_PID	0x0117
+#define MTXORB_FTDI_RANGE_0118_PID	0x0118
+#define MTXORB_FTDI_RANGE_0119_PID	0x0119
+#define MTXORB_FTDI_RANGE_011A_PID	0x011A
+#define MTXORB_FTDI_RANGE_011B_PID	0x011B
+#define MTXORB_FTDI_RANGE_011C_PID	0x011C
+#define MTXORB_FTDI_RANGE_011D_PID	0x011D
+#define MTXORB_FTDI_RANGE_011E_PID	0x011E
+#define MTXORB_FTDI_RANGE_011F_PID	0x011F
+#define MTXORB_FTDI_RANGE_0120_PID	0x0120
+#define MTXORB_FTDI_RANGE_0121_PID	0x0121
+#define MTXORB_FTDI_RANGE_0122_PID	0x0122
+#define MTXORB_FTDI_RANGE_0123_PID	0x0123
+#define MTXORB_FTDI_RANGE_0124_PID	0x0124
+#define MTXORB_FTDI_RANGE_0125_PID	0x0125
+#define MTXORB_FTDI_RANGE_0126_PID	0x0126
+#define MTXORB_FTDI_RANGE_0127_PID	0x0127
+#define MTXORB_FTDI_RANGE_0128_PID	0x0128
+#define MTXORB_FTDI_RANGE_0129_PID	0x0129
+#define MTXORB_FTDI_RANGE_012A_PID	0x012A
+#define MTXORB_FTDI_RANGE_012B_PID	0x012B
+#define MTXORB_FTDI_RANGE_012C_PID	0x012C
+#define MTXORB_FTDI_RANGE_012D_PID	0x012D
+#define MTXORB_FTDI_RANGE_012E_PID	0x012E
+#define MTXORB_FTDI_RANGE_012F_PID	0x012F
+#define MTXORB_FTDI_RANGE_0130_PID	0x0130
+#define MTXORB_FTDI_RANGE_0131_PID	0x0131
+#define MTXORB_FTDI_RANGE_0132_PID	0x0132
+#define MTXORB_FTDI_RANGE_0133_PID	0x0133
+#define MTXORB_FTDI_RANGE_0134_PID	0x0134
+#define MTXORB_FTDI_RANGE_0135_PID	0x0135
+#define MTXORB_FTDI_RANGE_0136_PID	0x0136
+#define MTXORB_FTDI_RANGE_0137_PID	0x0137
+#define MTXORB_FTDI_RANGE_0138_PID	0x0138
+#define MTXORB_FTDI_RANGE_0139_PID	0x0139
+#define MTXORB_FTDI_RANGE_013A_PID	0x013A
+#define MTXORB_FTDI_RANGE_013B_PID	0x013B
+#define MTXORB_FTDI_RANGE_013C_PID	0x013C
+#define MTXORB_FTDI_RANGE_013D_PID	0x013D
+#define MTXORB_FTDI_RANGE_013E_PID	0x013E
+#define MTXORB_FTDI_RANGE_013F_PID	0x013F
+#define MTXORB_FTDI_RANGE_0140_PID	0x0140
+#define MTXORB_FTDI_RANGE_0141_PID	0x0141
+#define MTXORB_FTDI_RANGE_0142_PID	0x0142
+#define MTXORB_FTDI_RANGE_0143_PID	0x0143
+#define MTXORB_FTDI_RANGE_0144_PID	0x0144
+#define MTXORB_FTDI_RANGE_0145_PID	0x0145
+#define MTXORB_FTDI_RANGE_0146_PID	0x0146
+#define MTXORB_FTDI_RANGE_0147_PID	0x0147
+#define MTXORB_FTDI_RANGE_0148_PID	0x0148
+#define MTXORB_FTDI_RANGE_0149_PID	0x0149
+#define MTXORB_FTDI_RANGE_014A_PID	0x014A
+#define MTXORB_FTDI_RANGE_014B_PID	0x014B
+#define MTXORB_FTDI_RANGE_014C_PID	0x014C
+#define MTXORB_FTDI_RANGE_014D_PID	0x014D
+#define MTXORB_FTDI_RANGE_014E_PID	0x014E
+#define MTXORB_FTDI_RANGE_014F_PID	0x014F
+#define MTXORB_FTDI_RANGE_0150_PID	0x0150
+#define MTXORB_FTDI_RANGE_0151_PID	0x0151
+#define MTXORB_FTDI_RANGE_0152_PID	0x0152
+#define MTXORB_FTDI_RANGE_0153_PID	0x0153
+#define MTXORB_FTDI_RANGE_0154_PID	0x0154
+#define MTXORB_FTDI_RANGE_0155_PID	0x0155
+#define MTXORB_FTDI_RANGE_0156_PID	0x0156
+#define MTXORB_FTDI_RANGE_0157_PID	0x0157
+#define MTXORB_FTDI_RANGE_0158_PID	0x0158
+#define MTXORB_FTDI_RANGE_0159_PID	0x0159
+#define MTXORB_FTDI_RANGE_015A_PID	0x015A
+#define MTXORB_FTDI_RANGE_015B_PID	0x015B
+#define MTXORB_FTDI_RANGE_015C_PID	0x015C
+#define MTXORB_FTDI_RANGE_015D_PID	0x015D
+#define MTXORB_FTDI_RANGE_015E_PID	0x015E
+#define MTXORB_FTDI_RANGE_015F_PID	0x015F
+#define MTXORB_FTDI_RANGE_0160_PID	0x0160
+#define MTXORB_FTDI_RANGE_0161_PID	0x0161
+#define MTXORB_FTDI_RANGE_0162_PID	0x0162
+#define MTXORB_FTDI_RANGE_0163_PID	0x0163
+#define MTXORB_FTDI_RANGE_0164_PID	0x0164
+#define MTXORB_FTDI_RANGE_0165_PID	0x0165
+#define MTXORB_FTDI_RANGE_0166_PID	0x0166
+#define MTXORB_FTDI_RANGE_0167_PID	0x0167
+#define MTXORB_FTDI_RANGE_0168_PID	0x0168
+#define MTXORB_FTDI_RANGE_0169_PID	0x0169
+#define MTXORB_FTDI_RANGE_016A_PID	0x016A
+#define MTXORB_FTDI_RANGE_016B_PID	0x016B
+#define MTXORB_FTDI_RANGE_016C_PID	0x016C
+#define MTXORB_FTDI_RANGE_016D_PID	0x016D
+#define MTXORB_FTDI_RANGE_016E_PID	0x016E
+#define MTXORB_FTDI_RANGE_016F_PID	0x016F
+#define MTXORB_FTDI_RANGE_0170_PID	0x0170
+#define MTXORB_FTDI_RANGE_0171_PID	0x0171
+#define MTXORB_FTDI_RANGE_0172_PID	0x0172
+#define MTXORB_FTDI_RANGE_0173_PID	0x0173
+#define MTXORB_FTDI_RANGE_0174_PID	0x0174
+#define MTXORB_FTDI_RANGE_0175_PID	0x0175
+#define MTXORB_FTDI_RANGE_0176_PID	0x0176
+#define MTXORB_FTDI_RANGE_0177_PID	0x0177
+#define MTXORB_FTDI_RANGE_0178_PID	0x0178
+#define MTXORB_FTDI_RANGE_0179_PID	0x0179
+#define MTXORB_FTDI_RANGE_017A_PID	0x017A
+#define MTXORB_FTDI_RANGE_017B_PID	0x017B
+#define MTXORB_FTDI_RANGE_017C_PID	0x017C
+#define MTXORB_FTDI_RANGE_017D_PID	0x017D
+#define MTXORB_FTDI_RANGE_017E_PID	0x017E
+#define MTXORB_FTDI_RANGE_017F_PID	0x017F
+#define MTXORB_FTDI_RANGE_0180_PID	0x0180
+#define MTXORB_FTDI_RANGE_0181_PID	0x0181
+#define MTXORB_FTDI_RANGE_0182_PID	0x0182
+#define MTXORB_FTDI_RANGE_0183_PID	0x0183
+#define MTXORB_FTDI_RANGE_0184_PID	0x0184
+#define MTXORB_FTDI_RANGE_0185_PID	0x0185
+#define MTXORB_FTDI_RANGE_0186_PID	0x0186
+#define MTXORB_FTDI_RANGE_0187_PID	0x0187
+#define MTXORB_FTDI_RANGE_0188_PID	0x0188
+#define MTXORB_FTDI_RANGE_0189_PID	0x0189
+#define MTXORB_FTDI_RANGE_018A_PID	0x018A
+#define MTXORB_FTDI_RANGE_018B_PID	0x018B
+#define MTXORB_FTDI_RANGE_018C_PID	0x018C
+#define MTXORB_FTDI_RANGE_018D_PID	0x018D
+#define MTXORB_FTDI_RANGE_018E_PID	0x018E
+#define MTXORB_FTDI_RANGE_018F_PID	0x018F
+#define MTXORB_FTDI_RANGE_0190_PID	0x0190
+#define MTXORB_FTDI_RANGE_0191_PID	0x0191
+#define MTXORB_FTDI_RANGE_0192_PID	0x0192
+#define MTXORB_FTDI_RANGE_0193_PID	0x0193
+#define MTXORB_FTDI_RANGE_0194_PID	0x0194
+#define MTXORB_FTDI_RANGE_0195_PID	0x0195
+#define MTXORB_FTDI_RANGE_0196_PID	0x0196
+#define MTXORB_FTDI_RANGE_0197_PID	0x0197
+#define MTXORB_FTDI_RANGE_0198_PID	0x0198
+#define MTXORB_FTDI_RANGE_0199_PID	0x0199
+#define MTXORB_FTDI_RANGE_019A_PID	0x019A
+#define MTXORB_FTDI_RANGE_019B_PID	0x019B
+#define MTXORB_FTDI_RANGE_019C_PID	0x019C
+#define MTXORB_FTDI_RANGE_019D_PID	0x019D
+#define MTXORB_FTDI_RANGE_019E_PID	0x019E
+#define MTXORB_FTDI_RANGE_019F_PID	0x019F
+#define MTXORB_FTDI_RANGE_01A0_PID	0x01A0
+#define MTXORB_FTDI_RANGE_01A1_PID	0x01A1
+#define MTXORB_FTDI_RANGE_01A2_PID	0x01A2
+#define MTXORB_FTDI_RANGE_01A3_PID	0x01A3
+#define MTXORB_FTDI_RANGE_01A4_PID	0x01A4
+#define MTXORB_FTDI_RANGE_01A5_PID	0x01A5
+#define MTXORB_FTDI_RANGE_01A6_PID	0x01A6
+#define MTXORB_FTDI_RANGE_01A7_PID	0x01A7
+#define MTXORB_FTDI_RANGE_01A8_PID	0x01A8
+#define MTXORB_FTDI_RANGE_01A9_PID	0x01A9
+#define MTXORB_FTDI_RANGE_01AA_PID	0x01AA
+#define MTXORB_FTDI_RANGE_01AB_PID	0x01AB
+#define MTXORB_FTDI_RANGE_01AC_PID	0x01AC
+#define MTXORB_FTDI_RANGE_01AD_PID	0x01AD
+#define MTXORB_FTDI_RANGE_01AE_PID	0x01AE
+#define MTXORB_FTDI_RANGE_01AF_PID	0x01AF
+#define MTXORB_FTDI_RANGE_01B0_PID	0x01B0
+#define MTXORB_FTDI_RANGE_01B1_PID	0x01B1
+#define MTXORB_FTDI_RANGE_01B2_PID	0x01B2
+#define MTXORB_FTDI_RANGE_01B3_PID	0x01B3
+#define MTXORB_FTDI_RANGE_01B4_PID	0x01B4
+#define MTXORB_FTDI_RANGE_01B5_PID	0x01B5
+#define MTXORB_FTDI_RANGE_01B6_PID	0x01B6
+#define MTXORB_FTDI_RANGE_01B7_PID	0x01B7
+#define MTXORB_FTDI_RANGE_01B8_PID	0x01B8
+#define MTXORB_FTDI_RANGE_01B9_PID	0x01B9
+#define MTXORB_FTDI_RANGE_01BA_PID	0x01BA
+#define MTXORB_FTDI_RANGE_01BB_PID	0x01BB
+#define MTXORB_FTDI_RANGE_01BC_PID	0x01BC
+#define MTXORB_FTDI_RANGE_01BD_PID	0x01BD
+#define MTXORB_FTDI_RANGE_01BE_PID	0x01BE
+#define MTXORB_FTDI_RANGE_01BF_PID	0x01BF
+#define MTXORB_FTDI_RANGE_01C0_PID	0x01C0
+#define MTXORB_FTDI_RANGE_01C1_PID	0x01C1
+#define MTXORB_FTDI_RANGE_01C2_PID	0x01C2
+#define MTXORB_FTDI_RANGE_01C3_PID	0x01C3
+#define MTXORB_FTDI_RANGE_01C4_PID	0x01C4
+#define MTXORB_FTDI_RANGE_01C5_PID	0x01C5
+#define MTXORB_FTDI_RANGE_01C6_PID	0x01C6
+#define MTXORB_FTDI_RANGE_01C7_PID	0x01C7
+#define MTXORB_FTDI_RANGE_01C8_PID	0x01C8
+#define MTXORB_FTDI_RANGE_01C9_PID	0x01C9
+#define MTXORB_FTDI_RANGE_01CA_PID	0x01CA
+#define MTXORB_FTDI_RANGE_01CB_PID	0x01CB
+#define MTXORB_FTDI_RANGE_01CC_PID	0x01CC
+#define MTXORB_FTDI_RANGE_01CD_PID	0x01CD
+#define MTXORB_FTDI_RANGE_01CE_PID	0x01CE
+#define MTXORB_FTDI_RANGE_01CF_PID	0x01CF
+#define MTXORB_FTDI_RANGE_01D0_PID	0x01D0
+#define MTXORB_FTDI_RANGE_01D1_PID	0x01D1
+#define MTXORB_FTDI_RANGE_01D2_PID	0x01D2
+#define MTXORB_FTDI_RANGE_01D3_PID	0x01D3
+#define MTXORB_FTDI_RANGE_01D4_PID	0x01D4
+#define MTXORB_FTDI_RANGE_01D5_PID	0x01D5
+#define MTXORB_FTDI_RANGE_01D6_PID	0x01D6
+#define MTXORB_FTDI_RANGE_01D7_PID	0x01D7
+#define MTXORB_FTDI_RANGE_01D8_PID	0x01D8
+#define MTXORB_FTDI_RANGE_01D9_PID	0x01D9
+#define MTXORB_FTDI_RANGE_01DA_PID	0x01DA
+#define MTXORB_FTDI_RANGE_01DB_PID	0x01DB
+#define MTXORB_FTDI_RANGE_01DC_PID	0x01DC
+#define MTXORB_FTDI_RANGE_01DD_PID	0x01DD
+#define MTXORB_FTDI_RANGE_01DE_PID	0x01DE
+#define MTXORB_FTDI_RANGE_01DF_PID	0x01DF
+#define MTXORB_FTDI_RANGE_01E0_PID	0x01E0
+#define MTXORB_FTDI_RANGE_01E1_PID	0x01E1
+#define MTXORB_FTDI_RANGE_01E2_PID	0x01E2
+#define MTXORB_FTDI_RANGE_01E3_PID	0x01E3
+#define MTXORB_FTDI_RANGE_01E4_PID	0x01E4
+#define MTXORB_FTDI_RANGE_01E5_PID	0x01E5
+#define MTXORB_FTDI_RANGE_01E6_PID	0x01E6
+#define MTXORB_FTDI_RANGE_01E7_PID	0x01E7
+#define MTXORB_FTDI_RANGE_01E8_PID	0x01E8
+#define MTXORB_FTDI_RANGE_01E9_PID	0x01E9
+#define MTXORB_FTDI_RANGE_01EA_PID	0x01EA
+#define MTXORB_FTDI_RANGE_01EB_PID	0x01EB
+#define MTXORB_FTDI_RANGE_01EC_PID	0x01EC
+#define MTXORB_FTDI_RANGE_01ED_PID	0x01ED
+#define MTXORB_FTDI_RANGE_01EE_PID	0x01EE
+#define MTXORB_FTDI_RANGE_01EF_PID	0x01EF
+#define MTXORB_FTDI_RANGE_01F0_PID	0x01F0
+#define MTXORB_FTDI_RANGE_01F1_PID	0x01F1
+#define MTXORB_FTDI_RANGE_01F2_PID	0x01F2
+#define MTXORB_FTDI_RANGE_01F3_PID	0x01F3
+#define MTXORB_FTDI_RANGE_01F4_PID	0x01F4
+#define MTXORB_FTDI_RANGE_01F5_PID	0x01F5
+#define MTXORB_FTDI_RANGE_01F6_PID	0x01F6
+#define MTXORB_FTDI_RANGE_01F7_PID	0x01F7
+#define MTXORB_FTDI_RANGE_01F8_PID	0x01F8
+#define MTXORB_FTDI_RANGE_01F9_PID	0x01F9
+#define MTXORB_FTDI_RANGE_01FA_PID	0x01FA
+#define MTXORB_FTDI_RANGE_01FB_PID	0x01FB
+#define MTXORB_FTDI_RANGE_01FC_PID	0x01FC
+#define MTXORB_FTDI_RANGE_01FD_PID	0x01FD
+#define MTXORB_FTDI_RANGE_01FE_PID	0x01FE
+#define MTXORB_FTDI_RANGE_01FF_PID	0x01FF
+
+
 
 /* Interbiometrics USB I/O Board */
 /* Developed for Interbiometrics by Rudolf Gugler */

+ 17 - 17
drivers/usb/serial/option.c

@@ -236,25 +236,25 @@ static struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */

+ 1 - 0
drivers/usb/serial/pl2303.c

@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
+	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },

+ 1 - 0
drivers/usb/serial/pl2303.h

@@ -14,6 +14,7 @@
 #define PL2303_PRODUCT_ID_PHAROS	0xaaa0
 #define PL2303_PRODUCT_ID_RSAQ3		0xaaa2
 #define PL2303_PRODUCT_ID_ALDIGA	0x0611
+#define PL2303_PRODUCT_ID_MMX		0x0612
 
 #define ATEN_VENDOR_ID		0x0557
 #define ATEN_VENDOR_ID2		0x0547

+ 6 - 4
drivers/usb/storage/unusual_devs.h

@@ -405,7 +405,7 @@ UNUSUAL_DEV(  0x04a5, 0x3010, 0x0100, 0x0100,
 UNUSUAL_DEV(  0x04b4, 0x6830, 0x0000, 0x9999,
 		"Cypress",
 		"Cypress AT2LP",
-		US_SC_CYP_ATACB, US_PR_BULK, NULL,
+		US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
 		0),
 #endif
 
@@ -1522,7 +1522,7 @@ UNUSUAL_DEV(  0x0fce, 0xe031, 0x0000, 0x0000,
 		"Sony Ericsson",
 		"M600i",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_CAPACITY ),
+		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
 
 /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
@@ -1716,10 +1716,12 @@ UNUSUAL_DEV(  0x22b8, 0x3010, 0x0001, 0x0001,
 /*
  * Patch by Pete Zaitcev <zaitcev@redhat.com>
  * Report by Mark Patton. Red Hat bz#208928.
+ * Added support for rev 0x0002 (Motorola ROKR W5)
+ * by Javier Smaldone <javier@smaldone.com.ar>
  */
-UNUSUAL_DEV(  0x22b8, 0x4810, 0x0001, 0x0001,
+UNUSUAL_DEV(  0x22b8, 0x4810, 0x0001, 0x0002,
 		"Motorola",
-		"RAZR V3i",
+		"RAZR V3i/ROKR W5",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),