Re: [PATCH 1/2] usb: make urb scatter-gather support more generic

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

 



On Mon, Aug 24, 2009 at 03:54:16PM +0000, David Vrabel wrote:
> 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.
>
> Always use scatter-gather urbs where possible, regardless of the
> endpoint type.  If the scatter-gather list doesn't have suitably sized
> elements for a particular endpoint type then splitting it up into
> separate urbs won't help.

Does this mean control URBs may have a scatter gather list?  The xHCI
driver can't currently handle that.

> Make the usb-storage driver use this new field.
> 
> Signed-off-by: David Vrabel <david.vrabel@xxxxxxx>
> Cc: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> ---
> Sarah,
> 
> Could you check the reasoning in the 2nd paragraph above and confirm
> that the xhci-hcd's sg_tablesize is a suitable value?
> 
>  drivers/usb/core/message.c  |    8 +-------
>  drivers/usb/host/xhci-pci.c |    2 ++
>  drivers/usb/storage/usb.c   |   10 ++++++++++
>  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 9720e69..e17bded 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,
>  	if (io->entries <= 0)
>  		return io->entries;
>  
> -	/* If we're running on an xHCI host controller, queue the whole scatter
> -	 * 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) {
> +	if (dev->bus->sg_tablesize > 0) {
>  		io->urbs = kmalloc(sizeof *io->urbs, mem_flags);
>  		use_sg = true;
>  	} else {
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 592fe7e..bbc3934 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -50,6 +50,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
>  	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
>  	int			retval;
>  
> +	hcd->self.sg_tablesize = 2048;
> +

Please set this to (TRBS_PER_SEGMENT - 1).  It's not a very big number
(currently 63).  I haven't added dynamic transfer ring resizing yet, so
there's only 63 TRBs to map to sg list entries.

>  	xhci->cap_regs = hcd->regs;
>  	xhci->op_regs = hcd->regs +
>  		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 8060b85..964d8ee 100644
> --- a/drivers/usb/storage/usb.c
> +++ b/drivers/usb/storage/usb.c
> @@ -840,6 +840,15 @@ static int usb_stor_scan_thread(void * __us)
>  	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 */
>  int usb_stor_probe1(struct us_data **pus,
> @@ -868,6 +877,7 @@ int usb_stor_probe1(struct us_data **pus,
>  	 * Allow 16-byte CDBs and thus > 2TB
>  	 */
>  	host->max_cmd_len = 16;
> +	host->sg_tablesize = usb_stor_sg_tablesize(intf);
>  	*pus = us = host_to_us(host);
>  	memset(us, 0, sizeof(struct us_data));
>  	mutex_init(&(us->dev_mutex));
> diff --git a/include/linux/usb.h b/include/linux/usb.h
> index b1e3c2f..199e467 100644
> --- a/include/linux/usb.h
> +++ b/include/linux/usb.h
> @@ -331,6 +331,7 @@ struct usb_bus {
>  	u8 otg_port;			/* 0, or number of OTG/HNP port */
>  	unsigned is_b_host:1;		/* true during some HNP roleswitches */
>  	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
>  					 * round-robin allocation */
> -- 
> 1.6.3.3
> 
--
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