aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 41ffc205724f..a8a2666831d3 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -728,6 +728,10 @@ static int
728megasas_check_reset_gen2(struct megasas_instance *instance, 728megasas_check_reset_gen2(struct megasas_instance *instance,
729 struct megasas_register_set __iomem *regs) 729 struct megasas_register_set __iomem *regs)
730{ 730{
731 if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
732 return 1;
733 }
734
731 return 0; 735 return 0;
732} 736}
733 737
@@ -940,6 +944,7 @@ megasas_make_sgl_skinny(struct megasas_instance *instance,
940 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl); 944 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
941 mfi_sgl->sge_skinny[i].phys_addr = 945 mfi_sgl->sge_skinny[i].phys_addr =
942 sg_dma_address(os_sgl); 946 sg_dma_address(os_sgl);
947 mfi_sgl->sge_skinny[i].flag = 0;
943 } 948 }
944 } 949 }
945 return sge_count; 950 return sge_count;
@@ -1567,6 +1572,28 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
1567 } 1572 }
1568} 1573}
1569 1574
1575static void
1576megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
1577
1578static void
1579process_fw_state_change_wq(struct work_struct *work);
1580
1581void megasas_do_ocr(struct megasas_instance *instance)
1582{
1583 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
1584 (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
1585 (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
1586 *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN;
1587 }
1588 instance->instancet->disable_intr(instance->reg_set);
1589 instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
1590 instance->issuepend_done = 0;
1591
1592 atomic_set(&instance->fw_outstanding, 0);
1593 megasas_internal_reset_defer_cmds(instance);
1594 process_fw_state_change_wq(&instance->work_init);
1595}
1596
1570/** 1597/**
1571 * megasas_wait_for_outstanding - Wait for all outstanding cmds 1598 * megasas_wait_for_outstanding - Wait for all outstanding cmds
1572 * @instance: Adapter soft state 1599 * @instance: Adapter soft state
@@ -1584,6 +1611,8 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
1584 unsigned long flags; 1611 unsigned long flags;
1585 struct list_head clist_local; 1612 struct list_head clist_local;
1586 struct megasas_cmd *reset_cmd; 1613 struct megasas_cmd *reset_cmd;
1614 u32 fw_state;
1615 u8 kill_adapter_flag;
1587 1616
1588 spin_lock_irqsave(&instance->hba_lock, flags); 1617 spin_lock_irqsave(&instance->hba_lock, flags);
1589 adprecovery = instance->adprecovery; 1618 adprecovery = instance->adprecovery;
@@ -1669,7 +1698,45 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
1669 msleep(1000); 1698 msleep(1000);
1670 } 1699 }
1671 1700
1672 if (atomic_read(&instance->fw_outstanding)) { 1701 i = 0;
1702 kill_adapter_flag = 0;
1703 do {
1704 fw_state = instance->instancet->read_fw_status_reg(
1705 instance->reg_set) & MFI_STATE_MASK;
1706 if ((fw_state == MFI_STATE_FAULT) &&
1707 (instance->disableOnlineCtrlReset == 0)) {
1708 if (i == 3) {
1709 kill_adapter_flag = 2;
1710 break;
1711 }
1712 megasas_do_ocr(instance);
1713 kill_adapter_flag = 1;
1714
1715 /* wait for 1 secs to let FW finish the pending cmds */
1716 msleep(1000);
1717 }
1718 i++;
1719 } while (i <= 3);
1720
1721 if (atomic_read(&instance->fw_outstanding) &&
1722 !kill_adapter_flag) {
1723 if (instance->disableOnlineCtrlReset == 0) {
1724
1725 megasas_do_ocr(instance);
1726
1727 /* wait for 5 secs to let FW finish the pending cmds */
1728 for (i = 0; i < wait_time; i++) {
1729 int outstanding =
1730 atomic_read(&instance->fw_outstanding);
1731 if (!outstanding)
1732 return SUCCESS;
1733 msleep(1000);
1734 }
1735 }
1736 }
1737
1738 if (atomic_read(&instance->fw_outstanding) ||
1739 (kill_adapter_flag == 2)) {
1673 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n"); 1740 printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n");
1674 /* 1741 /*
1675 * Send signal to FW to stop processing any pending cmds. 1742 * Send signal to FW to stop processing any pending cmds.
@@ -2679,6 +2746,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
2679 return -ENOMEM; 2746 return -ENOMEM;
2680 } 2747 }
2681 2748
2749 memset(cmd->frame, 0, total_sz);
2682 cmd->frame->io.context = cmd->index; 2750 cmd->frame->io.context = cmd->index;
2683 cmd->frame->io.pad_0 = 0; 2751 cmd->frame->io.pad_0 = 0;
2684 } 2752 }