[RFC/PATCH 1/2] usb: gadget: introduce support for sg lists

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

 



Some controllers support scatter/gather transfers
and that might be very useful for some gadget drivers.

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 include/linux/usb/gadget.h |   70 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 22c37d2..fd61375 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/scatterlist.h>
 #include <linux/types.h>
 #include <linux/usb/ch9.h>
 
@@ -32,6 +33,8 @@ struct usb_ep;
  * @dma: DMA address corresponding to 'buf'.  If you don't set this
  *	field, and the usb controller needs one, it is responsible
  *	for mapping and unmapping the buffer.
+ * @sg: a scatterlist for SG-capable controllers.
+ * @num_sgs: number of SG entries
  * @length: Length of that data
  * @stream_id: The stream id, when USB3.0 bulk streams are being used
  * @no_interrupt: If true, hints that no completion irq is needed.
@@ -88,6 +91,9 @@ struct usb_request {
 	unsigned		length;
 	dma_addr_t		dma;
 
+	struct scatterlist	*sg;
+	unsigned		num_sgs;
+
 	unsigned		stream_id:16;
 	unsigned		no_interrupt:1;
 	unsigned		zero:1;
@@ -102,6 +108,22 @@ struct usb_request {
 	unsigned		actual;
 };
 
+struct usb_request_sg {
+	int		status;
+	unsigned	actual;
+
+	void		(*complete)(struct usb_ep *ep,
+			struct usb_request_sg *rsg);
+	void		*context;
+
+	/*
+	 * Members below are private to the controller. Gadget
+	 * drivers should not touch them.
+	 */
+	struct usb_request	**requests;
+	int			num_entries;
+};
+
 /*-------------------------------------------------------------------------*/
 
 /* endpoint-specific parts of the api to the usb controller hardware.
@@ -120,6 +142,13 @@ struct usb_ep_ops {
 		gfp_t gfp_flags);
 	void (*free_request) (struct usb_ep *ep, struct usb_request *req);
 
+	int (*sg_prepare)(struct usb_ep *ep, struct usb_request_sg *rsg,
+			struct scatterlist *sg, unsigned int num_entries,
+			unsigned int length, gfp_t gfp_flags);
+	int (*sg_queue)(struct usb_ep *ep, struct usb_request_sg *rsg,
+			gfp_t gfp_flags);
+	int (*sg_dequeue)(struct usb_ep *ep, struct usb_request_sg *rsg);
+
 	int (*queue) (struct usb_ep *ep, struct usb_request *req,
 		gfp_t gfp_flags);
 	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
@@ -250,6 +279,45 @@ static inline void usb_ep_free_request(struct usb_ep *ep,
 }
 
 /**
+ * usb_ep_sg_prepare - prepares a sg list to be queued to the endpoint
+ * @ep: the endpoint associated with the request
+ * @rsg: the SG request
+ * @sg: the scatterlist
+ * @num_entries: number of entries
+ * @length: total length of the SG transfer
+ * @gfp_flags: flags for memory allocations on this call
+ */
+static inline int usb_ep_sg_prepare(struct usb_ep *ep,
+		struct usb_request_sg *rsg, struct scatterlist *sg,
+		unsigned int num_entries, unsigned int length, gfp_t gfp_flags)
+{
+	return ep->ops->sg_prepare(ep, rsg, sg, num_entries, length, gfp_flags);
+}
+
+/**
+ * usb_ep_sg_queue - queue a sg list to the endpoint
+ * @ep: the endpoint associated with the request
+ * @rsg: the SG request
+ * @gfp_flags: flags for memory allocations on this call
+ */
+static inline int usb_ep_sg_queue(struct usb_ep *ep,
+		struct usb_request_sg *rsg, gfp_t gfp_flags)
+{
+	return ep->ops->sg_queue(ep, rsg, gfp_flags);
+}
+
+/**
+ * usb_ep_sg_dequeue - dequeues a sg ist from the endpoint
+ * @ep: the endpoint associated with the request
+ * @rsg: the SG request to the dequeued
+ */
+static inline int usb_ep_sg_dequeue(struct usb_ep *ep,
+		struct usb_request_sg *rsg)
+{
+	return ep->ops->sg_dequeue(ep, rsg);
+}
+
+/**
  * usb_ep_queue - queues (submits) an I/O request to an endpoint.
  * @ep:the endpoint associated with the request
  * @req:the request being submitted
@@ -479,6 +547,7 @@ struct usb_gadget_ops {
  * @speed: Speed of current connection to USB host.
  * @max_speed: Maximal speed the UDC can handle.  UDC must support this
  *      and all slower speeds.
+ * @sg_tablesize: largest number of sg list entries or 0.
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  *	gadget driver must provide a USB OTG descriptor.
  * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
@@ -519,6 +588,7 @@ struct usb_gadget {
 	struct list_head		ep_list;	/* of usb_ep */
 	enum usb_device_speed		speed;
 	enum usb_device_speed		max_speed;
+	unsigned			sg_tablesize;
 	unsigned			is_otg:1;
 	unsigned			is_a_peripheral:1;
 	unsigned			b_hnp_enable:1;
-- 
1.7.8.rc0

--
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