aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c109
1 files changed, 56 insertions, 53 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 5a2cb484e137..584c5451641f 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -955,6 +955,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
955 match = 0; 955 match = 0;
956 irsp = &(saveq->iocb); 956 irsp = &(saveq->iocb);
957 957
958 if (irsp->ulpStatus == IOSTAT_NEED_BUFFER)
959 return 1;
958 if (irsp->ulpCommand == CMD_ASYNC_STATUS) { 960 if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
959 if (pring->lpfc_sli_rcv_async_status) 961 if (pring->lpfc_sli_rcv_async_status)
960 pring->lpfc_sli_rcv_async_status(phba, pring, saveq); 962 pring->lpfc_sli_rcv_async_status(phba, pring, saveq);
@@ -970,36 +972,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
970 return 1; 972 return 1;
971 } 973 }
972 974
973 if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX)
974 || (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX)
975 || (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)
976 || (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX)) {
977 Rctl = FC_ELS_REQ;
978 Type = FC_ELS_DATA;
979 } else {
980 w5p =
981 (WORD5 *) & (saveq->iocb.un.
982 ulpWord[5]);
983 Rctl = w5p->hcsw.Rctl;
984 Type = w5p->hcsw.Type;
985
986 /* Firmware Workaround */
987 if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
988 (irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
989 irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
990 Rctl = FC_ELS_REQ;
991 Type = FC_ELS_DATA;
992 w5p->hcsw.Rctl = Rctl;
993 w5p->hcsw.Type = Type;
994 }
995 }
996
997 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { 975 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
998 struct lpfc_hbq_entry *hbqe_1, *hbqe_2;
999 hbqe_1 = (struct lpfc_hbq_entry *) &saveq->iocb.un.ulpWord[0];
1000 hbqe_2 = (struct lpfc_hbq_entry *) &saveq->iocb.
1001 unsli3.sli3Words[4];
1002
1003 if (irsp->ulpBdeCount != 0) { 976 if (irsp->ulpBdeCount != 0) {
1004 saveq->context2 = lpfc_sli_get_buff(phba, pring, 977 saveq->context2 = lpfc_sli_get_buff(phba, pring,
1005 irsp->un.ulpWord[3]); 978 irsp->un.ulpWord[3]);
@@ -1011,7 +984,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1011 "an unsolicited iocb. tag 0x%x\n", 984 "an unsolicited iocb. tag 0x%x\n",
1012 pring->ringno, 985 pring->ringno,
1013 irsp->un.ulpWord[3]); 986 irsp->un.ulpWord[3]);
1014
1015 } 987 }
1016 if (irsp->ulpBdeCount == 2) { 988 if (irsp->ulpBdeCount == 2) {
1017 saveq->context3 = lpfc_sli_get_buff(phba, pring, 989 saveq->context3 = lpfc_sli_get_buff(phba, pring,
@@ -1026,16 +998,11 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1026 irsp->unsli3.sli3Words[7]); 998 irsp->unsli3.sli3Words[7]);
1027 } 999 }
1028 list_for_each_entry(iocbq, &saveq->list, list) { 1000 list_for_each_entry(iocbq, &saveq->list, list) {
1029 hbqe_1 = (struct lpfc_hbq_entry *) &iocbq->iocb.
1030 un.ulpWord[0];
1031 hbqe_2 = (struct lpfc_hbq_entry *) &iocbq->iocb.
1032 unsli3.sli3Words[4];
1033 irsp = &(iocbq->iocb); 1001 irsp = &(iocbq->iocb);
1034
1035 if (irsp->ulpBdeCount != 0) { 1002 if (irsp->ulpBdeCount != 0) {
1036 iocbq->context2 = lpfc_sli_get_buff(phba, pring, 1003 iocbq->context2 = lpfc_sli_get_buff(phba, pring,
1037 irsp->un.ulpWord[3]); 1004 irsp->un.ulpWord[3]);
1038 if (!saveq->context2) 1005 if (!iocbq->context2)
1039 lpfc_printf_log(phba, 1006 lpfc_printf_log(phba,
1040 KERN_ERR, 1007 KERN_ERR,
1041 LOG_SLI, 1008 LOG_SLI,
@@ -1047,7 +1014,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1047 if (irsp->ulpBdeCount == 2) { 1014 if (irsp->ulpBdeCount == 2) {
1048 iocbq->context3 = lpfc_sli_get_buff(phba, pring, 1015 iocbq->context3 = lpfc_sli_get_buff(phba, pring,
1049 irsp->unsli3.sli3Words[7]); 1016 irsp->unsli3.sli3Words[7]);
1050 if (!saveq->context3) 1017 if (!iocbq->context3)
1051 lpfc_printf_log(phba, 1018 lpfc_printf_log(phba,
1052 KERN_ERR, 1019 KERN_ERR,
1053 LOG_SLI, 1020 LOG_SLI,
@@ -1059,6 +1026,49 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1059 } 1026 }
1060 } 1027 }
1061 } 1028 }
1029 if (irsp->ulpBdeCount != 0 &&
1030 (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX ||
1031 irsp->ulpStatus == IOSTAT_INTERMED_RSP)) {
1032 int found = 0;
1033
1034 /* search continue save q for same XRI */
1035 list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) {
1036 if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) {
1037 list_add_tail(&saveq->list, &iocbq->list);
1038 found = 1;
1039 break;
1040 }
1041 }
1042 if (!found)
1043 list_add_tail(&saveq->clist,
1044 &pring->iocb_continue_saveq);
1045 if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) {
1046 list_del_init(&iocbq->clist);
1047 saveq = iocbq;
1048 irsp = &(saveq->iocb);
1049 } else
1050 return 0;
1051 }
1052 if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
1053 (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
1054 (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) {
1055 Rctl = FC_ELS_REQ;
1056 Type = FC_ELS_DATA;
1057 } else {
1058 w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]);
1059 Rctl = w5p->hcsw.Rctl;
1060 Type = w5p->hcsw.Type;
1061
1062 /* Firmware Workaround */
1063 if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
1064 (irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
1065 irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
1066 Rctl = FC_ELS_REQ;
1067 Type = FC_ELS_DATA;
1068 w5p->hcsw.Rctl = Rctl;
1069 w5p->hcsw.Type = Type;
1070 }
1071 }
1062 1072
1063 /* unSolicited Responses */ 1073 /* unSolicited Responses */
1064 if (pring->prt[0].profile) { 1074 if (pring->prt[0].profile) {
@@ -1069,12 +1079,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1069 } else { 1079 } else {
1070 /* We must search, based on rctl / type 1080 /* We must search, based on rctl / type
1071 for the right routine */ 1081 for the right routine */
1072 for (i = 0; i < pring->num_mask; 1082 for (i = 0; i < pring->num_mask; i++) {
1073 i++) { 1083 if ((pring->prt[i].rctl == Rctl)
1074 if ((pring->prt[i].rctl == 1084 && (pring->prt[i].type == Type)) {
1075 Rctl)
1076 && (pring->prt[i].
1077 type == Type)) {
1078 if (pring->prt[i].lpfc_sli_rcv_unsol_event) 1085 if (pring->prt[i].lpfc_sli_rcv_unsol_event)
1079 (pring->prt[i].lpfc_sli_rcv_unsol_event) 1086 (pring->prt[i].lpfc_sli_rcv_unsol_event)
1080 (phba, pring, saveq); 1087 (phba, pring, saveq);
@@ -1641,12 +1648,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
1641 1648
1642 writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx); 1649 writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
1643 1650
1644 if (list_empty(&(pring->iocb_continueq))) { 1651 list_add_tail(&rspiocbp->list, &(pring->iocb_continueq));
1645 list_add(&rspiocbp->list, &(pring->iocb_continueq));
1646 } else {
1647 list_add_tail(&rspiocbp->list,
1648 &(pring->iocb_continueq));
1649 }
1650 1652
1651 pring->iocb_continueq_cnt++; 1653 pring->iocb_continueq_cnt++;
1652 if (irsp->ulpLe) { 1654 if (irsp->ulpLe) {
@@ -1711,17 +1713,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
1711 iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK; 1713 iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK;
1712 type = lpfc_sli_iocb_cmd_type(iocb_cmd_type); 1714 type = lpfc_sli_iocb_cmd_type(iocb_cmd_type);
1713 if (type == LPFC_SOL_IOCB) { 1715 if (type == LPFC_SOL_IOCB) {
1714 spin_unlock_irqrestore(&phba->hbalock, 1716 spin_unlock_irqrestore(&phba->hbalock, iflag);
1715 iflag);
1716 rc = lpfc_sli_process_sol_iocb(phba, pring, 1717 rc = lpfc_sli_process_sol_iocb(phba, pring,
1717 saveq); 1718 saveq);
1718 spin_lock_irqsave(&phba->hbalock, iflag); 1719 spin_lock_irqsave(&phba->hbalock, iflag);
1719 } else if (type == LPFC_UNSOL_IOCB) { 1720 } else if (type == LPFC_UNSOL_IOCB) {
1720 spin_unlock_irqrestore(&phba->hbalock, 1721 spin_unlock_irqrestore(&phba->hbalock, iflag);
1721 iflag);
1722 rc = lpfc_sli_process_unsol_iocb(phba, pring, 1722 rc = lpfc_sli_process_unsol_iocb(phba, pring,
1723 saveq); 1723 saveq);
1724 spin_lock_irqsave(&phba->hbalock, iflag); 1724 spin_lock_irqsave(&phba->hbalock, iflag);
1725 if (!rc)
1726 free_saveq = 0;
1725 } else if (type == LPFC_ABORT_IOCB) { 1727 } else if (type == LPFC_ABORT_IOCB) {
1726 if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) && 1728 if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
1727 ((cmdiocbp = 1729 ((cmdiocbp =
@@ -3238,6 +3240,7 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba)
3238 INIT_LIST_HEAD(&pring->txq); 3240 INIT_LIST_HEAD(&pring->txq);
3239 INIT_LIST_HEAD(&pring->txcmplq); 3241 INIT_LIST_HEAD(&pring->txcmplq);
3240 INIT_LIST_HEAD(&pring->iocb_continueq); 3242 INIT_LIST_HEAD(&pring->iocb_continueq);
3243 INIT_LIST_HEAD(&pring->iocb_continue_saveq);
3241 INIT_LIST_HEAD(&pring->postbufq); 3244 INIT_LIST_HEAD(&pring->postbufq);
3242 } 3245 }
3243 spin_unlock_irq(&phba->hbalock); 3246 spin_unlock_irq(&phba->hbalock);