From 490515384dc4422fc1d470205e739d76f27a3866 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Fri, 10 Feb 2017 00:59:34 -0800 Subject: [PATCH] scsi: megaraid_sas: Use synchronize_irq to wait for IRQs to complete Orabug: 26608922 FIX - Do not use random delay to synchronize with IRQ. Use kernel API. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl Signed-off-by: Martin K. Petersen [ Upstream commit 29206da1490a7065e8a03ec43f6de60c5c978cae ] [ Added drivers/scsi/megaraid/kcompat.h to resolve pci_irq_vector symbol ] Signed-off-by: Somasundaram Krishnasamy Reviewed-by: Jack Vogel --- drivers/scsi/megaraid/kcompat.h | 19 +++++++++++++++++++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 drivers/scsi/megaraid/kcompat.h diff --git a/drivers/scsi/megaraid/kcompat.h b/drivers/scsi/megaraid/kcompat.h new file mode 100644 index 000000000000..f5cd94198934 --- /dev/null +++ b/drivers/scsi/megaraid/kcompat.h @@ -0,0 +1,19 @@ +#ifndef _KCOMPAT_H_ +#define _KCOMPAT_H_ +#endif + +#ifndef LINUX_VERSION_CODE +#include +#else +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + + +static inline int pci_irq_vector(struct pci_dev *dev, unsigned int nr) +{ + if (WARN_ON_ONCE(nr > 0)) + return -EINVAL; + return dev->irq; +} + + diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 303ec80c770b..6df1cc1d466a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -56,6 +56,7 @@ #include #include +#include "kcompat.h" #include "megaraid_sas_fusion.h" #include "megaraid_sas.h" @@ -2859,6 +2860,22 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) return IRQ_HANDLED; } +/** + * megasas_sync_irqs - Synchronizes all IRQs owned by adapter + * @instance: Adapter soft state + */ +void megasas_sync_irqs(unsigned long instance_addr) +{ + u32 count, i; + struct megasas_instance *instance = + (struct megasas_instance *)instance_addr; + + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + + for (i = 0; i < count; i++) + synchronize_irq(pci_irq_vector(instance->pdev, i)); +} + /** * megasas_complete_cmd_dpc_fusion - Completes command * @instance: Adapter soft state @@ -3535,7 +3552,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, break; else { instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); megasas_complete_cmd_dpc_fusion ((unsigned long)instance); instance->instancet->enable_intr(instance); @@ -3889,7 +3906,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING); instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); /* First try waiting for commands to complete */ if (megasas_wait_for_outstanding_fusion(instance, reason, -- 2.50.1