diff -rupN old/drivers/scsi/megaraid/megaraid_sas.c new/drivers/scsi/megaraid/megaraid_sas.c --- old/drivers/scsi/megaraid/megaraid_sas.c 2010-11-16 06:29:31.000000000 -0500 +++ new/drivers/scsi/megaraid/megaraid_sas.c 2010-11-17 13:08:03.000000000 -0500 @@ -121,6 +121,12 @@ static void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, u8 alt_status); +static u32 +megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); + +static int megasas_adp_reset_gen2(struct megasas_instance *instance, + struct megasas_register_set __iomem *reg_set); + /** * megasas_get_cmd - Get a command from the free pool * @instance: Adapter soft state @@ -497,6 +503,8 @@ static int megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) { u32 status; + u32 mfiStatus = 0; + /* * Check if it is our interrupt */ @@ -507,6 +515,15 @@ megasas_clear_intr_skinny(struct megasas } /* + * Check if it is our interrupt + */ + if ((megasas_read_fw_status_reg_gen2( regs) & MFI_STATE_MASK ) == + MFI_STATE_FAULT ) { + mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; + } else + mfiStatus |= MFI_INTR_FLAG_REPLY_MESSAGE; + + /* * Clear the interrupt by writing back the same value */ writel(status, ®s->outbound_intr_status); @@ -516,7 +533,7 @@ megasas_clear_intr_skinny(struct megasas */ readl(®s->outbound_intr_status); - return 1; + return mfiStatus; } /** @@ -540,17 +557,6 @@ megasas_fire_cmd_skinny(struct megasas_i } /** - * megasas_adp_reset_skinny - For controller reset - * @regs: MFI register set - */ -static int -megasas_adp_reset_skinny(struct megasas_instance *instance, - struct megasas_register_set __iomem *regs) -{ - return 0; -} - -/** * megasas_check_reset_skinny - For controller reset check * @regs: MFI register set */ @@ -568,7 +574,7 @@ static struct megasas_instance_template .disable_intr = megasas_disable_intr_skinny, .clear_intr = megasas_clear_intr_skinny, .read_fw_status_reg = megasas_read_fw_status_reg_skinny, - .adp_reset = megasas_adp_reset_skinny, + .adp_reset = megasas_adp_reset_gen2, .check_reset = megasas_check_reset_skinny, }; @@ -678,20 +684,26 @@ megasas_adp_reset_gen2(struct megasas_in { u32 retry = 0 ; u32 HostDiag; + u32 *seq_offset = ®_set->seq_offset; + u32 *hostdiag_offset = ®_set->host_diag; - writel(0, ®_set->seq_offset); - writel(4, ®_set->seq_offset); - writel(0xb, ®_set->seq_offset); - writel(2, ®_set->seq_offset); - writel(7, ®_set->seq_offset); - writel(0xd, ®_set->seq_offset); - msleep(1000); + if (instance->instancet == &megasas_instance_template_skinny ) { + seq_offset = ®_set->fusion_seq_offset; + hostdiag_offset = ®_set->fusion_host_diag; + } + writel(0, seq_offset); + writel(4, seq_offset); + writel(0xb, seq_offset); + writel(2, seq_offset); + writel(7, seq_offset); + writel(0xd, seq_offset); - HostDiag = (u32)readl(®_set->host_diag); + msleep(1000); + HostDiag = (u32)readl(hostdiag_offset); while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { msleep(100); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", retry, HostDiag); @@ -701,15 +713,15 @@ megasas_adp_reset_gen2(struct megasas_in } printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); - - writel((HostDiag | DIAG_RESET_ADAPTER), ®_set->host_diag); + writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); ssleep(10); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); + while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { msleep(100); - HostDiag = (u32)readl(®_set->host_diag); + HostDiag = (u32)readl(hostdiag_offset); printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", retry, HostDiag); @@ -1502,7 +1514,7 @@ static void megaraid_sas_kill_hba(struct if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { writel(MFI_STOP_ADP, - &instance->reg_set->reserved_0[0]); + &instance->reg_set->reserved_0); } else { writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); @@ -1754,7 +1766,7 @@ static int megasas_wait_for_outstanding( (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { writel(MFI_STOP_ADP, - &instance->reg_set->reserved_0[0]); + &instance->reg_set->reserved_0); } else { writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell); @@ -2506,7 +2518,7 @@ megasas_transition_to_ready(struct megas writel( MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, - &instance->reg_set->reserved_0[0]); + &instance->reg_set->reserved_0); } else { writel( MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, @@ -2523,7 +2535,7 @@ megasas_transition_to_ready(struct megas (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { writel(MFI_INIT_HOTPLUG, - &instance->reg_set->reserved_0[0]); + &instance->reg_set->reserved_0); } else writel(MFI_INIT_HOTPLUG, &instance->reg_set->inbound_doorbell); @@ -2542,7 +2554,7 @@ megasas_transition_to_ready(struct megas (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { writel(MFI_RESET_FLAGS, - &instance->reg_set->reserved_0[0]); + &instance->reg_set->reserved_0); } else writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); diff -rupN old/drivers/scsi/megaraid/megaraid_sas.h new/drivers/scsi/megaraid/megaraid_sas.h --- old/drivers/scsi/megaraid/megaraid_sas.h 2010-11-16 06:29:31.000000000 -0500 +++ new/drivers/scsi/megaraid/megaraid_sas.h 2010-11-14 16:23:04.000000000 -0500 @@ -771,7 +771,10 @@ struct megasas_ctrl_info { */ struct megasas_register_set { - u32 reserved_0[4]; /*0000h*/ + u32 reserved_0; /*0000h*/ + u32 fusion_seq_offset; /*0004h*/ + u32 fusion_host_diag; /*0008h*/ + u32 reserved_01; /*000Ch*/ u32 inbound_msg_0; /*0010h*/ u32 inbound_msg_1; /*0014h*/