Add support for SG lists on dwc3 driver. Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/dwc3/gadget.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 80 insertions(+), 0 deletions(-) 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; + } + + 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; + + rsg->requests[i] = request; + + /* FIXME allocate a TRB, prepare TRB, set CHN bit, etc */ + } + + /* we want interrupt on the last request */ + rsg->requests[--i]->no_interrupt = false; + + rsg->num_entries = num_entries; + rsg->status = 0; + rsg->actual = 0; + + return 0; + +err1: + kfree(rsg->requests); + +err0: + return ret; +} + +static int dwc3_gadget_ep_sg_queue(struct usb_ep *ep, + struct usb_request_sg *rsg, gfp_t gfp_flags) +{ + return 0; +} + +static int dwc3_gadget_ep_sg_dequeue(struct usb_ep *ep, + struct usb_request_sg *rsg) +{ + return 0; +} + /* * dwc3_prepare_trbs - setup TRBs from requests * @dep: endpoint for which requests are being prepared @@ -976,6 +1053,9 @@ static const struct usb_ep_ops dwc3_gadget_ep_ops = { .disable = dwc3_gadget_ep_disable, .alloc_request = dwc3_gadget_ep_alloc_request, .free_request = dwc3_gadget_ep_free_request, + .sg_prepare = dwc3_gadget_ep_sg_prepare, + .sg_queue = dwc3_gadget_ep_sg_queue, + .sg_dequeue = dwc3_gadget_ep_sg_dequeue, .queue = dwc3_gadget_ep_queue, .dequeue = dwc3_gadget_ep_dequeue, .set_halt = dwc3_gadget_ep_set_halt, -- 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