| From ec512fb8e5611fed1df2895f90317ce6797d6b32 Mon Sep 17 00:00:00 2001 |
| From: Amit Virdi <amit.virdi@st.com> |
| Date: Tue, 13 Jan 2015 14:27:20 +0530 |
| Subject: usb: dwc3: gadget: Fix TRB preparation during SG |
| |
| From: Amit Virdi <amit.virdi@st.com> |
| |
| commit ec512fb8e5611fed1df2895f90317ce6797d6b32 upstream. |
| |
| When scatter gather (SG) is used, multiple TRBs are prepared from one DWC3 |
| request (dwc3_request). So while preparing TRBs, the 'last' flag should be set |
| only when it is the last TRB being prepared from the last dwc3_request entry. |
| |
| The current implementation uses list_is_last to check if the dwc3_request is the |
| last entry from the request_list. However, list_is_last returns false for the |
| last entry too. This is because, while preparing the first TRB from a request, |
| the function dwc3_prepare_one_trb modifies the request's next and prev pointers |
| while moving the URB to req_queued. Hence, list_is_last always returns false no |
| matter what. |
| |
| The correct way is not to access the modified pointers of dwc3_request but to |
| use list_empty macro instead. |
| |
| Fixes: e5ba5ec833aa (usb: dwc3: gadget: fix scatter gather implementation) |
| Signed-off-by: Amit Virdi <amit.virdi@st.com> |
| Signed-off-by: Felipe Balbi <balbi@ti.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/dwc3/gadget.c | 3 +-- |
| 1 file changed, 1 insertion(+), 2 deletions(-) |
| |
| --- a/drivers/usb/dwc3/gadget.c |
| +++ b/drivers/usb/dwc3/gadget.c |
| @@ -882,8 +882,7 @@ static void dwc3_prepare_trbs(struct dwc |
| |
| if (i == (request->num_mapped_sgs - 1) || |
| sg_is_last(s)) { |
| - if (list_is_last(&req->list, |
| - &dep->request_list)) |
| + if (list_empty(&dep->request_list)) |
| last_one = true; |
| chain = false; |
| } |