aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>2016-04-26 02:32:37 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-04-29 19:08:24 -0400
commit78cbccd3bd683c295a44af8050797dc4a41376ff (patch)
tree766b8fecf29ffa81b8daed44be0cbb9437c3e112
parenteef76f16295d34d7fab6994b82dda60ce002f91d (diff)
aacraid: Fix for KDUMP driver hang
When KDUMP is triggered the driver first talks to the firmware in INTX mode, but the adapter firmware is still in MSIX mode. Therefore the first driver command hangs since the driver is waiting for an INTX response and firmware gives a MSIX response. If when the OS is installed on a RAID drive created by the adapter KDUMP will hang since the driver does not receive a response in sync mode. Fixed by: Change the firmware to INTX mode if it is in MSIX mode before sending the first sync command. Cc: stable@vger.kernel.org Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/aacraid/aacraid.h1
-rw-r--r--drivers/scsi/aacraid/comminit.c24
2 files changed, 25 insertions, 0 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index b70f3eb323f7..0ba8f6118e75 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -29,6 +29,7 @@ enum {
29#define AAC_INT_MODE_MSI (1<<1) 29#define AAC_INT_MODE_MSI (1<<1)
30#define AAC_INT_MODE_AIF (1<<2) 30#define AAC_INT_MODE_AIF (1<<2)
31#define AAC_INT_MODE_SYNC (1<<3) 31#define AAC_INT_MODE_SYNC (1<<3)
32#define AAC_INT_MODE_MSIX (1<<16)
32 33
33#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb 34#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
34#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa 35#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 50d521a452d2..341ea327ae79 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -37,6 +37,7 @@
37#include <linux/spinlock.h> 37#include <linux/spinlock.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/blkdev.h> 39#include <linux/blkdev.h>
40#include <linux/delay.h>
40#include <linux/completion.h> 41#include <linux/completion.h>
41#include <linux/mm.h> 42#include <linux/mm.h>
42#include <scsi/scsi_host.h> 43#include <scsi/scsi_host.h>
@@ -47,6 +48,20 @@ struct aac_common aac_config = {
47 .irq_mod = 1 48 .irq_mod = 1
48}; 49};
49 50
51static inline int aac_is_msix_mode(struct aac_dev *dev)
52{
53 u32 status;
54
55 status = src_readl(dev, MUnit.OMR);
56 return (status & AAC_INT_MODE_MSIX);
57}
58
59static inline void aac_change_to_intx(struct aac_dev *dev)
60{
61 aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
62 aac_src_access_devreg(dev, AAC_ENABLE_INTX);
63}
64
50static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign) 65static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
51{ 66{
52 unsigned char *base; 67 unsigned char *base;
@@ -414,6 +429,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
414 dev->comm_interface = AAC_COMM_PRODUCER; 429 dev->comm_interface = AAC_COMM_PRODUCER;
415 dev->raw_io_interface = dev->raw_io_64 = 0; 430 dev->raw_io_interface = dev->raw_io_64 = 0;
416 431
432
433 /*
434 * Enable INTX mode, if not done already Enabled
435 */
436 if (aac_is_msix_mode(dev)) {
437 aac_change_to_intx(dev);
438 dev_info(&dev->pdev->dev, "Changed firmware to INTX mode");
439 }
440
417 if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 441 if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
418 0, 0, 0, 0, 0, 0, 442 0, 0, 0, 0, 0, 0,
419 status+0, status+1, status+2, status+3, NULL)) && 443 status+0, status+1, status+2, status+3, NULL)) &&