aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-10-27 13:38:00 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:33 -0500
commit76bb24efdc5de8eead0ccc07ec7e3b59a4ca0f15 (patch)
tree989311bb1be4a8331407bb6d3d67e5bd95e8a7a6 /drivers/scsi/lpfc/lpfc_sli.c
parenta8adb83208020c913f010cb4e26d09e25300db8e (diff)
[SCSI] lpfc 8.2.3 : Internal loopback fixes
Internal loopback fixes: - Use HBQs rather than Q_RING_BUFF - Correct HBQs continuation entries - Update CT handler to SLI3 iocbs Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c123
1 files changed, 116 insertions, 7 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index c3743d6f445b..9bc85d5a02f7 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -931,6 +931,16 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
931 return &new_hbq_entry->dbuf; 931 return &new_hbq_entry->dbuf;
932} 932}
933 933
934static struct lpfc_dmabuf *
935lpfc_sli_get_buff(struct lpfc_hba *phba,
936 struct lpfc_sli_ring *pring,
937 uint32_t tag)
938{
939 if (tag & QUE_BUFTAG_BIT)
940 return lpfc_sli_ring_taggedbuf_get(phba, pring, tag);
941 else
942 return lpfc_sli_replace_hbqbuff(phba, tag);
943}
934 944
935static int 945static int
936lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 946lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
@@ -940,6 +950,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
940 WORD5 * w5p; 950 WORD5 * w5p;
941 uint32_t Rctl, Type; 951 uint32_t Rctl, Type;
942 uint32_t match, i; 952 uint32_t match, i;
953 struct lpfc_iocbq *iocbq;
943 954
944 match = 0; 955 match = 0;
945 irsp = &(saveq->iocb); 956 irsp = &(saveq->iocb);
@@ -984,12 +995,69 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
984 } 995 }
985 996
986 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { 997 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
987 if (irsp->ulpBdeCount != 0) 998 struct lpfc_hbq_entry *hbqe_1, *hbqe_2;
988 saveq->context2 = lpfc_sli_replace_hbqbuff(phba, 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) {
1004 saveq->context2 = lpfc_sli_get_buff(phba, pring,
989 irsp->un.ulpWord[3]); 1005 irsp->un.ulpWord[3]);
990 if (irsp->ulpBdeCount == 2) 1006 if (!saveq->context2)
991 saveq->context3 = lpfc_sli_replace_hbqbuff(phba, 1007 lpfc_printf_log(phba,
1008 KERN_ERR,
1009 LOG_SLI,
1010 "0341 Ring %d Cannot find buffer for "
1011 "an unsolicited iocb. tag 0x%x\n",
1012 pring->ringno,
1013 irsp->un.ulpWord[3]);
1014
1015 }
1016 if (irsp->ulpBdeCount == 2) {
1017 saveq->context3 = lpfc_sli_get_buff(phba, pring,
992 irsp->unsli3.sli3Words[7]); 1018 irsp->unsli3.sli3Words[7]);
1019 if (!saveq->context3)
1020 lpfc_printf_log(phba,
1021 KERN_ERR,
1022 LOG_SLI,
1023 "0342 Ring %d Cannot find buffer for an"
1024 " unsolicited iocb. tag 0x%x\n",
1025 pring->ringno,
1026 irsp->unsli3.sli3Words[7]);
1027 }
1028 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);
1034
1035 if (irsp->ulpBdeCount != 0) {
1036 iocbq->context2 = lpfc_sli_get_buff(phba, pring,
1037 irsp->un.ulpWord[3]);
1038 if (!saveq->context2)
1039 lpfc_printf_log(phba,
1040 KERN_ERR,
1041 LOG_SLI,
1042 "0343 Ring %d Cannot find "
1043 "buffer for an unsolicited iocb"
1044 ". tag 0x%x\n", pring->ringno,
1045 irsp->un.ulpWord[3]);
1046 }
1047 if (irsp->ulpBdeCount == 2) {
1048 iocbq->context3 = lpfc_sli_get_buff(phba, pring,
1049 irsp->unsli3.sli3Words[7]);
1050 if (!saveq->context3)
1051 lpfc_printf_log(phba,
1052 KERN_ERR,
1053 LOG_SLI,
1054 "0344 Ring %d Cannot find "
1055 "buffer for an unsolicited "
1056 "iocb. tag 0x%x\n",
1057 pring->ringno,
1058 irsp->unsli3.sli3Words[7]);
1059 }
1060 }
993 } 1061 }
994 1062
995 /* unSolicited Responses */ 1063 /* unSolicited Responses */
@@ -2480,7 +2548,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
2480 lpfc_sli_abort_iocb_ring(phba, pring); 2548 lpfc_sli_abort_iocb_ring(phba, pring);
2481 2549
2482 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, 2550 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
2483 "0316 Resetting board due to mailbox timeout\n"); 2551 "0345 Resetting board due to mailbox timeout\n");
2484 /* 2552 /*
2485 * lpfc_offline calls lpfc_sli_hba_down which will clean up 2553 * lpfc_offline calls lpfc_sli_hba_down which will clean up
2486 * on oustanding mailbox commands. 2554 * on oustanding mailbox commands.
@@ -2975,7 +3043,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
2975 lpfc_printf_log(phba, 3043 lpfc_printf_log(phba,
2976 KERN_ERR, 3044 KERN_ERR,
2977 LOG_SLI, 3045 LOG_SLI,
2978 "0327 Ring %d handler: unexpected ASYNC_STATUS" 3046 "0346 Ring %d handler: unexpected ASYNC_STATUS"
2979 " evt_code 0x%x\n", 3047 " evt_code 0x%x\n",
2980 pring->ringno, 3048 pring->ringno,
2981 icmd->un.asyncstat.evt_code); 3049 icmd->un.asyncstat.evt_code);
@@ -2988,7 +3056,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
2988 lpfc_printf_log(phba, 3056 lpfc_printf_log(phba,
2989 KERN_WARNING, 3057 KERN_WARNING,
2990 LOG_TEMP, 3058 LOG_TEMP,
2991 "0339 Adapter is very hot, please take " 3059 "0347 Adapter is very hot, please take "
2992 "corrective action. temperature : %d Celsius\n", 3060 "corrective action. temperature : %d Celsius\n",
2993 temp); 3061 temp);
2994 } 3062 }
@@ -3314,6 +3382,47 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3314 return 0; 3382 return 0;
3315} 3383}
3316 3384
3385uint32_t
3386lpfc_sli_get_buffer_tag(struct lpfc_hba *phba)
3387{
3388 spin_lock_irq(&phba->hbalock);
3389 phba->buffer_tag_count++;
3390 /*
3391 * Always set the QUE_BUFTAG_BIT to distiguish between
3392 * a tag assigned by HBQ.
3393 */
3394 phba->buffer_tag_count |= QUE_BUFTAG_BIT;
3395 spin_unlock_irq(&phba->hbalock);
3396 return phba->buffer_tag_count;
3397}
3398
3399struct lpfc_dmabuf *
3400lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3401 uint32_t tag)
3402{
3403 struct lpfc_dmabuf *mp, *next_mp;
3404 struct list_head *slp = &pring->postbufq;
3405
3406 /* Search postbufq, from the begining, looking for a match on tag */
3407 spin_lock_irq(&phba->hbalock);
3408 list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
3409 if (mp->buffer_tag == tag) {
3410 list_del_init(&mp->list);
3411 pring->postbufq_cnt--;
3412 spin_unlock_irq(&phba->hbalock);
3413 return mp;
3414 }
3415 }
3416
3417 spin_unlock_irq(&phba->hbalock);
3418 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
3419 "0410 Cannot find virtual addr for buffer tag on "
3420 "ring %d Data x%lx x%p x%p x%x\n",
3421 pring->ringno, (unsigned long) tag,
3422 slp->next, slp->prev, pring->postbufq_cnt);
3423
3424 return NULL;
3425}
3317 3426
3318struct lpfc_dmabuf * 3427struct lpfc_dmabuf *
3319lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 3428lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,