From patchwork Thu Feb 2 15:04:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650611 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94A0CC61DA4 for ; Thu, 2 Feb 2023 15:05:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231829AbjBBPFh (ORCPT ); Thu, 2 Feb 2023 10:05:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231598AbjBBPFg (ORCPT ); Thu, 2 Feb 2023 10:05:36 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4747929E3D for ; Thu, 2 Feb 2023 07:05:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350302; x=1706886302; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RQkoSU0SaCTBTfBj0nN4UWy1JmEroj8xiZzeWLkZURo=; b=DDFhs5VCPmjSlpW3se0aJ1Cx80pc/qmI7pDwMSWarksVbVFGnutkbwck C0cQsvTW4laJhROCP0YTAzLttN04YZURu4EsHifcHNNXWfhVFDDLh01n7 jbsdYCf15Ogx9K+LC+Yq5YuFDSIUiXViV21B3rxTBYhJcaexREnG0DNMP XA9T4B40NdQn+dSIiBEhzLsZ8Pi71pXi6bn+ivJLmILC1hOVakcf/0bxB ZVCqQoViwgrv7kPDzG9B+uBcMtQnkG7JxNvHD+tTUa7IoG32Khtrjm7am 9S35L3laxOidhwvxCPpVoIh8PRY8rzyhWCiBO3auF5l5TMZczIN2PfvL1 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327113942" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327113942" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:03:50 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905638" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905638" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:03:49 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 01/11] xhci: fix event ring segment table related masks and variables in header Date: Thu, 2 Feb 2023 17:04:55 +0200 Message-Id: <20230202150505.618915-2-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org xHC controller can supports up to 1024 interrupters. To fit these change the max_interrupters varable from u8 to u16. Add a separate mask for the reserve and preserve bits [5:0] in the erst base register and use it instead of the ERST_PRT_MASK. ERSR_PTR_MASK [3:0] is intended for masking bits in the event ring dequeue pointer register. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 81ca2bc1f0be..679befa97c7a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2529,8 +2529,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) "// Set ERST base address for ir_set 0 = 0x%llx", (unsigned long long)xhci->erst.erst_dma_addr); val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base); - val_64 &= ERST_PTR_MASK; - val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); + val_64 &= ERST_BASE_RSVDP; + val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_BASE_RSVDP); xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base); /* Set the event ring dequeue address */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7547037b57bf..0dd92f9089fe 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -513,6 +513,9 @@ struct xhci_intr_reg { /* Preserve bits 16:31 of erst_size */ #define ERST_SIZE_MASK (0xffff << 16) +/* erst_base bitmasks */ +#define ERST_BASE_RSVDP (0x3f) + /* erst_dequeue bitmasks */ /* Dequeue ERST Segment Index (DESI) - Segment number (or alias) * where the current dequeue pointer lies. This is an optional HW hint. @@ -1774,7 +1777,7 @@ struct xhci_hcd { u8 sbrn; u16 hci_version; u8 max_slots; - u8 max_interrupters; + u16 max_interrupters; u8 max_ports; u8 isoc_threshold; /* imod_interval in ns (I * 250ns) */ From patchwork Thu Feb 2 15:04:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650610 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 790C7C61DA4 for ; Thu, 2 Feb 2023 15:06:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232408AbjBBPGH (ORCPT ); Thu, 2 Feb 2023 10:06:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231860AbjBBPF6 (ORCPT ); Thu, 2 Feb 2023 10:05:58 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 444449218E for ; Thu, 2 Feb 2023 07:05:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350339; x=1706886339; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yU4VNxdbrt4ELJlgWza+xlTgWqZ+P0dgSErXeZeWRzw=; b=dsMFyVSGocmSEJ+kkEmbX9rgmv5Me7YTs6lsE9UTFRltKr/vcmc6NiXS OedLYAQmRCfMOtSRwGYv7P5M6V0CjEXBHknL52asjRBr4x6/j0QU8yOf/ FS6KG76iKgoviDvVk5MaPesDjhZTWUgoTPGOIZQC3aYvZpBYYQWgBsC3W fT92Xbo1cXbZFLm6jZkCHFVRbJRlbB2GU/lB7WYWo+LClw7Skia/x+KTZ NI3cAGmemKCuAQfUJXo2vZMFmaGIyzsKib+AoPX6j+oRXy4fYl9Zy3qQ6 XxwZPliuN2EdY7eCXImxr8m+34k/oL+tm0W9HTkdKoTxarNiPcmCwWN3V w==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327113991" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327113991" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:03:55 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905717" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905717" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:03:54 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 04/11] xhci: add helpers for enabling and disabling interrupters Date: Thu, 2 Feb 2023 17:04:58 +0200 Message-Id: <20230202150505.618915-5-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Simple helpers to set and clear the IE (interrupter enable) bit for an interrupter. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8dc3f2c00577..6183ce8574b1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -292,6 +292,32 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) xhci_info(xhci, "Fault detected\n"); } +static int xhci_enable_interrupter(struct xhci_interrupter *ir) +{ + u32 iman; + + if (!ir || !ir->ir_set) + return -EINVAL; + + iman = readl(&ir->ir_set->irq_pending); + writel(ER_IRQ_ENABLE(iman), &ir->ir_set->irq_pending); + + return 0; +} + +static int xhci_disable_interrupter(struct xhci_interrupter *ir) +{ + u32 iman; + + if (!ir || !ir->ir_set) + return -EINVAL; + + iman = readl(&ir->ir_set->irq_pending); + writel(ER_IRQ_DISABLE(iman), &ir->ir_set->irq_pending); + + return 0; +} + #ifdef CONFIG_USB_PCI /* * Set up MSI @@ -610,7 +636,6 @@ static int xhci_init(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ - static int xhci_run_finished(struct xhci_hcd *xhci) { struct xhci_interrupter *ir = xhci->interrupter; @@ -629,8 +654,7 @@ static int xhci_run_finished(struct xhci_hcd *xhci) writel(temp, &xhci->op_regs->command); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Enable primary interrupter"); - temp = readl(&ir->ir_set->irq_pending); - writel(ER_IRQ_ENABLE(temp), &ir->ir_set->irq_pending); + xhci_enable_interrupter(ir); if (xhci_start(xhci)) { xhci_halt(xhci); @@ -734,6 +758,7 @@ static void xhci_stop(struct usb_hcd *hcd) { u32 temp; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_interrupter *ir = xhci->interrupter; mutex_lock(&xhci->mutex); @@ -770,8 +795,7 @@ static void xhci_stop(struct usb_hcd *hcd) "// Disabling event ring interrupts"); temp = readl(&xhci->op_regs->status); writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status); - temp = readl(&xhci->interrupter->ir_set->irq_pending); - writel(ER_IRQ_DISABLE(temp), &xhci->interrupter->ir_set->irq_pending); + xhci_disable_interrupter(ir); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory"); xhci_mem_cleanup(xhci); @@ -1227,8 +1251,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "// Disabling event ring interrupts\n"); temp = readl(&xhci->op_regs->status); writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status); - temp = readl(&xhci->interrupter->ir_set->irq_pending); - writel(ER_IRQ_DISABLE(temp), &xhci->interrupter->ir_set->irq_pending); + xhci_disable_interrupter(xhci->interrupter); xhci_dbg(xhci, "cleaning up memory\n"); xhci_mem_cleanup(xhci); From patchwork Thu Feb 2 15:05:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD990C636D6 for ; Thu, 2 Feb 2023 15:06:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232371AbjBBPGQ (ORCPT ); Thu, 2 Feb 2023 10:06:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232432AbjBBPGH (ORCPT ); Thu, 2 Feb 2023 10:06:07 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E3E392195 for ; Thu, 2 Feb 2023 07:05:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350352; x=1706886352; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0gF5Z8g4fpUa6HSzCTodGpu1AGK1rxYmSufRSB1tj9g=; b=Unc9DDg17X9U7SF9d4xhYpTGkNaQXn0wfrPZie3v8VqhQwcFhn/jeU74 GS2ZbKg71EAnRG1Rlu/sQCxlXuy+boOLWngSzdsJh+wi+SNadMaNypT91 1qO/lxQED6SIZonO1I0+bxPFGyoxcHHIk/bTkpfUAUxhAhw0ikaaqfEWY 3FSs3tO6VOtlPcG4qxhNW7qZYSDLfiFAs/b29L0tYex8N/CMq5isUXQ7B ygaQxUON8Kd6+RvQHKDWyd0aEnFG14Y/TsdfIWDh6CrHVobm+4zwIIo2w eBJpxUYI3RD/jULHAEkaGU3pTKn7Wriyh6JQfGrhsXiYBQF9ZNr5ySrQ+ w==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327114015" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327114015" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:03:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905748" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905748" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:03:57 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 06/11] xhci: pass port pointer as parameter to xhci_set_port_power() Date: Thu, 2 Feb 2023 17:05:00 +0200 Message-Id: <20230202150505.618915-7-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Pass the port structure pointer directly to xhci_set_port_power() instead of hcd and port index. cleanup Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 181c070d6a99..238d05206d2c 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -666,20 +666,18 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd) * It will release and re-aquire the lock while calling ACPI * method. */ -static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, - u16 index, bool on, unsigned long *flags) +static void xhci_set_port_power(struct xhci_hcd *xhci, struct xhci_port *port, + bool on, unsigned long *flags) __must_hold(&xhci->lock) { - struct xhci_hub *rhub; - struct xhci_port *port; + struct usb_hcd *hcd; u32 temp; - rhub = xhci_get_rhub(hcd); - port = rhub->ports[index]; + hcd = port->rhub->hcd; temp = readl(port->addr); xhci_dbg(xhci, "set port power %d-%d %s, portsc: 0x%x\n", - hcd->self.busnum, index + 1, on ? "ON" : "OFF", temp); + hcd->self.busnum, port->hcd_portnum + 1, on ? "ON" : "OFF", temp); temp = xhci_port_state_to_neutral(temp); @@ -694,10 +692,10 @@ static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, spin_unlock_irqrestore(&xhci->lock, *flags); temp = usb_acpi_power_manageable(hcd->self.root_hub, - index); + port->hcd_portnum); if (temp) usb_acpi_set_power_state(hcd->self.root_hub, - index, on); + port->hcd_portnum, on); spin_lock_irqsave(&xhci->lock, *flags); } @@ -721,7 +719,6 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, u16 test_mode, u16 wIndex, unsigned long *flags) __must_hold(&xhci->lock) { - struct usb_hcd *usb3_hcd = xhci_get_usb3_hcd(xhci); int i, retval; /* Disable all Device Slots */ @@ -742,10 +739,10 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci, xhci_dbg(xhci, "Disable all port (PP = 0)\n"); /* Power off USB3 ports*/ for (i = 0; i < xhci->usb3_rhub.num_ports; i++) - xhci_set_port_power(xhci, usb3_hcd, i, false, flags); + xhci_set_port_power(xhci, xhci->usb3_rhub.ports[i], false, flags); /* Power off USB2 ports*/ for (i = 0; i < xhci->usb2_rhub.num_ports; i++) - xhci_set_port_power(xhci, xhci->main_hcd, i, false, flags); + xhci_set_port_power(xhci, xhci->usb2_rhub.ports[i], false, flags); /* Stop the controller */ xhci_dbg(xhci, "Stop controller\n"); retval = xhci_halt(xhci); @@ -1492,7 +1489,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, * However, hub_wq will ignore the roothub events until * the roothub is registered. */ - xhci_set_port_power(xhci, hcd, wIndex, true, &flags); + xhci_set_port_power(xhci, port, true, &flags); break; case USB_PORT_FEAT_RESET: temp = (temp | PORT_RESET); @@ -1609,7 +1606,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, port->addr, temp); break; case USB_PORT_FEAT_POWER: - xhci_set_port_power(xhci, hcd, wIndex, false, &flags); + xhci_set_port_power(xhci, port, false, &flags); break; case USB_PORT_FEAT_TEST: retval = xhci_exit_test_mode(xhci); From patchwork Thu Feb 2 15:05:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650608 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49C66C05027 for ; Thu, 2 Feb 2023 15:06:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232475AbjBBPGS (ORCPT ); Thu, 2 Feb 2023 10:06:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231904AbjBBPGI (ORCPT ); Thu, 2 Feb 2023 10:06:08 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF378921AB for ; Thu, 2 Feb 2023 07:05:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350353; x=1706886353; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MW73nPiu9by+PT8pD5gb2q2KRhsNkhWG/b6wbmbf9EA=; b=I0q9eZJIvNLUxbZ/cM2h6N3eaLemz4szcbswSqeqm/WofXh8C3h/K9NJ ySlcu6wb0KJbMm1uSoh7r0HYDuTB5a5KvwDU4nM9Gr2StEhn5bQ343kzl cGMna6AcQtmiJS68UGTs9eF9NtKJqvLiNC1Dq0pygaZ6kwwncZf4PpjLv ku+YPSEfCT2zrYH9dM3z/3jcfuNbTjUmpLPTfQmaHSlHIccg8xH+OXk3W KwaUL7O75RbEQDP9UbaH3aMtAbji85UxNZbbdyFptTX7aqMwm23yZVPuM hSREyVBkvp0UxKgyXBVY/houB7/Ww4YlmXG/a2KDUQszoyKnPHCjv7Oe/ Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327114029" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327114029" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:04:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905764" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905764" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:03:58 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 07/11] xhci: move port specific items such as state completions to port structure Date: Thu, 2 Feb 2023 17:05:01 +0200 Message-Id: <20230202150505.618915-8-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Now that we have a port structure for each port it makes sense to move per port variables, timestamps and completions there. Get rid of storing bitfileds and arrays of port specific items per bus. Move unsigned long resume_done; insigned long rexit_ports struct completion rexit_done; struct completion u3exit_done; Rename rexit_ports to rexit_active, and remove a redundant hcd speed check while checking if rexit_active is set. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 31 +++++++++++++++---------------- drivers/usb/host/xhci-mem.c | 10 +++------- drivers/usb/host/xhci-ring.c | 13 ++++++------- drivers/usb/host/xhci.h | 9 ++++----- 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 238d05206d2c..75c9609f32f0 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -936,7 +936,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, return -EINVAL; } /* did port event handler already start resume timing? */ - if (!bus_state->resume_done[wIndex]) { + if (!port->resume_done) { /* If not, maybe we are in a host initated resume? */ if (test_bit(wIndex, &bus_state->resuming_ports)) { /* Host initated resume doesn't time the resume @@ -953,28 +953,27 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(wIndex, &bus_state->resuming_ports); - bus_state->resume_done[wIndex] = timeout; + port->resume_done = timeout; mod_timer(&hcd->rh_timer, timeout); usb_hcd_start_port_resume(&hcd->self, wIndex); } /* Has resume been signalled for USB_RESUME_TIME yet? */ - } else if (time_after_eq(jiffies, bus_state->resume_done[wIndex])) { + } else if (time_after_eq(jiffies, port->resume_done)) { int time_left; xhci_dbg(xhci, "resume USB2 port %d-%d\n", hcd->self.busnum, wIndex + 1); - bus_state->resume_done[wIndex] = 0; + port->resume_done = 0; clear_bit(wIndex, &bus_state->resuming_ports); - - set_bit(wIndex, &bus_state->rexit_ports); + port->rexit_active = true; xhci_test_and_clear_bit(xhci, port, PORT_PLC); xhci_set_link_state(xhci, port, XDEV_U0); spin_unlock_irqrestore(&xhci->lock, *flags); time_left = wait_for_completion_timeout( - &bus_state->rexit_done[wIndex], + &port->rexit_done, msecs_to_jiffies(XHCI_MAX_REXIT_TIMEOUT_MS)); spin_lock_irqsave(&xhci->lock, *flags); @@ -993,7 +992,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, xhci_warn(xhci, "Port resume timed out, port %d-%d: 0x%x\n", hcd->self.busnum, wIndex + 1, port_status); *status |= USB_PORT_STAT_SUSPEND; - clear_bit(wIndex, &bus_state->rexit_ports); + port->rexit_active = false; } usb_hcd_end_port_resume(&hcd->self, wIndex); @@ -1100,10 +1099,10 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, if (link_state == XDEV_U2) *status |= USB_PORT_STAT_L1; if (link_state == XDEV_U0) { - if (bus_state->resume_done[portnum]) + if (port->resume_done) usb_hcd_end_port_resume(&port->rhub->hcd->self, portnum); - bus_state->resume_done[portnum] = 0; + port->resume_done = 0; clear_bit(portnum, &bus_state->resuming_ports); if (bus_state->suspended_ports & (1 << portnum)) { bus_state->suspended_ports &= ~(1 << portnum); @@ -1175,11 +1174,11 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, * Clear stale usb2 resume signalling variables in case port changed * state during resume signalling. For example on error */ - if ((bus_state->resume_done[wIndex] || + if ((port->resume_done || test_bit(wIndex, &bus_state->resuming_ports)) && (raw_port_status & PORT_PLS_MASK) != XDEV_U3 && (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) { - bus_state->resume_done[wIndex] = 0; + port->resume_done = 0; clear_bit(wIndex, &bus_state->resuming_ports); usb_hcd_end_port_resume(&hcd->self, wIndex); } @@ -1438,7 +1437,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, pls == XDEV_RESUME || pls == XDEV_RECOVERY) { wait_u0 = true; - reinit_completion(&bus_state->u3exit_done[wIndex]); + reinit_completion(&port->u3exit_done); } if (pls <= XDEV_U3) /* U1, U2, U3 */ xhci_set_link_state(xhci, port, USB_SS_PORT_LS_U0); @@ -1448,7 +1447,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; } spin_unlock_irqrestore(&xhci->lock, flags); - if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex], + if (!wait_for_completion_timeout(&port->u3exit_done, msecs_to_jiffies(500))) xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n", hcd->self.busnum, portnum1); @@ -1688,8 +1687,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) if ((temp & mask) != 0 || (bus_state->port_c_suspend & 1 << i) || - (bus_state->resume_done[i] && time_after_eq( - jiffies, bus_state->resume_done[i]))) { + (ports[i]->resume_done && time_after_eq( + jiffies, ports[i]->resume_done))) { buf[(i + 1) / 8] |= 1 << (i + 1) % 8; status = 1; } diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 6b83c5c35cf8..d0a9467aa5fc 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2154,6 +2154,9 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) xhci->hw_ports[i].addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * i; xhci->hw_ports[i].hw_portnum = i; + + init_completion(&xhci->hw_ports[i].rexit_done); + init_completion(&xhci->hw_ports[i].u3exit_done); } xhci->rh_bw = kcalloc_node(num_ports, sizeof(*xhci->rh_bw), flags, @@ -2439,13 +2442,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) */ for (i = 0; i < MAX_HC_SLOTS; i++) xhci->devs[i] = NULL; - for (i = 0; i < USB_MAXCHILDREN; i++) { - xhci->usb2_rhub.bus_state.resume_done[i] = 0; - xhci->usb3_rhub.bus_state.resume_done[i] = 0; - /* Only the USB 2.0 completions will ever be used. */ - init_completion(&xhci->usb2_rhub.bus_state.rexit_done[i]); - init_completion(&xhci->usb3_rhub.bus_state.u3exit_done[i]); - } if (scratchpad_alloc(xhci, flags)) goto fail; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 451d48b87cf7..611580d4adad 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1924,7 +1924,7 @@ static void handle_port_status(struct xhci_hcd *xhci, goto cleanup; } else if (!test_bit(hcd_portnum, &bus_state->resuming_ports)) { xhci_dbg(xhci, "resume HS port %d\n", port_id); - bus_state->resume_done[hcd_portnum] = jiffies + + port->resume_done = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(hcd_portnum, &bus_state->resuming_ports); /* Do the rest in GetPortStatus after resume time delay. @@ -1933,7 +1933,7 @@ static void handle_port_status(struct xhci_hcd *xhci, */ set_bit(HCD_FLAG_POLL_RH, &hcd->flags); mod_timer(&hcd->rh_timer, - bus_state->resume_done[hcd_portnum]); + port->resume_done); usb_hcd_start_port_resume(&hcd->self, hcd_portnum); bogus_port_status = true; } @@ -1945,7 +1945,7 @@ static void handle_port_status(struct xhci_hcd *xhci, (portsc & PORT_PLS_MASK) == XDEV_U1 || (portsc & PORT_PLS_MASK) == XDEV_U2)) { xhci_dbg(xhci, "resume SS port %d finished\n", port_id); - complete(&bus_state->u3exit_done[hcd_portnum]); + complete(&port->u3exit_done); /* We've just brought the device into U0/1/2 through either the * Resume state after a device remote wakeup, or through the * U3Exit state after a host-initiated resume. If it's a device @@ -1970,10 +1970,9 @@ static void handle_port_status(struct xhci_hcd *xhci, * RExit to a disconnect state). If so, let the driver know it's * out of the RExit state. */ - if (!DEV_SUPERSPEED_ANY(portsc) && hcd->speed < HCD_USB3 && - test_and_clear_bit(hcd_portnum, - &bus_state->rexit_ports)) { - complete(&bus_state->rexit_done[hcd_portnum]); + if (hcd->speed < HCD_USB3 && port->rexit_active) { + complete(&port->rexit_done); + port->rexit_active = false; bogus_port_status = true; goto cleanup; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 95eb235d1f70..578e219292fd 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1704,13 +1704,8 @@ struct xhci_bus_state { u32 port_c_suspend; u32 suspended_ports; u32 port_remote_wakeup; - unsigned long resume_done[USB_MAXCHILDREN]; /* which ports have started to resume */ unsigned long resuming_ports; - /* Which ports are waiting on RExit to U0 transition. */ - unsigned long rexit_ports; - struct completion rexit_done[USB_MAXCHILDREN]; - struct completion u3exit_done[USB_MAXCHILDREN]; }; struct xhci_interrupter { @@ -1745,6 +1740,10 @@ struct xhci_port { struct xhci_hub *rhub; struct xhci_port_cap *port_cap; unsigned int lpm_incapable:1; + unsigned long resume_done; + bool rexit_active; + struct completion rexit_done; + struct completion u3exit_done; }; struct xhci_hub { From patchwork Thu Feb 2 15:05:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E15ABC61DA4 for ; Thu, 2 Feb 2023 15:06:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232206AbjBBPGY (ORCPT ); Thu, 2 Feb 2023 10:06:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232256AbjBBPGL (ORCPT ); Thu, 2 Feb 2023 10:06:11 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BB4E561A3 for ; Thu, 2 Feb 2023 07:06:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350369; x=1706886369; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sUKJw7373aG8Mbue1dQeyPCbXQ/N6Kum1f0+YetfkVE=; b=Me7KayCZRHwjVvDrF8Jq/QjU39LuqQncGrIKTD6DS0b5wLmbpmPXC4dG IgW0Maunmaw5Vn7zBdzDKW7omfdRRX/64B4MmSbaPou41BSWH5OzFf0ry WfZU0OK4JXbK6zrDFJ+XVlb26WqyATaH+YdvQVXbLCoB26HJ+k8l/Jf5I FwqTzILYx+2Y/gFqFQT3AN+YeYIvVVFguSA2OxHVoplt7OC8pM+ETSSCM fas5X5RJGeL0GkoqU6m8IexnNmtXwflK3+YzLSbM02A2Z0OrT4pTq38Lg OB+17inG9VyC1XKj5Q5DjMPyd6sEaNkKejEkkCzyA9ZKzV/EzV/cy9BE7 g==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327114060" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327114060" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:04:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905839" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905839" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:04:01 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 09/11] xhci: rename resume_done to resume_timestamp Date: Thu, 2 Feb 2023 17:05:03 +0200 Message-Id: <20230202150505.618915-10-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org resume_done is just a timestamp, avoid confusing it with completions related to port state transitions that are named *_done Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 20 ++++++++++---------- drivers/usb/host/xhci-ring.c | 4 ++-- drivers/usb/host/xhci.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index b27969e3cdcf..a2053aa9b4a9 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -943,7 +943,7 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, return -EINVAL; } /* did port event handler already start resume timing? */ - if (!port->resume_done) { + if (!port->resume_timestamp) { /* If not, maybe we are in a host initated resume? */ if (test_bit(wIndex, &bus_state->resuming_ports)) { /* Host initated resume doesn't time the resume @@ -960,18 +960,18 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(wIndex, &bus_state->resuming_ports); - port->resume_done = timeout; + port->resume_timestamp = timeout; mod_timer(&hcd->rh_timer, timeout); usb_hcd_start_port_resume(&hcd->self, wIndex); } /* Has resume been signalled for USB_RESUME_TIME yet? */ - } else if (time_after_eq(jiffies, port->resume_done)) { + } else if (time_after_eq(jiffies, port->resume_timestamp)) { int time_left; xhci_dbg(xhci, "resume USB2 port %d-%d\n", hcd->self.busnum, wIndex + 1); - port->resume_done = 0; + port->resume_timestamp = 0; clear_bit(wIndex, &bus_state->resuming_ports); port->rexit_active = true; @@ -1106,10 +1106,10 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, if (link_state == XDEV_U2) *status |= USB_PORT_STAT_L1; if (link_state == XDEV_U0) { - if (port->resume_done) + if (port->resume_timestamp) usb_hcd_end_port_resume(&port->rhub->hcd->self, portnum); - port->resume_done = 0; + port->resume_timestamp = 0; clear_bit(portnum, &bus_state->resuming_ports); if (bus_state->suspended_ports & (1 << portnum)) { bus_state->suspended_ports &= ~(1 << portnum); @@ -1181,11 +1181,11 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, * Clear stale usb2 resume signalling variables in case port changed * state during resume signalling. For example on error */ - if ((port->resume_done || + if ((port->resume_timestamp || test_bit(wIndex, &bus_state->resuming_ports)) && (raw_port_status & PORT_PLS_MASK) != XDEV_U3 && (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) { - port->resume_done = 0; + port->resume_timestamp = 0; clear_bit(wIndex, &bus_state->resuming_ports); usb_hcd_end_port_resume(&hcd->self, wIndex); } @@ -1693,8 +1693,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) if ((temp & mask) != 0 || (bus_state->port_c_suspend & 1 << i) || - (ports[i]->resume_done && time_after_eq( - jiffies, ports[i]->resume_done))) { + (ports[i]->resume_timestamp && time_after_eq( + jiffies, ports[i]->resume_timestamp))) { buf[(i + 1) / 8] |= 1 << (i + 1) % 8; status = 1; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 611580d4adad..eb788c60c1c0 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1924,7 +1924,7 @@ static void handle_port_status(struct xhci_hcd *xhci, goto cleanup; } else if (!test_bit(hcd_portnum, &bus_state->resuming_ports)) { xhci_dbg(xhci, "resume HS port %d\n", port_id); - port->resume_done = jiffies + + port->resume_timestamp = jiffies + msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(hcd_portnum, &bus_state->resuming_ports); /* Do the rest in GetPortStatus after resume time delay. @@ -1933,7 +1933,7 @@ static void handle_port_status(struct xhci_hcd *xhci, */ set_bit(HCD_FLAG_POLL_RH, &hcd->flags); mod_timer(&hcd->rh_timer, - port->resume_done); + port->resume_timestamp); usb_hcd_start_port_resume(&hcd->self, hcd_portnum); bogus_port_status = true; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 578e219292fd..786002bb35db 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1740,7 +1740,7 @@ struct xhci_port { struct xhci_hub *rhub; struct xhci_port_cap *port_cap; unsigned int lpm_incapable:1; - unsigned long resume_done; + unsigned long resume_timestamp; bool rexit_active; struct completion rexit_done; struct completion u3exit_done; From patchwork Thu Feb 2 15:05:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 650606 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D2D3C636D6 for ; Thu, 2 Feb 2023 15:06:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232568AbjBBPGZ (ORCPT ); Thu, 2 Feb 2023 10:06:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232535AbjBBPGM (ORCPT ); Thu, 2 Feb 2023 10:06:12 -0500 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6FB8921A6 for ; Thu, 2 Feb 2023 07:06:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675350370; x=1706886370; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tmWob8C9oCAnTzzL7c9APENU1tp0rhM3drazZIf6DTA=; b=mrjrXQPm/tQPh4+hiINBr5a5f5RoErihWF0znncK81zywQcQkBxaqaR0 378vZcKKFCiE7NIrtdVavgf12yw/pWOVDhXXKi/EiqEGXLGilThCDzXVO iHJ/Pmi/Dkt4miCphZi8mVK3ZPoQ+7qY7CZBXWxiqkWRgvGJ6Sv4dBd3+ Lyd0igMeAwkRQGcGIkoQ02ROkLvttZ+AUpBjzjjzhGJNBoclRXknnfdNQ 63hqZB+fY3oAfT1UBS5j2VAADd6QVayC/Ml6fGMapyzMtADOknmU5BXhX TWxeJnwqeZBWSuF86zbGJgLs6Jdt3CQgz2t4FeHQk+hSNNDZ3q7/AIZRQ A==; X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="327114088" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="327114088" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Feb 2023 07:04:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10608"; a="728905923" X-IronPort-AV: E=Sophos;i="5.97,267,1669104000"; d="scan'208";a="728905923" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by fmsmga008.fm.intel.com with ESMTP; 02 Feb 2023 07:04:04 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 11/11] xhci: decouple usb2 port resume and get_port_status request handling Date: Thu, 2 Feb 2023 17:05:05 +0200 Message-Id: <20230202150505.618915-12-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230202150505.618915-1-mathias.nyman@linux.intel.com> References: <20230202150505.618915-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The get port status hub request code in xhci-hub.c will complete usb2 port resume signalling if signalling has been going on for long enough. The code that completes the resume signalling, and the code that returns the port status have gotten too intertwined, so separate them a bit. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 47 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 541ccc45ea51..0054d02239e2 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -924,7 +924,7 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, } static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, - u32 *status, u32 portsc, + u32 portsc, unsigned long *flags) { struct xhci_bus_state *bus_state; @@ -939,7 +939,6 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, wIndex = port->hcd_portnum; if ((portsc & PORT_RESET) || !(portsc & PORT_PE)) { - *status = 0xffffffff; return -EINVAL; } /* did port event handler already start resume timing? */ @@ -973,6 +972,8 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, port->resume_timestamp = 0; clear_bit(wIndex, &bus_state->resuming_ports); + + reinit_completion(&port->rexit_done); port->rexit_active = true; xhci_test_and_clear_bit(xhci, port, PORT_PLC); @@ -989,7 +990,6 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, wIndex + 1); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); - *status = 0xffffffff; return -ENODEV; } xhci_ring_device(xhci, slot_id); @@ -998,22 +998,19 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, xhci_warn(xhci, "Port resume timed out, port %d-%d: 0x%x\n", hcd->self.busnum, wIndex + 1, port_status); - *status |= USB_PORT_STAT_SUSPEND; - port->rexit_active = false; + /* + * keep rexit_active set if U0 transition failed so we + * know to report PORT_STAT_SUSPEND status back to + * usbcore. It will be cleared later once the port is + * out of RESUME/U3 state + */ } usb_hcd_end_port_resume(&hcd->self, wIndex); bus_state->port_c_suspend |= 1 << wIndex; bus_state->suspended_ports &= ~(1 << wIndex); - } else { - /* - * The resume has been signaling for less than - * USB_RESUME_TIME. Report the port status as SUSPEND, - * let the usbcore check port status again and clear - * resume signaling later. - */ - *status |= USB_PORT_STAT_SUSPEND; } + return 0; } @@ -1090,6 +1087,7 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, struct xhci_bus_state *bus_state; u32 link_state; u32 portnum; + int err; bus_state = &port->rhub->bus_state; link_state = portsc & PORT_PLS_MASK; @@ -1111,8 +1109,12 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, } } if (link_state == XDEV_RESUME) { - xhci_handle_usb2_port_link_resume(port, status, portsc, - flags); + err = xhci_handle_usb2_port_link_resume(port, portsc, + flags); + if (err < 0) + *status = 0xffffffff; + else if (port->resume_timestamp || port->rexit_active) + *status |= USB_PORT_STAT_SUSPEND; } } @@ -1121,13 +1123,14 @@ static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, * or resuming. Port either resumed to U0/U1/U2, disconnected, or in a * error state. Resume related variables should be cleared in all those cases. */ - if ((link_state != XDEV_U3 && - link_state != XDEV_RESUME) && - (port->resume_timestamp || - test_bit(portnum, &bus_state->resuming_ports))) { - port->resume_timestamp = 0; - clear_bit(portnum, &bus_state->resuming_ports); - usb_hcd_end_port_resume(&port->rhub->hcd->self, portnum); + if (link_state != XDEV_U3 && link_state != XDEV_RESUME) { + if (port->resume_timestamp || + test_bit(portnum, &bus_state->resuming_ports)) { + port->resume_timestamp = 0; + clear_bit(portnum, &bus_state->resuming_ports); + usb_hcd_end_port_resume(&port->rhub->hcd->self, portnum); + } + port->rexit_active = 0; } }