diff options
Diffstat (limited to 'drivers/dma/ioat/dma_v2.c')
-rw-r--r-- | drivers/dma/ioat/dma_v2.c | 24 |
1 files changed, 22 insertions, 2 deletions
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); |