diff options
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/ioat/dma.h | 1 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v2.c | 24 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 5 |
3 files changed, 27 insertions, 3 deletions
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 6d3a73b57e54..5216c8a92a21 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -97,6 +97,7 @@ struct ioat_chan_common { | |||
97 | #define IOAT_RESET_PENDING 2 | 97 | #define IOAT_RESET_PENDING 2 |
98 | #define IOAT_KOBJ_INIT_FAIL 3 | 98 | #define IOAT_KOBJ_INIT_FAIL 3 |
99 | #define IOAT_RESHAPE_PENDING 4 | 99 | #define IOAT_RESHAPE_PENDING 4 |
100 | #define IOAT_RUN 5 | ||
100 | struct timer_list timer; | 101 | struct timer_list timer; |
101 | #define COMPLETION_TIMEOUT msecs_to_jiffies(100) | 102 | #define COMPLETION_TIMEOUT msecs_to_jiffies(100) |
102 | #define IDLE_TIMEOUT msecs_to_jiffies(2000) | 103 | #define IDLE_TIMEOUT msecs_to_jiffies(2000) |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 3c8b32a83794..216f9d383b5b 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -287,7 +287,10 @@ void ioat2_timer_event(unsigned long data) | |||
287 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 287 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
288 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | 288 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", |
289 | __func__, chanerr); | 289 | __func__, chanerr); |
290 | BUG_ON(is_ioat_bug(chanerr)); | 290 | if (test_bit(IOAT_RUN, &chan->state)) |
291 | BUG_ON(is_ioat_bug(chanerr)); | ||
292 | else /* we never got off the ground */ | ||
293 | return; | ||
291 | } | 294 | } |
292 | 295 | ||
293 | /* if we haven't made progress and we have already | 296 | /* if we haven't made progress and we have already |
@@ -492,6 +495,8 @@ static struct ioat_ring_ent **ioat2_alloc_ring(struct dma_chan *c, int order, gf | |||
492 | return ring; | 495 | return ring; |
493 | } | 496 | } |
494 | 497 | ||
498 | void ioat2_free_chan_resources(struct dma_chan *c); | ||
499 | |||
495 | /* ioat2_alloc_chan_resources - allocate/initialize ioat2 descriptor ring | 500 | /* ioat2_alloc_chan_resources - allocate/initialize ioat2 descriptor ring |
496 | * @chan: channel to be initialized | 501 | * @chan: channel to be initialized |
497 | */ | 502 | */ |
@@ -500,6 +505,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
500 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); | 505 | struct ioat2_dma_chan *ioat = to_ioat2_chan(c); |
501 | struct ioat_chan_common *chan = &ioat->base; | 506 | struct ioat_chan_common *chan = &ioat->base; |
502 | struct ioat_ring_ent **ring; | 507 | struct ioat_ring_ent **ring; |
508 | u64 status; | ||
503 | int order; | 509 | int order; |
504 | 510 | ||
505 | /* have we already been set up? */ | 511 | /* have we already been set up? */ |
@@ -540,7 +546,20 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
540 | tasklet_enable(&chan->cleanup_task); | 546 | tasklet_enable(&chan->cleanup_task); |
541 | ioat2_start_null_desc(ioat); | 547 | ioat2_start_null_desc(ioat); |
542 | 548 | ||
543 | return 1 << ioat->alloc_order; | 549 | /* check that we got off the ground */ |
550 | udelay(5); | ||
551 | status = ioat_chansts(chan); | ||
552 | if (is_ioat_active(status) || is_ioat_idle(status)) { | ||
553 | set_bit(IOAT_RUN, &chan->state); | ||
554 | return 1 << ioat->alloc_order; | ||
555 | } else { | ||
556 | u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | ||
557 | |||
558 | dev_WARN(to_dev(chan), | ||
559 | "failed to start channel chanerr: %#x\n", chanerr); | ||
560 | ioat2_free_chan_resources(c); | ||
561 | return -EFAULT; | ||
562 | } | ||
544 | } | 563 | } |
545 | 564 | ||
546 | bool reshape_ring(struct ioat2_dma_chan *ioat, int order) | 565 | bool reshape_ring(struct ioat2_dma_chan *ioat, int order) |
@@ -778,6 +797,7 @@ void ioat2_free_chan_resources(struct dma_chan *c) | |||
778 | del_timer_sync(&chan->timer); | 797 | del_timer_sync(&chan->timer); |
779 | device->cleanup_fn((unsigned long) c); | 798 | device->cleanup_fn((unsigned long) c); |
780 | device->reset_hw(chan); | 799 | device->reset_hw(chan); |
800 | clear_bit(IOAT_RUN, &chan->state); | ||
781 | 801 | ||
782 | spin_lock_bh(&chan->cleanup_lock); | 802 | spin_lock_bh(&chan->cleanup_lock); |
783 | spin_lock_bh(&ioat->prep_lock); | 803 | spin_lock_bh(&ioat->prep_lock); |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 1cdd22e1051b..d0f499098479 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -361,7 +361,10 @@ static void ioat3_timer_event(unsigned long data) | |||
361 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 361 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
362 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | 362 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", |
363 | __func__, chanerr); | 363 | __func__, chanerr); |
364 | BUG_ON(is_ioat_bug(chanerr)); | 364 | if (test_bit(IOAT_RUN, &chan->state)) |
365 | BUG_ON(is_ioat_bug(chanerr)); | ||
366 | else /* we never got off the ground */ | ||
367 | return; | ||
365 | } | 368 | } |
366 | 369 | ||
367 | /* if we haven't made progress and we have already | 370 | /* if we haven't made progress and we have already |