Commit 49e10832 authored by Alex Estrin's avatar Alex Estrin Committed by Greg Kroah-Hartman

IB/{hfi1, qib}: Add handling of kernel restart

commit 8d3e7113 upstream.

A warm restart will fail to unload the driver, leaving link state
potentially flapping up to the point the BIOS resets the adapter.
Correct the issue by hooking the shutdown pci method,
which will bring port down.

Cc: <stable@vger.kernel.org> # 4.9.x
Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarAlex Estrin <alex.estrin@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e884ed82
...@@ -1851,6 +1851,7 @@ struct cc_state *get_cc_state_protected(struct hfi1_pportdata *ppd) ...@@ -1851,6 +1851,7 @@ struct cc_state *get_cc_state_protected(struct hfi1_pportdata *ppd)
#define HFI1_HAS_SDMA_TIMEOUT 0x8 #define HFI1_HAS_SDMA_TIMEOUT 0x8
#define HFI1_HAS_SEND_DMA 0x10 /* Supports Send DMA */ #define HFI1_HAS_SEND_DMA 0x10 /* Supports Send DMA */
#define HFI1_FORCED_FREEZE 0x80 /* driver forced freeze mode */ #define HFI1_FORCED_FREEZE 0x80 /* driver forced freeze mode */
#define HFI1_SHUTDOWN 0x100 /* device is shutting down */
/* IB dword length mask in PBC (lower 11 bits); same for all chips */ /* IB dword length mask in PBC (lower 11 bits); same for all chips */
#define HFI1_PBC_LENGTH_MASK ((1 << 11) - 1) #define HFI1_PBC_LENGTH_MASK ((1 << 11) - 1)
......
...@@ -1029,6 +1029,10 @@ static void shutdown_device(struct hfi1_devdata *dd) ...@@ -1029,6 +1029,10 @@ static void shutdown_device(struct hfi1_devdata *dd)
unsigned pidx; unsigned pidx;
int i; int i;
if (dd->flags & HFI1_SHUTDOWN)
return;
dd->flags |= HFI1_SHUTDOWN;
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx; ppd = dd->pport + pidx;
...@@ -1353,6 +1357,7 @@ void hfi1_disable_after_error(struct hfi1_devdata *dd) ...@@ -1353,6 +1357,7 @@ void hfi1_disable_after_error(struct hfi1_devdata *dd)
static void remove_one(struct pci_dev *); static void remove_one(struct pci_dev *);
static int init_one(struct pci_dev *, const struct pci_device_id *); static int init_one(struct pci_dev *, const struct pci_device_id *);
static void shutdown_one(struct pci_dev *);
#define DRIVER_LOAD_MSG "Intel " DRIVER_NAME " loaded: " #define DRIVER_LOAD_MSG "Intel " DRIVER_NAME " loaded: "
#define PFX DRIVER_NAME ": " #define PFX DRIVER_NAME ": "
...@@ -1369,6 +1374,7 @@ static struct pci_driver hfi1_pci_driver = { ...@@ -1369,6 +1374,7 @@ static struct pci_driver hfi1_pci_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.probe = init_one, .probe = init_one,
.remove = remove_one, .remove = remove_one,
.shutdown = shutdown_one,
.id_table = hfi1_pci_tbl, .id_table = hfi1_pci_tbl,
.err_handler = &hfi1_pci_err_handler, .err_handler = &hfi1_pci_err_handler,
}; };
...@@ -1780,6 +1786,13 @@ static void remove_one(struct pci_dev *pdev) ...@@ -1780,6 +1786,13 @@ static void remove_one(struct pci_dev *pdev)
postinit_cleanup(dd); postinit_cleanup(dd);
} }
static void shutdown_one(struct pci_dev *pdev)
{
struct hfi1_devdata *dd = pci_get_drvdata(pdev);
shutdown_device(dd);
}
/** /**
* hfi1_create_rcvhdrq - create a receive header queue * hfi1_create_rcvhdrq - create a receive header queue
* @dd: the hfi1_ib device * @dd: the hfi1_ib device
......
...@@ -1250,6 +1250,7 @@ static inline struct qib_ibport *to_iport(struct ib_device *ibdev, u8 port) ...@@ -1250,6 +1250,7 @@ static inline struct qib_ibport *to_iport(struct ib_device *ibdev, u8 port)
#define QIB_BADINTR 0x8000 /* severe interrupt problems */ #define QIB_BADINTR 0x8000 /* severe interrupt problems */
#define QIB_DCA_ENABLED 0x10000 /* Direct Cache Access enabled */ #define QIB_DCA_ENABLED 0x10000 /* Direct Cache Access enabled */
#define QIB_HAS_QSFP 0x20000 /* device (card instance) has QSFP */ #define QIB_HAS_QSFP 0x20000 /* device (card instance) has QSFP */
#define QIB_SHUTDOWN 0x40000 /* device is shutting down */
/* /*
* values for ppd->lflags (_ib_port_ related flags) * values for ppd->lflags (_ib_port_ related flags)
......
...@@ -850,6 +850,10 @@ static void qib_shutdown_device(struct qib_devdata *dd) ...@@ -850,6 +850,10 @@ static void qib_shutdown_device(struct qib_devdata *dd)
struct qib_pportdata *ppd; struct qib_pportdata *ppd;
unsigned pidx; unsigned pidx;
if (dd->flags & QIB_SHUTDOWN)
return;
dd->flags |= QIB_SHUTDOWN;
for (pidx = 0; pidx < dd->num_pports; ++pidx) { for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx; ppd = dd->pport + pidx;
...@@ -1189,6 +1193,7 @@ void qib_disable_after_error(struct qib_devdata *dd) ...@@ -1189,6 +1193,7 @@ void qib_disable_after_error(struct qib_devdata *dd)
static void qib_remove_one(struct pci_dev *); static void qib_remove_one(struct pci_dev *);
static int qib_init_one(struct pci_dev *, const struct pci_device_id *); static int qib_init_one(struct pci_dev *, const struct pci_device_id *);
static void qib_shutdown_one(struct pci_dev *);
#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: " #define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: "
#define PFX QIB_DRV_NAME ": " #define PFX QIB_DRV_NAME ": "
...@@ -1206,6 +1211,7 @@ static struct pci_driver qib_driver = { ...@@ -1206,6 +1211,7 @@ static struct pci_driver qib_driver = {
.name = QIB_DRV_NAME, .name = QIB_DRV_NAME,
.probe = qib_init_one, .probe = qib_init_one,
.remove = qib_remove_one, .remove = qib_remove_one,
.shutdown = qib_shutdown_one,
.id_table = qib_pci_tbl, .id_table = qib_pci_tbl,
.err_handler = &qib_pci_err_handler, .err_handler = &qib_pci_err_handler,
}; };
...@@ -1556,6 +1562,13 @@ static void qib_remove_one(struct pci_dev *pdev) ...@@ -1556,6 +1562,13 @@ static void qib_remove_one(struct pci_dev *pdev)
qib_postinit_cleanup(dd); qib_postinit_cleanup(dd);
} }
static void qib_shutdown_one(struct pci_dev *pdev)
{
struct qib_devdata *dd = pci_get_drvdata(pdev);
qib_shutdown_device(dd);
}
/** /**
* qib_create_rcvhdrq - create a receive header queue * qib_create_rcvhdrq - create a receive header queue
* @dd: the qlogic_ib device * @dd: the qlogic_ib device
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment