diff options
author | David Vrabel <david.vrabel@csr.com> | 2009-08-24 09:44:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:14 -0500 |
commit | 4c1bd3d7a7d114dabd58f62f386ac4bfd268be1f (patch) | |
tree | 1c8d7d6df693c71ac0b3dcc4124498d91c939f2d | |
parent | 09ce497e79a930ac4912d6bc295baab82b39f8ab (diff) |
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: David 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: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/core/message.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 2 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 10 | ||||
-rw-r--r-- | include/linux/usb.h | 1 |
4 files changed, 14 insertions, 7 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index e80f1af438c8..8d874cad6581 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -393,13 +393,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
393 | if (io->entries <= 0) | 393 | if (io->entries <= 0) |
394 | return io->entries; | 394 | return io->entries; |
395 | 395 | ||
396 | /* If we're running on an xHCI host controller, queue the whole scatter | 396 | if (dev->bus->sg_tablesize > 0) { |
397 | * gather list with one call to urb_enqueue(). This is only for bulk, | ||
398 | * as that endpoint type does not care how the data gets broken up | ||
399 | * across frames. | ||
400 | */ | ||
401 | if (usb_pipebulk(pipe) && | ||
402 | bus_to_hcd(dev->bus)->driver->flags & HCD_USB3) { | ||
403 | io->urbs = kmalloc(sizeof *io->urbs, mem_flags); | 397 | io->urbs = kmalloc(sizeof *io->urbs, mem_flags); |
404 | use_sg = true; | 398 | use_sg = true; |
405 | } else { | 399 | } else { |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 06595ec27bb7..e097008d6fb1 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -54,6 +54,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
54 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 54 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
55 | int retval; | 55 | int retval; |
56 | 56 | ||
57 | hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 1; | ||
58 | |||
57 | xhci->cap_regs = hcd->regs; | 59 | xhci->cap_regs = hcd->regs; |
58 | xhci->op_regs = hcd->regs + | 60 | xhci->op_regs = hcd->regs + |
59 | HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); | 61 | HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 01e43a13a6bf..1599d86154c4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -843,6 +843,15 @@ static int usb_stor_scan_thread(void * __us) | |||
843 | complete_and_exit(&us->scanning_done, 0); | 843 | complete_and_exit(&us->scanning_done, 0); |
844 | } | 844 | } |
845 | 845 | ||
846 | static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) | ||
847 | { | ||
848 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
849 | |||
850 | if (usb_dev->bus->sg_tablesize) { | ||
851 | return usb_dev->bus->sg_tablesize; | ||
852 | } | ||
853 | return SG_ALL; | ||
854 | } | ||
846 | 855 | ||
847 | /* First part of general USB mass-storage probing */ | 856 | /* First part of general USB mass-storage probing */ |
848 | int usb_stor_probe1(struct us_data **pus, | 857 | int usb_stor_probe1(struct us_data **pus, |
@@ -871,6 +880,7 @@ int usb_stor_probe1(struct us_data **pus, | |||
871 | * Allow 16-byte CDBs and thus > 2TB | 880 | * Allow 16-byte CDBs and thus > 2TB |
872 | */ | 881 | */ |
873 | host->max_cmd_len = 16; | 882 | host->max_cmd_len = 16; |
883 | host->sg_tablesize = usb_stor_sg_tablesize(intf); | ||
874 | *pus = us = host_to_us(host); | 884 | *pus = us = host_to_us(host); |
875 | memset(us, 0, sizeof(struct us_data)); | 885 | memset(us, 0, sizeof(struct us_data)); |
876 | mutex_init(&(us->dev_mutex)); | 886 | mutex_init(&(us->dev_mutex)); |
diff --git a/include/linux/usb.h b/include/linux/usb.h index a34fa89f1474..6e91ee4f5b81 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -331,6 +331,7 @@ struct usb_bus { | |||
331 | u8 otg_port; /* 0, or number of OTG/HNP port */ | 331 | u8 otg_port; /* 0, or number of OTG/HNP port */ |
332 | unsigned is_b_host:1; /* true during some HNP roleswitches */ | 332 | unsigned is_b_host:1; /* true during some HNP roleswitches */ |
333 | unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ | 333 | unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */ |
334 | unsigned sg_tablesize; /* 0 or largest number of sg list entries */ | ||
334 | 335 | ||
335 | int devnum_next; /* Next open device number in | 336 | int devnum_next; /* Next open device number in |
336 | * round-robin allocation */ | 337 | * round-robin allocation */ |