Commit 4c1bd3d7 authored by David Vrabel's avatar David Vrabel Committed by Greg Kroah-Hartman

USB: make urb scatter-gather support more generic

The WHCI HCD will also support urbs with scatter-gather lists.  Add a
usb_bus field to indicated how many sg list elements are supported by
the HCD.  Use this to decide whether to pass the scatter-list to the HCD
or not.

Make the usb-storage driver use this new field.
Signed-off-by: default avatarDavid Vrabel <david.vrabel@csr.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 09ce497e
...@@ -393,13 +393,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, ...@@ -393,13 +393,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
if (io->entries <= 0) if (io->entries <= 0)
return io->entries; return io->entries;
/* If we're running on an xHCI host controller, queue the whole scatter if (dev->bus->sg_tablesize > 0) {
* gather list with one call to urb_enqueue(). This is only for bulk,
* as that endpoint type does not care how the data gets broken up
* across frames.
*/
if (usb_pipebulk(pipe) &&
bus_to_hcd(dev->bus)->driver->flags & HCD_USB3) {
io->urbs = kmalloc(sizeof *io->urbs, mem_flags); io->urbs = kmalloc(sizeof *io->urbs, mem_flags);
use_sg = true; use_sg = true;
} else { } else {
......
...@@ -54,6 +54,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) ...@@ -54,6 +54,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
struct pci_dev *pdev = to_pci_dev(hcd->self.controller); struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
int retval; int retval;
hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 1;
xhci->cap_regs = hcd->regs; xhci->cap_regs = hcd->regs;
xhci->op_regs = hcd->regs + xhci->op_regs = hcd->regs +
HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase));
......
...@@ -843,6 +843,15 @@ static int usb_stor_scan_thread(void * __us) ...@@ -843,6 +843,15 @@ static int usb_stor_scan_thread(void * __us)
complete_and_exit(&us->scanning_done, 0); complete_and_exit(&us->scanning_done, 0);
} }
static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
if (usb_dev->bus->sg_tablesize) {
return usb_dev->bus->sg_tablesize;
}
return SG_ALL;
}
/* First part of general USB mass-storage probing */ /* First part of general USB mass-storage probing */
int usb_stor_probe1(struct us_data **pus, int usb_stor_probe1(struct us_data **pus,
...@@ -871,6 +880,7 @@ int usb_stor_probe1(struct us_data **pus, ...@@ -871,6 +880,7 @@ int usb_stor_probe1(struct us_data **pus,
* Allow 16-byte CDBs and thus > 2TB * Allow 16-byte CDBs and thus > 2TB
*/ */
host->max_cmd_len = 16; host->max_cmd_len = 16;
host->sg_tablesize = usb_stor_sg_tablesize(intf);
*pus = us = host_to_us(host); *pus = us = host_to_us(host);
memset(us, 0, sizeof(struct us_data)); memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex)); mutex_init(&(us->dev_mutex));
......
...@@ -331,6 +331,7 @@ struct usb_bus { ...@@ -331,6 +331,7 @@ struct usb_bus {
u8 otg_port; /* 0, or number of OTG/HNP port */ u8 otg_port; /* 0, or number of OTG/HNP port */
unsigned is_b_host:1; /* true during some HNP roleswitches */ unsigned is_b_host:1; /* true during some HNP roleswitches */
unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
unsigned sg_tablesize; /* 0 or largest number of sg list entries */
int devnum_next; /* Next open device number in int devnum_next; /* Next open device number in
* round-robin allocation */ * round-robin allocation */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment