diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-09-17 12:17:19 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-09-17 12:19:31 -0400 |
commit | 9b4f2e9576658c4e52d95dc8d309f51b2e2db096 (patch) | |
tree | 7b1902b0f931783fccc6fee45c6f9c16b4fde5ce /drivers/scsi/lpfc/lpfc_els.c | |
parent | 3c6c65f5ed5a6d307bd607aecd06d658c0934d88 (diff) | |
parent | 803db244b9f71102e366fd689000c1417b9a7508 (diff) |
ieee1394: merge from Linus
Conflicts: drivers/ieee1394/hosts.c
Patch "lockdep: annotate ieee1394 skb-queue-head locking" was meddling
with patch "ieee1394: fix kerneldoc of hpsb_alloc_host".
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 283b7d824c34..3567de613162 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static struct lpfc_nodelist * | 650 | static struct lpfc_nodelist * |
651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, |
652 | struct lpfc_nodelist *ndlp) | 652 | struct lpfc_nodelist *ndlp) |
653 | { | 653 | { |
654 | struct lpfc_nodelist *new_ndlp; | 654 | struct lpfc_nodelist *new_ndlp; |
655 | struct lpfc_dmabuf *pcmd, *prsp; | ||
656 | uint32_t *lp; | 655 | uint32_t *lp; |
657 | struct serv_parm *sp; | 656 | struct serv_parm *sp; |
658 | uint8_t name[sizeof (struct lpfc_name)]; | 657 | uint8_t name[sizeof (struct lpfc_name)]; |
659 | uint32_t rc; | 658 | uint32_t rc; |
660 | 659 | ||
661 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
662 | prsp = (struct lpfc_dmabuf *) pcmd->list.next; | ||
663 | lp = (uint32_t *) prsp->virt; | 660 | lp = (uint32_t *) prsp->virt; |
664 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 661 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
662 | memset(name, 0, sizeof (struct lpfc_name)); | ||
665 | 663 | ||
666 | /* Now we to find out if the NPort we are logging into, matches the WWPN | 664 | /* Now we to find out if the NPort we are logging into, matches the WWPN |
667 | * we have for that ndlp. If not, we have some work to do. | 665 | * we have for that ndlp. If not, we have some work to do. |
668 | */ | 666 | */ |
669 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | 667 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); |
670 | 668 | ||
671 | memset(name, 0, sizeof (struct lpfc_name)); | 669 | if (new_ndlp == ndlp) |
672 | rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
673 | if (!rc || (new_ndlp == ndlp)) { | ||
674 | return ndlp; | 670 | return ndlp; |
675 | } | ||
676 | 671 | ||
677 | if (!new_ndlp) { | 672 | if (!new_ndlp) { |
673 | rc = | ||
674 | memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
675 | if (!rc) | ||
676 | return ndlp; | ||
678 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 677 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
679 | if (!new_ndlp) | 678 | if (!new_ndlp) |
680 | return ndlp; | 679 | return ndlp; |
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
683 | } | 682 | } |
684 | 683 | ||
685 | lpfc_unreg_rpi(phba, new_ndlp); | 684 | lpfc_unreg_rpi(phba, new_ndlp); |
686 | new_ndlp->nlp_prev_state = ndlp->nlp_state; | ||
687 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 685 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
688 | new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 686 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; |
689 | lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); | 687 | new_ndlp->nlp_state = ndlp->nlp_state; |
688 | lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); | ||
690 | 689 | ||
691 | /* Move this back to NPR list */ | 690 | /* Move this back to NPR list */ |
692 | lpfc_unreg_rpi(phba, ndlp); | 691 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { |
693 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 692 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
694 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 693 | } |
695 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 694 | else { |
696 | 695 | lpfc_unreg_rpi(phba, ndlp); | |
696 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | ||
697 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
698 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
699 | } | ||
697 | return new_ndlp; | 700 | return new_ndlp; |
698 | } | 701 | } |
699 | 702 | ||
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
703 | { | 706 | { |
704 | IOCB_t *irsp; | 707 | IOCB_t *irsp; |
705 | struct lpfc_nodelist *ndlp; | 708 | struct lpfc_nodelist *ndlp; |
709 | struct lpfc_dmabuf *prsp; | ||
706 | int disc, rc, did, type; | 710 | int disc, rc, did, type; |
707 | 711 | ||
708 | 712 | ||
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
769 | } | 773 | } |
770 | } else { | 774 | } else { |
771 | /* Good status, call state machine */ | 775 | /* Good status, call state machine */ |
772 | ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); | 776 | prsp = list_entry(((struct lpfc_dmabuf *) |
777 | cmdiocb->context2)->list.next, | ||
778 | struct lpfc_dmabuf, list); | ||
779 | ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); | ||
773 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 780 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
774 | NLP_EVT_CMPL_PLOGI); | 781 | NLP_EVT_CMPL_PLOGI); |
775 | } | 782 | } |
@@ -821,7 +828,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 828 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
822 | 829 | ||
823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 830 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, | 831 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did, |
825 | ELS_CMD_PLOGI); | 832 | ELS_CMD_PLOGI); |
826 | if (!elsiocb) | 833 | if (!elsiocb) |
827 | return 1; | 834 | return 1; |
@@ -1841,9 +1848,12 @@ static void | |||
1841 | lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 1848 | lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
1842 | struct lpfc_iocbq * rspiocb) | 1849 | struct lpfc_iocbq * rspiocb) |
1843 | { | 1850 | { |
1851 | IOCB_t *irsp; | ||
1844 | struct lpfc_nodelist *ndlp; | 1852 | struct lpfc_nodelist *ndlp; |
1845 | LPFC_MBOXQ_t *mbox = NULL; | 1853 | LPFC_MBOXQ_t *mbox = NULL; |
1846 | 1854 | ||
1855 | irsp = &rspiocb->iocb; | ||
1856 | |||
1847 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1857 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1848 | if (cmdiocb->context_un.mbox) | 1858 | if (cmdiocb->context_un.mbox) |
1849 | mbox = cmdiocb->context_un.mbox; | 1859 | mbox = cmdiocb->context_un.mbox; |
@@ -1886,9 +1896,15 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1886 | mempool_free( mbox, phba->mbox_mem_pool); | 1896 | mempool_free( mbox, phba->mbox_mem_pool); |
1887 | } else { | 1897 | } else { |
1888 | mempool_free( mbox, phba->mbox_mem_pool); | 1898 | mempool_free( mbox, phba->mbox_mem_pool); |
1889 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 1899 | /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ |
1890 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1900 | if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && |
1891 | ndlp = NULL; | 1901 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || |
1902 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | ||
1903 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { | ||
1904 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | ||
1905 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
1906 | ndlp = NULL; | ||
1907 | } | ||
1892 | } | 1908 | } |
1893 | } | 1909 | } |
1894 | } | 1910 | } |
@@ -2791,8 +2807,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2791 | 2807 | ||
2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2808 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 2809 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
2794 | pmb->context1 = 0; | 2810 | pmb->context1 = NULL; |
2795 | pmb->context2 = 0; | 2811 | pmb->context2 = NULL; |
2796 | 2812 | ||
2797 | if (mb->mbxStatus) { | 2813 | if (mb->mbxStatus) { |
2798 | mempool_free( pmb, phba->mbox_mem_pool); | 2814 | mempool_free( pmb, phba->mbox_mem_pool); |
@@ -2832,7 +2848,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2832 | 2848 | ||
2833 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ | 2849 | /* Xmit ELS RPS ACC response tag <ulpIoTag> */ |
2834 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2850 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
2835 | "%d:0128 Xmit ELS RPS ACC response tag x%x " | 2851 | "%d:0118 Xmit ELS RPS ACC response tag x%x " |
2836 | "Data: x%x x%x x%x x%x x%x\n", | 2852 | "Data: x%x x%x x%x x%x x%x\n", |
2837 | phba->brd_no, | 2853 | phba->brd_no, |
2838 | elsiocb->iocb.ulpIoTag, | 2854 | elsiocb->iocb.ulpIoTag, |
@@ -2941,7 +2957,7 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, | |||
2941 | 2957 | ||
2942 | /* Xmit ELS RPL ACC response tag <ulpIoTag> */ | 2958 | /* Xmit ELS RPL ACC response tag <ulpIoTag> */ |
2943 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2959 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
2944 | "%d:0128 Xmit ELS RPL ACC response tag x%x " | 2960 | "%d:0120 Xmit ELS RPL ACC response tag x%x " |
2945 | "Data: x%x x%x x%x x%x x%x\n", | 2961 | "Data: x%x x%x x%x x%x x%x\n", |
2946 | phba->brd_no, | 2962 | phba->brd_no, |
2947 | elsiocb->iocb.ulpIoTag, | 2963 | elsiocb->iocb.ulpIoTag, |
@@ -3102,7 +3118,7 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3102 | struct lpfc_nodelist *ndlp, *next_ndlp; | 3118 | struct lpfc_nodelist *ndlp, *next_ndlp; |
3103 | 3119 | ||
3104 | /* FAN received */ | 3120 | /* FAN received */ |
3105 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n", | 3121 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0265 FAN received\n", |
3106 | phba->brd_no); | 3122 | phba->brd_no); |
3107 | 3123 | ||
3108 | icmd = &cmdiocb->iocb; | 3124 | icmd = &cmdiocb->iocb; |
@@ -3282,10 +3298,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3282 | } else | 3298 | } else |
3283 | lpfc_sli_release_iocbq(phba, piocb); | 3299 | lpfc_sli_release_iocbq(phba, piocb); |
3284 | } | 3300 | } |
3285 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { | 3301 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) |
3286 | phba->els_tmofunc.expires = jiffies + HZ * timeout; | 3302 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); |
3287 | add_timer(&phba->els_tmofunc); | 3303 | |
3288 | } | ||
3289 | spin_unlock_irq(phba->host->host_lock); | 3304 | spin_unlock_irq(phba->host->host_lock); |
3290 | } | 3305 | } |
3291 | 3306 | ||
@@ -3442,6 +3457,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3442 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3457 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3443 | ndlp->nlp_type |= NLP_FABRIC; | 3458 | ndlp->nlp_type |= NLP_FABRIC; |
3444 | } | 3459 | } |
3460 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
3461 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
3445 | } | 3462 | } |
3446 | 3463 | ||
3447 | phba->fc_stat.elsRcvFrame++; | 3464 | phba->fc_stat.elsRcvFrame++; |
@@ -3463,13 +3480,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3463 | rjt_err = 1; | 3480 | rjt_err = 1; |
3464 | break; | 3481 | break; |
3465 | } | 3482 | } |
3483 | ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); | ||
3466 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); | 3484 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); |
3467 | break; | 3485 | break; |
3468 | case ELS_CMD_FLOGI: | 3486 | case ELS_CMD_FLOGI: |
3469 | phba->fc_stat.elsRcvFLOGI++; | 3487 | phba->fc_stat.elsRcvFLOGI++; |
3470 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); | 3488 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); |
3471 | if (newnode) { | 3489 | if (newnode) { |
3472 | mempool_free( ndlp, phba->nlp_mem_pool); | 3490 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3473 | } | 3491 | } |
3474 | break; | 3492 | break; |
3475 | case ELS_CMD_LOGO: | 3493 | case ELS_CMD_LOGO: |
@@ -3492,7 +3510,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3492 | phba->fc_stat.elsRcvRSCN++; | 3510 | phba->fc_stat.elsRcvRSCN++; |
3493 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); | 3511 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); |
3494 | if (newnode) { | 3512 | if (newnode) { |
3495 | mempool_free( ndlp, phba->nlp_mem_pool); | 3513 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3496 | } | 3514 | } |
3497 | break; | 3515 | break; |
3498 | case ELS_CMD_ADISC: | 3516 | case ELS_CMD_ADISC: |
@@ -3535,28 +3553,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3535 | phba->fc_stat.elsRcvLIRR++; | 3553 | phba->fc_stat.elsRcvLIRR++; |
3536 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); | 3554 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); |
3537 | if (newnode) { | 3555 | if (newnode) { |
3538 | mempool_free( ndlp, phba->nlp_mem_pool); | 3556 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3539 | } | 3557 | } |
3540 | break; | 3558 | break; |
3541 | case ELS_CMD_RPS: | 3559 | case ELS_CMD_RPS: |
3542 | phba->fc_stat.elsRcvRPS++; | 3560 | phba->fc_stat.elsRcvRPS++; |
3543 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); | 3561 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); |
3544 | if (newnode) { | 3562 | if (newnode) { |
3545 | mempool_free( ndlp, phba->nlp_mem_pool); | 3563 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3546 | } | 3564 | } |
3547 | break; | 3565 | break; |
3548 | case ELS_CMD_RPL: | 3566 | case ELS_CMD_RPL: |
3549 | phba->fc_stat.elsRcvRPL++; | 3567 | phba->fc_stat.elsRcvRPL++; |
3550 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); | 3568 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); |
3551 | if (newnode) { | 3569 | if (newnode) { |
3552 | mempool_free( ndlp, phba->nlp_mem_pool); | 3570 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3553 | } | 3571 | } |
3554 | break; | 3572 | break; |
3555 | case ELS_CMD_RNID: | 3573 | case ELS_CMD_RNID: |
3556 | phba->fc_stat.elsRcvRNID++; | 3574 | phba->fc_stat.elsRcvRNID++; |
3557 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); | 3575 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); |
3558 | if (newnode) { | 3576 | if (newnode) { |
3559 | mempool_free( ndlp, phba->nlp_mem_pool); | 3577 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3560 | } | 3578 | } |
3561 | break; | 3579 | break; |
3562 | default: | 3580 | default: |
@@ -3568,7 +3586,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3568 | "%d:0115 Unknown ELS command x%x received from " | 3586 | "%d:0115 Unknown ELS command x%x received from " |
3569 | "NPORT x%x\n", phba->brd_no, cmd, did); | 3587 | "NPORT x%x\n", phba->brd_no, cmd, did); |
3570 | if (newnode) { | 3588 | if (newnode) { |
3571 | mempool_free( ndlp, phba->nlp_mem_pool); | 3589 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3572 | } | 3590 | } |
3573 | break; | 3591 | break; |
3574 | } | 3592 | } |