From: Quinn Tran <[email protected]>

This patch provide call back functions to stop the chip
and resume the chip if the PCI lower level driver wants
to perform function level reset/FLR.  Before the FLR,
the chip will be stopped to turn off all DMA activity.
After the FLR, the chip is reset to resume previous
operation state.

Signed-off-by: Quinn Tran <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
---
 drivers/scsi/qla2xxx/qla_os.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c6ef83d0d99b..39a0bdb66612 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -6930,6 +6930,57 @@ qla2xxx_pci_resume(struct pci_dev *pdev)
        ha->flags.eeh_busy = 0;
 }
 
+static void
+qla_pci_reset_prepare(struct pci_dev *pdev)
+{
+       scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
+       struct qla_hw_data *ha = base_vha->hw;
+       struct qla_qpair *qpair;
+
+       ql_log(ql_log_warn, base_vha, 0xffff,
+           "%s.\n", __func__);
+
+       /*
+        * PCI FLR/function reset is about to reset the
+        * slot. Stop the chip to stop all DMA access.
+        * It is assumed that pci_reset_done will be called
+        * after FLR to resume Chip operation.
+        */
+       ha->flags.eeh_busy = 1;
+       mutex_lock(&ha->mq_lock);
+       list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem)
+               qpair->online = 0;
+       mutex_unlock(&ha->mq_lock);
+
+       set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
+       qla2x00_abort_isp_cleanup(base_vha);
+       qla2x00_abort_all_cmds(base_vha, DID_RESET << 16);
+}
+
+static void
+qla_pci_reset_done(struct pci_dev *pdev)
+{
+       scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
+       struct qla_hw_data *ha = base_vha->hw;
+       struct qla_qpair *qpair;
+
+       ql_log(ql_log_warn, base_vha, 0xffff,
+           "%s.\n", __func__);
+
+       /*
+        * FLR just completed by PCI layer. Resume adapter
+        */
+       ha->flags.eeh_busy = 0;
+       mutex_lock(&ha->mq_lock);
+       list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem)
+               qpair->online = 1;
+       mutex_unlock(&ha->mq_lock);
+
+       base_vha->flags.online = 1;
+       ha->isp_ops->abort_isp(base_vha);
+       clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
+}
+
 static int qla2xxx_map_queues(struct Scsi_Host *shost)
 {
        int rc;
@@ -6948,6 +6999,8 @@ static const struct pci_error_handlers 
qla2xxx_err_handler = {
        .mmio_enabled = qla2xxx_pci_mmio_enabled,
        .slot_reset = qla2xxx_pci_slot_reset,
        .resume = qla2xxx_pci_resume,
+       .reset_prepare = qla_pci_reset_prepare,
+       .reset_done = qla_pci_reset_done,
 };
 
 static struct pci_device_id qla2xxx_pci_tbl[] = {
-- 
2.12.0

Reply via email to