|
@@ -544,6 +544,7 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
|
|
usbhsf_send_terminator(pipe, fifo);
|
|
usbhsf_send_terminator(pipe, fifo);
|
|
|
|
|
|
usbhsf_tx_irq_ctrl(pipe, !*is_done);
|
|
usbhsf_tx_irq_ctrl(pipe, !*is_done);
|
|
|
|
+ usbhs_pipe_running(pipe, !*is_done);
|
|
usbhs_pipe_enable(pipe);
|
|
usbhs_pipe_enable(pipe);
|
|
|
|
|
|
dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n",
|
|
dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n",
|
|
@@ -570,12 +571,21 @@ usbhs_fifo_write_busy:
|
|
* retry in interrupt
|
|
* retry in interrupt
|
|
*/
|
|
*/
|
|
usbhsf_tx_irq_ctrl(pipe, 1);
|
|
usbhsf_tx_irq_ctrl(pipe, 1);
|
|
|
|
+ usbhs_pipe_running(pipe, 1);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int usbhsf_pio_prepare_push(struct usbhs_pkt *pkt, int *is_done)
|
|
|
|
+{
|
|
|
|
+ if (usbhs_pipe_is_running(pkt->pipe))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return usbhsf_pio_try_push(pkt, is_done);
|
|
|
|
+}
|
|
|
|
+
|
|
struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = {
|
|
struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = {
|
|
- .prepare = usbhsf_pio_try_push,
|
|
|
|
|
|
+ .prepare = usbhsf_pio_prepare_push,
|
|
.try_run = usbhsf_pio_try_push,
|
|
.try_run = usbhsf_pio_try_push,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -589,6 +599,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
|
|
if (usbhs_pipe_is_busy(pipe))
|
|
if (usbhs_pipe_is_busy(pipe))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ if (usbhs_pipe_is_running(pipe))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* pipe enable to prepare packet receive
|
|
* pipe enable to prepare packet receive
|
|
*/
|
|
*/
|
|
@@ -597,6 +610,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
|
|
|
|
|
|
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
|
|
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
|
|
usbhs_pipe_enable(pipe);
|
|
usbhs_pipe_enable(pipe);
|
|
|
|
+ usbhs_pipe_running(pipe, 1);
|
|
usbhsf_rx_irq_ctrl(pipe, 1);
|
|
usbhsf_rx_irq_ctrl(pipe, 1);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -642,6 +656,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done)
|
|
(total_len < maxp)) { /* short packet */
|
|
(total_len < maxp)) { /* short packet */
|
|
*is_done = 1;
|
|
*is_done = 1;
|
|
usbhsf_rx_irq_ctrl(pipe, 0);
|
|
usbhsf_rx_irq_ctrl(pipe, 0);
|
|
|
|
+ usbhs_pipe_running(pipe, 0);
|
|
usbhs_pipe_disable(pipe); /* disable pipe first */
|
|
usbhs_pipe_disable(pipe); /* disable pipe first */
|
|
}
|
|
}
|
|
|
|
|
|
@@ -805,6 +820,7 @@ static void xfer_work(struct work_struct *work)
|
|
dev_dbg(dev, " %s %d (%d/ %d)\n",
|
|
dev_dbg(dev, " %s %d (%d/ %d)\n",
|
|
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
|
|
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
|
|
|
|
|
|
|
|
+ usbhs_pipe_running(pipe, 1);
|
|
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
|
|
usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
|
|
usbhs_pipe_enable(pipe);
|
|
usbhs_pipe_enable(pipe);
|
|
usbhsf_dma_start(pipe, fifo);
|
|
usbhsf_dma_start(pipe, fifo);
|
|
@@ -836,6 +852,10 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
|
|
if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
|
if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
|
goto usbhsf_pio_prepare_push;
|
|
goto usbhsf_pio_prepare_push;
|
|
|
|
|
|
|
|
+ /* return at this time if the pipe is running */
|
|
|
|
+ if (usbhs_pipe_is_running(pipe))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
/* get enable DMA fifo */
|
|
/* get enable DMA fifo */
|
|
fifo = usbhsf_get_dma_fifo(priv, pkt);
|
|
fifo = usbhsf_get_dma_fifo(priv, pkt);
|
|
if (!fifo)
|
|
if (!fifo)
|
|
@@ -873,6 +893,7 @@ static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done)
|
|
pkt->actual = pkt->trans;
|
|
pkt->actual = pkt->trans;
|
|
|
|
|
|
*is_done = !pkt->zero; /* send zero packet ? */
|
|
*is_done = !pkt->zero; /* send zero packet ? */
|
|
|
|
+ usbhs_pipe_running(pipe, !*is_done);
|
|
|
|
|
|
usbhsf_dma_stop(pipe, pipe->fifo);
|
|
usbhsf_dma_stop(pipe, pipe->fifo);
|
|
usbhsf_dma_unmap(pkt);
|
|
usbhsf_dma_unmap(pkt);
|
|
@@ -972,8 +993,10 @@ static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done)
|
|
if ((pkt->actual == pkt->length) || /* receive all data */
|
|
if ((pkt->actual == pkt->length) || /* receive all data */
|
|
(pkt->trans < maxp)) { /* short packet */
|
|
(pkt->trans < maxp)) { /* short packet */
|
|
*is_done = 1;
|
|
*is_done = 1;
|
|
|
|
+ usbhs_pipe_running(pipe, 0);
|
|
} else {
|
|
} else {
|
|
/* re-enable */
|
|
/* re-enable */
|
|
|
|
+ usbhs_pipe_running(pipe, 0);
|
|
usbhsf_prepare_pop(pkt, is_done);
|
|
usbhsf_prepare_pop(pkt, is_done);
|
|
}
|
|
}
|
|
|
|
|