aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-01-18 16:24:06 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-19 09:08:52 -0500
commit6b5151fd7baec6812fece993ddd7a2cf9fd0125f (patch)
treefeef3e1904163b444f90d834e16931cdb74f0088 /drivers/scsi
parent3ef6d24cd9f473518dd7941e86cc2a5f8992eed0 (diff)
[SCSI] lpfc 8.3.29: SLI related fixes
SLI related fixes: - Fix REG_RPI fails on SLI4 HBA putting NPort into NPR state (126230) - Fix ELS FDISC failing with local reject / invalid RPI. (126350) - Fix reset port when reset is needed during fw_dump (125807) - Fix unbounded firmware revision string from port cause panic (126560) - Fix driver behavior when receiving an ADISC (126654) - Fix driver not returning when bad ndlp found in abts error event handling (126209) - Add more driver logs in area of SLI4 port error attention and reset recovery (126813, 124466) - Fix failure in handling large CQ/EQ identifiers in an IOV environment (126856) - Fix for driver using duplicate RPIs after lancer port reset (126723) - Clear vport->fc_myDID in lpfc_els_issue_fdisc to guarentee a zero SID (126779, 126897) - Fix for SLI4 Port delivery for BLS ABORT ACC (126289) Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h26
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c64
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c76
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c47
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h3
11 files changed, 207 insertions, 34 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index f6697cb0e216..296ad5bc4240 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -353,7 +353,7 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
353 struct lpfc_hba *phba = vport->phba; 353 struct lpfc_hba *phba = vport->phba;
354 uint32_t if_type; 354 uint32_t if_type;
355 uint8_t sli_family; 355 uint8_t sli_family;
356 char fwrev[32]; 356 char fwrev[FW_REV_STR_SIZE];
357 int len; 357 int len;
358 358
359 lpfc_decode_firmware_rev(phba, fwrev, 1); 359 lpfc_decode_firmware_rev(phba, fwrev, 1);
@@ -922,11 +922,15 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
922 rc = lpfc_sli4_pdev_status_reg_wait(phba); 922 rc = lpfc_sli4_pdev_status_reg_wait(phba);
923 923
924 if (rc == -EPERM) { 924 if (rc == -EPERM) {
925 /* no privilage for reset, restore if needed */ 925 /* no privilage for reset */
926 if (before_fc_flag & FC_OFFLINE_MODE) 926 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
927 goto out; 927 "3150 No privilage to perform the requested "
928 "access: x%x\n", reg_val);
928 } else if (rc == -EIO) { 929 } else if (rc == -EIO) {
929 /* reset failed, there is nothing more we can do */ 930 /* reset failed, there is nothing more we can do */
931 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
932 "3153 Fail to perform the requested "
933 "access: x%x\n", reg_val);
930 return rc; 934 return rc;
931 } 935 }
932 936
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 6cb360d47ba3..141e4b40bb55 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -3980,7 +3980,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
3980 case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES: 3980 case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES:
3981 lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, 3981 lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3982 "3106 Handled SLI_CONFIG " 3982 "3106 Handled SLI_CONFIG "
3983 "subsys_fcoe, opcode:x%x\n", 3983 "subsys_comn, opcode:x%x\n",
3984 opcode); 3984 opcode);
3985 rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job, 3985 rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
3986 nemb_mse, dmabuf); 3986 nemb_mse, dmabuf);
@@ -3988,7 +3988,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
3988 default: 3988 default:
3989 lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, 3989 lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
3990 "3107 Reject SLI_CONFIG " 3990 "3107 Reject SLI_CONFIG "
3991 "subsys_fcoe, opcode:x%x\n", 3991 "subsys_comn, opcode:x%x\n",
3992 opcode); 3992 opcode);
3993 rc = -EPERM; 3993 rc = -EPERM;
3994 break; 3994 break;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 26924b7a6cde..330dd7192a7f 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -462,3 +462,4 @@ int lpfc_issue_unreg_vfi(struct lpfc_vport *);
462int lpfc_selective_reset(struct lpfc_hba *); 462int lpfc_selective_reset(struct lpfc_hba *);
463int lpfc_sli4_read_config(struct lpfc_hba *phba); 463int lpfc_sli4_read_config(struct lpfc_hba *phba);
464int lpfc_scsi_buf_update(struct lpfc_hba *phba); 464int lpfc_scsi_buf_update(struct lpfc_hba *phba);
465void lpfc_sli4_node_prep(struct lpfc_hba *phba);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 707081d0a226..93e96b3c9097 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1076,7 +1076,7 @@ int
1076lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol, 1076lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
1077 size_t size) 1077 size_t size)
1078{ 1078{
1079 char fwrev[16]; 1079 char fwrev[FW_REV_STR_SIZE];
1080 int n; 1080 int n;
1081 1081
1082 lpfc_decode_firmware_rev(vport->phba, fwrev, 0); 1082 lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
@@ -1834,7 +1834,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
1834 uint8_t *fwname; 1834 uint8_t *fwname;
1835 1835
1836 if (phba->sli_rev == LPFC_SLI_REV4) 1836 if (phba->sli_rev == LPFC_SLI_REV4)
1837 sprintf(fwrevision, "%s", vp->rev.opFwName); 1837 snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
1838 else if (vp->rev.rBit) { 1838 else if (vp->rev.rBit) {
1839 if (psli->sli_flag & LPFC_SLI_ACTIVE) 1839 if (psli->sli_flag & LPFC_SLI_ACTIVE)
1840 rev = vp->rev.sli2FwRev; 1840 rev = vp->rev.sli2FwRev;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 7afc757338de..2e7709f680bc 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -7172,7 +7172,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7172 goto out; 7172 goto out;
7173 /* FDISC failed */ 7173 /* FDISC failed */
7174 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 7174 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7175 "0126 FDISC failed. (%d/%d)\n", 7175 "0126 FDISC failed. (x%x/x%x)\n",
7176 irsp->ulpStatus, irsp->un.ulpWord[4]); 7176 irsp->ulpStatus, irsp->un.ulpWord[4]);
7177 goto fdisc_failed; 7177 goto fdisc_failed;
7178 } 7178 }
@@ -7283,6 +7283,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
7283 int rc; 7283 int rc;
7284 7284
7285 vport->port_state = LPFC_FDISC; 7285 vport->port_state = LPFC_FDISC;
7286 vport->fc_myDID = 0;
7286 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 7287 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
7287 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 7288 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
7288 ELS_CMD_FDISC); 7289 ELS_CMD_FDISC);
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 7b3dbf316bb3..5f280b5ae3db 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -70,6 +70,7 @@
70/* vendor ID used in SCSI netlink calls */ 70/* vendor ID used in SCSI netlink calls */
71#define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX) 71#define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX)
72 72
73#define FW_REV_STR_SIZE 32
73/* Common Transport structures and definitions */ 74/* Common Transport structures and definitions */
74 75
75union CtRevisionId { 76union CtRevisionId {
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index e5bfa7f334e3..cc19bc1b5ace 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -715,12 +715,20 @@ struct lpfc_register {
715#define lpfc_eqcq_doorbell_eqci_SHIFT 9 715#define lpfc_eqcq_doorbell_eqci_SHIFT 9
716#define lpfc_eqcq_doorbell_eqci_MASK 0x0001 716#define lpfc_eqcq_doorbell_eqci_MASK 0x0001
717#define lpfc_eqcq_doorbell_eqci_WORD word0 717#define lpfc_eqcq_doorbell_eqci_WORD word0
718#define lpfc_eqcq_doorbell_cqid_SHIFT 0 718#define lpfc_eqcq_doorbell_cqid_lo_SHIFT 0
719#define lpfc_eqcq_doorbell_cqid_MASK 0x03FF 719#define lpfc_eqcq_doorbell_cqid_lo_MASK 0x03FF
720#define lpfc_eqcq_doorbell_cqid_WORD word0 720#define lpfc_eqcq_doorbell_cqid_lo_WORD word0
721#define lpfc_eqcq_doorbell_eqid_SHIFT 0 721#define lpfc_eqcq_doorbell_cqid_hi_SHIFT 11
722#define lpfc_eqcq_doorbell_eqid_MASK 0x01FF 722#define lpfc_eqcq_doorbell_cqid_hi_MASK 0x001F
723#define lpfc_eqcq_doorbell_eqid_WORD word0 723#define lpfc_eqcq_doorbell_cqid_hi_WORD word0
724#define lpfc_eqcq_doorbell_eqid_lo_SHIFT 0
725#define lpfc_eqcq_doorbell_eqid_lo_MASK 0x01FF
726#define lpfc_eqcq_doorbell_eqid_lo_WORD word0
727#define lpfc_eqcq_doorbell_eqid_hi_SHIFT 11
728#define lpfc_eqcq_doorbell_eqid_hi_MASK 0x001F
729#define lpfc_eqcq_doorbell_eqid_hi_WORD word0
730#define LPFC_CQID_HI_FIELD_SHIFT 10
731#define LPFC_EQID_HI_FIELD_SHIFT 9
724 732
725#define LPFC_BMBX 0x0160 733#define LPFC_BMBX 0x0160
726#define lpfc_bmbx_addr_SHIFT 2 734#define lpfc_bmbx_addr_SHIFT 2
@@ -3313,7 +3321,11 @@ struct xmit_bls_rsp64_wqe {
3313 uint32_t rsrvd4; 3321 uint32_t rsrvd4;
3314 struct wqe_did wqe_dest; 3322 struct wqe_did wqe_dest;
3315 struct wqe_common wqe_com; /* words 6-11 */ 3323 struct wqe_common wqe_com; /* words 6-11 */
3316 uint32_t rsvd_12_15[4]; 3324 uint32_t word12;
3325#define xmit_bls_rsp64_temprpi_SHIFT 0
3326#define xmit_bls_rsp64_temprpi_MASK 0x0000ffff
3327#define xmit_bls_rsp64_temprpi_WORD word12
3328 uint32_t rsvd_13_15[3];
3317}; 3329};
3318 3330
3319struct wqe_rctl_dfctl { 3331struct wqe_rctl_dfctl {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d670b1c410ec..f3ad7349f5d1 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1475,8 +1475,12 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1475 phba->sli4_hba.u.if_type2.STATUSregaddr, 1475 phba->sli4_hba.u.if_type2.STATUSregaddr,
1476 &portstat_reg.word0); 1476 &portstat_reg.word0);
1477 /* consider PCI bus read error as pci_channel_offline */ 1477 /* consider PCI bus read error as pci_channel_offline */
1478 if (pci_rd_rc1 == -EIO) 1478 if (pci_rd_rc1 == -EIO) {
1479 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1480 "3151 PCI bus read access failure: x%x\n",
1481 readl(phba->sli4_hba.u.if_type2.STATUSregaddr));
1479 return; 1482 return;
1483 }
1480 reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr); 1484 reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
1481 reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr); 1485 reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
1482 if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) { 1486 if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) {
@@ -1526,6 +1530,9 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1526 } 1530 }
1527 /* fall through for not able to recover */ 1531 /* fall through for not able to recover */
1528 } 1532 }
1533 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1534 "3152 Unrecoverable error, bring the port "
1535 "offline\n");
1529 lpfc_sli4_offline_eratt(phba); 1536 lpfc_sli4_offline_eratt(phba);
1530 break; 1537 break;
1531 case LPFC_SLI_INTF_IF_TYPE_1: 1538 case LPFC_SLI_INTF_IF_TYPE_1:
@@ -2514,6 +2521,42 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
2514} 2521}
2515 2522
2516/** 2523/**
2524 * lpfc_sli4_node_prep - Assign RPIs for active nodes.
2525 * @phba: pointer to lpfc hba data structure.
2526 *
2527 * Allocate RPIs for all active remote nodes. This is needed whenever
2528 * an SLI4 adapter is reset and the driver is not unloading. Its purpose
2529 * is to fixup the temporary rpi assignments.
2530 **/
2531void
2532lpfc_sli4_node_prep(struct lpfc_hba *phba)
2533{
2534 struct lpfc_nodelist *ndlp, *next_ndlp;
2535 struct lpfc_vport **vports;
2536 int i;
2537
2538 if (phba->sli_rev != LPFC_SLI_REV4)
2539 return;
2540
2541 vports = lpfc_create_vport_work_array(phba);
2542 if (vports != NULL) {
2543 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
2544 if (vports[i]->load_flag & FC_UNLOADING)
2545 continue;
2546
2547 list_for_each_entry_safe(ndlp, next_ndlp,
2548 &vports[i]->fc_nodes,
2549 nlp_listp) {
2550 if (NLP_CHK_NODE_ACT(ndlp))
2551 ndlp->nlp_rpi =
2552 lpfc_sli4_alloc_rpi(phba);
2553 }
2554 }
2555 }
2556 lpfc_destroy_vport_work_array(phba, vports);
2557}
2558
2559/**
2517 * lpfc_online - Initialize and bring a HBA online 2560 * lpfc_online - Initialize and bring a HBA online
2518 * @phba: pointer to lpfc hba data structure. 2561 * @phba: pointer to lpfc hba data structure.
2519 * 2562 *
@@ -2654,6 +2697,15 @@ lpfc_offline_prep(struct lpfc_hba * phba)
2654 } 2697 }
2655 spin_lock_irq(shost->host_lock); 2698 spin_lock_irq(shost->host_lock);
2656 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 2699 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2700
2701 /*
2702 * Whenever an SLI4 port goes offline, free the
2703 * RPI. A new RPI when the adapter port comes
2704 * back online.
2705 */
2706 if (phba->sli_rev == LPFC_SLI_REV4)
2707 lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
2708
2657 spin_unlock_irq(shost->host_lock); 2709 spin_unlock_irq(shost->host_lock);
2658 lpfc_unreg_rpi(vports[i], ndlp); 2710 lpfc_unreg_rpi(vports[i], ndlp);
2659 } 2711 }
@@ -7224,19 +7276,17 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7224 rc = -ENODEV; 7276 rc = -ENODEV;
7225 goto out; 7277 goto out;
7226 } 7278 }
7227 if (bf_get(lpfc_sliport_status_rdy, &reg_data)) 7279 if (bf_get(lpfc_sliport_status_rn, &reg_data))
7228 break;
7229 if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
7230 reset_again++; 7280 reset_again++;
7281 if (bf_get(lpfc_sliport_status_rdy, &reg_data))
7231 break; 7282 break;
7232 }
7233 } 7283 }
7234 7284
7235 /* 7285 /*
7236 * If the port responds to the init request with 7286 * If the port responds to the init request with
7237 * reset needed, delay for a bit and restart the loop. 7287 * reset needed, delay for a bit and restart the loop.
7238 */ 7288 */
7239 if (reset_again) { 7289 if (reset_again && (rdy_chk < 1000)) {
7240 msleep(10); 7290 msleep(10);
7241 reset_again = 0; 7291 reset_again = 0;
7242 continue; 7292 continue;
@@ -9059,7 +9109,7 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
9059int 9109int
9060lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) 9110lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
9061{ 9111{
9062 char fwrev[32]; 9112 char fwrev[FW_REV_STR_SIZE];
9063 struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; 9113 struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data;
9064 struct list_head dma_buffer_list; 9114 struct list_head dma_buffer_list;
9065 int i, rc = 0; 9115 int i, rc = 0;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index e8bb00559943..32b6d72cd98d 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -48,6 +48,10 @@ static int
48lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 48lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
49 struct lpfc_name *nn, struct lpfc_name *pn) 49 struct lpfc_name *nn, struct lpfc_name *pn)
50{ 50{
51 /* First, we MUST have a RPI registered */
52 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))
53 return 0;
54
51 /* Compare the ADISC rsp WWNN / WWPN matches our internal node 55 /* Compare the ADISC rsp WWNN / WWPN matches our internal node
52 * table entry for that node. 56 * table entry for that node.
53 */ 57 */
@@ -385,6 +389,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
385 if (!mbox) 389 if (!mbox)
386 goto out; 390 goto out;
387 391
392 /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
393 if (phba->sli_rev == LPFC_SLI_REV4)
394 lpfc_unreg_rpi(vport, ndlp);
395
388 rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, 396 rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
389 (uint8_t *) sp, mbox, ndlp->nlp_rpi); 397 (uint8_t *) sp, mbox, ndlp->nlp_rpi);
390 if (rc) { 398 if (rc) {
@@ -445,11 +453,42 @@ out:
445 return 0; 453 return 0;
446} 454}
447 455
456/**
457 * lpfc_mbx_cmpl_resume_rpi - Resume RPI completion routine
458 * @phba: pointer to lpfc hba data structure.
459 * @mboxq: pointer to mailbox object
460 *
461 * This routine is invoked to issue a completion to a rcv'ed
462 * ADISC or PDISC after the paused RPI has been resumed.
463 **/
464static void
465lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
466{
467 struct lpfc_vport *vport;
468 struct lpfc_iocbq *elsiocb;
469 struct lpfc_nodelist *ndlp;
470 uint32_t cmd;
471
472 elsiocb = (struct lpfc_iocbq *)mboxq->context1;
473 ndlp = (struct lpfc_nodelist *) mboxq->context2;
474 vport = mboxq->vport;
475 cmd = elsiocb->drvrTimeout;
476
477 if (cmd == ELS_CMD_ADISC) {
478 lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);
479 } else {
480 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
481 ndlp, NULL);
482 }
483 kfree(elsiocb);
484}
485
448static int 486static int
449lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 487lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
450 struct lpfc_iocbq *cmdiocb) 488 struct lpfc_iocbq *cmdiocb)
451{ 489{
452 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 490 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
491 struct lpfc_iocbq *elsiocb;
453 struct lpfc_dmabuf *pcmd; 492 struct lpfc_dmabuf *pcmd;
454 struct serv_parm *sp; 493 struct serv_parm *sp;
455 struct lpfc_name *pnn, *ppn; 494 struct lpfc_name *pnn, *ppn;
@@ -475,12 +514,43 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
475 514
476 icmd = &cmdiocb->iocb; 515 icmd = &cmdiocb->iocb;
477 if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) { 516 if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
517
518 /*
519 * As soon as we send ACC, the remote NPort can
520 * start sending us data. Thus, for SLI4 we must
521 * resume the RPI before the ACC goes out.
522 */
523 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
524 elsiocb = kmalloc(sizeof(struct lpfc_iocbq),
525 GFP_KERNEL);
526 if (elsiocb) {
527
528 /* Save info from cmd IOCB used in rsp */
529 memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,
530 sizeof(struct lpfc_iocbq));
531
532 /* Save the ELS cmd */
533 elsiocb->drvrTimeout = cmd;
534
535 lpfc_sli4_resume_rpi(ndlp,
536 lpfc_mbx_cmpl_resume_rpi, elsiocb);
537 goto out;
538 }
539 }
540
478 if (cmd == ELS_CMD_ADISC) { 541 if (cmd == ELS_CMD_ADISC) {
479 lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp); 542 lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
480 } else { 543 } else {
481 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, 544 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
482 NULL); 545 ndlp, NULL);
483 } 546 }
547out:
548 /* If we are authenticated, move to the proper state */
549 if (ndlp->nlp_type & NLP_FCP_TARGET)
550 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
551 else
552 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
553
484 return 1; 554 return 1;
485 } 555 }
486 /* Reject this request because invalid parameters */ 556 /* Reject this request because invalid parameters */
@@ -1229,7 +1299,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
1229 } 1299 }
1230 1300
1231 if (phba->sli_rev == LPFC_SLI_REV4) { 1301 if (phba->sli_rev == LPFC_SLI_REV4) {
1232 rc = lpfc_sli4_resume_rpi(ndlp); 1302 rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
1233 if (rc) { 1303 if (rc) {
1234 /* Stay in state and retry. */ 1304 /* Stay in state and retry. */
1235 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; 1305 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 42ea367ddba7..1a391e2df3b3 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -293,7 +293,9 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm)
293 } 293 }
294 bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); 294 bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released);
295 bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); 295 bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
296 bf_set(lpfc_eqcq_doorbell_eqid, &doorbell, q->queue_id); 296 bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
297 (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
298 bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
297 writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); 299 writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
298 /* PCI read to flush PCI pipeline on re-arming for INTx mode */ 300 /* PCI read to flush PCI pipeline on re-arming for INTx mode */
299 if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) 301 if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
@@ -372,7 +374,9 @@ lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm)
372 bf_set(lpfc_eqcq_doorbell_arm, &doorbell, 1); 374 bf_set(lpfc_eqcq_doorbell_arm, &doorbell, 1);
373 bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released); 375 bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released);
374 bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_COMPLETION); 376 bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_COMPLETION);
375 bf_set(lpfc_eqcq_doorbell_cqid, &doorbell, q->queue_id); 377 bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell,
378 (q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT));
379 bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id);
376 writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); 380 writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
377 return released; 381 return released;
378} 382}
@@ -5596,6 +5600,8 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba)
5596 for (i = 0; i < count; i++) 5600 for (i = 0; i < count; i++)
5597 phba->sli4_hba.rpi_ids[i] = base + i; 5601 phba->sli4_hba.rpi_ids[i] = base + i;
5598 5602
5603 lpfc_sli4_node_prep(phba);
5604
5599 /* VPIs. */ 5605 /* VPIs. */
5600 count = phba->sli4_hba.max_cfg_param.max_vpi; 5606 count = phba->sli4_hba.max_cfg_param.max_vpi;
5601 base = phba->sli4_hba.max_cfg_param.vpi_base; 5607 base = phba->sli4_hba.max_cfg_param.vpi_base;
@@ -7555,6 +7561,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
7555 7561
7556 sgl = (struct sli4_sge *)sglq->sgl; 7562 sgl = (struct sli4_sge *)sglq->sgl;
7557 icmd = &piocbq->iocb; 7563 icmd = &piocbq->iocb;
7564 if (icmd->ulpCommand == CMD_XMIT_BLS_RSP64_CX)
7565 return sglq->sli4_xritag;
7558 if (icmd->un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { 7566 if (icmd->un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
7559 numBdes = icmd->un.genreq64.bdl.bdeSize / 7567 numBdes = icmd->un.genreq64.bdl.bdeSize /
7560 sizeof(struct ulp_bde64); 7568 sizeof(struct ulp_bde64);
@@ -7756,6 +7764,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
7756 if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { 7764 if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
7757 if (pcmd && (*pcmd == ELS_CMD_FLOGI || 7765 if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
7758 *pcmd == ELS_CMD_SCR || 7766 *pcmd == ELS_CMD_SCR ||
7767 *pcmd == ELS_CMD_FDISC ||
7759 *pcmd == ELS_CMD_PLOGI)) { 7768 *pcmd == ELS_CMD_PLOGI)) {
7760 bf_set(els_req64_sp, &wqe->els_req, 1); 7769 bf_set(els_req64_sp, &wqe->els_req, 1);
7761 bf_set(els_req64_sid, &wqe->els_req, 7770 bf_set(els_req64_sid, &wqe->els_req,
@@ -7982,6 +7991,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
7982 xritag = 0; 7991 xritag = 0;
7983 break; 7992 break;
7984 case CMD_XMIT_BLS_RSP64_CX: 7993 case CMD_XMIT_BLS_RSP64_CX:
7994 ndlp = (struct lpfc_nodelist *)iocbq->context1;
7985 /* As BLS ABTS RSP WQE is very different from other WQEs, 7995 /* As BLS ABTS RSP WQE is very different from other WQEs,
7986 * we re-construct this WQE here based on information in 7996 * we re-construct this WQE here based on information in
7987 * iocbq from scratch. 7997 * iocbq from scratch.
@@ -8008,8 +8018,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
8008 } 8018 }
8009 bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); 8019 bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
8010 bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); 8020 bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
8021
8022 /* Use CT=VPI */
8023 bf_set(wqe_els_did, &wqe->xmit_bls_rsp.wqe_dest,
8024 ndlp->nlp_DID);
8025 bf_set(xmit_bls_rsp64_temprpi, &wqe->xmit_bls_rsp,
8026 iocbq->iocb.ulpContext);
8027 bf_set(wqe_ct, &wqe->xmit_bls_rsp.wqe_com, 1);
8011 bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, 8028 bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
8012 iocbq->iocb.ulpContext); 8029 phba->vpi_ids[phba->pport->vpi]);
8013 bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1); 8030 bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1);
8014 bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com, 8031 bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com,
8015 LPFC_WQE_LENLOC_NONE); 8032 LPFC_WQE_LENLOC_NONE);
@@ -8073,8 +8090,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
8073 8090
8074 if (piocb->sli4_xritag == NO_XRI) { 8091 if (piocb->sli4_xritag == NO_XRI) {
8075 if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || 8092 if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
8076 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN || 8093 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
8077 piocb->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX)
8078 sglq = NULL; 8094 sglq = NULL;
8079 else { 8095 else {
8080 if (pring->txq_cnt) { 8096 if (pring->txq_cnt) {
@@ -8384,10 +8400,13 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba,
8384{ 8400{
8385 struct lpfc_vport *vport; 8401 struct lpfc_vport *vport;
8386 8402
8387 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 8403 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
8388 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 8404 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
8389 "3115 Node Context not found, driver " 8405 "3115 Node Context not found, driver "
8390 "ignoring abts err event\n"); 8406 "ignoring abts err event\n");
8407 return;
8408 }
8409
8391 vport = ndlp->vport; 8410 vport = ndlp->vport;
8392 lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, 8411 lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
8393 "3116 Port generated FCP XRI ABORT event on " 8412 "3116 Port generated FCP XRI ABORT event on "
@@ -14042,6 +14061,13 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,
14042{ 14061{
14043 if (cmd_iocbq) 14062 if (cmd_iocbq)
14044 lpfc_sli_release_iocbq(phba, cmd_iocbq); 14063 lpfc_sli_release_iocbq(phba, cmd_iocbq);
14064
14065 /* Failure means BLS ABORT RSP did not get delivered to remote node*/
14066 if (rsp_iocbq && rsp_iocbq->iocb.ulpStatus)
14067 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
14068 "3154 BLS ABORT RSP failed, data: x%x/x%x\n",
14069 rsp_iocbq->iocb.ulpStatus,
14070 rsp_iocbq->iocb.un.ulpWord[4]);
14045} 14071}
14046 14072
14047/** 14073/**
@@ -14748,7 +14774,8 @@ lpfc_sli4_remove_rpis(struct lpfc_hba *phba)
14748 * provided rpi via a bitmask. 14774 * provided rpi via a bitmask.
14749 **/ 14775 **/
14750int 14776int
14751lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp) 14777lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
14778 void (*cmpl)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *arg)
14752{ 14779{
14753 LPFC_MBOXQ_t *mboxq; 14780 LPFC_MBOXQ_t *mboxq;
14754 struct lpfc_hba *phba = ndlp->phba; 14781 struct lpfc_hba *phba = ndlp->phba;
@@ -14761,6 +14788,12 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp)
14761 14788
14762 /* Post all rpi memory regions to the port. */ 14789 /* Post all rpi memory regions to the port. */
14763 lpfc_resume_rpi(mboxq, ndlp); 14790 lpfc_resume_rpi(mboxq, ndlp);
14791 if (cmpl) {
14792 mboxq->mbox_cmpl = cmpl;
14793 mboxq->context1 = arg;
14794 mboxq->context2 = ndlp;
14795 }
14796 mboxq->vport = ndlp->vport;
14764 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); 14797 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
14765 if (rc == MBX_NOT_FINISHED) { 14798 if (rc == MBX_NOT_FINISHED) {
14766 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 14799 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 3f266e2c54e0..c19d139618b7 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -633,7 +633,8 @@ void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
633void lpfc_sli4_remove_rpis(struct lpfc_hba *); 633void lpfc_sli4_remove_rpis(struct lpfc_hba *);
634void lpfc_sli4_async_event_proc(struct lpfc_hba *); 634void lpfc_sli4_async_event_proc(struct lpfc_hba *);
635void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *); 635void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *);
636int lpfc_sli4_resume_rpi(struct lpfc_nodelist *); 636int lpfc_sli4_resume_rpi(struct lpfc_nodelist *,
637 void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *);
637void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); 638void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *);
638void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); 639void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *);
639void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *, 640void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *,