linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/19] xhci features for usb-next
@ 2023-12-01 15:06 Mathias Nyman
  2023-12-01 15:06 ` [PATCH 01/19] xhci: dbc: Drop duplicate checks for dma_free_coherent() Mathias Nyman
                   ` (18 more replies)
  0 siblings, 19 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

Hi Greg

A set of xhci features and cleanups for usb-next, including xhci dbc
cleanups, MSI rework, and fixing how we reconfigure max packet size
for xhc.

One patch fixes a null pointer deref issue, but this hasn't been seen
in real life. It's a theoretical case triggered by adding a 3 second
delay in the driver.
So I don't think it should go to stable.

Thanks
Mathias

Andy Shevchenko (10):
  xhci: dbc: Drop duplicate checks for dma_free_coherent()
  xhci: dbc: Convert to use sysfs_streq()
  xhci: dbc: Use sysfs_emit() to instead of scnprintf()
  xhci: dbc: Use ATTRIBUTE_GROUPS()
  xhci: dbc: Check for errors first in xhci_dbc_stop()
  xhci: dbc: Don't shadow error codes in store() functions
  xhci: dbc: Replace custom return value with proper Linux error code
  xhci: dbc: Use sizeof_field() where it makes sense
  xhci: dbc: Use sizeof(*pointer) instead of sizeof(type)
  xhci: dbc: Add missing headers

Mathias Nyman (2):
  xhci: Reconfigure endpoint 0 max packet size only during endpoint
    reset
  xhci: fix possible null pointer deref during xhci urb enqueue

Niklas Neronin (7):
  xhci: check if legacy irq is available before using it as fallback
  xhci: add handler for only one interrupt line
  xhci: refactor static MSI-X function
  xhci: refactor static MSI function
  xhci: change 'msix_count' to encompass MSI or MSI-X vectors
  xhci: rework 'xhci_try_enable_msi()' MSI and MSI-X setup code
  xhci: minor coding style cleanup in 'xhci_try_enable_msi()'

 drivers/usb/host/xhci-dbgcap.c | 132 ++++++++++++++++---------------
 drivers/usb/host/xhci-dbgcap.h |   1 +
 drivers/usb/host/xhci-pci.c    | 140 +++++++++------------------------
 drivers/usb/host/xhci.c        | 123 +++++++++++++++--------------
 drivers/usb/host/xhci.h        |   4 +-
 5 files changed, 175 insertions(+), 225 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 01/19] xhci: dbc: Drop duplicate checks for dma_free_coherent()
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 02/19] xhci: dbc: Convert to use sysfs_streq() Mathias Nyman
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

dma_free_coherent() is NULL-aware, not necessary to check for
the parameter twice. Drop duplicate conditionals in the caller.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index b40d9238d447..9e9ce3711813 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -28,7 +28,7 @@ static void dbc_ring_free(struct device *dev, struct xhci_ring *ring)
 	if (!ring)
 		return;
 
