aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-10-10 21:32:10 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 12:28:48 -0400
commit73d91e503a60bd164b636258ae9f558b72010602 (patch)
treedc319fbf3cb55fc8d011720d5c13f1b814ae8539
parent8d6f5cea12e5eebdaca94b3a3a4bd4f12e83d85d (diff)
[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes
Miscellanous logic and interface fixes - Fix lpfc_init_vfi_cmpl to check the interface type for interface type 0 before parsing the results. - Cast uint32_t values that are multiplied to uint64_t before the multiplication. - Instead of "break" statement when PCI read returned error, use the goto statement to the end of the routine after setting return value - moved the msleep(10) to the beginning of the wait loop for checking the SLIPort_Status register - Added the code to follow the existing wait for SLIPort_Status register RDY, ERR, and RN bits to be set by the port before proceeding to perform PCI function reset. - Do not override ulpCt_h and ulpCt_l for SLI 4 ports. - For vport delete, call lpfc_nlp_put when the vport's vpi state is not marked with VPI_REGISTERED. - Added missed fields into the driver's Controller Attributes Structure - Changed ringing EQ/CQ/RQ doorbell register to be dependent on the size of the queue. - Return -EACCES in issue_reset if cfg_enable_hba_reset is zero. - Added new logging flag LOG_FCP_UNDER 0x00040000 to qualify underrun logging. - Add a check in the fabric name display routine to display 0 if the port state is <= FLOGI. - Add a check to the switch statement in lpfc_decode_firmware_rev to check for an 'X'. 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>
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c25
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c22
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c23
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c34
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c65
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c16
11 files changed, 143 insertions, 57 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 13215cd396aa..72cb750860d6 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -749,9 +749,11 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
749 struct Scsi_Host *shost = class_to_shost(dev); 749 struct Scsi_Host *shost = class_to_shost(dev);
750 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; 750 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
751 struct lpfc_hba *phba = vport->phba; 751 struct lpfc_hba *phba = vport->phba;
752
753 int status = -EINVAL; 752 int status = -EINVAL;
754 753
754 if (!phba->cfg_enable_hba_reset)
755 return -EACCES;
756
755 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) 757 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
756 status = phba->lpfc_selective_reset(phba); 758 status = phba->lpfc_selective_reset(phba);
757 759
@@ -772,7 +774,7 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
772 * Returns: 774 * Returns:
773 * zero for success 775 * zero for success
774 **/ 776 **/
775static int 777int
776lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) 778lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
777{ 779{
778 struct lpfc_register portstat_reg = {0}; 780 struct lpfc_register portstat_reg = {0};
@@ -4494,9 +4496,10 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
4494 4496
4495 spin_lock_irq(shost->host_lock); 4497 spin_lock_irq(shost->host_lock);
4496 4498
4497 if ((vport->fc_flag & FC_FABRIC) || 4499 if ((vport->port_state > LPFC_FLOGI) &&
4498 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && 4500 ((vport->fc_flag & FC_FABRIC) ||
4499 (vport->fc_flag & FC_PUBLIC_LOOP))) 4501 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
4502 (vport->fc_flag & FC_PUBLIC_LOOP))))
4500 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn); 4503 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
4501 else 4504 else
4502 /* fabric is local port if there is no F/FL_Port */ 4505 /* fabric is local port if there is no F/FL_Port */
@@ -4569,9 +4572,17 @@ lpfc_get_stats(struct Scsi_Host *shost)
4569 memset(hs, 0, sizeof (struct fc_host_statistics)); 4572 memset(hs, 0, sizeof (struct fc_host_statistics));
4570 4573
4571 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt; 4574 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
4572 hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256); 4575 /*
4576 * The MBX_READ_STATUS returns tx_k_bytes which has to
4577 * converted to words
4578 */
4579 hs->tx_words = (uint64_t)
4580 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
4581 * (uint64_t)256);
4573 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt; 4582 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
4574 hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256); 4583 hs->rx_words = (uint64_t)
4584 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
4585 * (uint64_t)256);
4575 4586
4576 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t)); 4587 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
4577 pmb->mbxCommand = MBX_READ_LNK_STAT; 4588 pmb->mbxCommand = MBX_READ_LNK_STAT;
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 779b88e1469d..707081d0a226 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1856,6 +1856,9 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
1856 case 2: 1856 case 2:
1857 c = 'B'; 1857 c = 'B';
1858 break; 1858 break;
1859 case 3:
1860 c = 'X';
1861 break;
1859 default: 1862 default:
1860 c = 0; 1863 c = 0;
1861 break; 1864 break;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 727c793422f2..445826a4c981 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -3386,7 +3386,14 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3386 cmdiocb->context1 = NULL; 3386 cmdiocb->context1 = NULL;
3387 } 3387 }
3388 } 3388 }
3389
3390 /*
3391 * The driver received a LOGO from the rport and has ACK'd it.
3392 * At this point, the driver is done so release the IOCB and
3393 * remove the ndlp reference.
3394 */
3389 lpfc_els_free_iocb(phba, cmdiocb); 3395 lpfc_els_free_iocb(phba, cmdiocb);
3396 lpfc_nlp_put(ndlp);
3390 return; 3397 return;
3391} 3398}
3392 3399
@@ -7257,16 +7264,11 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
7257 icmd->un.elsreq64.myID = 0; 7264 icmd->un.elsreq64.myID = 0;
7258 icmd->un.elsreq64.fl = 1; 7265 icmd->un.elsreq64.fl = 1;
7259 7266
7260 if ((phba->sli_rev == LPFC_SLI_REV4) && 7267 /*
7261 (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == 7268 * SLI3 ports require a different context type value than SLI4.
7262 LPFC_SLI_INTF_IF_TYPE_0)) { 7269 * Catch SLI3 ports here and override the prep.
7263 /* FDISC needs to be 1 for WQE VPI */ 7270 */
7264 elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1; 7271 if (phba->sli_rev == LPFC_SLI_REV3) {
7265 elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
7266 /* Set the ulpContext to the vpi */
7267 elsiocb->iocb.ulpContext = phba->vpi_ids[vport->vpi];
7268 } else {
7269 /* For FDISC, Let FDISC rsp set the NPortID for this VPI */
7270 icmd->ulpCt_h = 1; 7272 icmd->ulpCt_h = 1;
7271 icmd->ulpCt_l = 0; 7273 icmd->ulpCt_l = 0;
7272 } 7274 }
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 7eb34a6e8346..091f68e5cb70 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -2646,7 +2646,9 @@ lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
2646{ 2646{
2647 struct lpfc_vport *vport = mboxq->vport; 2647 struct lpfc_vport *vport = mboxq->vport;
2648 2648
2649 if (mboxq->u.mb.mbxStatus && (mboxq->u.mb.mbxStatus != 0x4002)) { 2649 /* VFI not supported on interface type 0, just do the flogi */
2650 if (mboxq->u.mb.mbxStatus && (bf_get(lpfc_sli_intf_if_type,
2651 &phba->sli4_hba.sli_intf) != LPFC_SLI_INTF_IF_TYPE_0)) {
2650 lpfc_printf_vlog(vport, KERN_ERR, 2652 lpfc_printf_vlog(vport, KERN_ERR,
2651 LOG_MBOX, 2653 LOG_MBOX,
2652 "2891 Init VFI mailbox failed 0x%x\n", 2654 "2891 Init VFI mailbox failed 0x%x\n",
@@ -2655,6 +2657,7 @@ lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
2655 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 2657 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
2656 return; 2658 return;
2657 } 2659 }
2660
2658 lpfc_initial_flogi(vport); 2661 lpfc_initial_flogi(vport);
2659 mempool_free(mboxq, phba->mbox_mem_pool); 2662 mempool_free(mboxq, phba->mbox_mem_pool);
2660 return; 2663 return;
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 52a197db71e6..7db794aa118c 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -680,7 +680,6 @@ struct lpfc_register {
680#define lpfc_rq_doorbell_num_posted_SHIFT 16 680#define lpfc_rq_doorbell_num_posted_SHIFT 16
681#define lpfc_rq_doorbell_num_posted_MASK 0x3FFF 681#define lpfc_rq_doorbell_num_posted_MASK 0x3FFF
682#define lpfc_rq_doorbell_num_posted_WORD word0 682#define lpfc_rq_doorbell_num_posted_WORD word0
683#define LPFC_RQ_POST_BATCH 8 /* RQEs to post at one time */
684#define lpfc_rq_doorbell_id_SHIFT 0 683#define lpfc_rq_doorbell_id_SHIFT 0
685#define lpfc_rq_doorbell_id_MASK 0xFFFF 684#define lpfc_rq_doorbell_id_MASK 0xFFFF
686#define lpfc_rq_doorbell_id_WORD word0 685#define lpfc_rq_doorbell_id_WORD word0
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d8ac7694854e..bdb8f2da27cc 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1438,6 +1438,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1438 struct Scsi_Host *shost; 1438 struct Scsi_Host *shost;
1439 uint32_t if_type; 1439 uint32_t if_type;
1440 struct lpfc_register portstat_reg; 1440 struct lpfc_register portstat_reg;
1441 int rc;
1441 1442
1442 /* If the pci channel is offline, ignore possible errors, since 1443 /* If the pci channel is offline, ignore possible errors, since
1443 * we cannot communicate with the pci card anyway. 1444 * we cannot communicate with the pci card anyway.
@@ -1480,7 +1481,12 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
1480 lpfc_sli4_offline_eratt(phba); 1481 lpfc_sli4_offline_eratt(phba);
1481 return; 1482 return;
1482 } 1483 }
1483 if (bf_get(lpfc_sliport_status_rn, &portstat_reg)) { 1484 /*
1485 * On error status condition, driver need to wait for port
1486 * ready before performing reset.
1487 */
1488 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1489 if (!rc) {
1484 /* need reset: attempt for port recovery */ 1490 /* need reset: attempt for port recovery */
1485 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 1491 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1486 "2887 Port Error: Attempting " 1492 "2887 Port Error: Attempting "
@@ -6725,6 +6731,10 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
6725 "0540 Receive Queue not allocated\n"); 6731 "0540 Receive Queue not allocated\n");
6726 goto out_destroy_fcp_wq; 6732 goto out_destroy_fcp_wq;
6727 } 6733 }
6734
6735 lpfc_rq_adjust_repost(phba, phba->sli4_hba.hdr_rq, LPFC_ELS_HBQ);
6736 lpfc_rq_adjust_repost(phba, phba->sli4_hba.dat_rq, LPFC_ELS_HBQ);
6737
6728 rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq, 6738 rc = lpfc_rq_create(phba, phba->sli4_hba.hdr_rq, phba->sli4_hba.dat_rq,
6729 phba->sli4_hba.els_cq, LPFC_USOL); 6739 phba->sli4_hba.els_cq, LPFC_USOL);
6730 if (rc) { 6740 if (rc) {
@@ -6733,6 +6743,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
6733 "rc = 0x%x\n", rc); 6743 "rc = 0x%x\n", rc);
6734 goto out_destroy_fcp_wq; 6744 goto out_destroy_fcp_wq;
6735 } 6745 }
6746
6736 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 6747 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
6737 "2592 USL RQ setup: hdr-rq-id=%d, dat-rq-id=%d " 6748 "2592 USL RQ setup: hdr-rq-id=%d, dat-rq-id=%d "
6738 "parent cq-id=%d\n", 6749 "parent cq-id=%d\n",
@@ -7042,10 +7053,11 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7042 * the loop again. 7053 * the loop again.
7043 */ 7054 */
7044 for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) { 7055 for (rdy_chk = 0; rdy_chk < 1000; rdy_chk++) {
7056 msleep(10);
7045 if (lpfc_readl(phba->sli4_hba.u.if_type2. 7057 if (lpfc_readl(phba->sli4_hba.u.if_type2.
7046 STATUSregaddr, &reg_data.word0)) { 7058 STATUSregaddr, &reg_data.word0)) {
7047 rc = -ENODEV; 7059 rc = -ENODEV;
7048 break; 7060 goto out;
7049 } 7061 }
7050 if (bf_get(lpfc_sliport_status_rdy, &reg_data)) 7062 if (bf_get(lpfc_sliport_status_rdy, &reg_data))
7051 break; 7063 break;
@@ -7053,7 +7065,6 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7053 reset_again++; 7065 reset_again++;
7054 break; 7066 break;
7055 } 7067 }
7056 msleep(10);
7057 } 7068 }
7058 7069
7059 /* 7070 /*
@@ -7067,11 +7078,6 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7067 } 7078 }
7068 7079
7069 /* Detect any port errors. */ 7080 /* Detect any port errors. */
7070 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
7071 &reg_data.word0)) {
7072 rc = -ENODEV;
7073 break;
7074 }
7075 if ((bf_get(lpfc_sliport_status_err, &reg_data)) || 7081 if ((bf_get(lpfc_sliport_status_err, &reg_data)) ||
7076 (rdy_chk >= 1000)) { 7082 (rdy_chk >= 1000)) {
7077 phba->work_status[0] = readl( 7083 phba->work_status[0] = readl(
@@ -7104,6 +7110,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
7104 break; 7110 break;
7105 } 7111 }
7106 7112
7113out:
7107 /* Catch the not-ready port failure after a port reset. */ 7114 /* Catch the not-ready port failure after a port reset. */
7108 if (num_resets >= MAX_IF_TYPE_2_RESETS) 7115 if (num_resets >= MAX_IF_TYPE_2_RESETS)
7109 rc = -ENODEV; 7116 rc = -ENODEV;
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index e3b790e59156..baf53e6c2bd1 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -36,6 +36,7 @@
36#define LOG_SECURITY 0x00008000 /* Security events */ 36#define LOG_SECURITY 0x00008000 /* Security events */
37#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ 37#define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */
38#define LOG_FIP 0x00020000 /* FIP events */ 38#define LOG_FIP 0x00020000 /* FIP events */
39#define LOG_FCP_UNDER 0x00040000 /* FCP underruns errors */
39#define LOG_ALL_MSG 0xffffffff /* LOG all messages */ 40#define LOG_ALL_MSG 0xffffffff /* LOG all messages */
40 41
41#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ 42#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 75a48e38c1fe..2a3c9c924279 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2325,8 +2325,9 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2325 } 2325 }
2326 lp = (uint32_t *)cmnd->sense_buffer; 2326 lp = (uint32_t *)cmnd->sense_buffer;
2327 2327
2328 if (!scsi_status && (resp_info & RESID_UNDER)) 2328 if (!scsi_status && (resp_info & RESID_UNDER) &&
2329 logit = LOG_FCP; 2329 vport->cfg_log_verbose & LOG_FCP_UNDER)
2330 logit = LOG_FCP_UNDER;
2330 2331
2331 lpfc_printf_vlog(vport, KERN_WARNING, logit, 2332 lpfc_printf_vlog(vport, KERN_WARNING, logit,
2332 "9024 FCP command x%x failed: x%x SNS x%x x%x " 2333 "9024 FCP command x%x failed: x%x SNS x%x x%x "
@@ -2342,7 +2343,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2342 if (resp_info & RESID_UNDER) { 2343 if (resp_info & RESID_UNDER) {
2343 scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); 2344 scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
2344 2345
2345 lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, 2346 lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER,
2346 "9025 FCP Read Underrun, expected %d, " 2347 "9025 FCP Read Underrun, expected %d, "
2347 "residual %d Data: x%x x%x x%x\n", 2348 "residual %d Data: x%x x%x x%x\n",
2348 be32_to_cpu(fcpcmd->fcpDl), 2349 be32_to_cpu(fcpcmd->fcpDl),
@@ -2449,6 +2450,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2449 struct lpfc_fast_path_event *fast_path_evt; 2450 struct lpfc_fast_path_event *fast_path_evt;
2450 struct Scsi_Host *shost; 2451 struct Scsi_Host *shost;
2451 uint32_t queue_depth, scsi_id; 2452 uint32_t queue_depth, scsi_id;
2453 uint32_t logit = LOG_FCP;
2452 2454
2453 /* Sanity check on return of outstanding command */ 2455 /* Sanity check on return of outstanding command */
2454 if (!(lpfc_cmd->pCmd)) 2456 if (!(lpfc_cmd->pCmd))
@@ -2470,16 +2472,22 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
2470 lpfc_cmd->status = IOSTAT_DRIVER_REJECT; 2472 lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
2471 else if (lpfc_cmd->status >= IOSTAT_CNT) 2473 else if (lpfc_cmd->status >= IOSTAT_CNT)
2472 lpfc_cmd->status = IOSTAT_DEFAULT; 2474 lpfc_cmd->status = IOSTAT_DEFAULT;
2473 2475 if (lpfc_cmd->status == IOSTAT_FCP_RSP_ERROR
2474 lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, 2476 && !lpfc_cmd->fcp_rsp->rspStatus3
2475 "9030 FCP cmd x%x failed <%d/%d> " 2477 && (lpfc_cmd->fcp_rsp->rspStatus2 & RESID_UNDER)
2476 "status: x%x result: x%x Data: x%x x%x\n", 2478 && !(phba->cfg_log_verbose & LOG_FCP_UNDER))
2477 cmd->cmnd[0], 2479 logit = 0;
2478 cmd->device ? cmd->device->id : 0xffff, 2480 else
2479 cmd->device ? cmd->device->lun : 0xffff, 2481 logit = LOG_FCP | LOG_FCP_UNDER;
2480 lpfc_cmd->status, lpfc_cmd->result, 2482 lpfc_printf_vlog(vport, KERN_WARNING, logit,
2481 pIocbOut->iocb.ulpContext, 2483 "9030 FCP cmd x%x failed <%d/%d> "
2482 lpfc_cmd->cur_iocbq.iocb.ulpIoTag); 2484 "status: x%x result: x%x Data: x%x x%x\n",
2485 cmd->cmnd[0],
2486 cmd->device ? cmd->device->id : 0xffff,
2487 cmd->device ? cmd->device->lun : 0xffff,
2488 lpfc_cmd->status, lpfc_cmd->result,
2489 pIocbOut->iocb.ulpContext,
2490 lpfc_cmd->cur_iocbq.iocb.ulpIoTag);
2483 2491
2484 switch (lpfc_cmd->status) { 2492 switch (lpfc_cmd->status) {
2485 case IOSTAT_FCP_RSP_ERROR: 2493 case IOSTAT_FCP_RSP_ERROR:
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index abed73d4414a..332c6b716f81 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -379,10 +379,10 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq,
379 dq->host_index = ((dq->host_index + 1) % dq->entry_count); 379 dq->host_index = ((dq->host_index + 1) % dq->entry_count);
380 380
381 /* Ring The Header Receive Queue Doorbell */ 381 /* Ring The Header Receive Queue Doorbell */
382 if (!(hq->host_index % LPFC_RQ_POST_BATCH)) { 382 if (!(hq->host_index % hq->entry_repost)) {
383 doorbell.word0 = 0; 383 doorbell.word0 = 0;
384 bf_set(lpfc_rq_doorbell_num_posted, &doorbell, 384 bf_set(lpfc_rq_doorbell_num_posted, &doorbell,
385 LPFC_RQ_POST_BATCH); 385 hq->entry_repost);
386 bf_set(lpfc_rq_doorbell_id, &doorbell, hq->queue_id); 386 bf_set(lpfc_rq_doorbell_id, &doorbell, hq->queue_id);
387 writel(doorbell.word0, hq->phba->sli4_hba.RQDBregaddr); 387 writel(doorbell.word0, hq->phba->sli4_hba.RQDBregaddr);
388 } 388 }
@@ -1864,7 +1864,7 @@ lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno)
1864{ 1864{
1865 if (phba->sli_rev == LPFC_SLI_REV4) 1865 if (phba->sli_rev == LPFC_SLI_REV4)
1866 return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, 1866 return lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
1867 lpfc_hbq_defs[qno]->entry_count); 1867 lpfc_hbq_defs[qno]->entry_count);
1868 else 1868 else
1869 return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, 1869 return lpfc_sli_hbqbuf_fill_hbqs(phba, qno,
1870 lpfc_hbq_defs[qno]->init_count); 1870 lpfc_hbq_defs[qno]->init_count);
@@ -10419,12 +10419,17 @@ lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe)
10419 /* Move mbox data to caller's mailbox region, do endian swapping */ 10419 /* Move mbox data to caller's mailbox region, do endian swapping */
10420 if (pmb->mbox_cmpl && mbox) 10420 if (pmb->mbox_cmpl && mbox)
10421 lpfc_sli_pcimem_bcopy(mbox, mqe, sizeof(struct lpfc_mqe)); 10421 lpfc_sli_pcimem_bcopy(mbox, mqe, sizeof(struct lpfc_mqe));
10422 /* Set the mailbox status with SLI4 range 0x4000 */
10423 mcqe_status = bf_get(lpfc_mcqe_status, mcqe);
10424 if (mcqe_status != MB_CQE_STATUS_SUCCESS)
10425 bf_set(lpfc_mqe_status, mqe,
10426 (LPFC_MBX_ERROR_RANGE | mcqe_status));
10427 10422
10423 /*
10424 * For mcqe errors, conditionally move a modified error code to
10425 * the mbox so that the error will not be missed.
10426 */
10427 mcqe_status = bf_get(lpfc_mcqe_status, mcqe);
10428 if (mcqe_status != MB_CQE_STATUS_SUCCESS) {
10429 if (bf_get(lpfc_mqe_status, mqe) == MBX_SUCCESS)
10430 bf_set(lpfc_mqe_status, mqe,
10431 (LPFC_MBX_ERROR_RANGE | mcqe_status));
10432 }
10428 if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) { 10433 if (pmb->mbox_flag & LPFC_MBX_IMED_UNREG) {
10429 pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG; 10434 pmb->mbox_flag &= ~LPFC_MBX_IMED_UNREG;
10430 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_MBOX_VPORT, 10435 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_MBOX_VPORT,
@@ -10800,7 +10805,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
10800 case LPFC_MCQ: 10805 case LPFC_MCQ:
10801 while ((cqe = lpfc_sli4_cq_get(cq))) { 10806 while ((cqe = lpfc_sli4_cq_get(cq))) {
10802 workposted |= lpfc_sli4_sp_handle_mcqe(phba, cqe); 10807 workposted |= lpfc_sli4_sp_handle_mcqe(phba, cqe);
10803 if (!(++ecount % LPFC_GET_QE_REL_INT)) 10808 if (!(++ecount % cq->entry_repost))
10804 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM); 10809 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
10805 } 10810 }
10806 break; 10811 break;
@@ -10812,7 +10817,7 @@ lpfc_sli4_sp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe)
10812 else 10817 else
10813 workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, 10818 workposted |= lpfc_sli4_sp_handle_cqe(phba, cq,
10814 cqe); 10819 cqe);
10815 if (!(++ecount % LPFC_GET_QE_REL_INT)) 10820 if (!(++ecount % cq->entry_repost))
10816 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM); 10821 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
10817 } 10822 }
10818 break; 10823 break;
@@ -11044,7 +11049,7 @@ lpfc_sli4_fp_handle_eqe(struct lpfc_hba *phba, struct lpfc_eqe *eqe,
11044 /* Process all the entries to the CQ */ 11049 /* Process all the entries to the CQ */
11045 while ((cqe = lpfc_sli4_cq_get(cq))) { 11050 while ((cqe = lpfc_sli4_cq_get(cq))) {
11046 workposted |= lpfc_sli4_fp_handle_wcqe(phba, cq, cqe); 11051 workposted |= lpfc_sli4_fp_handle_wcqe(phba, cq, cqe);
11047 if (!(++ecount % LPFC_GET_QE_REL_INT)) 11052 if (!(++ecount % cq->entry_repost))
11048 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM); 11053 lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
11049 } 11054 }
11050 11055
@@ -11131,7 +11136,7 @@ lpfc_sli4_sp_intr_handler(int irq, void *dev_id)
11131 */ 11136 */
11132 while ((eqe = lpfc_sli4_eq_get(speq))) { 11137 while ((eqe = lpfc_sli4_eq_get(speq))) {
11133 lpfc_sli4_sp_handle_eqe(phba, eqe); 11138 lpfc_sli4_sp_handle_eqe(phba, eqe);
11134 if (!(++ecount % LPFC_GET_QE_REL_INT)) 11139 if (!(++ecount % speq->entry_repost))
11135 lpfc_sli4_eq_release(speq, LPFC_QUEUE_NOARM); 11140 lpfc_sli4_eq_release(speq, LPFC_QUEUE_NOARM);
11136 } 11141 }
11137 11142
@@ -11211,7 +11216,7 @@ lpfc_sli4_fp_intr_handler(int irq, void *dev_id)
11211 */ 11216 */
11212 while ((eqe = lpfc_sli4_eq_get(fpeq))) { 11217 while ((eqe = lpfc_sli4_eq_get(fpeq))) {
11213 lpfc_sli4_fp_handle_eqe(phba, eqe, fcp_eqidx); 11218 lpfc_sli4_fp_handle_eqe(phba, eqe, fcp_eqidx);
11214 if (!(++ecount % LPFC_GET_QE_REL_INT)) 11219 if (!(++ecount % fpeq->entry_repost))
11215 lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_NOARM); 11220 lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_NOARM);
11216 } 11221 }
11217 11222
@@ -11363,6 +11368,15 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t entry_size,
11363 } 11368 }
11364 queue->entry_size = entry_size; 11369 queue->entry_size = entry_size;
11365 queue->entry_count = entry_count; 11370 queue->entry_count = entry_count;
11371
11372 /*
11373 * entry_repost is calculated based on the number of entries in the
11374 * queue. This works out except for RQs. If buffers are NOT initially
11375 * posted for every RQE, entry_repost should be adjusted accordingly.
11376 */
11377 queue->entry_repost = (entry_count >> 3);
11378 if (queue->entry_repost < LPFC_QUEUE_MIN_REPOST)
11379 queue->entry_repost = LPFC_QUEUE_MIN_REPOST;
11366 queue->phba = phba; 11380 queue->phba = phba;
11367 11381
11368 return queue; 11382 return queue;
@@ -11928,6 +11942,31 @@ out:
11928} 11942}
11929 11943
11930/** 11944/**
11945 * lpfc_rq_adjust_repost - Adjust entry_repost for an RQ
11946 * @phba: HBA structure that indicates port to create a queue on.
11947 * @rq: The queue structure to use for the receive queue.
11948 * @qno: The associated HBQ number
11949 *
11950 *
11951 * For SLI4 we need to adjust the RQ repost value based on
11952 * the number of buffers that are initially posted to the RQ.
11953 */
11954void
11955lpfc_rq_adjust_repost(struct lpfc_hba *phba, struct lpfc_queue *rq, int qno)
11956{
11957 uint32_t cnt;
11958
11959 cnt = lpfc_hbq_defs[qno]->entry_count;
11960
11961 /* Recalc repost for RQs based on buffers initially posted */
11962 cnt = (cnt >> 3);
11963 if (cnt < LPFC_QUEUE_MIN_REPOST)
11964 cnt = LPFC_QUEUE_MIN_REPOST;
11965
11966 rq->entry_repost = cnt;
11967}
11968
11969/**
11931 * lpfc_rq_create - Create a Receive Queue on the HBA 11970 * lpfc_rq_create - Create a Receive Queue on the HBA
11932 * @phba: HBA structure that indicates port to create a queue on. 11971 * @phba: HBA structure that indicates port to create a queue on.
11933 * @hrq: The queue structure to use to create the header receive queue. 11972 * @hrq: The queue structure to use to create the header receive queue.
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 19bb87ae8597..7888964d5b7a 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -23,7 +23,6 @@
23#define LPFC_XRI_EXCH_BUSY_WAIT_T1 10 23#define LPFC_XRI_EXCH_BUSY_WAIT_T1 10
24#define LPFC_XRI_EXCH_BUSY_WAIT_T2 30000 24#define LPFC_XRI_EXCH_BUSY_WAIT_T2 30000
25#define LPFC_RELEASE_NOTIFICATION_INTERVAL 32 25#define LPFC_RELEASE_NOTIFICATION_INTERVAL 32
26#define LPFC_GET_QE_REL_INT 32
27#define LPFC_RPI_LOW_WATER_MARK 10 26#define LPFC_RPI_LOW_WATER_MARK 10
28 27
29#define LPFC_UNREG_FCF 1 28#define LPFC_UNREG_FCF 1
@@ -126,6 +125,8 @@ struct lpfc_queue {
126 struct list_head child_list; 125 struct list_head child_list;
127 uint32_t entry_count; /* Number of entries to support on the queue */ 126 uint32_t entry_count; /* Number of entries to support on the queue */
128 uint32_t entry_size; /* Size of each queue entry. */ 127 uint32_t entry_size; /* Size of each queue entry. */
128 uint32_t entry_repost; /* Count of entries before doorbell is rung */
129#define LPFC_QUEUE_MIN_REPOST 8
129 uint32_t queue_id; /* Queue ID assigned by the hardware */ 130 uint32_t queue_id; /* Queue ID assigned by the hardware */
130 uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */ 131 uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */
131 struct list_head page_list; 132 struct list_head page_list;
@@ -553,6 +554,7 @@ struct lpfc_rsrc_blks {
553 * SLI4 specific function prototypes 554 * SLI4 specific function prototypes
554 */ 555 */
555int lpfc_pci_function_reset(struct lpfc_hba *); 556int lpfc_pci_function_reset(struct lpfc_hba *);
557int lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *);
556int lpfc_sli4_hba_setup(struct lpfc_hba *); 558int lpfc_sli4_hba_setup(struct lpfc_hba *);
557int lpfc_sli4_config(struct lpfc_hba *, struct lpfcMboxq *, uint8_t, 559int lpfc_sli4_config(struct lpfc_hba *, struct lpfcMboxq *, uint8_t,
558 uint8_t, uint32_t, bool); 560 uint8_t, uint32_t, bool);
@@ -576,6 +578,7 @@ uint32_t lpfc_wq_create(struct lpfc_hba *, struct lpfc_queue *,
576 struct lpfc_queue *, uint32_t); 578 struct lpfc_queue *, uint32_t);
577uint32_t lpfc_rq_create(struct lpfc_hba *, struct lpfc_queue *, 579uint32_t lpfc_rq_create(struct lpfc_hba *, struct lpfc_queue *,
578 struct lpfc_queue *, struct lpfc_queue *, uint32_t); 580 struct lpfc_queue *, struct lpfc_queue *, uint32_t);
581void lpfc_rq_adjust_repost(struct lpfc_hba *, struct lpfc_queue *, int);
579uint32_t lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *); 582uint32_t lpfc_eq_destroy(struct lpfc_hba *, struct lpfc_queue *);
580uint32_t lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *); 583uint32_t lpfc_cq_destroy(struct lpfc_hba *, struct lpfc_queue *);
581uint32_t lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *); 584uint32_t lpfc_mq_destroy(struct lpfc_hba *, struct lpfc_queue *);
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 1feb551a57bc..cff6ca67415c 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -692,13 +692,14 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
692 /* Indicate free memory when release */ 692 /* Indicate free memory when release */
693 NLP_SET_FREE_REQ(ndlp); 693 NLP_SET_FREE_REQ(ndlp);
694 } else { 694 } else {
695 if (!NLP_CHK_NODE_ACT(ndlp)) 695 if (!NLP_CHK_NODE_ACT(ndlp)) {
696 ndlp = lpfc_enable_node(vport, ndlp, 696 ndlp = lpfc_enable_node(vport, ndlp,
697 NLP_STE_UNUSED_NODE); 697 NLP_STE_UNUSED_NODE);
698 if (!ndlp) 698 if (!ndlp)
699 goto skip_logo; 699 goto skip_logo;
700 }
700 701
701 /* Remove ndlp from vport npld list */ 702 /* Remove ndlp from vport list */
702 lpfc_dequeue_node(vport, ndlp); 703 lpfc_dequeue_node(vport, ndlp);
703 spin_lock_irq(&phba->ndlp_lock); 704 spin_lock_irq(&phba->ndlp_lock);
704 if (!NLP_CHK_FREE_REQ(ndlp)) 705 if (!NLP_CHK_FREE_REQ(ndlp))
@@ -711,8 +712,17 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
711 } 712 }
712 spin_unlock_irq(&phba->ndlp_lock); 713 spin_unlock_irq(&phba->ndlp_lock);
713 } 714 }
714 if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) 715
716 /*
717 * If the vpi is not registered, then a valid FDISC doesn't
718 * exist and there is no need for a ELS LOGO. Just cleanup
719 * the ndlp.
720 */
721 if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) {
722 lpfc_nlp_put(ndlp);
715 goto skip_logo; 723 goto skip_logo;
724 }
725
716 vport->unreg_vpi_cmpl = VPORT_INVAL; 726 vport->unreg_vpi_cmpl = VPORT_INVAL;
717 timeout = msecs_to_jiffies(phba->fc_ratov * 2000); 727 timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
718 if (!lpfc_issue_els_npiv_logo(vport, ndlp)) 728 if (!lpfc_issue_els_npiv_logo(vport, ndlp))