diff options
author | Michael Grzeschik <m.grzeschik@pengutronix.de> | 2011-10-10 12:38:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-14 14:51:27 -0500 |
commit | 954aad8cd18c928e2db5229f6fa71c80d1c3d8b5 (patch) | |
tree | b14aa643608ee6ff2aaa861791f05c009ba3983f /drivers/usb/gadget | |
parent | 001428e4871d6c62f5e16c62df681624d8b480c1 (diff) |
USB: ci13xxx_udc: fix logic to mark request dma addresses as invalid
The current driver sets the request's dma addr (mReq->req.dma) to 0 to
mark the DMA address as not valid. However some gadget drivers
(e.g. gadgetfs) set the request's dma addr to DMA_ADDR_INVALID to mark
the address as invalid. This leads to bogus data send because the
ci13xxx_udc driver assumes the request has already been mapped.
This patch fixes the problem, by using DMA_ADDR_INVALID instead of 0
to mark the request's DMA address as invalid.
Tested-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 83428f56253b..ae6c0010f5e7 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -71,6 +71,9 @@ | |||
71 | /****************************************************************************** | 71 | /****************************************************************************** |
72 | * DEFINE | 72 | * DEFINE |
73 | *****************************************************************************/ | 73 | *****************************************************************************/ |
74 | |||
75 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
76 | |||
74 | /* ctrl register bank access */ | 77 | /* ctrl register bank access */ |
75 | static DEFINE_SPINLOCK(udc_lock); | 78 | static DEFINE_SPINLOCK(udc_lock); |
76 | 79 | ||
@@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1434 | return -EALREADY; | 1437 | return -EALREADY; |
1435 | 1438 | ||
1436 | mReq->req.status = -EALREADY; | 1439 | mReq->req.status = -EALREADY; |
1437 | if (length && !mReq->req.dma) { | 1440 | if (length && mReq->req.dma == DMA_ADDR_INVALID) { |
1438 | mReq->req.dma = \ | 1441 | mReq->req.dma = \ |
1439 | dma_map_single(mEp->device, mReq->req.buf, | 1442 | dma_map_single(mEp->device, mReq->req.buf, |
1440 | length, mEp->dir ? DMA_TO_DEVICE : | 1443 | length, mEp->dir ? DMA_TO_DEVICE : |
@@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1453 | dma_unmap_single(mEp->device, mReq->req.dma, | 1456 | dma_unmap_single(mEp->device, mReq->req.dma, |
1454 | length, mEp->dir ? DMA_TO_DEVICE : | 1457 | length, mEp->dir ? DMA_TO_DEVICE : |
1455 | DMA_FROM_DEVICE); | 1458 | DMA_FROM_DEVICE); |
1456 | mReq->req.dma = 0; | 1459 | mReq->req.dma = DMA_ADDR_INVALID; |
1457 | mReq->map = 0; | 1460 | mReq->map = 0; |
1458 | } | 1461 | } |
1459 | return -ENOMEM; | 1462 | return -ENOMEM; |
@@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) | |||
1549 | if (mReq->map) { | 1552 | if (mReq->map) { |
1550 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | 1553 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, |
1551 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 1554 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
1552 | mReq->req.dma = 0; | 1555 | mReq->req.dma = DMA_ADDR_INVALID; |
1553 | mReq->map = 0; | 1556 | mReq->map = 0; |
1554 | } | 1557 | } |
1555 | 1558 | ||
@@ -2189,6 +2192,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
2189 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); | 2192 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); |
2190 | if (mReq != NULL) { | 2193 | if (mReq != NULL) { |
2191 | INIT_LIST_HEAD(&mReq->queue); | 2194 | INIT_LIST_HEAD(&mReq->queue); |
2195 | mReq->req.dma = DMA_ADDR_INVALID; | ||
2192 | 2196 | ||
2193 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, | 2197 | mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, |
2194 | &mReq->dma); | 2198 | &mReq->dma); |
@@ -2328,7 +2332,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2328 | if (mReq->map) { | 2332 | if (mReq->map) { |
2329 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, | 2333 | dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, |
2330 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | 2334 | mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); |
2331 | mReq->req.dma = 0; | 2335 | mReq->req.dma = DMA_ADDR_INVALID; |
2332 | mReq->map = 0; | 2336 | mReq->map = 0; |
2333 | } | 2337 | } |
2334 | req->status = -ECONNRESET; | 2338 | req->status = -ECONNRESET; |