aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c83
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c56
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c23
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c43
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c26
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
9 files changed, 224 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 1ddfd688fea3..b06635ac3356 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -583,6 +583,11 @@ struct lpfc_hba {
583 atomic_t slow_ring_trc_cnt; 583 atomic_t slow_ring_trc_cnt;
584#endif 584#endif
585 585
586 /* Used for deferred freeing of ELS data buffers */
587 struct list_head elsbuf;
588 int elsbuf_cnt;
589 int elsbuf_prev_cnt;
590
586 uint8_t temp_sensor_support; 591 uint8_t temp_sensor_support;
587 /* Fields used for heart beat. */ 592 /* Fields used for heart beat. */
588 unsigned long last_completion_time; 593 unsigned long last_completion_time;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index d09eb533a27d..50fcb7c930bc 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -89,6 +89,7 @@ int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
89 struct serv_parm *, uint32_t); 89 struct serv_parm *, uint32_t);
90int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *); 90int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);
91void lpfc_more_plogi(struct lpfc_vport *); 91void lpfc_more_plogi(struct lpfc_vport *);
92void lpfc_more_adisc(struct lpfc_vport *);
92void lpfc_end_rscn(struct lpfc_vport *); 93void lpfc_end_rscn(struct lpfc_vport *);
93int lpfc_els_chk_latt(struct lpfc_vport *); 94int lpfc_els_chk_latt(struct lpfc_vport *);
94int lpfc_els_abort_flogi(struct lpfc_hba *); 95int lpfc_els_abort_flogi(struct lpfc_hba *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index e8bd7c122f1e..c735ed4ad070 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -426,6 +426,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
426 426
427 lpfc_set_disctmo(vport); 427 lpfc_set_disctmo(vport);
428 vport->num_disc_nodes = 0; 428 vport->num_disc_nodes = 0;
429 vport->fc_ns_retry = 0;
429 430
430 431
431 list_add_tail(&head, &mp->list); 432 list_add_tail(&head, &mp->list);
@@ -506,7 +507,17 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
506 Did, vport->fc_flag, 507 Did, vport->fc_flag,
507 vport->fc_rscn_id_cnt); 508 vport->fc_rscn_id_cnt);
508 509
509 if (lpfc_ns_cmd(vport, 510 /* This NPortID was previously
511 * a FCP target, * Don't even
512 * bother to send GFF_ID.
513 */
514 ndlp = lpfc_findnode_did(vport,
515 Did);
516 if (ndlp && (ndlp->nlp_type &
517 NLP_FCP_TARGET))
518 lpfc_setup_disc_node
519 (vport, Did);
520 else if (lpfc_ns_cmd(vport,
510 SLI_CTNS_GFF_ID, 521 SLI_CTNS_GFF_ID,
511 0, Did) == 0) 522 0, Did) == 0)
512 vport->num_disc_nodes++; 523 vport->num_disc_nodes++;
@@ -554,7 +565,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
554 struct lpfc_dmabuf *outp; 565 struct lpfc_dmabuf *outp;
555 struct lpfc_sli_ct_request *CTrsp; 566 struct lpfc_sli_ct_request *CTrsp;
556 struct lpfc_nodelist *ndlp; 567 struct lpfc_nodelist *ndlp;
557 int rc; 568 int rc, retry;
558 569
559 /* First save ndlp, before we overwrite it */ 570 /* First save ndlp, before we overwrite it */
560 ndlp = cmdiocb->context_un.ndlp; 571 ndlp = cmdiocb->context_un.ndlp;
@@ -585,14 +596,35 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
585 if (irsp->ulpStatus) { 596 if (irsp->ulpStatus) {
586 /* Check for retry */ 597 /* Check for retry */
587 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { 598 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
588 if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || 599 retry = 1;
589 (irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)) 600 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
601 switch (irsp->un.ulpWord[4]) {
602 case IOERR_NO_RESOURCES:
603 /* We don't increment the retry
604 * count for this case.
605 */
606 break;
607 case IOERR_LINK_DOWN:
608 case IOERR_SLI_ABORTED:
609 case IOERR_SLI_DOWN:
610 retry = 0;
611 break;
612 default:
613 vport->fc_ns_retry++;
614 }
615 }
616 else
590 vport->fc_ns_retry++; 617 vport->fc_ns_retry++;
591 /* CT command is being retried */ 618
592 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 619 if (retry) {
620 /* CT command is being retried */
621 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
593 vport->fc_ns_retry, 0); 622 vport->fc_ns_retry, 0);
594 if (rc == 0) 623 if (rc == 0) {
595 goto out; 624 /* success */
625 goto out;
626 }
627 }
596 } 628 }
597 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 629 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
598 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 630 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -698,7 +730,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
698 struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; 730 struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
699 struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; 731 struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
700 struct lpfc_sli_ct_request *CTrsp; 732 struct lpfc_sli_ct_request *CTrsp;
701 int did; 733 int did, rc, retry;
702 uint8_t fbits; 734 uint8_t fbits;
703 struct lpfc_nodelist *ndlp; 735 struct lpfc_nodelist *ndlp;
704 736
@@ -729,6 +761,39 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
729 } 761 }
730 } 762 }
731 else { 763 else {
764 /* Check for retry */
765 if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
766 retry = 1;
767 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
768 switch (irsp->un.ulpWord[4]) {
769 case IOERR_NO_RESOURCES:
770 /* We don't increment the retry
771 * count for this case.
772 */
773 break;
774 case IOERR_LINK_DOWN:
775 case IOERR_SLI_ABORTED:
776 case IOERR_SLI_DOWN:
777 retry = 0;
778 break;
779 default:
780 cmdiocb->retry++;
781 }
782 }
783 else
784 cmdiocb->retry++;
785
786 if (retry) {
787 /* CT command is being retried */
788 rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,
789 cmdiocb->retry, did);
790 if (rc == 0) {
791 /* success */
792 lpfc_ct_free_iocb(phba, cmdiocb);
793 return;
794 }
795 }
796 }
732 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 797 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
733 "0267 NameServer GFF Rsp " 798 "0267 NameServer GFF Rsp "
734 "x%x Error (%d %d) Data: x%x x%x\n", 799 "x%x Error (%d %d) Data: x%x x%x\n",
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index bf332cba2fc0..f5e002435972 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -783,6 +783,8 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
783{ 783{
784 struct lpfc_vport *vport = ndlp->vport; 784 struct lpfc_vport *vport = ndlp->vport;
785 struct lpfc_nodelist *new_ndlp; 785 struct lpfc_nodelist *new_ndlp;
786 struct lpfc_rport_data *rdata;
787 struct fc_rport *rport;
786 struct serv_parm *sp; 788 struct serv_parm *sp;
787 uint8_t name[sizeof(struct lpfc_name)]; 789 uint8_t name[sizeof(struct lpfc_name)];
788 uint32_t rc; 790 uint32_t rc;
@@ -819,6 +821,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
819 lpfc_unreg_rpi(vport, new_ndlp); 821 lpfc_unreg_rpi(vport, new_ndlp);
820 new_ndlp->nlp_DID = ndlp->nlp_DID; 822 new_ndlp->nlp_DID = ndlp->nlp_DID;
821 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; 823 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
824
825 if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
826 new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
827 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
828
822 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); 829 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
823 830
824 /* Move this back to NPR state */ 831 /* Move this back to NPR state */
@@ -826,6 +833,20 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
826 /* The new_ndlp is replacing ndlp totally, so we need 833 /* The new_ndlp is replacing ndlp totally, so we need
827 * to put ndlp on UNUSED list and try to free it. 834 * to put ndlp on UNUSED list and try to free it.
828 */ 835 */
836
837 /* Fix up the rport accordingly */
838 rport = ndlp->rport;
839 if (rport) {
840 rdata = rport->dd_data;
841 if (rdata->pnode == ndlp) {
842 lpfc_nlp_put(ndlp);
843 ndlp->rport = NULL;
844 rdata->pnode = lpfc_nlp_get(new_ndlp);
845 new_ndlp->rport = rport;
846 }
847 new_ndlp->nlp_type = ndlp->nlp_type;
848 }
849
829 lpfc_drop_node(vport, ndlp); 850 lpfc_drop_node(vport, ndlp);
830 } 851 }
831 else { 852 else {
@@ -1149,7 +1170,7 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1149 return 0; 1170 return 0;
1150} 1171}
1151 1172
1152static void 1173void
1153lpfc_more_adisc(struct lpfc_vport *vport) 1174lpfc_more_adisc(struct lpfc_vport *vport)
1154{ 1175{
1155 int sentadisc; 1176 int sentadisc;
@@ -2100,8 +2121,35 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
2100 } 2121 }
2101 /* context2 = cmd, context2->next = rsp, context3 = bpl */ 2122 /* context2 = cmd, context2->next = rsp, context3 = bpl */
2102 if (elsiocb->context2) { 2123 if (elsiocb->context2) {
2103 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; 2124 if (elsiocb->iocb_flag & LPFC_DELAY_MEM_FREE) {
2104 lpfc_els_free_data(phba, buf_ptr1); 2125 /* Firmware could still be in progress of DMAing
2126 * payload, so don't free data buffer till after
2127 * a hbeat.
2128 */
2129 elsiocb->iocb_flag &= ~LPFC_DELAY_MEM_FREE;
2130 buf_ptr = elsiocb->context2;
2131 elsiocb->context2 = NULL;
2132 if (buf_ptr) {
2133 buf_ptr1 = NULL;
2134 spin_lock_irq(&phba->hbalock);
2135 if (!list_empty(&buf_ptr->list)) {
2136 list_remove_head(&buf_ptr->list,
2137 buf_ptr1, struct lpfc_dmabuf,
2138 list);
2139 INIT_LIST_HEAD(&buf_ptr1->list);
2140 list_add_tail(&buf_ptr1->list,
2141 &phba->elsbuf);
2142 phba->elsbuf_cnt++;
2143 }
2144 INIT_LIST_HEAD(&buf_ptr->list);
2145 list_add_tail(&buf_ptr->list, &phba->elsbuf);
2146 phba->elsbuf_cnt++;
2147 spin_unlock_irq(&phba->hbalock);
2148 }
2149 } else {
2150 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
2151 lpfc_els_free_data(phba, buf_ptr1);
2152 }
2105 } 2153 }
2106 2154
2107 if (elsiocb->context3) { 2155 if (elsiocb->context3) {
@@ -3027,6 +3075,8 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
3027 3075
3028 /* To process RSCN, first compare RSCN data with NameServer */ 3076 /* To process RSCN, first compare RSCN data with NameServer */
3029 vport->fc_ns_retry = 0; 3077 vport->fc_ns_retry = 0;
3078 vport->num_disc_nodes = 0;
3079
3030 ndlp = lpfc_findnode_did(vport, NameServer_DID); 3080 ndlp = lpfc_findnode_did(vport, NameServer_DID);
3031 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { 3081 if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
3032 /* Good ndlp, issue CT Request to NameServer */ 3082 /* Good ndlp, issue CT Request to NameServer */
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 74c3b7039c9e..f2b8bc49fe52 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -2564,6 +2564,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2564 } 2564 }
2565 if (vport->port_state != LPFC_FLOGI) { 2565 if (vport->port_state != LPFC_FLOGI) {
2566 lpfc_initial_flogi(vport); 2566 lpfc_initial_flogi(vport);
2567 return;
2567 } 2568 }
2568 break; 2569 break;
2569 2570
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0143baf4ba3b..f32cd9acd3f6 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -547,8 +547,10 @@ void
547lpfc_hb_timeout_handler(struct lpfc_hba *phba) 547lpfc_hb_timeout_handler(struct lpfc_hba *phba)
548{ 548{
549 LPFC_MBOXQ_t *pmboxq; 549 LPFC_MBOXQ_t *pmboxq;
550 struct lpfc_dmabuf *buf_ptr;
550 int retval; 551 int retval;
551 struct lpfc_sli *psli = &phba->sli; 552 struct lpfc_sli *psli = &phba->sli;
553 LIST_HEAD(completions);
552 554
553 if ((phba->link_state == LPFC_HBA_ERROR) || 555 if ((phba->link_state == LPFC_HBA_ERROR) ||
554 (phba->pport->load_flag & FC_UNLOADING) || 556 (phba->pport->load_flag & FC_UNLOADING) ||
@@ -575,6 +577,24 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
575 } 577 }
576 spin_unlock_irq(&phba->pport->work_port_lock); 578 spin_unlock_irq(&phba->pport->work_port_lock);
577 579
580 if (phba->elsbuf_cnt &&
581 (phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) {
582 spin_lock_irq(&phba->hbalock);
583 list_splice_init(&phba->elsbuf, &completions);
584 phba->elsbuf_cnt = 0;
585 phba->elsbuf_prev_cnt = 0;
586 spin_unlock_irq(&phba->hbalock);
587
588 while (!list_empty(&completions)) {
589 list_remove_head(&completions, buf_ptr,
590 struct lpfc_dmabuf, list);
591 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
592 kfree(buf_ptr);
593 }
594 }
595 phba->elsbuf_prev_cnt = phba->elsbuf_cnt;
596
597
578 /* If there is no heart beat outstanding, issue a heartbeat command */ 598 /* If there is no heart beat outstanding, issue a heartbeat command */
579 if (!phba->hb_outstanding) { 599 if (!phba->hb_outstanding) {
580 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL); 600 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
@@ -1999,6 +2019,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
1999 /* Initialize list of fabric iocbs */ 2019 /* Initialize list of fabric iocbs */
2000 INIT_LIST_HEAD(&phba->fabric_iocb_list); 2020 INIT_LIST_HEAD(&phba->fabric_iocb_list);
2001 2021
2022 /* Initialize list to save ELS buffers */
2023 INIT_LIST_HEAD(&phba->elsbuf);
2024
2002 vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); 2025 vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
2003 if (!vport) 2026 if (!vport)
2004 goto out_kthread_stop; 2027 goto out_kthread_stop;
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index c654c787c3e6..783659aa2102 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -442,7 +442,27 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
442 spin_lock_irq(shost->host_lock); 442 spin_lock_irq(shost->host_lock);
443 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; 443 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
444 spin_unlock_irq(shost->host_lock); 444 spin_unlock_irq(shost->host_lock);
445 if (vport->num_disc_nodes) { 445
446 if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
447 (vport->num_disc_nodes)) {
448 /* Check to see if there are more
449 * ADISCs to be sent
450 */
451 lpfc_more_adisc(vport);
452
453 if ((vport->num_disc_nodes == 0) &&
454 (vport->fc_npr_cnt))
455 lpfc_els_disc_plogi(vport);
456
457 if (vport->num_disc_nodes == 0) {
458 spin_lock_irq(shost->host_lock);
459 vport->fc_flag &= ~FC_NDISC_ACTIVE;
460 spin_unlock_irq(shost->host_lock);
461 lpfc_can_disctmo(vport);
462 lpfc_end_rscn(vport);
463 }
464 }
465 else if (vport->num_disc_nodes) {
446 /* Check to see if there are more 466 /* Check to see if there are more
447 * PLOGIs to be sent 467 * PLOGIs to be sent
448 */ 468 */
@@ -813,6 +833,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
813 uint32_t evt) 833 uint32_t evt)
814{ 834{
815 struct lpfc_hba *phba = vport->phba; 835 struct lpfc_hba *phba = vport->phba;
836 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
816 struct lpfc_iocbq *cmdiocb, *rspiocb; 837 struct lpfc_iocbq *cmdiocb, *rspiocb;
817 struct lpfc_dmabuf *pcmd, *prsp, *mp; 838 struct lpfc_dmabuf *pcmd, *prsp, *mp;
818 uint32_t *lp; 839 uint32_t *lp;
@@ -930,11 +951,27 @@ out:
930 "0261 Cannot Register NameServer login\n"); 951 "0261 Cannot Register NameServer login\n");
931 } 952 }
932 953
954 spin_lock_irq(shost->host_lock);
933 ndlp->nlp_flag |= NLP_DEFER_RM; 955 ndlp->nlp_flag |= NLP_DEFER_RM;
956 spin_unlock_irq(shost->host_lock);
934 return NLP_STE_FREED_NODE; 957 return NLP_STE_FREED_NODE;
935} 958}
936 959
937static uint32_t 960static uint32_t
961lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
962 void *arg, uint32_t evt)
963{
964 return ndlp->nlp_state;
965}
966
967static uint32_t
968lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,
969 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)
970{
971 return ndlp->nlp_state;
972}
973
974static uint32_t
938lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 975lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
939 void *arg, uint32_t evt) 976 void *arg, uint32_t evt)
940{ 977{
@@ -2006,9 +2043,9 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
2006 lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ 2043 lpfc_rcv_els_plogi_issue, /* RCV_PRLO */
2007 lpfc_cmpl_plogi_plogi_issue, /* CMPL_PLOGI */ 2044 lpfc_cmpl_plogi_plogi_issue, /* CMPL_PLOGI */
2008 lpfc_disc_illegal, /* CMPL_PRLI */ 2045 lpfc_disc_illegal, /* CMPL_PRLI */
2009 lpfc_disc_illegal, /* CMPL_LOGO */ 2046 lpfc_cmpl_logo_plogi_issue, /* CMPL_LOGO */
2010 lpfc_disc_illegal, /* CMPL_ADISC */ 2047 lpfc_disc_illegal, /* CMPL_ADISC */
2011 lpfc_disc_illegal, /* CMPL_REG_LOGIN */ 2048 lpfc_cmpl_reglogin_plogi_issue,/* CMPL_REG_LOGIN */
2012 lpfc_device_rm_plogi_issue, /* DEVICE_RM */ 2049 lpfc_device_rm_plogi_issue, /* DEVICE_RM */
2013 lpfc_device_recov_plogi_issue, /* DEVICE_RECOVERY */ 2050 lpfc_device_recov_plogi_issue, /* DEVICE_RECOVERY */
2014 2051
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dcc48988040c..be6519793f8a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1147,6 +1147,12 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1147 IOSTAT_LOCAL_REJECT; 1147 IOSTAT_LOCAL_REJECT;
1148 saveq->iocb.un.ulpWord[4] = 1148 saveq->iocb.un.ulpWord[4] =
1149 IOERR_SLI_ABORTED; 1149 IOERR_SLI_ABORTED;
1150
1151 /* Firmware could still be in progress
1152 * of DMAing payload, so don't free data
1153 * buffer till after a hbeat.
1154 */
1155 saveq->iocb_flag |= LPFC_DELAY_MEM_FREE;
1150 } 1156 }
1151 } 1157 }
1152 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); 1158 (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
@@ -3281,6 +3287,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
3281 LIST_HEAD(completions); 3287 LIST_HEAD(completions);
3282 struct lpfc_sli *psli = &phba->sli; 3288 struct lpfc_sli *psli = &phba->sli;
3283 struct lpfc_sli_ring *pring; 3289 struct lpfc_sli_ring *pring;
3290 struct lpfc_dmabuf *buf_ptr;
3284 LPFC_MBOXQ_t *pmb; 3291 LPFC_MBOXQ_t *pmb;
3285 struct lpfc_iocbq *iocb; 3292 struct lpfc_iocbq *iocb;
3286 IOCB_t *cmd = NULL; 3293 IOCB_t *cmd = NULL;
@@ -3320,6 +3327,19 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
3320 } 3327 }
3321 } 3328 }
3322 3329
3330 spin_lock_irqsave(&phba->hbalock, flags);
3331 list_splice_init(&phba->elsbuf, &completions);
3332 phba->elsbuf_cnt = 0;
3333 phba->elsbuf_prev_cnt = 0;
3334 spin_unlock_irqrestore(&phba->hbalock, flags);
3335
3336 while (!list_empty(&completions)) {
3337 list_remove_head(&completions, buf_ptr,
3338 struct lpfc_dmabuf, list);
3339 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
3340 kfree(buf_ptr);
3341 }
3342
3323 /* Return any active mbox cmds */ 3343 /* Return any active mbox cmds */
3324 del_timer_sync(&psli->mbox_tmo); 3344 del_timer_sync(&psli->mbox_tmo);
3325 spin_lock_irqsave(&phba->hbalock, flags); 3345 spin_lock_irqsave(&phba->hbalock, flags);
@@ -3490,6 +3510,12 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3490 pring->txcmplq_cnt--; 3510 pring->txcmplq_cnt--;
3491 spin_unlock_irq(&phba->hbalock); 3511 spin_unlock_irq(&phba->hbalock);
3492 3512
3513 /* Firmware could still be in progress of DMAing
3514 * payload, so don't free data buffer till after
3515 * a hbeat.
3516 */
3517 abort_iocb->iocb_flag |= LPFC_DELAY_MEM_FREE;
3518
3493 abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; 3519 abort_iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
3494 abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; 3520 abort_iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
3495 abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; 3521 abort_iocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED;
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 5fcfe88e2a3f..1796473ad65e 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -44,6 +44,7 @@ struct lpfc_iocbq {
44#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ 44#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */
45#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ 45#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */
46#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */ 46#define LPFC_IO_FABRIC 0x10 /* Iocb send using fabric scheduler */
47#define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */
47 48
48 uint8_t abort_count; 49 uint8_t abort_count;
49 uint8_t rsvd2; 50 uint8_t rsvd2;