Loading drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -648,6 +648,7 @@ struct dwc3_request { u8 epnum; struct dwc3_trb *trb; struct dwc3_trb *ztrb; dma_addr_t trb_dma; unsigned direction:1; Loading drivers/usb/dwc3/gadget.c +54 −3 Original line number Diff line number Diff line Loading @@ -294,6 +294,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, dep->busy_slot++; } while(++i < req->request.num_mapped_sgs); req->queued = false; if (req->request.zero && req->ztrb) { dep->busy_slot++; req->ztrb = NULL; if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) dep->busy_slot++; } } list_del(&req->list); req->trb = NULL; Loading Loading @@ -863,6 +872,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, dep->free_slot++; update_trb: trb->size = DWC3_TRB_SIZE_LENGTH(length); trb->bpl = lower_32_bits(dma); trb->bph = upper_32_bits(dma); Loading Loading @@ -897,8 +907,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; trb->ctrl |= DWC3_TRB_CTRL_CSP; } else if (last) { trb->ctrl |= DWC3_TRB_CTRL_LST; } if (chain) Loading @@ -908,6 +916,25 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); trb->ctrl |= DWC3_TRB_CTRL_HWO; if (req->request.zero && length && (length % usb_endpoint_maxp(dep->endpoint.desc) == 0)) { /* Skip the LINK-TRB on ISOC */ if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) dep->free_slot++; trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; dep->free_slot++; req->ztrb = trb; length = 0; goto update_trb; } if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && last) trb->ctrl |= DWC3_TRB_CTRL_LST; } /* Loading Loading @@ -1011,12 +1038,25 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) } dbg_queue(dep->number, &req->request, 0); } else { struct dwc3_request *req1; int maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc); dma = req->request.dma; length = req->request.length; trbs_left--; if (!trbs_left) if (req->request.zero && length && (length % maxpkt_size == 0)) trbs_left--; if (!trbs_left) { last_one = 1; } else if (dep->direction && (trbs_left <= 1)) { req1 = next_request(&req->list); if (req1->request.zero && req1->request.length && (req1->request.length % maxpkt_size == 0)) last_one = 1; } /* Is this the last request? */ if (list_is_last(&req->list, &dep->request_list)) Loading Loading @@ -2201,6 +2241,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, break; }while (++i < req->request.num_mapped_sgs); if (req->ztrb) { trb = req->ztrb; if ((event->status & DEPEVT_STATUS_LST) && (trb->ctrl & (DWC3_TRB_CTRL_LST | DWC3_TRB_CTRL_HWO))) ret = 1; if ((event->status & DEPEVT_STATUS_IOC) && (trb->ctrl & DWC3_TRB_CTRL_IOC)) ret = 1; } dwc3_gadget_giveback(dep, req, status); if (ret) Loading Loading
drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -648,6 +648,7 @@ struct dwc3_request { u8 epnum; struct dwc3_trb *trb; struct dwc3_trb *ztrb; dma_addr_t trb_dma; unsigned direction:1; Loading
drivers/usb/dwc3/gadget.c +54 −3 Original line number Diff line number Diff line Loading @@ -294,6 +294,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, dep->busy_slot++; } while(++i < req->request.num_mapped_sgs); req->queued = false; if (req->request.zero && req->ztrb) { dep->busy_slot++; req->ztrb = NULL; if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) dep->busy_slot++; } } list_del(&req->list); req->trb = NULL; Loading Loading @@ -863,6 +872,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, dep->free_slot++; update_trb: trb->size = DWC3_TRB_SIZE_LENGTH(length); trb->bpl = lower_32_bits(dma); trb->bph = upper_32_bits(dma); Loading Loading @@ -897,8 +907,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; trb->ctrl |= DWC3_TRB_CTRL_CSP; } else if (last) { trb->ctrl |= DWC3_TRB_CTRL_LST; } if (chain) Loading @@ -908,6 +916,25 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); trb->ctrl |= DWC3_TRB_CTRL_HWO; if (req->request.zero && length && (length % usb_endpoint_maxp(dep->endpoint.desc) == 0)) { /* Skip the LINK-TRB on ISOC */ if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) dep->free_slot++; trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; dep->free_slot++; req->ztrb = trb; length = 0; goto update_trb; } if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && last) trb->ctrl |= DWC3_TRB_CTRL_LST; } /* Loading Loading @@ -1011,12 +1038,25 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) } dbg_queue(dep->number, &req->request, 0); } else { struct dwc3_request *req1; int maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc); dma = req->request.dma; length = req->request.length; trbs_left--; if (!trbs_left) if (req->request.zero && length && (length % maxpkt_size == 0)) trbs_left--; if (!trbs_left) { last_one = 1; } else if (dep->direction && (trbs_left <= 1)) { req1 = next_request(&req->list); if (req1->request.zero && req1->request.length && (req1->request.length % maxpkt_size == 0)) last_one = 1; } /* Is this the last request? */ if (list_is_last(&req->list, &dep->request_list)) Loading Loading @@ -2201,6 +2241,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, break; }while (++i < req->request.num_mapped_sgs); if (req->ztrb) { trb = req->ztrb; if ((event->status & DEPEVT_STATUS_LST) && (trb->ctrl & (DWC3_TRB_CTRL_LST | DWC3_TRB_CTRL_HWO))) ret = 1; if ((event->status & DEPEVT_STATUS_IOC) && (trb->ctrl & DWC3_TRB_CTRL_IOC)) ret = 1; } dwc3_gadget_giveback(dep, req, status); if (ret) Loading