diff mbox

[v1,1/4] USB: introduce usb_device_no_sg_limit() helper

Message ID 1375497998-7424-2-git-send-email-ming.lei@canonical.com
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Ming Lei Aug. 3, 2013, 2:46 a.m. UTC
Some host controllers(such as xHCI) can support building
packet from discontinuous buffers, so introduce one flag
and helper for this kind of host controllers, then the
feature can help some applications(such as, usbnet) by
supporting arbitrary length of sg buffers.

Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 drivers/usb/core/urb.c |    3 ++-
 include/linux/usb.h    |   11 ++++++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

Comments

Alan Stern Aug. 3, 2013, 3:53 p.m. UTC | #1
On Sat, 3 Aug 2013, Ming Lei wrote:

> Some host controllers(such as xHCI) can support building
> packet from discontinuous buffers, so introduce one flag
> and helper for this kind of host controllers, then the
> feature can help some applications(such as, usbnet) by
> supporting arbitrary length of sg buffers.

> diff --git a/include/linux/usb.h b/include/linux/usb.h
> index 84f14e2..5d03074 100644
> --- a/include/linux/usb.h
> +++ b/include/linux/usb.h
> @@ -337,6 +337,7 @@ struct usb_bus {
>  					 * the ep queue on a short transfer
>  					 * with the URB_SHORT_NOT_OK flag set.
>  					 */
> +	unsigned no_sg_limit:1;		/* no sg list limit */

Why do you call this "no_sg_limit"?  It isn't a limit on the SG list; 
the list can be arbitrarily long, provided all the entries except the 
last are divisible by the maxpacket size.

You could call it "no_sg_constraint" if you want.  Or 
"allow_arbitrary_sg", to put a more positive spin on it.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ming Lei Aug. 4, 2013, 12:22 a.m. UTC | #2
On Sat, Aug 3, 2013 at 11:53 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Sat, 3 Aug 2013, Ming Lei wrote:
>
>> Some host controllers(such as xHCI) can support building
>> packet from discontinuous buffers, so introduce one flag
>> and helper for this kind of host controllers, then the
>> feature can help some applications(such as, usbnet) by
>> supporting arbitrary length of sg buffers.
>
>> diff --git a/include/linux/usb.h b/include/linux/usb.h
>> index 84f14e2..5d03074 100644
>> --- a/include/linux/usb.h
>> +++ b/include/linux/usb.h
>> @@ -337,6 +337,7 @@ struct usb_bus {
>>                                        * the ep queue on a short transfer
>>                                        * with the URB_SHORT_NOT_OK flag set.
>>                                        */
>> +     unsigned no_sg_limit:1;         /* no sg list limit */
>
> Why do you call this "no_sg_limit"?  It isn't a limit on the SG list;
> the list can be arbitrarily long, provided all the entries except the
> last are divisible by the maxpacket size.
>
> You could call it "no_sg_constraint" if you want.  Or
> "allow_arbitrary_sg", to put a more positive spin on it.

OK, I prefer no_sg_constraint, and will do it in v2.

Thanks,
--
Ming Lei
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index e75115a..7a88ae8 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -414,7 +414,8 @@  int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 			urb->iso_frame_desc[n].status = -EXDEV;
 			urb->iso_frame_desc[n].actual_length = 0;
 		}
-	} else if (dev->speed != USB_SPEED_WIRELESS && urb->num_sgs) {
+	} else if (urb->num_sgs && !urb->dev->bus->no_sg_limit &&
+			dev->speed != USB_SPEED_WIRELESS) {
 		struct scatterlist *sg;
 		int i;
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 84f14e2..5d03074 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -337,6 +337,7 @@  struct usb_bus {
 					 * the ep queue on a short transfer
 					 * with the URB_SHORT_NOT_OK flag set.
 					 */
+	unsigned no_sg_limit:1;		/* no sg list limit */
 	unsigned sg_tablesize;		/* 0 or largest number of sg list entries */
 
 	int devnum_next;		/* Next open device number in
@@ -684,6 +685,14 @@  static inline bool usb_device_supports_ltm(struct usb_device *udev)
 	return udev->bos->ss_cap->bmAttributes & USB_LTM_SUPPORT;
 }
 
+static inline bool usb_device_no_sg_limit(struct usb_device *udev)
+{
+	if (udev && udev->bus && udev->bus->no_sg_limit)
+		return true;
+	else
+		return false;
+}
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -1249,7 +1258,7 @@  typedef void (*usb_complete_t)(struct urb *);
  *	transfer_buffer.
  * @sg: scatter gather buffer list, the buffer size of each element in
  * 	the list (except the last) must be divisible by the endpoint's
- * 	max packet size
+ * 	max packet size if no_sg_limit isn't set in 'struct usb_bus'
  * @num_mapped_sgs: (internal) number of mapped sg entries
  * @num_sgs: number of entries in the sg list
  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may