Hi All, Please let me know if the changes in this patch are okay . If the changes looks fine , can we proceed with this patch. Thanks, Anurag Kumar Vulisha >-----Original Message----- >From: v.anuragkumar@xxxxxxxxx [mailto:v.anuragkumar@xxxxxxxxx] >Sent: Tuesday, March 27, 2018 4:35 PM >To: Felipe Balbi <balbi@xxxxxxxxxx>; Greg Kroah-Hartman ><gregkh@xxxxxxxxxxxxxxxxxxx> >Cc: linux-usb@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Ajay Yugalkishore >Pandey <APANDEY@xxxxxxxxxx>; v.anuragkumar@xxxxxxxxx; Anurag Kumar Vulisha ><anuragku@xxxxxxxxxx> >Subject: [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists > >From: Anurag Kumar Vulisha <anuragku@xxxxxxxxxx> > >The code logic in dwc3_prepare_one_trb() incorrectly uses the address and length >fields present in req packet for mapping TRB's instead of using the address and length >fields of scattergather lists. This patch correct's the code to use sg->address and sg- >>length when scattergather lists are present. > >Signed-off-by: Anurag Kumar Vulisha <anuragku@xxxxxxxxxx> >--- > Changes in v2: > 1. Split the single patch into 2 patches as suggested by Felipe Balbi > 2. Renamed sg_to_start variable to start_sg >--- > drivers/usb/dwc3/core.h | 2 ++ > drivers/usb/dwc3/gadget.c | 25 ++++++++++++++++++++++--- > 2 files changed, 24 insertions(+), 3 deletions(-) > >diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index >860d2bc..1406c4f 100644 >--- a/drivers/usb/dwc3/core.h >+++ b/drivers/usb/dwc3/core.h >@@ -718,6 +718,7 @@ struct dwc3_hwparams { > * @list: a list_head used for request queueing > * @dep: struct dwc3_ep owning this request > * @sg: pointer to first incomplete sg >+ * @start_sg: pointer to the sg which should be queued next > * @num_pending_sgs: counter to pending sgs > * @remaining: amount of data remaining > * @epnum: endpoint number to which this request refers @@ -734,6 +735,7 @@ >struct dwc3_request { > struct list_head list; > struct dwc3_ep *dep; > struct scatterlist *sg; >+ struct scatterlist *start_sg; > > unsigned num_pending_sgs; > unsigned remaining; >diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index >2bda4eb..330a4de 100644 >--- a/drivers/usb/dwc3/gadget.c >+++ b/drivers/usb/dwc3/gadget.c >@@ -978,11 +978,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, > struct dwc3_request *req, unsigned chain, unsigned node) { > struct dwc3_trb *trb; >- unsigned length = req->request.length; >+ unsigned int length; >+ dma_addr_t dma; > unsigned stream_id = req->request.stream_id; > unsigned short_not_ok = req->request.short_not_ok; > unsigned no_interrupt = req->request.no_interrupt; >- dma_addr_t dma = req->request.dma; >+ >+ if (req->request.num_sgs > 0) { >+ length = sg_dma_len(req->start_sg); >+ dma = sg_dma_address(req->start_sg); >+ } else { >+ length = req->request.length; >+ dma = req->request.dma; >+ } > > trb = &dep->trb_pool[dep->trb_enqueue]; > >@@ -1048,7 +1056,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) >static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, > struct dwc3_request *req) > { >- struct scatterlist *sg = req->sg; >+ struct scatterlist *sg = req->start_sg; > struct scatterlist *s; > int i; > >@@ -1081,6 +1089,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep >*dep, > dwc3_prepare_one_trb(dep, req, chain, i); > } > >+ /* >+ * There can be a situation where all sgs in sglist are not >+ * queued because of insufficient trb number. To handle this >+ * case, update start_sg to next sg to be queued, so that >+ * we have free trbs we can continue queuing from where we >+ * previously stopped >+ */ >+ if (chain) >+ req->start_sg = sg_next(s); >+ > if (!dwc3_calc_trbs_left(dep)) > break; > } >@@ -1171,6 +1189,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) > return; > > req->sg = req->request.sg; >+ req->start_sg = req->sg; > req->num_pending_sgs = req->request.num_mapped_sgs; > > if (req->num_pending_sgs > 0) >-- >2.1.1 -- 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