From 75a557251bfbfea989bae0bad935dad45793cc7c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 27 Jul 2018 11:45:26 +0200 Subject: [PATCH] 3.18-stable patches added patches: arm-fix-put_user-for-gcc-8.patch can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch usb-cdc_acm-add-quirk-for-castles-vega3000.patch usb-core-handle-hub-c_port_over_current-condition.patch usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch --- queue-3.18/arm-fix-put_user-for-gcc-8.patch | 49 +++ ...evice-dropping-off-bus-on-rx-overrun.patch | 41 +++ ...ct-clear-of-non-processed-interrupts.patch | 54 +++ ...om-error-states-not-being-propagated.patch | 234 ++++++++++++ ...p-if-rxnemp-is-asserted-without-rxok.patch | 98 +++++ ...overflow-interrupt-not-being-enabled.patch | 37 ++ ...ames-in-tx-fifo-to-fix-tx-accounting.patch | 335 ++++++++++++++++++ queue-3.18/series | 10 + ...c_acm-add-quirk-for-castles-vega3000.patch | 33 ++ ...le-hub-c_port_over_current-condition.patch | 49 +++ ...-return-delayed-status-when-len-is-0.patch | 54 +++ 11 files changed, 994 insertions(+) create mode 100644 queue-3.18/arm-fix-put_user-for-gcc-8.patch create mode 100644 queue-3.18/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch create mode 100644 queue-3.18/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch create mode 100644 queue-3.18/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch create mode 100644 queue-3.18/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch create mode 100644 queue-3.18/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch create mode 100644 queue-3.18/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch create mode 100644 queue-3.18/usb-cdc_acm-add-quirk-for-castles-vega3000.patch create mode 100644 queue-3.18/usb-core-handle-hub-c_port_over_current-condition.patch create mode 100644 queue-3.18/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch diff --git a/queue-3.18/arm-fix-put_user-for-gcc-8.patch b/queue-3.18/arm-fix-put_user-for-gcc-8.patch new file mode 100644 index 00000000000..a6d2aa5ed64 --- /dev/null +++ b/queue-3.18/arm-fix-put_user-for-gcc-8.patch @@ -0,0 +1,49 @@ +From arnd@arndb.de Fri Jul 27 11:21:29 2018 +From: Arnd Bergmann +Date: Thu, 26 Jul 2018 10:13:23 +0200 +Subject: ARM: fix put_user() for gcc-8 +To: stable@vger.kernel.org +Cc: gregkh@linuxfoundation.org, Arnd Bergmann , Russell King , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org +Message-ID: <20180726081358.3829157-2-arnd@arndb.de> + +From: Arnd Bergmann + +Building kernels before linux-4.7 with gcc-8 results in many build failures +when gcc triggers a check that was meant to catch broken compilers: + +/tmp/ccCGMQmS.s:648: Error: .err encountered + +According to the discussion in the gcc bugzilla, a local "register +asm()" variable is still supposed to be the correct way to force an +inline assembly to use a particular register, but marking it 'const' +lets the compiler do optimizations that break that, i.e the compiler is +free to treat the variable as either 'const' or 'register' in that case. + +Upstream commit 9f73bd8bb445 ("ARM: uaccess: remove put_user() code +duplication") fixed this problem in linux-4.8 as part of a larger change, +but seems a little too big to be backported to 4.4. + +Let's take the simplest fix and change only the one broken line in the +same way as newer kernels. + +Suggested-by: Bernd Edlinger +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85745 +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86673 +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/include/asm/uaccess.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/include/asm/uaccess.h ++++ b/arch/arm/include/asm/uaccess.h +@@ -220,7 +220,7 @@ extern int __put_user_8(void *, unsigned + ({ \ + unsigned long __limit = current_thread_info()->addr_limit - 1; \ + const typeof(*(p)) __user *__tmp_p = (p); \ +- register const typeof(*(p)) __r2 asm("r2") = (x); \ ++ register typeof(*(p)) __r2 asm("r2") = (x); \ + register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ + register unsigned long __l asm("r1") = __limit; \ + register int __e asm("r0"); \ diff --git a/queue-3.18/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch b/queue-3.18/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch new file mode 100644 index 00000000000..e80235abc39 --- /dev/null +++ b/queue-3.18/can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch @@ -0,0 +1,41 @@ +From 2574fe54515ed3487405de329e4e9f13d7098c10 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Tue, 7 Feb 2017 13:23:04 +0200 +Subject: can: xilinx_can: fix device dropping off bus on RX overrun + +From: Anssi Hannula + +commit 2574fe54515ed3487405de329e4e9f13d7098c10 upstream. + +The xilinx_can driver performs a software reset when an RX overrun is +detected. This causes the device to enter Configuration mode where no +messages are received or transmitted. + +The documentation does not mention any need to perform a reset on an RX +overrun, and testing by inducing an RX overflow also indicated that the +device continues to work just fine without a reset. + +Remove the software reset. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -694,7 +694,6 @@ static void xcan_err_interrupt(struct ne + if (isr & XCAN_IXR_RXOFLW_MASK) { + stats->rx_over_errors++; + stats->rx_errors++; +- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK); + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; diff --git a/queue-3.18/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch b/queue-3.18/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch new file mode 100644 index 00000000000..ab5d2f4ed51 --- /dev/null +++ b/queue-3.18/can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch @@ -0,0 +1,54 @@ +From 2f4f0f338cf453bfcdbcf089e177c16f35f023c8 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 26 Feb 2018 14:39:59 +0200 +Subject: can: xilinx_can: fix incorrect clear of non-processed interrupts + +From: Anssi Hannula + +commit 2f4f0f338cf453bfcdbcf089e177c16f35f023c8 upstream. + +xcan_interrupt() clears ERROR|RXOFLV|BSOFF|ARBLST interrupts if any of +them is asserted. This does not take into account that some of them +could have been asserted between interrupt status read and interrupt +clear, therefore clearing them without handling them. + +Fix the code to only clear those interrupts that it knows are asserted +and therefore going to be processed in xcan_err_interrupt(). + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: Michal Simek +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -939,6 +939,7 @@ static irqreturn_t xcan_interrupt(int ir + struct net_device *ndev = (struct net_device *)dev_id; + struct xcan_priv *priv = netdev_priv(ndev); + u32 isr, ier; ++ u32 isr_errors; + + /* Get the interrupt status from Xilinx CAN */ + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); +@@ -957,11 +958,10 @@ static irqreturn_t xcan_interrupt(int ir + xcan_tx_interrupt(ndev, isr); + + /* Check for the type of error interrupt and Processing it */ +- if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | +- XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK | +- XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK | +- XCAN_IXR_ARBLST_MASK)); ++ isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | ++ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK); ++ if (isr_errors) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors); + xcan_err_interrupt(ndev, isr); + } + diff --git a/queue-3.18/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch b/queue-3.18/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch new file mode 100644 index 00000000000..a889efc779a --- /dev/null +++ b/queue-3.18/can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch @@ -0,0 +1,234 @@ +From 877e0b75947e2c7acf5624331bb17ceb093c98ae Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Wed, 8 Feb 2017 13:13:40 +0200 +Subject: can: xilinx_can: fix recovery from error states not being propagated + +From: Anssi Hannula + +commit 877e0b75947e2c7acf5624331bb17ceb093c98ae upstream. + +The xilinx_can driver contains no mechanism for propagating recovery +from CAN_STATE_ERROR_WARNING and CAN_STATE_ERROR_PASSIVE. + +Add such a mechanism by factoring the handling of +XCAN_STATE_ERROR_PASSIVE and XCAN_STATE_ERROR_WARNING out of +xcan_err_interrupt and checking for recovery after RX and TX if the +interface is in one of those states. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 155 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 127 insertions(+), 28 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -2,6 +2,7 @@ + * + * Copyright (C) 2012 - 2014 Xilinx, Inc. + * Copyright (C) 2009 PetaLogix. All rights reserved. ++ * Copyright (C) 2017 Sandvik Mining and Construction Oy + * + * Description: + * This driver is developed for Axi CAN IP and for Zynq CANPS Controller. +@@ -528,6 +529,123 @@ static int xcan_rx(struct net_device *nd + } + + /** ++ * xcan_current_error_state - Get current error state from HW ++ * @ndev: Pointer to net_device structure ++ * ++ * Checks the current CAN error state from the HW. Note that this ++ * only checks for ERROR_PASSIVE and ERROR_WARNING. ++ * ++ * Return: ++ * ERROR_PASSIVE or ERROR_WARNING if either is active, ERROR_ACTIVE ++ * otherwise. ++ */ ++static enum can_state xcan_current_error_state(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 status = priv->read_reg(priv, XCAN_SR_OFFSET); ++ ++ if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) ++ return CAN_STATE_ERROR_PASSIVE; ++ else if (status & XCAN_SR_ERRWRN_MASK) ++ return CAN_STATE_ERROR_WARNING; ++ else ++ return CAN_STATE_ERROR_ACTIVE; ++} ++ ++/** ++ * xcan_set_error_state - Set new CAN error state ++ * @ndev: Pointer to net_device structure ++ * @new_state: The new CAN state to be set ++ * @cf: Error frame to be populated or NULL ++ * ++ * Set new CAN error state for the device, updating statistics and ++ * populating the error frame if given. ++ */ ++static void xcan_set_error_state(struct net_device *ndev, ++ enum can_state new_state, ++ struct can_frame *cf) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ u32 ecr = priv->read_reg(priv, XCAN_ECR_OFFSET); ++ u32 txerr = ecr & XCAN_ECR_TEC_MASK; ++ u32 rxerr = (ecr & XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT; ++ ++ priv->can.state = new_state; ++ ++ if (cf) { ++ cf->can_id |= CAN_ERR_CRTL; ++ cf->data[6] = txerr; ++ cf->data[7] = rxerr; ++ } ++ ++ switch (new_state) { ++ case CAN_STATE_ERROR_PASSIVE: ++ priv->can.can_stats.error_passive++; ++ if (cf) ++ cf->data[1] = (rxerr > 127) ? ++ CAN_ERR_CRTL_RX_PASSIVE : ++ CAN_ERR_CRTL_TX_PASSIVE; ++ break; ++ case CAN_STATE_ERROR_WARNING: ++ priv->can.can_stats.error_warning++; ++ if (cf) ++ cf->data[1] |= (txerr > rxerr) ? ++ CAN_ERR_CRTL_TX_WARNING : ++ CAN_ERR_CRTL_RX_WARNING; ++ break; ++ case CAN_STATE_ERROR_ACTIVE: ++ if (cf) ++ cf->data[1] |= CAN_ERR_CRTL_ACTIVE; ++ break; ++ default: ++ /* non-ERROR states are handled elsewhere */ ++ WARN_ON(1); ++ break; ++ } ++} ++ ++/** ++ * xcan_update_error_state_after_rxtx - Update CAN error state after RX/TX ++ * @ndev: Pointer to net_device structure ++ * ++ * If the device is in a ERROR-WARNING or ERROR-PASSIVE state, check if ++ * the performed RX/TX has caused it to drop to a lesser state and set ++ * the interface state accordingly. ++ */ ++static void xcan_update_error_state_after_rxtx(struct net_device *ndev) ++{ ++ struct xcan_priv *priv = netdev_priv(ndev); ++ enum can_state old_state = priv->can.state; ++ enum can_state new_state; ++ ++ /* changing error state due to successful frame RX/TX can only ++ * occur from these states ++ */ ++ if (old_state != CAN_STATE_ERROR_WARNING && ++ old_state != CAN_STATE_ERROR_PASSIVE) ++ return; ++ ++ new_state = xcan_current_error_state(ndev); ++ ++ if (new_state != old_state) { ++ struct sk_buff *skb; ++ struct can_frame *cf; ++ ++ skb = alloc_can_err_skb(ndev, &cf); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); ++ ++ if (skb) { ++ struct net_device_stats *stats = &ndev->stats; ++ ++ stats->rx_packets++; ++ stats->rx_bytes += cf->can_dlc; ++ netif_rx(skb); ++ } ++ } ++} ++ ++/** + * xcan_err_interrupt - error frame Isr + * @ndev: net_device pointer + * @isr: interrupt status register value +@@ -542,16 +660,12 @@ static void xcan_err_interrupt(struct ne + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf; + struct sk_buff *skb; +- u32 err_status, status, txerr = 0, rxerr = 0; ++ u32 err_status; + + skb = alloc_can_err_skb(ndev, &cf); + + err_status = priv->read_reg(priv, XCAN_ESR_OFFSET); + priv->write_reg(priv, XCAN_ESR_OFFSET, err_status); +- txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK; +- rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) & +- XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT); +- status = priv->read_reg(priv, XCAN_SR_OFFSET); + + if (isr & XCAN_IXR_BSOFF_MASK) { + priv->can.state = CAN_STATE_BUS_OFF; +@@ -561,28 +675,10 @@ static void xcan_err_interrupt(struct ne + can_bus_off(ndev); + if (skb) + cf->can_id |= CAN_ERR_BUSOFF; +- } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) { +- priv->can.state = CAN_STATE_ERROR_PASSIVE; +- priv->can.can_stats.error_passive++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] = (rxerr > 127) ? +- CAN_ERR_CRTL_RX_PASSIVE : +- CAN_ERR_CRTL_TX_PASSIVE; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } +- } else if (status & XCAN_SR_ERRWRN_MASK) { +- priv->can.state = CAN_STATE_ERROR_WARNING; +- priv->can.can_stats.error_warning++; +- if (skb) { +- cf->can_id |= CAN_ERR_CRTL; +- cf->data[1] |= (txerr > rxerr) ? +- CAN_ERR_CRTL_TX_WARNING : +- CAN_ERR_CRTL_RX_WARNING; +- cf->data[6] = txerr; +- cf->data[7] = rxerr; +- } ++ } else { ++ enum can_state new_state = xcan_current_error_state(ndev); ++ ++ xcan_set_error_state(ndev, new_state, skb ? cf : NULL); + } + + /* Check for Arbitration lost interrupt */ +@@ -715,8 +811,10 @@ static int xcan_rx_poll(struct napi_stru + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + +- if (work_done) ++ if (work_done) { + can_led_event(ndev, CAN_LED_EVENT_RX); ++ xcan_update_error_state_after_rxtx(ndev); ++ } + + if (work_done < quota) { + napi_complete(napi); +@@ -747,6 +845,7 @@ static void xcan_tx_interrupt(struct net + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } + can_led_event(ndev, CAN_LED_EVENT_TX); ++ xcan_update_error_state_after_rxtx(ndev); + netif_wake_queue(ndev); + } + diff --git a/queue-3.18/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch b/queue-3.18/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch new file mode 100644 index 00000000000..4de5a220bca --- /dev/null +++ b/queue-3.18/can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch @@ -0,0 +1,98 @@ +From 32852c561bffd613d4ed7ec464b1e03e1b7b6c5c Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Tue, 7 Feb 2017 17:01:14 +0200 +Subject: can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK + +From: Anssi Hannula + +commit 32852c561bffd613d4ed7ec464b1e03e1b7b6c5c upstream. + +If the device gets into a state where RXNEMP (RX FIFO not empty) +interrupt is asserted without RXOK (new frame received successfully) +interrupt being asserted, xcan_rx_poll() will continue to try to clear +RXNEMP without actually reading frames from RX FIFO. If the RX FIFO is +not empty, the interrupt will not be cleared and napi_schedule() will +just be called again. + +This situation can occur when: + +(a) xcan_rx() returns without reading RX FIFO due to an error condition. +The code tries to clear both RXOK and RXNEMP but RXNEMP will not clear +due to a frame still being in the FIFO. The frame will never be read +from the FIFO as RXOK is no longer set. + +(b) A frame is received between xcan_rx_poll() reading interrupt status +and clearing RXOK. RXOK will be cleared, but RXNEMP will again remain +set as the new message is still in the FIFO. + +I'm able to trigger case (b) by flooding the bus with frames under load. + +There does not seem to be any benefit in using both RXNEMP and RXOK in +the way the driver does, and the polling example in the reference manual +(UG585 v1.10 18.3.7 Read Messages from RxFIFO) also says that either +RXOK or RXNEMP can be used for detecting incoming messages. + +Fix the issue and simplify the RX processing by only using RXNEMP +without RXOK. + +Tested with the integrated CAN on Zynq-7000 SoC. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -100,7 +100,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK) ++ XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN___SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ +@@ -710,15 +710,7 @@ static int xcan_rx_poll(struct napi_stru + + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) { +- if (isr & XCAN_IXR_RXOK_MASK) { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXOK_MASK); +- work_done += xcan_rx(ndev); +- } else { +- priv->write_reg(priv, XCAN_ICR_OFFSET, +- XCAN_IXR_RXNEMP_MASK); +- break; +- } ++ work_done += xcan_rx(ndev); + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK); + isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } +@@ -729,7 +721,7 @@ static int xcan_rx_poll(struct napi_stru + if (work_done < quota) { + napi_complete(napi); + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK); ++ ier |= XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + } + return work_done; +@@ -801,9 +793,9 @@ static irqreturn_t xcan_interrupt(int ir + } + + /* Check for the type of receive interrupt and Processing it */ +- if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) { ++ if (isr & XCAN_IXR_RXNEMP_MASK) { + ier = priv->read_reg(priv, XCAN_IER_OFFSET); +- ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK); ++ ier &= ~XCAN_IXR_RXNEMP_MASK; + priv->write_reg(priv, XCAN_IER_OFFSET, ier); + napi_schedule(&priv->napi); + } diff --git a/queue-3.18/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch b/queue-3.18/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch new file mode 100644 index 00000000000..f90db77ddae --- /dev/null +++ b/queue-3.18/can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch @@ -0,0 +1,37 @@ +From 83997997252f5d3fc7f04abc24a89600c2b504ab Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 26 Feb 2018 14:27:13 +0200 +Subject: can: xilinx_can: fix RX overflow interrupt not being enabled + +From: Anssi Hannula + +commit 83997997252f5d3fc7f04abc24a89600c2b504ab upstream. + +RX overflow interrupt (RXOFLW) is disabled even though xcan_interrupt() +processes it. This means that an RX overflow interrupt will only be +processed when another interrupt gets asserted (e.g. for RX/TX). + +Fix that by enabling the RXOFLW interrupt. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: Michal Simek +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -103,7 +103,7 @@ enum xcan_reg { + #define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\ + XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \ + XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \ +- XCAN_IXR_ARBLST_MASK) ++ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_ARBLST_MASK) + + /* CAN register bit shift - XCAN___SHIFT */ + #define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */ diff --git a/queue-3.18/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch b/queue-3.18/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch new file mode 100644 index 00000000000..3fbaa32c293 --- /dev/null +++ b/queue-3.18/can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch @@ -0,0 +1,335 @@ +From 620050d9c2be15c47017ba95efe59e0832e99a56 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 23 Feb 2017 14:50:03 +0200 +Subject: can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting + +From: Anssi Hannula + +commit 620050d9c2be15c47017ba95efe59e0832e99a56 upstream. + +The xilinx_can driver assumes that the TXOK interrupt only clears after +it has been acknowledged as many times as there have been successfully +sent frames. + +However, the documentation does not mention such behavior, instead +saying just that the interrupt is cleared when the clear bit is set. + +Similarly, testing seems to also suggest that it is immediately cleared +regardless of the amount of frames having been sent. Performing some +heavy TX load and then going back to idle has the tx_head drifting +further away from tx_tail over time, steadily reducing the amount of +frames the driver keeps in the TX FIFO (but not to zero, as the TXOK +interrupt always frees up space for 1 frame from the driver's +perspective, so frames continue to be sent) and delaying the local echo +frames. + +The TX FIFO tracking is also otherwise buggy as it does not account for +TX FIFO being cleared after software resets, causing + BUG!, TX FIFO full when queue awake! +messages to be output. + +There does not seem to be any way to accurately track the state of the +TX FIFO for local echo support while using the full TX FIFO. + +The Zynq version of the HW (but not the soft-AXI version) has watermark +programming support and with it an additional TX-FIFO-empty interrupt +bit. + +Modify the driver to only put 1 frame into TX FIFO at a time on soft-AXI +and 2 frames at a time on Zynq. On Zynq the TXFEMP interrupt bit is used +to detect whether 1 or 2 frames have been sent at interrupt processing +time. + +Tested with the integrated CAN on Zynq-7000 SoC. The 1-frame-FIFO mode +was also tested. + +An alternative way to solve this would be to drop local echo support but +keep using the full TX FIFO. + +v2: Add FIFO space check before TX queue wake with locking to +synchronize with queue stop. This avoids waking the queue when xmit() +had just filled it. + +v3: Keep local echo support and reduce the amount of frames in FIFO +instead as suggested by Marc Kleine-Budde. + +Fixes: b1201e44f50b ("can: xilinx CAN controller support") +Signed-off-by: Anssi Hannula +Cc: +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/xilinx_can.c | 139 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 123 insertions(+), 16 deletions(-) + +--- a/drivers/net/can/xilinx_can.c ++++ b/drivers/net/can/xilinx_can.c +@@ -26,8 +26,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -118,6 +120,7 @@ enum xcan_reg { + /** + * struct xcan_priv - This definition define CAN driver instance + * @can: CAN private data structure. ++ * @tx_lock: Lock for synchronizing TX interrupt handling + * @tx_head: Tx CAN packets ready to send on the queue + * @tx_tail: Tx CAN packets successfully sended on the queue + * @tx_max: Maximum number packets the driver can send +@@ -132,6 +135,7 @@ enum xcan_reg { + */ + struct xcan_priv { + struct can_priv can; ++ spinlock_t tx_lock; + unsigned int tx_head; + unsigned int tx_tail; + unsigned int tx_max; +@@ -159,6 +163,11 @@ static const struct can_bittiming_const + .brp_inc = 1, + }; + ++#define XCAN_CAP_WATERMARK 0x0001 ++struct xcan_devtype_data { ++ unsigned int caps; ++}; ++ + /** + * xcan_write_reg_le - Write a value to the device register little endian + * @priv: Driver private data structure +@@ -238,6 +247,10 @@ static int set_reset_mode(struct net_dev + usleep_range(500, 10000); + } + ++ /* reset clears FIFOs */ ++ priv->tx_head = 0; ++ priv->tx_tail = 0; ++ + return 0; + } + +@@ -392,6 +405,7 @@ static int xcan_start_xmit(struct sk_buf + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf = (struct can_frame *)skb->data; + u32 id, dlc, data[2] = {0, 0}; ++ unsigned long flags; + + if (can_dropped_invalid_skb(ndev, skb)) + return NETDEV_TX_OK; +@@ -439,6 +453,9 @@ static int xcan_start_xmit(struct sk_buf + data[1] = be32_to_cpup((__be32 *)(cf->data + 4)); + + can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max); ++ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ + priv->tx_head++; + + /* Write the Frame to Xilinx CAN TX FIFO */ +@@ -454,10 +471,16 @@ static int xcan_start_xmit(struct sk_buf + stats->tx_bytes += cf->can_dlc; + } + ++ /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */ ++ if (priv->tx_max > 1) ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK); ++ + /* Check if the TX buffer is full */ + if ((priv->tx_head - priv->tx_tail) == priv->tx_max) + netif_stop_queue(ndev); + ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + return NETDEV_TX_OK; + } + +@@ -833,19 +856,71 @@ static void xcan_tx_interrupt(struct net + { + struct xcan_priv *priv = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; ++ unsigned int frames_in_fifo; ++ int frames_sent = 1; /* TXOK => at least 1 frame was sent */ ++ unsigned long flags; ++ int retries = 0; ++ ++ /* Synchronize with xmit as we need to know the exact number ++ * of frames in the FIFO to stay in sync due to the TXFEMP ++ * handling. ++ * This also prevents a race between netif_wake_queue() and ++ * netif_stop_queue(). ++ */ ++ spin_lock_irqsave(&priv->tx_lock, flags); ++ ++ frames_in_fifo = priv->tx_head - priv->tx_tail; + +- while ((priv->tx_head - priv->tx_tail > 0) && +- (isr & XCAN_IXR_TXOK_MASK)) { ++ if (WARN_ON_ONCE(frames_in_fifo == 0)) { ++ /* clear TXOK anyway to avoid getting back here */ + priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ return; ++ } ++ ++ /* Check if 2 frames were sent (TXOK only means that at least 1 ++ * frame was sent). ++ */ ++ if (frames_in_fifo > 1) { ++ WARN_ON(frames_in_fifo > priv->tx_max); ++ ++ /* Synchronize TXOK and isr so that after the loop: ++ * (1) isr variable is up-to-date at least up to TXOK clear ++ * time. This avoids us clearing a TXOK of a second frame ++ * but not noticing that the FIFO is now empty and thus ++ * marking only a single frame as sent. ++ * (2) No TXOK is left. Having one could mean leaving a ++ * stray TXOK as we might process the associated frame ++ * via TXFEMP handling as we read TXFEMP *after* TXOK ++ * clear to satisfy (1). ++ */ ++ while ((isr & XCAN_IXR_TXOK_MASK) && !WARN_ON(++retries == 100)) { ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ isr = priv->read_reg(priv, XCAN_ISR_OFFSET); ++ } ++ ++ if (isr & XCAN_IXR_TXFEMP_MASK) { ++ /* nothing in FIFO anymore */ ++ frames_sent = frames_in_fifo; ++ } ++ } else { ++ /* single frame in fifo, just clear TXOK */ ++ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK); ++ } ++ ++ while (frames_sent--) { + can_get_echo_skb(ndev, priv->tx_tail % + priv->tx_max); + priv->tx_tail++; + stats->tx_packets++; +- isr = priv->read_reg(priv, XCAN_ISR_OFFSET); + } ++ ++ netif_wake_queue(ndev); ++ ++ spin_unlock_irqrestore(&priv->tx_lock, flags); ++ + can_led_event(ndev, CAN_LED_EVENT_TX); + xcan_update_error_state_after_rxtx(ndev); +- netif_wake_queue(ndev); + } + + /** +@@ -1122,6 +1197,18 @@ static int __maybe_unused xcan_resume(st + + static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume); + ++static const struct xcan_devtype_data xcan_zynq_data = { ++ .caps = XCAN_CAP_WATERMARK, ++}; ++ ++/* Match table for OF platform binding */ ++static const struct of_device_id xcan_of_match[] = { ++ { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data }, ++ { .compatible = "xlnx,axi-can-1.00.a", }, ++ { /* end of list */ }, ++}; ++MODULE_DEVICE_TABLE(of, xcan_of_match); ++ + /** + * xcan_probe - Platform registration call + * @pdev: Handle to the platform device structure +@@ -1136,8 +1223,10 @@ static int xcan_probe(struct platform_de + struct resource *res; /* IO mem resources */ + struct net_device *ndev; + struct xcan_priv *priv; ++ const struct of_device_id *of_id; ++ int caps = 0; + void __iomem *addr; +- int ret, rx_max, tx_max; ++ int ret, rx_max, tx_max, tx_fifo_depth; + + /* Get the virtual base address for the device */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -1147,7 +1236,8 @@ static int xcan_probe(struct platform_de + goto err; + } + +- ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max); ++ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", ++ &tx_fifo_depth); + if (ret < 0) + goto err; + +@@ -1155,6 +1245,30 @@ static int xcan_probe(struct platform_de + if (ret < 0) + goto err; + ++ of_id = of_match_device(xcan_of_match, &pdev->dev); ++ if (of_id) { ++ const struct xcan_devtype_data *devtype_data = of_id->data; ++ ++ if (devtype_data) ++ caps = devtype_data->caps; ++ } ++ ++ /* There is no way to directly figure out how many frames have been ++ * sent when the TXOK interrupt is processed. If watermark programming ++ * is supported, we can have 2 frames in the FIFO and use TXFEMP ++ * to determine if 1 or 2 frames have been sent. ++ * Theoretically we should be able to use TXFWMEMP to determine up ++ * to 3 frames, but it seems that after putting a second frame in the ++ * FIFO, with watermark at 2 frames, it can happen that TXFWMEMP (less ++ * than 2 frames in FIFO) is set anyway with no TXOK (a frame was ++ * sent), which is not a sensible state - possibly TXFWMEMP is not ++ * completely synchronized with the rest of the bits? ++ */ ++ if (caps & XCAN_CAP_WATERMARK) ++ tx_max = min(tx_fifo_depth, 2); ++ else ++ tx_max = 1; ++ + /* Create a CAN device instance */ + ndev = alloc_candev(sizeof(struct xcan_priv), tx_max); + if (!ndev) +@@ -1169,6 +1283,7 @@ static int xcan_probe(struct platform_de + CAN_CTRLMODE_BERR_REPORTING; + priv->reg_base = addr; + priv->tx_max = tx_max; ++ spin_lock_init(&priv->tx_lock); + + /* Get IRQ for the device */ + ndev->irq = platform_get_irq(pdev, 0); +@@ -1236,9 +1351,9 @@ static int xcan_probe(struct platform_de + devm_can_led_init(ndev); + clk_disable_unprepare(priv->bus_clk); + clk_disable_unprepare(priv->can_clk); +- netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n", ++ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth: actual %d, using %d\n", + priv->reg_base, ndev->irq, priv->can.clock.freq, +- priv->tx_max); ++ tx_fifo_depth, priv->tx_max); + + return 0; + +@@ -1274,14 +1389,6 @@ static int xcan_remove(struct platform_d + return 0; + } + +-/* Match table for OF platform binding */ +-static struct of_device_id xcan_of_match[] = { +- { .compatible = "xlnx,zynq-can-1.0", }, +- { .compatible = "xlnx,axi-can-1.00.a", }, +- { /* end of list */ }, +-}; +-MODULE_DEVICE_TABLE(of, xcan_of_match); +- + static struct platform_driver xcan_driver = { + .probe = xcan_probe, + .remove = xcan_remove, diff --git a/queue-3.18/series b/queue-3.18/series index a569edd498c..b7e1ad6b331 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -16,3 +16,13 @@ tcp-do-not-cancel-delay-ack-on-dctcp-special-ack.patch tcp-do-not-delay-ack-in-dctcp-upon-ce-status-change.patch tcp-avoid-collapses-in-tcp_prune_queue-if-possible.patch tcp-detect-malicious-patterns-in-tcp_collapse_ofo_queue.patch +usb-cdc_acm-add-quirk-for-castles-vega3000.patch +usb-core-handle-hub-c_port_over_current-condition.patch +usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch +can-xilinx_can-fix-rx-loop-if-rxnemp-is-asserted-without-rxok.patch +can-xilinx_can-fix-recovery-from-error-states-not-being-propagated.patch +can-xilinx_can-fix-device-dropping-off-bus-on-rx-overrun.patch +can-xilinx_can-keep-only-1-2-frames-in-tx-fifo-to-fix-tx-accounting.patch +can-xilinx_can-fix-incorrect-clear-of-non-processed-interrupts.patch +can-xilinx_can-fix-rx-overflow-interrupt-not-being-enabled.patch +arm-fix-put_user-for-gcc-8.patch diff --git a/queue-3.18/usb-cdc_acm-add-quirk-for-castles-vega3000.patch b/queue-3.18/usb-cdc_acm-add-quirk-for-castles-vega3000.patch new file mode 100644 index 00000000000..d3b033c6209 --- /dev/null +++ b/queue-3.18/usb-cdc_acm-add-quirk-for-castles-vega3000.patch @@ -0,0 +1,33 @@ +From 1445cbe476fc3dd09c0b380b206526a49403c071 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Tue, 10 Jul 2018 08:28:49 +0200 +Subject: usb: cdc_acm: Add quirk for Castles VEGA3000 + +From: Lubomir Rintel + +commit 1445cbe476fc3dd09c0b380b206526a49403c071 upstream. + +The device (a POS terminal) implements CDC ACM, but has not union +descriptor. + +Signed-off-by: Lubomir Rintel +Acked-by: Oliver Neukum +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1785,6 +1785,9 @@ static const struct usb_device_id acm_id + { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ + .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ + }, ++ { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ ++ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ ++ }, + + { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ + .driver_info = CLEAR_HALT_CONDITIONS, diff --git a/queue-3.18/usb-core-handle-hub-c_port_over_current-condition.patch b/queue-3.18/usb-core-handle-hub-c_port_over_current-condition.patch new file mode 100644 index 00000000000..5bc357031c5 --- /dev/null +++ b/queue-3.18/usb-core-handle-hub-c_port_over_current-condition.patch @@ -0,0 +1,49 @@ +From 249a32b7eeb3edb6897dd38f89651a62163ac4ed Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Thu, 19 Jul 2018 14:39:37 -0500 +Subject: usb: core: handle hub C_PORT_OVER_CURRENT condition + +From: Bin Liu + +commit 249a32b7eeb3edb6897dd38f89651a62163ac4ed upstream. + +Based on USB2.0 Spec Section 11.12.5, + + "If a hub has per-port power switching and per-port current limiting, + an over-current on one port may still cause the power on another port + to fall below specific minimums. In this case, the affected port is + placed in the Power-Off state and C_PORT_OVER_CURRENT is set for the + port, but PORT_OVER_CURRENT is not set." + +so let's check C_PORT_OVER_CURRENT too for over current condition. + +Fixes: 08d1dec6f405 ("usb:hub set hub->change_bits when over-current happens") +Cc: +Tested-by: Alessandro Antenucci +Signed-off-by: Bin Liu +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1151,10 +1151,14 @@ static void hub_activate(struct usb_hub + + if (!udev || udev->state == USB_STATE_NOTATTACHED) { + /* Tell hub_wq to disconnect the device or +- * check for a new connection ++ * check for a new connection or over current condition. ++ * Based on USB2.0 Spec Section 11.12.5, ++ * C_PORT_OVER_CURRENT could be set while ++ * PORT_OVER_CURRENT is not. So check for any of them. + */ + if (udev || (portstatus & USB_PORT_STAT_CONNECTION) || +- (portstatus & USB_PORT_STAT_OVERCURRENT)) ++ (portstatus & USB_PORT_STAT_OVERCURRENT) || ++ (portchange & USB_PORT_STAT_C_OVERCURRENT)) + set_bit(port1, hub->change_bits); + + } else if (portstatus & USB_PORT_STAT_ENABLE) { diff --git a/queue-3.18/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch b/queue-3.18/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch new file mode 100644 index 00000000000..1ff6f5b80ff --- /dev/null +++ b/queue-3.18/usb-gadget-f_fs-only-return-delayed-status-when-len-is-0.patch @@ -0,0 +1,54 @@ +From 4d644abf25698362bd33d17c9ddc8f7122c30f17 Mon Sep 17 00:00:00 2001 +From: Jerry Zhang +Date: Mon, 2 Jul 2018 12:48:08 -0700 +Subject: usb: gadget: f_fs: Only return delayed status when len is 0 + +From: Jerry Zhang + +commit 4d644abf25698362bd33d17c9ddc8f7122c30f17 upstream. + +Commit 1b9ba000 ("Allow function drivers to pause control +transfers") states that USB_GADGET_DELAYED_STATUS is only +supported if data phase is 0 bytes. + +It seems that when the length is not 0 bytes, there is no +need to explicitly delay the data stage since the transfer +is not completed until the user responds. However, when the +length is 0, there is no data stage and the transfer is +finished once setup() returns, hence there is a need to +explicitly delay completion. + +This manifests as the following bugs: + +Prior to 946ef68ad4e4 ('Let setup() return +USB_GADGET_DELAYED_STATUS'), when setup is 0 bytes, ffs +would require user to queue a 0 byte request in order to +clear setup state. However, that 0 byte request was actually +not needed and would hang and cause errors in other setup +requests. + +After the above commit, 0 byte setups work since the gadget +now accepts empty queues to ep0 to clear the delay, but all +other setups hang. + +Fixes: 946ef68ad4e4 ("Let setup() return USB_GADGET_DELAYED_STATUS") +Signed-off-by: Jerry Zhang +Cc: stable +Acked-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -2987,7 +2987,7 @@ static int ffs_func_setup(struct usb_fun + __ffs_event_add(ffs, FUNCTIONFS_SETUP); + spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags); + +- return USB_GADGET_DELAYED_STATUS; ++ return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0; + } + + static void ffs_func_suspend(struct usb_function *f) -- 2.47.3