From c27d13395f64dab69b380cc313402e55ad1c0220 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 16 Oct 2022 09:28:25 +0200 Subject: [PATCH] 5.4-stable patches added patches: can-kvaser_usb-fix-use-of-uninitialized-completion.patch can-kvaser_usb_leaf-fix-can-state-after-restart.patch can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch cifs-fix-the-error-length-of-validate_negotiate_info-message.patch iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch iio-pressure-dps310-refactor-startup-procedure.patch iio-pressure-dps310-reset-chip-after-timeout.patch mmc-sdhci-sprd-fix-minimum-clock-limit.patch usb-add-quirks-for-lenovo-onelink-dock.patch --- ...-fix-use-of-uninitialized-completion.patch | 57 +++++ ...usb_leaf-fix-can-state-after-restart.patch | 40 +++ ...fix-overread-with-an-invalid-command.patch | 143 +++++++++++ ...x-tx-queue-out-of-sync-after-restart.patch | 68 +++++ ...efore-re-reading-them-for-cache-none.patch | 44 ++++ ...h-of-validate_negotiate_info-message.patch | 45 ++++ ...r-fix-i2c-read-protocol-requirements.patch | 113 +++++++++ ...re-dps310-refactor-startup-procedure.patch | 239 ++++++++++++++++++ ...sure-dps310-reset-chip-after-timeout.patch | 148 +++++++++++ ...ring-rw-fix-unexpected-link-breakage.patch | 38 --- ...c-sdhci-sprd-fix-minimum-clock-limit.patch | 39 +++ queue-5.4/series | 12 +- ...b-add-quirks-for-lenovo-onelink-dock.patch | 146 +++++++++++ 13 files changed, 1093 insertions(+), 39 deletions(-) create mode 100644 queue-5.4/can-kvaser_usb-fix-use-of-uninitialized-completion.patch create mode 100644 queue-5.4/can-kvaser_usb_leaf-fix-can-state-after-restart.patch create mode 100644 queue-5.4/can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch create mode 100644 queue-5.4/can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch create mode 100644 queue-5.4/cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch create mode 100644 queue-5.4/cifs-fix-the-error-length-of-validate_negotiate_info-message.patch create mode 100644 queue-5.4/iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch create mode 100644 queue-5.4/iio-pressure-dps310-refactor-startup-procedure.patch create mode 100644 queue-5.4/iio-pressure-dps310-reset-chip-after-timeout.patch delete mode 100644 queue-5.4/io_uring-rw-fix-unexpected-link-breakage.patch create mode 100644 queue-5.4/mmc-sdhci-sprd-fix-minimum-clock-limit.patch create mode 100644 queue-5.4/usb-add-quirks-for-lenovo-onelink-dock.patch diff --git a/queue-5.4/can-kvaser_usb-fix-use-of-uninitialized-completion.patch b/queue-5.4/can-kvaser_usb-fix-use-of-uninitialized-completion.patch new file mode 100644 index 00000000000..a29acd75187 --- /dev/null +++ b/queue-5.4/can-kvaser_usb-fix-use-of-uninitialized-completion.patch @@ -0,0 +1,57 @@ +From cd7f30e174d09a02ca2afa5ef093fb0f0352e0d8 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:27 +0200 +Subject: can: kvaser_usb: Fix use of uninitialized completion + +From: Anssi Hannula + +commit cd7f30e174d09a02ca2afa5ef093fb0f0352e0d8 upstream. + +flush_comp is initialized when CMD_FLUSH_QUEUE is sent to the device and +completed when the device sends CMD_FLUSH_QUEUE_RESP. + +This causes completion of uninitialized completion if the device sends +CMD_FLUSH_QUEUE_RESP before CMD_FLUSH_QUEUE is ever sent (e.g. as a +response to a flush by a previously bound driver, or a misbehaving +device). + +Fix that by initializing flush_comp in kvaser_usb_init_one() like the +other completions. + +This issue is only triggerable after RX URBs have been set up, i.e. the +interface has been opened at least once. + +Cc: stable@vger.kernel.org +Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-3-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 1 + + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -690,6 +690,7 @@ static int kvaser_usb_init_one(struct kv + init_usb_anchor(&priv->tx_submitted); + init_completion(&priv->start_comp); + init_completion(&priv->stop_comp); ++ init_completion(&priv->flush_comp); + priv->can.ctrlmode_supported = 0; + + priv->dev = dev; +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -1886,7 +1886,7 @@ static int kvaser_usb_hydra_flush_queue( + { + int err; + +- init_completion(&priv->flush_comp); ++ reinit_completion(&priv->flush_comp); + + err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE, + priv->channel); diff --git a/queue-5.4/can-kvaser_usb_leaf-fix-can-state-after-restart.patch b/queue-5.4/can-kvaser_usb_leaf-fix-can-state-after-restart.patch new file mode 100644 index 00000000000..3652b5be7c3 --- /dev/null +++ b/queue-5.4/can-kvaser_usb_leaf-fix-can-state-after-restart.patch @@ -0,0 +1,40 @@ +From 0be1a655fe68c8e6dcadbcbddb69cf2fb29881f5 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:29 +0200 +Subject: can: kvaser_usb_leaf: Fix CAN state after restart + +From: Anssi Hannula + +commit 0be1a655fe68c8e6dcadbcbddb69cf2fb29881f5 upstream. + +can_restart() expects CMD_START_CHIP to set the error state to +ERROR_ACTIVE as it calls netif_carrier_on() immediately afterwards. + +Otherwise the user may immediately trigger restart again and hit a +BUG_ON() in can_restart(). + +Fix kvaser_usb_leaf set_mode(CMD_START_CHIP) to set the expected state. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-5-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -1435,6 +1435,8 @@ static int kvaser_usb_leaf_set_mode(stru + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); + if (err) + return err; ++ ++ priv->can.state = CAN_STATE_ERROR_ACTIVE; + break; + default: + return -EOPNOTSUPP; diff --git a/queue-5.4/can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch b/queue-5.4/can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch new file mode 100644 index 00000000000..7b762a8416f --- /dev/null +++ b/queue-5.4/can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch @@ -0,0 +1,143 @@ +From 1499ecaea9d2ba68d5e18d80573b4561a8dc4ee7 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:26 +0200 +Subject: can: kvaser_usb_leaf: Fix overread with an invalid command + +From: Anssi Hannula + +commit 1499ecaea9d2ba68d5e18d80573b4561a8dc4ee7 upstream. + +For command events read from the device, +kvaser_usb_leaf_read_bulk_callback() verifies that cmd->len does not +exceed the size of the received data, but the actual kvaser_cmd handlers +will happily read any kvaser_cmd fields without checking for cmd->len. + +This can cause an overread if the last cmd in the buffer is shorter than +expected for the command type (with cmd->len showing the actual short +size). + +Maximum overread seems to be 22 bytes (CMD_LEAF_LOG_MESSAGE), some of +which are delivered to userspace as-is. + +Fix that by verifying the length of command before handling it. + +This issue can only occur after RX URBs have been set up, i.e. the +interface has been opened at least once. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-2-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 75 +++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -309,6 +309,38 @@ struct kvaser_cmd { + } u; + } __packed; + ++#define CMD_SIZE_ANY 0xff ++#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field) ++ ++static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { ++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), ++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), ++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo), ++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can), ++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), ++ [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), ++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), ++ /* ignored events: */ ++ [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, ++}; ++ ++static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { ++ [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), ++ [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), ++ [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), ++ [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo), ++ [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), ++ [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), ++ [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), ++ [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), ++ /* ignored events: */ ++ [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, ++}; ++ + /* Summary of a kvaser error event, for a unified Leaf/Usbcan error + * handling. Some discrepancies between the two families exist: + * +@@ -396,6 +428,43 @@ static const struct kvaser_usb_dev_cfg k + .bittiming_const = &kvaser_usb_flexc_bittiming_const, + }; + ++static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, ++ const struct kvaser_cmd *cmd) ++{ ++ /* buffer size >= cmd->len ensured by caller */ ++ u8 min_size = 0; ++ ++ switch (dev->driver_info->family) { ++ case KVASER_LEAF: ++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf)) ++ min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id]; ++ break; ++ case KVASER_USBCAN: ++ if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan)) ++ min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id]; ++ break; ++ } ++ ++ if (min_size == CMD_SIZE_ANY) ++ return 0; ++ ++ if (min_size) { ++ min_size += CMD_HEADER_LEN; ++ if (cmd->len >= min_size) ++ return 0; ++ ++ dev_err_ratelimited(&dev->intf->dev, ++ "Received command %u too short (size %u, needed %u)", ++ cmd->id, cmd->len, min_size); ++ return -EIO; ++ } ++ ++ dev_warn_ratelimited(&dev->intf->dev, ++ "Unhandled command (%d, size %d)\n", ++ cmd->id, cmd->len); ++ return -EINVAL; ++} ++ + static void * + kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, + const struct sk_buff *skb, int *frame_len, +@@ -503,6 +572,9 @@ static int kvaser_usb_leaf_wait_cmd(cons + end: + kfree(buf); + ++ if (err == 0) ++ err = kvaser_usb_leaf_verify_size(dev, cmd); ++ + return err; + } + +@@ -1137,6 +1209,9 @@ static void kvaser_usb_leaf_stop_chip_re + static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) + { ++ if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) ++ return; ++ + switch (cmd->id) { + case CMD_START_CHIP_REPLY: + kvaser_usb_leaf_start_chip_reply(dev, cmd); diff --git a/queue-5.4/can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch b/queue-5.4/can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch new file mode 100644 index 00000000000..d607b85e88a --- /dev/null +++ b/queue-5.4/can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch @@ -0,0 +1,68 @@ +From 455561fb618fde40558776b5b8435f9420f335db Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Mon, 10 Oct 2022 17:08:28 +0200 +Subject: can: kvaser_usb_leaf: Fix TX queue out of sync after restart + +From: Anssi Hannula + +commit 455561fb618fde40558776b5b8435f9420f335db upstream. + +The TX queue seems to be implicitly flushed by the hardware during +bus-off or bus-off recovery, but the driver does not reset the TX +bookkeeping. + +Despite not resetting TX bookkeeping the driver still re-enables TX +queue unconditionally, leading to "cannot find free context" / +NETDEV_TX_BUSY errors if the TX queue was full at bus-off time. + +Fix that by resetting TX bookkeeping on CAN restart. + +Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. + +Cc: stable@vger.kernel.org +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Tested-by: Jimmy Assarsson +Signed-off-by: Anssi Hannula +Signed-off-by: Jimmy Assarsson +Link: https://lore.kernel.org/all/20221010150829.199676-4-extja@kvaser.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 ++ + drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ + 3 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +@@ -178,6 +178,8 @@ struct kvaser_usb_dev_cfg { + extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; + extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; + ++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); ++ + int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, + int *actual_len); + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +@@ -453,7 +453,7 @@ static void kvaser_usb_reset_tx_urb_cont + /* This method might sleep. Do not call it in the atomic context + * of URB completions. + */ +-static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) ++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) + { + usb_kill_anchored_urbs(&priv->tx_submitted); + kvaser_usb_reset_tx_urb_contexts(priv); +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -1430,6 +1430,8 @@ static int kvaser_usb_leaf_set_mode(stru + + switch (mode) { + case CAN_MODE_START: ++ kvaser_usb_unlink_tx_urbs(priv); ++ + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); + if (err) + return err; diff --git a/queue-5.4/cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch b/queue-5.4/cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch new file mode 100644 index 00000000000..08464cb2177 --- /dev/null +++ b/queue-5.4/cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch @@ -0,0 +1,44 @@ +From bb44c31cdcac107344dd2fcc3bd0504a53575c51 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Tue, 20 Sep 2022 14:32:02 +1000 +Subject: cifs: destage dirty pages before re-reading them for cache=none + +From: Ronnie Sahlberg + +commit bb44c31cdcac107344dd2fcc3bd0504a53575c51 upstream. + +This is the opposite case of kernel bugzilla 216301. +If we mmap a file using cache=none and then proceed to update the mmapped +area these updates are not reflected in a later pread() of that part of the +file. +To fix this we must first destage any dirty pages in the range before +we allow the pread() to proceed. + +Cc: stable@vger.kernel.org +Reviewed-by: Paulo Alcantara (SUSE) +Reviewed-by: Enzo Matsumiya +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/file.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -3877,6 +3877,15 @@ static ssize_t __cifs_readv( + len = ctx->len; + } + ++ if (direct) { ++ rc = filemap_write_and_wait_range(file->f_inode->i_mapping, ++ offset, offset + len - 1); ++ if (rc) { ++ kref_put(&ctx->refcount, cifs_aio_ctx_release); ++ return -EAGAIN; ++ } ++ } ++ + /* grab a lock here due to read response handlers can access ctx */ + mutex_lock(&ctx->aio_mutex); + diff --git a/queue-5.4/cifs-fix-the-error-length-of-validate_negotiate_info-message.patch b/queue-5.4/cifs-fix-the-error-length-of-validate_negotiate_info-message.patch new file mode 100644 index 00000000000..fd8b5caa2ab --- /dev/null +++ b/queue-5.4/cifs-fix-the-error-length-of-validate_negotiate_info-message.patch @@ -0,0 +1,45 @@ +From e98ecc6e94f4e6d21c06660b0f336df02836694f Mon Sep 17 00:00:00 2001 +From: Zhang Xiaoxu +Date: Mon, 26 Sep 2022 11:36:29 +0800 +Subject: cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message + +From: Zhang Xiaoxu + +commit e98ecc6e94f4e6d21c06660b0f336df02836694f upstream. + +Commit d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") +extend the dialects from 3 to 4, but forget to decrease the extended +length when specific the dialect, then the message length is larger +than expected. + +This maybe leak some info through network because not initialize the +message body. + +After apply this patch, the VALIDATE_NEGOTIATE_INFO message length is +reduced from 28 bytes to 26 bytes. + +Fixes: d5c7076b772a ("smb3: add smb3.1.1 to default dialect list") +Signed-off-by: Zhang Xiaoxu +Cc: +Acked-by: Paulo Alcantara (SUSE) +Reviewed-by: Tom Talpey +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/smb2pdu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1100,9 +1100,9 @@ int smb3_validate_negotiate(const unsign + pneg_inbuf->Dialects[0] = + cpu_to_le16(server->vals->protocol_id); + pneg_inbuf->DialectCount = cpu_to_le16(1); +- /* structure is big enough for 3 dialects, sending only 1 */ ++ /* structure is big enough for 4 dialects, sending only 1 */ + inbuflen = sizeof(*pneg_inbuf) - +- sizeof(pneg_inbuf->Dialects[0]) * 2; ++ sizeof(pneg_inbuf->Dialects[0]) * 3; + } + + rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, diff --git a/queue-5.4/iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch b/queue-5.4/iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch new file mode 100644 index 00000000000..f26faac52ee --- /dev/null +++ b/queue-5.4/iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch @@ -0,0 +1,113 @@ +From 558a25f903b4af6361b7fbeea08a6446a0745653 Mon Sep 17 00:00:00 2001 +From: Michael Hennerich +Date: Tue, 13 Sep 2022 09:34:12 +0200 +Subject: iio: dac: ad5593r: Fix i2c read protocol requirements +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michael Hennerich + +commit 558a25f903b4af6361b7fbeea08a6446a0745653 upstream. + +For reliable operation across the full range of supported +interface rates, the AD5593R needs a STOP condition between +address write, and data read (like show in the datasheet Figure 40) +so in turn i2c_smbus_read_word_swapped cannot be used. + +While at it, a simple helper was added to make the code simpler. + +Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs") +Signed-off-by: Michael Hennerich +Signed-off-by: Nuno Sá +Cc: +Link: https://lore.kernel.org/r/20220913073413.140475-2-nuno.sa@analog.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/dac/ad5593r.c | 46 +++++++++++++++++++++++++++------------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +--- a/drivers/iio/dac/ad5593r.c ++++ b/drivers/iio/dac/ad5593r.c +@@ -14,6 +14,8 @@ + #include + #include + ++#include ++ + #define AD5593R_MODE_CONF (0 << 4) + #define AD5593R_MODE_DAC_WRITE (1 << 4) + #define AD5593R_MODE_ADC_READBACK (4 << 4) +@@ -21,6 +23,24 @@ + #define AD5593R_MODE_GPIO_READBACK (6 << 4) + #define AD5593R_MODE_REG_READBACK (7 << 4) + ++static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value) ++{ ++ int ret; ++ u8 buf[2]; ++ ++ ret = i2c_smbus_write_byte(i2c, reg); ++ if (ret < 0) ++ return ret; ++ ++ ret = i2c_master_recv(i2c, buf, sizeof(buf)); ++ if (ret < 0) ++ return ret; ++ ++ *value = get_unaligned_be16(buf); ++ ++ return 0; ++} ++ + static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +@@ -39,13 +59,7 @@ static int ad5593r_read_adc(struct ad559 + if (val < 0) + return (int) val; + +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); +- if (val < 0) +- return (int) val; +- +- *value = (u16) val; +- +- return 0; ++ return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value); + } + + static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) +@@ -59,25 +73,19 @@ static int ad5593r_reg_write(struct ad55 + static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +- s32 val; +- +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); +- if (val < 0) +- return (int) val; + +- *value = (u16) val; +- +- return 0; ++ return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value); + } + + static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) + { + struct i2c_client *i2c = to_i2c_client(st->dev); +- s32 val; ++ u16 val; ++ int ret; + +- val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); +- if (val < 0) +- return (int) val; ++ ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val); ++ if (ret) ++ return ret; + + *value = (u8) val; + diff --git a/queue-5.4/iio-pressure-dps310-refactor-startup-procedure.patch b/queue-5.4/iio-pressure-dps310-refactor-startup-procedure.patch new file mode 100644 index 00000000000..08672dfd39e --- /dev/null +++ b/queue-5.4/iio-pressure-dps310-refactor-startup-procedure.patch @@ -0,0 +1,239 @@ +From c2329717bdd3fa62f8a2f3d8d85ad0bee4556bd7 Mon Sep 17 00:00:00 2001 +From: Eddie James +Date: Thu, 15 Sep 2022 14:57:18 -0500 +Subject: iio: pressure: dps310: Refactor startup procedure + +From: Eddie James + +commit c2329717bdd3fa62f8a2f3d8d85ad0bee4556bd7 upstream. + +Move the startup procedure into a function, and correct a missing +check on the return code for writing the PRS_CFG register. + +Cc: +Signed-off-by: Eddie James +Reviewed-by: Joel Stanley +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220915195719.136812-2-eajames@linux.ibm.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/pressure/dps310.c | 188 ++++++++++++++++++++++-------------------- + 1 file changed, 99 insertions(+), 89 deletions(-) + +--- a/drivers/iio/pressure/dps310.c ++++ b/drivers/iio/pressure/dps310.c +@@ -159,6 +159,102 @@ static int dps310_get_coefs(struct dps31 + return 0; + } + ++/* ++ * Some versions of the chip will read temperatures in the ~60C range when ++ * it's actually ~20C. This is the manufacturer recommended workaround ++ * to correct the issue. The registers used below are undocumented. ++ */ ++static int dps310_temp_workaround(struct dps310_data *data) ++{ ++ int rc; ++ int reg; ++ ++ rc = regmap_read(data->regmap, 0x32, ®); ++ if (rc) ++ return rc; ++ ++ /* ++ * If bit 1 is set then the device is okay, and the workaround does not ++ * need to be applied ++ */ ++ if (reg & BIT(1)) ++ return 0; ++ ++ rc = regmap_write(data->regmap, 0x0e, 0xA5); ++ if (rc) ++ return rc; ++ ++ rc = regmap_write(data->regmap, 0x0f, 0x96); ++ if (rc) ++ return rc; ++ ++ rc = regmap_write(data->regmap, 0x62, 0x02); ++ if (rc) ++ return rc; ++ ++ rc = regmap_write(data->regmap, 0x0e, 0x00); ++ if (rc) ++ return rc; ++ ++ return regmap_write(data->regmap, 0x0f, 0x00); ++} ++ ++static int dps310_startup(struct dps310_data *data) ++{ ++ int rc; ++ int ready; ++ ++ /* ++ * Set up pressure sensor in single sample, one measurement per second ++ * mode ++ */ ++ rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); ++ if (rc) ++ return rc; ++ ++ /* ++ * Set up external (MEMS) temperature sensor in single sample, one ++ * measurement per second mode ++ */ ++ rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); ++ if (rc) ++ return rc; ++ ++ /* Temp and pressure shifts are disabled when PRC <= 8 */ ++ rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, ++ DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); ++ if (rc) ++ return rc; ++ ++ /* MEAS_CFG doesn't update correctly unless first written with 0 */ ++ rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, ++ DPS310_MEAS_CTRL_BITS, 0); ++ if (rc) ++ return rc; ++ ++ /* Turn on temperature and pressure measurement in the background */ ++ rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, ++ DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | ++ DPS310_TEMP_EN | DPS310_BACKGROUND); ++ if (rc) ++ return rc; ++ ++ /* ++ * Calibration coefficients required for reporting temperature. ++ * They are available 40ms after the device has started ++ */ ++ rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ++ ready & DPS310_COEF_RDY, 10000, 40000); ++ if (rc) ++ return rc; ++ ++ rc = dps310_get_coefs(data); ++ if (rc) ++ return rc; ++ ++ return dps310_temp_workaround(data); ++} ++ + static int dps310_get_pres_precision(struct dps310_data *data) + { + int rc; +@@ -677,52 +773,12 @@ static const struct iio_info dps310_info + .write_raw = dps310_write_raw, + }; + +-/* +- * Some verions of chip will read temperatures in the ~60C range when +- * its actually ~20C. This is the manufacturer recommended workaround +- * to correct the issue. The registers used below are undocumented. +- */ +-static int dps310_temp_workaround(struct dps310_data *data) +-{ +- int rc; +- int reg; +- +- rc = regmap_read(data->regmap, 0x32, ®); +- if (rc < 0) +- return rc; +- +- /* +- * If bit 1 is set then the device is okay, and the workaround does not +- * need to be applied +- */ +- if (reg & BIT(1)) +- return 0; +- +- rc = regmap_write(data->regmap, 0x0e, 0xA5); +- if (rc < 0) +- return rc; +- +- rc = regmap_write(data->regmap, 0x0f, 0x96); +- if (rc < 0) +- return rc; +- +- rc = regmap_write(data->regmap, 0x62, 0x02); +- if (rc < 0) +- return rc; +- +- rc = regmap_write(data->regmap, 0x0e, 0x00); +- if (rc < 0) +- return rc; +- +- return regmap_write(data->regmap, 0x0f, 0x00); +-} +- + static int dps310_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { + struct dps310_data *data; + struct iio_dev *iio; +- int rc, ready; ++ int rc; + + iio = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!iio) +@@ -748,54 +804,8 @@ static int dps310_probe(struct i2c_clien + if (rc) + return rc; + +- /* +- * Set up pressure sensor in single sample, one measurement per second +- * mode +- */ +- rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); +- +- /* +- * Set up external (MEMS) temperature sensor in single sample, one +- * measurement per second mode +- */ +- rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); +- if (rc < 0) +- return rc; +- +- /* Temp and pressure shifts are disabled when PRC <= 8 */ +- rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, +- DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); +- if (rc < 0) +- return rc; +- +- /* MEAS_CFG doesn't update correctly unless first written with 0 */ +- rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, +- DPS310_MEAS_CTRL_BITS, 0); +- if (rc < 0) +- return rc; +- +- /* Turn on temperature and pressure measurement in the background */ +- rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, +- DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | +- DPS310_TEMP_EN | DPS310_BACKGROUND); +- if (rc < 0) +- return rc; +- +- /* +- * Calibration coefficients required for reporting temperature. +- * They are available 40ms after the device has started +- */ +- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, +- ready & DPS310_COEF_RDY, 10000, 40000); +- if (rc < 0) +- return rc; +- +- rc = dps310_get_coefs(data); +- if (rc < 0) +- return rc; +- +- rc = dps310_temp_workaround(data); +- if (rc < 0) ++ rc = dps310_startup(data); ++ if (rc) + return rc; + + rc = devm_iio_device_register(&client->dev, iio); diff --git a/queue-5.4/iio-pressure-dps310-reset-chip-after-timeout.patch b/queue-5.4/iio-pressure-dps310-reset-chip-after-timeout.patch new file mode 100644 index 00000000000..ddbbbf9d15d --- /dev/null +++ b/queue-5.4/iio-pressure-dps310-reset-chip-after-timeout.patch @@ -0,0 +1,148 @@ +From 7b4ab4abcea4c0c10b25187bf2569e5a07e9a20c Mon Sep 17 00:00:00 2001 +From: Eddie James +Date: Thu, 15 Sep 2022 14:57:19 -0500 +Subject: iio: pressure: dps310: Reset chip after timeout + +From: Eddie James + +commit 7b4ab4abcea4c0c10b25187bf2569e5a07e9a20c upstream. + +The DPS310 chip has been observed to get "stuck" such that pressure +and temperature measurements are never indicated as "ready" in the +MEAS_CFG register. The only solution is to reset the device and try +again. In order to avoid continual failures, use a boolean flag to +only try the reset after timeout once if errors persist. + +Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310") +Cc: +Signed-off-by: Eddie James +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220915195719.136812-3-eajames@linux.ibm.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/pressure/dps310.c | 74 ++++++++++++++++++++++++++++++++++++------ + 1 file changed, 64 insertions(+), 10 deletions(-) + +--- a/drivers/iio/pressure/dps310.c ++++ b/drivers/iio/pressure/dps310.c +@@ -89,6 +89,7 @@ struct dps310_data { + s32 c00, c10, c20, c30, c01, c11, c21; + s32 pressure_raw; + s32 temp_raw; ++ bool timeout_recovery_failed; + }; + + static const struct iio_chan_spec dps310_channels[] = { +@@ -393,11 +394,69 @@ static int dps310_get_temp_k(struct dps3 + return scale_factors[ilog2(rc)]; + } + ++static int dps310_reset_wait(struct dps310_data *data) ++{ ++ int rc; ++ ++ rc = regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); ++ if (rc) ++ return rc; ++ ++ /* Wait for device chip access: 2.5ms in specification */ ++ usleep_range(2500, 12000); ++ return 0; ++} ++ ++static int dps310_reset_reinit(struct dps310_data *data) ++{ ++ int rc; ++ ++ rc = dps310_reset_wait(data); ++ if (rc) ++ return rc; ++ ++ return dps310_startup(data); ++} ++ ++static int dps310_ready_status(struct dps310_data *data, int ready_bit, int timeout) ++{ ++ int sleep = DPS310_POLL_SLEEP_US(timeout); ++ int ready; ++ ++ return regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ready & ready_bit, ++ sleep, timeout); ++} ++ ++static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout) ++{ ++ int rc; ++ ++ rc = dps310_ready_status(data, ready_bit, timeout); ++ if (rc) { ++ if (rc == -ETIMEDOUT && !data->timeout_recovery_failed) { ++ /* Reset and reinitialize the chip. */ ++ if (dps310_reset_reinit(data)) { ++ data->timeout_recovery_failed = true; ++ } else { ++ /* Try again to get sensor ready status. */ ++ if (dps310_ready_status(data, ready_bit, timeout)) ++ data->timeout_recovery_failed = true; ++ else ++ return 0; ++ } ++ } ++ ++ return rc; ++ } ++ ++ data->timeout_recovery_failed = false; ++ return 0; ++} ++ + static int dps310_read_pres_raw(struct dps310_data *data) + { + int rc; + int rate; +- int ready; + int timeout; + s32 raw; + u8 val[3]; +@@ -409,9 +468,7 @@ static int dps310_read_pres_raw(struct d + timeout = DPS310_POLL_TIMEOUT_US(rate); + + /* Poll for sensor readiness; base the timeout upon the sample rate. */ +- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, +- ready & DPS310_PRS_RDY, +- DPS310_POLL_SLEEP_US(timeout), timeout); ++ rc = dps310_ready(data, DPS310_PRS_RDY, timeout); + if (rc) + goto done; + +@@ -448,7 +505,6 @@ static int dps310_read_temp_raw(struct d + { + int rc; + int rate; +- int ready; + int timeout; + + if (mutex_lock_interruptible(&data->lock)) +@@ -458,10 +514,8 @@ static int dps310_read_temp_raw(struct d + timeout = DPS310_POLL_TIMEOUT_US(rate); + + /* Poll for sensor readiness; base the timeout upon the sample rate. */ +- rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, +- ready & DPS310_TMP_RDY, +- DPS310_POLL_SLEEP_US(timeout), timeout); +- if (rc < 0) ++ rc = dps310_ready(data, DPS310_TMP_RDY, timeout); ++ if (rc) + goto done; + + rc = dps310_read_temp_ready(data); +@@ -756,7 +810,7 @@ static void dps310_reset(void *action_da + { + struct dps310_data *data = action_data; + +- regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); ++ dps310_reset_wait(data); + } + + static const struct regmap_config dps310_regmap_config = { diff --git a/queue-5.4/io_uring-rw-fix-unexpected-link-breakage.patch b/queue-5.4/io_uring-rw-fix-unexpected-link-breakage.patch deleted file mode 100644 index b829ef2919e..00000000000 --- a/queue-5.4/io_uring-rw-fix-unexpected-link-breakage.patch +++ /dev/null @@ -1,38 +0,0 @@ -From bf68b5b34311ee57ed40749a1257a30b46127556 Mon Sep 17 00:00:00 2001 -From: Pavel Begunkov -Date: Tue, 27 Sep 2022 00:44:39 +0100 -Subject: io_uring/rw: fix unexpected link breakage - -From: Pavel Begunkov - -commit bf68b5b34311ee57ed40749a1257a30b46127556 upstream. - -req->cqe.res is set in io_read() to the amount of bytes left to be done, -which is used to figure out whether to fail a read or not. However, -io_read() may do another without returning, and we stash the previous -value into ->bytes_done but forget to update cqe.res. Then we ask a read -to do strictly less than cqe.res but expect the return to be exactly -cqe.res. - -Fix the bug by updating cqe.res for retries. - -Cc: stable@vger.kernel.org -Reported-and-Tested-by: Beld Zhang -Signed-off-by: Pavel Begunkov -Link: https://lore.kernel.org/r/3a1088440c7be98e5800267af922a67da0ef9f13.1664235732.git.asml.silence@gmail.com -Signed-off-by: Jens Axboe -Signed-off-by: Greg Kroah-Hartman ---- - fs/io_uring.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/fs/io_uring.c -+++ b/fs/io_uring.c -@@ -854,6 +854,7 @@ static int io_do_iopoll(struct io_ring_c - list_for_each_entry_safe(req, tmp, &ctx->poll_list, list) { - struct kiocb *kiocb = &req->rw; - -+ req->cqe.res = iov_iter_count(&s->iter); - /* - * Move completed entries to our local list. If we find a - * request that requires polling, break out and complete diff --git a/queue-5.4/mmc-sdhci-sprd-fix-minimum-clock-limit.patch b/queue-5.4/mmc-sdhci-sprd-fix-minimum-clock-limit.patch new file mode 100644 index 00000000000..44679350264 --- /dev/null +++ b/queue-5.4/mmc-sdhci-sprd-fix-minimum-clock-limit.patch @@ -0,0 +1,39 @@ +From 6e141772e6465f937458b35ddcfd0a981b6f5280 Mon Sep 17 00:00:00 2001 +From: Wenchao Chen +Date: Tue, 11 Oct 2022 18:49:35 +0800 +Subject: mmc: sdhci-sprd: Fix minimum clock limit + +From: Wenchao Chen + +commit 6e141772e6465f937458b35ddcfd0a981b6f5280 upstream. + +The Spreadtrum controller supports 100KHz minimal clock rate, which means +that the current value 400KHz is wrong. + +Unfortunately this has also lead to fail to initialize some cards, which +are allowed to require 100KHz to work. So, let's fix the problem by +changing the minimal supported clock rate to 100KHz. + +Signed-off-by: Wenchao Chen +Acked-by: Adrian Hunter +Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20221011104935.10980-1-wenchao.chen666@gmail.com +[Ulf: Clarified to commit-message] +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-sprd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-sprd.c ++++ b/drivers/mmc/host/sdhci-sprd.c +@@ -295,7 +295,7 @@ static unsigned int sdhci_sprd_get_max_c + + static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host) + { +- return 400000; ++ return 100000; + } + + static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host, diff --git a/queue-5.4/series b/queue-5.4/series index 3eb7468f240..dc9d20b818d 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -7,4 +7,14 @@ alsa-hda-realtek-correct-pin-configs-for-asus-g533z.patch alsa-hda-realtek-add-quirk-for-asus-gv601r-laptop.patch alsa-hda-realtek-add-intel-reference-ssid-to-support-headset-keys.patch mtd-rawnand-atmel-unmap-streaming-dma-mappings.patch -io_uring-rw-fix-unexpected-link-breakage.patch +cifs-destage-dirty-pages-before-re-reading-them-for-cache-none.patch +cifs-fix-the-error-length-of-validate_negotiate_info-message.patch +iio-dac-ad5593r-fix-i2c-read-protocol-requirements.patch +iio-pressure-dps310-refactor-startup-procedure.patch +iio-pressure-dps310-reset-chip-after-timeout.patch +usb-add-quirks-for-lenovo-onelink-dock.patch +can-kvaser_usb-fix-use-of-uninitialized-completion.patch +can-kvaser_usb_leaf-fix-overread-with-an-invalid-command.patch +can-kvaser_usb_leaf-fix-tx-queue-out-of-sync-after-restart.patch +can-kvaser_usb_leaf-fix-can-state-after-restart.patch +mmc-sdhci-sprd-fix-minimum-clock-limit.patch diff --git a/queue-5.4/usb-add-quirks-for-lenovo-onelink-dock.patch b/queue-5.4/usb-add-quirks-for-lenovo-onelink-dock.patch new file mode 100644 index 00000000000..dba60f3a60c --- /dev/null +++ b/queue-5.4/usb-add-quirks-for-lenovo-onelink-dock.patch @@ -0,0 +1,146 @@ +From 37d49519b41405b08748392c6a7f193d9f77ecd2 Mon Sep 17 00:00:00 2001 +From: Jean-Francois Le Fillatre +Date: Tue, 27 Sep 2022 09:34:07 +0200 +Subject: usb: add quirks for Lenovo OneLink+ Dock + +From: Jean-Francois Le Fillatre + +commit 37d49519b41405b08748392c6a7f193d9f77ecd2 upstream. + +The Lenovo OneLink+ Dock contains two VL812 USB3.0 controllers: +17ef:1018 upstream +17ef:1019 downstream + +These hubs suffer from two separate problems: + +1) After the host system was suspended and woken up, the hubs appear to + be in a random state. Some downstream ports (both internal to the + built-in audio and network controllers, and external to USB sockets) + may no longer be functional. The exact list of disabled ports (if + any) changes from wakeup to wakeup. Ports remain in that state until + the dock is power-cycled, or until the laptop is rebooted. + + Wakeup sources connected to the hubs (keyboard, WoL on the integrated + gigabit controller) will wake the system up from suspend, but they + may no longer work after wakeup (and in that case will no longer work + as wakeup source in a subsequent suspend-wakeup cycle). + + This issue appears in the logs with messages such as: + + usb 1-6.1-port4: cannot disable (err = -71) + usb 1-6-port2: cannot disable (err = -71) + usb 1-6.1: clear tt 1 (80c0) error -71 + usb 1-6-port4: cannot disable (err = -71) + usb 1-6.4: PM: dpm_run_callback(): usb_dev_resume+0x0/0x10 [usbcore] returns -71 + usb 1-6.4: PM: failed to resume async: error -71 + usb 1-7: reset full-speed USB device number 5 using xhci_hcd + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: Cannot enable. Maybe the USB cable is bad? + usb 1-6.1-port1: cannot disable (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: cannot reset (err = -71) + usb 1-6.1-port1: Cannot enable. Maybe the USB cable is bad? + usb 1-6.1-port1: cannot disable (err = -71) + +2) Some USB devices cannot be enumerated properly. So far I have only + seen the issue with USB 3.0 devices. The same devices work without + problem directly connected to the host system, to other systems or to + other hubs (even when those hubs are connected to the OneLink+ dock). + + One very reliable reproducer is this USB 3.0 HDD enclosure: + 152d:9561 JMicron Technology Corp. / JMicron USA Technology Corp. Mobius + + I have seen it happen sporadically with other USB 3.0 enclosures, + with controllers from different manufacturers, all self-powered. + + Typical messages in the logs: + + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + usb 2-1.4: device not accepting address 6, error -62 + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + usb 2-1.4: device not accepting address 7, error -62 + usb 2-1-port4: attempt power cycle + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + usb 2-1.4: device not accepting address 8, error -62 + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + usb 2-1.4: device not accepting address 9, error -62 + usb 2-1-port4: unable to enumerate USB device + +Through trial and error, I found that the USB_QUIRK_RESET_RESUME solved +the second issue. Further testing then uncovered the first issue. Test +results are summarized in this table: + +======================================================================================= +Settings USB2 hotplug USB3 hotplug State after waking up +--------------------------------------------------------------------------------------- + +power/control=auto works fails broken + +usbcore.autosuspend=-1 works works broken +OR power/control=on + +power/control=auto works (1) works (1) works +and USB_QUIRK_RESET_RESUME + +power/control=on works works works +and USB_QUIRK_RESET_RESUME + +HUB_QUIRK_DISABLE_AUTOSUSPEND works works works +and USB_QUIRK_RESET_RESUME + +======================================================================================= + +In those results, the power/control settings are applied to both hubs, +both on the USB2 and USB3 side, before each test. + +From those results, USB_QUIRK_RESET_RESUME is required to reset the hubs +properly after a suspend-wakeup cycle, and the hubs must not autosuspend +to work around the USB3 issue. + +A secondary effect of USB_QUIRK_RESET_RESUME is to prevent the hubs' +upstream links from suspending (the downstream ports can still suspend). +This secondary effect is used in results (1). It is enough to solve the +USB3 problem. + +Setting USB_QUIRK_RESET_RESUME on those hubs is the smallest patch that +solves both issues. + +Prior to creating this patch, I have used the USB_QUIRK_RESET_RESUME via +the kernel command line for over a year without noticing any side +effect. + +Thanks to Oliver Neukum @Suse for explanations of the operations of +USB_QUIRK_RESET_RESUME, and requesting more testing. + +Signed-off-by: Jean-Francois Le Fillatre +Cc: stable +Link: https://lore.kernel.org/r/20220927073407.5672-1-jflf_kernel@gmx.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -438,6 +438,10 @@ static const struct usb_device_id usb_qu + { USB_DEVICE(0x1532, 0x0116), .driver_info = + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + ++ /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ ++ { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME }, ++ { USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + /* Lenovo USB-C to Ethernet Adapter RTL8153-04 */ + { USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM }, + -- 2.47.3