aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c23
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h5
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index da4a2cfb61b4..e397ec0d388f 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -104,6 +104,9 @@ static int __devinit ipath_init_one(struct pci_dev *,
104#define PCI_DEVICE_ID_INFINIPATH_HT 0xd 104#define PCI_DEVICE_ID_INFINIPATH_HT 0xd
105#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 105#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
106 106
107/* Number of seconds before our card status check... */
108#define STATUS_TIMEOUT 60
109
107static const struct pci_device_id ipath_pci_tbl[] = { 110static const struct pci_device_id ipath_pci_tbl[] = {
108 { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) }, 111 { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
109 { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) }, 112 { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
@@ -119,6 +122,18 @@ static struct pci_driver ipath_driver = {
119 .id_table = ipath_pci_tbl, 122 .id_table = ipath_pci_tbl,
120}; 123};
121 124
125static void ipath_check_status(struct work_struct *work)
126{
127 struct ipath_devdata *dd = container_of(work, struct ipath_devdata,
128 status_work.work);
129
130 /*
131 * If we don't have any interrupts, let the user know and
132 * don't bother checking again.
133 */
134 if (dd->ipath_int_counter == 0)
135 dev_err(&dd->pcidev->dev, "No interrupts detected.\n");
136}
122 137
123static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev, 138static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
124 u32 *bar0, u32 *bar1) 139 u32 *bar0, u32 *bar1)
@@ -187,6 +202,8 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
187 dd->pcidev = pdev; 202 dd->pcidev = pdev;
188 pci_set_drvdata(pdev, dd); 203 pci_set_drvdata(pdev, dd);
189 204
205 INIT_DELAYED_WORK(&dd->status_work, ipath_check_status);
206
190 list_add(&dd->ipath_list, &ipath_dev_list); 207 list_add(&dd->ipath_list, &ipath_dev_list);
191 208
192bail_unlock: 209bail_unlock:
@@ -511,6 +528,9 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
511 ipath_diag_add(dd); 528 ipath_diag_add(dd);
512 ipath_register_ib_device(dd); 529 ipath_register_ib_device(dd);
513 530
531 /* Check that card status in STATUS_TIMEOUT seconds. */
532 schedule_delayed_work(&dd->status_work, HZ * STATUS_TIMEOUT);
533
514 goto bail; 534 goto bail;
515 535
516bail_irqsetup: 536bail_irqsetup:
@@ -638,6 +658,9 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
638 */ 658 */
639 ipath_shutdown_device(dd); 659 ipath_shutdown_device(dd);
640 660
661 cancel_delayed_work(&dd->status_work);
662 flush_scheduled_work();
663
641 if (dd->verbs_dev) 664 if (dd->verbs_dev)
642 ipath_unregister_ib_device(dd->verbs_dev); 665 ipath_unregister_ib_device(dd->verbs_dev);
643 666
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index ce490235c24f..47aa43428fbf 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -1009,6 +1009,9 @@ irqreturn_t ipath_intr(int irq, void *data)
1009 1009
1010 ipath_stats.sps_ints++; 1010 ipath_stats.sps_ints++;
1011 1011
1012 if (dd->ipath_int_counter != (u32) -1)
1013 dd->ipath_int_counter++;
1014
1012 if (!(dd->ipath_flags & IPATH_PRESENT)) { 1015 if (!(dd->ipath_flags & IPATH_PRESENT)) {
1013 /* 1016 /*
1014 * This return value is not great, but we do not want the 1017 * This return value is not great, but we do not want the
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index a27e06297636..3105005fc9d2 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -297,6 +297,8 @@ struct ipath_devdata {
297 u32 ipath_lastport_piobuf; 297 u32 ipath_lastport_piobuf;
298 /* is a stats timer active */ 298 /* is a stats timer active */
299 u32 ipath_stats_timer_active; 299 u32 ipath_stats_timer_active;
300 /* number of interrupts for this device -- saturates... */
301 u32 ipath_int_counter;
300 /* dwords sent read from counter */ 302 /* dwords sent read from counter */
301 u32 ipath_lastsword; 303 u32 ipath_lastsword;
302 /* dwords received read from counter */ 304 /* dwords received read from counter */
@@ -571,6 +573,9 @@ struct ipath_devdata {
571 u32 ipath_overrun_thresh_errs; 573 u32 ipath_overrun_thresh_errs;
572 u32 ipath_lli_errs; 574 u32 ipath_lli_errs;
573 575
576 /* status check work */
577 struct delayed_work status_work;
578
574 /* 579 /*
575 * Not all devices managed by a driver instance are the same 580 * Not all devices managed by a driver instance are the same
576 * type, so these fields must be per-device. 581 * type, so these fields must be per-device.