aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_hbadisc.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2010-05-18 10:33:43 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-18 10:37:41 -0400
commit95bb335c0ebe96afe926387a1ef3a096bd884a82 (patch)
tree56115332b4f2f7ef300c36248a6a7d20db2e639d /drivers/scsi/lpfc/lpfc_hbadisc.c
parent1b4d0d8ea7b3cbd107f345ab766416f9b38ce66a (diff)
parent9cccde93fed1ca988eb2fb17ab9194bf7b5ed1b0 (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.c79
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 **/
1552static bool
1553lpfc_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);