-	if (ring->first_seg && ring->first_seg->trbs) {
+	if (ring->first_seg) {
 		dma_free_coherent(dev, TRB_SEGMENT_SIZE,
 				  ring->first_seg->trbs,
 				  ring->first_seg->dma);
@@ -394,9 +394,8 @@ static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
 
 static void dbc_erst_free(struct device *dev, struct xhci_erst *erst)
 {
-	if (erst->entries)
-		dma_free_coherent(dev, sizeof(struct xhci_erst_entry),
-				  erst->entries, erst->erst_dma_addr);
+	dma_free_coherent(dev, sizeof(struct xhci_erst_entry), erst->entries,
+			  erst->erst_dma_addr);
 	erst->entries = NULL;
 }
 
@@ -543,11 +542,8 @@ static void xhci_dbc_mem_cleanup(struct xhci_dbc *dbc)
 
 	xhci_dbc_eps_exit(dbc);
 
-	if (dbc->string) {
-		dma_free_coherent(dbc->dev, dbc->string_size,
-				  dbc->string, dbc->string_dma);
-		dbc->string = NULL;
-	}
+	dma_free_coherent(dbc->dev, dbc->string_size, dbc->string, dbc->string_dma);
+	dbc->string = NULL;
 
 	dbc_free_ctx(dbc->dev, dbc->ctx);
 	dbc->ctx = NULL;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/19] xhci: dbc: Convert to use sysfs_streq()
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
  2023-12-01 15:06 ` [PATCH 01/19] xhci: dbc: Drop duplicate checks for dma_free_coherent() Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 03/19] xhci: dbc: Use sysfs_emit() to instead of scnprintf() Mathias Nyman
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

It's standard approach to parse values from user space by using
sysfs_streq(). Make driver use it.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 9e9ce3711813..f505b79afe53 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -957,9 +957,9 @@ static ssize_t dbc_store(struct device *dev,
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	if (!strncmp(buf, "enable", 6))
+	if (sysfs_streq(buf, "enable"))
 		xhci_dbc_start(dbc);
-	else if (!strncmp(buf, "disable", 7))
+	else if (sysfs_streq(buf, "disable"))
 		xhci_dbc_stop(dbc);
 	else
 		return -EINVAL;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/19] xhci: dbc: Use sysfs_emit() to instead of scnprintf()
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
  2023-12-01 15:06 ` [PATCH 01/19] xhci: dbc: Drop duplicate checks for dma_free_coherent() Mathias Nyman
  2023-12-01 15:06 ` [PATCH 02/19] xhci: dbc: Convert to use sysfs_streq() Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 04/19] xhci: dbc: Use ATTRIBUTE_GROUPS() Mathias Nyman
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Follow the advice of the Documentation/filesystems/sysfs.rst and show()
should only use sysfs_emit() or sysfs_emit_at() when formatting the
value to be returned to user space.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 44 +++++++++++++---------------------
 drivers/usb/host/xhci-dbgcap.h |  1 +
 2 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index f505b79afe53..df14e336370d 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -910,41 +910,29 @@ static void xhci_dbc_handle_events(struct work_struct *work)
 	mod_delayed_work(system_wq, &dbc->event_work, 1);
 }
 
+static const char * const dbc_state_strings[DS_MAX] = {
+	[DS_DISABLED] = "disabled",
+	[DS_INITIALIZED] = "initialized",
+	[DS_ENABLED] = "enabled",
+	[DS_CONNECTED] = "connected",
+	[DS_CONFIGURED] = "configured",
+	[DS_STALLED] = "stalled",
+};
+
 static ssize_t dbc_show(struct device *dev,
 			struct device_attribute *attr,
 			char *buf)
 {
-	const char		*p;
 	struct xhci_dbc		*dbc;
 	struct xhci_hcd		*xhci;
 
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	switch (dbc->state) {
-	case DS_DISABLED:
-		p = "disabled";
-		break;
-	case DS_INITIALIZED:
-		p = "initialized";
-		break;
-	case DS_ENABLED:
-		p = "enabled";
-		break;
-	case DS_CONNECTED:
-		p = "connected";
-		break;
-	case DS_CONFIGURED:
-		p = "configured";
-		break;
-	case DS_STALLED:
-		p = "stalled";
-		break;
-	default:
-		p = "unknown";
-	}
+	if (dbc->state >= ARRAY_SIZE(dbc_state_strings))
+		return sysfs_emit(buf, "unknown\n");
 
-	return sprintf(buf, "%s\n", p);
+	return sysfs_emit(buf, "%s\n", dbc_state_strings[dbc->state]);
 }
 
 static ssize_t dbc_store(struct device *dev,
@@ -977,7 +965,7 @@ static ssize_t dbc_idVendor_show(struct device *dev,
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	return sprintf(buf, "%04x\n", dbc->idVendor);
+	return sysfs_emit(buf, "%04x\n", dbc->idVendor);
 }
 
 static ssize_t dbc_idVendor_store(struct device *dev,
@@ -1017,7 +1005,7 @@ static ssize_t dbc_idProduct_show(struct device *dev,
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	return sprintf(buf, "%04x\n", dbc->idProduct);
+	return sysfs_emit(buf, "%04x\n", dbc->idProduct);
 }
 
 static ssize_t dbc_idProduct_store(struct device *dev,
@@ -1056,7 +1044,7 @@ static ssize_t dbc_bcdDevice_show(struct device *dev,
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	return sprintf(buf, "%04x\n", dbc->bcdDevice);
+	return sysfs_emit(buf, "%04x\n", dbc->bcdDevice);
 }
 
 static ssize_t dbc_bcdDevice_store(struct device *dev,
@@ -1096,7 +1084,7 @@ static ssize_t dbc_bInterfaceProtocol_show(struct device *dev,
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
 
-	return sprintf(buf, "%02x\n", dbc->bInterfaceProtocol);
+	return sysfs_emit(buf, "%02x\n", dbc->bInterfaceProtocol);
 }
 
 static ssize_t dbc_bInterfaceProtocol_store(struct device *dev,
diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h
index 51a7ab3ba0ca..e39e3ae1677a 100644
--- a/drivers/usb/host/xhci-dbgcap.h
+++ b/drivers/usb/host/xhci-dbgcap.h
@@ -82,6 +82,7 @@ enum dbc_state {
 	DS_CONNECTED,
 	DS_CONFIGURED,
 	DS_STALLED,
+	DS_MAX
 };
 
 struct dbc_ep {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/19] xhci: dbc: Use ATTRIBUTE_GROUPS()
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (2 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 03/19] xhci: dbc: Use sysfs_emit() to instead of scnprintf() Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 05/19] xhci: dbc: Check for errors first in xhci_dbc_stop() Mathias Nyman
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Embrace ATTRIBUTE_GROUPS() to avoid boiler plate code.
This should not introduce any functional changes.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index df14e336370d..660e3ee31dc6 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1123,7 +1123,7 @@ static DEVICE_ATTR_RW(dbc_idProduct);
 static DEVICE_ATTR_RW(dbc_bcdDevice);
 static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
 
-static struct attribute *dbc_dev_attributes[] = {
+static struct attribute *dbc_dev_attrs[] = {
 	&dev_attr_dbc.attr,
 	&dev_attr_dbc_idVendor.attr,
 	&dev_attr_dbc_idProduct.attr,
@@ -1131,10 +1131,7 @@ static struct attribute *dbc_dev_attributes[] = {
 	&dev_attr_dbc_bInterfaceProtocol.attr,
 	NULL
 };
-
-static const struct attribute_group dbc_dev_attrib_grp = {
-	.attrs = dbc_dev_attributes,
-};
+ATTRIBUTE_GROUPS(dbc_dev);
 
 struct xhci_dbc *
 xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *driver)
@@ -1160,7 +1157,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *
 	INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events);
 	spin_lock_init(&dbc->lock);
 
-	ret = sysfs_create_group(&dev->kobj, &dbc_dev_attrib_grp);
+	ret = sysfs_create_groups(&dev->kobj, dbc_dev_groups);
 	if (ret)
 		goto err;
 
@@ -1179,7 +1176,7 @@ void xhci_dbc_remove(struct xhci_dbc *dbc)
 	xhci_dbc_stop(dbc);
 
 	/* remove sysfs files */
-	sysfs_remove_group(&dbc->dev->kobj, &dbc_dev_attrib_grp);
+	sysfs_remove_groups(&dbc->dev->kobj, dbc_dev_groups);
 
 	kfree(dbc);
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/19] xhci: dbc: Check for errors first in xhci_dbc_stop()
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (3 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 04/19] xhci: dbc: Use ATTRIBUTE_GROUPS() Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 06/19] xhci: dbc: Don't shadow error codes in store() functions Mathias Nyman
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

The usual pattern is to check for errors and then continue if none.
Apply that pattern to xhci_dbc_stop() code.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 660e3ee31dc6..6b9f4b839270 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -646,11 +646,11 @@ static void xhci_dbc_stop(struct xhci_dbc *dbc)
 	spin_lock_irqsave(&dbc->lock, flags);
 	ret = xhci_do_dbc_stop(dbc);
 	spin_unlock_irqrestore(&dbc->lock, flags);
+	if (ret)
+		return;
 
-	if (!ret) {
-		xhci_dbc_mem_cleanup(dbc);
-		pm_runtime_put_sync(dbc->dev); /* note, was self.controller */
-	}
+	xhci_dbc_mem_cleanup(dbc);
+	pm_runtime_put_sync(dbc->dev); /* note, was self.controller */
 }
 
 static void
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/19] xhci: dbc: Don't shadow error codes in store() functions
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (4 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 05/19] xhci: dbc: Check for errors first in xhci_dbc_stop() Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 07/19] xhci: dbc: Replace custom return value with proper Linux error code Mathias Nyman
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

kstrtox() along with regmap API can return different error codes
based on the circumstances. Don't shadow them when returning to
the caller.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 6b9f4b839270..c211c69e8041 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -977,9 +977,11 @@ static ssize_t dbc_idVendor_store(struct device *dev,
 	void __iomem		*ptr;
 	u16			value;
 	u32			dev_info;
+	int ret;
 
-	if (kstrtou16(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtou16(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
@@ -1017,9 +1019,11 @@ static ssize_t dbc_idProduct_store(struct device *dev,
 	void __iomem		*ptr;
 	u32			dev_info;
 	u16			value;
+	int ret;
 
-	if (kstrtou16(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtou16(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
@@ -1056,9 +1060,11 @@ static ssize_t dbc_bcdDevice_store(struct device *dev,
 	void __iomem *ptr;
 	u32 dev_info;
 	u16 value;
+	int ret;
 
-	if (kstrtou16(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtou16(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
 	dbc = xhci->dbc;
@@ -1098,9 +1104,13 @@ static ssize_t dbc_bInterfaceProtocol_store(struct device *dev,
 	u8 value;
 	int ret;
 
-	/* bInterfaceProtocol is 8 bit, but xhci only supports values 0 and 1 */
+	/* bInterfaceProtocol is 8 bit, but... */
 	ret = kstrtou8(buf, 0, &value);
-	if (ret || value > 1)
+	if (ret)
+		return ret;
+
+	/* ...xhci only supports values 0 and 1 */
+	if (value > 1)
 		return -EINVAL;
 
 	xhci = hcd_to_xhci(dev_get_drvdata(dev));
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/19] xhci: dbc: Replace custom return value with proper Linux error code
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (5 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 06/19] xhci: dbc: Don't shadow error codes in store() functions Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense Mathias Nyman
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Replace the custom return value with proper Linux error code.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index c211c69e8041..779a564ad698 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -593,7 +593,7 @@ static int xhci_do_dbc_start(struct xhci_dbc *dbc)
 static int xhci_do_dbc_stop(struct xhci_dbc *dbc)
 {
 	if (dbc->state == DS_DISABLED)
-		return -1;
+		return -EINVAL;
 
 	writel(0, &dbc->regs->control);
 	dbc->state = DS_DISABLED;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (6 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 07/19] xhci: dbc: Replace custom return value with proper Linux error code Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 17:31   ` David Laight
  2023-12-01 15:06 ` [PATCH 09/19] xhci: dbc: Use sizeof(*pointer) instead of sizeof(type) Mathias Nyman
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Instead of doing custom calculations, use sizeof_field() macro.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 779a564ad698..0c9fd61e9c5b 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -374,7 +374,7 @@ static void xhci_dbc_eps_init(struct xhci_dbc *dbc)
 
 static void xhci_dbc_eps_exit(struct xhci_dbc *dbc)
 {
-	memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
+	memset(dbc->eps, 0, sizeof_field(struct xhci_dbc, eps));
 }
 
 static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/19] xhci: dbc: Use sizeof(*pointer) instead of sizeof(type)
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (7 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 10/19] xhci: dbc: Add missing headers Mathias Nyman
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

It is preferred to use sizeof(*pointer) instead of sizeof(type).
The type of the variable can change and one needs not change
the former (unlike the latter). No functional change intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 0c9fd61e9c5b..73494d55b0be 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -380,7 +380,7 @@ static void xhci_dbc_eps_exit(struct xhci_dbc *dbc)
 static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
 		    struct xhci_erst *erst, gfp_t flags)
 {
-	erst->entries = dma_alloc_coherent(dev, sizeof(struct xhci_erst_entry),
+	erst->entries = dma_alloc_coherent(dev, sizeof(*erst->entries),
 					   &erst->erst_dma_addr, flags);
 	if (!erst->entries)
 		return -ENOMEM;
@@ -394,7 +394,7 @@ static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
 
 static void dbc_erst_free(struct device *dev, struct xhci_erst *erst)
 {
-	dma_free_coherent(dev, sizeof(struct xhci_erst_entry), erst->entries,
+	dma_free_coherent(dev, sizeof(*erst->entries), erst->entries,
 			  erst->erst_dma_addr);
 	erst->entries = NULL;
 }
@@ -494,7 +494,7 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
 		goto ctx_fail;
 
 	/* Allocate the string table: */
-	dbc->string_size = sizeof(struct dbc_str_descs);
+	dbc->string_size = sizeof(*dbc->string);
 	dbc->string = dma_alloc_coherent(dev, dbc->string_size,
 					 &dbc->string_dma, flags);
 	if (!dbc->string)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/19] xhci: dbc: Add missing headers
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (8 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 09/19] xhci: dbc: Use sizeof(*pointer) instead of sizeof(type) Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 11/19] xhci: check if legacy irq is available before using it as fallback Mathias Nyman
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Andy Shevchenko, Mathias Nyman

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Don't inherit headers "by chances" from asm/bug.h, asm/io.h,
etc... Include the needed headers explicitly.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-dbgcap.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 73494d55b0be..d82935d31126 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -6,9 +6,24 @@
  *
  * Author: Lu Baolu <baolu.lu@linux.intel.com>
  */
+#include <linux/bug.h>
+#include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/kstrtox.h>
+#include <linux/list.h>
 #include <linux/nls.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include <linux/io-64-nonatomic-lo-hi.h>
+
+#include <asm/byteorder.h>
 
 #include "xhci.h"
 #include "xhci-trace.h"
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 11/19] xhci: check if legacy irq is available before using it as fallback
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (9 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 10/19] xhci: dbc: Add missing headers Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 12/19] xhci: add handler for only one interrupt line Mathias Nyman
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

Move the error check "No MSI-X/MSI found and no IRQ in BIOS" inside
'goto legacy'. It is better to check if the IRQ interrupt is available,
before trying to add a handler. Additionally the aforementioned error
message is much more clear.

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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 95ed9404f6f8..7f2b1312e943 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -228,12 +228,12 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 		return 0;
 	}
 
+legacy_irq:
 	if (!pdev->irq) {
 		xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
 		return -EINVAL;
 	}
 
- legacy_irq:
 	if (!strlen(hcd->irq_descr))
 		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
 			 hcd->driver->description, hcd->self.busnum);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 12/19] xhci: add handler for only one interrupt line
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (10 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 11/19] xhci: check if legacy irq is available before using it as fallback Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 13/19] xhci: refactor static MSI-X function Mathias Nyman
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

Current xHCI driver only supports one "interrupter", meaning we will
only use one MSI/MSI-X interrupt line. Thus, add handler only to the
first interrupt line.

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Co-developed-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-pci.c | 35 ++++++++++-------------------------
 1 file changed, 10 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 7f2b1312e943..59bbae69f97c 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -95,10 +95,9 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)
 
 	if (hcd->msix_enabled) {
 		struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
-		int i;
 
-		for (i = 0; i < xhci->msix_count; i++)
-			synchronize_irq(pci_irq_vector(pdev, i));
+		/* for now, the driver only supports one primary interrupter */
+		synchronize_irq(pci_irq_vector(pdev, 0));
 	}
 }
 
@@ -112,15 +111,7 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 	if (hcd->irq > 0)
 		return;
 
-	if (hcd->msix_enabled) {
-		int i;
-
-		for (i = 0; i < xhci->msix_count; i++)
-			free_irq(pci_irq_vector(pdev, i), xhci_to_hcd(xhci));
-	} else {
-		free_irq(pci_irq_vector(pdev, 0), xhci_to_hcd(xhci));
-	}
-
+	free_irq(pci_irq_vector(pdev, 0), xhci_to_hcd(xhci));
 	pci_free_irq_vectors(pdev);
 	hcd->msix_enabled = 0;
 }
@@ -159,9 +150,9 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
  */
 static int xhci_setup_msix(struct xhci_hcd *xhci)
 {
-	int i, ret;
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
 	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	int ret;
 
 	/*
 	 * calculate number of msi-x vectors supported.
@@ -181,22 +172,16 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 		return ret;
 	}
 
-	for (i = 0; i < xhci->msix_count; i++) {
-		ret = request_irq(pci_irq_vector(pdev, i), xhci_msi_irq, 0,
-				"xhci_hcd", xhci_to_hcd(xhci));
-		if (ret)
-			goto disable_msix;
+	ret = request_irq(pci_irq_vector(pdev, 0), xhci_msi_irq, 0, "xhci_hcd",
+			  xhci_to_hcd(xhci));
+	if (ret) {
+		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI-X interrupt");
+		pci_free_irq_vectors(pdev);
+		return ret;
 	}
 
 	hcd->msix_enabled = 1;
 	return ret;
-
-disable_msix:
-	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI-X interrupt");
-	while (--i >= 0)
-		free_irq(pci_irq_vector(pdev, i), xhci_to_hcd(xhci));
-	pci_free_irq_vectors(pdev);
-	return ret;
 }
 
 static int xhci_try_enable_msi(struct usb_hcd *hcd)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 13/19] xhci: refactor static MSI-X function
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (11 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 12/19] xhci: add handler for only one interrupt line Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 14/19] xhci: refactor static MSI function Mathias Nyman
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

The current way the xhci driver sets up MSI/MSI-X interrupts is overly
complex and messy. The whole MSI/MSI-X setup can be done in one simple
function.

Start refactoring this by incorporating 'xhci_setup_msix()' into
'xhci_try_enable_msi()'. 'xhci_setup_msix()' is a static function which
is only called by 'xhci_try_enable_msi()'.

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 | 68 +++++++++++++++----------------------
 1 file changed, 28 insertions(+), 40 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 59bbae69f97c..370943c04881 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -145,31 +145,40 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
 	return ret;
 }
 
-/*
- * Set up MSI-X
- */
-static int xhci_setup_msix(struct xhci_hcd *xhci)
+static int xhci_try_enable_msi(struct usb_hcd *hcd)
 {
-	struct usb_hcd *hcd = xhci_to_hcd(xhci);
-	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct pci_dev  *pdev;
 	int ret;
 
+	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
 	/*
-	 * calculate number of msi-x vectors supported.
+	 * Some Fresco Logic host controllers advertise MSI, but fail to
+	 * generate interrupts.  Don't even try to enable MSI.
+	 */
+	if (xhci->quirks & XHCI_BROKEN_MSI)
+		goto legacy_irq;
+
+	/* unregister the legacy interrupt */
+	if (hcd->irq)
+		free_irq(hcd->irq, hcd);
+	hcd->irq = 0;
+
+	/*
+	 * calculate number of MSI-X vectors supported.
 	 * - HCS_MAX_INTRS: the max number of interrupts the host can handle,
 	 *   with max number of interrupters based on the xhci HCSPARAMS1.
-	 * - num_online_cpus: maximum msi-x vectors per CPUs core.
+	 * - num_online_cpus: maximum MSI-X vectors per CPUs core.
 	 *   Add additional 1 vector to ensure always available interrupt.
 	 */
 	xhci->msix_count = min(num_online_cpus() + 1,
-				HCS_MAX_INTRS(xhci->hcs_params1));
+			       HCS_MAX_INTRS(xhci->hcs_params1));
 
 	ret = pci_alloc_irq_vectors(pdev, xhci->msix_count, xhci->msix_count,
-			PCI_IRQ_MSIX);
+				    PCI_IRQ_MSIX);
 	if (ret < 0) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-				"Failed to enable MSI-X");
-		return ret;
+		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Failed to enable MSI-X");
+		goto setup_msi;
 	}
 
 	ret = request_irq(pci_irq_vector(pdev, 0), xhci_msi_irq, 0, "xhci_hcd",
@@ -177,37 +186,16 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
 	if (ret) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI-X interrupt");
 		pci_free_irq_vectors(pdev);
-		return ret;
+		goto setup_msi;
 	}
 
+	hcd->msi_enabled = 1;
 	hcd->msix_enabled = 1;
-	return ret;
-}
-
-static int xhci_try_enable_msi(struct usb_hcd *hcd)
-{
-	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct pci_dev  *pdev;
-	int ret;
-
-	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-	/*
-	 * Some Fresco Logic host controllers advertise MSI, but fail to
-	 * generate interrupts.  Don't even try to enable MSI.
-	 */
-	if (xhci->quirks & XHCI_BROKEN_MSI)
-		goto legacy_irq;
-
-	/* unregister the legacy interrupt */
-	if (hcd->irq)
-		free_irq(hcd->irq, hcd);
-	hcd->irq = 0;
-
-	ret = xhci_setup_msix(xhci);
-	if (ret)
-		/* fall back to msi*/
-		ret = xhci_setup_msi(xhci);
+	return 0;
 
+setup_msi:
+	/* fall back to MSI */
+	ret = xhci_setup_msi(xhci);
 	if (!ret) {
 		hcd->msi_enabled = 1;
 		return 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 14/19] xhci: refactor static MSI function
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (12 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 13/19] xhci: refactor static MSI-X function Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 15/19] xhci: change 'msix_count' to encompass MSI or MSI-X vectors Mathias Nyman
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

The current way the xhci driver sets up MSI interrupts is overly complex
and messy. The whole MSI setup can be done in one simple function.

Continue refactoring MSI/MSI-X setup by incorporating 'xhci_setup_msi()'
into 'xhci_try_enable_msi()'. Now all interrupt enabling is contained in
one function, which should make it easier to 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-pci.c | 49 ++++++++++++-------------------------
 1 file changed, 15 insertions(+), 34 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 370943c04881..dbec0a315566 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -116,35 +116,6 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 	hcd->msix_enabled = 0;
 }
 
-/*
- * Set up MSI
- */
-static int xhci_setup_msi(struct xhci_hcd *xhci)
-{
-	int ret;
-	/*
-	 * TODO:Check with MSI Soc for sysdev
-	 */
-	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
-
-	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
-	if (ret < 0) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-				"failed to allocate MSI entry");
-		return ret;
-	}
-
-	ret = request_irq(pdev->irq, xhci_msi_irq,
-				0, "xhci_hcd", xhci_to_hcd(xhci));
-	if (ret) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-				"disable MSI interrupt");
-		pci_free_irq_vectors(pdev);
-	}
-
-	return ret;
-}
-
 static int xhci_try_enable_msi(struct usb_hcd *hcd)
 {
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -194,13 +165,23 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 	return 0;
 
 setup_msi:
-	/* fall back to MSI */
-	ret = xhci_setup_msi(xhci);
-	if (!ret) {
-		hcd->msi_enabled = 1;
-		return 0;
+	/* TODO: Check with MSI Soc for sysdev */
+	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+	if (ret < 0) {
+		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "failed to allocate MSI entry");
+		goto legacy_irq;
 	}
 
+	ret = request_irq(pdev->irq, xhci_msi_irq, 0, "xhci_hcd", xhci_to_hcd(xhci));
+	if (ret) {
+		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI interrupt");
+		pci_free_irq_vectors(pdev);
+		goto legacy_irq;
+	}
+
+	hcd->msi_enabled = 1;
+	return 0;
+
 legacy_irq:
 	if (!pdev->irq) {
 		xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 15/19] xhci: change 'msix_count' to encompass MSI or MSI-X vectors
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (13 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 14/19] xhci: refactor static MSI function Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 16/19] xhci: rework 'xhci_try_enable_msi()' MSI and MSI-X setup code Mathias Nyman
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

Instead of variable 'msix_count' containing the number of MSI-X vectors,
now it can contains MSI or MSI-X vector amount. Because both interrupt
methods allow several vectors. Thus, 'msix_count' is renamed to 'nvecs'.

Additionally, instead of storing the maximum possible vector amount,
now it stores the amount of successfully allocated vectors, or negative
integer on allocation failure.

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 | 14 +++++++-------
 drivers/usb/host/xhci.h     |  4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index dbec0a315566..2307164a1e81 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -142,12 +142,12 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 	 * - num_online_cpus: maximum MSI-X vectors per CPUs core.
 	 *   Add additional 1 vector to ensure always available interrupt.
 	 */
-	xhci->msix_count = min(num_online_cpus() + 1,
-			       HCS_MAX_INTRS(xhci->hcs_params1));
+	xhci->nvecs = min(num_online_cpus() + 1,
+			  HCS_MAX_INTRS(xhci->hcs_params1));
 
-	ret = pci_alloc_irq_vectors(pdev, xhci->msix_count, xhci->msix_count,
-				    PCI_IRQ_MSIX);
-	if (ret < 0) {
+	xhci->nvecs = pci_alloc_irq_vectors(pdev, xhci->nvecs, xhci->nvecs,
+					    PCI_IRQ_MSIX);
+	if (xhci->nvecs < 0) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Failed to enable MSI-X");
 		goto setup_msi;
 	}
@@ -166,8 +166,8 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 
 setup_msi:
 	/* TODO: Check with MSI Soc for sysdev */
-	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
-	if (ret < 0) {
+	xhci->nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+	if (xhci->nvecs < 0) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "failed to allocate MSI entry");
 		goto legacy_irq;
 	}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3ea5c092bba7..b166f47e379f 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1760,8 +1760,8 @@ struct xhci_hcd {
 	int		page_size;
 	/* Valid values are 12 to 20, inclusive */
 	int		page_shift;
-	/* msi-x vectors */
-	int		msix_count;
+	/* MSI-X/MSI vectors */
+	int		nvecs;
 	/* optional clocks */
 	struct clk		*clk;
 	struct clk		*reg_clk;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 16/19] xhci: rework 'xhci_try_enable_msi()' MSI and MSI-X setup code
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (14 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 15/19] xhci: change 'msix_count' to encompass MSI or MSI-X vectors Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 17/19] xhci: minor coding style cleanup in 'xhci_try_enable_msi()' Mathias Nyman
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

Simplify 'xhci_try_enable_msi()' and reduce unnecessary function calls.

xHCI driver first tries to allocate 'num_online_cpu()' number of MSI-X
vectors, if that fails it falls back to a single MSI vector. There is no
good reason for this, we currently only support a primary interrupter.
However, we are still interested in knowing if there are more vectors
available, which will be utilized once we get secondary interrupter
support.

Call 'pci_alloc_irq_vectors()' once (with MSI-X and MSI flag), instead
of separately for MSI-X and MSI. And accept any number of MSI-X or MSI
vectors between 1 and 'num_online_cpu()'.

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 | 44 +++++++++++++------------------------
 1 file changed, 15 insertions(+), 29 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 2307164a1e81..398f81b0500b 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -116,13 +116,13 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 	hcd->msix_enabled = 0;
 }
 
+/* Try enabling MSI-X with MSI and legacy IRQ as fallback */
 static int xhci_try_enable_msi(struct usb_hcd *hcd)
 {
+	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct pci_dev  *pdev;
 	int ret;
 
-	pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
 	/*
 	 * Some Fresco Logic host controllers advertise MSI, but fail to
 	 * generate interrupts.  Don't even try to enable MSI.
@@ -145,42 +145,28 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 	xhci->nvecs = min(num_online_cpus() + 1,
 			  HCS_MAX_INTRS(xhci->hcs_params1));
 
-	xhci->nvecs = pci_alloc_irq_vectors(pdev, xhci->nvecs, xhci->nvecs,
-					    PCI_IRQ_MSIX);
+	/* TODO: Check with MSI Soc for sysdev */
+	xhci->nvecs = pci_alloc_irq_vectors(pdev, 1, xhci->nvecs,
+					    PCI_IRQ_MSIX | PCI_IRQ_MSI);
 	if (xhci->nvecs < 0) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Failed to enable MSI-X");
-		goto setup_msi;
+		xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+			       "failed to allocate IRQ vectors");
+		goto legacy_irq;
 	}
 
 	ret = request_irq(pci_irq_vector(pdev, 0), xhci_msi_irq, 0, "xhci_hcd",
 			  xhci_to_hcd(xhci));
-	if (ret) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI-X interrupt");
-		pci_free_irq_vectors(pdev);
-		goto setup_msi;
-	}
+	if (ret)
+		goto free_irq_vectors;
 
 	hcd->msi_enabled = 1;
-	hcd->msix_enabled = 1;
+	hcd->msix_enabled = pdev->msix_enabled;
 	return 0;
 
-setup_msi:
-	/* TODO: Check with MSI Soc for sysdev */
-	xhci->nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
-	if (xhci->nvecs < 0) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "failed to allocate MSI entry");
-		goto legacy_irq;
-	}
-
-	ret = request_irq(pdev->irq, xhci_msi_irq, 0, "xhci_hcd", xhci_to_hcd(xhci));
-	if (ret) {
-		xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable MSI interrupt");
-		pci_free_irq_vectors(pdev);
-		goto legacy_irq;
-	}
-
-	hcd->msi_enabled = 1;
-	return 0;
+free_irq_vectors:
+	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "disable %s interrupt",
+		       pdev->msix_enabled ? "MSI-X" : "MSI");
+	pci_free_irq_vectors(pdev);
 
 legacy_irq:
 	if (!pdev->irq) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 17/19] xhci: minor coding style cleanup in 'xhci_try_enable_msi()'
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (15 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 16/19] xhci: rework 'xhci_try_enable_msi()' MSI and MSI-X setup code Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 18/19] xhci: Reconfigure endpoint 0 max packet size only during endpoint reset Mathias Nyman
  2023-12-01 15:06 ` [PATCH 19/19] xhci: fix possible null pointer deref during xhci urb enqueue Mathias Nyman
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Niklas Neronin, Mathias Nyman

From: Niklas Neronin <niklas.neronin@linux.intel.com>

Remove extra spaces/indentation and add spaces where required.
This commit does not change any functionality.

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 | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 398f81b0500b..dfeca3cbac8b 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -178,12 +178,10 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
 			 hcd->driver->description, hcd->self.busnum);
 
