diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-10-27 13:38:00 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:22:33 -0500 |
commit | 76bb24efdc5de8eead0ccc07ec7e3b59a4ca0f15 (patch) | |
tree | 989311bb1be4a8331407bb6d3d67e5bd95e8a7a6 /drivers/scsi/lpfc/lpfc_sli.c | |
parent | a8adb83208020c913f010cb4e26d09e25300db8e (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.c | 123 |
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 | ||
934 | static struct lpfc_dmabuf * | ||
935 | lpfc_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 | ||
935 | static int | 945 | static int |
936 | lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 946 | lpfc_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 | ||
3385 | uint32_t | ||
3386 | lpfc_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 | |||
3399 | struct lpfc_dmabuf * | ||
3400 | lpfc_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 | ||
3318 | struct lpfc_dmabuf * | 3427 | struct lpfc_dmabuf * |
3319 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 3428 | lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |