scsi: aacraid: Perform initialization reset only once
authorGuilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Fri, 17 Nov 2017 21:14:54 +0000 (19:14 -0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 21 Nov 2017 03:32:00 +0000 (22:32 -0500)
Currently the driver accepts two ways of requesting an initialization
reset on the adapter: by passing aac_reset_devices module parameter,
or the generic kernel parameter reset_devices.

It's working as intended...but if we end up reaching a scsi hang and
the scsi EH mechanism takes place, aacraid performs resets as part of
the scsi error recovery procedure. These EH routines might reinitialize
the device, and if we have provided some of the reset parameters in the
kernel command-line, we again perform an "initialization" reset.

So, to avoid this duplication of resets in case of scsi EH path, this
patch adds a field to aac_dev struct to keep per-adapter track of the
init reset request - once it's done, we set it to false and don't
proactively reset anymore in case of reinitializations.

Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
Reviewed-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/src.c

index 403a639574e5ea10c5c8500141204ebc513bd7c1..6e3d81969a77cc895580f79fa8e3aaa3b8bb4fee 100644 (file)
@@ -1673,6 +1673,7 @@ struct aac_dev
        struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
        u8                      adapter_shutdown;
        u32                     handle_pci_error;
+       bool                    init_reset;
 };
 
 #define aac_adapter_interrupt(dev) \
index c9252b138c1fe0e21d217b0fb305cc45afc1545a..bdf127aaab41d814e2337d2944166a0498bf1a66 100644 (file)
@@ -1680,6 +1680,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        aac->cardtype = index;
        INIT_LIST_HEAD(&aac->entry);
 
+       if (aac_reset_devices || reset_devices)
+               aac->init_reset = true;
+
        aac->fibs = kzalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
        if (!aac->fibs)
                goto out_free_host;
index 93ef7c37e568e0e2ca4a38d8a08dd1b987482626..6201666941717042e3c7a2a1cd5f459b41b3360c 100644 (file)
@@ -561,11 +561,16 @@ int _aac_rx_init(struct aac_dev *dev)
        dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
        dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
        dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
-       if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
-         !aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
-               /* Make sure the Hardware FIFO is empty */
-               while ((++restart < 512) &&
-                 (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL));
+
+       if (((status & 0x0c) != 0x0c) || dev->init_reset) {
+               dev->init_reset = false;
+               if (!aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET)) {
+                       /* Make sure the Hardware FIFO is empty */
+                       while ((++restart < 512) &&
+                              (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL));
+               }
+       }
+
        /*
         *      Check to see if the board panic'd while booting.
         */
index 0c9361c87ec8de8b853f6ccaa6132663a4b982bd..fde6b6aa86e38a1af487d94b1117f3ffc340c5a5 100644 (file)
@@ -868,9 +868,13 @@ int aac_src_init(struct aac_dev *dev)
        /* Failure to reset here is an option ... */
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
        dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
-       if ((aac_reset_devices || reset_devices) &&
-               !aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
-               ++restart;
+
+       if (dev->init_reset) {
+               dev->init_reset = false;
+               if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
+                       ++restart;
+       }
+
        /*
         *      Check to see if the board panic'd while booting.
         */
@@ -1014,9 +1018,13 @@ int aac_srcv_init(struct aac_dev *dev)
        /* Failure to reset here is an option ... */
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
        dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
-       if ((aac_reset_devices || reset_devices) &&
-               !aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
-               ++restart;
+
+       if (dev->init_reset) {
+               dev->init_reset = false;
+               if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
+                       ++restart;
+       }
+
        /*
         *      Check to see if flash update is running.
         *      Wait for the adapter to be up and running. Wait up to 5 minutes