From: Greg Kroah-Hartman Date: Wed, 18 Dec 2013 18:12:33 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.75~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f61f04cde66a01a4ec8c178d750e4d5b60aefaed;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: futex-fix-handling-of-read-only-mapped-hugepages.patch input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch media-af9035-fix-broken-i2c-and-usb-i-o.patch nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch pci-disable-bus-master-only-on-kexec-reboot.patch usb-dwc3-fix-implementation-of-endpoint-wedge.patch usb-gadget-composite-reset-delayed_status-on-reset_config.patch usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch usb-option-support-new-huawei-devices.patch usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch --- diff --git a/queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch b/queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch new file mode 100644 index 00000000000..b903d5747b4 --- /dev/null +++ b/queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch @@ -0,0 +1,44 @@ +From f12d5bfceb7e1f9051563381ec047f7f13956c3c Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Thu, 12 Dec 2013 09:38:42 -0800 +Subject: futex: fix handling of read-only-mapped hugepages + +From: Linus Torvalds + +commit f12d5bfceb7e1f9051563381ec047f7f13956c3c upstream. + +The hugepage code had the exact same bug that regular pages had in +commit 7485d0d3758e ("futexes: Remove rw parameter from +get_futex_key()"). + +The regular page case was fixed by commit 9ea71503a8ed ("futex: Fix +regression with read only mappings"), but the transparent hugepage case +(added in a5b338f2b0b1: "thp: update futex compound knowledge") case +remained broken. + +Found by Dave Jones and his trinity tool. + +Reported-and-tested-by: Dave Jones +Acked-by: Thomas Gleixner +Cc: Mel Gorman +Cc: Darren Hart +Cc: Andrea Arcangeli +Cc: Oleg Nesterov +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -288,7 +288,7 @@ again: + put_page(page); + /* serialize against __split_huge_page_splitting() */ + local_irq_disable(); +- if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) { ++ if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) { + page_head = compound_head(page); + /* + * page_head is valid pointer but we must pin diff --git a/queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch b/queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch new file mode 100644 index 00000000000..1b3fb8b4b85 --- /dev/null +++ b/queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch @@ -0,0 +1,94 @@ +From 4ef38351d770cc421f4a0c7a849fd13207fc5741 Mon Sep 17 00:00:00 2001 +From: Christian Engelmayer +Date: Tue, 26 Nov 2013 18:16:17 -0800 +Subject: Input: usbtouchscreen - separate report and transmit buffer size handling + +From: Christian Engelmayer + +commit 4ef38351d770cc421f4a0c7a849fd13207fc5741 upstream. + +This patch supports the separate handling of the USB transfer buffer length +and the length of the buffer used for multi packet support. For devices +supporting multiple report or diagnostic packets, the USB transfer size is now +limited to the USB endpoints wMaxPacketSize - otherwise it defaults to the +configured report packet size as before. + +This fixes an issue where event reporting can be delayed for an arbitrary +time for multi packet devices. For instance the report size for eGalax devices +is defined to the 16 byte maximum diagnostic packet size as opposed to the 5 +byte report packet size. In case the driver requests 16 byte from the USB +interrupt endpoint, the USB host controller driver needs to split up the +request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte. +When the first transfer is answered by the eGalax device with not less than +the full 8 byte requested, the host controller has got no way of knowing +whether the touch controller has got additional data queued and will issue +the second transfer. If per example a liftoff event finishes at such a +wMaxPacketSize boundary, the data will not be available to the usbtouch driver +until a further event is triggered and transfered to the host. From user +perspective the BTN_TOUCH release event in this case is stuck until the next +touch down event. + +Signed-off-by: Christian Engelmayer +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/touchscreen/usbtouchscreen.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +--- a/drivers/input/touchscreen/usbtouchscreen.c ++++ b/drivers/input/touchscreen/usbtouchscreen.c +@@ -106,6 +106,7 @@ struct usbtouch_device_info { + struct usbtouch_usb { + unsigned char *data; + dma_addr_t data_dma; ++ int data_size; + unsigned char *buffer; + int buf_len; + struct urb *irq; +@@ -1521,7 +1522,7 @@ static int usbtouch_reset_resume(struct + static void usbtouch_free_buffers(struct usb_device *udev, + struct usbtouch_usb *usbtouch) + { +- usb_free_coherent(udev, usbtouch->type->rept_size, ++ usb_free_coherent(udev, usbtouch->data_size, + usbtouch->data, usbtouch->data_dma); + kfree(usbtouch->buffer); + } +@@ -1566,7 +1567,20 @@ static int usbtouch_probe(struct usb_int + if (!type->process_pkt) + type->process_pkt = usbtouch_process_pkt; + +- usbtouch->data = usb_alloc_coherent(udev, type->rept_size, ++ usbtouch->data_size = type->rept_size; ++ if (type->get_pkt_len) { ++ /* ++ * When dealing with variable-length packets we should ++ * not request more than wMaxPacketSize bytes at once ++ * as we do not know if there is more data coming or ++ * we filled exactly wMaxPacketSize bytes and there is ++ * nothing else. ++ */ ++ usbtouch->data_size = min(usbtouch->data_size, ++ usb_endpoint_maxp(endpoint)); ++ } ++ ++ usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size, + GFP_KERNEL, &usbtouch->data_dma); + if (!usbtouch->data) + goto out_free; +@@ -1626,12 +1640,12 @@ static int usbtouch_probe(struct usb_int + if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) + usb_fill_int_urb(usbtouch->irq, udev, + usb_rcvintpipe(udev, endpoint->bEndpointAddress), +- usbtouch->data, type->rept_size, ++ usbtouch->data, usbtouch->data_size, + usbtouch_irq, usbtouch, endpoint->bInterval); + else + usb_fill_bulk_urb(usbtouch->irq, udev, + usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), +- usbtouch->data, type->rept_size, ++ usbtouch->data, usbtouch->data_size, + usbtouch_irq, usbtouch); + + usbtouch->irq->dev = udev; diff --git a/queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch b/queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch new file mode 100644 index 00000000000..7eb1dbf446a --- /dev/null +++ b/queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch @@ -0,0 +1,157 @@ +From 6960a059b2c618f32fe549f13287b3d2278c09e9 Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Mon, 11 Nov 2013 15:23:01 +0200 +Subject: iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160 + +From: Emmanuel Grumbach + +commit 6960a059b2c618f32fe549f13287b3d2278c09e9 upstream. + +We changed the timeout for the interrupt coealescing for +calibration, but that wasn't effective since we changed +that value back before loading the firmware. Since +calibrations are notification from firmware and not Rx +packets, this doesn't change anyway - the firmware will +fire an interrupt straight away regardless of the interrupt +coalescing value. +Also, a HW issue has been discovered in 7000 devices series. +The work around is to disable the new interrupt coalescing +timeout feature - do this by setting bit 31 in +CSR_INT_COALESCING. +This has been fixed in 7265 which means that we can't rely +on the device family and must have a hint in the iwl_cfg +structure. + +Fixes: 99cd47142399 ("iwlwifi: add 7000 series device configuration") +Reviewed-by: Johannes Berg +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-7000.c | 7 +++++++ + drivers/net/wireless/iwlwifi/iwl-config.h | 3 +++ + drivers/net/wireless/iwlwifi/iwl-csr.h | 5 +---- + drivers/net/wireless/iwlwifi/pcie/rx.c | 4 ++++ + drivers/net/wireless/iwlwifi/pcie/trans.c | 3 --- + 5 files changed, 15 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-7000.c ++++ b/drivers/net/wireless/iwlwifi/iwl-7000.c +@@ -125,6 +125,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { +@@ -135,6 +136,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_hig + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, + .high_temp = true, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl7260_2n_cfg = { +@@ -144,6 +146,7 @@ const struct iwl_cfg iwl7260_2n_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl7260_n_cfg = { +@@ -153,6 +156,7 @@ const struct iwl_cfg iwl7260_n_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl3160_2ac_cfg = { +@@ -162,6 +166,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL3160_NVM_VERSION, + .nvm_calib_ver = IWL3160_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl3160_2n_cfg = { +@@ -171,6 +176,7 @@ const struct iwl_cfg iwl3160_2n_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL3160_NVM_VERSION, + .nvm_calib_ver = IWL3160_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + const struct iwl_cfg iwl3160_n_cfg = { +@@ -180,6 +186,7 @@ const struct iwl_cfg iwl3160_n_cfg = { + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL3160_NVM_VERSION, + .nvm_calib_ver = IWL3160_TX_POWER_VERSION, ++ .host_interrupt_operation_mode = true, + }; + + MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); +--- a/drivers/net/wireless/iwlwifi/iwl-config.h ++++ b/drivers/net/wireless/iwlwifi/iwl-config.h +@@ -207,6 +207,8 @@ struct iwl_eeprom_params { + * @rx_with_siso_diversity: 1x1 device with rx antenna diversity + * @internal_wimax_coex: internal wifi/wimax combo device + * @high_temp: Is this NIC is designated to be in high temperature. ++ * @host_interrupt_operation_mode: device needs host interrupt operation ++ * mode set + * + * We enable the driver to be backward compatible wrt. hardware features. + * API differences in uCode shouldn't be handled here but through TLVs +@@ -235,6 +237,7 @@ struct iwl_cfg { + enum iwl_led_mode led_mode; + const bool rx_with_siso_diversity; + const bool internal_wimax_coex; ++ const bool host_interrupt_operation_mode; + bool high_temp; + }; + +--- a/drivers/net/wireless/iwlwifi/iwl-csr.h ++++ b/drivers/net/wireless/iwlwifi/iwl-csr.h +@@ -463,14 +463,11 @@ + * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit + * + * default interrupt coalescing timer is 64 x 32 = 2048 usecs +- * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs + */ + #define IWL_HOST_INT_TIMEOUT_MAX (0xFF) + #define IWL_HOST_INT_TIMEOUT_DEF (0x40) + #define IWL_HOST_INT_TIMEOUT_MIN (0x0) +-#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) +-#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) +-#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) ++#define IWL_HOST_INT_OPER_MODE BIT(31) + + /***************************************************************************** + * 7000/3000 series SHR DTS addresses * +--- a/drivers/net/wireless/iwlwifi/pcie/rx.c ++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c +@@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct i + + /* Set interrupt coalescing timer to default (2048 usecs) */ + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); ++ ++ /* W/A for interrupt coalescing bug in 7260 and 3160 */ ++ if (trans->cfg->host_interrupt_operation_mode) ++ iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE); + } + + static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) +--- a/drivers/net/wireless/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c +@@ -276,9 +276,6 @@ static int iwl_pcie_nic_init(struct iwl_ + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + iwl_pcie_apm_init(trans); + +- /* Set interrupt coalescing calibration timer to default (512 usecs) */ +- iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); +- + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); + + iwl_pcie_set_pwr(trans, false); diff --git a/queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch b/queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch new file mode 100644 index 00000000000..301dc5ea339 --- /dev/null +++ b/queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch @@ -0,0 +1,53 @@ +From 9323297dc0ea9141f8099e474657391bb3ad98f8 Mon Sep 17 00:00:00 2001 +From: Antti Palosaari +Date: Wed, 27 Nov 2013 17:23:00 -0300 +Subject: media: af9035: fix broken I2C and USB I/O + +From: Antti Palosaari + +commit 9323297dc0ea9141f8099e474657391bb3ad98f8 upstream. + +There was three small buffer len calculation bugs which caused +driver non-working. These are coming from recent commit: +commit 7760e148350bf6df95662bc0db3734e9d991cb03 +[media] af9035: Don't use dynamic static allocation + +Signed-off-by: Antti Palosaari +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/dvb-usb-v2/af9035.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/af9035.c ++++ b/drivers/media/usb/dvb-usb-v2/af9035.c +@@ -131,7 +131,7 @@ static int af9035_wr_regs(struct dvb_usb + { + u8 wbuf[MAX_XFER_SIZE]; + u8 mbox = (reg >> 16) & 0xff; +- struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL }; ++ struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL }; + + if (6 + len > sizeof(wbuf)) { + dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n", +@@ -238,7 +238,7 @@ static int af9035_i2c_master_xfer(struct + } else { + /* I2C */ + u8 buf[MAX_XFER_SIZE]; +- struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf), ++ struct usb_req req = { CMD_I2C_RD, 0, 5 + msg[0].len, + buf, msg[1].len, msg[1].buf }; + + if (5 + msg[0].len > sizeof(buf)) { +@@ -274,8 +274,8 @@ static int af9035_i2c_master_xfer(struct + } else { + /* I2C */ + u8 buf[MAX_XFER_SIZE]; +- struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf, +- 0, NULL }; ++ struct usb_req req = { CMD_I2C_WR, 0, 5 + msg[0].len, ++ buf, 0, NULL }; + + if (5 + msg[0].len > sizeof(buf)) { + dev_warn(&d->udev->dev, diff --git a/queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch b/queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch new file mode 100644 index 00000000000..19668306bc0 --- /dev/null +++ b/queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch @@ -0,0 +1,59 @@ +From 781c2a5a5f75eacc04663aced0f0f1a648d4f308 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Mon, 2 Dec 2013 15:26:19 -0500 +Subject: nfsd: when reusing an existing repcache entry, unhash it first + +From: Jeff Layton + +commit 781c2a5a5f75eacc04663aced0f0f1a648d4f308 upstream. + +The DRC code will attempt to reuse an existing, expired cache entry in +preference to allocating a new one. It'll then search the cache, and if +it gets a hit it'll then free the cache entry that it was going to +reuse. + +The cache code doesn't unhash the entry that it's going to reuse +however, so it's possible for it end up designating an entry for reuse +and then subsequently freeing the same entry after it finds it. This +leads it to a later use-after-free situation and usually some list +corruption warnings or an oops. + +Fix this by simply unhashing the entry that we intend to reuse. That +will mean that it's not findable via a search and should prevent this +situation from occurring. + +Reported-by: Christoph Hellwig +Reported-by: g. artim +Signed-off-by: Jeff Layton +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfscache.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfscache.c ++++ b/fs/nfsd/nfscache.c +@@ -132,6 +132,13 @@ nfsd_reply_cache_alloc(void) + } + + static void ++nfsd_reply_cache_unhash(struct svc_cacherep *rp) ++{ ++ hlist_del_init(&rp->c_hash); ++ list_del_init(&rp->c_lru); ++} ++ ++static void + nfsd_reply_cache_free_locked(struct svc_cacherep *rp) + { + if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) { +@@ -417,7 +424,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp + rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru); + if (nfsd_cache_entry_expired(rp) || + num_drc_entries >= max_drc_entries) { +- lru_put_end(rp); ++ nfsd_reply_cache_unhash(rp); + prune_cache_entries(); + goto search_cache; + } diff --git a/queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch b/queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch new file mode 100644 index 00000000000..0df05f4f516 --- /dev/null +++ b/queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch @@ -0,0 +1,97 @@ +From 4fc9bbf98fd66f879e628d8537ba7c240be2b58e Mon Sep 17 00:00:00 2001 +From: Khalid Aziz +Date: Wed, 27 Nov 2013 15:19:25 -0700 +Subject: PCI: Disable Bus Master only on kexec reboot + +From: Khalid Aziz + +commit 4fc9bbf98fd66f879e628d8537ba7c240be2b58e upstream. + +Add a flag to tell the PCI subsystem that kernel is shutting down in +preparation to kexec a kernel. Add code in PCI subsystem to use this flag +to clear Bus Master bit on PCI devices only in case of kexec reboot. + +This fixes a power-off problem on Acer Aspire V5-573G and likely other +machines and avoids any other issues caused by clearing Bus Master bit on +PCI devices in normal shutdown path. The problem was introduced by +b566a22c2332 ("PCI: disable Bus Master on PCI device shutdown"). + +This patch is based on discussion at +http://marc.info/?l=linux-pci&m=138425645204355&w=2 + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=63861 +Reported-by: Chang Liu +Signed-off-by: Khalid Aziz +Signed-off-by: Bjorn Helgaas +Acked-by: Konstantin Khlebnikov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci-driver.c | 12 +++++++++--- + include/linux/kexec.h | 3 +++ + kernel/kexec.c | 4 ++++ + 3 files changed, 16 insertions(+), 3 deletions(-) + +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "pci.h" + + struct pci_dynid { +@@ -388,12 +389,17 @@ static void pci_device_shutdown(struct d + pci_msi_shutdown(pci_dev); + pci_msix_shutdown(pci_dev); + ++#ifdef CONFIG_KEXEC + /* +- * Turn off Bus Master bit on the device to tell it to not +- * continue to do DMA. Don't touch devices in D3cold or unknown states. ++ * If this is a kexec reboot, turn off Bus Master bit on the ++ * device to tell it to not continue to do DMA. Don't touch ++ * devices in D3cold or unknown states. ++ * If it is not a kexec reboot, firmware will hit the PCI ++ * devices with big hammer and stop their DMA any way. + */ +- if (pci_dev->current_state <= PCI_D3hot) ++ if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot)) + pci_clear_master(pci_dev); ++#endif + } + + #ifdef CONFIG_PM +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NO + extern size_t vmcoreinfo_size; + extern size_t vmcoreinfo_max_size; + ++/* flag to track if kexec reboot is in progress */ ++extern bool kexec_in_progress; ++ + int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, + unsigned long long *crash_size, unsigned long long *crash_base); + int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, +--- a/kernel/kexec.c ++++ b/kernel/kexec.c +@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE + size_t vmcoreinfo_size; + size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); + ++/* Flag to indicate we are going to kexec a new kernel */ ++bool kexec_in_progress = false; ++ + /* Location of the reserved area for the crash kernel */ + struct resource crashk_res = { + .name = "Crash kernel", +@@ -1675,6 +1678,7 @@ int kernel_kexec(void) + } else + #endif + { ++ kexec_in_progress = true; + kernel_restart_prepare(NULL); + printk(KERN_EMERG "Starting new kernel\n"); + machine_shutdown(); diff --git a/queue-3.12/series b/queue-3.12/series index 2ed04e8205d..a3e3149823b 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -23,3 +23,17 @@ hwmon-w83l786ng-fix-fan-speed-control-mode-setting-and-reporting.patch hwmon-w83l768ng-fix-fan-speed-control-range.patch xfs-growfs-overruns-agfl-buffer-on-v4-filesystems.patch xfs-underflow-bug-in-xfs_attrlist_by_handle.patch +iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch +pci-disable-bus-master-only-on-kexec-reboot.patch +futex-fix-handling-of-read-only-mapped-hugepages.patch +nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch +usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch +usb-dwc3-fix-implementation-of-endpoint-wedge.patch +usb-gadget-composite-reset-delayed_status-on-reset_config.patch +usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch +usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch +usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch +usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch +usb-option-support-new-huawei-devices.patch +input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch +media-af9035-fix-broken-i2c-and-usb-i-o.patch diff --git a/queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch b/queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch new file mode 100644 index 00000000000..8643130900c --- /dev/null +++ b/queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch @@ -0,0 +1,58 @@ +From a535d81c92615b8ffb99b7e1fd1fb01effaed1af Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 1 Nov 2013 12:05:12 -0400 +Subject: usb: dwc3: fix implementation of endpoint wedge + +From: Alan Stern + +commit a535d81c92615b8ffb99b7e1fd1fb01effaed1af upstream. + +The dwc3 UDC driver doesn't implement endpoint wedging correctly. +When an endpoint is wedged, the gadget driver should be allowed to +clear the wedge by calling usb_ep_clear_halt(). Only the host is +prevented from resetting the endpoint. + +This patch fixes the implementation. + +Signed-off-by: Alan Stern +Tested-by: Pratyush Anand +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/ep0.c | 2 ++ + drivers/usb/dwc3/gadget.c | 5 +---- + 2 files changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/usb/dwc3/ep0.c ++++ b/drivers/usb/dwc3/ep0.c +@@ -459,6 +459,8 @@ static int dwc3_ep0_handle_feature(struc + dep = dwc3_wIndex_to_dep(dwc, wIndex); + if (!dep) + return -EINVAL; ++ if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) ++ break; + ret = __dwc3_gadget_ep_set_halt(dep, set); + if (ret) + return -EINVAL; +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1200,9 +1200,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc + else + dep->flags |= DWC3_EP_STALL; + } else { +- if (dep->flags & DWC3_EP_WEDGE) +- return 0; +- + ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, + DWC3_DEPCMD_CLEARSTALL, ¶ms); + if (ret) +@@ -1210,7 +1207,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc + value ? "set" : "clear", + dep->name); + else +- dep->flags &= ~DWC3_EP_STALL; ++ dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); + } + + return ret; diff --git a/queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch b/queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch new file mode 100644 index 00000000000..3c83ad766a8 --- /dev/null +++ b/queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch @@ -0,0 +1,32 @@ +From 2bac51a1827a18821150ed8c9f9752c02f9c2b02 Mon Sep 17 00:00:00 2001 +From: Michael Grzeschik +Date: Mon, 11 Nov 2013 23:43:32 +0100 +Subject: usb: gadget: composite: reset delayed_status on reset_config + +From: Michael Grzeschik + +commit 2bac51a1827a18821150ed8c9f9752c02f9c2b02 upstream. + +The delayed_status value is used to keep track of status response +packets on ep0. It needs to be reset or the set_config function would +still delay the answer, if the usb device got unplugged while waiting +for setup_continue to be called. + +Signed-off-by: Michael Grzeschik +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/composite.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -593,6 +593,7 @@ static void reset_config(struct usb_comp + bitmap_zero(f->endpoints, 32); + } + cdev->config = NULL; ++ cdev->delayed_status = 0; + } + + static int set_config(struct usb_composite_dev *cdev, diff --git a/queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch b/queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch new file mode 100644 index 00000000000..dcd84f8cd9f --- /dev/null +++ b/queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch @@ -0,0 +1,37 @@ +From 2d51f3cd11f414c56a87dc018196b85fd50b04a4 Mon Sep 17 00:00:00 2001 +From: Julius Werner +Date: Thu, 7 Nov 2013 10:59:14 -0800 +Subject: usb: hub: Use correct reset for wedged USB3 devices that are NOTATTACHED + +From: Julius Werner + +commit 2d51f3cd11f414c56a87dc018196b85fd50b04a4 upstream. + +This patch adds a check for USB_STATE_NOTATTACHED to the +hub_port_warm_reset_required() workaround for ports that end up in +Compliance Mode in hub_events() when trying to decide which reset +function to use. Trying to call usb_reset_device() with a NOTATTACHED +device will just fail and leave the port broken. + +Signed-off-by: Julius Werner +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4836,8 +4836,9 @@ static void hub_events(void) + hub->ports[i - 1]->child; + + dev_dbg(hub_dev, "warm reset port %d\n", i); +- if (!udev || !(portstatus & +- USB_PORT_STAT_CONNECTION)) { ++ if (!udev || ++ !(portstatus & USB_PORT_STAT_CONNECTION) || ++ udev->state == USB_STATE_NOTATTACHED) { + status = hub_port_reset(hub, i, + NULL, HUB_BH_RESET_TIME, + true); diff --git a/queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch b/queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch new file mode 100644 index 00000000000..2f7789c052a --- /dev/null +++ b/queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch @@ -0,0 +1,114 @@ +From d373a8534d5e1e7a350e40d3c11961a7cd8d530b Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 12 Nov 2013 16:37:46 +0100 +Subject: usb: musb: musb_cppi41: factor most of cppi41_dma_callback() into cppi41_trans_done() + +From: Sebastian Andrzej Siewior + +commit d373a8534d5e1e7a350e40d3c11961a7cd8d530b upstream. + +This patch moves most of the logic in cppi41_dma_callback() into +cppi41_trans_done() where it can be called from another function. +Instead of computing "transferred" (the number of bytes transferred in +the last transaction) in cppi41_trans_done() the member +"cppi41_channel->prog_len" is now set to 0 if the transfer as a whole +can be considered as done. If it is != 0 then the next iteration is +assumed. +This is a preparation for a workaround. + +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_cppi41.c | 59 +++++++++++++++++++++++++---------------- + 1 file changed, 36 insertions(+), 23 deletions(-) + +--- a/drivers/usb/musb/musb_cppi41.c ++++ b/drivers/usb/musb/musb_cppi41.c +@@ -96,31 +96,15 @@ static void update_rx_toggle(struct cppi + cppi41_channel->usb_toggle = toggle; + } + +-static void cppi41_dma_callback(void *private_data) ++static void cppi41_dma_callback(void *private_data); ++ ++static void cppi41_trans_done(struct dma_channel *channel) + { +- struct dma_channel *channel = private_data; + struct cppi41_dma_channel *cppi41_channel = channel->private_data; + struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; + struct musb *musb = hw_ep->musb; +- unsigned long flags; +- struct dma_tx_state txstate; +- u32 transferred; + +- spin_lock_irqsave(&musb->lock, flags); +- +- dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, +- &txstate); +- transferred = cppi41_channel->prog_len - txstate.residue; +- cppi41_channel->transferred += transferred; +- +- dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", +- hw_ep->epnum, cppi41_channel->transferred, +- cppi41_channel->total_len); +- +- update_rx_toggle(cppi41_channel); +- +- if (cppi41_channel->transferred == cppi41_channel->total_len || +- transferred < cppi41_channel->packet_sz) { ++ if (!cppi41_channel->prog_len) { + + /* done, complete */ + cppi41_channel->channel.actual_len = +@@ -150,10 +134,8 @@ static void cppi41_dma_callback(void *pr + remain_bytes, + direction, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +- if (WARN_ON(!dma_desc)) { +- spin_unlock_irqrestore(&musb->lock, flags); ++ if (WARN_ON(!dma_desc)) + return; +- } + + dma_desc->callback = cppi41_dma_callback; + dma_desc->callback_param = channel; +@@ -166,6 +148,37 @@ static void cppi41_dma_callback(void *pr + musb_writew(epio, MUSB_RXCSR, csr); + } + } ++} ++ ++static void cppi41_dma_callback(void *private_data) ++{ ++ struct dma_channel *channel = private_data; ++ struct cppi41_dma_channel *cppi41_channel = channel->private_data; ++ struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; ++ struct musb *musb = hw_ep->musb; ++ unsigned long flags; ++ struct dma_tx_state txstate; ++ u32 transferred; ++ ++ spin_lock_irqsave(&musb->lock, flags); ++ ++ dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, ++ &txstate); ++ transferred = cppi41_channel->prog_len - txstate.residue; ++ cppi41_channel->transferred += transferred; ++ ++ dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", ++ hw_ep->epnum, cppi41_channel->transferred, ++ cppi41_channel->total_len); ++ ++ update_rx_toggle(cppi41_channel); ++ ++ if (cppi41_channel->transferred == cppi41_channel->total_len || ++ transferred < cppi41_channel->packet_sz) ++ cppi41_channel->prog_len = 0; ++ ++ cppi41_trans_done(channel); ++ + spin_unlock_irqrestore(&musb->lock, flags); + } + diff --git a/queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch b/queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch new file mode 100644 index 00000000000..f7beb1d5ddb --- /dev/null +++ b/queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch @@ -0,0 +1,268 @@ +From a655f481d83d6d37bec0a2ddfdd24c30ff8f541f Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 12 Nov 2013 16:37:47 +0100 +Subject: usb: musb: musb_cppi41: handle pre-mature TX complete interrupt + +From: Sebastian Andrzej Siewior + +commit a655f481d83d6d37bec0a2ddfdd24c30ff8f541f upstream. + +The TX-complete interrupt of the CPPI41 on AM335x fires too early. +Adding a loop and counting how long it takes until the +MUSB_TXCSR_TXPKTRDY bit is cleared I see +FS: +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadc54002, len=1514 is_tx=1 +|cppi41_dma_callback() 74 loops +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8802, len=1514 is_tx=1 +|cppi41_dma_callback() 66 loops +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8002, len=1514 is_tx=1 +|cppi41_dma_callback() 136 loops +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadf55802, len=1514 is_tx=1 +|cppi41_dma_callback() 136 loops + +avg: 110 - 150us + +HS: +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xaca6f002, len=1514 is_tx=1 +|cppi41_dma_callback() 0 loops +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f802, len=1514 is_tx=1 +|cppi41_dma_callback() 2 loops +|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f002, len=1514 is_tx=1 +|cppi41_dma_callback() 13 loops + +avg: 2us + +for the same test case. One loop means a udelay(1). The delay seems to +depend on the packet size. On HS the bit is always cleared for small +packet sizes while on FS it is never the case, it mostly around 110us. +This testing has been performed with g_ether (musb as device) and using BULK +transfers. + +INTR transfers are way more fun: during init the gadget sends a INT +packet to the host and cppi41 says "transfer done" shortly after. The +MUSB_TXCSR_TXPKTRDY bit is set even seconds later. The reason is that the host +did not try to receive it, it does so after the interface (on host side) has +been configured. Until this happens, that packet remains in musb's FIFO. + +To fix this, two things are done: +- No DMA transfers for INT based endpoints. These transfer are usually + very small and rare so it is likely better to skip the DMA engine and + stuff the four bytes directly into the FIFO +- on HS we poll up to 25us and hope that bit goes away. If not we setup + a hrtimer to poll for it. The 140us delay is a rule of thumb. In FS + the command + | ping 10.10.10.10 -c1 -s65130 + creates about 44 1514bytes transfers. About 19 of them need a second + timer to complete. + +Reported-by: Bin Liu +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_cppi41.c | 113 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 108 insertions(+), 5 deletions(-) + +--- a/drivers/usb/musb/musb_cppi41.c ++++ b/drivers/usb/musb/musb_cppi41.c +@@ -38,6 +38,7 @@ struct cppi41_dma_channel { + u32 prog_len; + u32 transferred; + u32 packet_sz; ++ struct list_head tx_check; + }; + + #define MUSB_DMA_NUM_CHANNELS 15 +@@ -47,6 +48,8 @@ struct cppi41_dma_controller { + struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; + struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; + struct musb *musb; ++ struct hrtimer early_tx; ++ struct list_head early_tx_list; + u32 rx_mode; + u32 tx_mode; + u32 auto_req; +@@ -96,11 +99,23 @@ static void update_rx_toggle(struct cppi + cppi41_channel->usb_toggle = toggle; + } + ++static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) ++{ ++ u8 epnum = hw_ep->epnum; ++ struct musb *musb = hw_ep->musb; ++ void __iomem *epio = musb->endpoints[epnum].regs; ++ u16 csr; ++ ++ csr = musb_readw(epio, MUSB_TXCSR); ++ if (csr & MUSB_TXCSR_TXPKTRDY) ++ return false; ++ return true; ++} ++ + static void cppi41_dma_callback(void *private_data); + +-static void cppi41_trans_done(struct dma_channel *channel) ++static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) + { +- struct cppi41_dma_channel *cppi41_channel = channel->private_data; + struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; + struct musb *musb = hw_ep->musb; + +@@ -138,7 +153,7 @@ static void cppi41_trans_done(struct dma + return; + + dma_desc->callback = cppi41_dma_callback; +- dma_desc->callback_param = channel; ++ dma_desc->callback_param = &cppi41_channel->channel; + cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); + dma_async_issue_pending(dc); + +@@ -150,6 +165,41 @@ static void cppi41_trans_done(struct dma + } + } + ++static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) ++{ ++ struct cppi41_dma_controller *controller; ++ struct cppi41_dma_channel *cppi41_channel, *n; ++ struct musb *musb; ++ unsigned long flags; ++ enum hrtimer_restart ret = HRTIMER_NORESTART; ++ ++ controller = container_of(timer, struct cppi41_dma_controller, ++ early_tx); ++ musb = controller->musb; ++ ++ spin_lock_irqsave(&musb->lock, flags); ++ list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list, ++ tx_check) { ++ bool empty; ++ struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; ++ ++ empty = musb_is_tx_fifo_empty(hw_ep); ++ if (empty) { ++ list_del_init(&cppi41_channel->tx_check); ++ cppi41_trans_done(cppi41_channel); ++ } ++ } ++ ++ if (!list_empty(&controller->early_tx_list)) { ++ ret = HRTIMER_RESTART; ++ hrtimer_forward_now(&controller->early_tx, ++ ktime_set(0, 150 * NSEC_PER_USEC)); ++ } ++ ++ spin_unlock_irqrestore(&musb->lock, flags); ++ return ret; ++} ++ + static void cppi41_dma_callback(void *private_data) + { + struct dma_channel *channel = private_data; +@@ -159,6 +209,7 @@ static void cppi41_dma_callback(void *pr + unsigned long flags; + struct dma_tx_state txstate; + u32 transferred; ++ bool empty; + + spin_lock_irqsave(&musb->lock, flags); + +@@ -177,8 +228,52 @@ static void cppi41_dma_callback(void *pr + transferred < cppi41_channel->packet_sz) + cppi41_channel->prog_len = 0; + +- cppi41_trans_done(channel); +- ++ empty = musb_is_tx_fifo_empty(hw_ep); ++ if (empty) { ++ cppi41_trans_done(cppi41_channel); ++ } else { ++ struct cppi41_dma_controller *controller; ++ /* ++ * On AM335x it has been observed that the TX interrupt fires ++ * too early that means the TXFIFO is not yet empty but the DMA ++ * engine says that it is done with the transfer. We don't ++ * receive a FIFO empty interrupt so the only thing we can do is ++ * to poll for the bit. On HS it usually takes 2us, on FS around ++ * 110us - 150us depending on the transfer size. ++ * We spin on HS (no longer than than 25us and setup a timer on ++ * FS to check for the bit and complete the transfer. ++ */ ++ controller = cppi41_channel->controller; ++ ++ if (musb->g.speed == USB_SPEED_HIGH) { ++ unsigned wait = 25; ++ ++ do { ++ empty = musb_is_tx_fifo_empty(hw_ep); ++ if (empty) ++ break; ++ wait--; ++ if (!wait) ++ break; ++ udelay(1); ++ } while (1); ++ ++ empty = musb_is_tx_fifo_empty(hw_ep); ++ if (empty) { ++ cppi41_trans_done(cppi41_channel); ++ goto out; ++ } ++ } ++ list_add_tail(&cppi41_channel->tx_check, ++ &controller->early_tx_list); ++ if (!hrtimer_active(&controller->early_tx)) { ++ hrtimer_start_range_ns(&controller->early_tx, ++ ktime_set(0, 140 * NSEC_PER_USEC), ++ 40 * NSEC_PER_USEC, ++ HRTIMER_MODE_REL); ++ } ++ } ++out: + spin_unlock_irqrestore(&musb->lock, flags); + } + +@@ -377,6 +472,8 @@ static int cppi41_is_compatible(struct d + WARN_ON(1); + return 1; + } ++ if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK) ++ return 0; + if (cppi41_channel->is_tx) + return 1; + /* AM335x Advisory 1.0.13. No workaround for device RX mode */ +@@ -401,6 +498,7 @@ static int cppi41_dma_channel_abort(stru + if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) + return 0; + ++ list_del_init(&cppi41_channel->tx_check); + if (is_tx) { + csr = musb_readw(epio, MUSB_TXCSR); + csr &= ~MUSB_TXCSR_DMAENAB; +@@ -507,6 +605,7 @@ static int cppi41_dma_controller_start(s + cppi41_channel->controller = controller; + cppi41_channel->port_num = port; + cppi41_channel->is_tx = is_tx; ++ INIT_LIST_HEAD(&cppi41_channel->tx_check); + + musb_dma = &cppi41_channel->channel; + musb_dma->private_data = cppi41_channel; +@@ -531,6 +630,7 @@ void dma_controller_destroy(struct dma_c + struct cppi41_dma_controller *controller = container_of(c, + struct cppi41_dma_controller, controller); + ++ hrtimer_cancel(&controller->early_tx); + cppi41_dma_controller_stop(controller); + kfree(controller); + } +@@ -550,6 +650,9 @@ struct dma_controller *dma_controller_cr + if (!controller) + goto kzalloc_fail; + ++ hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ controller->early_tx.function = cppi41_recheck_tx_req; ++ INIT_LIST_HEAD(&controller->early_tx_list); + controller->musb = musb; + + controller->controller.channel_alloc = cppi41_dma_channel_allocate; diff --git a/queue-3.12/usb-option-support-new-huawei-devices.patch b/queue-3.12/usb-option-support-new-huawei-devices.patch new file mode 100644 index 00000000000..f0f76c24202 --- /dev/null +++ b/queue-3.12/usb-option-support-new-huawei-devices.patch @@ -0,0 +1,87 @@ +From 2bf308d7bc5e8cdd69672199f59532f35339133c Mon Sep 17 00:00:00 2001 +From: "Fangxiaozhi (Franko)" +Date: Mon, 2 Dec 2013 09:00:11 +0000 +Subject: USB: option: support new huawei devices + +From: "Fangxiaozhi (Franko)" + +commit 2bf308d7bc5e8cdd69672199f59532f35339133c upstream. + +Add new supporting declarations to option.c, to support Huawei new +devices with new bInterfaceProtocol value. + +Signed-off-by: fangxiaozhi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -637,6 +637,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, +@@ -691,6 +695,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, +@@ -745,6 +753,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7A) }, +@@ -799,6 +811,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7A) }, +@@ -853,6 +869,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7A) }, +@@ -907,6 +927,10 @@ static const struct usb_device_id option + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6D) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6E) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6F) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x72) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x73) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x74) }, ++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x75) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x78) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x79) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7A) }, diff --git a/queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch b/queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch new file mode 100644 index 00000000000..a4beba3055d --- /dev/null +++ b/queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch @@ -0,0 +1,43 @@ +From 8f173e22abf2258ddfa73f46eadbb6a6c29f1631 Mon Sep 17 00:00:00 2001 +From: Gustavo Zacarias +Date: Mon, 11 Nov 2013 09:59:15 -0300 +Subject: USB: serial: option: blacklist interface 1 for Huawei E173s-6 + +From: Gustavo Zacarias + +commit 8f173e22abf2258ddfa73f46eadbb6a6c29f1631 upstream. + +Interface 1 on this device isn't for option to bind to otherwise an oops +on usb_wwan with log flooding will happen when accessing the port: + +tty_release: ttyUSB1: read/write wait queue active! + +It doesn't seem to respond to QMI if it's added to qmi_wwan so don't add +it there - it's likely used by the card reader. + +Signed-off-by: Gustavo Zacarias +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -85,6 +85,7 @@ static void option_instat_callback(struc + #define HUAWEI_PRODUCT_K4505 0x1464 + #define HUAWEI_PRODUCT_K3765 0x1465 + #define HUAWEI_PRODUCT_K4605 0x14C6 ++#define HUAWEI_PRODUCT_E173S6 0x1C07 + + #define QUANTA_VENDOR_ID 0x0408 + #define QUANTA_PRODUCT_Q101 0xEA02 +@@ -572,6 +573,8 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, diff --git a/queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch b/queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch new file mode 100644 index 00000000000..696d7c6befe --- /dev/null +++ b/queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch @@ -0,0 +1,135 @@ +From 35773dac5f862cb1c82ea151eba3e2f6de51ec3e Mon Sep 17 00:00:00 2001 +From: David Laight +Date: Mon, 11 Nov 2013 12:26:54 +0000 +Subject: usb: xhci: Link TRB must not occur within a USB payload burst + +From: David Laight + +commit 35773dac5f862cb1c82ea151eba3e2f6de51ec3e upstream. + +Section 4.11.7.1 of rev 1.0 of the xhci specification states that a link TRB +can only occur at a boundary between underlying USB frames (512 bytes for +high speed devices). + +If this isn't done the USB frames aren't formatted correctly and, for example, +the USB3 ethernet ax88179_178a card will stop sending (while still receiving) +when running a netperf tcp transmit test with (say) and 8k buffer. + +This should be a candidate for stable, the ax88179_178a driver defaults to +gso and tso enabled so it passes a lot of fragmented skb to the USB stack. + +Notes from Sarah: + +Discussion: http://marc.info/?l=linux-usb&m=138384509604981&w=2 + +This patch fixes a long-standing xHCI driver bug that was revealed by a +change in 3.12 in the usb-net driver. Commit +638c5115a794981441246fa8fa5d95c1875af5ba "USBNET: support DMA SG" added +support to use bulk endpoint scatter-gather (urb->sg). Only the USB +ethernet drivers trigger this bug, because the mass storage driver sends +sg list entries in page-sized chunks. + +This patch only fixes the issue for bulk endpoint scatter-gather. The +problem will still occur for periodic endpoints, because hosts will +interpret no-op transfers as a request to skip a service interval, which +is not what we want. + +Luckily, the USB core isn't set up for scatter-gather on isochronous +endpoints, and no USB drivers use scatter-gather for interrupt +endpoints. Document this known limitation so that developers won't try +to use urb->sg for interrupt endpoints until this issue is fixed. The +more comprehensive fix would be to allow link TRBs in the middle of the +endpoint ring and revert this patch, but that fix would touch too much +code to be allowed in for stable. + +This patch should be backported to kernels as old as 3.12, that contain +the commit 638c5115a794981441246fa8fa5d95c1875af5ba "USBNET: support DMA +SG". Without this patch, the USB network device gets wedged, and stops +sending packets. Mark Lord confirms this patch fixes the regression: + +http://marc.info/?l=linux-netdev&m=138487107625966&w=2 + +Signed-off-by: David Laight +Signed-off-by: Sarah Sharp +Tested-by: Mark Lord +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 54 +++++++++++++++++++++++++++++++++++++++++-- + include/linux/usb.h | 2 + + 2 files changed, 54 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2929,8 +2929,58 @@ static int prepare_ring(struct xhci_hcd + } + + while (1) { +- if (room_on_ring(xhci, ep_ring, num_trbs)) +- break; ++ if (room_on_ring(xhci, ep_ring, num_trbs)) { ++ union xhci_trb *trb = ep_ring->enqueue; ++ unsigned int usable = ep_ring->enq_seg->trbs + ++ TRBS_PER_SEGMENT - 1 - trb; ++ u32 nop_cmd; ++ ++ /* ++ * Section 4.11.7.1 TD Fragments states that a link ++ * TRB must only occur at the boundary between ++ * data bursts (eg 512 bytes for 480M). ++ * While it is possible to split a large fragment ++ * we don't know the size yet. ++ * Simplest solution is to fill the trb before the ++ * LINK with nop commands. ++ */ ++ if (num_trbs == 1 || num_trbs <= usable || usable == 0) ++ break; ++ ++ if (ep_ring->type != TYPE_BULK) ++ /* ++ * While isoc transfers might have a buffer that ++ * crosses a 64k boundary it is unlikely. ++ * Since we can't add NOPs without generating ++ * gaps in the traffic just hope it never ++ * happens at the end of the ring. ++ * This could be fixed by writing a LINK TRB ++ * instead of the first NOP - however the ++ * TRB_TYPE_LINK_LE32() calls would all need ++ * changing to check the ring length. ++ */ ++ break; ++ ++ if (num_trbs >= TRBS_PER_SEGMENT) { ++ xhci_err(xhci, "Too many fragments %d, max %d\n", ++ num_trbs, TRBS_PER_SEGMENT - 1); ++ return -ENOMEM; ++ } ++ ++ nop_cmd = cpu_to_le32(TRB_TYPE(TRB_TR_NOOP) | ++ ep_ring->cycle_state); ++ ep_ring->num_trbs_free -= usable; ++ do { ++ trb->generic.field[0] = 0; ++ trb->generic.field[1] = 0; ++ trb->generic.field[2] = 0; ++ trb->generic.field[3] = nop_cmd; ++ trb++; ++ } while (--usable); ++ ep_ring->enqueue = trb; ++ if (room_on_ring(xhci, ep_ring, num_trbs)) ++ break; ++ } + + if (ep_ring == xhci->cmd_ring) { + xhci_err(xhci, "Do not support expand command ring\n"); +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1262,6 +1262,8 @@ typedef void (*usb_complete_t)(struct ur + * @sg: scatter gather buffer list, the buffer size of each element in + * the list (except the last) must be divisible by the endpoint's + * max packet size if no_sg_constraint isn't set in 'struct usb_bus' ++ * (FIXME: scatter-gather under xHCI is broken for periodic transfers. ++ * Do not use urb->sg for interrupt endpoints for now, only bulk.) + * @num_mapped_sgs: (internal) number of mapped sg entries + * @num_sgs: number of entries in the sg list + * @transfer_buffer_length: How big is transfer_buffer. The transfer may