-	/* fall back to legacy interrupt*/
-	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
-			hcd->irq_descr, hcd);
+	/* fall back to legacy interrupt */
+	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd);
 	if (ret) {
-		xhci_err(xhci, "request interrupt %d failed\n",
-				pdev->irq);
+		xhci_err(xhci, "request interrupt %d failed\n", pdev->irq);
 		return ret;
 	}
 	hcd->irq = pdev->irq;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 18/19] xhci: Reconfigure endpoint 0 max packet size only during endpoint reset
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (16 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 17/19] xhci: minor coding style cleanup in 'xhci_try_enable_msi()' Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  2023-12-01 15:06 ` [PATCH 19/19] xhci: fix possible null pointer deref during xhci urb enqueue Mathias Nyman
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman

The max packet size for full speed control endpoint 0 may vary. It is
defined in the device descriptor, which is read using the same endpoint.
Usb core sets a temporary max packet size value until the real value is
read.

xhci driver needs to reconfigure the endpoint context seen by the
controller if the max packet size changes.
It makes more sense to do this reconfiguration in xhci_endpoint_reset()
instead of urb enqueue as usb core will call endpoint reset during
enumeration if the max packet values differ.
Max packet size adjustment for endpoint 0 can only happen once per
device enumeration.

Previously the max packet size was checked during every urb enqueue.
This is an additional check for every enqueued urb, and also turned out
to have locking issues as urbs may be queued in any context while xhci
max packet size reconfiguration requires memory allocation, locking, and
sleeping.

Tested with a full speed device using both old and new scheme enumeration
and an intentionally incorrect preliminary max packet size value.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---

Change since RFT patch:
  Fix typos in commit message pointed out by Kuen-Han Tsai

 drivers/usb/host/xhci.c | 85 ++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 43 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 884b0898d9c9..df31d44498d6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1438,10 +1438,8 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
  * descriptor.  If the usb_device's max packet size changes after that point,
  * we need to issue an evaluate context command and wait on it.
  */
-static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
-		unsigned int ep_index, struct urb *urb, gfp_t mem_flags)
+static int xhci_check_ep0_maxpacket(struct xhci_hcd *xhci, struct xhci_virt_device *vdev)
 {
-	struct xhci_container_ctx *out_ctx;
 	struct xhci_input_control_ctx *ctrl_ctx;
 	struct xhci_ep_ctx *ep_ctx;
 	struct xhci_command *command;
@@ -1449,11 +1447,15 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
 	int hw_max_packet_size;
 	int ret = 0;
 
-	out_ctx = xhci->devs[slot_id]->out_ctx;
-	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+	ep_ctx = xhci_get_ep_ctx(xhci, vdev->out_ctx, 0);
 	hw_max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
-	max_packet_size = usb_endpoint_maxp(&urb->dev->ep0.desc);
-	if (hw_max_packet_size != max_packet_size) {
+	max_packet_size = usb_endpoint_maxp(&vdev->udev->ep0.desc);
+
+	if (hw_max_packet_size == max_packet_size)
+		return 0;
+
+	switch (max_packet_size) {
+	case 8: case 16: case 32: case 64: case 9:
 		xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
 				"Max Packet Size for ep 0 changed.");
 		xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
@@ -1465,28 +1467,22 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
 		xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change,
 				"Issuing evaluate context command.");
 
-		/* Set up the input context flags for the command */
-		/* FIXME: This won't work if a non-default control endpoint
-		 * changes max packet sizes.
-		 */
-
-		command = xhci_alloc_command(xhci, true, mem_flags);
+		command = xhci_alloc_command(xhci, true, GFP_KERNEL);
 		if (!command)
 			return -ENOMEM;
 
-		command->in_ctx = xhci->devs[slot_id]->in_ctx;
+		command->in_ctx = vdev->in_ctx;
 		ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
 		if (!ctrl_ctx) {
 			xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
 					__func__);
 			ret = -ENOMEM;
-			goto command_cleanup;
+			break;
 		}
 		/* Set up the modified control endpoint 0 */
-		xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,
-				xhci->devs[slot_id]->out_ctx, ep_index);
+		xhci_endpoint_copy(xhci, vdev->in_ctx, vdev->out_ctx, 0);
 
-		ep_ctx = xhci_get_ep_ctx(xhci, command->in_ctx, ep_index);
+		ep_ctx = xhci_get_ep_ctx(xhci, command->in_ctx, 0);
 		ep_ctx->ep_info &= cpu_to_le32(~EP_STATE_MASK);/* must clear */
 		ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET_MASK);
 		ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size));
@@ -1494,17 +1490,20 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
 		ctrl_ctx->add_flags = cpu_to_le32(EP0_FLAG);
 		ctrl_ctx->drop_flags = 0;
 
-		ret = xhci_configure_endpoint(xhci, urb->dev, command,
-				true, false);
-
-		/* Clean up the input context for later use by bandwidth
-		 * functions.
-		 */
+		ret = xhci_configure_endpoint(xhci, vdev->udev, command,
+					      true, false);
+		/* Clean up the input context for later use by bandwidth functions */
 		ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
-command_cleanup:
-		kfree(command->completion);
-		kfree(command);
+		break;
+	default:
+		dev_dbg(&vdev->udev->dev, "incorrect max packet size %d for ep0\n",
+			max_packet_size);
+		return -EINVAL;
 	}
+
+	kfree(command->completion);
+	kfree(command);
+
 	return ret;
 }
 
@@ -1561,21 +1560,6 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
 
 	trace_xhci_urb_enqueue(urb);
 
-	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
-		/* Check to see if the max packet size for the default control
-		 * endpoint changed during FS device enumeration
-		 */
-		if (urb->dev->speed == USB_SPEED_FULL) {
-			ret = xhci_check_maxpacket(xhci, slot_id,
-					ep_index, urb, mem_flags);
-			if (ret < 0) {
-				xhci_urb_free_priv(urb_priv);
-				urb->hcpriv = NULL;
-				return ret;
-			}
-		}
-	}
-
 	spin_lock_irqsave(&xhci->lock, flags);
 
 	if (xhci->xhc_state & XHCI_STATE_DYING) {
@@ -3104,6 +3088,21 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 	int err;
 
 	xhci = hcd_to_xhci(hcd);
+	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+
+	/*
+	 * Usb core assumes a max packet value for ep0 on FS devices until the
+	 * real value is read from the descriptor. Core resets Ep0 if values
+	 * mismatch. Reconfigure the xhci ep0 endpoint context here in that case
+	 */
+	if (usb_endpoint_xfer_control(&host_ep->desc) && ep_index == 0) {
+		udev = container_of(host_ep, struct usb_device, ep0);
+		if (udev->speed == USB_SPEED_FULL)
+			xhci_check_ep0_maxpacket(xhci, xhci->devs[udev->slot_id]);
+		/* Nothing else should be done here for ep0 during ep reset */
+		return;
+	}
+
 	if (!host_ep->hcpriv)
 		return;
 	udev = (struct usb_device *) host_ep->hcpriv;
@@ -3116,7 +3115,7 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
 	 */
 	if (!udev->slot_id || !vdev)
 		return;
-	ep_index = xhci_get_endpoint_index(&host_ep->desc);
+
 	ep = &vdev->eps[ep_index];
 
 	/* Bail out if toggle is already being cleared by a endpoint reset */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 19/19] xhci: fix possible null pointer deref during xhci urb enqueue
  2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
                   ` (17 preceding siblings ...)
  2023-12-01 15:06 ` [PATCH 18/19] xhci: Reconfigure endpoint 0 max packet size only during endpoint reset Mathias Nyman
@ 2023-12-01 15:06 ` Mathias Nyman
  18 siblings, 0 replies; 25+ messages in thread
