Loading drivers/usb/dwc3/dwc3-msm.c +23 −4 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,8 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) struct dwc3_trb *trb; int num_trbs = (dep->direction) ? (2 * (req->num_bufs) + 2) : (req->num_bufs + 2); struct scatterlist *sg; struct sg_table *sgt; dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), Loading @@ -1073,6 +1075,19 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } dep->num_trbs = num_trbs; dma_get_sgtable(dwc->sysdev, &req->sgt_trb_xfer_ring, dep->trb_pool, dep->trb_pool_dma, num_trbs * sizeof(struct dwc3_trb)); sgt = &req->sgt_trb_xfer_ring; dev_dbg(dwc->dev, "%s(): trb_pool:%pK trb_pool_dma:%lx\n", __func__, dep->trb_pool, (unsigned long)dep->trb_pool_dma); for_each_sg(sgt->sgl, sg, sgt->nents, i) dev_dbg(dwc->dev, "%i: page_link:%lx offset:%x length:%x address:%lx\n", i, sg->page_link, sg->offset, sg->length, (unsigned long)sg->dma_address); /* IN direction */ if (dep->direction) { for (i = 0; i < num_trbs ; i++) { Loading Loading @@ -1138,11 +1153,13 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } } pr_debug("%s: Initialized TRB Ring for %s\n", __func__, dep->name); dev_dbg(dwc->dev, "%s: Initialized TRB Ring for %s\n", __func__, dep->name); trb = &dep->trb_pool[0]; if (trb) { for (i = 0; i < num_trbs; i++) { pr_debug("TRB(%d): ADDRESS:%lx bpl:%x bph:%x size:%x ctrl:%x\n", dev_dbg(dwc->dev, "TRB %d: ADDR:%lx bpl:%x bph:%x sz:%x ctl:%x\n", i, (unsigned long)dwc3_trb_dma_offset(dep, &dep->trb_pool[i]), trb->bpl, trb->bph, trb->size, trb->ctrl); Loading @@ -1159,7 +1176,7 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) * @usb_ep - pointer to usb_ep instance. * */ static void gsi_free_trbs(struct usb_ep *ep) static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; Loading @@ -1176,6 +1193,7 @@ static void gsi_free_trbs(struct usb_ep *ep) dep->trb_pool = NULL; dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); } /* * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. Loading Loading @@ -1365,7 +1383,8 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, break; case GSI_EP_OP_FREE_TRBS: dev_dbg(mdwc->dev, "EP_OP_FREE_TRBS for %s\n", ep->name); gsi_free_trbs(ep); request = (struct usb_gsi_request *)op_data; gsi_free_trbs(ep, request); break; case GSI_EP_OP_CONFIG: request = (struct usb_gsi_request *)op_data; Loading drivers/usb/gadget/function/f_gsi.c +27 −2 Original line number Diff line number Diff line Loading @@ -307,6 +307,10 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) in_params->data_buff_base_len = d_port->in_request.buf_len * d_port->in_request.num_bufs; in_params->data_buff_base_addr_iova = d_port->in_request.dma; in_params->sgt_xfer_rings = &d_port->in_request.sgt_trb_xfer_ring; in_params->sgt_data_buff = &d_port->in_request.sgt_data_buff; log_event_dbg("%s(): IN: sgt_xfer_rings:%pK sgt_data_buff:%pK\n", __func__, in_params->sgt_xfer_rings, in_params->sgt_data_buff); in_params->xfer_scratch.const_buffer_size = gsi_channel_info.const_buffer_size; in_params->xfer_scratch.depcmd_low_addr = Loading Loading @@ -344,6 +348,13 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) d_port->out_request.num_bufs; out_params->data_buff_base_addr_iova = d_port->out_request.dma; out_params->sgt_xfer_rings = &d_port->out_request.sgt_trb_xfer_ring; out_params->sgt_data_buff = &d_port->out_request.sgt_data_buff; log_event_dbg("%s(): OUT: sgt_xfer_rings:%pK sgt_data_buff:%pK\n", __func__, out_params->sgt_xfer_rings, out_params->sgt_data_buff); out_params->xfer_scratch.last_trb_addr_iova = gsi_channel_info.last_trb_addr; out_params->xfer_scratch.const_buffer_size = Loading Loading @@ -497,10 +508,12 @@ static void ipa_disconnect_work_handler(struct gsi_data_port *d_port) gsi->d_port.in_channel_handle = -EINVAL; gsi->d_port.out_channel_handle = -EINVAL; usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_FREE_TRBS); usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request, GSI_EP_OP_FREE_TRBS); if (gsi->d_port.out_ep) usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_FREE_TRBS); usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_FREE_TRBS); /* free buffers allocated with each TRB */ gsi_free_trb_buffer(gsi); Loading Loading @@ -1945,6 +1958,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi) ret = -ENOMEM; goto fail1; } dma_get_sgtable(dev->parent, &gsi->d_port.in_request.sgt_data_buff, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma, len_in); } if (gsi->d_port.out_ep && !gsi->d_port.out_request.buf_base_addr) { Loading @@ -1964,6 +1982,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi) ret = -ENOMEM; goto fail; } dma_get_sgtable(dev->parent, &gsi->d_port.out_request.sgt_data_buff, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma, len_out); } log_event_dbg("finished allocating trb's buffer\n"); Loading Loading @@ -1994,6 +2017,7 @@ static void gsi_free_trb_buffer(struct f_gsi *gsi) gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma); gsi->d_port.out_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.out_request.sgt_data_buff); } if (gsi->d_port.in_ep && Loading @@ -2004,6 +2028,7 @@ static void gsi_free_trb_buffer(struct f_gsi *gsi) gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.in_request.sgt_data_buff); } } Loading include/linux/usb/gadget.h +4 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ enum gsi_ep_op { * @db_reg_phs_addr_lsb: IPA channel doorbell register's physical address LSB * @mapped_db_reg_phs_addr_lsb: doorbell LSB IOVA address mapped with IOMMU * @db_reg_phs_addr_msb: IPA channel doorbell register's physical address MSB * @sgt_trb_xfer_ring: USB TRB ring related sgtable entries * @sgt_data_buff: Data buffer related sgtable entries */ struct usb_gsi_request { void *buf_base_addr; Loading @@ -93,6 +95,8 @@ struct usb_gsi_request { u32 db_reg_phs_addr_lsb; dma_addr_t mapped_db_reg_phs_addr_lsb; u32 db_reg_phs_addr_msb; struct sg_table sgt_trb_xfer_ring; struct sg_table sgt_data_buff; }; /* Loading Loading
drivers/usb/dwc3/dwc3-msm.c +23 −4 Original line number Diff line number Diff line Loading @@ -1061,6 +1061,8 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) struct dwc3_trb *trb; int num_trbs = (dep->direction) ? (2 * (req->num_bufs) + 2) : (req->num_bufs + 2); struct scatterlist *sg; struct sg_table *sgt; dep->trb_pool = dma_zalloc_coherent(dwc->sysdev, num_trbs * sizeof(struct dwc3_trb), Loading @@ -1073,6 +1075,19 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } dep->num_trbs = num_trbs; dma_get_sgtable(dwc->sysdev, &req->sgt_trb_xfer_ring, dep->trb_pool, dep->trb_pool_dma, num_trbs * sizeof(struct dwc3_trb)); sgt = &req->sgt_trb_xfer_ring; dev_dbg(dwc->dev, "%s(): trb_pool:%pK trb_pool_dma:%lx\n", __func__, dep->trb_pool, (unsigned long)dep->trb_pool_dma); for_each_sg(sgt->sgl, sg, sgt->nents, i) dev_dbg(dwc->dev, "%i: page_link:%lx offset:%x length:%x address:%lx\n", i, sg->page_link, sg->offset, sg->length, (unsigned long)sg->dma_address); /* IN direction */ if (dep->direction) { for (i = 0; i < num_trbs ; i++) { Loading Loading @@ -1138,11 +1153,13 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) } } pr_debug("%s: Initialized TRB Ring for %s\n", __func__, dep->name); dev_dbg(dwc->dev, "%s: Initialized TRB Ring for %s\n", __func__, dep->name); trb = &dep->trb_pool[0]; if (trb) { for (i = 0; i < num_trbs; i++) { pr_debug("TRB(%d): ADDRESS:%lx bpl:%x bph:%x size:%x ctrl:%x\n", dev_dbg(dwc->dev, "TRB %d: ADDR:%lx bpl:%x bph:%x sz:%x ctl:%x\n", i, (unsigned long)dwc3_trb_dma_offset(dep, &dep->trb_pool[i]), trb->bpl, trb->bph, trb->size, trb->ctrl); Loading @@ -1159,7 +1176,7 @@ static int gsi_prepare_trbs(struct usb_ep *ep, struct usb_gsi_request *req) * @usb_ep - pointer to usb_ep instance. * */ static void gsi_free_trbs(struct usb_ep *ep) static void gsi_free_trbs(struct usb_ep *ep, struct usb_gsi_request *req) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; Loading @@ -1176,6 +1193,7 @@ static void gsi_free_trbs(struct usb_ep *ep) dep->trb_pool = NULL; dep->trb_pool_dma = 0; } sg_free_table(&req->sgt_trb_xfer_ring); } /* * Configures GSI EPs. For GSI EPs we need to set interrupter numbers. Loading Loading @@ -1365,7 +1383,8 @@ static int dwc3_msm_gsi_ep_op(struct usb_ep *ep, break; case GSI_EP_OP_FREE_TRBS: dev_dbg(mdwc->dev, "EP_OP_FREE_TRBS for %s\n", ep->name); gsi_free_trbs(ep); request = (struct usb_gsi_request *)op_data; gsi_free_trbs(ep, request); break; case GSI_EP_OP_CONFIG: request = (struct usb_gsi_request *)op_data; Loading
drivers/usb/gadget/function/f_gsi.c +27 −2 Original line number Diff line number Diff line Loading @@ -307,6 +307,10 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) in_params->data_buff_base_len = d_port->in_request.buf_len * d_port->in_request.num_bufs; in_params->data_buff_base_addr_iova = d_port->in_request.dma; in_params->sgt_xfer_rings = &d_port->in_request.sgt_trb_xfer_ring; in_params->sgt_data_buff = &d_port->in_request.sgt_data_buff; log_event_dbg("%s(): IN: sgt_xfer_rings:%pK sgt_data_buff:%pK\n", __func__, in_params->sgt_xfer_rings, in_params->sgt_data_buff); in_params->xfer_scratch.const_buffer_size = gsi_channel_info.const_buffer_size; in_params->xfer_scratch.depcmd_low_addr = Loading Loading @@ -344,6 +348,13 @@ static int ipa_connect_channels(struct gsi_data_port *d_port) d_port->out_request.num_bufs; out_params->data_buff_base_addr_iova = d_port->out_request.dma; out_params->sgt_xfer_rings = &d_port->out_request.sgt_trb_xfer_ring; out_params->sgt_data_buff = &d_port->out_request.sgt_data_buff; log_event_dbg("%s(): OUT: sgt_xfer_rings:%pK sgt_data_buff:%pK\n", __func__, out_params->sgt_xfer_rings, out_params->sgt_data_buff); out_params->xfer_scratch.last_trb_addr_iova = gsi_channel_info.last_trb_addr; out_params->xfer_scratch.const_buffer_size = Loading Loading @@ -497,10 +508,12 @@ static void ipa_disconnect_work_handler(struct gsi_data_port *d_port) gsi->d_port.in_channel_handle = -EINVAL; gsi->d_port.out_channel_handle = -EINVAL; usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_FREE_TRBS); usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request, GSI_EP_OP_FREE_TRBS); if (gsi->d_port.out_ep) usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_FREE_TRBS); usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request, GSI_EP_OP_FREE_TRBS); /* free buffers allocated with each TRB */ gsi_free_trb_buffer(gsi); Loading Loading @@ -1945,6 +1958,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi) ret = -ENOMEM; goto fail1; } dma_get_sgtable(dev->parent, &gsi->d_port.in_request.sgt_data_buff, gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma, len_in); } if (gsi->d_port.out_ep && !gsi->d_port.out_request.buf_base_addr) { Loading @@ -1964,6 +1982,11 @@ static int gsi_alloc_trb_buffer(struct f_gsi *gsi) ret = -ENOMEM; goto fail; } dma_get_sgtable(dev->parent, &gsi->d_port.out_request.sgt_data_buff, gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma, len_out); } log_event_dbg("finished allocating trb's buffer\n"); Loading Loading @@ -1994,6 +2017,7 @@ static void gsi_free_trb_buffer(struct f_gsi *gsi) gsi->d_port.out_request.buf_base_addr, gsi->d_port.out_request.dma); gsi->d_port.out_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.out_request.sgt_data_buff); } if (gsi->d_port.in_ep && Loading @@ -2004,6 +2028,7 @@ static void gsi_free_trb_buffer(struct f_gsi *gsi) gsi->d_port.in_request.buf_base_addr, gsi->d_port.in_request.dma); gsi->d_port.in_request.buf_base_addr = NULL; sg_free_table(&gsi->d_port.in_request.sgt_data_buff); } } Loading
include/linux/usb/gadget.h +4 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ enum gsi_ep_op { * @db_reg_phs_addr_lsb: IPA channel doorbell register's physical address LSB * @mapped_db_reg_phs_addr_lsb: doorbell LSB IOVA address mapped with IOMMU * @db_reg_phs_addr_msb: IPA channel doorbell register's physical address MSB * @sgt_trb_xfer_ring: USB TRB ring related sgtable entries * @sgt_data_buff: Data buffer related sgtable entries */ struct usb_gsi_request { void *buf_base_addr; Loading @@ -93,6 +95,8 @@ struct usb_gsi_request { u32 db_reg_phs_addr_lsb; dma_addr_t mapped_db_reg_phs_addr_lsb; u32 db_reg_phs_addr_msb; struct sg_table sgt_trb_xfer_ring; struct sg_table sgt_data_buff; }; /* Loading