static int dwc3_ep0_start_trans(struct dwc3_ep *dep) { struct dwc3_gadget_ep_cmd_params params; struct dwc3 *dwc; int ret; if (dep->flags & DWC3_EP_BUSY) return 0; dwc = dep->dwc; memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) return ret; dep->flags |= DWC3_EP_BUSY; dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep); dwc->ep0_next_event = DWC3_EP0_COMPLETE; return 0; }
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; }
static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, u32 len, u32 type) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; struct dwc3_ep *dep; int ret; dep = dwc->eps[epnum]; if (dep->flags & DWC3_EP_BUSY) { dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); return 0; } trb_hw = dwc->ep0_trb; memset(&trb, 0, sizeof(trb)); trb.trbctl = type; trb.bplh = buf_dma; trb.length = len; trb.hwo = 1; trb.lst = 1; trb.ioc = 1; trb.isp_imi = 1; //Before writing to the registers dwc3_trb_to_hw(&trb, trb_hw); trb_address = (u32*)dwc->ep0_trb_addr; memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) { dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); 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; }
static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) { struct dwc3_gadget_ep_cmd_params params; u32 cmd; int ret; if (!dep->resource_index) return; cmd = DWC3_DEPCMD_ENDTRANSFER; cmd |= DWC3_DEPCMD_CMDIOC; cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); memset(¶ms, 0, sizeof(params)); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); WARN_ON_ONCE(ret); dep->resource_index = 0; }
static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, u32 len, u32 type) { 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) { dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); return 0; } trb = dwc->ep0_trb; 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_LST | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); memset(¶ms, 0, sizeof(params)); params.param0 = upper_32_bits(dwc->ep0_trb_addr); params.param1 = lower_32_bits(dwc->ep0_trb_addr); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) { dbg_event(dep->number, "STTRAFL", ret); dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); 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; }
static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) { struct dwc3_gadget_ep_cmd_params params; u32 cmd; int ret; if (!dep->resource_index) return; cmd = DWC3_DEPCMD_ENDTRANSFER; cmd |= DWC3_DEPCMD_CMDIOC; cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); memset(¶ms, 0, sizeof(params)); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); if (ret) { dev_dbg(dwc->dev, "%s: send ep cmd ENDTRANSFER failed", dep->name); dbg_event(dep->number, "EENDXFER", ret); } dep->resource_index = 0; }
static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, u32 len) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb_hw *trb_hw; struct dwc3_trb trb; struct dwc3_ep *dep; int ret; dep = dwc->eps[epnum]; trb_hw = dwc->ep0_trb; memset(&trb, 0, sizeof(trb)); switch (dwc->ep0state) { case EP0_IDLE: trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; break; case EP0_IN_WAIT_NRDY: case EP0_OUT_WAIT_NRDY: case EP0_IN_STATUS_PHASE: case EP0_OUT_STATUS_PHASE: if (dwc->three_stage_setup) trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS3; else trb.trbctl = DWC3_TRBCTL_CONTROL_STATUS2; if (dwc->ep0state == EP0_IN_WAIT_NRDY) dwc->ep0state = EP0_IN_STATUS_PHASE; else if (dwc->ep0state == EP0_OUT_WAIT_NRDY) dwc->ep0state = EP0_OUT_STATUS_PHASE; break; case EP0_IN_WAIT_GADGET: dwc->ep0state = EP0_IN_WAIT_NRDY; return 0; break; case EP0_OUT_WAIT_GADGET: dwc->ep0state = EP0_OUT_WAIT_NRDY; return 0; break; case EP0_IN_DATA_PHASE: case EP0_OUT_DATA_PHASE: trb.trbctl = DWC3_TRBCTL_CONTROL_DATA; break; default: dev_err(dwc->dev, "%s() can't in state %d\n", __func__, dwc->ep0state); return -EINVAL; } trb.bplh = buf_dma; trb.length = len; trb.hwo = 1; trb.lst = 1; trb.ioc = 1; trb.isp_imi = 1; dwc3_trb_to_hw(&trb, trb_hw); memset(¶ms, 0, sizeof(params)); params.param0.depstrtxfer.transfer_desc_addr_high = upper_32_bits(dwc->ep0_trb_addr); params.param1.depstrtxfer.transfer_desc_addr_low = lower_32_bits(dwc->ep0_trb_addr); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_STARTTRANSFER, ¶ms); if (ret < 0) { dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); return ret; } dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, dep->number); return 0; }