scsi: qedf: Fix firmware halt over suspend and resume

While performing certain power-off sequences, PCI drivers are called to
suspend and resume their underlying devices through PCI PM (power
management) interface. However the hardware does not support PCI PM
suspend/resume operations so system wide suspend/resume leads to bad MFW
(management firmware) state which causes various follow-up errors in driver
when communicating with the device/firmware.

To fix this driver implements PCI PM suspend handler to indicate
unsupported operation to the PCI subsystem explicitly, thus avoiding system
to go into suspended/standby mode.

Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.")
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://lore.kernel.org/r/20230807093725.46829-1-njavali@marvell.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by Nilesh Javali and committed by Martin K. Petersen ef222f55 1516ee03

Changed files
+18
drivers
scsi
+18
drivers/scsi/qedf/qedf_main.c
··· 31 31 static void qedf_shutdown(struct pci_dev *pdev); 32 32 static void qedf_schedule_recovery_handler(void *dev); 33 33 static void qedf_recovery_handler(struct work_struct *work); 34 + static int qedf_suspend(struct pci_dev *pdev, pm_message_t state); 34 35 35 36 /* 36 37 * Driver module parameters. ··· 3272 3271 .probe = qedf_probe, 3273 3272 .remove = qedf_remove, 3274 3273 .shutdown = qedf_shutdown, 3274 + .suspend = qedf_suspend, 3275 3275 }; 3276 3276 3277 3277 static int __qedf_probe(struct pci_dev *pdev, int mode) ··· 4000 3998 static void qedf_shutdown(struct pci_dev *pdev) 4001 3999 { 4002 4000 __qedf_remove(pdev, QEDF_MODE_NORMAL); 4001 + } 4002 + 4003 + static int qedf_suspend(struct pci_dev *pdev, pm_message_t state) 4004 + { 4005 + struct qedf_ctx *qedf; 4006 + 4007 + if (!pdev) { 4008 + QEDF_ERR(NULL, "pdev is NULL.\n"); 4009 + return -ENODEV; 4010 + } 4011 + 4012 + qedf = pci_get_drvdata(pdev); 4013 + 4014 + QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); 4015 + 4016 + return -EPERM; 4003 4017 } 4004 4018 4005 4019 /*