From: Mathias Nyman @ 2023-12-01 15:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman, Kuen-Han Tsai

There is a short gap between urb being submitted and actually added to the
endpoint queue (linked). If the device is disconnected during this time
then usb core is not yet aware of the pending urb, and device may be freed
just before xhci_urq_enqueue() continues, dereferencing the freed device.

Freeing the device is protected by the xhci spinlock, so make sure we take
and keep the lock while checking that device exists, dereference it, and
add the urb to the queue.

Remove the unnecessary URB check, usb core checks it before calling
xhci_urb_enqueue()

Suggested-by: Kuen-Han Tsai <khtsai@google.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci.c | 40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index df31d44498d6..4929c4396e9e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1521,24 +1521,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
 	struct urb_priv	*urb_priv;
 	int num_tds;
 
-	if (!urb)
-		return -EINVAL;
-	ret = xhci_check_args(hcd, urb->dev, urb->ep,
-					true, true, __func__);
-	if (ret <= 0)
-		return ret ? ret : -EINVAL;
-
-	slot_id = urb->dev->slot_id;
 	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-	ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state;
-
-	if (!HCD_HW_ACCESSIBLE(hcd))
-		return -ESHUTDOWN;
-
-	if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) {
-		xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n");
-		return -ENODEV;
-	}
 
 	if (usb_endpoint_xfer_isoc(&urb->ep->desc))
 		num_tds = urb->number_of_packets;
