From: Greg Kroah-Hartman Date: Thu, 31 Mar 2022 19:02:55 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.14.275~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d919fdedc1713f0270d8fb40a73d754a1100b7b4;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index c81b1acb2b6..a636402cf6e 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -16,3 +16,7 @@ iommu-iova-improve-32-bit-free-space-estimate.patch tpm-fix-reference-counting-for-struct-tpm_chip.patch block-add-a-helper-to-validate-the-block-size.patch virtio-blk-use-blk_validate_block_size-to-validate-block-size.patch +usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch +xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch +xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch +xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch diff --git a/queue-5.4/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch b/queue-5.4/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch new file mode 100644 index 00000000000..5bce74483b3 --- /dev/null +++ b/queue-5.4/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch @@ -0,0 +1,353 @@ +From 1892bf90677abcad7f06e897e308f5c3e3618dd4 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 17 Mar 2022 16:39:10 -0400 +Subject: USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c + +From: Alan Stern + +commit 1892bf90677abcad7f06e897e308f5c3e3618dd4 upstream. + +The kernel test robot found a problem with the ene_ub6250 subdriver in +usb-storage: It uses structures containing bitfields to represent +hardware bits in its SD_STATUS, MS_STATUS, and SM_STATUS bytes. This +is not safe; it presumes a particular bit ordering and it assumes the +compiler will not insert padding, neither of which is guaranteed. + +This patch fixes the problem by changing the structures to simple u8 +values, with the bitfields replaced by bitmask constants. + +CC: +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YjOcbuU106UpJ/V8@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/ene_ub6250.c | 153 +++++++++++++++++++-------------------- + 1 file changed, 75 insertions(+), 78 deletions(-) + +--- a/drivers/usb/storage/ene_ub6250.c ++++ b/drivers/usb/storage/ene_ub6250.c +@@ -237,36 +237,33 @@ static struct us_unusual_dev ene_ub6250_ + #define memstick_logaddr(logadr1, logadr0) ((((u16)(logadr1)) << 8) | (logadr0)) + + +-struct SD_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 IsMMC:1; +- u8 HiCapacity:1; +- u8 HiSpeed:1; +- u8 WtP:1; +- u8 Reserved:1; +-}; +- +-struct MS_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 IsMSPro:1; +- u8 IsMSPHG:1; +- u8 Reserved1:1; +- u8 WtP:1; +- u8 Reserved2:1; +-}; +- +-struct SM_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 Reserved:3; +- u8 WtP:1; +- u8 IsMS:1; +-}; ++/* SD_STATUS bits */ ++#define SD_Insert BIT(0) ++#define SD_Ready BIT(1) ++#define SD_MediaChange BIT(2) ++#define SD_IsMMC BIT(3) ++#define SD_HiCapacity BIT(4) ++#define SD_HiSpeed BIT(5) ++#define SD_WtP BIT(6) ++ /* Bit 7 reserved */ ++ ++/* MS_STATUS bits */ ++#define MS_Insert BIT(0) ++#define MS_Ready BIT(1) ++#define MS_MediaChange BIT(2) ++#define MS_IsMSPro BIT(3) ++#define MS_IsMSPHG BIT(4) ++ /* Bit 5 reserved */ ++#define MS_WtP BIT(6) ++ /* Bit 7 reserved */ ++ ++/* SM_STATUS bits */ ++#define SM_Insert BIT(0) ++#define SM_Ready BIT(1) ++#define SM_MediaChange BIT(2) ++ /* Bits 3-5 reserved */ ++#define SM_WtP BIT(6) ++#define SM_IsMS BIT(7) + + struct ms_bootblock_cis { + u8 bCistplDEVICE[6]; /* 0 */ +@@ -437,9 +434,9 @@ struct ene_ub6250_info { + u8 *bbuf; + + /* for 6250 code */ +- struct SD_STATUS SD_Status; +- struct MS_STATUS MS_Status; +- struct SM_STATUS SM_Status; ++ u8 SD_Status; ++ u8 MS_Status; ++ u8 SM_Status; + + /* ----- SD Control Data ---------------- */ + /*SD_REGISTER SD_Regs; */ +@@ -602,7 +599,7 @@ static int sd_scsi_test_unit_ready(struc + { + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + +- if (info->SD_Status.Insert && info->SD_Status.Ready) ++ if ((info->SD_Status & SD_Insert) && (info->SD_Status & SD_Ready)) + return USB_STOR_TRANSPORT_GOOD; + else { + ene_sd_init(us); +@@ -622,7 +619,7 @@ static int sd_scsi_mode_sense(struct us_ + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + +- if (info->SD_Status.WtP) ++ if (info->SD_Status & SD_WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); +@@ -641,9 +638,9 @@ static int sd_scsi_read_capacity(struct + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + usb_stor_dbg(us, "sd_scsi_read_capacity\n"); +- if (info->SD_Status.HiCapacity) { ++ if (info->SD_Status & SD_HiCapacity) { + bl_len = 0x200; +- if (info->SD_Status.IsMMC) ++ if (info->SD_Status & SD_IsMMC) + bl_num = info->HC_C_SIZE-1; + else + bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; +@@ -693,7 +690,7 @@ static int sd_scsi_read(struct us_data * + return USB_STOR_TRANSPORT_ERROR; + } + +- if (info->SD_Status.HiCapacity) ++ if (info->SD_Status & SD_HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ +@@ -733,7 +730,7 @@ static int sd_scsi_write(struct us_data + return USB_STOR_TRANSPORT_ERROR; + } + +- if (info->SD_Status.HiCapacity) ++ if (info->SD_Status & SD_HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ +@@ -1455,7 +1452,7 @@ static int ms_scsi_test_unit_ready(struc + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */ +- if (info->MS_Status.Insert && info->MS_Status.Ready) { ++ if ((info->MS_Status & MS_Insert) && (info->MS_Status & MS_Ready)) { + return USB_STOR_TRANSPORT_GOOD; + } else { + ene_ms_init(us); +@@ -1475,7 +1472,7 @@ static int ms_scsi_mode_sense(struct us_ + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + +- if (info->MS_Status.WtP) ++ if (info->MS_Status & MS_WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); +@@ -1494,7 +1491,7 @@ static int ms_scsi_read_capacity(struct + + usb_stor_dbg(us, "ms_scsi_read_capacity\n"); + bl_len = 0x200; +- if (info->MS_Status.IsMSPro) ++ if (info->MS_Status & MS_IsMSPro) + bl_num = info->MSP_TotalBlock - 1; + else + bl_num = info->MS_Lib.NumberOfLogBlock * info->MS_Lib.blockSize * 2 - 1; +@@ -1649,7 +1646,7 @@ static int ms_scsi_read(struct us_data * + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + +- if (info->MS_Status.IsMSPro) { ++ if (info->MS_Status & MS_IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + usb_stor_dbg(us, "Load MPS RW pattern Fail !!\n"); +@@ -1750,7 +1747,7 @@ static int ms_scsi_write(struct us_data + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + +- if (info->MS_Status.IsMSPro) { ++ if (info->MS_Status & MS_IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + pr_info("Load MSP RW pattern Fail !!\n"); +@@ -1858,12 +1855,12 @@ static int ene_get_card_status(struct us + + tmpreg = (u16) reg4b; + reg4b = *(u32 *)(&buf[0x14]); +- if (info->SD_Status.HiCapacity && !info->SD_Status.IsMMC) ++ if ((info->SD_Status & SD_HiCapacity) && !(info->SD_Status & SD_IsMMC)) + info->HC_C_SIZE = (reg4b >> 8) & 0x3fffff; + + info->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (u16)(reg4b >> 22); + info->SD_C_SIZE_MULT = (u8)(reg4b >> 7) & 0x07; +- if (info->SD_Status.HiCapacity && info->SD_Status.IsMMC) ++ if ((info->SD_Status & SD_HiCapacity) && (info->SD_Status & SD_IsMMC)) + info->HC_C_SIZE = *(u32 *)(&buf[0x100]); + + if (info->SD_READ_BL_LEN > SD_BLOCK_LEN) { +@@ -2075,6 +2072,7 @@ static int ene_ms_init(struct us_data *u + u16 MSP_BlockSize, MSP_UserAreaBlocks; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + u8 *bbuf = info->bbuf; ++ unsigned int s; + + printk(KERN_INFO "transport --- ENE_MSInit\n"); + +@@ -2099,15 +2097,16 @@ static int ene_ms_init(struct us_data *u + return USB_STOR_TRANSPORT_ERROR; + } + /* the same part to test ENE */ +- info->MS_Status = *(struct MS_STATUS *) bbuf; ++ info->MS_Status = bbuf[0]; + +- if (info->MS_Status.Insert && info->MS_Status.Ready) { +- printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); +- printk(KERN_INFO "Ready = %x\n", info->MS_Status.Ready); +- printk(KERN_INFO "IsMSPro = %x\n", info->MS_Status.IsMSPro); +- printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); +- printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); +- if (info->MS_Status.IsMSPro) { ++ s = info->MS_Status; ++ if ((s & MS_Insert) && (s & MS_Ready)) { ++ printk(KERN_INFO "Insert = %x\n", !!(s & MS_Insert)); ++ printk(KERN_INFO "Ready = %x\n", !!(s & MS_Ready)); ++ printk(KERN_INFO "IsMSPro = %x\n", !!(s & MS_IsMSPro)); ++ printk(KERN_INFO "IsMSPHG = %x\n", !!(s & MS_IsMSPHG)); ++ printk(KERN_INFO "WtP= %x\n", !!(s & MS_WtP)); ++ if (s & MS_IsMSPro) { + MSP_BlockSize = (bbuf[6] << 8) | bbuf[7]; + MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11]; + info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; +@@ -2168,17 +2167,17 @@ static int ene_sd_init(struct us_data *u + return USB_STOR_TRANSPORT_ERROR; + } + +- info->SD_Status = *(struct SD_STATUS *) bbuf; +- if (info->SD_Status.Insert && info->SD_Status.Ready) { +- struct SD_STATUS *s = &info->SD_Status; ++ info->SD_Status = bbuf[0]; ++ if ((info->SD_Status & SD_Insert) && (info->SD_Status & SD_Ready)) { ++ unsigned int s = info->SD_Status; + + ene_get_card_status(us, bbuf); +- usb_stor_dbg(us, "Insert = %x\n", s->Insert); +- usb_stor_dbg(us, "Ready = %x\n", s->Ready); +- usb_stor_dbg(us, "IsMMC = %x\n", s->IsMMC); +- usb_stor_dbg(us, "HiCapacity = %x\n", s->HiCapacity); +- usb_stor_dbg(us, "HiSpeed = %x\n", s->HiSpeed); +- usb_stor_dbg(us, "WtP = %x\n", s->WtP); ++ usb_stor_dbg(us, "Insert = %x\n", !!(s & SD_Insert)); ++ usb_stor_dbg(us, "Ready = %x\n", !!(s & SD_Ready)); ++ usb_stor_dbg(us, "IsMMC = %x\n", !!(s & SD_IsMMC)); ++ usb_stor_dbg(us, "HiCapacity = %x\n", !!(s & SD_HiCapacity)); ++ usb_stor_dbg(us, "HiSpeed = %x\n", !!(s & SD_HiSpeed)); ++ usb_stor_dbg(us, "WtP = %x\n", !!(s & SD_WtP)); + } else { + usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]); + return USB_STOR_TRANSPORT_ERROR; +@@ -2200,14 +2199,14 @@ static int ene_init(struct us_data *us) + + misc_reg03 = bbuf[0]; + if (misc_reg03 & 0x01) { +- if (!info->SD_Status.Ready) { ++ if (!(info->SD_Status & SD_Ready)) { + result = ene_sd_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + } + } + if (misc_reg03 & 0x02) { +- if (!info->MS_Status.Ready) { ++ if (!(info->MS_Status & MS_Ready)) { + result = ene_ms_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; +@@ -2306,14 +2305,14 @@ static int ene_transport(struct scsi_cmn + + /*US_DEBUG(usb_stor_show_command(us, srb)); */ + scsi_set_resid(srb, 0); +- if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) ++ if (unlikely(!(info->SD_Status & SD_Ready) || (info->MS_Status & MS_Ready))) + result = ene_init(us); + if (result == USB_STOR_XFER_GOOD) { + result = USB_STOR_TRANSPORT_ERROR; +- if (info->SD_Status.Ready) ++ if (info->SD_Status & SD_Ready) + result = sd_scsi_irp(us, srb); + +- if (info->MS_Status.Ready) ++ if (info->MS_Status & MS_Ready) + result = ms_scsi_irp(us, srb); + } + return result; +@@ -2377,7 +2376,6 @@ static int ene_ub6250_probe(struct usb_i + + static int ene_ub6250_resume(struct usb_interface *iface) + { +- u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + +@@ -2389,17 +2387,16 @@ static int ene_ub6250_resume(struct usb_ + mutex_unlock(&us->dev_mutex); + + info->Power_IsResum = true; +- /*info->SD_Status.Ready = 0; */ +- info->SD_Status = *(struct SD_STATUS *)&tmp; +- info->MS_Status = *(struct MS_STATUS *)&tmp; +- info->SM_Status = *(struct SM_STATUS *)&tmp; ++ /* info->SD_Status &= ~SD_Ready; */ ++ info->SD_Status = 0; ++ info->MS_Status = 0; ++ info->SM_Status = 0; + + return 0; + } + + static int ene_ub6250_reset_resume(struct usb_interface *iface) + { +- u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + +@@ -2411,10 +2408,10 @@ static int ene_ub6250_reset_resume(struc + * the device + */ + info->Power_IsResum = true; +- /*info->SD_Status.Ready = 0; */ +- info->SD_Status = *(struct SD_STATUS *)&tmp; +- info->MS_Status = *(struct MS_STATUS *)&tmp; +- info->SM_Status = *(struct SM_STATUS *)&tmp; ++ /* info->SD_Status &= ~SD_Ready; */ ++ info->SD_Status = 0; ++ info->MS_Status = 0; ++ info->SM_Status = 0; + + return 0; + } diff --git a/queue-5.4/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch b/queue-5.4/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch new file mode 100644 index 00000000000..09bc35156a9 --- /dev/null +++ b/queue-5.4/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch @@ -0,0 +1,41 @@ +From 70c05e4cf63054cd755ca66c1819327b22cb085f Mon Sep 17 00:00:00 2001 +From: Henry Lin +Date: Thu, 3 Mar 2022 13:08:58 +0200 +Subject: xhci: fix runtime PM imbalance in USB2 resume + +From: Henry Lin + +commit 70c05e4cf63054cd755ca66c1819327b22cb085f upstream. + +A race between system resume and device-initiated resume may result in +runtime PM imbalance on USB2 root hub. If a device-initiated resume +starts and system resume xhci_bus_resume() directs U0 before hub driver +sees the resuming device in RESUME state, device-initiated resume will +not be finished in xhci_handle_usb2_port_link_resume(). In this case, +usb_hcd_end_port_resume() call is missing. + +This changes calls usb_hcd_end_port_resume() if resuming device reaches +U0 to keep runtime PM balance. + +Fixes: a231ec41e6f6 ("xhci: refactor U0 link state handling in get_port_status") +Cc: stable@vger.kernel.org +Signed-off-by: Henry Lin +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-5-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-hub.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1000,6 +1000,9 @@ static void xhci_get_usb2_port_status(st + if (link_state == XDEV_U2) + *status |= USB_PORT_STAT_L1; + if (link_state == XDEV_U0) { ++ if (bus_state->resume_done[portnum]) ++ usb_hcd_end_port_resume(&port->rhub->hcd->self, ++ portnum); + bus_state->resume_done[portnum] = 0; + clear_bit(portnum, &bus_state->resuming_ports); + if (bus_state->suspended_ports & (1 << portnum)) { diff --git a/queue-5.4/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch b/queue-5.4/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch new file mode 100644 index 00000000000..85e2268dcd5 --- /dev/null +++ b/queue-5.4/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch @@ -0,0 +1,43 @@ +From 05519b8589a679edb8fa781259893d20bece04ad Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 3 Mar 2022 13:08:57 +0200 +Subject: xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx() + +From: Anssi Hannula + +commit 05519b8589a679edb8fa781259893d20bece04ad upstream. + +xhci_decode_ctrl_ctx() returns the untouched buffer as-is if both "drop" +and "add" parameters are zero. + +Fix the function to return an empty string in that case. + +It was not immediately clear from the possible call chains whether this +issue is currently actually triggerable or not. + +Note that before commit 4843b4b5ec64 ("xhci: fix even more unsafe memory +usage in xhci tracing") the result effect in the failure case was different +as a static buffer was used here, but the code still worked incorrectly. + +Fixes: 90d6d5731da7 ("xhci: Add tracing for input control context") +Cc: stable@vger.kernel.org +Signed-off-by: Anssi Hannula +Signed-off-by: Mathias Nyman +commit 4843b4b5ec64 ("xhci: fix even more unsafe memory usage in xhci tracing") +Link: https://lore.kernel.org/r/20220303110903.1662404-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -2452,6 +2452,8 @@ static inline const char *xhci_decode_ct + unsigned int bit; + int ret = 0; + ++ str[0] = '\0'; ++ + if (drop) { + ret = sprintf(str, "Drop:"); + for_each_set_bit(bit, &drop, 32) diff --git a/queue-5.4/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch b/queue-5.4/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch new file mode 100644 index 00000000000..36c63ef3fdf --- /dev/null +++ b/queue-5.4/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch @@ -0,0 +1,176 @@ +From 14073ce951b5919da450022c050772902f24f054 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 3 Mar 2022 13:08:55 +0200 +Subject: xhci: make xhci_handshake timeout for xhci_reset() adjustable + +From: Mathias Nyman + +commit 14073ce951b5919da450022c050772902f24f054 upstream. + +xhci_reset() timeout was increased from 250ms to 10 seconds in order to +give Renesas 720201 xHC enough time to get ready in probe. + +xhci_reset() is called with interrupts disabled in other places, and +waiting for 10 seconds there is not acceptable. + +Add a timeout parameter to xhci_reset(), and adjust it back to 250ms +when called from xhci_stop() or xhci_shutdown() where interrupts are +disabled, and successful reset isn't that critical. +This solves issues when deactivating host mode on platforms like SM8450. + +For now don't change the timeout if xHC is reset in xhci_resume(). +No issues are reported for it, and we need the reset to succeed. +Locking around that reset needs to be revisited later. + +Additionally change the signed integer timeout parameter in +xhci_handshake() to a u64 to match the timeout value we pass to +readl_poll_timeout_atomic() + +Fixes: 22ceac191211 ("xhci: Increase reset timeout for Renesas 720201 host.") +Cc: stable@vger.kernel.org +Reported-by: Sergey Shtylyov +Reported-by: Pavan Kondeti +Tested-by: Pavan Kondeti +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-hub.c | 2 +- + drivers/usb/host/xhci-mem.c | 2 +- + drivers/usb/host/xhci.c | 20 +++++++++----------- + drivers/usb/host/xhci.h | 7 +++++-- + 4 files changed, 16 insertions(+), 15 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -674,7 +674,7 @@ static int xhci_exit_test_mode(struct xh + } + pm_runtime_allow(xhci_to_hcd(xhci)->self.controller); + xhci->test_mode = 0; +- return xhci_reset(xhci); ++ return xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + } + + void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port, +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2583,7 +2583,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, + + fail: + xhci_halt(xhci); +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + xhci_mem_cleanup(xhci); + return -ENOMEM; + } +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -66,7 +66,7 @@ static bool td_on_ring(struct xhci_td *t + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +-int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us) + { + u32 result; + int ret; +@@ -74,7 +74,7 @@ int xhci_handshake(void __iomem *ptr, u3 + ret = readl_poll_timeout_atomic(ptr, result, + (result & mask) == done || + result == U32_MAX, +- 1, usec); ++ 1, timeout_us); + if (result == U32_MAX) /* card removed */ + return -ENODEV; + +@@ -163,7 +163,7 @@ int xhci_start(struct xhci_hcd *xhci) + * Transactions will be terminated immediately, and operational registers + * will be set to their defaults. + */ +-int xhci_reset(struct xhci_hcd *xhci) ++int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us) + { + u32 command; + u32 state; +@@ -196,8 +196,7 @@ int xhci_reset(struct xhci_hcd *xhci) + if (xhci->quirks & XHCI_INTEL_HOST) + udelay(1000); + +- ret = xhci_handshake(&xhci->op_regs->command, +- CMD_RESET, 0, 10 * 1000 * 1000); ++ ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us); + if (ret) + return ret; + +@@ -210,8 +209,7 @@ int xhci_reset(struct xhci_hcd *xhci) + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ +- ret = xhci_handshake(&xhci->op_regs->status, +- STS_CNR, 0, 10 * 1000 * 1000); ++ ret = xhci_handshake(&xhci->op_regs->status, STS_CNR, 0, timeout_us); + + xhci->usb2_rhub.bus_state.port_c_suspend = 0; + xhci->usb2_rhub.bus_state.suspended_ports = 0; +@@ -732,7 +730,7 @@ static void xhci_stop(struct usb_hcd *hc + xhci->xhc_state |= XHCI_STATE_HALTED; + xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; + xhci_halt(xhci); +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + spin_unlock_irq(&xhci->lock); + + xhci_cleanup_msix(xhci); +@@ -785,7 +783,7 @@ void xhci_shutdown(struct usb_hcd *hcd) + xhci_halt(xhci); + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + spin_unlock_irq(&xhci->lock); + + xhci_cleanup_msix(xhci); +@@ -1170,7 +1168,7 @@ int xhci_resume(struct xhci_hcd *xhci, b + xhci_dbg(xhci, "Stop HCD\n"); + xhci_halt(xhci); + xhci_zero_64b_regs(xhci); +- retval = xhci_reset(xhci); ++ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); + spin_unlock_irq(&xhci->lock); + if (retval) + return retval; +@@ -5272,7 +5270,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, + + xhci_dbg(xhci, "Resetting HCD\n"); + /* Reset the internal HC memory state and registers. */ +- retval = xhci_reset(xhci); ++ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); + if (retval) + return retval; + xhci_dbg(xhci, "Reset complete\n"); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -229,6 +229,9 @@ struct xhci_op_regs { + #define CMD_ETE (1 << 14) + /* bits 15:31 are reserved (and should be preserved on writes). */ + ++#define XHCI_RESET_LONG_USEC (10 * 1000 * 1000) ++#define XHCI_RESET_SHORT_USEC (250 * 1000) ++ + /* IMAN - Interrupt Management Register */ + #define IMAN_IE (1 << 1) + #define IMAN_IP (1 << 0) +@@ -2061,11 +2064,11 @@ void xhci_free_container_ctx(struct xhci + + /* xHCI host controller glue */ + typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); +-int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us); + void xhci_quiesce(struct xhci_hcd *xhci); + int xhci_halt(struct xhci_hcd *xhci); + int xhci_start(struct xhci_hcd *xhci); +-int xhci_reset(struct xhci_hcd *xhci); ++int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us); + int xhci_run(struct usb_hcd *hcd); + int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); + void xhci_shutdown(struct usb_hcd *hcd);