diff options
author | Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com> | 2015-03-26 10:41:28 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-09 19:53:37 -0400 |
commit | dafde947bce37b10f3681d6b9df473ba7136fc05 (patch) | |
tree | e907612fa34bf9d509e6ad9de0f45e4d2e38fdaa | |
parent | a7129a5443cd01b0a3544785974e09032f19b464 (diff) |
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>
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 1 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 4 | ||||
-rw-r--r-- | drivers/scsi/aacraid/src.c | 36 |
3 files changed, 31 insertions, 10 deletions
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index bf14ae02ca77..9b469a4254b7 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1216,6 +1216,7 @@ struct aac_dev | |||
1216 | int sync_mode; | 1216 | int sync_mode; |
1217 | struct fib *sync_fib; | 1217 | struct fib *sync_fib; |
1218 | struct list_head sync_fib_list; | 1218 | struct list_head sync_fib_list; |
1219 | u32 doorbell_mask; | ||
1219 | u32 max_msix; /* max. MSI-X vectors */ | 1220 | u32 max_msix; /* max. MSI-X vectors */ |
1220 | u32 vector_cap; /* MSI-X vector capab.*/ | 1221 | u32 vector_cap; /* MSI-X vector capab.*/ |
1221 | int msi_enabled; /* MSI/MSI-X enabled */ | 1222 | int msi_enabled; /* MSI/MSI-X enabled */ |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index fdd95247f034..284b1c54be7f 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -358,8 +358,10 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
358 | dev->raw_io_interface = dev->raw_io_64 = 0; | 358 | dev->raw_io_interface = dev->raw_io_64 = 0; |
359 | 359 | ||
360 | if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, | 360 | if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, |
361 | 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && | 361 | 0, 0, 0, 0, 0, 0, |
362 | status+0, status+1, status+2, status+3, NULL)) && | ||
362 | (status[0] == 0x00000001)) { | 363 | (status[0] == 0x00000001)) { |
364 | dev->doorbell_mask = status[3]; | ||
363 | if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64)) | 365 | if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64)) |
364 | dev->raw_io_64 = 1; | 366 | dev->raw_io_64 = 1; |
365 | dev->sync_mode = aac_sync_mode; | 367 | dev->sync_mode = aac_sync_mode; |
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, | |||
204 | u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) | 204 | u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) |
205 | { | 205 | { |
206 | unsigned long start; | 206 | unsigned long start; |
207 | unsigned long delay; | ||
207 | int ok; | 208 | int ok; |
208 | 209 | ||
209 | /* | 210 | /* |
@@ -246,10 +247,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command, | |||
246 | ok = 0; | 247 | ok = 0; |
247 | start = jiffies; | 248 | start = jiffies; |
248 | 249 | ||
249 | /* | 250 | if (command == IOP_RESET_ALWAYS) { |
250 | * Wait up to 5 minutes | 251 | /* Wait up to 10 sec */ |
251 | */ | 252 | delay = 10*HZ; |
252 | while (time_before(jiffies, start+300*HZ)) { | 253 | } else { |
254 | /* Wait up to 5 minutes */ | ||
255 | delay = 300*HZ; | ||
256 | } | ||
257 | while (time_before(jiffies, start+delay)) { | ||
253 | udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ | 258 | udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ |
254 | /* | 259 | /* |
255 | * Mon960 will set doorbell0 bit when it has completed the command. | 260 | * 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) | |||
574 | if (bled) | 579 | if (bled) |
575 | printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", | 580 | printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", |
576 | dev->name, dev->id, bled); | 581 | dev->name, dev->id, bled); |
582 | dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; | ||
577 | bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, | 583 | bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, |
578 | 0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL); | 584 | 0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL); |
579 | if (bled || (var != 0x00000001)) | 585 | if ((bled || (var != 0x00000001)) && |
580 | return -EINVAL; | 586 | !dev->doorbell_mask) |
587 | return -EINVAL; | ||
588 | else if (dev->doorbell_mask) { | ||
589 | reset_mask = dev->doorbell_mask; | ||
590 | bled = 0; | ||
591 | var = 0x00000001; | ||
592 | } | ||
581 | 593 | ||
582 | if ((dev->pdev->device == PMC_DEVICE_S7 || | 594 | if ((dev->pdev->device == PMC_DEVICE_S7 || |
583 | dev->pdev->device == PMC_DEVICE_S8 || | 595 | dev->pdev->device == PMC_DEVICE_S8 || |
@@ -587,10 +599,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled) | |||
587 | msleep(5000); /* Delay 5 seconds */ | 599 | msleep(5000); /* Delay 5 seconds */ |
588 | } | 600 | } |
589 | 601 | ||
590 | if (dev->supplement_adapter_info.SupportedOptions2 & | 602 | if (!bled && (dev->supplement_adapter_info.SupportedOptions2 & |
591 | AAC_OPTION_DOORBELL_RESET) { | 603 | AAC_OPTION_DOORBELL_RESET)) { |
592 | src_writel(dev, MUnit.IDR, reset_mask); | 604 | src_writel(dev, MUnit.IDR, reset_mask); |
593 | ssleep(45); | 605 | ssleep(45); |
606 | } else { | ||
607 | src_writel(dev, MUnit.IDR, 0x100); | ||
608 | ssleep(45); | ||
594 | } | 609 | } |
595 | } | 610 | } |
596 | 611 | ||
@@ -612,7 +627,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm) | |||
612 | { | 627 | { |
613 | switch (comm) { | 628 | switch (comm) { |
614 | case AAC_COMM_MESSAGE: | 629 | case AAC_COMM_MESSAGE: |
615 | dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message; | ||
616 | dev->a_ops.adapter_intr = aac_src_intr_message; | 630 | dev->a_ops.adapter_intr = aac_src_intr_message; |
617 | dev->a_ops.adapter_deliver = aac_src_deliver_message; | 631 | dev->a_ops.adapter_deliver = aac_src_deliver_message; |
618 | break; | 632 | break; |
@@ -710,6 +724,7 @@ int aac_src_init(struct aac_dev *dev) | |||
710 | */ | 724 | */ |
711 | dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; | 725 | dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; |
712 | dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; | 726 | dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; |
727 | dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; | ||
713 | dev->a_ops.adapter_notify = aac_src_notify_adapter; | 728 | dev->a_ops.adapter_notify = aac_src_notify_adapter; |
714 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; | 729 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; |
715 | dev->a_ops.adapter_check_health = aac_src_check_health; | 730 | dev->a_ops.adapter_check_health = aac_src_check_health; |
@@ -747,6 +762,7 @@ int aac_src_init(struct aac_dev *dev) | |||
747 | dev->dbg_base = pci_resource_start(dev->pdev, 2); | 762 | dev->dbg_base = pci_resource_start(dev->pdev, 2); |
748 | dev->dbg_base_mapped = dev->regs.src.bar1; | 763 | dev->dbg_base_mapped = dev->regs.src.bar1; |
749 | dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE; | 764 | dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE; |
765 | dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message; | ||
750 | 766 | ||
751 | aac_adapter_enable_int(dev); | 767 | aac_adapter_enable_int(dev); |
752 | 768 | ||
@@ -873,6 +889,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
873 | */ | 889 | */ |
874 | dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; | 890 | dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter; |
875 | dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; | 891 | dev->a_ops.adapter_disable_int = aac_src_disable_interrupt; |
892 | dev->a_ops.adapter_enable_int = aac_src_disable_interrupt; | ||
876 | dev->a_ops.adapter_notify = aac_src_notify_adapter; | 893 | dev->a_ops.adapter_notify = aac_src_notify_adapter; |
877 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; | 894 | dev->a_ops.adapter_sync_cmd = src_sync_cmd; |
878 | dev->a_ops.adapter_check_health = aac_src_check_health; | 895 | dev->a_ops.adapter_check_health = aac_src_check_health; |
@@ -930,6 +947,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
930 | dev->dbg_base = dev->base_start; | 947 | dev->dbg_base = dev->base_start; |
931 | dev->dbg_base_mapped = dev->base; | 948 | dev->dbg_base_mapped = dev->base; |
932 | dev->dbg_size = dev->base_size; | 949 | dev->dbg_size = dev->base_size; |
950 | dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message; | ||
933 | 951 | ||
934 | aac_adapter_enable_int(dev); | 952 | aac_adapter_enable_int(dev); |
935 | 953 | ||