aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c23
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c36
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h5
3 files changed, 42 insertions, 22 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 1245180f210c..a3141bbc177a 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -138,19 +138,6 @@ static struct pci_driver ipath_driver = {
138 }, 138 },
139}; 139};
140 140
141static void ipath_check_status(struct work_struct *work)
142{
143 struct ipath_devdata *dd = container_of(work, struct ipath_devdata,
144 status_work.work);
145
146 /*
147 * If we don't have any interrupts, let the user know and
148 * don't bother checking again.
149 */
150 if (dd->ipath_int_counter == 0)
151 dev_err(&dd->pcidev->dev, "No interrupts detected.\n");
152}
153
154static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev, 141static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
155 u32 *bar0, u32 *bar1) 142 u32 *bar0, u32 *bar1)
156{ 143{
@@ -218,8 +205,6 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
218 dd->pcidev = pdev; 205 dd->pcidev = pdev;
219 pci_set_drvdata(pdev, dd); 206 pci_set_drvdata(pdev, dd);
220 207
221 INIT_DELAYED_WORK(&dd->status_work, ipath_check_status);
222
223 list_add(&dd->ipath_list, &ipath_dev_list); 208 list_add(&dd->ipath_list, &ipath_dev_list);
224 209
225bail_unlock: 210bail_unlock:
@@ -620,9 +605,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
620 ipath_diag_add(dd); 605 ipath_diag_add(dd);
621 ipath_register_ib_device(dd); 606 ipath_register_ib_device(dd);
622 607
623 /* Check that card status in STATUS_TIMEOUT seconds. */
624 schedule_delayed_work(&dd->status_work, HZ * STATUS_TIMEOUT);
625
626 goto bail; 608 goto bail;
627 609
628bail_irqsetup: 610bail_irqsetup:
@@ -753,7 +735,6 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
753 */ 735 */
754 ipath_shutdown_device(dd); 736 ipath_shutdown_device(dd);
755 737
756 cancel_delayed_work(&dd->status_work);
757 flush_scheduled_work(); 738 flush_scheduled_work();
758 739
759 if (dd->verbs_dev) 740 if (dd->verbs_dev)
@@ -2195,6 +2176,10 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
2195 del_timer_sync(&dd->ipath_stats_timer); 2176 del_timer_sync(&dd->ipath_stats_timer);
2196 dd->ipath_stats_timer_active = 0; 2177 dd->ipath_stats_timer_active = 0;
2197 } 2178 }
2179 if (dd->ipath_intrchk_timer.data) {
2180 del_timer_sync(&dd->ipath_intrchk_timer);
2181 dd->ipath_intrchk_timer.data = 0;
2182 }
2198 2183
2199 /* 2184 /*
2200 * clear all interrupts and errors, so that the next time the driver 2185 * clear all interrupts and errors, so that the next time the driver
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 1adafa97e082..0db19c1b45c3 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -665,6 +665,28 @@ done:
665 return ret; 665 return ret;
666} 666}
667 667
668static void verify_interrupt(unsigned long opaque)
669{
670 struct ipath_devdata *dd = (struct ipath_devdata *) opaque;
671
672 if (!dd)
673 return; /* being torn down */
674
675 /*
676 * If we don't have any interrupts, let the user know and
677 * don't bother checking again.
678 */
679 if (dd->ipath_int_counter == 0) {
680 if (!dd->ipath_f_intr_fallback(dd))
681 dev_err(&dd->pcidev->dev, "No interrupts detected, "
682 "not usable.\n");
683 else /* re-arm the timer to see if fallback works */
684 mod_timer(&dd->ipath_intrchk_timer, jiffies + HZ/2);
685 } else
686 ipath_cdbg(VERBOSE, "%u interrupts at timer check\n",
687 dd->ipath_int_counter);
688}
689
668/** 690/**
669 * ipath_init_chip - do the actual initialization sequence on the chip 691 * ipath_init_chip - do the actual initialization sequence on the chip
670 * @dd: the infinipath device 692 * @dd: the infinipath device
@@ -968,6 +990,20 @@ done:
968 0ULL); 990 0ULL);
969 /* chip is usable; mark it as initialized */ 991 /* chip is usable; mark it as initialized */
970 *dd->ipath_statusp |= IPATH_STATUS_INITTED; 992 *dd->ipath_statusp |= IPATH_STATUS_INITTED;
993
994 /*
995 * setup to verify we get an interrupt, and fallback
996 * to an alternate if necessary and possible
997 */
998 if (!reinit) {
999 init_timer(&dd->ipath_intrchk_timer);
1000 dd->ipath_intrchk_timer.function =
1001 verify_interrupt;
1002 dd->ipath_intrchk_timer.data =
1003 (unsigned long) dd;
1004 }
1005 dd->ipath_intrchk_timer.expires = jiffies + HZ/2;
1006 add_timer(&dd->ipath_intrchk_timer);
971 } else 1007 } else
972 ipath_dev_err(dd, "No interrupts enabled, couldn't " 1008 ipath_dev_err(dd, "No interrupts enabled, couldn't "
973 "setup interrupt address\n"); 1009 "setup interrupt address\n");
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index cef3296efb96..56e51cd7d6b9 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -426,6 +426,8 @@ struct ipath_devdata {
426 struct class_device *diag_class_dev; 426 struct class_device *diag_class_dev;
427 /* timer used to prevent stats overflow, error throttling, etc. */ 427 /* timer used to prevent stats overflow, error throttling, etc. */
428 struct timer_list ipath_stats_timer; 428 struct timer_list ipath_stats_timer;
429 /* timer to verify interrupts work, and fallback if possible */
430 struct timer_list ipath_intrchk_timer;
429 void *ipath_dummy_hdrq; /* used after port close */ 431 void *ipath_dummy_hdrq; /* used after port close */
430 dma_addr_t ipath_dummy_hdrq_phys; 432 dma_addr_t ipath_dummy_hdrq_phys;
431 433
@@ -629,9 +631,6 @@ struct ipath_devdata {
629 u32 ipath_overrun_thresh_errs; 631 u32 ipath_overrun_thresh_errs;
630 u32 ipath_lli_errs; 632 u32 ipath_lli_errs;
631 633
632 /* status check work */
633 struct delayed_work status_work;
634
635 /* 634 /*
636 * Not all devices managed by a driver instance are the same 635 * Not all devices managed by a driver instance are the same
637 * type, so these fields must be per-device. 636 * type, so these fields must be per-device.