summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/src.c
diff options
context:
space:
mode:
authorMahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>2015-03-26 15:41:28 +0100
committerJames Bottomley <JBottomley@Odin.com>2015-04-10 01:53:37 +0200
commitdafde947bce37b10f3681d6b9df473ba7136fc05 (patch)
treee907612fa34bf9d509e6ad9de0f45e4d2e38fdaa /drivers/scsi/aacraid/src.c
parentaacraid: 240 simple volume support (diff)
downloadlinux-dafde947bce37b10f3681d6b9df473ba7136fc05.tar.xz
linux-dafde947bce37b10f3681d6b9df473ba7136fc05.zip
aacraid: IOP RESET command handling changes
This patch fixes the IOP_RESET issue. Sending IOP_RESET command need to wait for only 10 sec instead of 5 minutes in case of firmware does not response IOP_RESET command. Disable interrupt before setup interrupt routine to prevent spurious interrupts. Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/aacraid/src.c')
-rw-r--r--drivers/scsi/aacraid/src.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 50f181f6d1be..4a963cd4a941 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -204,6 +204,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
{
unsigned long start;
+ unsigned long delay;
int ok;
/*
@@ -246,10 +247,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
ok = 0;
start = jiffies;
- /*
- * Wait up to 5 minutes
- */
- while (time_before(jiffies, start+300*HZ)) {
+ if (command == IOP_RESET_ALWAYS) {
+ /* Wait up to 10 sec */
+ delay = 10*HZ;
+ } else {
+ /* Wait up to 5 minutes */
+ delay = 300*HZ;
+ }
+ while (time_before(jiffies, start+delay)) {
udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
/*
* Mon960 will set doorbell0 bit when it has completed the command.
@@ -574,10 +579,17 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
if (bled)
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
dev->name, dev->id, bled);
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
- if (bled || (var != 0x00000001))
- return -EINVAL;
+ if ((bled || (var != 0x00000001)) &&
+ !dev->doorbell_mask)
+ return -EINVAL;
+ else if (dev->doorbell_mask) {
+ reset_mask = dev->doorbell_mask;
+ bled = 0;
+ var = 0x00000001;
+ }
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
@@ -587,10 +599,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
msleep(5000); /* Delay 5 seconds */
}
- if (dev->supplement_adapter_info.SupportedOptions2 &
- AAC_OPTION_DOORBELL_RESET) {
+ if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_DOORBELL_RESET)) {
src_writel(dev, MUnit.IDR, reset_mask);
ssleep(45);
+ } else {
+ src_writel(dev, MUnit.IDR, 0x100);
+ ssleep(45);
}
}
@@ -612,7 +627,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm)
{
switch (comm) {
case AAC_COMM_MESSAGE:
- dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
dev->a_ops.adapter_intr = aac_src_intr_message;
dev->a_ops.adapter_deliver = aac_src_deliver_message;
break;
@@ -710,6 +724,7 @@ int aac_src_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -747,6 +762,7 @@ int aac_src_init(struct aac_dev *dev)
dev->dbg_base = pci_resource_start(dev->pdev, 2);
dev->dbg_base_mapped = dev->regs.src.bar1;
dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
@@ -873,6 +889,7 @@ int aac_srcv_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -930,6 +947,7 @@ int aac_srcv_init(struct aac_dev *dev)
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
dev->dbg_size = dev->base_size;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);