scsi: aacraid: Perform initialization reset only once

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>
This commit is contained in:
Guilherme G. Piccoli 2017-11-17 19:14:54 -02:00 committed by Martin K. Petersen
parent bd257b2f3b
commit d9b6d85a38
4 changed files with 28 additions and 11 deletions

View File

@ -1673,6 +1673,7 @@ struct aac_dev
struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS]; struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
u8 adapter_shutdown; u8 adapter_shutdown;
u32 handle_pci_error; u32 handle_pci_error;
bool init_reset;
}; };
#define aac_adapter_interrupt(dev) \ #define aac_adapter_interrupt(dev) \

View File

@ -1680,6 +1680,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
aac->cardtype = index; aac->cardtype = index;
INIT_LIST_HEAD(&aac->entry); 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); aac->fibs = kzalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
if (!aac->fibs) if (!aac->fibs)
goto out_free_host; goto out_free_host;

View 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_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
dev->OIMR = status = rx_readb (dev, MUnit.OIMR); 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)) if (((status & 0x0c) != 0x0c) || dev->init_reset) {
/* Make sure the Hardware FIFO is empty */ dev->init_reset = false;
while ((++restart < 512) && if (!aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET)) {
(rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL)); /* 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. * Check to see if the board panic'd while booting.
*/ */

View File

@ -868,9 +868,13 @@ int aac_src_init(struct aac_dev *dev)
/* Failure to reset here is an option ... */ /* Failure to reset here is an option ... */
dev->a_ops.adapter_sync_cmd = src_sync_cmd; dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 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)) if (dev->init_reset) {
++restart; 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. * 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 ... */ /* Failure to reset here is an option ... */
dev->a_ops.adapter_sync_cmd = src_sync_cmd; dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; 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)) if (dev->init_reset) {
++restart; dev->init_reset = false;
if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
++restart;
}
/* /*
* Check to see if flash update is running. * Check to see if flash update is running.
* Wait for the adapter to be up and running. Wait up to 5 minutes * Wait for the adapter to be up and running. Wait up to 5 minutes