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

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

 



* Felipe Balbi | 2011-11-23 13:07:11 [+0200]:

>On Tue, Nov 22, 2011 at 03:38:34PM +0100, Sebastian Andrzej Siewior wrote:
>> * Felipe Balbi | 2011-11-22 11:42:05 [+0200]:
>> 
>> >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
>> >@@ -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;
>> >+};
>> 
>> Ehm, why do you need this? This seem to be part of something else.
>
>what do you mean ? I need one big request which will group all struct
>usb_requests, it's just the easiest way to know how usb requests you
>have on this SG list and, with that, how many requests will have CHN bit
>set (on dwc3).

I think you confuse two things: one usb_request has one buffer contigues
buffer and therefore one length. So if you as a gadget need pass 1MiB of
data you can either allocate 1MiB in one piece and deal with the
consequences _or_ you allocate 256 requests and split buffer in requests
of 4KiB in size.
The host should not see a difference. The udc however has the additional
255 requests including 255 additional interrupts to notify about the
completion and not to forget the complete callbacks to the gadget.
Now here is where the sg list comes into the game. You still have your
1MiB transfer you want to push through. Instead of 256 usb_requests you
allocate one. You tell sg_num_entries to be 256 and your sg list will
have 256 enties (ofcourse you need allocate one of that size but this is
another story).
Now, the udc driver gets one usb_request with sg_num_entries = 256 and
it has to use its sg capabilities which it said it has. Ideally 256 is
the number of TRBs you need. In the unlikely event where one sg list
entry exceeds the size of 16MiB you need to split this sg entry into two
TRBs instead of one. Sarah is forced to do something similar as she has
64KiB limit (as you can see in count_sg_trbs_needed()). So once you
prepared all TRBs (or half of if it if your ring is too small or
anything) you start the transfer.
Since the gadget pass one usb_request to the udc it does _not_ care when
the udc finished the first 20 sg list entries. So you call the callback
function of the usb_request once all of the 256 sg are through.

According to this little story you need another struct for sg
processing.

>> >+	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,
>> 
>> Why do you need also this extra callbacks?
>
>so that scatter/gather API is separate from the other API ?!? don't get
>your concern.

You don't need to do this. The existing API was enough for the host
side, should be for the gadget side.

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