usb: renesas_usbhs: fix the usb_pkt_pop()

This patch fixes the usb_pkt_pop(). If a gadget driver calls
usb_ep_dequeue(), this driver will call the usb_pkt_pop().
So, the usb_pkt_pop() should cancel the transaction.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
Yoshihiro Shimoda 2014-08-22 20:14:28 +09:00 committed by Felipe Balbi
parent c0ed8b23b2
commit 2743e7f90d

View File

@ -108,19 +108,45 @@ static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
return list_first_entry(&pipe->list, struct usbhs_pkt, node); return list_first_entry(&pipe->list, struct usbhs_pkt, node);
} }
static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
struct usbhs_fifo *fifo);
static void usbhsf_fifo_unselect(struct usbhs_pipe *pipe,
struct usbhs_fifo *fifo);
static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo,
struct usbhs_pkt *pkt);
#define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1)
#define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0)
static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map);
struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
{ {
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe);
unsigned long flags; unsigned long flags;
/******************** spin lock ********************/ /******************** spin lock ********************/
usbhs_lock(priv, flags); usbhs_lock(priv, flags);
usbhs_pipe_disable(pipe);
if (!pkt) if (!pkt)
pkt = __usbhsf_pkt_get(pipe); pkt = __usbhsf_pkt_get(pipe);
if (pkt) if (pkt) {
struct dma_chan *chan = NULL;
if (fifo)
chan = usbhsf_dma_chan_get(fifo, pkt);
if (chan) {
dmaengine_terminate_all(chan);
usbhsf_fifo_clear(pipe, fifo);
usbhsf_dma_unmap(pkt);
}
__usbhsf_pkt_del(pkt); __usbhsf_pkt_del(pkt);
}
if (fifo)
usbhsf_fifo_unselect(pipe, fifo);
usbhs_unlock(priv, flags); usbhs_unlock(priv, flags);
/******************** spin unlock ******************/ /******************** spin unlock ******************/
@ -778,8 +804,6 @@ static void __usbhsf_dma_ctrl(struct usbhs_pipe *pipe,
usbhs_bset(priv, fifo->sel, DREQE, dreqe); usbhs_bset(priv, fifo->sel, DREQE, dreqe);
} }
#define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1)
#define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0)
static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map) static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
{ {
struct usbhs_pipe *pipe = pkt->pipe; struct usbhs_pipe *pipe = pkt->pipe;