]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
aacraid: Fix for KDUMP driver hang
authorRaghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Tue, 26 Apr 2016 06:32:37 +0000 (23:32 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Mon, 27 Feb 2017 06:21:06 +0000 (22:21 -0800)
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>
(cherry picked from commit 78cbccd3bd683c295a44af8050797dc4a41376ff)

Orabug: 25505509
Signed-off-by: Dhaval Giani <dhaval.giani@oracle.com>
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/comminit.c

index 86d218659ba85492dfd7fd9205f812eeb4827e27..50310290733b63e6fda2ffb4298eeb6bb8d6991d 100644 (file)
@@ -29,6 +29,7 @@ enum {
 #define AAC_INT_MODE_MSI               (1<<1)
 #define AAC_INT_MODE_AIF               (1<<2)
 #define AAC_INT_MODE_SYNC              (1<<3)
+#define AAC_INT_MODE_MSIX              (1<<16)
 
 #define AAC_INT_ENABLE_TYPE1_INTX      0xfffffffb
 #define AAC_INT_ENABLE_TYPE1_MSIX      0xfffffffa
index 50d521a452d2c9eebb2699258d34e5dffae5a536..341ea327ae7946f758bbcc8b9a518ef2051bf7e9 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/mm.h>
 #include <scsi/scsi_host.h>
@@ -47,6 +48,20 @@ struct aac_common aac_config = {
        .irq_mod = 1
 };
 
+static inline int aac_is_msix_mode(struct aac_dev *dev)
+{
+       u32 status;
+
+       status = src_readl(dev, MUnit.OMR);
+       return (status & AAC_INT_MODE_MSIX);
+}
+
+static inline void aac_change_to_intx(struct aac_dev *dev)
+{
+       aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
+       aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+}
+
 static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
 {
        unsigned char *base;
@@ -414,6 +429,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
        dev->comm_interface = AAC_COMM_PRODUCER;
        dev->raw_io_interface = dev->raw_io_64 = 0;
 
+
+       /*
+        * Enable INTX mode, if not done already Enabled
+        */
+       if (aac_is_msix_mode(dev)) {
+               aac_change_to_intx(dev);
+               dev_info(&dev->pdev->dev, "Changed firmware to INTX mode");
+       }
+
        if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
                0, 0, 0, 0, 0, 0,
                status+0, status+1, status+2, status+3, NULL)) &&