[RFT] xhci: Add a modparam to increase bulk ring size.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a new module parameter to increase the bulk ring size.  Matrix Vision
has a libusb program for their USB 2.0 cameras that submits a number of
very large transfers.  The xHCI driver ends up rejecting some transfers
because it doesn't have enough room on the one bulk ring segment.  By
experimentation, their program works if 20 bulk segments are allocated.

We really need to fix this by adding dynamic ring segment allocation, but
that code is a bit complex and will take a while to write.  To ensure
Matrix Vision's libusb program works when their device is connected under
an xHCI host, add a module parameter to allow users to increase the number
of bulk endpoint ring segments.  This is a temporary fix, and should be
removed once the xHCI driver has dynamic segment allocation.

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
Cc: Kruno Mrak <kruno.mrak@xxxxxxxxxxxxxxxx>
---

Hi Kruno,

Would you please try to apply this patch against Linus' latest tree and
let me know if your program works when you load the xHCI driver with
this command:

sudo insmod drivers/usb/host/xhci-hcd.ko bulk_segs=20

Or something similar with modprobe, if you even up installing the driver
and rebooting.

Thanks,

Sarah Sharp

 drivers/usb/host/xhci-mem.c |    4 ++++
 drivers/usb/host/xhci.c     |    8 ++++++++
 drivers/usb/host/xhci.h     |    1 +
 3 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index fcb7f7e..ad99dd5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1176,6 +1176,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
 	if (usb_endpoint_xfer_isoc(&ep->desc))
 		virt_dev->eps[ep_index].new_ring =
 			xhci_ring_alloc(xhci, 8, true, mem_flags);
+	else if (usb_endpoint_xfer_bulk(&ep->desc))
+		virt_dev->eps[ep_index].new_ring =
+			xhci_ring_alloc(xhci, xhci->num_bulk_segs,
+					true, mem_flags);
 	else
 		virt_dev->eps[ep_index].new_ring =
 			xhci_ring_alloc(xhci, 1, true, mem_flags);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f5fe1ac..211dcca 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -37,6 +37,10 @@ static int link_quirk;
 module_param(link_quirk, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
 
+static int bulk_segs;
+module_param(bulk_segs, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bulk_segs, "Number of ring segments for bulk endpoints");
+
 /* TODO: copied from ehci-hcd.c - can this be refactored? */
 /*
  * handshake - spin reading hc until handshake completes or fails
@@ -322,6 +326,10 @@ int xhci_init(struct usb_hcd *hcd)
 	} else {
 		xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n");
 	}
+	if (bulk_segs > 1)
+		xhci->num_bulk_segs = bulk_segs;
+	else
+		xhci->num_bulk_segs = 1;
 	retval = xhci_mem_init(xhci, GFP_KERNEL);
 	xhci_dbg(xhci, "Finished xhci_init\n");
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d8bbf5c..e88d2fa 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1313,6 +1313,7 @@ struct xhci_hcd {
 #define XHCI_RESET_ON_RESUME	(1 << 7)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
+	unsigned int		num_bulk_segs;
 	/* There are two roothubs to keep track of bus suspend info for */
 	struct xhci_bus_state   bus_state[2];
 	/* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux