aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_sdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_sdma.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sdma.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c
index 5918cafb880b..1974df7a9f78 100644
--- a/drivers/infiniband/hw/ipath/ipath_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_sdma.c
@@ -230,7 +230,6 @@ static void dump_sdma_state(struct ipath_devdata *dd)
230static void sdma_abort_task(unsigned long opaque) 230static void sdma_abort_task(unsigned long opaque)
231{ 231{
232 struct ipath_devdata *dd = (struct ipath_devdata *) opaque; 232 struct ipath_devdata *dd = (struct ipath_devdata *) opaque;
233 int kick = 0;
234 u64 status; 233 u64 status;
235 unsigned long flags; 234 unsigned long flags;
236 235
@@ -308,30 +307,26 @@ static void sdma_abort_task(unsigned long opaque)
308 /* done with sdma state for a bit */ 307 /* done with sdma state for a bit */
309 spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); 308 spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
310 309
311 /* restart sdma engine */ 310 /*
311 * Don't restart sdma here. Wait until link is up to ACTIVE.
312 * VL15 MADs used to bring the link up use PIO, and multiple
313 * link transitions otherwise cause the sdma engine to be
314 * stopped and started multiple times.
315 * The disable is done here, including the shadow, so the
316 * state is kept consistent.
317 * See ipath_restart_sdma() for the actual starting of sdma.
318 */
312 spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); 319 spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
313 dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE; 320 dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE;
314 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, 321 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
315 dd->ipath_sendctrl); 322 dd->ipath_sendctrl);
316 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 323 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
317 dd->ipath_sendctrl |= INFINIPATH_S_SDMAENABLE;
318 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
319 dd->ipath_sendctrl);
320 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
321 spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); 324 spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
322 kick = 1;
323 ipath_dbg("sdma restarted from abort\n");
324
325 /* now clear status bits */
326 spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
327 __clear_bit(IPATH_SDMA_ABORTING, &dd->ipath_sdma_status);
328 __clear_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
329 __clear_bit(IPATH_SDMA_DISABLED, &dd->ipath_sdma_status);
330 325
331 /* make sure I see next message */ 326 /* make sure I see next message */
332 dd->ipath_sdma_abort_jiffies = 0; 327 dd->ipath_sdma_abort_jiffies = 0;
333 328
334 goto unlock; 329 goto done;
335 } 330 }
336 331
337resched: 332resched:
@@ -353,10 +348,8 @@ resched_noprint:
353 348
354unlock: 349unlock:
355 spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); 350 spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
356 351done:
357 /* kick upper layers */ 352 return;
358 if (kick)
359 ipath_ib_piobufavail(dd->verbs_dev);
360} 353}
361 354
362/* 355/*
@@ -481,10 +474,14 @@ int setup_sdma(struct ipath_devdata *dd)
481 tasklet_init(&dd->ipath_sdma_abort_task, sdma_abort_task, 474 tasklet_init(&dd->ipath_sdma_abort_task, sdma_abort_task,
482 (unsigned long) dd); 475 (unsigned long) dd);
483 476
484 /* Turn on SDMA */ 477 /*
478 * No use to turn on SDMA here, as link is probably not ACTIVE
479 * Just mark it RUNNING and enable the interrupt, and let the
480 * ipath_restart_sdma() on link transition to ACTIVE actually
481 * enable it.
482 */
485 spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); 483 spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
486 dd->ipath_sendctrl |= INFINIPATH_S_SDMAENABLE | 484 dd->ipath_sendctrl |= INFINIPATH_S_SDMAINTENABLE;
487 INFINIPATH_S_SDMAINTENABLE;
488 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); 485 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
489 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); 486 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
490 __set_bit(IPATH_SDMA_RUNNING, &dd->ipath_sdma_status); 487 __set_bit(IPATH_SDMA_RUNNING, &dd->ipath_sdma_status);
@@ -572,6 +569,56 @@ void teardown_sdma(struct ipath_devdata *dd)
572 sdma_descq, sdma_descq_phys); 569 sdma_descq, sdma_descq_phys);
573} 570}
574 571
572/*
573 * [Re]start SDMA, if we use it, and it's not already OK.
574 * This is called on transition to link ACTIVE, either the first or
575 * subsequent times.
576 */
577void ipath_restart_sdma(struct ipath_devdata *dd)
578{
579 unsigned long flags;
580 int needed = 1;
581
582 if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA))
583 goto bail;
584
585 /*
586 * First, make sure we should, which is to say,
587 * check that we are "RUNNING" (not in teardown)
588 * and not "SHUTDOWN"
589 */
590 spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
591 if (!test_bit(IPATH_SDMA_RUNNING, &dd->ipath_sdma_status)
592 || test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
593 needed = 0;
594 else {
595 __clear_bit(IPATH_SDMA_DISABLED, &dd->ipath_sdma_status);
596 __clear_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
597 __clear_bit(IPATH_SDMA_ABORTING, &dd->ipath_sdma_status);
598 }
599 spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
600 if (!needed) {
601 ipath_dbg("invalid attempt to restart SDMA, status 0x%016llx\n",
602 dd->ipath_sdma_status);
603 goto bail;
604 }
605 spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
606 /*
607 * First clear, just to be safe. Enable is only done
608 * in chip on 0->1 transition
609 */
610 dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE;
611 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
612 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
613 dd->ipath_sendctrl |= INFINIPATH_S_SDMAENABLE;
614 ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
615 ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
616 spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
617
618bail:
619 return;
620}
621
575static inline void make_sdma_desc(struct ipath_devdata *dd, 622static inline void make_sdma_desc(struct ipath_devdata *dd,
576 u64 *sdmadesc, u64 addr, u64 dwlen, u64 dwoffset) 623 u64 *sdmadesc, u64 addr, u64 dwlen, u64 dwoffset)
577{ 624{