aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2013-10-22 06:14:05 -0400
committerVinod Koul <vinod.koul@intel.com>2013-11-12 03:58:24 -0500
commit1e378a6d7789bf142319c6207398367336c49082 (patch)
tree520f3cdd71c21e1a55df6786a2e5747bc36f7bb1 /drivers/dma
parent706ff628f0669f28e370d2ad30672e5032dc64b2 (diff)
dma: cppi41: redo descriptor collection in abort case
Most of the logic here is try and error since what actually happens does not match the trm or I miss read it. My first assumption was that the queue on which the tear-down descriptor completes (their own complete queue vs "active descriptor" complete queue) depends on the transfer direction. This seems not to be true because I manage to trigger | WARN_ON(c->desc_phys != desc_phys); and the other few were fine means the tear-down descriptor was valid but on different queue. This patch changes the logic here to look on both queues for the descriptor. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/cppi41.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index 2500f60393f4..ec87492cfb07 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -563,36 +563,26 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c)
563 c->td_retry = 100; 563 c->td_retry = 100;
564 } 564 }
565 565
566 if (!c->td_seen) { 566 if (!c->td_seen || !c->td_desc_seen) {
567 unsigned td_comp_queue;
568 567
569 if (c->is_tx) 568 desc_phys = cppi41_pop_desc(cdd, cdd->td_queue.complete);
570 td_comp_queue = cdd->td_queue.complete; 569 if (!desc_phys)
571 else 570 desc_phys = cppi41_pop_desc(cdd, c->q_comp_num);
572 td_comp_queue = c->q_comp_num;
573 571
574 desc_phys = cppi41_pop_desc(cdd, td_comp_queue); 572 if (desc_phys == c->desc_phys) {
575 if (desc_phys) { 573 c->td_desc_seen = 1;
576 __iormb(); 574
575 } else if (desc_phys == td_desc_phys) {
576 u32 pd0;
577 577
578 if (desc_phys == td_desc_phys) {
579 u32 pd0;
580 pd0 = td->pd0;
581 WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD);
582 WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX));
583 WARN_ON((pd0 & 0x1f) != c->port_num);
584 } else {
585 WARN_ON_ONCE(1);
586 }
587 c->td_seen = 1;
588 }
589 }
590 if (!c->td_desc_seen) {
591 desc_phys = cppi41_pop_desc(cdd, c->q_comp_num);
592 if (desc_phys) {
593 __iormb(); 578 __iormb();
594 WARN_ON(c->desc_phys != desc_phys); 579 pd0 = td->pd0;
595 c->td_desc_seen = 1; 580 WARN_ON((pd0 >> DESC_TYPE) != DESC_TYPE_TEARD);
581 WARN_ON(!c->is_tx && !(pd0 & TD_DESC_IS_RX));
582 WARN_ON((pd0 & 0x1f) != c->port_num);
583 c->td_seen = 1;
584 } else if (desc_phys) {
585 WARN_ON_ONCE(1);
596 } 586 }
597 } 587 }
598 c->td_retry--; 588 c->td_retry--;