aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-07-19 10:01:21 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-08-22 18:51:58 -0400
commit32b9793fe6ff09a85f36b8bd7d6ff214653a7497 (patch)
treee4bfaf3c28982f9e9b2555ba06dc780e7cb70dca /drivers/scsi/lpfc
parent8568a4d2495ebcf5da38a2141c7633399143b1a5 (diff)
[SCSI] lpfc 8.3.4: Fix a pair of FCoE issues
Fix a pair of FCoE issues - Fix Region 23 FCoE Parameters not being read correctly - Fix race condition when there are FCoE events during FCF table read Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c77
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c7
5 files changed, 92 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 8b69a110a305..d982ac78009e 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -526,6 +526,7 @@ struct lpfc_hba {
526#define ELS_XRI_ABORT_EVENT 0x40 526#define ELS_XRI_ABORT_EVENT 0x40
527#define ASYNC_EVENT 0x80 527#define ASYNC_EVENT 0x80
528#define LINK_DISABLED 0x100 /* Link disabled by user */ 528#define LINK_DISABLED 0x100 /* Link disabled by user */
529#define FCF_DISC_INPROGRESS 0x200 /* FCF discovery in progress */
529 struct lpfc_dmabuf slim2p; 530 struct lpfc_dmabuf slim2p;
530 531
531 MAILBOX_t *mbox; 532 MAILBOX_t *mbox;
@@ -767,6 +768,8 @@ struct lpfc_hba {
767/* Maximum number of events that can be outstanding at any time*/ 768/* Maximum number of events that can be outstanding at any time*/
768#define LPFC_MAX_EVT_COUNT 512 769#define LPFC_MAX_EVT_COUNT 512
769 atomic_t fast_event_count; 770 atomic_t fast_event_count;
771 uint32_t fcoe_eventtag;
772 uint32_t fcoe_eventtag_at_fcf_scan;
770 struct lpfc_fcf fcf; 773 struct lpfc_fcf fcf;
771 uint8_t fc_map[3]; 774 uint8_t fc_map[3];
772 uint8_t valid_vlan; 775 uint8_t valid_vlan;
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 84e53bb1daa3..d52aa3310551 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -189,6 +189,7 @@ void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t);
189void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); 189void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *);
190void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); 190void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
191void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *); 191void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
192int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t);
192 193
193void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *, 194void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *,
194 uint32_t , LPFC_MBOXQ_t *); 195 uint32_t , LPFC_MBOXQ_t *);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 625b2ef3050f..cc4b6ba9e4d5 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -61,6 +61,7 @@ static uint8_t lpfcAlpaArray[] = {
61 61
62static void lpfc_disc_timeout_handler(struct lpfc_vport *); 62static void lpfc_disc_timeout_handler(struct lpfc_vport *);
63static void lpfc_disc_flush_list(struct lpfc_vport *vport); 63static void lpfc_disc_flush_list(struct lpfc_vport *vport);
64static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
64 65
65void 66void
66lpfc_terminate_rport_io(struct fc_rport *rport) 67lpfc_terminate_rport_io(struct fc_rport *rport)
@@ -1009,9 +1010,15 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1009 spin_lock_irqsave(&phba->hbalock, flags); 1010 spin_lock_irqsave(&phba->hbalock, flags);
1010 phba->fcf.fcf_flag |= FCF_REGISTERED; 1011 phba->fcf.fcf_flag |= FCF_REGISTERED;
1011 spin_unlock_irqrestore(&phba->hbalock, flags); 1012 spin_unlock_irqrestore(&phba->hbalock, flags);
1013 /* If there is a pending FCoE event, restart FCF table scan. */
1014 if (lpfc_check_pending_fcoe_event(phba, 1)) {
1015 mempool_free(mboxq, phba->mbox_mem_pool);
1016 return;
1017 }
1012 if (vport->port_state != LPFC_FLOGI) { 1018 if (vport->port_state != LPFC_FLOGI) {
1013 spin_lock_irqsave(&phba->hbalock, flags); 1019 spin_lock_irqsave(&phba->hbalock, flags);
1014 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); 1020 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
1021 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1015 spin_unlock_irqrestore(&phba->hbalock, flags); 1022 spin_unlock_irqrestore(&phba->hbalock, flags);
1016 lpfc_initial_flogi(vport); 1023 lpfc_initial_flogi(vport);
1017 } 1024 }
@@ -1199,6 +1206,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
1199 /* The FCF is already registered, start discovery */ 1206 /* The FCF is already registered, start discovery */
1200 if (phba->fcf.fcf_flag & FCF_REGISTERED) { 1207 if (phba->fcf.fcf_flag & FCF_REGISTERED) {
1201 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); 1208 phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
1209 phba->hba_flag &= ~FCF_DISC_INPROGRESS;
1202 spin_unlock_irqrestore(&phba->hbalock, flags); 1210 spin_unlock_irqrestore(&phba->hbalock, flags);
1203 if (phba->pport->port_state != LPFC_FLOGI) 1211 if (phba->pport->port_state != LPFC_FLOGI)
1204 lpfc_initial_flogi(phba->pport); 1212 lpfc_initial_flogi(phba->pport);
@@ -1388,6 +1396,60 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
1388} 1396}
1389 1397
1390/** 1398/**
1399 * lpfc_check_pending_fcoe_event - Check if there is pending fcoe event.
1400 * @phba: pointer to lpfc hba data structure.
1401 * @unreg_fcf: Unregister FCF if FCF table need to be re-scaned.
1402 *
1403 * This function check if there is any fcoe event pending while driver
1404 * scan FCF entries. If there is any pending event, it will restart the
1405 * FCF saning and return 1 else return 0.
1406 */
1407int
1408lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
1409{
1410 LPFC_MBOXQ_t *mbox;
1411 int rc;
1412 /*
1413 * If the Link is up and no FCoE events while in the
1414 * FCF discovery, no need to restart FCF discovery.
1415 */
1416 if ((phba->link_state >= LPFC_LINK_UP) &&
1417 (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
1418 return 0;
1419
1420 spin_lock_irq(&phba->hbalock);
1421 phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
1422 spin_unlock_irq(&phba->hbalock);
1423
1424 if (phba->link_state >= LPFC_LINK_UP)
1425 lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
1426
1427 if (unreg_fcf) {
1428 spin_lock_irq(&phba->hbalock);
1429 phba->fcf.fcf_flag &= ~FCF_REGISTERED;
1430 spin_unlock_irq(&phba->hbalock);
1431 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1432 if (!mbox) {
1433 lpfc_printf_log(phba, KERN_ERR,
1434 LOG_DISCOVERY|LOG_MBOX,
1435 "2610 UNREG_FCFI mbox allocation failed\n");
1436 return 1;
1437 }
1438 lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
1439 mbox->vport = phba->pport;
1440 mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
1441 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1442 if (rc == MBX_NOT_FINISHED) {
1443 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
1444 "2611 UNREG_FCFI issue mbox failed\n");
1445 mempool_free(mbox, phba->mbox_mem_pool);
1446 }
1447 }
1448
1449 return 1;
1450}
1451
1452/**
1391 * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. 1453 * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
1392 * @phba: pointer to lpfc hba data structure. 1454 * @phba: pointer to lpfc hba data structure.
1393 * @mboxq: pointer to mailbox object. 1455 * @mboxq: pointer to mailbox object.
@@ -1419,6 +1481,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1419 unsigned long flags; 1481 unsigned long flags;
1420 uint16_t vlan_id; 1482 uint16_t vlan_id;
1421 1483
1484 /* If there is pending FCoE event restart FCF table scan */
1485 if (lpfc_check_pending_fcoe_event(phba, 0)) {
1486 lpfc_sli4_mbox_cmd_free(phba, mboxq);
1487 return;
1488 }
1489
1422 /* Get the first SGE entry from the non-embedded DMA memory. This 1490 /* Get the first SGE entry from the non-embedded DMA memory. This
1423 * routine only uses a single SGE. 1491 * routine only uses a single SGE.
1424 */ 1492 */
@@ -1823,6 +1891,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
1823 goto out; 1891 goto out;
1824 } 1892 }
1825 } else { 1893 } else {
1894 vport->port_state = LPFC_VPORT_UNKNOWN;
1826 /* 1895 /*
1827 * Add the driver's default FCF record at FCF index 0 now. This 1896 * Add the driver's default FCF record at FCF index 0 now. This
1828 * is phase 1 implementation that support FCF index 0 and driver 1897 * is phase 1 implementation that support FCF index 0 and driver
@@ -1858,6 +1927,12 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
1858 * The driver is expected to do FIP/FCF. Call the port 1927 * The driver is expected to do FIP/FCF. Call the port
1859 * and get the FCF Table. 1928 * and get the FCF Table.
1860 */ 1929 */
1930 spin_lock_irq(&phba->hbalock);
1931 if (phba->hba_flag & FCF_DISC_INPROGRESS) {
1932 spin_unlock_irq(&phba->hbalock);
1933 return;
1934 }
1935 spin_unlock_irq(&phba->hbalock);
1861 rc = lpfc_sli4_read_fcf_record(phba, 1936 rc = lpfc_sli4_read_fcf_record(phba,
1862 LPFC_FCOE_FCF_GET_FIRST); 1937 LPFC_FCOE_FCF_GET_FIRST);
1863 if (rc) 1938 if (rc)
@@ -4414,7 +4489,7 @@ lpfc_read_fcoe_param(struct lpfc_hba *phba,
4414 fcoe_param_hdr = (struct lpfc_fip_param_hdr *) 4489 fcoe_param_hdr = (struct lpfc_fip_param_hdr *)
4415 buff; 4490 buff;
4416 fcoe_param = (struct lpfc_fcoe_params *) 4491 fcoe_param = (struct lpfc_fcoe_params *)
4417 buff + sizeof(struct lpfc_fip_param_hdr); 4492 (buff + sizeof(struct lpfc_fip_param_hdr));
4418 4493
4419 if ((fcoe_param_hdr->parm_version != FIPP_VERSION) || 4494 if ((fcoe_param_hdr->parm_version != FIPP_VERSION) ||
4420 (fcoe_param_hdr->length != FCOE_PARAM_LENGTH)) 4495 (fcoe_param_hdr->length != FCOE_PARAM_LENGTH))
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index dc561e3c8b92..a7f32ed256bd 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2829,6 +2829,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
2829 att_type = lpfc_sli4_parse_latt_type(phba, acqe_link); 2829 att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
2830 if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP) 2830 if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
2831 return; 2831 return;
2832 phba->fcoe_eventtag = acqe_link->event_tag;
2832 pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 2833 pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2833 if (!pmb) { 2834 if (!pmb) {
2834 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, 2835 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -2916,6 +2917,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2916 uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe); 2917 uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
2917 int rc; 2918 int rc;
2918 2919
2920 phba->fcoe_eventtag = acqe_fcoe->event_tag;
2919 switch (event_type) { 2921 switch (event_type) {
2920 case LPFC_FCOE_EVENT_TYPE_NEW_FCF: 2922 case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
2921 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, 2923 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
@@ -2923,11 +2925,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
2923 acqe_fcoe->fcf_index, 2925 acqe_fcoe->fcf_index,
2924 acqe_fcoe->event_tag); 2926 acqe_fcoe->event_tag);
2925 /* 2927 /*
2926 * If the current FCF is in discovered state, 2928 * If the current FCF is in discovered state, or
2927 * do nothing. 2929 * FCF discovery is in progress do nothing.
2928 */ 2930 */
2929 spin_lock_irq(&phba->hbalock); 2931 spin_lock_irq(&phba->hbalock);
2930 if (phba->fcf.fcf_flag & FCF_DISCOVERED) { 2932 if ((phba->fcf.fcf_flag & FCF_DISCOVERED) ||
2933 (phba->hba_flag & FCF_DISC_INPROGRESS)) {
2931 spin_unlock_irq(&phba->hbalock); 2934 spin_unlock_irq(&phba->hbalock);
2932 break; 2935 break;
2933 } 2936 }
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 174a1b0d005d..a0f973e7acb3 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -11536,6 +11536,7 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
11536 uint32_t alloc_len, req_len; 11536 uint32_t alloc_len, req_len;
11537 struct lpfc_mbx_read_fcf_tbl *read_fcf; 11537 struct lpfc_mbx_read_fcf_tbl *read_fcf;
11538 11538
11539 phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag;
11539 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 11540 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
11540 if (!mboxq) { 11541 if (!mboxq) {
11541 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 11542 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11587,8 +11588,12 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
11587 if (rc == MBX_NOT_FINISHED) { 11588 if (rc == MBX_NOT_FINISHED) {
11588 lpfc_sli4_mbox_cmd_free(phba, mboxq); 11589 lpfc_sli4_mbox_cmd_free(phba, mboxq);
11589 error = -EIO; 11590 error = -EIO;
11590 } else 11591 } else {
11592 spin_lock_irq(&phba->hbalock);
11593 phba->hba_flag |= FCF_DISC_INPROGRESS;
11594 spin_unlock_irq(&phba->hbalock);
11591 error = 0; 11595 error = 0;
11596 }
11592 return error; 11597 return error;
11593} 11598}
11594 11599