static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep, dma_addr_t buf_dma, u32 len, u32 type, bool chain) { struct dwc3_trb *trb; struct dwc3 *dwc; dwc = dep->dwc; trb = &dwc->ep0_trb[dep->trb_enqueue]; if (chain) dep->trb_enqueue++; trb->bpl = lower_32_bits(buf_dma); trb->bph = upper_32_bits(buf_dma); trb->size = len; trb->ctrl = type; trb->ctrl |= (DWC3_TRB_CTRL_HWO | DWC3_TRB_CTRL_ISP_IMI); if (chain) trb->ctrl |= DWC3_TRB_CTRL_CHN; else trb->ctrl |= (DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_LST); trace_dwc3_prepare_trb(dep, trb); }
static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, u32 len, u32 type, bool chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; struct dwc3_ep *dep; int ret; dep = dwc->eps[epnum]; if (dep->flags & DWC3_EP_BUSY) { dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name); return 0; } trb = &dwc->ep0_trb[dep->free_slot]; if (chain) dep->free_slot++; trb->bpl = lower_32_bits(buf_dma); trb->bph = upper_32_bits(buf_dma); trb->size = len; trb->ctrl = type; trb->ctrl |= (DWC3_TRB_CTRL_HWO | DWC3_TRB_CTRL_ISP_IMI); if (chain) trb->ctrl |= DWC3_TRB_CTRL_CHN; else trb->ctrl |= (DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_LST); if (chain) return 0; memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); trace_dwc3_prepare_trb(dep, trb); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) { dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed", dep->name); return ret; } dep->flags |= DWC3_EP_BUSY; dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, dep->number); dwc->ep0_next_event = DWC3_EP0_COMPLETE; return 0; }