diff options
author | Balsundar P <balsundar.p@microsemi.com> | 2019-10-15 11:52:03 +0530 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-10-18 19:34:18 -0400 |
commit | 26c54d0ec25c186329d845ad1beb9d3dde586af9 (patch) | |
tree | b40f236f2005970aa453f11d52ba18eeb809a42f /drivers/scsi | |
parent | 572ee53a9badf62f3973d66f6475f9ce69720a25 (diff) | |
download | linux-26c54d0ec25c186329d845ad1beb9d3dde586af9.tar.gz linux-26c54d0ec25c186329d845ad1beb9d3dde586af9.tar.bz2 linux-26c54d0ec25c186329d845ad1beb9d3dde586af9.zip |
scsi: aacraid: send AIF request post IOP RESET
After IOP reset completion, AIF request command is not issued to the
controller. Driver schedules a worker thread to issue a AIF request command
after IOP reset completion.
[mkp: fix zeroday warning]
Link: https://lore.kernel.org/r/1571120524-6037-7-git-send-email-balsundar.p@microsemi.com
Acked-by: Balsundar P < Balsundar.P@microchip.com>
Signed-off-by: Balsundar P <balsundar.p@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 18 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 21 |
3 files changed, 50 insertions, 9 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f76a33cb0259..17a4e8b8bd00 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1330,7 +1330,7 @@ struct fib { #define AAC_DEVTYPE_ARC_RAW 2 #define AAC_DEVTYPE_NATIVE_RAW 3 -#define AAC_SAFW_RESCAN_DELAY (10 * HZ) +#define AAC_RESCAN_DELAY (10 * HZ) struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ @@ -1603,6 +1603,7 @@ struct aac_dev struct fsa_dev_info *fsa_dev; struct task_struct *thread; struct delayed_work safw_rescan_work; + struct delayed_work src_reinit_aif_worker; int cardtype; /* *This lock will protect the two 32-bit @@ -2647,7 +2648,12 @@ int aac_scan_host(struct aac_dev *dev); static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev) { - schedule_delayed_work(&dev->safw_rescan_work, AAC_SAFW_RESCAN_DELAY); + schedule_delayed_work(&dev->safw_rescan_work, AAC_RESCAN_DELAY); +} + +static inline void aac_schedule_src_reinit_aif_worker(struct aac_dev *dev) +{ + schedule_delayed_work(&dev->src_reinit_aif_worker, AAC_RESCAN_DELAY); } static inline void aac_safw_rescan_worker(struct work_struct *work) @@ -2661,10 +2667,10 @@ static inline void aac_safw_rescan_worker(struct work_struct *work) aac_scan_host(dev); } -static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) +static inline void aac_cancel_rescan_worker(struct aac_dev *dev) { - if (dev->sa_firmware) - cancel_delayed_work_sync(&dev->safw_rescan_work); + cancel_delayed_work_sync(&dev->safw_rescan_work); + cancel_delayed_work_sync(&dev->src_reinit_aif_worker); } /* SCp.phase values */ @@ -2674,6 +2680,7 @@ static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) #define AAC_OWNER_FIRMWARE 0x106 void aac_safw_rescan_worker(struct work_struct *work); +void aac_src_reinit_aif_worker(struct work_struct *work); int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); int aac_setup_safw_adapter(struct aac_dev *dev); @@ -2731,6 +2738,7 @@ int aac_probe_container(struct aac_dev *dev, int cid); int _aac_rx_init(struct aac_dev *dev); int aac_rx_select_comm(struct aac_dev *dev, int comm); int aac_rx_deliver_producer(struct fib * fib); +void aac_reinit_aif(struct aac_dev *aac, unsigned int index); static inline int aac_is_src(struct aac_dev *dev) { diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 3f268f669cc3..5a8a999606ea 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1464,6 +1464,14 @@ retry_next: } } +static void aac_schedule_bus_scan(struct aac_dev *aac) +{ + if (aac->sa_firmware) + aac_schedule_safw_scan_worker(aac); + else + aac_schedule_src_reinit_aif_worker(aac); +} + static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) { int index, quirks; @@ -1639,7 +1647,7 @@ out: */ if (!retval && !is_kdump_kernel()) { dev_info(&aac->pdev->dev, "Scheduling bus rescan\n"); - aac_schedule_safw_scan_worker(aac); + aac_schedule_bus_scan(aac); } if (jafo) { @@ -1960,6 +1968,16 @@ int aac_scan_host(struct aac_dev *dev) return rcode; } +void aac_src_reinit_aif_worker(struct work_struct *work) +{ + struct aac_dev *dev = container_of(to_delayed_work(work), + struct aac_dev, src_reinit_aif_worker); + + wait_event(dev->scsi_host_ptr->host_wait, + !scsi_host_in_recovery(dev->scsi_host_ptr)); + aac_reinit_aif(dev, dev->cardtype); +} + /** * aac_handle_sa_aif Handle a message from the firmware * @dev: Which adapter this fib is from diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 55a55c56fea9..ee6bc2f9b80a 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1593,6 +1593,19 @@ static void aac_init_char(void) } } +void aac_reinit_aif(struct aac_dev *aac, unsigned int index) +{ + /* + * Firmware may send a AIF messages very early and the Driver may have + * ignored as it is not fully ready to process the messages. Send + * AIF to firmware so that if there are any unprocessed events they + * can be processed now. + */ + if (aac_drivers[index].quirks & AAC_QUIRK_SRC) + aac_intr_normal(aac, 0, 2, 0, NULL); + +} + static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { unsigned index = id->driver_data; @@ -1690,6 +1703,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(&aac->scan_mutex); INIT_DELAYED_WORK(&aac->safw_rescan_work, aac_safw_rescan_worker); + INIT_DELAYED_WORK(&aac->src_reinit_aif_worker, + aac_src_reinit_aif_worker); /* * Map in the registers from the adapter. */ @@ -1880,7 +1895,7 @@ static int aac_suspend(struct pci_dev *pdev, pm_message_t state) struct aac_dev *aac = (struct aac_dev *)shost->hostdata; scsi_block_requests(shost); - aac_cancel_safw_rescan_worker(aac); + aac_cancel_rescan_worker(aac); aac_send_shutdown(aac); aac_release_resources(aac); @@ -1939,7 +1954,7 @@ static void aac_remove_one(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct aac_dev *aac = (struct aac_dev *)shost->hostdata; - aac_cancel_safw_rescan_worker(aac); + aac_cancel_rescan_worker(aac); scsi_remove_host(shost); __aac_shutdown(aac); @@ -1997,7 +2012,7 @@ static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, aac->handle_pci_error = 1; scsi_block_requests(aac->scsi_host_ptr); - aac_cancel_safw_rescan_worker(aac); + aac_cancel_rescan_worker(aac); aac_flush_ios(aac); aac_release_resources(aac); |