diff options
author | James Bottomley <James.Bottomley@suse.de> | 2010-05-18 10:33:43 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-18 10:37:41 -0400 |
commit | 95bb335c0ebe96afe926387a1ef3a096bd884a82 (patch) | |
tree | 56115332b4f2f7ef300c36248a6a7d20db2e639d /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 1b4d0d8ea7b3cbd107f345ab766416f9b38ce66a (diff) | |
parent | 9cccde93fed1ca988eb2fb17ab9194bf7b5ed1b0 (diff) |
[SCSI] Merge scsi-misc-2.6 into scsi-rc-fixes-2.6
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e1466eec56b7..1f87b4fb8b50 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -475,6 +475,10 @@ lpfc_work_list_done(struct lpfc_hba *phba) | |||
475 | lpfc_send_fastpath_evt(phba, evtp); | 475 | lpfc_send_fastpath_evt(phba, evtp); |
476 | free_evt = 0; | 476 | free_evt = 0; |
477 | break; | 477 | break; |
478 | case LPFC_EVT_RESET_HBA: | ||
479 | if (!(phba->pport->load_flag & FC_UNLOADING)) | ||
480 | lpfc_reset_hba(phba); | ||
481 | break; | ||
478 | } | 482 | } |
479 | if (free_evt) | 483 | if (free_evt) |
480 | kfree(evtp); | 484 | kfree(evtp); |
@@ -1531,7 +1535,37 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1531 | } | 1535 | } |
1532 | 1536 | ||
1533 | /** | 1537 | /** |
1534 | * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command | 1538 | * lpfc_sli4_new_fcf_random_select - Randomly select an eligible new fcf record |
1539 | * @phba: pointer to lpfc hba data structure. | ||
1540 | * @fcf_cnt: number of eligible fcf record seen so far. | ||
1541 | * | ||
1542 | * This function makes an running random selection decision on FCF record to | ||
1543 | * use through a sequence of @fcf_cnt eligible FCF records with equal | ||
1544 | * probability. To perform integer manunipulation of random numbers with | ||
1545 | * size unit32_t, the lower 16 bits of the 32-bit random number returned | ||
1546 | * from random32() are taken as the random random number generated. | ||
1547 | * | ||
1548 | * Returns true when outcome is for the newly read FCF record should be | ||
1549 | * chosen; otherwise, return false when outcome is for keeping the previously | ||
1550 | * chosen FCF record. | ||
1551 | **/ | ||
1552 | static bool | ||
1553 | lpfc_sli4_new_fcf_random_select(struct lpfc_hba *phba, uint32_t fcf_cnt) | ||
1554 | { | ||
1555 | uint32_t rand_num; | ||
1556 | |||
1557 | /* Get 16-bit uniform random number */ | ||
1558 | rand_num = (0xFFFF & random32()); | ||
1559 | |||
1560 | /* Decision with probability 1/fcf_cnt */ | ||
1561 | if ((fcf_cnt * rand_num) < 0xFFFF) | ||
1562 | return true; | ||
1563 | else | ||
1564 | return false; | ||
1565 | } | ||
1566 | |||
1567 | /** | ||
1568 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | ||
1535 | * @phba: pointer to lpfc hba data structure. | 1569 | * @phba: pointer to lpfc hba data structure. |
1536 | * @mboxq: pointer to mailbox object. | 1570 | * @mboxq: pointer to mailbox object. |
1537 | * @next_fcf_index: pointer to holder of next fcf index. | 1571 | * @next_fcf_index: pointer to holder of next fcf index. |
@@ -1592,7 +1626,9 @@ lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
1592 | new_fcf_record = (struct fcf_record *)(virt_addr + | 1626 | new_fcf_record = (struct fcf_record *)(virt_addr + |
1593 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | 1627 | sizeof(struct lpfc_mbx_read_fcf_tbl)); |
1594 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | 1628 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, |
1595 | sizeof(struct fcf_record)); | 1629 | offsetof(struct fcf_record, vlan_bitmap)); |
1630 | new_fcf_record->word137 = le32_to_cpu(new_fcf_record->word137); | ||
1631 | new_fcf_record->word138 = le32_to_cpu(new_fcf_record->word138); | ||
1596 | 1632 | ||
1597 | return new_fcf_record; | 1633 | return new_fcf_record; |
1598 | } | 1634 | } |
@@ -1679,6 +1715,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1679 | uint16_t fcf_index, next_fcf_index; | 1715 | uint16_t fcf_index, next_fcf_index; |
1680 | struct lpfc_fcf_rec *fcf_rec = NULL; | 1716 | struct lpfc_fcf_rec *fcf_rec = NULL; |
1681 | uint16_t vlan_id; | 1717 | uint16_t vlan_id; |
1718 | uint32_t seed; | ||
1719 | bool select_new_fcf; | ||
1682 | int rc; | 1720 | int rc; |
1683 | 1721 | ||
1684 | /* If there is pending FCoE event restart FCF table scan */ | 1722 | /* If there is pending FCoE event restart FCF table scan */ |
@@ -1809,9 +1847,21 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1809 | * than the driver FCF record, use the new record. | 1847 | * than the driver FCF record, use the new record. |
1810 | */ | 1848 | */ |
1811 | if (new_fcf_record->fip_priority < fcf_rec->priority) { | 1849 | if (new_fcf_record->fip_priority < fcf_rec->priority) { |
1812 | /* Choose this FCF record */ | 1850 | /* Choose the new FCF record with lower priority */ |
1813 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, | 1851 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1814 | addr_mode, vlan_id, 0); | 1852 | addr_mode, vlan_id, 0); |
1853 | /* Reset running random FCF selection count */ | ||
1854 | phba->fcf.eligible_fcf_cnt = 1; | ||
1855 | } else if (new_fcf_record->fip_priority == fcf_rec->priority) { | ||
1856 | /* Update running random FCF selection count */ | ||
1857 | phba->fcf.eligible_fcf_cnt++; | ||
1858 | select_new_fcf = lpfc_sli4_new_fcf_random_select(phba, | ||
1859 | phba->fcf.eligible_fcf_cnt); | ||
1860 | if (select_new_fcf) | ||
1861 | /* Choose the new FCF by random selection */ | ||
1862 | __lpfc_update_fcf_record(phba, fcf_rec, | ||
1863 | new_fcf_record, | ||
1864 | addr_mode, vlan_id, 0); | ||
1815 | } | 1865 | } |
1816 | spin_unlock_irq(&phba->hbalock); | 1866 | spin_unlock_irq(&phba->hbalock); |
1817 | goto read_next_fcf; | 1867 | goto read_next_fcf; |
@@ -1825,6 +1875,11 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1825 | addr_mode, vlan_id, (boot_flag ? | 1875 | addr_mode, vlan_id, (boot_flag ? |
1826 | BOOT_ENABLE : 0)); | 1876 | BOOT_ENABLE : 0)); |
1827 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1877 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1878 | /* Setup initial running random FCF selection count */ | ||
1879 | phba->fcf.eligible_fcf_cnt = 1; | ||
1880 | /* Seeding the random number generator for random selection */ | ||
1881 | seed = (uint32_t)(0xFFFFFFFF & jiffies); | ||
1882 | srandom32(seed); | ||
1828 | } | 1883 | } |
1829 | spin_unlock_irq(&phba->hbalock); | 1884 | spin_unlock_irq(&phba->hbalock); |
1830 | goto read_next_fcf; | 1885 | goto read_next_fcf; |
@@ -2686,11 +2741,18 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2686 | switch (mb->mbxStatus) { | 2741 | switch (mb->mbxStatus) { |
2687 | case 0x0011: | 2742 | case 0x0011: |
2688 | case 0x0020: | 2743 | case 0x0020: |
2689 | case 0x9700: | ||
2690 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, | 2744 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, |
2691 | "0911 cmpl_unreg_vpi, mb status = 0x%x\n", | 2745 | "0911 cmpl_unreg_vpi, mb status = 0x%x\n", |
2692 | mb->mbxStatus); | 2746 | mb->mbxStatus); |
2693 | break; | 2747 | break; |
2748 | /* If VPI is busy, reset the HBA */ | ||
2749 | case 0x9700: | ||
2750 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, | ||
2751 | "2798 Unreg_vpi failed vpi 0x%x, mb status = 0x%x\n", | ||
2752 | vport->vpi, mb->mbxStatus); | ||
2753 | if (!(phba->pport->load_flag & FC_UNLOADING)) | ||
2754 | lpfc_workq_post_event(phba, NULL, NULL, | ||
2755 | LPFC_EVT_RESET_HBA); | ||
2694 | } | 2756 | } |
2695 | spin_lock_irq(shost->host_lock); | 2757 | spin_lock_irq(shost->host_lock); |
2696 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2758 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
@@ -2965,7 +3027,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2965 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 3027 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
2966 | 3028 | ||
2967 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 3029 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
2968 | lpfc_start_fdiscs(phba); | 3030 | /* when physical port receive logo donot start |
3031 | * vport discovery */ | ||
3032 | if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) | ||
3033 | lpfc_start_fdiscs(phba); | ||
3034 | else | ||
3035 | vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ; | ||
2969 | lpfc_do_scr_ns_plogi(phba, vport); | 3036 | lpfc_do_scr_ns_plogi(phba, vport); |
2970 | } | 3037 | } |
2971 | 3038 | ||
@@ -3177,7 +3244,6 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
3177 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 3244 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
3178 | 3245 | ||
3179 | if (new_state == NLP_STE_UNMAPPED_NODE) { | 3246 | if (new_state == NLP_STE_UNMAPPED_NODE) { |
3180 | ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); | ||
3181 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; | 3247 | ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; |
3182 | ndlp->nlp_type |= NLP_FC_NODE; | 3248 | ndlp->nlp_type |= NLP_FC_NODE; |
3183 | } | 3249 | } |
@@ -4935,6 +5001,7 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) | |||
4935 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); | 5001 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); |
4936 | if (ndlp) | 5002 | if (ndlp) |
4937 | lpfc_cancel_retry_delay_tmo(vports[i], ndlp); | 5003 | lpfc_cancel_retry_delay_tmo(vports[i], ndlp); |
5004 | lpfc_cleanup_pending_mbox(vports[i]); | ||
4938 | lpfc_mbx_unreg_vpi(vports[i]); | 5005 | lpfc_mbx_unreg_vpi(vports[i]); |
4939 | shost = lpfc_shost_from_vport(vports[i]); | 5006 | shost = lpfc_shost_from_vport(vports[i]); |
4940 | spin_lock_irq(shost->host_lock); | 5007 | spin_lock_irq(shost->host_lock); |