@@ -1562,12 +1545,35 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
 
 	spin_lock_irqsave(&xhci->lock, flags);
 
+	ret = xhci_check_args(hcd, urb->dev, urb->ep,
+			      true, true, __func__);
+	if (ret <= 0) {
+		ret = ret ? ret : -EINVAL;
+		goto free_priv;
+	}
+
+	slot_id = urb->dev->slot_id;
+
+	if (!HCD_HW_ACCESSIBLE(hcd)) {
+		ret = -ESHUTDOWN;
+		goto free_priv;
+	}
+
+	if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) {
+		xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n");
+		ret = -ENODEV;
+		goto free_priv;
+	}
+
 	if (xhci->xhc_state & XHCI_STATE_DYING) {
 		xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for non-responsive xHCI host.\n",
 			 urb->ep->desc.bEndpointAddress, urb);
 		ret = -ESHUTDOWN;
 		goto free_priv;
 	}
+
+	ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state;
+
 	if (*ep_state & (EP_GETTING_STREAMS | EP_GETTING_NO_STREAMS)) {
 		xhci_warn(xhci, "WARN: Can't enqueue URB, ep in streams transition state %x\n",
 			  *ep_state);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* RE: [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-01 15:06 ` [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense Mathias Nyman
@ 2023-12-01 17:31   ` David Laight
  2023-12-01 19:08     ` Andy Shevchenko
  0 siblings, 1 reply; 25+ messages in thread
From: David Laight @ 2023-12-01 17:31 UTC (permalink / raw)
  To: 'Mathias Nyman', gregkh@linuxfoundation.org
  Cc: linux-usb@vger.kernel.org, Andy Shevchenko

From: Mathias Nyman
> Sent: 01 December 2023 15:07
> 
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> 
> Instead of doing custom calculations, use sizeof_field() macro.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
>  drivers/usb/host/xhci-dbgcap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
> index 779a564ad698..0c9fd61e9c5b 100644
> --- a/drivers/usb/host/xhci-dbgcap.c
> +++ b/drivers/usb/host/xhci-dbgcap.c
> @@ -374,7 +374,7 @@ static void xhci_dbc_eps_init(struct xhci_dbc *dbc)
> 
>  static void xhci_dbc_eps_exit(struct xhci_dbc *dbc)
>  {
> -	memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
> +	memset(dbc->eps, 0, sizeof_field(struct xhci_dbc, eps));

Isn't that just:
	memset(dpc->eps, 0, sizeof (dpc->eps));
perhaps better written as:
	memset(&dpc->epc, 0, sizeof (dpc->eps);

Otherwise the existing code wouldn't make sense at all.

	David

>  }
> 
>  static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
> --
> 2.25.1
> 

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-01 17:31   ` David Laight
@ 2023-12-01 19:08     ` Andy Shevchenko
  2023-12-02 15:50       ` David Laight
  0 siblings, 1 reply; 25+ messages in thread
From: Andy Shevchenko @ 2023-12-01 19:08 UTC (permalink / raw)
  To: David Laight
  Cc: 'Mathias Nyman', gregkh@linuxfoundation.org,
	linux-usb@vger.kernel.org

On Fri, Dec 01, 2023 at 05:31:52PM +0000, David Laight wrote:
> From: Mathias Nyman
> > Sent: 01 December 2023 15:07

...

> > -	memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
> > +	memset(dbc->eps, 0, sizeof_field(struct xhci_dbc, eps));
> 
> Isn't that just:
> 	memset(dpc->eps, 0, sizeof (dpc->eps));
> perhaps better written as:
> 	memset(&dpc->epc, 0, sizeof (dpc->eps);

Maybe...
You can send a patch, so it gets tested for regressions!

> Otherwise the existing code wouldn't make sense at all.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-01 19:08     ` Andy Shevchenko
@ 2023-12-02 15:50       ` David Laight
  2023-12-04 10:23         ` Mathias Nyman
  0 siblings, 1 reply; 25+ messages in thread
From: David Laight @ 2023-12-02 15:50 UTC (permalink / raw)
  To: 'Andy Shevchenko'
  Cc: 'Mathias Nyman', gregkh@linuxfoundation.org,
	linux-usb@vger.kernel.org

From: Andy Shevchenko
> Sent: 01 December 2023 19:08
> 
> On Fri, Dec 01, 2023 at 05:31:52PM +0000, David Laight wrote:
> > From: Mathias Nyman
> > > Sent: 01 December 2023 15:07
> 
> ...
> 
> > > -	memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
> > > +	memset(dbc->eps, 0, sizeof_field(struct xhci_dbc, eps));
> >
> > Isn't that just:
> > 	memset(dpc->eps, 0, sizeof (dpc->eps));
> > perhaps better written as:
> > 	memset(&dpc->epc, 0, sizeof (dpc->eps);
> 
> Maybe...
> You can send a patch, so it gets tested for regressions!

Any patch I write will conflict with v2 of this series.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-02 15:50       ` David Laight
@ 2023-12-04 10:23         ` Mathias Nyman
  2023-12-04 10:45           ` David Laight
  0 siblings, 1 reply; 25+ messages in thread
From: Mathias Nyman @ 2023-12-04 10:23 UTC (permalink / raw)
  To: David Laight, 'Andy Shevchenko'
  Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org

On 2.12.2023 17.50, David Laight wrote:
> From: Andy Shevchenko
>> Sent: 01 December 2023 19:08
>>
>> On Fri, Dec 01, 2023 at 05:31:52PM +0000, David Laight wrote:
>>> From: Mathias Nyman
>>>> Sent: 01 December 2023 15:07
>>
>> ...
>>
>>>> -	memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
>>>> +	memset(dbc->eps, 0, sizeof_field(struct xhci_dbc, eps));
>>>
>>> Isn't that just:
>>> 	memset(dpc->eps, 0, sizeof (dpc->eps));
>>> perhaps better written as:
>>> 	memset(&dpc->epc, 0, sizeof (dpc->eps);
>>
>> Maybe...
>> You can send a patch, so it gets tested for regressions!
> 
> Any patch I write will conflict with v2 of this series.
> 

I'll drop this 8/19 patch as it's just a one liner cleanup that does no
harm, but apparently doesn't really help either.

David, I'll be happy to take a patch for this from you, but still need to
run it through some testing

I'll send v2 of this series

Thanks
Mathias

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense
  2023-12-04 10:23         ` Mathias Nyman
@ 2023-12-04 10:45           ` David Laight
  0 siblings, 0 replies; 25+ messages in thread
From: David Laight @ 2023-12-04 10:45 UTC (permalink / raw)
  To: 'Mathias Nyman', 'Andy Shevchenko'
  Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org

> I'll drop this 8/19 patch as it's just a one liner cleanup that does no
> harm, but apparently doesn't really help either.
> 
> David, I'll be happy to take a patch for this from you, but still need to
> run it through some testing

I'd just run objdump to check the constant is the same.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2023-12-04 10:45 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-01 15:06 [PATCH 00/19] xhci features for usb-next Mathias Nyman
2023-12-01 15:06 ` [PATCH 01/19] xhci: dbc: Drop duplicate checks for dma_free_coherent() Mathias Nyman
2023-12-01 15:06 ` [PATCH 02/19] xhci: dbc: Convert to use sysfs_streq() Mathias Nyman
2023-12-01 15:06 ` [PATCH 03/19] xhci: dbc: Use sysfs_emit() to instead of scnprintf() Mathias Nyman
2023-12-01 15:06 ` [PATCH 04/19] xhci: dbc: Use ATTRIBUTE_GROUPS() Mathias Nyman
2023-12-01 15:06 ` [PATCH 05/19] xhci: dbc: Check for errors first in xhci_dbc_stop() Mathias Nyman
2023-12-01 15:06 ` [PATCH 06/19] xhci: dbc: Don't shadow error codes in store() functions Mathias Nyman
2023-12-01 15:06 ` [PATCH 07/19] xhci: dbc: Replace custom return value with proper Linux error code Mathias Nyman
2023-12-01 15:06 ` [PATCH 08/19] xhci: dbc: Use sizeof_field() where it makes sense Mathias Nyman
2023-12-01 17:31   ` David Laight
2023-12-01 19:08     ` Andy Shevchenko
2023-12-02 15:50       ` David Laight
2023-12-04 10:23         ` Mathias Nyman
2023-12-04 10:45           ` David Laight
2023-12-01 15:06 ` [PATCH 09/19] xhci: dbc: Use sizeof(*pointer) instead of sizeof(type) Mathias Nyman
2023-12-01 15:06 ` [PATCH 10/19] xhci: dbc: Add missing headers Mathias Nyman
2023-12-01 15:06 ` [PATCH 11/19] xhci: check if legacy irq is available before using it as fallback Mathias Nyman
2023-12-01 15:06 ` [PATCH 12/19] xhci: add handler for only one interrupt line Mathias Nyman
2023-12-01 15:06 ` [PATCH 13/19] xhci: refactor static MSI-X function Mathias Nyman
2023-12-01 15:06 ` [PATCH 14/19] xhci: refactor static MSI function Mathias Nyman
2023-12-01 15:06 ` [PATCH 15/19] xhci: change 'msix_count' to encompass MSI or MSI-X vectors Mathias Nyman
2023-12-01 15:06 ` [PATCH 16/19] xhci: rework 'xhci_try_enable_msi()' MSI and MSI-X setup code Mathias Nyman
2023-12-01 15:06 ` [PATCH 17/19] xhci: minor coding style cleanup in 'xhci_try_enable_msi()' Mathias Nyman
2023-12-01 15:06 ` [PATCH 18/19] xhci: Reconfigure endpoint 0 max packet size only during endpoint reset Mathias Nyman
2023-12-01 15:06 ` [PATCH 19/19] xhci: fix possible null pointer deref during xhci urb enqueue 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).