diff options
author | James Smart <james.smart@emulex.com> | 2010-11-20 23:11:55 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:24:01 -0500 |
commit | 19ca760979e4be41a3eb215fb8d0e96637161947 (patch) | |
tree | de6c32815eb813ba770a26178c1612015acf719b /drivers/scsi/lpfc/lpfc_sli.c | |
parent | 76a95d75ede64e4f1684ddb8c626fdfdb641bda2 (diff) |
[SCSI] lpfc 8.3.19: Added support for ELS RRQ command
Added support for ELS RRQ command
- Add new routine lpfc_set_rrq_active() to track XRI qualifier state.
- Add new module parameter lpfc_enable_rrq to control RRQ operation.
- Add logic to ELS RRQ completion handler and xri qualifier timeout
to clear XRI qualifier state.
- Use OX_ID from XRI_ABORTED_CQE for RRQ payload.
- Tie abort and XRI_ABORTED_CQE andler to RRQ generation.
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/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 396 |
1 files changed, 387 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bedaa4e7cbf8..752601509549 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -513,8 +513,344 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
513 | } | 513 | } |
514 | 514 | ||
515 | /** | 515 | /** |
516 | * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap. | ||
517 | * @phba: Pointer to HBA context object. | ||
518 | * @ndlp: nodelist pointer for this target. | ||
519 | * @xritag: xri used in this exchange. | ||
520 | * @rxid: Remote Exchange ID. | ||
521 | * @send_rrq: Flag used to determine if we should send rrq els cmd. | ||
522 | * | ||
523 | * This function is called with hbalock held. | ||
524 | * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an | ||
525 | * rrq struct and adds it to the active_rrq_list. | ||
526 | * | ||
527 | * returns 0 for rrq slot for this xri | ||
528 | * < 0 Were not able to get rrq mem or invalid parameter. | ||
529 | **/ | ||
530 | static int | ||
531 | __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
532 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | ||
533 | { | ||
534 | uint16_t adj_xri; | ||
535 | struct lpfc_node_rrq *rrq; | ||
536 | int empty; | ||
537 | |||
538 | /* | ||
539 | * set the active bit even if there is no mem available. | ||
540 | */ | ||
541 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | ||
542 | if (!ndlp) | ||
543 | return -EINVAL; | ||
544 | if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) | ||
545 | return -EINVAL; | ||
546 | rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL); | ||
547 | if (rrq) { | ||
548 | rrq->send_rrq = send_rrq; | ||
549 | rrq->xritag = xritag; | ||
550 | rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
551 | rrq->ndlp = ndlp; | ||
552 | rrq->nlp_DID = ndlp->nlp_DID; | ||
553 | rrq->vport = ndlp->vport; | ||
554 | rrq->rxid = rxid; | ||
555 | empty = list_empty(&phba->active_rrq_list); | ||
556 | if (phba->cfg_enable_rrq && send_rrq) | ||
557 | /* | ||
558 | * We need the xri before we can add this to the | ||
559 | * phba active rrq list. | ||
560 | */ | ||
561 | rrq->send_rrq = send_rrq; | ||
562 | else | ||
563 | rrq->send_rrq = 0; | ||
564 | list_add_tail(&rrq->list, &phba->active_rrq_list); | ||
565 | if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) { | ||
566 | phba->hba_flag |= HBA_RRQ_ACTIVE; | ||
567 | if (empty) | ||
568 | lpfc_worker_wake_up(phba); | ||
569 | } | ||
570 | return 0; | ||
571 | } | ||
572 | return -ENOMEM; | ||
573 | } | ||
574 | |||
575 | /** | ||
576 | * __lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | ||
577 | * @phba: Pointer to HBA context object. | ||
578 | * @xritag: xri used in this exchange. | ||
579 | * @rrq: The RRQ to be cleared. | ||
580 | * | ||
581 | * This function is called with hbalock held. This function | ||
582 | **/ | ||
583 | static void | ||
584 | __lpfc_clr_rrq_active(struct lpfc_hba *phba, | ||
585 | uint16_t xritag, | ||
586 | struct lpfc_node_rrq *rrq) | ||
587 | { | ||
588 | uint16_t adj_xri; | ||
589 | struct lpfc_nodelist *ndlp; | ||
590 | |||
591 | ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID); | ||
592 | |||
593 | /* The target DID could have been swapped (cable swap) | ||
594 | * we should use the ndlp from the findnode if it is | ||
595 | * available. | ||
596 | */ | ||
597 | if (!ndlp) | ||
598 | ndlp = rrq->ndlp; | ||
599 | |||
600 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | ||
601 | if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) { | ||
602 | rrq->send_rrq = 0; | ||
603 | rrq->xritag = 0; | ||
604 | rrq->rrq_stop_time = 0; | ||
605 | } | ||
606 | mempool_free(rrq, phba->rrq_pool); | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * lpfc_handle_rrq_active - Checks if RRQ has waithed RATOV. | ||
611 | * @phba: Pointer to HBA context object. | ||
612 | * | ||
613 | * This function is called with hbalock held. This function | ||
614 | * Checks if stop_time (ratov from setting rrq active) has | ||
615 | * been reached, if it has and the send_rrq flag is set then | ||
616 | * it will call lpfc_send_rrq. If the send_rrq flag is not set | ||
617 | * then it will just call the routine to clear the rrq and | ||
618 | * free the rrq resource. | ||
619 | * The timer is set to the next rrq that is going to expire before | ||
620 | * leaving the routine. | ||
621 | * | ||
622 | **/ | ||
623 | void | ||
624 | lpfc_handle_rrq_active(struct lpfc_hba *phba) | ||
625 | { | ||
626 | struct lpfc_node_rrq *rrq; | ||
627 | struct lpfc_node_rrq *nextrrq; | ||
628 | unsigned long next_time; | ||
629 | unsigned long iflags; | ||
630 | |||
631 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
632 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
633 | next_time = jiffies + HZ * (phba->fc_ratov + 1); | ||
634 | list_for_each_entry_safe(rrq, nextrrq, | ||
635 | &phba->active_rrq_list, list) { | ||
636 | if (time_after(jiffies, rrq->rrq_stop_time)) { | ||
637 | list_del(&rrq->list); | ||
638 | if (!rrq->send_rrq) | ||
639 | /* this call will free the rrq */ | ||
640 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
641 | else { | ||
642 | /* if we send the rrq then the completion handler | ||
643 | * will clear the bit in the xribitmap. | ||
644 | */ | ||
645 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
646 | if (lpfc_send_rrq(phba, rrq)) { | ||
647 | lpfc_clr_rrq_active(phba, rrq->xritag, | ||
648 | rrq); | ||
649 | } | ||
650 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
651 | } | ||
652 | } else if (time_before(rrq->rrq_stop_time, next_time)) | ||
653 | next_time = rrq->rrq_stop_time; | ||
654 | } | ||
655 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
656 | if (!list_empty(&phba->active_rrq_list)) | ||
657 | mod_timer(&phba->rrq_tmr, next_time); | ||
658 | } | ||
659 | |||
660 | /** | ||
661 | * lpfc_get_active_rrq - Get the active RRQ for this exchange. | ||
662 | * @vport: Pointer to vport context object. | ||
663 | * @xri: The xri used in the exchange. | ||
664 | * @did: The targets DID for this exchange. | ||
665 | * | ||
666 | * returns NULL = rrq not found in the phba->active_rrq_list. | ||
667 | * rrq = rrq for this xri and target. | ||
668 | **/ | ||
669 | struct lpfc_node_rrq * | ||
670 | lpfc_get_active_rrq(struct lpfc_vport *vport, uint16_t xri, uint32_t did) | ||
671 | { | ||
672 | struct lpfc_hba *phba = vport->phba; | ||
673 | struct lpfc_node_rrq *rrq; | ||
674 | struct lpfc_node_rrq *nextrrq; | ||
675 | unsigned long iflags; | ||
676 | |||
677 | if (phba->sli_rev != LPFC_SLI_REV4) | ||
678 | return NULL; | ||
679 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
680 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { | ||
681 | if (rrq->vport == vport && rrq->xritag == xri && | ||
682 | rrq->nlp_DID == did){ | ||
683 | list_del(&rrq->list); | ||
684 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
685 | return rrq; | ||
686 | } | ||
687 | } | ||
688 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
689 | return NULL; | ||
690 | } | ||
691 | |||
692 | /** | ||
693 | * lpfc_cleanup_vports_rrqs - Remove and clear the active RRQ for this vport. | ||
694 | * @vport: Pointer to vport context object. | ||
695 | * | ||
696 | * Remove all active RRQs for this vport from the phba->active_rrq_list and | ||
697 | * clear the rrq. | ||
698 | **/ | ||
699 | void | ||
700 | lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport) | ||
701 | |||
702 | { | ||
703 | struct lpfc_hba *phba = vport->phba; | ||
704 | struct lpfc_node_rrq *rrq; | ||
705 | struct lpfc_node_rrq *nextrrq; | ||
706 | unsigned long iflags; | ||
707 | |||
708 | if (phba->sli_rev != LPFC_SLI_REV4) | ||
709 | return; | ||
710 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
711 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { | ||
712 | if (rrq->vport == vport) { | ||
713 | list_del(&rrq->list); | ||
714 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
715 | } | ||
716 | } | ||
717 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
718 | } | ||
719 | |||
720 | /** | ||
721 | * lpfc_cleanup_wt_rrqs - Remove all rrq's from the active list. | ||
722 | * @phba: Pointer to HBA context object. | ||
723 | * | ||
724 | * Remove all rrqs from the phba->active_rrq_list and free them by | ||
725 | * calling __lpfc_clr_active_rrq | ||
726 | * | ||
727 | **/ | ||
728 | void | ||
729 | lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba) | ||
730 | { | ||
731 | struct lpfc_node_rrq *rrq; | ||
732 | struct lpfc_node_rrq *nextrrq; | ||
733 | unsigned long next_time; | ||
734 | unsigned long iflags; | ||
735 | |||
736 | if (phba->sli_rev != LPFC_SLI_REV4) | ||
737 | return; | ||
738 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
739 | phba->hba_flag &= ~HBA_RRQ_ACTIVE; | ||
740 | next_time = jiffies + HZ * (phba->fc_ratov * 2); | ||
741 | list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { | ||
742 | list_del(&rrq->list); | ||
743 | __lpfc_clr_rrq_active(phba, rrq->xritag, rrq); | ||
744 | } | ||
745 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
746 | if (!list_empty(&phba->active_rrq_list)) | ||
747 | mod_timer(&phba->rrq_tmr, next_time); | ||
748 | } | ||
749 | |||
750 | |||
751 | /** | ||
752 | * __lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. | ||
753 | * @phba: Pointer to HBA context object. | ||
754 | * @ndlp: Targets nodelist pointer for this exchange. | ||
755 | * @xritag the xri in the bitmap to test. | ||
756 | * | ||
757 | * This function is called with hbalock held. This function | ||
758 | * returns 0 = rrq not active for this xri | ||
759 | * 1 = rrq is valid for this xri. | ||
760 | **/ | ||
761 | static int | ||
762 | __lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
763 | uint16_t xritag) | ||
764 | { | ||
765 | uint16_t adj_xri; | ||
766 | |||
767 | adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base; | ||
768 | if (!ndlp) | ||
769 | return 0; | ||
770 | if (test_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) | ||
771 | return 1; | ||
772 | else | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | /** | ||
777 | * lpfc_set_rrq_active - set RRQ active bit in xri_bitmap. | ||
778 | * @phba: Pointer to HBA context object. | ||
779 | * @ndlp: nodelist pointer for this target. | ||
780 | * @xritag: xri used in this exchange. | ||
781 | * @rxid: Remote Exchange ID. | ||
782 | * @send_rrq: Flag used to determine if we should send rrq els cmd. | ||
783 | * | ||
784 | * This function takes the hbalock. | ||
785 | * The active bit is always set in the active rrq xri_bitmap even | ||
786 | * if there is no slot avaiable for the other rrq information. | ||
787 | * | ||
788 | * returns 0 rrq actived for this xri | ||
789 | * < 0 No memory or invalid ndlp. | ||
790 | **/ | ||
791 | int | ||
792 | lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
793 | uint16_t xritag, uint16_t rxid, uint16_t send_rrq) | ||
794 | { | ||
795 | int ret; | ||
796 | unsigned long iflags; | ||
797 | |||
798 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
799 | ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq); | ||
800 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | /** | ||
805 | * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap. | ||
806 | * @phba: Pointer to HBA context object. | ||
807 | * @xritag: xri used in this exchange. | ||
808 | * @rrq: The RRQ to be cleared. | ||
809 | * | ||
810 | * This function is takes the hbalock. | ||
811 | **/ | ||
812 | void | ||
813 | lpfc_clr_rrq_active(struct lpfc_hba *phba, | ||
814 | uint16_t xritag, | ||
815 | struct lpfc_node_rrq *rrq) | ||
816 | { | ||
817 | unsigned long iflags; | ||
818 | |||
819 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
820 | __lpfc_clr_rrq_active(phba, xritag, rrq); | ||
821 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
822 | return; | ||
823 | } | ||
824 | |||
825 | |||
826 | |||
827 | /** | ||
828 | * lpfc_test_rrq_active - Test RRQ bit in xri_bitmap. | ||
829 | * @phba: Pointer to HBA context object. | ||
830 | * @ndlp: Targets nodelist pointer for this exchange. | ||
831 | * @xritag the xri in the bitmap to test. | ||
832 | * | ||
833 | * This function takes the hbalock. | ||
834 | * returns 0 = rrq not active for this xri | ||
835 | * 1 = rrq is valid for this xri. | ||
836 | **/ | ||
837 | int | ||
838 | lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | ||
839 | uint16_t xritag) | ||
840 | { | ||
841 | int ret; | ||
842 | unsigned long iflags; | ||
843 | |||
844 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
845 | ret = __lpfc_test_rrq_active(phba, ndlp, xritag); | ||
846 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
847 | return ret; | ||
848 | } | ||
849 | |||
850 | /** | ||
516 | * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool | 851 | * __lpfc_sli_get_sglq - Allocates an iocb object from sgl pool |
517 | * @phba: Pointer to HBA context object. | 852 | * @phba: Pointer to HBA context object. |
853 | * @piocb: Pointer to the iocbq. | ||
518 | * | 854 | * |
519 | * This function is called with hbalock held. This function | 855 | * This function is called with hbalock held. This function |
520 | * Gets a new driver sglq object from the sglq list. If the | 856 | * Gets a new driver sglq object from the sglq list. If the |
@@ -522,17 +858,53 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
522 | * allocated sglq object else it returns NULL. | 858 | * allocated sglq object else it returns NULL. |
523 | **/ | 859 | **/ |
524 | static struct lpfc_sglq * | 860 | static struct lpfc_sglq * |
525 | __lpfc_sli_get_sglq(struct lpfc_hba *phba) | 861 | __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) |
526 | { | 862 | { |
527 | struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list; | 863 | struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list; |
528 | struct lpfc_sglq *sglq = NULL; | 864 | struct lpfc_sglq *sglq = NULL; |
865 | struct lpfc_sglq *start_sglq = NULL; | ||
529 | uint16_t adj_xri; | 866 | uint16_t adj_xri; |
867 | struct lpfc_scsi_buf *lpfc_cmd; | ||
868 | struct lpfc_nodelist *ndlp; | ||
869 | int found = 0; | ||
870 | |||
871 | if (piocbq->iocb_flag & LPFC_IO_FCP) { | ||
872 | lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1; | ||
873 | ndlp = lpfc_cmd->rdata->pnode; | ||
874 | } else if (piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) | ||
875 | ndlp = piocbq->context_un.ndlp; | ||
876 | else if (piocbq->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX) | ||
877 | ndlp = lpfc_findnode_did(piocbq->vport, | ||
878 | piocbq->iocb.ulpContext); | ||
879 | else | ||
880 | ndlp = piocbq->context1; | ||
881 | |||
530 | list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list); | 882 | list_remove_head(lpfc_sgl_list, sglq, struct lpfc_sglq, list); |
531 | if (!sglq) | 883 | start_sglq = sglq; |
532 | return NULL; | 884 | while (!found) { |
533 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; | 885 | if (!sglq) |
534 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | 886 | return NULL; |
535 | sglq->state = SGL_ALLOCATED; | 887 | adj_xri = sglq->sli4_xritag - |
888 | phba->sli4_hba.max_cfg_param.xri_base; | ||
889 | if (__lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) { | ||
890 | /* This xri has an rrq outstanding for this DID. | ||
891 | * put it back in the list and get another xri. | ||
892 | */ | ||
893 | list_add_tail(&sglq->list, lpfc_sgl_list); | ||
894 | sglq = NULL; | ||
895 | list_remove_head(lpfc_sgl_list, sglq, | ||
896 | struct lpfc_sglq, list); | ||
897 | if (sglq == start_sglq) { | ||
898 | sglq = NULL; | ||
899 | break; | ||
900 | } else | ||
901 | continue; | ||
902 | } | ||
903 | sglq->ndlp = ndlp; | ||
904 | found = 1; | ||
905 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | ||
906 | sglq->state = SGL_ALLOCATED; | ||
907 | } | ||
536 | return sglq; | 908 | return sglq; |
537 | } | 909 | } |
538 | 910 | ||
@@ -598,6 +970,7 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
598 | &phba->sli4_hba.abts_sgl_list_lock, iflag); | 970 | &phba->sli4_hba.abts_sgl_list_lock, iflag); |
599 | } else { | 971 | } else { |
600 | sglq->state = SGL_FREED; | 972 | sglq->state = SGL_FREED; |
973 | sglq->ndlp = NULL; | ||
601 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); | 974 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); |
602 | 975 | ||
603 | /* Check if TXQ queue needs to be serviced */ | 976 | /* Check if TXQ queue needs to be serviced */ |
@@ -6352,7 +6725,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6352 | return IOCB_BUSY; | 6725 | return IOCB_BUSY; |
6353 | } | 6726 | } |
6354 | } else { | 6727 | } else { |
6355 | sglq = __lpfc_sli_get_sglq(phba); | 6728 | sglq = __lpfc_sli_get_sglq(phba, piocb); |
6356 | if (!sglq) { | 6729 | if (!sglq) { |
6357 | if (!(flag & SLI_IOCB_RET_IOCB)) { | 6730 | if (!(flag & SLI_IOCB_RET_IOCB)) { |
6358 | __lpfc_sli_ringtx_put(phba, | 6731 | __lpfc_sli_ringtx_put(phba, |
@@ -11570,6 +11943,10 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | |||
11570 | "SID:x%x\n", oxid, sid); | 11943 | "SID:x%x\n", oxid, sid); |
11571 | return; | 11944 | return; |
11572 | } | 11945 | } |
11946 | if (rxid >= phba->sli4_hba.max_cfg_param.xri_base | ||
11947 | && rxid <= (phba->sli4_hba.max_cfg_param.max_xri | ||
11948 | + phba->sli4_hba.max_cfg_param.xri_base)) | ||
11949 | lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0); | ||
11573 | 11950 | ||
11574 | /* Allocate buffer for acc iocb */ | 11951 | /* Allocate buffer for acc iocb */ |
11575 | ctiocb = lpfc_sli_get_iocbq(phba); | 11952 | ctiocb = lpfc_sli_get_iocbq(phba); |
@@ -13008,12 +13385,13 @@ lpfc_drain_txq(struct lpfc_hba *phba) | |||
13008 | while (pring->txq_cnt) { | 13385 | while (pring->txq_cnt) { |
13009 | spin_lock_irqsave(&phba->hbalock, iflags); | 13386 | spin_lock_irqsave(&phba->hbalock, iflags); |
13010 | 13387 | ||
13011 | sglq = __lpfc_sli_get_sglq(phba); | 13388 | piocbq = lpfc_sli_ringtx_get(phba, pring); |
13389 | sglq = __lpfc_sli_get_sglq(phba, piocbq); | ||
13012 | if (!sglq) { | 13390 | if (!sglq) { |
13391 | __lpfc_sli_ringtx_put(phba, pring, piocbq); | ||
13013 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 13392 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
13014 | break; | 13393 | break; |
13015 | } else { | 13394 | } else { |
13016 | piocbq = lpfc_sli_ringtx_get(phba, pring); | ||
13017 | if (!piocbq) { | 13395 | if (!piocbq) { |
13018 | /* The txq_cnt out of sync. This should | 13396 | /* The txq_cnt out of sync. This should |
13019 | * never happen | 13397 | * never happen |