[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>
This commit is contained in:
James Smart
2007-10-27 13:38:00 -04:00
committed by James Bottomley
parent a8adb83208
commit 76bb24efdc
4 changed files with 153 additions and 13 deletions

View File

@@ -931,6 +931,16 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
return &new_hbq_entry->dbuf;
}
static struct lpfc_dmabuf *
lpfc_sli_get_buff(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring,
uint32_t tag)
{
if (tag & QUE_BUFTAG_BIT)
return lpfc_sli_ring_taggedbuf_get(phba, pring, tag);
else
return lpfc_sli_replace_hbqbuff(phba, tag);
}
static int
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,
WORD5 * w5p;
uint32_t Rctl, Type;
uint32_t match, i;
struct lpfc_iocbq *iocbq;
match = 0;
irsp = &(saveq->iocb);
@@ -984,12 +995,69 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
if (irsp->ulpBdeCount != 0)
saveq->context2 = lpfc_sli_replace_hbqbuff(phba,
struct lpfc_hbq_entry *hbqe_1, *hbqe_2;
hbqe_1 = (struct lpfc_hbq_entry *) &saveq->iocb.un.ulpWord[0];
hbqe_2 = (struct lpfc_hbq_entry *) &saveq->iocb.
unsli3.sli3Words[4];
if (irsp->ulpBdeCount != 0) {
saveq->context2 = lpfc_sli_get_buff(phba, pring,
irsp->un.ulpWord[3]);
if (irsp->ulpBdeCount == 2)
saveq->context3 = lpfc_sli_replace_hbqbuff(phba,
if (!saveq->context2)
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"0341 Ring %d Cannot find buffer for "
"an unsolicited iocb. tag 0x%x\n",
pring->ringno,
irsp->un.ulpWord[3]);
}
if (irsp->ulpBdeCount == 2) {
saveq->context3 = lpfc_sli_get_buff(phba, pring,
irsp->unsli3.sli3Words[7]);
if (!saveq->context3)
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"0342 Ring %d Cannot find buffer for an"
" unsolicited iocb. tag 0x%x\n",
pring->ringno,
irsp->unsli3.sli3Words[7]);
}
list_for_each_entry(iocbq, &saveq->list, list) {
hbqe_1 = (struct lpfc_hbq_entry *) &iocbq->iocb.
un.ulpWord[0];
hbqe_2 = (struct lpfc_hbq_entry *) &iocbq->iocb.
unsli3.sli3Words[4];
irsp = &(iocbq->iocb);
if (irsp->ulpBdeCount != 0) {
iocbq->context2 = lpfc_sli_get_buff(phba, pring,
irsp->un.ulpWord[3]);
if (!saveq->context2)
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"0343 Ring %d Cannot find "
"buffer for an unsolicited iocb"
". tag 0x%x\n", pring->ringno,
irsp->un.ulpWord[3]);
}
if (irsp->ulpBdeCount == 2) {
iocbq->context3 = lpfc_sli_get_buff(phba, pring,
irsp->unsli3.sli3Words[7]);
if (!saveq->context3)
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"0344 Ring %d Cannot find "
"buffer for an unsolicited "
"iocb. tag 0x%x\n",
pring->ringno,
irsp->unsli3.sli3Words[7]);
}
}
}
/* unSolicited Responses */
@@ -2480,7 +2548,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
lpfc_sli_abort_iocb_ring(phba, pring);
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
"0316 Resetting board due to mailbox timeout\n");
"0345 Resetting board due to mailbox timeout\n");
/*
* lpfc_offline calls lpfc_sli_hba_down which will clean up
* on oustanding mailbox commands.
@@ -2975,7 +3043,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
lpfc_printf_log(phba,
KERN_ERR,
LOG_SLI,
"0327 Ring %d handler: unexpected ASYNC_STATUS"
"0346 Ring %d handler: unexpected ASYNC_STATUS"
" evt_code 0x%x\n",
pring->ringno,
icmd->un.asyncstat.evt_code);
@@ -2988,7 +3056,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
lpfc_printf_log(phba,
KERN_WARNING,
LOG_TEMP,
"0339 Adapter is very hot, please take "
"0347 Adapter is very hot, please take "
"corrective action. temperature : %d Celsius\n",
temp);
}
@@ -3314,6 +3382,47 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return 0;
}
uint32_t
lpfc_sli_get_buffer_tag(struct lpfc_hba *phba)
{
spin_lock_irq(&phba->hbalock);
phba->buffer_tag_count++;
/*
* Always set the QUE_BUFTAG_BIT to distiguish between
* a tag assigned by HBQ.
*/
phba->buffer_tag_count |= QUE_BUFTAG_BIT;
spin_unlock_irq(&phba->hbalock);
return phba->buffer_tag_count;
}
struct lpfc_dmabuf *
lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
uint32_t tag)
{
struct lpfc_dmabuf *mp, *next_mp;
struct list_head *slp = &pring->postbufq;
/* Search postbufq, from the begining, looking for a match on tag */
spin_lock_irq(&phba->hbalock);
list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) {
if (mp->buffer_tag == tag) {
list_del_init(&mp->list);
pring->postbufq_cnt--;
spin_unlock_irq(&phba->hbalock);
return mp;
}
}
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0410 Cannot find virtual addr for buffer tag on "
"ring %d Data x%lx x%p x%p x%x\n",
pring->ringno, (unsigned long) tag,
slp->next, slp->prev, pring->postbufq_cnt);
return NULL;
}
struct lpfc_dmabuf *
lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,