提交 13bbfb5c 编写于 作者: D Daniel Mack 提交者: Vinod Koul

dma: cppi41: handle 0-length packets

When a 0-length packet is received on the bus, desc->pd0 yields 1,
which confuses the driver's users. This information is clearly wrong
and not in accordance to the datasheet, but it's been observed on an
AM335x board, very reproducible.

Fix this by looking at bit 19 in PD2 of the completed packet. This bit
will tell us if a zero-length packet was received on a queue. If it's
set, ignore the value in PD0 and report a total length of 0 instead.
Signed-off-by: NDaniel Mack <zonque@gmail.com>
Signed-off-by: NVinod Koul <vinod.koul@intel.com>
上级 4c834452
...@@ -86,6 +86,9 @@ ...@@ -86,6 +86,9 @@
#define USBSS_IRQ_PD_COMP (1 << 2) #define USBSS_IRQ_PD_COMP (1 << 2)
/* Packet Descriptor */
#define PD2_ZERO_LENGTH (1 << 19)
struct cppi41_channel { struct cppi41_channel {
struct dma_chan chan; struct dma_chan chan;
struct dma_async_tx_descriptor txd; struct dma_async_tx_descriptor txd;
...@@ -307,7 +310,7 @@ static irqreturn_t cppi41_irq(int irq, void *data) ...@@ -307,7 +310,7 @@ static irqreturn_t cppi41_irq(int irq, void *data)
__iormb(); __iormb();
while (val) { while (val) {
u32 desc; u32 desc, len;
q_num = __fls(val); q_num = __fls(val);
val &= ~(1 << q_num); val &= ~(1 << q_num);
...@@ -319,9 +322,13 @@ static irqreturn_t cppi41_irq(int irq, void *data) ...@@ -319,9 +322,13 @@ static irqreturn_t cppi41_irq(int irq, void *data)
q_num, desc); q_num, desc);
continue; continue;
} }
c->residue = pd_trans_len(c->desc->pd6) -
pd_trans_len(c->desc->pd0);
if (c->desc->pd2 & PD2_ZERO_LENGTH)
len = 0;
else
len = pd_trans_len(c->desc->pd0);
c->residue = pd_trans_len(c->desc->pd6) - len;
dma_cookie_complete(&c->txd); dma_cookie_complete(&c->txd);
c->txd.callback(c->txd.callback_param); c->txd.callback(c->txd.callback_param);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册