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>
This commit is contained in:
parent
001428e487
commit
954aad8cd1
|
@ -71,6 +71,9 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* DEFINE
|
* DEFINE
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
|
||||||
|
|
||||||
/* ctrl register bank access */
|
/* ctrl register bank access */
|
||||||
static DEFINE_SPINLOCK(udc_lock);
|
static DEFINE_SPINLOCK(udc_lock);
|
||||||
|
|
||||||
|
@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
|
|
||||||
mReq->req.status = -EALREADY;
|
mReq->req.status = -EALREADY;
|
||||||
if (length && !mReq->req.dma) {
|
if (length && mReq->req.dma == DMA_ADDR_INVALID) {
|
||||||
mReq->req.dma = \
|
mReq->req.dma = \
|
||||||
dma_map_single(mEp->device, mReq->req.buf,
|
dma_map_single(mEp->device, mReq->req.buf,
|
||||||
length, mEp->dir ? DMA_TO_DEVICE :
|
length, mEp->dir ? DMA_TO_DEVICE :
|
||||||
|
@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
||||||
dma_unmap_single(mEp->device, mReq->req.dma,
|
dma_unmap_single(mEp->device, mReq->req.dma,
|
||||||
length, mEp->dir ? DMA_TO_DEVICE :
|
length, mEp->dir ? DMA_TO_DEVICE :
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
mReq->req.dma = 0;
|
mReq->req.dma = DMA_ADDR_INVALID;
|
||||||
mReq->map = 0;
|
mReq->map = 0;
|
||||||
}
|
}
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
||||||
if (mReq->map) {
|
if (mReq->map) {
|
||||||
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
||||||
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||||
mReq->req.dma = 0;
|
mReq->req.dma = DMA_ADDR_INVALID;
|
||||||
mReq->map = 0;
|
mReq->map = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2189,6 +2192,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
|
||||||
mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
|
mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
|
||||||
if (mReq != NULL) {
|
if (mReq != NULL) {
|
||||||
INIT_LIST_HEAD(&mReq->queue);
|
INIT_LIST_HEAD(&mReq->queue);
|
||||||
|
mReq->req.dma = DMA_ADDR_INVALID;
|
||||||
|
|
||||||
mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
|
mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
|
||||||
&mReq->dma);
|
&mReq->dma);
|
||||||
|
@ -2328,7 +2332,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
||||||
if (mReq->map) {
|
if (mReq->map) {
|
||||||
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
||||||
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||||
mReq->req.dma = 0;
|
mReq->req.dma = DMA_ADDR_INVALID;
|
||||||
mReq->map = 0;
|
mReq->map = 0;
|
||||||
}
|
}
|
||||||
req->status = -ECONNRESET;
|
req->status = -ECONNRESET;
|
||||||
|
|
Loading…
Reference in New Issue