diff options
author | James Smart <james.smart@emulex.com> | 2011-02-16 12:39:35 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-18 13:45:21 -0500 |
commit | 1151e3ec15c32021a8a12a123459ab5e41692898 (patch) | |
tree | 57cf6cf10dbd7e77654958987ca0f840311fcf2d /drivers/scsi/lpfc | |
parent | fedd3b7b93302c7789bd3eeb190653cfb0fe7645 (diff) |
[SCSI] lpfc 8.3.21: RRQ Implementation fixes
RRQ Implementation fixes
- Added checks to prevent a call to findnode_did in clr_active_rrq
- Added the del_sync_timer call for the rrq_tmr to the stop_hba_timers routine.
- Added a check in __lpfc_set_active_rrq for the driver unloading to prevent
adding an rrq when the driver is being removed.
- Add code to scsi_iocb_cmpl to check for the remote stop and add the rrq.
- Added the same check to els retry.
- Added code to compare the source did in the els rrq to the vports did and
chose the right exchange ID.
- Initialize the start_cmd pointer to indicate when we have looped through
all of the scsi buffers.
- Remove the need for the lock around the clearing of the active bit in the
rrq.
- Added code to clean the els and fcp xri aborted list and remove the all of
the RRQs for a deleted vport.
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 52 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 77 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 191 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 2 |
7 files changed, 205 insertions, 138 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 5b4513792a89..34fbc1820c40 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -423,6 +423,6 @@ int lpfc_send_rrq(struct lpfc_hba *, struct lpfc_node_rrq *); | |||
423 | int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, | 423 | int lpfc_set_rrq_active(struct lpfc_hba *, struct lpfc_nodelist *, |
424 | uint16_t, uint16_t, uint16_t); | 424 | uint16_t, uint16_t, uint16_t); |
425 | void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); | 425 | void lpfc_cleanup_wt_rrqs(struct lpfc_hba *); |
426 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *); | 426 | void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *); |
427 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, | 427 | struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t, |
428 | uint32_t); | 428 | uint32_t); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 58e1a55d97f9..c6d01f63f557 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -2816,9 +2816,17 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2816 | 2816 | ||
2817 | switch (irsp->ulpStatus) { | 2817 | switch (irsp->ulpStatus) { |
2818 | case IOSTAT_FCP_RSP_ERROR: | 2818 | case IOSTAT_FCP_RSP_ERROR: |
2819 | break; | ||
2819 | case IOSTAT_REMOTE_STOP: | 2820 | case IOSTAT_REMOTE_STOP: |
2821 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
2822 | /* This IO was aborted by the target, we don't | ||
2823 | * know the rxid and because we did not send the | ||
2824 | * ABTS we cannot generate and RRQ. | ||
2825 | */ | ||
2826 | lpfc_set_rrq_active(phba, ndlp, | ||
2827 | cmdiocb->sli4_xritag, 0, 0); | ||
2828 | } | ||
2820 | break; | 2829 | break; |
2821 | |||
2822 | case IOSTAT_LOCAL_REJECT: | 2830 | case IOSTAT_LOCAL_REJECT: |
2823 | switch ((irsp->un.ulpWord[4] & 0xff)) { | 2831 | switch ((irsp->un.ulpWord[4] & 0xff)) { |
2824 | case IOERR_LOOP_OPEN_FAILURE: | 2832 | case IOERR_LOOP_OPEN_FAILURE: |
@@ -4014,28 +4022,34 @@ lpfc_els_clear_rrq(struct lpfc_vport *vport, | |||
4014 | uint8_t *pcmd; | 4022 | uint8_t *pcmd; |
4015 | struct RRQ *rrq; | 4023 | struct RRQ *rrq; |
4016 | uint16_t rxid; | 4024 | uint16_t rxid; |
4025 | uint16_t xri; | ||
4017 | struct lpfc_node_rrq *prrq; | 4026 | struct lpfc_node_rrq *prrq; |
4018 | 4027 | ||
4019 | 4028 | ||
4020 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt); | 4029 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt); |
4021 | pcmd += sizeof(uint32_t); | 4030 | pcmd += sizeof(uint32_t); |
4022 | rrq = (struct RRQ *)pcmd; | 4031 | rrq = (struct RRQ *)pcmd; |
4023 | rxid = bf_get(rrq_oxid, rrq); | 4032 | rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg); |
4033 | rxid = be16_to_cpu(bf_get(rrq_rxid, rrq)); | ||
4024 | 4034 | ||
4025 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 4035 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, |
4026 | "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x" | 4036 | "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x" |
4027 | " x%x x%x\n", | 4037 | " x%x x%x\n", |
4028 | bf_get(rrq_did, rrq), | 4038 | be32_to_cpu(bf_get(rrq_did, rrq)), |
4029 | bf_get(rrq_oxid, rrq), | 4039 | be16_to_cpu(bf_get(rrq_oxid, rrq)), |
4030 | rxid, | 4040 | rxid, |
4031 | iocb->iotag, iocb->iocb.ulpContext); | 4041 | iocb->iotag, iocb->iocb.ulpContext); |
4032 | 4042 | ||
4033 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | 4043 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, |
4034 | "Clear RRQ: did:x%x flg:x%x exchg:x%.08x", | 4044 | "Clear RRQ: did:x%x flg:x%x exchg:x%.08x", |
4035 | ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg); | 4045 | ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg); |
4036 | prrq = lpfc_get_active_rrq(vport, rxid, ndlp->nlp_DID); | 4046 | if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq))) |
4047 | xri = be16_to_cpu(bf_get(rrq_oxid, rrq)); | ||
4048 | else | ||
4049 | xri = rxid; | ||
4050 | prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID); | ||
4037 | if (prrq) | 4051 | if (prrq) |
4038 | lpfc_clr_rrq_active(phba, rxid, prrq); | 4052 | lpfc_clr_rrq_active(phba, xri, prrq); |
4039 | return; | 4053 | return; |
4040 | } | 4054 | } |
4041 | 4055 | ||
@@ -7583,6 +7597,32 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
7583 | } | 7597 | } |
7584 | 7598 | ||
7585 | /** | 7599 | /** |
7600 | * lpfc_sli4_vport_delete_els_xri_aborted -Remove all ndlp references for vport | ||
7601 | * @vport: pointer to lpfc vport data structure. | ||
7602 | * | ||
7603 | * This routine is invoked by the vport cleanup for deletions and the cleanup | ||
7604 | * for an ndlp on removal. | ||
7605 | **/ | ||
7606 | void | ||
7607 | lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport) | ||
7608 | { | ||
7609 | struct lpfc_hba *phba = vport->phba; | ||
7610 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | ||
7611 | unsigned long iflag = 0; | ||
7612 | |||
7613 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
7614 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | ||
7615 | list_for_each_entry_safe(sglq_entry, sglq_next, | ||
7616 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | ||
7617 | if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport) | ||
7618 | sglq_entry->ndlp = NULL; | ||
7619 | } | ||
7620 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | ||
7621 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
7622 | return; | ||
7623 | } | ||
7624 | |||
7625 | /** | ||
7586 | * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort | 7626 | * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort |
7587 | * @phba: pointer to lpfc hba data structure. | 7627 | * @phba: pointer to lpfc hba data structure. |
7588 | * @axri: pointer to the els xri abort wcqe structure. | 7628 | * @axri: pointer to the els xri abort wcqe structure. |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1f9c7f19c31f..63300be2e45b 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -3160,7 +3160,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3160 | spin_unlock_irq(shost->host_lock); | 3160 | spin_unlock_irq(shost->host_lock); |
3161 | vport->unreg_vpi_cmpl = VPORT_OK; | 3161 | vport->unreg_vpi_cmpl = VPORT_OK; |
3162 | mempool_free(pmb, phba->mbox_mem_pool); | 3162 | mempool_free(pmb, phba->mbox_mem_pool); |
3163 | lpfc_cleanup_vports_rrqs(vport); | 3163 | lpfc_cleanup_vports_rrqs(vport, NULL); |
3164 | /* | 3164 | /* |
3165 | * This shost reference might have been taken at the beginning of | 3165 | * This shost reference might have been taken at the beginning of |
3166 | * lpfc_vport_delete() | 3166 | * lpfc_vport_delete() |
@@ -3900,6 +3900,8 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
3900 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 3900 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
3901 | return; | 3901 | return; |
3902 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); | 3902 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
3903 | if (vport->phba->sli_rev == LPFC_SLI_REV4) | ||
3904 | lpfc_cleanup_vports_rrqs(vport, ndlp); | ||
3903 | lpfc_nlp_put(ndlp); | 3905 | lpfc_nlp_put(ndlp); |
3904 | return; | 3906 | return; |
3905 | } | 3907 | } |
@@ -4289,7 +4291,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4289 | 4291 | ||
4290 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 4292 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
4291 | list_del_init(&ndlp->dev_loss_evt.evt_listp); | 4293 | list_del_init(&ndlp->dev_loss_evt.evt_listp); |
4292 | 4294 | lpfc_cleanup_vports_rrqs(vport, ndlp); | |
4293 | lpfc_unreg_rpi(vport, ndlp); | 4295 | lpfc_unreg_rpi(vport, ndlp); |
4294 | 4296 | ||
4295 | return 0; | 4297 | return 0; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0b5f76caa6e4..32cd138f6543 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -945,17 +945,13 @@ static void | |||
945 | lpfc_rrq_timeout(unsigned long ptr) | 945 | lpfc_rrq_timeout(unsigned long ptr) |
946 | { | 946 | { |
947 | struct lpfc_hba *phba; | 947 | struct lpfc_hba *phba; |
948 | uint32_t tmo_posted; | ||
949 | unsigned long iflag; | 948 | unsigned long iflag; |
950 | 949 | ||
951 | phba = (struct lpfc_hba *)ptr; | 950 | phba = (struct lpfc_hba *)ptr; |
952 | spin_lock_irqsave(&phba->pport->work_port_lock, iflag); | 951 | spin_lock_irqsave(&phba->pport->work_port_lock, iflag); |
953 | tmo_posted = phba->hba_flag & HBA_RRQ_ACTIVE; | 952 | phba->hba_flag |= HBA_RRQ_ACTIVE; |
954 | if (!tmo_posted) | ||
955 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
956 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | 953 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); |
957 | if (!tmo_posted) | 954 | lpfc_worker_wake_up(phba); |
958 | lpfc_worker_wake_up(phba); | ||
959 | } | 955 | } |
960 | 956 | ||
961 | /** | 957 | /** |
@@ -2280,6 +2276,7 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
2280 | /* Wait for any activity on ndlps to settle */ | 2276 | /* Wait for any activity on ndlps to settle */ |
2281 | msleep(10); | 2277 | msleep(10); |
2282 | } | 2278 | } |
2279 | lpfc_cleanup_vports_rrqs(vport, NULL); | ||
2283 | } | 2280 | } |
2284 | 2281 | ||
2285 | /** | 2282 | /** |
@@ -2355,6 +2352,10 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba) | |||
2355 | del_timer_sync(&phba->fabric_block_timer); | 2352 | del_timer_sync(&phba->fabric_block_timer); |
2356 | del_timer_sync(&phba->eratt_poll); | 2353 | del_timer_sync(&phba->eratt_poll); |
2357 | del_timer_sync(&phba->hb_tmofunc); | 2354 | del_timer_sync(&phba->hb_tmofunc); |
2355 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
2356 | del_timer_sync(&phba->rrq_tmr); | ||
2357 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
2358 | } | ||
2358 | phba->hb_outstanding = 0; | 2359 | phba->hb_outstanding = 0; |
2359 | 2360 | ||
2360 | switch (phba->pci_dev_grp) { | 2361 | switch (phba->pci_dev_grp) { |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index af5498d735e2..d482dfc951f3 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -609,6 +609,32 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) | |||
609 | } | 609 | } |
610 | 610 | ||
611 | /** | 611 | /** |
612 | * lpfc_sli4_vport_delete_fcp_xri_aborted -Remove all ndlp references for vport | ||
613 | * @vport: pointer to lpfc vport data structure. | ||
614 | * | ||
615 | * This routine is invoked by the vport cleanup for deletions and the cleanup | ||
616 | * for an ndlp on removal. | ||
617 | **/ | ||
618 | void | ||
619 | lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport) | ||
620 | { | ||
621 | struct lpfc_hba *phba = vport->phba; | ||
622 | struct lpfc_scsi_buf *psb, *next_psb; | ||
623 | unsigned long iflag = 0; | ||
624 | |||
625 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
626 | spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock); | ||
627 | list_for_each_entry_safe(psb, next_psb, | ||
628 | &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { | ||
629 | if (psb->rdata && psb->rdata->pnode | ||
630 | && psb->rdata->pnode->vport == vport) | ||
631 | psb->rdata = NULL; | ||
632 | } | ||
633 | spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock); | ||
634 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
635 | } | ||
636 | |||
637 | /** | ||
612 | * lpfc_sli4_fcp_xri_aborted - Fast-path process of fcp xri abort | 638 | * lpfc_sli4_fcp_xri_aborted - Fast-path process of fcp xri abort |
613 | * @phba: pointer to lpfc hba data structure. | 639 | * @phba: pointer to lpfc hba data structure. |
614 | * @axri: pointer to the fcp xri abort wcqe structure. | 640 | * @axri: pointer to the fcp xri abort wcqe structure. |
@@ -640,7 +666,11 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, | |||
640 | psb->status = IOSTAT_SUCCESS; | 666 | psb->status = IOSTAT_SUCCESS; |
641 | spin_unlock( | 667 | spin_unlock( |
642 | &phba->sli4_hba.abts_scsi_buf_list_lock); | 668 | &phba->sli4_hba.abts_scsi_buf_list_lock); |
643 | ndlp = psb->rdata->pnode; | 669 | if (psb->rdata && psb->rdata->pnode) |
670 | ndlp = psb->rdata->pnode; | ||
671 | else | ||
672 | ndlp = NULL; | ||
673 | |||
644 | rrq_empty = list_empty(&phba->active_rrq_list); | 674 | rrq_empty = list_empty(&phba->active_rrq_list); |
645 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 675 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
646 | if (ndlp) | 676 | if (ndlp) |
@@ -964,36 +994,29 @@ lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
964 | static struct lpfc_scsi_buf* | 994 | static struct lpfc_scsi_buf* |
965 | lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | 995 | lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
966 | { | 996 | { |
967 | struct lpfc_scsi_buf *lpfc_cmd = NULL; | 997 | struct lpfc_scsi_buf *lpfc_cmd ; |
968 | struct lpfc_scsi_buf *start_lpfc_cmd = NULL; | ||
969 | struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; | ||
970 | unsigned long iflag = 0; | 998 | unsigned long iflag = 0; |
971 | int found = 0; | 999 | int found = 0; |
972 | 1000 | ||
973 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); | 1001 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); |
974 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | 1002 | list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list, |
975 | spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); | 1003 | list) { |
976 | while (!found && lpfc_cmd) { | ||
977 | if (lpfc_test_rrq_active(phba, ndlp, | 1004 | if (lpfc_test_rrq_active(phba, ndlp, |
978 | lpfc_cmd->cur_iocbq.sli4_xritag)) { | 1005 | lpfc_cmd->cur_iocbq.sli4_xritag)) |
979 | lpfc_release_scsi_buf_s4(phba, lpfc_cmd); | 1006 | continue; |
980 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); | 1007 | list_del(&lpfc_cmd->list); |
981 | list_remove_head(scsi_buf_list, lpfc_cmd, | ||
982 | struct lpfc_scsi_buf, list); | ||
983 | spin_unlock_irqrestore(&phba->scsi_buf_list_lock, | ||
984 | iflag); | ||
985 | if (lpfc_cmd == start_lpfc_cmd) { | ||
986 | lpfc_cmd = NULL; | ||
987 | break; | ||
988 | } else | ||
989 | continue; | ||
990 | } | ||
991 | found = 1; | 1008 | found = 1; |
992 | lpfc_cmd->seg_cnt = 0; | 1009 | lpfc_cmd->seg_cnt = 0; |
993 | lpfc_cmd->nonsg_phys = 0; | 1010 | lpfc_cmd->nonsg_phys = 0; |
994 | lpfc_cmd->prot_seg_cnt = 0; | 1011 | lpfc_cmd->prot_seg_cnt = 0; |
1012 | break; | ||
995 | } | 1013 | } |
996 | return lpfc_cmd; | 1014 | spin_unlock_irqrestore(&phba->scsi_buf_list_lock, |
1015 | iflag); | ||
1016 | if (!found) | ||
1017 | return NULL; | ||
1018 | else | ||
1019 | return lpfc_cmd; | ||
997 | } | 1020 | } |
998 | /** | 1021 | /** |
999 | * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA | 1022 | * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA |
@@ -2484,6 +2507,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
2484 | lpfc_worker_wake_up(phba); | 2507 | lpfc_worker_wake_up(phba); |
2485 | break; | 2508 | break; |
2486 | case IOSTAT_LOCAL_REJECT: | 2509 | case IOSTAT_LOCAL_REJECT: |
2510 | case IOSTAT_REMOTE_STOP: | ||
2487 | if (lpfc_cmd->result == IOERR_INVALID_RPI || | 2511 | if (lpfc_cmd->result == IOERR_INVALID_RPI || |
2488 | lpfc_cmd->result == IOERR_NO_RESOURCES || | 2512 | lpfc_cmd->result == IOERR_NO_RESOURCES || |
2489 | lpfc_cmd->result == IOERR_ABORT_REQUESTED || | 2513 | lpfc_cmd->result == IOERR_ABORT_REQUESTED || |
@@ -2510,6 +2534,17 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
2510 | "on unprotected cmd\n"); | 2534 | "on unprotected cmd\n"); |
2511 | } | 2535 | } |
2512 | } | 2536 | } |
2537 | if ((lpfc_cmd->status == IOSTAT_REMOTE_STOP) | ||
2538 | && (phba->sli_rev == LPFC_SLI_REV4) | ||
2539 | && (pnode && NLP_CHK_NODE_ACT(pnode))) { | ||
2540 | /* This IO was aborted by the target, we don't | ||
2541 | * know the rxid and because we did not send the | ||
2542 | * ABTS we cannot generate and RRQ. | ||
2543 | */ | ||
2544 | lpfc_set_rrq_active(phba, pnode, | ||
2545 | lpfc_cmd->cur_iocbq.sli4_xritag, | ||
2546 | 0, 0); | ||
2547 | } | ||
2513 | 2548 | ||
2514 | /* else: fall through */ | 2549 | /* else: fall through */ |
2515 | default: | 2550 | default: |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ed8f048dfb53..b85c40e3bf55 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -535,15 +535,35 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
535 | uint16_t adj_xri; | 535 | uint16_t adj_xri; |
536 | struct lpfc_node_rrq *rrq; | 536 | struct lpfc_node_rrq *rrq; |
537 | int empty; | 537 | int empty; |
538 | uint32_t did = 0; | ||
539 | |||
540 | |||
541 | if (!ndlp) | ||
542 | return -EINVAL; | ||
543 | |||
544 | if (!phba->cfg_enable_rrq) | ||
545 | return -EINVAL; | ||
546 | |||
547 | if (phba->pport->load_flag & FC_UNLOADING) { | ||
548 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
549 | goto out; | ||
550 | } | ||
551 | did = ndlp->nlp_DID; | ||
538 | 552 | ||
539 | /* | 553 | /* |
540 | * set the active bit even if there is no mem available. | 554 | * set the active bit even if there is no mem available. |
541 | */ | 555 | */ |
542 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | 556 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; |
543 | if (!ndlp) | 557 | |
544 | return -EINVAL; | 558 | if (NLP_CHK_FREE_REQ(ndlp)) |
559 | goto out; | ||
560 | |||
561 | if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING)) | ||
562 | goto out; | ||
563 | |||
545 | if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) | 564 | if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) |
546 | return -EINVAL; | 565 | goto out; |
566 | |||
547 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); | 567 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); |
548 | if (rrq) { | 568 | if (rrq) { |
549 | rrq->send_rrq = send_rrq; | 569 | rrq->send_rrq = send_rrq; |
@@ -554,14 +574,7 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
554 | rrq->vport = ndlp->vport; | 574 | rrq->vport = ndlp->vport; |
555 | rrq->rxid = rxid; | 575 | rrq->rxid = rxid; |
556 | empty = list_empty(&phba->active_rrq_list); | 576 | empty = list_empty(&phba->active_rrq_list); |
557 | if (phba->cfg_enable_rrq && send_rrq) | 577 | rrq->send_rrq = send_rrq; |
558 | /* | ||
559 | * We need the xri before we can add this to the | ||
560 | * phba active rrq list. | ||
561 | */ | ||
562 | rrq->send_rrq = send_rrq; | ||
563 | else | ||
564 | rrq->send_rrq = 0; | ||
565 | list_add_tail(&rrq->list, &phba->active_rrq_list); | 578 | list_add_tail(&rrq->list, &phba->active_rrq_list); |
566 | if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { | 579 | if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { |
567 | phba->hba_flag |= HBA_RRQ_ACTIVE; | 580 | phba->hba_flag |= HBA_RRQ_ACTIVE; |
@@ -570,40 +583,49 @@ __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
570 | } | 583 | } |
571 | return 0; | 584 | return 0; |
572 | } | 585 | } |
573 | return -ENOMEM; | 586 | out: |
587 | lpfc_printf_log(phba, KERN_INFO, LOG_SLI, | ||
588 | "2921 Can't set rrq active xri:0x%x rxid:0x%x" | ||
589 | " DID:0x%x Send:%d\n", | ||
590 | xritag, rxid, did, send_rrq); | ||
591 | return -EINVAL; | ||
574 | } | 592 | } |
575 | 593 | ||
576 | /** | 594 | /** |
577 | * __lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | 595 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. |
578 | * @phba: Pointer to HBA context object. | 596 | * @phba: Pointer to HBA context object. |
579 | * @xritag: xri used in this exchange. | 597 | * @xritag: xri used in this exchange. |
580 | * @rrq: The RRQ to be cleared. | 598 | * @rrq: The RRQ to be cleared. |
581 | * | 599 | * |
582 | * This function is called with hbalock held. This function | ||
583 | **/ | 600 | **/ |
584 | static void | 601 | void |
585 | __lpfc_clr_rrq_active(struct lpfc_hba *phba, | 602 | lpfc_clr_rrq_active(struct lpfc_hba *phba, |
586 | uint16_t xritag, | 603 | uint16_t xritag, |
587 | struct lpfc_node_rrq *rrq) | 604 | struct lpfc_node_rrq *rrq) |
588 | { | 605 | { |
589 | uint16_t adj_xri; | 606 | uint16_t adj_xri; |
590 | struct lpfc_nodelist *ndlp; | 607 | struct lpfc_nodelist *ndlp = NULL; |
591 | 608 | ||
592 | ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID); | 609 | if ((rrq->vport) && NLP_CHK_NODE_ACT(rrq->ndlp)) |
610 | ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID); | ||
593 | 611 | ||
594 | /* The target DID could have been swapped (cable swap) | 612 | /* The target DID could have been swapped (cable swap) |
595 | * we should use the ndlp from the findnode if it is | 613 | * we should use the ndlp from the findnode if it is |
596 | * available. | 614 | * available. |
597 | */ | 615 | */ |
598 | if (!ndlp) | 616 | if ((!ndlp) && rrq->ndlp) |
599 | ndlp = rrq->ndlp; | 617 | ndlp = rrq->ndlp; |
600 | 618 | ||
619 | if (!ndlp) | ||
620 | goto out; | ||
621 | |||
601 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | 622 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; |
602 | if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) { | 623 | if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) { |
603 | rrq->send_rrq = 0; | 624 | rrq->send_rrq = 0; |
604 | rrq->xritag = 0; | 625 | rrq->xritag = 0; |
605 | rrq->rrq_stop_time = 0; | 626 | rrq->rrq_stop_time = 0; |
606 | } | 627 | } |
628 | out: | ||
607 | mempool_free(rrq, phba->rrq_pool); | 629 | mempool_free(rrq, phba->rrq_pool); |
608 | } | 630 | } |
609 | 631 | ||
@@ -628,34 +650,34 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba) | |||
628 | struct lpfc_node_rrq *nextrrq; | 650 | struct lpfc_node_rrq *nextrrq; |
629 | unsigned long next_time; | 651 | unsigned long next_time; |
630 | unsigned long iflags; | 652 | unsigned long iflags; |
653 | LIST_HEAD(send_rrq); | ||
631 | 654 | ||
632 | spin_lock_irqsave(&phba->hbalock, iflags); | 655 | spin_lock_irqsave(&phba->hbalock, iflags); |
633 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | 656 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; |
634 | next_time = jiffies + HZ * (phba->fc_ratov + 1); | 657 | next_time = jiffies + HZ * (phba->fc_ratov + 1); |
635 | list_for_each_entry_safe(rrq, nextrrq, | 658 | list_for_each_entry_safe(rrq, nextrrq, |
636 | &phba->active_rrq_list, list) { | 659 | &phba->active_rrq_list, list) { |
637 | if (time_after(jiffies, rrq->rrq_stop_time)) { | 660 | if (time_after(jiffies, rrq->rrq_stop_time)) |
638 | list_del(&rrq->list); | 661 | list_move(&rrq->list, &send_rrq); |
639 | if (!rrq->send_rrq) | 662 | else if (time_before(rrq->rrq_stop_time, next_time)) |
640 | /* this call will free the rrq */ | ||
641 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
642 | else { | ||
643 | /* if we send the rrq then the completion handler | ||
644 | * will clear the bit in the xribitmap. | ||
645 | */ | ||
646 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
647 | if (lpfc_send_rrq(phba, rrq)) { | ||
648 | lpfc_clr_rrq_active(phba, rrq->xritag, | ||
649 | rrq); | ||
650 | } | ||
651 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
652 | } | ||
653 | } else if (time_before(rrq->rrq_stop_time, next_time)) | ||
654 | next_time = rrq->rrq_stop_time; | 663 | next_time = rrq->rrq_stop_time; |
655 | } | 664 | } |
656 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 665 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
657 | if (!list_empty(&phba->active_rrq_list)) | 666 | if (!list_empty(&phba->active_rrq_list)) |
658 | mod_timer(&phba->rrq_tmr, next_time); | 667 | mod_timer(&phba->rrq_tmr, next_time); |
668 | list_for_each_entry_safe(rrq, nextrrq, &send_rrq, list) { | ||
669 | list_del(&rrq->list); | ||
670 | if (!rrq->send_rrq) | ||
671 | /* this call will free the rrq */ | ||
672 | lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
673 | else if (lpfc_send_rrq(phba, rrq)) { | ||
674 | /* if we send the rrq then the completion handler | ||
675 | * will clear the bit in the xribitmap. | ||
676 | */ | ||
677 | lpfc_clr_rrq_active(phba, rrq->xritag, | ||
678 | rrq); | ||
679 | } | ||
680 | } | ||
659 | } | 681 | } |
660 | 682 | ||
661 | /** | 683 | /** |
@@ -693,29 +715,37 @@ lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did) | |||
693 | /** | 715 | /** |
694 | * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport. | 716 | * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport. |
695 | * @vport: Pointer to vport context object. | 717 | * @vport: Pointer to vport context object. |
696 | * | 718 | * @ndlp: Pointer to the lpfc_node_list structure. |
697 | * Remove all active RRQs for this vport from the phba->active_rrq_list and | 719 | * If ndlp is NULL Remove all active RRQs for this vport from the |
698 | * clear the rrq. | 720 | * phba->active_rrq_list and clear the rrq. |
721 | * If ndlp is not NULL then only remove rrqs for this vport & this ndlp. | ||
699 | **/ | 722 | **/ |
700 | void | 723 | void |
701 | lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport) | 724 | lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
702 | 725 | ||
703 | { | 726 | { |
704 | struct lpfc_hba *phba = vport->phba; | 727 | struct lpfc_hba *phba = vport->phba; |
705 | struct lpfc_node_rrq *rrq; | 728 | struct lpfc_node_rrq *rrq; |
706 | struct lpfc_node_rrq *nextrrq; | 729 | struct lpfc_node_rrq *nextrrq; |
707 | unsigned long iflags; | 730 | unsigned long iflags; |
731 | LIST_HEAD(rrq_list); | ||
708 | 732 | ||
709 | if (phba->sli_rev != LPFC_SLI_REV4) | 733 | if (phba->sli_rev != LPFC_SLI_REV4) |
710 | return; | 734 | return; |
711 | spin_lock_irqsave(&phba->hbalock, iflags); | 735 | if (!ndlp) { |
712 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { | 736 | lpfc_sli4_vport_delete_els_xri_aborted(vport); |
713 | if (rrq->vport == vport) { | 737 | lpfc_sli4_vport_delete_fcp_xri_aborted(vport); |
714 | list_del(&rrq->list); | ||
715 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
716 | } | ||
717 | } | 738 | } |
739 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
740 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) | ||
741 | if ((rrq->vport == vport) && (!ndlp || rrq->ndlp == ndlp)) | ||
742 | list_move(&rrq->list, &rrq_list); | ||
718 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 743 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
744 | |||
745 | list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) { | ||
746 | list_del(&rrq->list); | ||
747 | lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
748 | } | ||
719 | } | 749 | } |
720 | 750 | ||
721 | /** | 751 | /** |
@@ -733,24 +763,27 @@ lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba) | |||
733 | struct lpfc_node_rrq *nextrrq; | 763 | struct lpfc_node_rrq *nextrrq; |
734 | unsigned long next_time; | 764 | unsigned long next_time; |
735 | unsigned long iflags; | 765 | unsigned long iflags; |
766 | LIST_HEAD(rrq_list); | ||
736 | 767 | ||
737 | if (phba->sli_rev != LPFC_SLI_REV4) | 768 | if (phba->sli_rev != LPFC_SLI_REV4) |
738 | return; | 769 | return; |
739 | spin_lock_irqsave(&phba->hbalock, iflags); | 770 | spin_lock_irqsave(&phba->hbalock, iflags); |
740 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | 771 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; |
741 | next_time = jiffies + HZ * (phba->fc_ratov * 2); | 772 | next_time = jiffies + HZ * (phba->fc_ratov * 2); |
742 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { | 773 | list_splice_init(&phba->active_rrq_list, &rrq_list); |
774 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
775 | |||
776 | list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) { | ||
743 | list_del(&rrq->list); | 777 | list_del(&rrq->list); |
744 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | 778 | lpfc_clr_rrq_active(phba, rrq->xritag, rrq); |
745 | } | 779 | } |
746 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
747 | if (!list_empty(&phba->active_rrq_list)) | 780 | if (!list_empty(&phba->active_rrq_list)) |
748 | mod_timer(&phba->rrq_tmr, next_time); | 781 | mod_timer(&phba->rrq_tmr, next_time); |
749 | } | 782 | } |
750 | 783 | ||
751 | 784 | ||
752 | /** | 785 | /** |
753 | * __lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. | 786 | * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. |
754 | * @phba: Pointer to HBA context object. | 787 | * @phba: Pointer to HBA context object. |
755 | * @ndlp: Targets nodelist pointer for this exchange. | 788 | * @ndlp: Targets nodelist pointer for this exchange. |
756 | * @xritag the xri in the bitmap to test. | 789 | * @xritag the xri in the bitmap to test. |
@@ -759,8 +792,8 @@ lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba) | |||
759 | * returns 0 = rrq not active for this xri | 792 | * returns 0 = rrq not active for this xri |
760 | * 1 = rrq is valid for this xri. | 793 | * 1 = rrq is valid for this xri. |
761 | **/ | 794 | **/ |
762 | static int | 795 | int |
763 | __lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | 796 | lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, |
764 | uint16_t xritag) | 797 | uint16_t xritag) |
765 | { | 798 | { |
766 | uint16_t adj_xri; | 799 | uint16_t adj_xri; |
@@ -803,52 +836,6 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
803 | } | 836 | } |
804 | 837 | ||
805 | /** | 838 | /** |
806 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | ||
807 | * @phba: Pointer to HBA context object. | ||
808 | * @xritag: xri used in this exchange. | ||
809 | * @rrq: The RRQ to be cleared. | ||
810 | * | ||
811 | * This function is takes the hbalock. | ||
812 | **/ | ||
813 | void | ||
814 | lpfc_clr_rrq_active(struct lpfc_hba *phba, | ||
815 | uint16_t xritag, | ||
816 | struct lpfc_node_rrq *rrq) | ||
817 | { | ||
818 | unsigned long iflags; | ||
819 | |||
820 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
821 | __lpfc_clr_rrq_active(phba, xritag, rrq); | ||
822 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
823 | return; | ||
824 | } | ||
825 | |||
826 | |||
827 | |||
828 | /** | ||
829 | * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. | ||
830 | * @phba: Pointer to HBA context object. | ||
831 | * @ndlp: Targets nodelist pointer for this exchange. | ||
832 | * @xritag the xri in the bitmap to test. | ||
833 | * | ||
834 | * This function takes the hbalock. | ||
835 | * returns 0 = rrq not active for this xri | ||
836 | * 1 = rrq is valid for this xri. | ||
837 | **/ | ||
838 | int | ||
839 | lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
840 | uint16_t xritag) | ||
841 | { | ||
842 | int ret; | ||
843 | unsigned long iflags; | ||
844 | |||
845 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
846 | ret = __lpfc_test_rrq_active(phba, ndlp, xritag); | ||
847 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
848 | return ret; | ||
849 | } | ||
850 | |||
851 | /** | ||
852 | * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool | 839 | * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool |
853 | * @phba: Pointer to HBA context object. | 840 | * @phba: Pointer to HBA context object. |
854 | * @piocb: Pointer to the iocbq. | 841 | * @piocb: Pointer to the iocbq. |
@@ -885,7 +872,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) | |||
885 | return NULL; | 872 | return NULL; |
886 | adj_xri = sglq->sli4_xritag - | 873 | adj_xri = sglq->sli4_xritag - |
887 | phba->sli4_hba.max_cfg_param.xri_base; | 874 | phba->sli4_hba.max_cfg_param.xri_base; |
888 | if (__lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { | 875 | if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { |
889 | /* This xri has an rrq outstanding for this DID. | 876 | /* This xri has an rrq outstanding for this DID. |
890 | * put it back in the list and get another xri. | 877 | * put it back in the list and get another xri. |
891 | */ | 878 | */ |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index aea4aa012270..435a09d331ee 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -566,6 +566,8 @@ void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *, | |||
566 | struct sli4_wcqe_xri_aborted *); | 566 | struct sli4_wcqe_xri_aborted *); |
567 | void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, | 567 | void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, |
568 | struct sli4_wcqe_xri_aborted *); | 568 | struct sli4_wcqe_xri_aborted *); |
569 | void lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *); | ||
570 | void lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *); | ||
569 | int lpfc_sli4_brdreset(struct lpfc_hba *); | 571 | int lpfc_sli4_brdreset(struct lpfc_hba *); |
570 | int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *); | 572 | int lpfc_sli4_add_fcf_record(struct lpfc_hba *, struct fcf_record *); |
571 | void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *); | 573 | void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *); |