aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2014-09-03 12:57:08 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:10:09 -0400
commit2f6fa2c911167e7a3fda130689a36f55b39ed86d (patch)
treee5adad6b8e32a0c54fb0fb31e50449df18ce33d0 /drivers/scsi/lpfc/lpfc_init.c
parentc62321978f542e82960264f175c9e33d7279bec5 (diff)
lpfc: fix IP Reset processing - wait for RDY before proceeding
Fix IP Reset processing - wait for RDY before proceeding Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c109
1 files changed, 47 insertions, 62 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 7f54916c4f62..33a24fc0afec 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7903,7 +7903,8 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7903 LPFC_MBOXQ_t *mboxq; 7903 LPFC_MBOXQ_t *mboxq;
7904 uint32_t rc = 0, if_type; 7904 uint32_t rc = 0, if_type;
7905 uint32_t shdr_status, shdr_add_status; 7905 uint32_t shdr_status, shdr_add_status;
7906 uint32_t rdy_chk, num_resets = 0, reset_again = 0; 7906 uint32_t rdy_chk;
7907 uint32_t port_reset = 0;
7907 union lpfc_sli4_cfg_shdr *shdr; 7908 union lpfc_sli4_cfg_shdr *shdr;
7908 struct lpfc_register reg_data; 7909 struct lpfc_register reg_data;
7909 uint16_t devid; 7910 uint16_t devid;
@@ -7943,9 +7944,42 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7943 } 7944 }
7944 break; 7945 break;
7945 case LPFC_SLI_INTF_IF_TYPE_2: 7946 case LPFC_SLI_INTF_IF_TYPE_2:
7946 for (num_resets = 0; 7947wait:
7947 num_resets < MAX_IF_TYPE_2_RESETS; 7948 /*
7948 num_resets++) { 7949 * Poll the Port Status Register and wait for RDY for
7950 * up to 30 seconds. If the port doesn't respond, treat
7951 * it as an error.
7952 */
7953 for (rdy_chk = 0; rdy_chk < 3000; rdy_chk++) {
7954 if (lpfc_readl(phba->sli4_hba.u.if_type2.
7955 STATUSregaddr, &reg_data.word0)) {
7956 rc = -ENODEV;
7957 goto out;
7958 }
7959 if (bf_get(lpfc_sliport_status_rdy, &reg_data))
7960 break;
7961 msleep(20);
7962 }
7963
7964 if (!bf_get(lpfc_sliport_status_rdy, &reg_data)) {
7965 phba->work_status[0] = readl(
7966 phba->sli4_hba.u.if_type2.ERR1regaddr);
7967 phba->work_status[1] = readl(
7968 phba->sli4_hba.u.if_type2.ERR2regaddr);
7969 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7970 "2890 Port not ready, port status reg "
7971 "0x%x error 1=0x%x, error 2=0x%x\n",
7972 reg_data.word0,
7973 phba->work_status[0],
7974 phba->work_status[1]);
7975 rc = -ENODEV;
7976 goto out;
7977 }
7978
7979 if (!port_reset) {
7980 /*
7981 * Reset the port now
7982 */
7949 reg_data.word0 = 0; 7983 reg_data.word0 = 0;
7950 bf_set(lpfc_sliport_ctrl_end, &reg_data, 7984 bf_set(lpfc_sliport_ctrl_end, &reg_data,
7951 LPFC_SLIPORT_LITTLE_ENDIAN); 7985 LPFC_SLIPORT_LITTLE_ENDIAN);
@@ -7956,64 +7990,16 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7956 /* flush */ 7990 /* flush */
7957 pci_read_config_word(phba->pcidev, 7991 pci_read_config_word(phba->pcidev,
7958 PCI_DEVICE_ID, &devid); 7992 PCI_DEVICE_ID, &devid);
7959 /*
7960 * Poll the Port Status Register and wait for RDY for
7961 * up to 10 seconds. If the port doesn't respond, treat
7962 * it as an error. If the port responds with RN, start
7963 * the loop again.
7964 */
7965 for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) {
7966 msleep(10);
7967 if (lpfc_readl(phba->sli4_hba.u.if_type2.
7968 STATUSregaddr, &reg_data.word0)) {
7969 rc = -ENODEV;
7970 goto out;
7971 }
7972 if (bf_get(lpfc_sliport_status_rn, &reg_data))
7973 reset_again++;
7974 if (bf_get(lpfc_sliport_status_rdy, &reg_data))
7975 break;
7976 }
7977
7978 /*
7979 * If the port responds to the init request with
7980 * reset needed, delay for a bit and restart the loop.
7981 */
7982 if (reset_again && (rdy_chk < 1000)) {
7983 msleep(10);
7984 reset_again = 0;
7985 continue;
7986 }
7987 7993
7988 /* Detect any port errors. */ 7994 port_reset = 1;
7989 if ((bf_get(lpfc_sliport_status_err, &reg_data)) || 7995 msleep(20);
7990 (rdy_chk >= 1000)) { 7996 goto wait;
7991 phba->work_status[0] = readl( 7997 } else if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
7992 phba->sli4_hba.u.if_type2.ERR1regaddr); 7998 rc = -ENODEV;
7993 phba->work_status[1] = readl( 7999 goto out;
7994 phba->sli4_hba.u.if_type2.ERR2regaddr);
7995 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7996 "2890 Port error detected during port "
7997 "reset(%d): wait_tmo:%d ms, "
7998 "port status reg 0x%x, "
7999 "error 1=0x%x, error 2=0x%x\n",
8000 num_resets, rdy_chk*10,
8001 reg_data.word0,
8002 phba->work_status[0],
8003 phba->work_status[1]);
8004 rc = -ENODEV;
8005 }
8006
8007 /*
8008 * Terminate the outer loop provided the Port indicated
8009 * ready within 10 seconds.
8010 */
8011 if (rdy_chk < 1000)
8012 break;
8013 } 8000 }
8014 /* delay driver action following IF_TYPE_2 function reset */
8015 msleep(100);
8016 break; 8001 break;
8002
8017 case LPFC_SLI_INTF_IF_TYPE_1: 8003 case LPFC_SLI_INTF_IF_TYPE_1:
8018 default: 8004 default:
8019 break; 8005 break;
@@ -8021,11 +8007,10 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
8021 8007
8022out: 8008out:
8023 /* Catch the not-ready port failure after a port reset. */ 8009 /* Catch the not-ready port failure after a port reset. */
8024 if (num_resets >= MAX_IF_TYPE_2_RESETS) { 8010 if (rc) {
8025 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 8011 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
8026 "3317 HBA not functional: IP Reset Failed " 8012 "3317 HBA not functional: IP Reset Failed "
8027 "after (%d) retries, try: " 8013 "try: echo fw_reset > board_mode\n");
8028 "echo fw_reset > board_mode\n", num_resets);
8029 rc = -ENODEV; 8014 rc = -ENODEV;
8030 } 8015 }
8031 8016