From: Greg Kroah-Hartman Date: Thu, 14 Mar 2013 20:24:55 +0000 (-0700) Subject: 3.8-stable patches X-Git-Tag: v3.0.70~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=34a069e8298639b5d7388213936640099292ea06;p=thirdparty%2Fkernel%2Fstable-queue.git 3.8-stable patches added patches: qcserial-bind-to-dm-diag-port-on-gobi-1k-devices.patch staging-comedi-dt9812-use-cr_chan-for-channel-number.patch staging-vt6656-fix-oops-on-resume-from-suspend.patch usb-added-support-for-cinterion-s-products-ah6-and-pls8.patch usb-cp210x-new-vendor-device-ids.patch usb-dwc3-core-don-t-forget-to-free-coherent-memory.patch usb-ehci-don-t-check-dma-values-in-qh-overlays.patch usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch usb-serial-add-rigblaster-advantage-to-device-table.patch usb-storage-fix-huawei-mode-switching-regression.patch --- diff --git a/queue-3.8/qcserial-bind-to-dm-diag-port-on-gobi-1k-devices.patch b/queue-3.8/qcserial-bind-to-dm-diag-port-on-gobi-1k-devices.patch new file mode 100644 index 00000000000..4d6550891b1 --- /dev/null +++ b/queue-3.8/qcserial-bind-to-dm-diag-port-on-gobi-1k-devices.patch @@ -0,0 +1,38 @@ +From 3f8bc5e4da29c7e05edeca6b475abb4fb01a5a13 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 13 Mar 2013 09:58:18 -0500 +Subject: qcserial: bind to DM/DIAG port on Gobi 1K devices + +From: Dan Williams + +commit 3f8bc5e4da29c7e05edeca6b475abb4fb01a5a13 upstream. + +Turns out we just need altsetting 1 and then we can talk to it. + +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/qcserial.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/qcserial.c ++++ b/drivers/usb/serial/qcserial.c +@@ -197,12 +197,15 @@ static int qcprobe(struct usb_serial *se + + if (is_gobi1k) { + /* Gobi 1K USB layout: +- * 0: serial port (doesn't respond) ++ * 0: DM/DIAG (use libqcdm from ModemManager for communication) + * 1: serial port (doesn't respond) + * 2: AT-capable modem port + * 3: QMI/net + */ +- if (ifnum == 2) ++ if (ifnum == 0) { ++ dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n"); ++ altsetting = 1; ++ } else if (ifnum == 2) + dev_dbg(dev, "Modem port found\n"); + else + altsetting = -1; diff --git a/queue-3.8/series b/queue-3.8/series index 99b38105903..cf17221eefd 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -4,3 +4,13 @@ virtio-rng-disallow-multiple-device-registrations-fixes-crashes.patch usb-option-add-huawei-e5331.patch usb-cdc-wdm-fix-buffer-overflow.patch tools-usb-ffs-test-fix-build-failure.patch +usb-dwc3-core-don-t-forget-to-free-coherent-memory.patch +usb-cp210x-new-vendor-device-ids.patch +usb-added-support-for-cinterion-s-products-ah6-and-pls8.patch +usb-serial-add-rigblaster-advantage-to-device-table.patch +usb-storage-fix-huawei-mode-switching-regression.patch +usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch +usb-ehci-don-t-check-dma-values-in-qh-overlays.patch +staging-vt6656-fix-oops-on-resume-from-suspend.patch +staging-comedi-dt9812-use-cr_chan-for-channel-number.patch +qcserial-bind-to-dm-diag-port-on-gobi-1k-devices.patch diff --git a/queue-3.8/staging-comedi-dt9812-use-cr_chan-for-channel-number.patch b/queue-3.8/staging-comedi-dt9812-use-cr_chan-for-channel-number.patch new file mode 100644 index 00000000000..316b8a86a87 --- /dev/null +++ b/queue-3.8/staging-comedi-dt9812-use-cr_chan-for-channel-number.patch @@ -0,0 +1,101 @@ +From 564c526a1bed5e42b5cd52cfe1752c4296ef17a6 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Tue, 5 Mar 2013 13:13:44 +0000 +Subject: staging: comedi: dt9812: use CR_CHAN() for channel number + +From: Ian Abbott + +commit 564c526a1bed5e42b5cd52cfe1752c4296ef17a6 upstream. + +As pointed out by Dan Carpenper in +, +the dt9812 comedi driver's use of the `chanspec` member of `struct +comedi_insn` as a channel number is incorrect. Change it to use +`CR_CHAN(insn->chanspec)` as the channel number (where `insn` is a +pointer to the `struct comedi_insn` being processed). + +Reported-by: Dan Carpenter +Cc: Anders Blomdell +Signed-off-by: Ian Abbott +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/comedi/drivers/dt9812.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/staging/comedi/drivers/dt9812.c ++++ b/drivers/staging/comedi/drivers/dt9812.c +@@ -948,12 +948,13 @@ static int dt9812_di_rinsn(struct comedi + unsigned int *data) + { + struct comedi_dt9812 *devpriv = dev->private; ++ unsigned int channel = CR_CHAN(insn->chanspec); + int n; + u8 bits = 0; + + dt9812_digital_in(devpriv->slot, &bits); + for (n = 0; n < insn->n; n++) +- data[n] = ((1 << insn->chanspec) & bits) != 0; ++ data[n] = ((1 << channel) & bits) != 0; + return n; + } + +@@ -962,12 +963,13 @@ static int dt9812_do_winsn(struct comedi + unsigned int *data) + { + struct comedi_dt9812 *devpriv = dev->private; ++ unsigned int channel = CR_CHAN(insn->chanspec); + int n; + u8 bits = 0; + + dt9812_digital_out_shadow(devpriv->slot, &bits); + for (n = 0; n < insn->n; n++) { +- u8 mask = 1 << insn->chanspec; ++ u8 mask = 1 << channel; + + bits &= ~mask; + if (data[n]) +@@ -982,13 +984,13 @@ static int dt9812_ai_rinsn(struct comedi + unsigned int *data) + { + struct comedi_dt9812 *devpriv = dev->private; ++ unsigned int channel = CR_CHAN(insn->chanspec); + int n; + + for (n = 0; n < insn->n; n++) { + u16 value = 0; + +- dt9812_analog_in(devpriv->slot, insn->chanspec, &value, +- DT9812_GAIN_1); ++ dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1); + data[n] = value; + } + return n; +@@ -999,12 +1001,13 @@ static int dt9812_ao_rinsn(struct comedi + unsigned int *data) + { + struct comedi_dt9812 *devpriv = dev->private; ++ unsigned int channel = CR_CHAN(insn->chanspec); + int n; + u16 value; + + for (n = 0; n < insn->n; n++) { + value = 0; +- dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value); ++ dt9812_analog_out_shadow(devpriv->slot, channel, &value); + data[n] = value; + } + return n; +@@ -1015,10 +1018,11 @@ static int dt9812_ao_winsn(struct comedi + unsigned int *data) + { + struct comedi_dt9812 *devpriv = dev->private; ++ unsigned int channel = CR_CHAN(insn->chanspec); + int n; + + for (n = 0; n < insn->n; n++) +- dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]); ++ dt9812_analog_out(devpriv->slot, channel, data[n]); + return n; + } + diff --git a/queue-3.8/staging-vt6656-fix-oops-on-resume-from-suspend.patch b/queue-3.8/staging-vt6656-fix-oops-on-resume-from-suspend.patch new file mode 100644 index 00000000000..1b6c29cf815 --- /dev/null +++ b/queue-3.8/staging-vt6656-fix-oops-on-resume-from-suspend.patch @@ -0,0 +1,41 @@ +From 6987a6dabfc40222ef767f67b57212fe3a0225fb Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley +Date: Mon, 18 Feb 2013 19:54:18 +0000 +Subject: staging: vt6656: Fix oops on resume from suspend. + +From: Malcolm Priestley + +commit 6987a6dabfc40222ef767f67b57212fe3a0225fb upstream. + +Remove usb_put_dev from vt6656_suspend and usb_get_dev +from vt6566_resume. + +These are not normally in suspend/resume functions. + +Signed-off-by: Malcolm Priestley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/vt6656/main_usb.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -644,8 +644,6 @@ static int vt6656_suspend(struct usb_int + if (device->flags & DEVICE_FLAGS_OPENED) + device_close(device->dev); + +- usb_put_dev(interface_to_usbdev(intf)); +- + return 0; + } + +@@ -656,8 +654,6 @@ static int vt6656_resume(struct usb_inte + if (!device || !device->dev) + return -ENODEV; + +- usb_get_dev(interface_to_usbdev(intf)); +- + if (!(device->flags & DEVICE_FLAGS_OPENED)) + device_open(device->dev); + diff --git a/queue-3.8/usb-added-support-for-cinterion-s-products-ah6-and-pls8.patch b/queue-3.8/usb-added-support-for-cinterion-s-products-ah6-and-pls8.patch new file mode 100644 index 00000000000..dbea31d12ec --- /dev/null +++ b/queue-3.8/usb-added-support-for-cinterion-s-products-ah6-and-pls8.patch @@ -0,0 +1,39 @@ +From 1941138e1c024ecb5bd797d414928d3eb94d8662 Mon Sep 17 00:00:00 2001 +From: Christian Schmiedl +Date: Wed, 6 Mar 2013 17:08:50 +0100 +Subject: USB: added support for Cinterion's products AH6 and PLS8 + +From: Christian Schmiedl + +commit 1941138e1c024ecb5bd797d414928d3eb94d8662 upstream. + +add support for Cinterion's products AH6 and PLS8 by adding Product IDs +and USB_DEVICE tuples. + +Signed-off-by: Christian Schmiedl +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -341,6 +341,8 @@ static void option_instat_callback(struc + #define CINTERION_PRODUCT_EU3_E 0x0051 + #define CINTERION_PRODUCT_EU3_P 0x0052 + #define CINTERION_PRODUCT_PH8 0x0053 ++#define CINTERION_PRODUCT_AH6 0x0055 ++#define CINTERION_PRODUCT_PLS8 0x0060 + + /* Olivetti products */ + #define OLIVETTI_VENDOR_ID 0x0b3c +@@ -1261,6 +1263,8 @@ static const struct usb_device_id option + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, ++ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, diff --git a/queue-3.8/usb-cp210x-new-vendor-device-ids.patch b/queue-3.8/usb-cp210x-new-vendor-device-ids.patch new file mode 100644 index 00000000000..2dc112fefda --- /dev/null +++ b/queue-3.8/usb-cp210x-new-vendor-device-ids.patch @@ -0,0 +1,53 @@ +From be3101c23394af59694c8a2aae6d07f5da62fea5 Mon Sep 17 00:00:00 2001 +From: "Matwey V. Kornilov" +Date: Sat, 9 Mar 2013 13:57:32 +0400 +Subject: usb: cp210x new Vendor/Device IDs + +From: "Matwey V. Kornilov" + +commit be3101c23394af59694c8a2aae6d07f5da62fea5 upstream. + +This patch adds support for the Lake Shore Cryotronics devices to +the CP210x driver. + +These lines are ported from cp210x driver distributed by Lake Shore web site: + http://www.lakeshore.com/Documents/Lake%20Shore%20cp210x-3.0.0.tar.gz +and licensed under the terms of GPLv2. + +Moreover, I've tested this changes with Lake Shore 335 in my labs. + +Signed-off-by: Matwey V. Kornilov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -150,6 +150,25 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ ++ { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */ ++ { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */ ++ { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */ ++ { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */ ++ { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */ ++ { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */ ++ { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */ ++ { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */ ++ { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */ ++ { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */ ++ { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */ ++ { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */ ++ { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */ ++ { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */ ++ { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */ ++ { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */ ++ { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ ++ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ ++ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ + { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ diff --git a/queue-3.8/usb-dwc3-core-don-t-forget-to-free-coherent-memory.patch b/queue-3.8/usb-dwc3-core-don-t-forget-to-free-coherent-memory.patch new file mode 100644 index 00000000000..ebb8a1fedf9 --- /dev/null +++ b/queue-3.8/usb-dwc3-core-don-t-forget-to-free-coherent-memory.patch @@ -0,0 +1,39 @@ +From d9b4330adec006c2e8907bdcacd9dcc0e8874d18 Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Fri, 8 Feb 2013 15:14:16 +0200 +Subject: usb: dwc3: core: don't forget to free coherent memory + +From: Felipe Balbi + +commit d9b4330adec006c2e8907bdcacd9dcc0e8874d18 upstream. + +commit 3921426 (usb: dwc3: core: move +event buffer allocation out of +dwc3_core_init()) introduced a memory leak +of the coherent memory we use as event +buffers on dwc3 driver. + +If the driver is compiled as a dynamically +loadable module and use constantly loads +and unloads the driver, we will continue +to leak the coherent memory allocated during +->probe() because dwc3_free_event_buffers() +is never called during ->remove(). + +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/core.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -575,6 +575,7 @@ static int dwc3_remove(struct platform_d + break; + } + ++ dwc3_free_event_buffers(dwc); + dwc3_core_exit(dwc); + + return 0; diff --git a/queue-3.8/usb-ehci-don-t-check-dma-values-in-qh-overlays.patch b/queue-3.8/usb-ehci-don-t-check-dma-values-in-qh-overlays.patch new file mode 100644 index 00000000000..52f3ef9e6e5 --- /dev/null +++ b/queue-3.8/usb-ehci-don-t-check-dma-values-in-qh-overlays.patch @@ -0,0 +1,74 @@ +From feca7746d5d9e84b105a613b7f3b6ad00d327372 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 1 Mar 2013 10:51:15 -0500 +Subject: USB: EHCI: don't check DMA values in QH overlays + +From: Alan Stern + +commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream. + +This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a +couple of places, the driver compares the DMA address stored in a QH's +overlay region with the address of a particular qTD, in order to see +whether that qTD is the one currently being processed by the hardware. +(If it is then the status in the QH's overlay region is more +up-to-date than the status in the qTD, and if it isn't then the +overlay's value needs to be adjusted when the QH is added back to the +active schedule.) + +However, DMA address in the overlay region isn't always valid. It +sometimes will contain a stale value, which may happen by coincidence +to be equal to a qTD's DMA address. Instead of checking the DMA +address, we should check whether the overlay region is active and +valid. The patch tests the ACTIVE bit in the overlay, and clears this +bit when the overlay becomes invalid (which happens when the +currently-executing URB is unlinked). + +This is the second part of a fix for the regression reported at: + + https://bugs.launchpad.net/bugs/1088733 + +Signed-off-by: Alan Stern +Reported-by: Joseph Salisbury +Reported-and-tested-by: Stephen Thirlwall +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-q.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struc + * qtd is updated in qh_completions(). Update the QH + * overlay here. + */ +- if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { ++ if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { + qh->hw->hw_qtd_next = qtd->hw_next; + qtd = NULL; + } +@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, s + else if (last_status == -EINPROGRESS && !urb->unlinked) + continue; + +- /* qh unlinked; token in overlay may be most current */ +- if (state == QH_STATE_IDLE +- && cpu_to_hc32(ehci, qtd->qtd_dma) +- == hw->hw_current) { ++ /* ++ * If this was the active qtd when the qh was unlinked ++ * and the overlay's token is active, then the overlay ++ * hasn't been written back to the qtd yet so use its ++ * token instead of the qtd's. After the qtd is ++ * processed and removed, the overlay won't be valid ++ * any more. ++ */ ++ if (state == QH_STATE_IDLE && ++ qh->qtd_list.next == &qtd->qtd_list && ++ (hw->hw_token & ACTIVE_BIT(ehci))) { + token = hc32_to_cpu(ehci, hw->hw_token); ++ hw->hw_token &= ~ACTIVE_BIT(ehci); + + /* An unlink may leave an incomplete + * async transaction in the TT buffer. diff --git a/queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch b/queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch new file mode 100644 index 00000000000..4a3ce47d1da --- /dev/null +++ b/queue-3.8/usb-ehci-work-around-silicon-bug-in-intel-s-ehci-controllers.patch @@ -0,0 +1,95 @@ +From 6402c796d3b4205d3d7296157956c5100a05d7d6 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 1 Mar 2013 10:50:08 -0500 +Subject: USB: EHCI: work around silicon bug in Intel's EHCI controllers + +From: Alan Stern + +commit 6402c796d3b4205d3d7296157956c5100a05d7d6 upstream. + +This patch (as1660) works around a hardware problem present in some +(if not all) Intel EHCI controllers. After a QH has been unlinked +from the async schedule and the corresponding IAA interrupt has +occurred, the controller is not supposed access the QH and its qTDs. +There certainly shouldn't be any more DMA writes to those structures. +Nevertheless, Intel's controllers have been observed to perform a +final writeback to the QH's overlay region and to the most recent qTD. +For more information and a test program to determine whether this +problem is present in a particular controller, see + + http://marc.info/?l=linux-usb&m=135492071812265&w=2 + http://marc.info/?l=linux-usb&m=136182570800963&w=2 + +This patch works around the problem by always waiting for two IAA +cycles when unlinking an async QH. The extra IAA delay gives the +controller time to perform its final writeback. + +Surprisingly enough, the effects of this silicon bug have gone +undetected until quite recently. More through luck than anything +else, it hasn't caused any apparent problems. However, it does +interact badly with the path that follows this one, so it needs to be +addressed. + +This is the first part of a fix for the regression reported at: + + https://bugs.launchpad.net/bugs/1088733 + +Signed-off-by: Alan Stern +Tested-by: Stephen Thirlwall +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hcd.c | 6 ++---- + drivers/usb/host/ehci-q.c | 18 ++++++++++++++---- + 2 files changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_ + /* guard against (alleged) silicon errata */ + if (cmd & CMD_IAAD) + ehci_dbg(ehci, "IAA with IAAD still set?\n"); +- if (ehci->async_iaa) { ++ if (ehci->async_iaa) + COUNT(ehci->stats.iaa); +- end_unlink_async(ehci); +- } else +- ehci_dbg(ehci, "IAA with nothing unlinked?\n"); ++ end_unlink_async(ehci); + } + + /* remote wakeup [4.3.1] */ +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -1170,7 +1170,7 @@ static void single_unlink_async(struct e + struct ehci_qh *prev; + + /* Add to the end of the list of QHs waiting for the next IAAD */ +- qh->qh_state = QH_STATE_UNLINK; ++ qh->qh_state = QH_STATE_UNLINK_WAIT; + if (ehci->async_unlink) + ehci->async_unlink_last->unlink_next = qh; + else +@@ -1213,9 +1213,19 @@ static void start_iaa_cycle(struct ehci_ + + /* Do only the first waiting QH (nVidia bug?) */ + qh = ehci->async_unlink; +- ehci->async_iaa = qh; +- ehci->async_unlink = qh->unlink_next; +- qh->unlink_next = NULL; ++ ++ /* ++ * Intel (?) bug: The HC can write back the overlay region ++ * even after the IAA interrupt occurs. In self-defense, ++ * always go through two IAA cycles for each QH. ++ */ ++ if (qh->qh_state == QH_STATE_UNLINK_WAIT) { ++ qh->qh_state = QH_STATE_UNLINK; ++ } else { ++ ehci->async_iaa = qh; ++ ehci->async_unlink = qh->unlink_next; ++ qh->unlink_next = NULL; ++ } + + /* Make sure the unlinks are all visible to the hardware */ + wmb(); diff --git a/queue-3.8/usb-serial-add-rigblaster-advantage-to-device-table.patch b/queue-3.8/usb-serial-add-rigblaster-advantage-to-device-table.patch new file mode 100644 index 00000000000..04558e71c48 --- /dev/null +++ b/queue-3.8/usb-serial-add-rigblaster-advantage-to-device-table.patch @@ -0,0 +1,30 @@ +From a57e82a18779ab8a5e5a1f5841cef937cf578913 Mon Sep 17 00:00:00 2001 +From: Steve Conklin +Date: Thu, 7 Mar 2013 17:19:33 -0600 +Subject: usb: serial: Add Rigblaster Advantage to device table + +From: Steve Conklin + +commit a57e82a18779ab8a5e5a1f5841cef937cf578913 upstream. + +The Rigblaster Advantage is an amateur radio interface sold by West Mountain +Radio. It contains a cp210x serial interface but the device ID is not in +the driver. + +Signed-off-by: Steve Conklin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -85,6 +85,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ + { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ + { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ ++ { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */ + { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ + { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ diff --git a/queue-3.8/usb-storage-fix-huawei-mode-switching-regression.patch b/queue-3.8/usb-storage-fix-huawei-mode-switching-regression.patch new file mode 100644 index 00000000000..212eb6adf80 --- /dev/null +++ b/queue-3.8/usb-storage-fix-huawei-mode-switching-regression.patch @@ -0,0 +1,492 @@ +From ab4b71644a26d1ab92b987b2fd30e17c25e89f85 Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +Date: Mon, 4 Mar 2013 14:19:21 +0100 +Subject: USB: storage: fix Huawei mode switching regression + +From: Bjørn Mork + +commit ab4b71644a26d1ab92b987b2fd30e17c25e89f85 upstream. + +This reverts commit 200e0d99 ("USB: storage: optimize to match the +Huawei USB storage devices and support new switch command" and the +followup bugfix commit cd060956 ("USB: storage: properly handle +the endian issues of idProduct"). + +The commit effectively added a large number of Huawei devices to +the deprecated usb-storage mode switching logic. Many of these +devices have been in use and supported by the userspace +usb_modeswitch utility for years. Forcing the switching inside +the kernel causes a number of regressions as a result of ignoring +existing onfigurations, and also completely takes away the ability +to configure mode switching per device/system/user. + +Known regressions caused by this: + - Some of the devices support multiple modes, using different + switching commands. There are existing configurations taking + advantage of this. + + - There is a real use case for disabling mode switching and + instead mounting the exposed storage device. This becomes + impossible with switching logic inside the usb-storage driver. + + - At least on device fail as a result of the usb-storage switching + command, becoming completely unswitchable. This is possibly a + firmware bug, but still a regression because the device work as + expected using usb_modeswitch defaults. + +In-kernel mode switching was deprecated years ago with the +development of the more user friendly userspace alternatives. The +existing list of devices in usb-storage was only kept to prevent +breaking already working systems. The long term plan is to remove +the list, not to add to it. Ref: +http://permalink.gmane.org/gmane.linux.usb.general/28543 + +Signed-off-by: Bjørn Mork +Cc: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/initializers.c | 76 -------- + drivers/usb/storage/initializers.h | 4 + drivers/usb/storage/unusual_devs.h | 329 ++++++++++++++++++++++++++++++++++++- + 3 files changed, 331 insertions(+), 78 deletions(-) + +--- a/drivers/usb/storage/initializers.c ++++ b/drivers/usb/storage/initializers.c +@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_dat + return 0; + } + +-/* This places the HUAWEI usb dongles in multi-port mode */ +-static int usb_stor_huawei_feature_init(struct us_data *us) ++/* This places the HUAWEI E220 devices in multi-port mode */ ++int usb_stor_huawei_e220_init(struct us_data *us) + { + int result; + +@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init( + US_DEBUGP("Huawei mode set result is %d\n", result); + return 0; + } +- +-/* +- * It will send a scsi switch command called rewind' to huawei dongle. +- * When the dongle receives this command at the first time, +- * it will reboot immediately. After rebooted, it will ignore this command. +- * So it is unnecessary to read its response. +- */ +-static int usb_stor_huawei_scsi_init(struct us_data *us) +-{ +- int result = 0; +- int act_len = 0; +- struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; +- char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, +- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +- +- bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); +- bcbw->Tag = 0; +- bcbw->DataTransferLength = 0; +- bcbw->Flags = bcbw->Lun = 0; +- bcbw->Length = sizeof(rewind_cmd); +- memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); +- memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); +- +- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, +- US_BULK_CB_WRAP_LEN, &act_len); +- US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); +- return result; +-} +- +-/* +- * It tries to find the supported Huawei USB dongles. +- * In Huawei, they assign the following product IDs +- * for all of their mobile broadband dongles, +- * including the new dongles in the future. +- * So if the product ID is not included in this list, +- * it means it is not Huawei's mobile broadband dongles. +- */ +-static int usb_stor_huawei_dongles_pid(struct us_data *us) +-{ +- struct usb_interface_descriptor *idesc; +- int idProduct; +- +- idesc = &us->pusb_intf->cur_altsetting->desc; +- idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); +- /* The first port is CDROM, +- * means the dongle in the single port mode, +- * and a switch command is required to be sent. */ +- if (idesc && idesc->bInterfaceNumber == 0) { +- if ((idProduct == 0x1001) +- || (idProduct == 0x1003) +- || (idProduct == 0x1004) +- || (idProduct >= 0x1401 && idProduct <= 0x1500) +- || (idProduct >= 0x1505 && idProduct <= 0x1600) +- || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { +- return 1; +- } +- } +- return 0; +-} +- +-int usb_stor_huawei_init(struct us_data *us) +-{ +- int result = 0; +- +- if (usb_stor_huawei_dongles_pid(us)) { +- if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) +- result = usb_stor_huawei_scsi_init(us); +- else +- result = usb_stor_huawei_feature_init(us); +- } +- return result; +-} +--- a/drivers/usb/storage/initializers.h ++++ b/drivers/usb/storage/initializers.h +@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data + * flash reader */ + int usb_stor_ucr61s2b_init(struct us_data *us); + +-/* This places the HUAWEI usb dongles in multi-port mode */ +-int usb_stor_huawei_init(struct us_data *us); ++/* This places the HUAWEI E220 devices in multi-port mode */ ++int usb_stor_huawei_e220_init(struct us_data *us); +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1527,10 +1527,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x + /* Reported by fangxiaozhi + * This brings the HUAWEI data card devices into multi-port mode + */ +-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, ++UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", +- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, ++ 0), ++UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, ++ "HUAWEI MOBILE", ++ "Mass Storage", ++ USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), + + /* Reported by Vilius Bilinkevicius