* 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