[ofa-general] [PATCH 26/28] IB/ipath - print warning if LID not acquired and link ACTIVE within one minute
Arthur Jones
arthur.jones at qlogic.com
Tue Jun 19 16:43:04 PDT 2007
From: Robert Walsh <robert.walsh at qlogic.com>
Signed-off-by: Robert Walsh <robert.walsh at qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan at qlogic.com>
---
drivers/infiniband/hw/ipath/ipath_driver.c | 45 ++++++++++++++++++++++++++++
drivers/infiniband/hw/ipath/ipath_kernel.h | 3 ++
2 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 8b61179..1d2369b 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -104,6 +104,13 @@ static int __devinit ipath_init_one(struct pci_dev *,
#define PCI_DEVICE_ID_INFINIPATH_HT 0xd
#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
+/*
+ * Number of seconds before we complain about not getting a LID
+ * assignment.
+ */
+
+#define LID_TIMEOUT 60
+
static const struct pci_device_id ipath_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
@@ -119,6 +126,32 @@ static struct pci_driver ipath_driver = {
.id_table = ipath_pci_tbl,
};
+static void check_link_status(struct work_struct *work)
+{
+ struct ipath_devdata *dd = container_of(work, struct ipath_devdata,
+ link_work);
+
+ /*
+ * If we're in the NOCABLE state, try again in another minute.
+ */
+
+ if (*dd->ipath_statusp & IPATH_STATUS_IB_NOCABLE) {
+ schedule_delayed_work(&dd->link_work, HZ * LID_TIMEOUT);
+ return;
+ }
+
+ /*
+ * If we don't have a LID, let the user know and don't bother
+ * checking again.
+ */
+
+ if (dd->ipath_lid == 0)
+ dev_info(&dd->pcidev->dev,
+ "We don't have a LID yet (no subnet manager?)\n");
+ else if (!(*dd->ipath_statusp & IPATH_STATUS_IB_READY))
+ dev_info(&dd->pcidev->dev,
+ "LID assigned, but IB link is not ACTIVE\n");
+}
static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev,
u32 *bar0, u32 *bar1)
@@ -187,6 +220,8 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
dd->pcidev = pdev;
pci_set_drvdata(pdev, dd);
+ INIT_DELAYED_WORK(&dd->link_work, check_link_status);
+
list_add(&dd->ipath_list, &ipath_dev_list);
bail_unlock:
@@ -511,6 +546,9 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
ipath_diag_add(dd);
ipath_register_ib_device(dd);
+ /* Check that we have a LID in LID_TIMEOUT seconds. */
+ schedule_delayed_work(&dd->link_work, HZ * LID_TIMEOUT);
+
goto bail;
bail_irqsetup:
@@ -638,6 +676,9 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
*/
ipath_shutdown_device(dd);
+ cancel_delayed_work(&dd->link_work);
+ flush_scheduled_work();
+
if (dd->verbs_dev)
ipath_unregister_ib_device(dd->verbs_dev);
@@ -1840,6 +1881,10 @@ int ipath_set_lid(struct ipath_devdata *dd, u32 arg, u8 lmc)
dd->ipath_lid = arg;
dd->ipath_lmc = lmc;
+ ipath_layer_lid_changed(dd);
+
+ dev_info(&dd->pcidev->dev, "We got a lid: 0x%x\n", arg);
+
return 0;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 034c283..f261af1 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -574,6 +574,9 @@ struct ipath_devdata {
u32 ipath_overrun_thresh_errs;
u32 ipath_lli_errs;
+ /* Link status check work */
+ struct delayed_work link_work;
+
/*
* Not all devices managed by a driver instance are the same
* type, so these fields must be per-device.
More information about the general
mailing list