* [PATCH 00/18] xhci cleanups and rework for usb-next
@ 2024-04-29 14:02 Mathias Nyman
2024-04-29 14:02 ` [PATCH 01/18] xhci: stored cached port capability values in one place Mathias Nyman
` (17 more replies)
0 siblings, 18 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman
Hi Greg
This series for usb-next is mostly xhci cleanups and refactoring.
Thanks
Mathias
Andy Shevchenko (3):
xhci: pci: Use full names in PCI IDs for Intel platforms
xhci: pci: Group out Thunderbolt xHCI IDs
xhci: pci: Use PCI_VENDOR_ID_RENESAS
Mathias Nyman (4):
xhci: stored cached port capability values in one place
xhci: remove xhci_check_usb2_port_capability helper
xhci: improve PORTSC register debugging output
xhci: remove XHCI_TRUST_TX_LENGTH quirk
Niklas Neronin (11):
usb: xhci: check if 'requested segments' exceeds ERST capacity
usb: xhci: improve debug message in xhci_ring_expansion_needed()
usb: xhci: address off-by-one in xhci_num_trbs_free()
usb: xhci: remove redundant variable 'erst_size'
usb: xhci: use array_size() when allocating and freeing memory
usb: xhci: prevent potential failure in handle_tx_event() for Transfer
events without TRB
usb: xhci: remove 'handling_skipped_tds' from handle_tx_event()
usb: xhci: replace goto with return when possible in handle_tx_event()
usb: xhci: remove goto 'cleanup' in handle_tx_event()
usb: xhci: remove duplicate TRB_TO_SLOT_ID() calls
usb: xhci: compact 'trb_in_td()' arguments
drivers/usb/host/xhci-dbgcap.c | 2 +-
drivers/usb/host/xhci-mem.c | 48 +++++-------
drivers/usb/host/xhci-pci.c | 49 +++++-------
drivers/usb/host/xhci-rcar.c | 6 +-
drivers/usb/host/xhci-ring.c | 138 ++++++++++++++-------------------
drivers/usb/host/xhci.c | 38 ++-------
drivers/usb/host/xhci.h | 28 ++++---
7 files changed, 121 insertions(+), 188 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 01/18] xhci: stored cached port capability values in one place
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 02/18] xhci: remove xhci_check_usb2_port_capability helper Mathias Nyman
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman
Port capability flags for USB2 ports have been cached in an
u32 xhci->ext_caps[] array long before the driver had struct xhci_port
and struct xhci_port_cap structures.
Move these cached USB2 port capability values together with the other
port capability values into struct xhci_port_cap cability structure.
This also gets rid of the cumbersome way of mapping port to USB2
capability based on portnum as each port has a pointer to its capability
structure.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 12 +-----------
drivers/usb/host/xhci.c | 19 +++++--------------
drivers/usb/host/xhci.h | 4 +---
3 files changed, 7 insertions(+), 28 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 69dd86669883..7ff2ff29b48e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1950,7 +1950,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
kfree(xhci->usb3_rhub.ports);
kfree(xhci->hw_ports);
kfree(xhci->rh_bw);
- kfree(xhci->ext_caps);
for (i = 0; i < xhci->num_port_caps; i++)
kfree(xhci->port_caps[i].psi);
kfree(xhci->port_caps);
@@ -1961,7 +1960,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->usb3_rhub.ports = NULL;
xhci->hw_ports = NULL;
xhci->rh_bw = NULL;
- xhci->ext_caps = NULL;
xhci->port_caps = NULL;
xhci->interrupters = NULL;
@@ -2089,10 +2087,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
port_cap->maj_rev = major_revision;
port_cap->min_rev = minor_revision;
-
- /* cache usb2 port capabilities */
- if (major_revision < 0x03 && xhci->num_ext_caps < max_caps)
- xhci->ext_caps[xhci->num_ext_caps++] = temp;
+ port_cap->protocol_caps = temp;
if ((xhci->hci_version >= 0x100) && (major_revision != 0x03) &&
(temp & XHCI_HLC)) {
@@ -2212,11 +2207,6 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
XHCI_EXT_CAPS_PROTOCOL);
}
- xhci->ext_caps = kcalloc_node(cap_count, sizeof(*xhci->ext_caps),
- flags, dev_to_node(dev));
- if (!xhci->ext_caps)
- return -ENOMEM;
-
xhci->port_caps = kcalloc_node(cap_count, sizeof(*xhci->port_caps),
flags, dev_to_node(dev));
if (!xhci->port_caps)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 8579603edaff..7f07672d4110 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4511,23 +4511,14 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
* only USB2 ports extended protocol capability values are cached.
* Return 1 if capability is supported
*/
-static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,
+static bool xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int portnum,
unsigned capability)
{
- u32 port_offset, port_count;
- int i;
+ struct xhci_port *port;
- for (i = 0; i < xhci->num_ext_caps; i++) {
- if (xhci->ext_caps[i] & capability) {
- /* port offsets starts at 1 */
- port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1;
- port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]);
- if (port >= port_offset &&
- port < port_offset + port_count)
- return 1;
- }
- }
- return 0;
+ port = xhci->usb2_rhub.ports[portnum];
+
+ return !!(port->port_cap->protocol_caps & capability);
}
static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6f4bf98a6282..1c9519205330 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1451,6 +1451,7 @@ struct xhci_port_cap {
u8 psi_uid_count;
u8 maj_rev;
u8 min_rev;
+ u32 protocol_caps;
};
struct xhci_port {
@@ -1640,9 +1641,6 @@ struct xhci_hcd {
unsigned broken_suspend:1;
/* Indicates that omitting hcd is supported if root hub has no ports */
unsigned allow_single_roothub:1;
- /* cached usb2 extened protocol capabilites */
- u32 *ext_caps;
- unsigned int num_ext_caps;
/* cached extended protocol port capabilities */
struct xhci_port_cap *port_caps;
unsigned int num_port_caps;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 02/18] xhci: remove xhci_check_usb2_port_capability helper
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
2024-04-29 14:02 ` [PATCH 01/18] xhci: stored cached port capability values in one place Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 03/18] usb: xhci: check if 'requested segments' exceeds ERST capacity Mathias Nyman
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman
This helper was only called from one function.
Removing it both reduces lines of code and made it more readable.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci.c | 29 ++++++++---------------------
1 file changed, 8 insertions(+), 21 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7f07672d4110..37eb37b0affa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4507,26 +4507,13 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
return 0;
}
-/* check if a usb2 port supports a given extened capability protocol
- * only USB2 ports extended protocol capability values are cached.
- * Return 1 if capability is supported
- */
-static bool xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int portnum,
- unsigned capability)
-{
- struct xhci_port *port;
-
- port = xhci->usb2_rhub.ports[portnum];
-
- return !!(port->port_cap->protocol_caps & capability);
-}
-
static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- int portnum = udev->portnum - 1;
+ struct xhci_port *port;
+ u32 capability;
- if (hcd->speed >= HCD_USB3 || !udev->lpm_capable)
+ if (hcd->speed >= HCD_USB3 || !udev->lpm_capable || !xhci->hw_lpm_support)
return 0;
/* we only support lpm for non-hub device connected to root hub yet */
@@ -4534,14 +4521,14 @@ static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
udev->descriptor.bDeviceClass == USB_CLASS_HUB)
return 0;
- if (xhci->hw_lpm_support == 1 &&
- xhci_check_usb2_port_capability(
- xhci, portnum, XHCI_HLC)) {
+ port = xhci->usb2_rhub.ports[udev->portnum - 1];
+ capability = port->port_cap->protocol_caps;
+
+ if (capability & XHCI_HLC) {
udev->usb2_hw_lpm_capable = 1;
udev->l1_params.timeout = XHCI_L1_TIMEOUT;
udev->l1_params.besl = XHCI_DEFAULT_BESL;
- if (xhci_check_usb2_port_capability(xhci, portnum,
- XHCI_BLC))
+ if (capability & XHCI_BLC)
udev->usb2_hw_lpm_besl_capable = 1;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 03/18] usb: xhci: check if 'requested segments' exceeds ERST capacity
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
2024-04-29 14:02 ` [PATCH 01/18] xhci: stored cached port capability values in one place Mathias Nyman
2024-04-29 14:02 ` [PATCH 02/18] xhci: remove xhci_check_usb2_port_capability helper Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 04/18] usb: xhci: improve debug message in xhci_ring_expansion_needed() Mathias Nyman
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Check if requested segments ('segs' or 'ERST_DEFAULT_SEGS') exceeds the
maximum amount ERST supports.
When 'segs' is '0', 'ERST_DEFAULT_SEGS' is used instead. But both values
may not exceed ERST max.
Macro 'ERST_MAX_SEGS' is renamed to 'ERST_DEFAULT_SEGS'. The new name
better represents the macros, which is the number of Event Ring segments
to allocate, when the amount is not specified.
Additionally, rename and change xhci_create_secondary_interrupter()'s
argument 'int num_segs' to 'unsigned int segs'. This makes it the same
as its counter part in xhci_alloc_interrupter().
Fixes: c99b38c41234 ("xhci: add support to allocate several interrupters")
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 22 +++++++++++-----------
drivers/usb/host/xhci.h | 6 +++---
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 7ff2ff29b48e..1a16b44506da 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2259,24 +2259,24 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
}
static struct xhci_interrupter *
-xhci_alloc_interrupter(struct xhci_hcd *xhci, int segs, gfp_t flags)
+xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
struct xhci_interrupter *ir;
- unsigned int num_segs = segs;
+ unsigned int max_segs;
int ret;
+ if (!segs)
+ segs = ERST_DEFAULT_SEGS;
+
+ max_segs = BIT(HCS_ERST_MAX(xhci->hcs_params2));
+ segs = min(segs, max_segs);
+
ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
if (!ir)
return NULL;
- /* number of ring segments should be greater than 0 */
- if (segs <= 0)
- num_segs = min_t(unsigned int, 1 << HCS_ERST_MAX(xhci->hcs_params2),
- ERST_MAX_SEGS);
-
- ir->event_ring = xhci_ring_alloc(xhci, num_segs, 1, TYPE_EVENT, 0,
- flags);
+ ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags);
if (!ir->event_ring) {
xhci_warn(xhci, "Failed to allocate interrupter event ring\n");
kfree(ir);
@@ -2334,7 +2334,7 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
}
struct xhci_interrupter *
-xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_interrupter *ir;
@@ -2344,7 +2344,7 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
if (!xhci->interrupters || xhci->max_interrupters <= 1)
return NULL;
- ir = xhci_alloc_interrupter(xhci, num_seg, GFP_KERNEL);
+ ir = xhci_alloc_interrupter(xhci, segs, GFP_KERNEL);
if (!ir)
return NULL;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 1c9519205330..8a3ae5049d1c 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1392,8 +1392,8 @@ struct urb_priv {
struct xhci_td td[] __counted_by(num_tds);
};
-/* Reasonable limit for number of Event Ring segments (spec allows 32k) */
-#define ERST_MAX_SEGS 2
+/* Number of Event Ring segments to allocate, when amount is not specified. (spec allows 32k) */
+#define ERST_DEFAULT_SEGS 2
/* Poll every 60 seconds */
#define POLL_TIMEOUT 60
/* Stop endpoint command timeout (secs) for URB cancellation watchdog timer */
@@ -1831,7 +1831,7 @@ struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
void xhci_free_container_ctx(struct xhci_hcd *xhci,
struct xhci_container_ctx *ctx);
struct xhci_interrupter *
-xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg);
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs);
void xhci_remove_secondary_interrupter(struct usb_hcd
*hcd, struct xhci_interrupter *ir);
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 04/18] usb: xhci: improve debug message in xhci_ring_expansion_needed()
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (2 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 03/18] usb: xhci: check if 'requested segments' exceeds ERST capacity Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 05/18] usb: xhci: address off-by-one in xhci_num_trbs_free() Mathias Nyman
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Address debug message inaccuracies in xhci_ring_expansion_needed().
Specifically, remove the portion of the debug message that indicates the
number of enqueue TRBs to be added to the dequeue segment. This part of
the message may mislead and the calculated value is incorrect. Given that
this value is not of significant importance and the statement is not
consistently accurate, it has been omitted.
The specific issues with the debug message that this commit resolves:
- The calculation of the number of TRBs is incorrect. The current
calculation erroneously includes the link TRB, which is reserved.
Furthermore, the calculated number of TRBs can exceed the dequeue
segment, resulting in a misleading debug message.
- The current phrasing suggests that "ring expansion by X is needed,
adding X TRBs moves enqueue Y TRBs into the dequeue segment".
The intended message, however, is "IF the ring is NOT expanded by X,
THEN adding X TRBs moves enqueue Y TRBs into the dequeue segment".
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 575f0fd9c9f1..3cc5c70d54c7 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -351,10 +351,8 @@ static unsigned int xhci_ring_expansion_needed(struct xhci_hcd *xhci, struct xhc
while (new_segs > 0) {
seg = seg->next;
if (seg == ring->deq_seg) {
- xhci_dbg(xhci, "Ring expansion by %d segments needed\n",
- new_segs);
- xhci_dbg(xhci, "Adding %d trbs moves enq %d trbs into deq seg\n",
- num_trbs, trbs_past_seg % TRBS_PER_SEGMENT);
+ xhci_dbg(xhci, "Adding %d trbs requires expanding ring by %d segments\n",
+ num_trbs, new_segs);
return new_segs;
}
new_segs--;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 05/18] usb: xhci: address off-by-one in xhci_num_trbs_free()
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (3 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 04/18] usb: xhci: improve debug message in xhci_ring_expansion_needed() Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 06/18] usb: xhci: remove redundant variable 'erst_size' Mathias Nyman
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Reduce the number of do-while loops by 1. The number of loops should be
number of segment + 1, the +1 is in case deq and enq are on the same
segment. But due to the use of a do-while loop, the expression is
evaluated after executing the loop, thus the loop is executed 1 extra
time.
Changing the do-while loop expression from "<=" to "<", reduces the loop
amount by 1. The expression "<=" would also work if it was a while loop
instead of a do-while loop.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 3cc5c70d54c7..0a7c70ae5edc 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -308,7 +308,7 @@ static unsigned int xhci_num_trbs_free(struct xhci_hcd *xhci, struct xhci_ring *
free += last_on_seg - enq;
enq_seg = enq_seg->next;
enq = enq_seg->trbs;
- } while (i++ <= ring->num_segs);
+ } while (i++ < ring->num_segs);
return free;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 06/18] usb: xhci: remove redundant variable 'erst_size'
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (4 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 05/18] usb: xhci: address off-by-one in xhci_num_trbs_free() Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 07/18] usb: xhci: use array_size() when allocating and freeing memory Mathias Nyman
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
'erst_size' represents the maximum capacity of entries that ERST can hold,
while 'num_entries' indicates the actual number of entries currently held
in the ERST. These two values are identical because the xhci driver does
not support ERST expansion. Thus, 'erst_size' is removed.
Suggested-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-dbgcap.c | 2 +-
drivers/usb/host/xhci.h | 2 --
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 8a9869ef0db6..872d9cddbcef 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -516,7 +516,7 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
goto string_fail;
/* Setup ERST register: */
- writel(dbc->erst.erst_size, &dbc->regs->ersts);
+ writel(dbc->erst.num_entries, &dbc->regs->ersts);
lo_hi_writeq(dbc->erst.erst_dma_addr, &dbc->regs->erstba);
deq = xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg,
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8a3ae5049d1c..10805196e197 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1376,8 +1376,6 @@ struct xhci_erst {
unsigned int num_entries;
/* xhci->event_ring keeps track of segment dma addresses */
dma_addr_t erst_dma_addr;
- /* Num entries the ERST can contain */
- unsigned int erst_size;
};
struct xhci_scratchpad {
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 07/18] usb: xhci: use array_size() when allocating and freeing memory
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (5 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 06/18] usb: xhci: remove redundant variable 'erst_size' Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 08/18] xhci: improve PORTSC register debugging output Mathias Nyman
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Andy Shevchenko, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Replace size_mul() with array_size() in memory allocation and freeing
processes, it fits better semantically.
Macro array_size() is identical to size_mult(), which clamps the max size,
so it's imperative that array_size() is used when freeing said memory.
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1a16b44506da..3100219d6496 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -536,7 +536,7 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,
struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
- size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs;
+ size_t size = array_size(sizeof(struct xhci_stream_ctx), num_stream_ctxs);
if (size > MEDIUM_STREAM_ARRAY_SIZE)
dma_free_coherent(dev, size, stream_ctx, dma);
@@ -561,7 +561,7 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,
gfp_t mem_flags)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
- size_t size = size_mul(sizeof(struct xhci_stream_ctx), num_stream_ctxs);
+ size_t size = array_size(sizeof(struct xhci_stream_ctx), num_stream_ctxs);
if (size > MEDIUM_STREAM_ARRAY_SIZE)
return dma_alloc_coherent(dev, size, dma, mem_flags);
@@ -1638,7 +1638,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
goto fail_sp;
xhci->scratchpad->sp_array = dma_alloc_coherent(dev,
- size_mul(sizeof(u64), num_sp),
+ array_size(sizeof(u64), num_sp),
&xhci->scratchpad->sp_dma, flags);
if (!xhci->scratchpad->sp_array)
goto fail_sp2;
@@ -1671,7 +1671,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
kfree(xhci->scratchpad->sp_buffers);
fail_sp3:
- dma_free_coherent(dev, num_sp * sizeof(u64),
+ dma_free_coherent(dev, array_size(sizeof(u64), num_sp),
xhci->scratchpad->sp_array,
xhci->scratchpad->sp_dma);
@@ -1700,7 +1700,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)
xhci->scratchpad->sp_array[i]);
}
kfree(xhci->scratchpad->sp_buffers);
- dma_free_coherent(dev, num_sp * sizeof(u64),
+ dma_free_coherent(dev, array_size(sizeof(u64), num_sp),
xhci->scratchpad->sp_array,
xhci->scratchpad->sp_dma);
kfree(xhci->scratchpad);
@@ -1778,7 +1778,7 @@ static int xhci_alloc_erst(struct xhci_hcd *xhci,
struct xhci_segment *seg;
struct xhci_erst_entry *entry;
- size = size_mul(sizeof(struct xhci_erst_entry), evt_ring->num_segs);
+ size = array_size(sizeof(struct xhci_erst_entry), evt_ring->num_segs);
erst->entries = dma_alloc_coherent(xhci_to_hcd(xhci)->self.sysdev,
size, &erst->erst_dma_addr, flags);
if (!erst->entries)
@@ -1829,7 +1829,7 @@ xhci_free_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
if (!ir)
return;
- erst_size = sizeof(struct xhci_erst_entry) * ir->erst.num_entries;
+ erst_size = array_size(sizeof(struct xhci_erst_entry), ir->erst.num_entries);
if (ir->erst.entries)
dma_free_coherent(dev, erst_size,
ir->erst.entries,
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 08/18] xhci: improve PORTSC register debugging output
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (6 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 07/18] usb: xhci: use array_size() when allocating and freeing memory Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 09/18] xhci: remove XHCI_TRUST_TX_LENGTH quirk Mathias Nyman
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman
Print the full hex value of PORTSC register in addition to the human
readable decoded string while debugging PORTSC value.
If PORTSC value is 0xffffffff then don't decode it.
This lets us inspect Rsvd bits of PORTSC.
Same is done for USBSTS register values.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 10805196e197..8c96dd6ef3d4 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2336,7 +2336,12 @@ static inline const char *xhci_decode_portsc(char *str, u32 portsc)
{
int ret;
- ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ",
+ ret = sprintf(str, "0x%08x ", portsc);
+
+ if (portsc == ~(u32)0)
+ return str;
+
+ ret += sprintf(str + ret, "%s %s %s Link:%s PortSpeed:%d ",
portsc & PORT_POWER ? "Powered" : "Powered-off",
portsc & PORT_CONNECT ? "Connected" : "Not-connected",
portsc & PORT_PE ? "Enabled" : "Disabled",
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 09/18] xhci: remove XHCI_TRUST_TX_LENGTH quirk
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (7 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 08/18] xhci: improve PORTSC register debugging output Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 10/18] usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB Mathias Nyman
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman, Niklas Neronin
If this quirk was set then driver would treat transfer events with
'Success' completion code as 'Short packet' if there were untransferred
bytes left.
This is so common that turn it into default behavior.
xhci_warn_ratelimited() is no longer used after this, so remove it.
A success event with untransferred bytes left doesn't always mean a
misbehaving controller. If there was an error mid a multi-TRB TD it's
allowed to issue a success event for the last TRB in that TD.
See xhci 1.2 spec 4.9.1 Transfer Descriptors
"Note: If an error is detected while processing a multi-TRB TD, the xHC
shall generate a Transfer Event for the TRB that the error was detected
on with the appropriate error Condition Code, then may advance to the
next TD. If in the process of advancing to the next TD, a Transfer TRB
is encountered with its IOC flag set, then the Condition Code of the
Transfer Event generated for that Transfer TRB should be Success,
because there was no error actually associated with the TRB that
generated the Event. However, an xHC implementation may redundantly
assert the original error Condition Code."
Co-developed-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-pci.c | 15 ++-------------
drivers/usb/host/xhci-rcar.c | 6 ++----
drivers/usb/host/xhci-ring.c | 15 +++++----------
drivers/usb/host/xhci.h | 4 +---
4 files changed, 10 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 93b697648018..653b47c45591 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -270,17 +270,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
"QUIRK: Fresco Logic revision %u "
"has broken MSI implementation",
pdev->revision);
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
}
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009)
xhci->quirks |= XHCI_BROKEN_STREAMS;
- if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
- pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1100)
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
-
if (pdev->vendor == PCI_VENDOR_ID_NEC)
xhci->quirks |= XHCI_NEC_HOST;
@@ -307,11 +302,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_RESET_ON_RESUME;
}
- if (pdev->vendor == PCI_VENDOR_ID_AMD) {
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
- if (pdev->device == 0x43f7)
- xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
- }
+ if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43f7)
+ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
@@ -399,12 +391,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
pdev->device == PCI_DEVICE_ID_EJ168) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
xhci->quirks |= XHCI_BROKEN_STREAMS;
}
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
pdev->device == 0x0014) {
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
xhci->quirks |= XHCI_ZERO_64B_REGS;
}
if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
@@ -434,7 +424,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
}
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
- xhci->quirks |= XHCI_TRUST_TX_LENGTH;
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
}
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index ab9c5969e462..8b357647728c 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -214,8 +214,7 @@ static int xhci_rcar_resume_quirk(struct usb_hcd *hcd)
*/
#define SET_XHCI_PLAT_PRIV_FOR_RCAR(firmware) \
.firmware_name = firmware, \
- .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH | \
- XHCI_SLOW_SUSPEND, \
+ .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND, \
.init_quirk = xhci_rcar_init_quirk, \
.plat_start = xhci_rcar_start, \
.resume_quirk = xhci_rcar_resume_quirk,
@@ -229,8 +228,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
};
static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = {
- .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH |
- XHCI_SLOW_SUSPEND,
+ .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND,
.init_quirk = xhci_rzv2m_init_quirk,
.plat_start = xhci_rzv2m_start,
};
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0a7c70ae5edc..07c529e072c9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2397,8 +2397,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
break;
if (remaining) {
frame->status = short_framestatus;
- if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
- sum_trbs_for_length = true;
+ sum_trbs_for_length = true;
break;
}
frame->status = 0;
@@ -2648,15 +2647,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* transfer type
*/
case COMP_SUCCESS:
- if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
- break;
- if (xhci->quirks & XHCI_TRUST_TX_LENGTH ||
- ep_ring->last_td_was_short)
+ if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
trb_comp_code = COMP_SHORT_PACKET;
- else
- xhci_warn_ratelimited(xhci,
- "WARN Successful completion on short TX for slot %u ep %u: needs XHCI_TRUST_TX_LENGTH quirk?\n",
- slot_id, ep_index);
+ xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n",
+ slot_id, ep_index, ep_ring->last_td_was_short);
+ }
break;
case COMP_SHORT_PACKET:
break;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8c96dd6ef3d4..933f8a296014 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1588,7 +1588,7 @@ struct xhci_hcd {
#define XHCI_RESET_ON_RESUME BIT_ULL(7)
#define XHCI_SW_BW_CHECKING BIT_ULL(8)
#define XHCI_AMD_0x96_HOST BIT_ULL(9)
-#define XHCI_TRUST_TX_LENGTH BIT_ULL(10)
+#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) /* Deprecated */
#define XHCI_LPM_SUPPORT BIT_ULL(11)
#define XHCI_INTEL_HOST BIT_ULL(12)
#define XHCI_SPURIOUS_REBOOT BIT_ULL(13)
@@ -1725,8 +1725,6 @@ static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci)
dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
#define xhci_warn(xhci, fmt, args...) \
dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
-#define xhci_warn_ratelimited(xhci, fmt, args...) \
- dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
#define xhci_info(xhci, fmt, args...) \
dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 10/18] usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (8 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 09/18] xhci: remove XHCI_TRUST_TX_LENGTH quirk Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 11/18] usb: xhci: remove 'handling_skipped_tds' from handle_tx_event() Mathias Nyman
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Some transfer events don't always point to a TRB, and consequently don't
have a endpoint ring. In these cases, function handle_tx_event() should
not proceed, because if 'ep->skip' is set, the pointer to the endpoint
ring is used.
To prevent a potential failure and make the code logical, return after
checking the completion code for a Transfer event without TRBs.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 07c529e072c9..00f48dd197ac 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2625,16 +2625,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
else
xhci_handle_halted_endpoint(xhci, ep, NULL,
EP_SOFT_RESET);
- goto cleanup;
+ break;
case COMP_RING_UNDERRUN:
case COMP_RING_OVERRUN:
case COMP_STOPPED_LENGTH_INVALID:
- goto cleanup;
+ break;
default:
xhci_err(xhci, "ERROR Transfer event for unknown stream ring slot %u ep %u\n",
slot_id, ep_index);
goto err_out;
}
+ return 0;
}
/* Count current td numbers if ep->skip is set */
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 11/18] usb: xhci: remove 'handling_skipped_tds' from handle_tx_event()
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (9 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 10/18] usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 12/18] usb: xhci: replace goto with return when possible in handle_tx_event() Mathias Nyman
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
When handle_tx_event() encounters a COMP_MISSED_SERVICE_ERROR or
COMP_NO_PING_RESPONSE_ERROR event, it moves to 'goto cleanup'.
Here, it sets a flag, 'handling_skipped_tds', based on conditions that
exclude these two error events.
Subsequently, the process evaluates the loop that persists as long as
'handling_skipped_tds' remains true. However, since 'trb_comp_code' does
not change after its assignment, if it indicates either of the two error
conditions, the loop terminates immediately.
To simplify this process and enhance clarity, the modification involves
returning immediately upon detecting COMP_MISSED_SERVICE_ERROR or
COMP_NO_PING_RESPONSE_ERROR. This adjustment allows for the direct use of
'ep->skip', removing the necessity for the 'handling_skipped_tds' flag.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 00f48dd197ac..e96ac2d7b9b1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2587,7 +2587,6 @@ static int handle_tx_event(struct xhci_hcd *xhci,
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
int td_num = 0;
- bool handling_skipped_tds = false;
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -2748,13 +2747,13 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_dbg(xhci,
"Miss service interval error for slot %u ep %u, set skip flag\n",
slot_id, ep_index);
- goto cleanup;
+ return 0;
case COMP_NO_PING_RESPONSE_ERROR:
ep->skip = true;
xhci_dbg(xhci,
"No Ping response error for slot %u ep %u, Skip one Isoc TD\n",
slot_id, ep_index);
- goto cleanup;
+ return 0;
case COMP_INCOMPATIBLE_DEVICE_ERROR:
/* needs disable slot command to recover */
@@ -2939,18 +2938,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
process_isoc_td(xhci, ep, ep_ring, td, ep_trb, event);
else
process_bulk_intr_td(xhci, ep, ep_ring, td, ep_trb, event);
-cleanup:
- handling_skipped_tds = ep->skip &&
- trb_comp_code != COMP_MISSED_SERVICE_ERROR &&
- trb_comp_code != COMP_NO_PING_RESPONSE_ERROR;
-
+cleanup:;
/*
* If ep->skip is set, it means there are missed tds on the
* endpoint ring need to take care of.
* Process them as short transfer until reach the td pointed by
* the event.
*/
- } while (handling_skipped_tds);
+ } while (ep->skip);
return 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 12/18] usb: xhci: replace goto with return when possible in handle_tx_event()
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (10 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 11/18] usb: xhci: remove 'handling_skipped_tds' from handle_tx_event() Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 13/18] usb: xhci: remove goto 'cleanup' " Mathias Nyman
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Simplifying the handle_tx_event() function by addressing the complexity
of its while loop. Replaces specific 'goto cleanup' statements with
'return' statements, applicable only where 'ep->skip' is set to 'false',
ensuring loop termination.
The original while loop, combined with 'goto cleanup', adds unnecessary
complexity. This change aims to untangle the loop's logic, facilitating a
more straightforward review of the upcoming comprehensive rework.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e96ac2d7b9b1..0f48f9befc94 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2804,7 +2804,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_handle_halted_endpoint(xhci, ep, NULL,
EP_HARD_RESET);
}
- goto cleanup;
+ return 0;
}
/* We've skipped all the TDs on the ep ring when ep->skip set */
@@ -2812,7 +2812,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
ep->skip = false;
xhci_dbg(xhci, "All tds on the ep_ring skipped. Clear skip flag for slot %u ep %u.\n",
slot_id, ep_index);
- goto cleanup;
+ return 0;
}
td = list_first_entry(&ep_ring->td_list, struct xhci_td,
@@ -2851,7 +2851,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
ep_ring->last_td_was_short) {
ep_ring->last_td_was_short = false;
- goto cleanup;
+ return 0;
}
/*
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 13/18] usb: xhci: remove goto 'cleanup' in handle_tx_event()
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (11 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 12/18] usb: xhci: replace goto with return when possible in handle_tx_event() Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 14/18] xhci: pci: Use full names in PCI IDs for Intel platforms Mathias Nyman
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
By removing the goto 'cleanup' statement, and replacing it with 'continue',
'break' and 'return', helps simplify the code and further showcase in which
case the while loop iterates.
This change prepares for the comprehensive handle_tx_event() rework.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 38 ++++++++++++++++++++----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0f48f9befc94..b395708c488c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2727,7 +2727,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
"still with TDs queued?\n",
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index);
- goto cleanup;
+ if (ep->skip)
+ break;
+ return 0;
case COMP_RING_OVERRUN:
xhci_dbg(xhci, "overrun event on endpoint\n");
if (!list_empty(&ep_ring->td_list))
@@ -2735,7 +2737,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
"still with TDs queued?\n",
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index);
- goto cleanup;
+ if (ep->skip)
+ break;
+ return 0;
case COMP_MISSED_SERVICE_ERROR:
/*
* When encounter missed service error, one or more isoc tds
@@ -2770,7 +2774,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_warn(xhci,
"ERROR Unknown event condition %u for slot %u ep %u , HC probably busted\n",
trb_comp_code, slot_id, ep_index);
- goto cleanup;
+ if (ep->skip)
+ break;
+ return 0;
}
do {
@@ -2834,14 +2840,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
if (!ep_seg && (trb_comp_code == COMP_STOPPED ||
trb_comp_code == COMP_STOPPED_LENGTH_INVALID)) {
- goto cleanup;
+ continue;
}
if (!ep_seg) {
if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
skip_isoc_td(xhci, td, ep, status);
- goto cleanup;
+ continue;
}
/*
@@ -2926,19 +2932,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
trb_comp_code))
xhci_handle_halted_endpoint(xhci, ep, td,
EP_HARD_RESET);
- goto cleanup;
- }
-
- td->status = status;
+ } else {
+ td->status = status;
- /* update the urb's actual_length and give back to the core */
- if (usb_endpoint_xfer_control(&td->urb->ep->desc))
- process_ctrl_td(xhci, ep, ep_ring, td, ep_trb, event);
- else if (usb_endpoint_xfer_isoc(&td->urb->ep->desc))
- process_isoc_td(xhci, ep, ep_ring, td, ep_trb, event);
- else
- process_bulk_intr_td(xhci, ep, ep_ring, td, ep_trb, event);
-cleanup:;
+ /* update the urb's actual_length and give back to the core */
+ if (usb_endpoint_xfer_control(&td->urb->ep->desc))
+ process_ctrl_td(xhci, ep, ep_ring, td, ep_trb, event);
+ else if (usb_endpoint_xfer_isoc(&td->urb->ep->desc))
+ process_isoc_td(xhci, ep, ep_ring, td, ep_trb, event);
+ else
+ process_bulk_intr_td(xhci, ep, ep_ring, td, ep_trb, event);
+ }
/*
* If ep->skip is set, it means there are missed tds on the
* endpoint ring need to take care of.
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 14/18] xhci: pci: Use full names in PCI IDs for Intel platforms
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (12 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 13/18] usb: xhci: remove goto 'cleanup' " Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 15/18] xhci: pci: Group out Thunderbolt xHCI IDs Mathias Nyman
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
There are three out of many Intel platforms that are using TLAs
instead of the full names in the PCI IDs. Modify them accordingly.
This also fixes the logic of grouping as seemed to be by an LSB
byte of the ID.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-pci.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 653b47c45591..d45c84062b61 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -45,8 +45,7 @@
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8
-#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
-#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0
+#define PCI_DEVICE_ID_INTEL_APOLLO_LAKE_XHCI 0x5aa8
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI 0x15b5
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI 0x15b6
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_XHCI 0x15c1
@@ -55,9 +54,10 @@
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_XHCI 0x15e9
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0
+#define PCI_DEVICE_ID_INTEL_DENVERTON_XHCI 0x19d0
#define PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI 0x8a13
-#define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af
#define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
+#define PCI_DEVICE_ID_INTEL_COMET_LAKE_XHCI 0xa3af
#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed
@@ -348,9 +348,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_CML_XHCI)) {
+ pdev->device == PCI_DEVICE_ID_INTEL_APOLLO_LAKE_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_DENVERTON_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_COMET_LAKE_XHCI)) {
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
}
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
@@ -359,14 +359,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
(pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
+ pdev->device == PCI_DEVICE_ID_INTEL_APOLLO_LAKE_XHCI))
xhci->quirks |= XHCI_INTEL_USB_ROLE_SW;
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
(pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
+ pdev->device == PCI_DEVICE_ID_INTEL_APOLLO_LAKE_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_DENVERTON_XHCI))
xhci->quirks |= XHCI_MISSING_CAS;
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 15/18] xhci: pci: Group out Thunderbolt xHCI IDs
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (13 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 14/18] xhci: pci: Use full names in PCI IDs for Intel platforms Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 16/18] xhci: pci: Use PCI_VENDOR_ID_RENESAS Mathias Nyman
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
It's better to keep track on Thunderbolt xHCI IDs in a separate group.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-pci.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index d45c84062b61..8e9b720ab330 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -46,6 +46,15 @@
#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8
#define PCI_DEVICE_ID_INTEL_APOLLO_LAKE_XHCI 0x5aa8
+#define PCI_DEVICE_ID_INTEL_DENVERTON_XHCI 0x19d0
+#define PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI 0x8a13
+#define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
+#define PCI_DEVICE_ID_INTEL_COMET_LAKE_XHCI 0xa3af
+#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
+#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed
+
+/* Thunderbolt */
+#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI 0x15b5
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI 0x15b6
#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_XHCI 0x15c1
@@ -54,13 +63,6 @@
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_XHCI 0x15e9
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0
-#define PCI_DEVICE_ID_INTEL_DENVERTON_XHCI 0x19d0
-#define PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI 0x8a13
-#define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
-#define PCI_DEVICE_ID_INTEL_COMET_LAKE_XHCI 0xa3af
-#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed
#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 16/18] xhci: pci: Use PCI_VENDOR_ID_RENESAS
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (14 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 15/18] xhci: pci: Group out Thunderbolt xHCI IDs Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 17/18] usb: xhci: remove duplicate TRB_TO_SLOT_ID() calls Mathias Nyman
2024-04-29 14:02 ` [PATCH 18/18] usb: xhci: compact 'trb_in_td()' arguments Mathias Nyman
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Instead of plain hexadecimal, use already defined PCI_VENDOR_ID_RENESAS.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-pci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 8e9b720ab330..c040d816e626 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -880,10 +880,10 @@ static const struct xhci_driver_data reneses_data = {
/* PCI driver selection metadata; PCI hotplugging uses this */
static const struct pci_device_id pci_ids[] = {
- { PCI_DEVICE(0x1912, 0x0014),
+ { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014),
.driver_data = (unsigned long)&reneses_data,
},
- { PCI_DEVICE(0x1912, 0x0015),
+ { PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015),
.driver_data = (unsigned long)&reneses_data,
},
/* handle any USB 3.0 xHCI controller */
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 17/18] usb: xhci: remove duplicate TRB_TO_SLOT_ID() calls
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (15 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 16/18] xhci: pci: Use PCI_VENDOR_ID_RENESAS Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
2024-04-29 14:02 ` [PATCH 18/18] usb: xhci: compact 'trb_in_td()' arguments Mathias Nyman
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Remove unnecessary repeated calls to TRB_TO_SLOT_ID(). The slot ID is
stored in the 'slot_id' variable at the function's start.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b395708c488c..a7423ed992ee 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2723,20 +2723,16 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
xhci_dbg(xhci, "underrun event on endpoint\n");
if (!list_empty(&ep_ring->td_list))
- xhci_dbg(xhci, "Underrun Event for slot %d ep %d "
- "still with TDs queued?\n",
- TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
- ep_index);
+ xhci_dbg(xhci, "Underrun Event for slot %u ep %d still with TDs queued?\n",
+ slot_id, ep_index);
if (ep->skip)
break;
return 0;
case COMP_RING_OVERRUN:
xhci_dbg(xhci, "overrun event on endpoint\n");
if (!list_empty(&ep_ring->td_list))
- xhci_dbg(xhci, "Overrun Event for slot %d ep %d "
- "still with TDs queued?\n",
- TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
- ep_index);
+ xhci_dbg(xhci, "Overrun Event for slot %u ep %d still with TDs queued?\n",
+ slot_id, ep_index);
if (ep->skip)
break;
return 0;
@@ -2795,9 +2791,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (!(trb_comp_code == COMP_STOPPED ||
trb_comp_code == COMP_STOPPED_LENGTH_INVALID ||
ep_ring->last_td_was_short)) {
- xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
- TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
- ep_index);
+ xhci_warn(xhci, "WARN Event TRB for slot %u ep %d with no TDs queued?\n",
+ slot_id, ep_index);
}
if (ep->skip) {
ep->skip = false;
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 18/18] usb: xhci: compact 'trb_in_td()' arguments
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
` (16 preceding siblings ...)
2024-04-29 14:02 ` [PATCH 17/18] usb: xhci: remove duplicate TRB_TO_SLOT_ID() calls Mathias Nyman
@ 2024-04-29 14:02 ` Mathias Nyman
17 siblings, 0 replies; 19+ messages in thread
From: Mathias Nyman @ 2024-04-29 14:02 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Pass pointer to the TD (struct xhci_td *) directly, instead of its
components separately.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 38 +++++++++++++-----------------------
drivers/usb/host/xhci.h | 5 ++---
2 files changed, 16 insertions(+), 27 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index a7423ed992ee..9e90d2952760 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1024,8 +1024,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
td->urb->stream_id);
hw_deq &= ~0xf;
- if (td->cancel_status == TD_HALTED ||
- trb_in_td(xhci, td->start_seg, td->first_trb, td->last_trb, hw_deq, false)) {
+ if (td->cancel_status == TD_HALTED || trb_in_td(xhci, td, hw_deq, false)) {
switch (td->cancel_status) {
case TD_CLEARED: /* TD is already no-op */
case TD_CLEARING_CACHE: /* set TR deq command already queued */
@@ -1082,8 +1081,7 @@ static struct xhci_td *find_halted_td(struct xhci_virt_ep *ep)
hw_deq = xhci_get_hw_deq(ep->xhci, ep->vdev, ep->ep_index, 0);
hw_deq &= ~0xf;
td = list_first_entry(&ep->ring->td_list, struct xhci_td, td_list);
- if (trb_in_td(ep->xhci, td->start_seg, td->first_trb,
- td->last_trb, hw_deq, false))
+ if (trb_in_td(ep->xhci, td, hw_deq, false))
return td;
}
return NULL;
@@ -2049,25 +2047,19 @@ static void handle_port_status(struct xhci_hcd *xhci,
}
/*
- * This TD is defined by the TRBs starting at start_trb in start_seg and ending
- * at end_trb, which may be in another segment. If the suspect DMA address is a
- * TRB in this TD, this function returns that TRB's segment. Otherwise it
- * returns 0.
+ * If the suspect DMA address is a TRB in this TD, this function returns that
+ * TRB's segment. Otherwise it returns 0.
*/
-struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
- struct xhci_segment *start_seg,
- union xhci_trb *start_trb,
- union xhci_trb *end_trb,
- dma_addr_t suspect_dma,
- bool debug)
+struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, dma_addr_t suspect_dma,
+ bool debug)
{
dma_addr_t start_dma;
dma_addr_t end_seg_dma;
dma_addr_t end_trb_dma;
struct xhci_segment *cur_seg;
- start_dma = xhci_trb_virt_to_dma(start_seg, start_trb);
- cur_seg = start_seg;
+ start_dma = xhci_trb_virt_to_dma(td->start_seg, td->first_trb);
+ cur_seg = td->start_seg;
do {
if (start_dma == 0)
@@ -2076,7 +2068,7 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
&cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
/* If the end TRB isn't in this segment, this is set to 0 */
- end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb);
+ end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->last_trb);
if (debug)
xhci_warn(xhci,
@@ -2110,7 +2102,7 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
}
cur_seg = cur_seg->next;
start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
- } while (cur_seg != start_seg);
+ } while (cur_seg != td->start_seg);
return NULL;
}
@@ -2822,8 +2814,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
td_num--;
/* Is this a TRB in the currently executing TD? */
- ep_seg = trb_in_td(xhci, td->start_seg, td->first_trb,
- td->last_trb, ep_trb_dma, false);
+ ep_seg = trb_in_td(xhci, td, ep_trb_dma, false);
/*
* Skip the Force Stopped Event. The event_trb(event_dma) of FSE
@@ -2870,8 +2861,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
!list_is_last(&td->td_list, &ep_ring->td_list)) {
struct xhci_td *td_next = list_next_entry(td, td_list);
- ep_seg = trb_in_td(xhci, td_next->start_seg, td_next->first_trb,
- td_next->last_trb, ep_trb_dma, false);
+ ep_seg = trb_in_td(xhci, td_next, ep_trb_dma, false);
if (ep_seg) {
/* give back previous TD, start handling new */
xhci_dbg(xhci, "Missing TD completion event after mid TD error\n");
@@ -2890,8 +2880,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
"part of current TD ep_index %d "
"comp_code %u\n", ep_index,
trb_comp_code);
- trb_in_td(xhci, td->start_seg, td->first_trb,
- td->last_trb, ep_trb_dma, true);
+ trb_in_td(xhci, td, ep_trb_dma, true);
+
return -ESHUTDOWN;
}
}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 933f8a296014..30415158ed3c 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1870,9 +1870,8 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
/* xHCI ring, segment, TRB, and TD functions */
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
-struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
- struct xhci_segment *start_seg, union xhci_trb *start_trb,
- union xhci_trb *end_trb, dma_addr_t suspect_dma, bool debug);
+struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td,
+ dma_addr_t suspect_dma, bool debug);
int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code);
void xhci_ring_cmd_db(struct xhci_hcd *xhci);
int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd,
--
2.25.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
end of thread, other threads:[~2024-04-29 14:01 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-29 14:02 [PATCH 00/18] xhci cleanups and rework for usb-next Mathias Nyman
2024-04-29 14:02 ` [PATCH 01/18] xhci: stored cached port capability values in one place Mathias Nyman
2024-04-29 14:02 ` [PATCH 02/18] xhci: remove xhci_check_usb2_port_capability helper Mathias Nyman
2024-04-29 14:02 ` [PATCH 03/18] usb: xhci: check if 'requested segments' exceeds ERST capacity Mathias Nyman
2024-04-29 14:02 ` [PATCH 04/18] usb: xhci: improve debug message in xhci_ring_expansion_needed() Mathias Nyman
2024-04-29 14:02 ` [PATCH 05/18] usb: xhci: address off-by-one in xhci_num_trbs_free() Mathias Nyman
2024-04-29 14:02 ` [PATCH 06/18] usb: xhci: remove redundant variable 'erst_size' Mathias Nyman
2024-04-29 14:02 ` [PATCH 07/18] usb: xhci: use array_size() when allocating and freeing memory Mathias Nyman
2024-04-29 14:02 ` [PATCH 08/18] xhci: improve PORTSC register debugging output Mathias Nyman
2024-04-29 14:02 ` [PATCH 09/18] xhci: remove XHCI_TRUST_TX_LENGTH quirk Mathias Nyman
2024-04-29 14:02 ` [PATCH 10/18] usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB Mathias Nyman
2024-04-29 14:02 ` [PATCH 11/18] usb: xhci: remove 'handling_skipped_tds' from handle_tx_event() Mathias Nyman
2024-04-29 14:02 ` [PATCH 12/18] usb: xhci: replace goto with return when possible in handle_tx_event() Mathias Nyman
2024-04-29 14:02 ` [PATCH 13/18] usb: xhci: remove goto 'cleanup' " Mathias Nyman
2024-04-29 14:02 ` [PATCH 14/18] xhci: pci: Use full names in PCI IDs for Intel platforms Mathias Nyman
2024-04-29 14:02 ` [PATCH 15/18] xhci: pci: Group out Thunderbolt xHCI IDs Mathias Nyman
2024-04-29 14:02 ` [PATCH 16/18] xhci: pci: Use PCI_VENDOR_ID_RENESAS Mathias Nyman
2024-04-29 14:02 ` [PATCH 17/18] usb: xhci: remove duplicate TRB_TO_SLOT_ID() calls Mathias Nyman
2024-04-29 14:02 ` [PATCH 18/18] usb: xhci: compact 'trb_in_td()' arguments Mathias Nyman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).