diff options
author | adam radford <aradford@gmail.com> | 2011-02-24 23:57:15 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-28 13:04:14 -0500 |
commit | ebf054b00b0a6dfa81dc4472d8b19301318b7f47 (patch) | |
tree | 9043de5cb98203203b5335332e2a12df4fcae84a /drivers | |
parent | 42a8d2b34d107df34533ea4840daf8d62bdc90aa (diff) |
[SCSI] megaraid_sas: Fix iMR OCR support to work correctly
Signed-off-by: Adam Radford <aradford@gmail.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 960b88cb4ff6..970d635574b3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -134,7 +134,11 @@ spinlock_t poll_aen_lock; | |||
134 | void | 134 | void |
135 | megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, | 135 | megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, |
136 | u8 alt_status); | 136 | u8 alt_status); |
137 | 137 | static u32 | |
138 | megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); | ||
139 | static int | ||
140 | megasas_adp_reset_gen2(struct megasas_instance *instance, | ||
141 | struct megasas_register_set __iomem *reg_set); | ||
138 | static irqreturn_t megasas_isr(int irq, void *devp); | 142 | static irqreturn_t megasas_isr(int irq, void *devp); |
139 | static u32 | 143 | static u32 |
140 | megasas_init_adapter_mfi(struct megasas_instance *instance); | 144 | megasas_init_adapter_mfi(struct megasas_instance *instance); |
@@ -554,6 +558,8 @@ static int | |||
554 | megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | 558 | megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) |
555 | { | 559 | { |
556 | u32 status; | 560 | u32 status; |
561 | u32 mfiStatus = 0; | ||
562 | |||
557 | /* | 563 | /* |
558 | * Check if it is our interrupt | 564 | * Check if it is our interrupt |
559 | */ | 565 | */ |
@@ -564,6 +570,15 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | |||
564 | } | 570 | } |
565 | 571 | ||
566 | /* | 572 | /* |
573 | * Check if it is our interrupt | ||
574 | */ | ||
575 | if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == | ||
576 | MFI_STATE_FAULT) { | ||
577 | mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; | ||
578 | } else | ||
579 | mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; | ||
580 | |||
581 | /* | ||
567 | * Clear the interrupt by writing back the same value | 582 | * Clear the interrupt by writing back the same value |
568 | */ | 583 | */ |
569 | writel(status, ®s->outbound_intr_status); | 584 | writel(status, ®s->outbound_intr_status); |
@@ -573,7 +588,7 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | |||
573 | */ | 588 | */ |
574 | readl(®s->outbound_intr_status); | 589 | readl(®s->outbound_intr_status); |
575 | 590 | ||
576 | return 1; | 591 | return mfiStatus; |
577 | } | 592 | } |
578 | 593 | ||
579 | /** | 594 | /** |
@@ -597,17 +612,6 @@ megasas_fire_cmd_skinny(struct megasas_instance *instance, | |||
597 | } | 612 | } |
598 | 613 | ||
599 | /** | 614 | /** |
600 | * megasas_adp_reset_skinny - For controller reset | ||
601 | * @regs: MFI register set | ||
602 | */ | ||
603 | static int | ||
604 | megasas_adp_reset_skinny(struct megasas_instance *instance, | ||
605 | struct megasas_register_set __iomem *regs) | ||
606 | { | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * megasas_check_reset_skinny - For controller reset check | 615 | * megasas_check_reset_skinny - For controller reset check |
612 | * @regs: MFI register set | 616 | * @regs: MFI register set |
613 | */ | 617 | */ |
@@ -625,7 +629,7 @@ static struct megasas_instance_template megasas_instance_template_skinny = { | |||
625 | .disable_intr = megasas_disable_intr_skinny, | 629 | .disable_intr = megasas_disable_intr_skinny, |
626 | .clear_intr = megasas_clear_intr_skinny, | 630 | .clear_intr = megasas_clear_intr_skinny, |
627 | .read_fw_status_reg = megasas_read_fw_status_reg_skinny, | 631 | .read_fw_status_reg = megasas_read_fw_status_reg_skinny, |
628 | .adp_reset = megasas_adp_reset_skinny, | 632 | .adp_reset = megasas_adp_reset_gen2, |
629 | .check_reset = megasas_check_reset_skinny, | 633 | .check_reset = megasas_check_reset_skinny, |
630 | .service_isr = megasas_isr, | 634 | .service_isr = megasas_isr, |
631 | .tasklet = megasas_complete_cmd_dpc, | 635 | .tasklet = megasas_complete_cmd_dpc, |
@@ -740,20 +744,28 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, | |||
740 | { | 744 | { |
741 | u32 retry = 0 ; | 745 | u32 retry = 0 ; |
742 | u32 HostDiag; | 746 | u32 HostDiag; |
747 | u32 *seq_offset = ®_set->seq_offset; | ||
748 | u32 *hostdiag_offset = ®_set->host_diag; | ||
749 | |||
750 | if (instance->instancet == &megasas_instance_template_skinny) { | ||
751 | seq_offset = ®_set->fusion_seq_offset; | ||
752 | hostdiag_offset = ®_set->fusion_host_diag; | ||
753 | } | ||
754 | |||
755 | writel(0, seq_offset); | ||
756 | writel(4, seq_offset); | ||
757 | writel(0xb, seq_offset); | ||
758 | writel(2, seq_offset); | ||
759 | writel(7, seq_offset); | ||
760 | writel(0xd, seq_offset); | ||
743 | 761 | ||
744 | writel(0, ®_set->seq_offset); | ||
745 | writel(4, ®_set->seq_offset); | ||
746 | writel(0xb, ®_set->seq_offset); | ||
747 | writel(2, ®_set->seq_offset); | ||
748 | writel(7, ®_set->seq_offset); | ||
749 | writel(0xd, ®_set->seq_offset); | ||
750 | msleep(1000); | 762 | msleep(1000); |
751 | 763 | ||
752 | HostDiag = (u32)readl(®_set->host_diag); | 764 | HostDiag = (u32)readl(hostdiag_offset); |
753 | 765 | ||
754 | while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { | 766 | while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { |
755 | msleep(100); | 767 | msleep(100); |
756 | HostDiag = (u32)readl(®_set->host_diag); | 768 | HostDiag = (u32)readl(hostdiag_offset); |
757 | printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", | 769 | printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", |
758 | retry, HostDiag); | 770 | retry, HostDiag); |
759 | 771 | ||
@@ -764,14 +776,14 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, | |||
764 | 776 | ||
765 | printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); | 777 | printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); |
766 | 778 | ||
767 | writel((HostDiag | DIAG_RESET_ADAPTER), ®_set->host_diag); | 779 | writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); |
768 | 780 | ||
769 | ssleep(10); | 781 | ssleep(10); |
770 | 782 | ||
771 | HostDiag = (u32)readl(®_set->host_diag); | 783 | HostDiag = (u32)readl(hostdiag_offset); |
772 | while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { | 784 | while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { |
773 | msleep(100); | 785 | msleep(100); |
774 | HostDiag = (u32)readl(®_set->host_diag); | 786 | HostDiag = (u32)readl(hostdiag_offset); |
775 | printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", | 787 | printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", |
776 | retry, HostDiag); | 788 | retry, HostDiag); |
777 | 789 | ||