Loading drivers/usb/dwc3/gadget.c +78 −68 Original line number Diff line number Diff line Loading @@ -539,6 +539,78 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, kfree(req); } /** * dwc3_prepare_one_trb - setup one TRB from one request * @dep: endpoint for which this request is prepared * @req: dwc3_request pointer */ static int dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned last) { struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; unsigned int cur_slot; trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; cur_slot = dep->free_slot; dep->free_slot++; /* Skip the LINK-TRB on ISOC */ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->desc)) return 0; dwc3_gadget_move_request_queued(req); memset(&trb, 0, sizeof(trb)); req->trb = trb_hw; if (usb_endpoint_xfer_isoc(dep->desc)) { trb.isp_imi = true; trb.csp = true; } else { trb.lst = last; } if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) trb.sid_sofn = req->request.stream_id; switch (usb_endpoint_type(dep->desc)) { case USB_ENDPOINT_XFER_CONTROL: trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; break; case USB_ENDPOINT_XFER_ISOC: trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; /* IOC every DWC3_TRB_NUM / 4 so we can refill */ if (!(cur_slot % (DWC3_TRB_NUM / 4))) trb.ioc = last; break; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: trb.trbctl = DWC3_TRBCTL_NORMAL; break; default: /* * This is only possible with faulty memory because we * checked it already :) */ BUG(); } trb.length = req->request.length; trb.bplh = req->request.dma; trb.hwo = true; dwc3_trb_to_hw(&trb, trb_hw); req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); return 0; } /* * dwc3_prepare_trbs - setup TRBs from requests * @dep: endpoint for which requests are being prepared Loading @@ -552,14 +624,14 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) { struct dwc3_request *req, *n, *ret = NULL; struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; u32 trbs_left; unsigned int last_one = 0; BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); /* the first request must not be queued */ trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; /* * if busy & slot are equal than it is either full or empty. If we are * starting to proceed requests then we are empty. Otherwise we ar Loading Loading @@ -594,25 +666,11 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, return NULL; list_for_each_entry_safe(req, n, &dep->request_list, list) { unsigned int last_one = 0; unsigned int cur_slot; trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; cur_slot = dep->free_slot; dep->free_slot++; /* Skip the LINK-TRB on ISOC */ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->desc)) continue; dwc3_gadget_move_request_queued(req); memset(&trb, 0, sizeof(trb)); trbs_left--; /* Is our TRB pool empty? */ if (!trbs_left) last_one = 1; /* Is this the last request? */ if (list_empty(&dep->request_list)) last_one = 1; Loading @@ -625,56 +683,8 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, * While we're debugging the problem, as a workaround to * multiple TRBs handling, use only one TRB at a time. */ last_one = 1; req->trb = trb_hw; if (!ret) dwc3_prepare_one_trb(dep, req, true); ret = req; trb.bplh = req->request.dma; if (usb_endpoint_xfer_isoc(dep->desc)) { trb.isp_imi = true; trb.csp = true; } else { trb.lst = last_one; } if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) trb.sid_sofn = req->request.stream_id; switch (usb_endpoint_type(dep->desc)) { case USB_ENDPOINT_XFER_CONTROL: trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; break; case USB_ENDPOINT_XFER_ISOC: trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; /* IOC every DWC3_TRB_NUM / 4 so we can refill */ if (!(cur_slot % (DWC3_TRB_NUM / 4))) trb.ioc = last_one; break; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: trb.trbctl = DWC3_TRBCTL_NORMAL; break; default: /* * This is only possible with faulty memory because we * checked it already :) */ BUG(); } trb.length = req->request.length; trb.hwo = true; dwc3_trb_to_hw(&trb, trb_hw); req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); if (last_one) break; } Loading Loading
drivers/usb/dwc3/gadget.c +78 −68 Original line number Diff line number Diff line Loading @@ -539,6 +539,78 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, kfree(req); } /** * dwc3_prepare_one_trb - setup one TRB from one request * @dep: endpoint for which this request is prepared * @req: dwc3_request pointer */ static int dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned last) { struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; unsigned int cur_slot; trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; cur_slot = dep->free_slot; dep->free_slot++; /* Skip the LINK-TRB on ISOC */ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->desc)) return 0; dwc3_gadget_move_request_queued(req); memset(&trb, 0, sizeof(trb)); req->trb = trb_hw; if (usb_endpoint_xfer_isoc(dep->desc)) { trb.isp_imi = true; trb.csp = true; } else { trb.lst = last; } if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) trb.sid_sofn = req->request.stream_id; switch (usb_endpoint_type(dep->desc)) { case USB_ENDPOINT_XFER_CONTROL: trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; break; case USB_ENDPOINT_XFER_ISOC: trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; /* IOC every DWC3_TRB_NUM / 4 so we can refill */ if (!(cur_slot % (DWC3_TRB_NUM / 4))) trb.ioc = last; break; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: trb.trbctl = DWC3_TRBCTL_NORMAL; break; default: /* * This is only possible with faulty memory because we * checked it already :) */ BUG(); } trb.length = req->request.length; trb.bplh = req->request.dma; trb.hwo = true; dwc3_trb_to_hw(&trb, trb_hw); req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); return 0; } /* * dwc3_prepare_trbs - setup TRBs from requests * @dep: endpoint for which requests are being prepared Loading @@ -552,14 +624,14 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) { struct dwc3_request *req, *n, *ret = NULL; struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; u32 trbs_left; unsigned int last_one = 0; BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); /* the first request must not be queued */ trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; /* * if busy & slot are equal than it is either full or empty. If we are * starting to proceed requests then we are empty. Otherwise we ar Loading Loading @@ -594,25 +666,11 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, return NULL; list_for_each_entry_safe(req, n, &dep->request_list, list) { unsigned int last_one = 0; unsigned int cur_slot; trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; cur_slot = dep->free_slot; dep->free_slot++; /* Skip the LINK-TRB on ISOC */ if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->desc)) continue; dwc3_gadget_move_request_queued(req); memset(&trb, 0, sizeof(trb)); trbs_left--; /* Is our TRB pool empty? */ if (!trbs_left) last_one = 1; /* Is this the last request? */ if (list_empty(&dep->request_list)) last_one = 1; Loading @@ -625,56 +683,8 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep, * While we're debugging the problem, as a workaround to * multiple TRBs handling, use only one TRB at a time. */ last_one = 1; req->trb = trb_hw; if (!ret) dwc3_prepare_one_trb(dep, req, true); ret = req; trb.bplh = req->request.dma; if (usb_endpoint_xfer_isoc(dep->desc)) { trb.isp_imi = true; trb.csp = true; } else { trb.lst = last_one; } if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable) trb.sid_sofn = req->request.stream_id; switch (usb_endpoint_type(dep->desc)) { case USB_ENDPOINT_XFER_CONTROL: trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; break; case USB_ENDPOINT_XFER_ISOC: trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; /* IOC every DWC3_TRB_NUM / 4 so we can refill */ if (!(cur_slot % (DWC3_TRB_NUM / 4))) trb.ioc = last_one; break; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: trb.trbctl = DWC3_TRBCTL_NORMAL; break; default: /* * This is only possible with faulty memory because we * checked it already :) */ BUG(); } trb.length = req->request.length; trb.hwo = true; dwc3_trb_to_hw(&trb, trb_hw); req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); if (last_one) break; } Loading