From 55dd719983af76fde1c086cfd4469f4bcaf45458 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Mon, 12 Aug 2019 12:20:20 +0530 Subject: [PATCH] usb: dwc3: gadget: Update chain bit correctly when using sg list If scatter-gather operation is allowed, a large USB request is split into multiple TRBs. For preparing TRBs for sg list, driver iterates over the list and creates TRB for each sg and mark the chain bit to false for the last sg. The current IOMMU driver is clubbing the list of sgs which shares a page boundary into one and giving it to USB driver. With this the number of sgs mapped it not equal to the the number of sgs passed. Because of this USB driver is not marking the chain bit to false since it couldn't iterate to the last sg. This patch addresses this issue by marking the chain bit to false if it is the last mapped sg. Change-Id: Ie496234ebae6e04a3b4ea68a682cc32109663e44 Signed-off-by: Pratham Pratap --- drivers/usb/dwc3/gadget.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 173f5329d3d9..a44aa3ca3881 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1062,7 +1062,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, unsigned int rem = length % maxp; unsigned chain = true; - if (sg_is_last(s)) + /* + * IOMMU driver is clubbing the list of sgs which shares a page + * boundary into one and giving it to USB driver. With this the + * number of sgs mapped it not equal to the the number of sgs + * passed. Mark the chain bit to false if it is the last mapped + * sg. + */ + if (sg_is_last(s) || (i == remaining - 1)) chain = false; if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {