aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@nxp.com>2020-09-10 17:11:23 +0800
committerFelipe Balbi <balbi@kernel.org>2020-10-02 09:57:45 +0300
commitabc6b579048e2084ea28c677dd11106d67fe8498 (patch)
treeaeb73ba0accfa3a31d0da5939290f68d25bdb2f6 /drivers
parentdt-bindings: document a new quirk for dwc3 (diff)
downloadwireguard-linux-abc6b579048e2084ea28c677dd11106d67fe8498.tar.xz
wireguard-linux-abc6b579048e2084ea28c677dd11106d67fe8498.zip
usb: cdns3: gadget: using correct sg operations
It needs to use request->num_mapped_sgs to indicate mapped sg number, the request->num_sgs is the sg number before the mapping. These two entries have different values for the platforms which iommu or swiotlb is used. Besides, it needs to use correct sg APIs for mapped sg list for TRB assignment. Signed-off-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/cdns3/gadget.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 26ba41700672..caf011f59a4c 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -1098,11 +1098,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
u32 control;
int pcs;
u16 total_tdl = 0;
+ struct scatterlist *s = NULL;
+ bool sg_supported = !!(request->num_mapped_sgs);
if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
num_trb = priv_ep->interval;
else
- num_trb = request->num_sgs ? request->num_sgs : 1;
+ num_trb = sg_supported ? request->num_mapped_sgs : 1;
if (num_trb > priv_ep->free_trbs) {
priv_ep->flags |= EP_RING_FULL;
@@ -1162,6 +1164,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
if (priv_dev->dev_ver <= DEV_VER_V2)
togle_pcs = cdns3_wa1_update_guard(priv_ep, trb);
+ if (sg_supported)
+ s = request->sg;
+
/* set incorrect Cycle Bit for first trb*/
control = priv_ep->pcs ? 0 : TRB_CYCLE;
@@ -1171,13 +1176,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
/* fill TRB */
control |= TRB_TYPE(TRB_NORMAL);
- trb->buffer = cpu_to_le32(TRB_BUFFER(request->num_sgs == 0
- ? trb_dma : request->sg[sg_iter].dma_address));
-
- if (likely(!request->num_sgs))
+ if (sg_supported) {
+ trb->buffer = cpu_to_le32(TRB_BUFFER(sg_dma_address(s)));
+ length = sg_dma_len(s);
+ } else {
+ trb->buffer = cpu_to_le32(TRB_BUFFER(trb_dma));
length = request->length;
- else
- length = request->sg[sg_iter].length;
+ }
if (likely(priv_dev->dev_ver >= DEV_VER_V2))
td_size = DIV_ROUND_UP(length,
@@ -1215,6 +1220,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
else
priv_req->trb->control = cpu_to_le32(control);
+ if (sg_supported)
+ s = sg_next(s);
+
control = 0;
++sg_iter;
priv_req->end_trb = priv_ep->enqueue;