Re: [RFC/PATCH 2/2] usb: dwc3: gadget: implement SG support

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

 



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

>On Tue, Nov 22, 2011 at 03:54:01PM +0100, Sebastian Andrzej Siewior wrote:
>> * Felipe Balbi | 2011-11-22 11:42:06 [+0200]:
>> 
>> >diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> >index c04a0d3..c9bdada 100644
>> >--- a/drivers/usb/dwc3/gadget.c
>> >+++ b/drivers/usb/dwc3/gadget.c
>> >@@ -539,6 +539,83 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
>> > 	kfree(req);
>> > }
>> > 
>> >+static int dwc3_gadget_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)
>> >+{
>> >+	struct dwc3_ep		*dep = to_dwc3_ep(ep);
>> >+	int			ret = -ENOMEM;
>> >+	int			i;
>> >+
>> >+	if (!rsg || !sg || num_entries == 0)
>> >+		return -EINVAL;
>> >+
>> >+	rsg->requests = kcalloc(num_entries, sizeof(*rsg->requests), gfp_flags);
>> >+	if (!rsg->requests)
>> >+		goto err0;
>> >+
>> >+	for_each_sg(sg, sg, rsg->num_entries, i) {
>> >+		struct usb_request	*request;
>> >+		unsigned		len;
>> >+
>> >+		request = usb_ep_alloc_request(ep, gfp_flags);
>> >+		if (!request) {
>> >+			rsg->num_entries = i;
>> >+			goto err1;
>> >+		}
>> >+
>> >+		len = length;
>> >+		if (len == 0) {
>> >+			struct scatterlist	*sg2;
>> >+			int			j;
>> >+
>> >+			for_each_sg(sg, sg2, num_entries, j)
>> >+				len += sg2->length;
>> >+		}
>> 
>> Why do iterate twice in case length is zero? And we do we have multiple
>
>this is also "borrowed" from host API. If the Length is zero, it means
>that we're asking for the entire SG to be sent, so I need to count the
>size of all entries before I can assign it to usb_request->length.

I see. I assumed the host is supposed to fill this field before
submitting the request.

>> What imagine for sg supportis th follwing: if the udc supports sg we can
>> queue sg-based requests which have buf = NULL. A request which we
>> receive could look like: req->length = 8192 and req->num_sgs = 3.
>> And the sgs are:
>> sg 1 starts at mem_page_offset + 2048 len 2048
>> sg 2 starts at mem_page_offset + 0 len 4096
>> sg 3 starts at mem_page_offset + 0 len 2048
>> 
>> Those three transfers should be part of _one_ request. Therefore you
>> don't need this no_interrupt field or anything else like that because
>> you call ->complete() once the whole thing is through. With one struct
>> usb_request only.
>
>I don't think using a NULL buffer pointer as a check for an SG-based
>transfer is really good.

No. You have num_sgs entry which says how many sg entries it has. 0
means no entry i.e. no sg support at all, one means only one sg entry
for the complete transfers, two means ....
->buffer may be NULL if the memory is not in kernel space but accessible
for the device via DMA. Highmem memory for instance :)

>> If you queue 2 usb_request struct and the gadget can wait with its
>> notification after the second is compled, this is another story.
>> 
>> >+
>> >+		request->no_interrupt = true;
>> >+		request->buf = NULL;
>> >+		request->num_sgs = num_entries;
>> >+
>> >+		request->length = len;
>> >+
>> >+		if (usb_endpoint_dir_in(dep->desc))
>> >+			request->short_not_ok = true;
>> 
>> Why is this for you to decice? Shouldn't the gadget take care of this?
>
>we shouldn't have shorts on IN transfer, we have created the transfer,
>how could it be short ? :-)
I don't see any user of that flag. Anyway, you as a udc should not touch
it by writting. Reading is okay.

>> 
>> >+		rsg->requests[i] = request;
>> >+
>> >+		/* FIXME allocate a TRB, prepare TRB, set CHN bit, etc */
>> 
>> We have 16 or 32 TRBs waiting. All we need to do prepare then and set
>> the CHN bit.
>
>yeah, I know, but we need to re-factor prepare_trbs() a bit.

Yeah, we need to learn that multiple TRBs belong to one usb_request.
First step of fixing this would be to support usb_requests > 16MiB :)

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