mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-29 16:21:59 +00:00
[SCSI] lpfc 8.2.4 : Fix Unsolicited Data items
Fix Drivers Unsolicited CT command handling - we did not handle multiframe sequences well. Fix error due to delay in replenishing buffers for unsolicited data. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
83108bd382
commit
9c2face687
4 changed files with 123 additions and 113 deletions
|
@ -57,45 +57,27 @@
|
||||||
|
|
||||||
static char *lpfc_release_version = LPFC_DRIVER_VERSION;
|
static char *lpfc_release_version = LPFC_DRIVER_VERSION;
|
||||||
|
|
||||||
/*
|
|
||||||
* lpfc_ct_unsol_event
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
|
||||||
struct lpfc_dmabuf *mp, uint32_t size)
|
|
||||||
{
|
|
||||||
if (!mp) {
|
|
||||||
printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, "
|
|
||||||
"piocbq = %p, status = x%x, mp = %p, size = %d\n",
|
|
||||||
__FUNCTION__, __LINE__,
|
|
||||||
piocbq, piocbq->iocb.ulpStatus, mp, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, "
|
|
||||||
"buffer = %p, size = %d, status = x%x\n",
|
|
||||||
__FUNCTION__, __LINE__,
|
|
||||||
piocbq, mp, size,
|
|
||||||
piocbq->iocb.ulpStatus);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
||||||
struct lpfc_dmabuf *mp, uint32_t size)
|
struct lpfc_dmabuf *mp, uint32_t size)
|
||||||
{
|
{
|
||||||
if (!mp) {
|
if (!mp) {
|
||||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||||
"HBQ buffer, piocbq = %p, status = x%x\n",
|
"0146 Ignoring unsolicted CT No HBQ "
|
||||||
__FUNCTION__, __LINE__,
|
"status = x%x\n",
|
||||||
piocbq, piocbq->iocb.ulpStatus);
|
piocbq->iocb.ulpStatus);
|
||||||
} else {
|
|
||||||
lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
|
|
||||||
printk(KERN_ERR "%s (%d): Ignoring unsolicted CT "
|
|
||||||
"piocbq = %p, buffer = %p, size = %d, "
|
|
||||||
"status = x%x\n",
|
|
||||||
__FUNCTION__, __LINE__,
|
|
||||||
piocbq, mp, size, piocbq->iocb.ulpStatus);
|
|
||||||
}
|
}
|
||||||
|
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
|
||||||
|
"0145 Ignoring unsolicted CT HBQ Size:%d "
|
||||||
|
"status = x%x\n",
|
||||||
|
size, piocbq->iocb.ulpStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
|
||||||
|
struct lpfc_dmabuf *mp, uint32_t size)
|
||||||
|
{
|
||||||
|
lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -109,11 +91,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
struct lpfc_iocbq *iocbq;
|
struct lpfc_iocbq *iocbq;
|
||||||
dma_addr_t paddr;
|
dma_addr_t paddr;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
struct lpfc_dmabuf *bdeBuf1 = piocbq->context2;
|
struct list_head head;
|
||||||
struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
|
struct lpfc_dmabuf *bdeBuf;
|
||||||
|
|
||||||
piocbq->context2 = NULL;
|
|
||||||
piocbq->context3 = NULL;
|
|
||||||
|
|
||||||
if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
|
if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
|
||||||
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
|
lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
|
||||||
|
@ -122,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
/* Not enough posted buffers; Try posting more buffers */
|
/* Not enough posted buffers; Try posting more buffers */
|
||||||
phba->fc_stat.NoRcvBuf++;
|
phba->fc_stat.NoRcvBuf++;
|
||||||
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
|
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
|
||||||
lpfc_post_buffer(phba, pring, 0, 1);
|
lpfc_post_buffer(phba, pring, 2, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,38 +112,34 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||||
list_for_each_entry(iocbq, &piocbq->list, list) {
|
INIT_LIST_HEAD(&head);
|
||||||
|
list_add_tail(&head, &piocbq->list);
|
||||||
|
list_for_each_entry(iocbq, &head, list) {
|
||||||
icmd = &iocbq->iocb;
|
icmd = &iocbq->iocb;
|
||||||
if (icmd->ulpBdeCount == 0) {
|
if (icmd->ulpBdeCount == 0)
|
||||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
|
||||||
"BDE, iocbq = %p, status = x%x\n",
|
|
||||||
__FUNCTION__, __LINE__,
|
|
||||||
iocbq, iocbq->iocb.ulpStatus);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
bdeBuf = iocbq->context2;
|
||||||
|
iocbq->context2 = NULL;
|
||||||
size = icmd->un.cont64[0].tus.f.bdeSize;
|
size = icmd->un.cont64[0].tus.f.bdeSize;
|
||||||
lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size);
|
lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
|
||||||
lpfc_in_buf_free(phba, bdeBuf1);
|
lpfc_in_buf_free(phba, bdeBuf);
|
||||||
if (icmd->ulpBdeCount == 2) {
|
if (icmd->ulpBdeCount == 2) {
|
||||||
lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2,
|
bdeBuf = iocbq->context3;
|
||||||
size);
|
iocbq->context3 = NULL;
|
||||||
lpfc_in_buf_free(phba, bdeBuf2);
|
size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
|
||||||
|
lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf,
|
||||||
|
size);
|
||||||
|
lpfc_in_buf_free(phba, bdeBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
list_del(&head);
|
||||||
} else {
|
} else {
|
||||||
struct lpfc_iocbq *next;
|
struct lpfc_iocbq *next;
|
||||||
|
|
||||||
list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
|
list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
|
||||||
icmd = &iocbq->iocb;
|
icmd = &iocbq->iocb;
|
||||||
if (icmd->ulpBdeCount == 0) {
|
if (icmd->ulpBdeCount == 0)
|
||||||
printk(KERN_ERR "%s (%d): Unsolited CT, no "
|
lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0);
|
||||||
"BDE, iocbq = %p, status = x%x\n",
|
|
||||||
__FUNCTION__, __LINE__,
|
|
||||||
iocbq, iocbq->iocb.ulpStatus);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < icmd->ulpBdeCount; i++) {
|
for (i = 0; i < icmd->ulpBdeCount; i++) {
|
||||||
paddr = getPaddr(icmd->un.cont64[i].addrHigh,
|
paddr = getPaddr(icmd->un.cont64[i].addrHigh,
|
||||||
icmd->un.cont64[i].addrLow);
|
icmd->un.cont64[i].addrLow);
|
||||||
|
@ -176,6 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
}
|
}
|
||||||
list_del(&iocbq->list);
|
list_del(&iocbq->list);
|
||||||
lpfc_sli_release_iocbq(phba, iocbq);
|
lpfc_sli_release_iocbq(phba, iocbq);
|
||||||
|
lpfc_post_buffer(phba, pring, i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2994,6 +2994,34 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
} RCV_ELS_REQ64;
|
} RCV_ELS_REQ64;
|
||||||
|
|
||||||
|
/* IOCB Command template for RCV_SEQ64 */
|
||||||
|
struct rcv_seq64 {
|
||||||
|
struct ulp_bde64 elsReq;
|
||||||
|
uint32_t hbq_1;
|
||||||
|
uint32_t parmRo;
|
||||||
|
#ifdef __BIG_ENDIAN_BITFIELD
|
||||||
|
uint32_t rctl:8;
|
||||||
|
uint32_t type:8;
|
||||||
|
uint32_t dfctl:8;
|
||||||
|
uint32_t ls:1;
|
||||||
|
uint32_t fs:1;
|
||||||
|
uint32_t rsvd2:3;
|
||||||
|
uint32_t si:1;
|
||||||
|
uint32_t bc:1;
|
||||||
|
uint32_t rsvd3:1;
|
||||||
|
#else /* __LITTLE_ENDIAN_BITFIELD */
|
||||||
|
uint32_t rsvd3:1;
|
||||||
|
uint32_t bc:1;
|
||||||
|
uint32_t si:1;
|
||||||
|
uint32_t rsvd2:3;
|
||||||
|
uint32_t fs:1;
|
||||||
|
uint32_t ls:1;
|
||||||
|
uint32_t dfctl:8;
|
||||||
|
uint32_t type:8;
|
||||||
|
uint32_t rctl:8;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/* IOCB Command template for all 64 bit FCP Initiator commands */
|
/* IOCB Command template for all 64 bit FCP Initiator commands */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ULP_BDL bdl;
|
ULP_BDL bdl;
|
||||||
|
@ -3085,6 +3113,7 @@ typedef struct _IOCB { /* IOCB structure */
|
||||||
FCPT_FIELDS64 fcpt64; /* FCP 64 bit target template */
|
FCPT_FIELDS64 fcpt64; /* FCP 64 bit target template */
|
||||||
ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */
|
ASYNCSTAT_FIELDS asyncstat; /* async_status iocb */
|
||||||
QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */
|
QUE_XRI64_CX_FIELDS quexri64cx; /* que_xri64_cx fields */
|
||||||
|
struct rcv_seq64 rcvseq64; /* RCV_SEQ64 and RCV_CONT64 */
|
||||||
|
|
||||||
uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */
|
uint32_t ulpWord[IOCB_WORD_SZ - 2]; /* generic 6 'words' */
|
||||||
} un;
|
} un;
|
||||||
|
|
|
@ -955,6 +955,8 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
match = 0;
|
match = 0;
|
||||||
irsp = &(saveq->iocb);
|
irsp = &(saveq->iocb);
|
||||||
|
|
||||||
|
if (irsp->ulpStatus == IOSTAT_NEED_BUFFER)
|
||||||
|
return 1;
|
||||||
if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
|
if (irsp->ulpCommand == CMD_ASYNC_STATUS) {
|
||||||
if (pring->lpfc_sli_rcv_async_status)
|
if (pring->lpfc_sli_rcv_async_status)
|
||||||
pring->lpfc_sli_rcv_async_status(phba, pring, saveq);
|
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,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX)
|
|
||||||
|| (irsp->ulpCommand == CMD_RCV_ELS_REQ_CX)
|
|
||||||
|| (irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)
|
|
||||||
|| (irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX)) {
|
|
||||||
Rctl = FC_ELS_REQ;
|
|
||||||
Type = FC_ELS_DATA;
|
|
||||||
} else {
|
|
||||||
w5p =
|
|
||||||
(WORD5 *) & (saveq->iocb.un.
|
|
||||||
ulpWord[5]);
|
|
||||||
Rctl = w5p->hcsw.Rctl;
|
|
||||||
Type = w5p->hcsw.Type;
|
|
||||||
|
|
||||||
/* Firmware Workaround */
|
|
||||||
if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
|
|
||||||
(irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
|
|
||||||
irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
|
|
||||||
Rctl = FC_ELS_REQ;
|
|
||||||
Type = FC_ELS_DATA;
|
|
||||||
w5p->hcsw.Rctl = Rctl;
|
|
||||||
w5p->hcsw.Type = Type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
|
||||||
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) {
|
if (irsp->ulpBdeCount != 0) {
|
||||||
saveq->context2 = lpfc_sli_get_buff(phba, pring,
|
saveq->context2 = lpfc_sli_get_buff(phba, pring,
|
||||||
irsp->un.ulpWord[3]);
|
irsp->un.ulpWord[3]);
|
||||||
|
@ -1011,7 +984,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
"an unsolicited iocb. tag 0x%x\n",
|
"an unsolicited iocb. tag 0x%x\n",
|
||||||
pring->ringno,
|
pring->ringno,
|
||||||
irsp->un.ulpWord[3]);
|
irsp->un.ulpWord[3]);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (irsp->ulpBdeCount == 2) {
|
if (irsp->ulpBdeCount == 2) {
|
||||||
saveq->context3 = lpfc_sli_get_buff(phba, pring,
|
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,
|
||||||
irsp->unsli3.sli3Words[7]);
|
irsp->unsli3.sli3Words[7]);
|
||||||
}
|
}
|
||||||
list_for_each_entry(iocbq, &saveq->list, list) {
|
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);
|
irsp = &(iocbq->iocb);
|
||||||
|
|
||||||
if (irsp->ulpBdeCount != 0) {
|
if (irsp->ulpBdeCount != 0) {
|
||||||
iocbq->context2 = lpfc_sli_get_buff(phba, pring,
|
iocbq->context2 = lpfc_sli_get_buff(phba, pring,
|
||||||
irsp->un.ulpWord[3]);
|
irsp->un.ulpWord[3]);
|
||||||
if (!saveq->context2)
|
if (!iocbq->context2)
|
||||||
lpfc_printf_log(phba,
|
lpfc_printf_log(phba,
|
||||||
KERN_ERR,
|
KERN_ERR,
|
||||||
LOG_SLI,
|
LOG_SLI,
|
||||||
|
@ -1047,7 +1014,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
if (irsp->ulpBdeCount == 2) {
|
if (irsp->ulpBdeCount == 2) {
|
||||||
iocbq->context3 = lpfc_sli_get_buff(phba, pring,
|
iocbq->context3 = lpfc_sli_get_buff(phba, pring,
|
||||||
irsp->unsli3.sli3Words[7]);
|
irsp->unsli3.sli3Words[7]);
|
||||||
if (!saveq->context3)
|
if (!iocbq->context3)
|
||||||
lpfc_printf_log(phba,
|
lpfc_printf_log(phba,
|
||||||
KERN_ERR,
|
KERN_ERR,
|
||||||
LOG_SLI,
|
LOG_SLI,
|
||||||
|
@ -1059,6 +1026,49 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (irsp->ulpBdeCount != 0 &&
|
||||||
|
(irsp->ulpCommand == CMD_IOCB_RCV_CONT64_CX ||
|
||||||
|
irsp->ulpStatus == IOSTAT_INTERMED_RSP)) {
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
/* search continue save q for same XRI */
|
||||||
|
list_for_each_entry(iocbq, &pring->iocb_continue_saveq, clist) {
|
||||||
|
if (iocbq->iocb.ulpContext == saveq->iocb.ulpContext) {
|
||||||
|
list_add_tail(&saveq->list, &iocbq->list);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
list_add_tail(&saveq->clist,
|
||||||
|
&pring->iocb_continue_saveq);
|
||||||
|
if (saveq->iocb.ulpStatus != IOSTAT_INTERMED_RSP) {
|
||||||
|
list_del_init(&iocbq->clist);
|
||||||
|
saveq = iocbq;
|
||||||
|
irsp = &(saveq->iocb);
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((irsp->ulpCommand == CMD_RCV_ELS_REQ64_CX) ||
|
||||||
|
(irsp->ulpCommand == CMD_RCV_ELS_REQ_CX) ||
|
||||||
|
(irsp->ulpCommand == CMD_IOCB_RCV_ELS64_CX)) {
|
||||||
|
Rctl = FC_ELS_REQ;
|
||||||
|
Type = FC_ELS_DATA;
|
||||||
|
} else {
|
||||||
|
w5p = (WORD5 *)&(saveq->iocb.un.ulpWord[5]);
|
||||||
|
Rctl = w5p->hcsw.Rctl;
|
||||||
|
Type = w5p->hcsw.Type;
|
||||||
|
|
||||||
|
/* Firmware Workaround */
|
||||||
|
if ((Rctl == 0) && (pring->ringno == LPFC_ELS_RING) &&
|
||||||
|
(irsp->ulpCommand == CMD_RCV_SEQUENCE64_CX ||
|
||||||
|
irsp->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
|
||||||
|
Rctl = FC_ELS_REQ;
|
||||||
|
Type = FC_ELS_DATA;
|
||||||
|
w5p->hcsw.Rctl = Rctl;
|
||||||
|
w5p->hcsw.Type = Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* unSolicited Responses */
|
/* unSolicited Responses */
|
||||||
if (pring->prt[0].profile) {
|
if (pring->prt[0].profile) {
|
||||||
|
@ -1069,12 +1079,9 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
|
||||||
} else {
|
} else {
|
||||||
/* We must search, based on rctl / type
|
/* We must search, based on rctl / type
|
||||||
for the right routine */
|
for the right routine */
|
||||||
for (i = 0; i < pring->num_mask;
|
for (i = 0; i < pring->num_mask; i++) {
|
||||||
i++) {
|
if ((pring->prt[i].rctl == Rctl)
|
||||||
if ((pring->prt[i].rctl ==
|
&& (pring->prt[i].type == Type)) {
|
||||||
Rctl)
|
|
||||||
&& (pring->prt[i].
|
|
||||||
type == Type)) {
|
|
||||||
if (pring->prt[i].lpfc_sli_rcv_unsol_event)
|
if (pring->prt[i].lpfc_sli_rcv_unsol_event)
|
||||||
(pring->prt[i].lpfc_sli_rcv_unsol_event)
|
(pring->prt[i].lpfc_sli_rcv_unsol_event)
|
||||||
(phba, pring, saveq);
|
(phba, pring, saveq);
|
||||||
|
@ -1641,12 +1648,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
|
||||||
|
|
||||||
writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
|
writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
|
||||||
|
|
||||||
if (list_empty(&(pring->iocb_continueq))) {
|
list_add_tail(&rspiocbp->list, &(pring->iocb_continueq));
|
||||||
list_add(&rspiocbp->list, &(pring->iocb_continueq));
|
|
||||||
} else {
|
|
||||||
list_add_tail(&rspiocbp->list,
|
|
||||||
&(pring->iocb_continueq));
|
|
||||||
}
|
|
||||||
|
|
||||||
pring->iocb_continueq_cnt++;
|
pring->iocb_continueq_cnt++;
|
||||||
if (irsp->ulpLe) {
|
if (irsp->ulpLe) {
|
||||||
|
@ -1711,17 +1713,17 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
|
||||||
iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK;
|
iocb_cmd_type = irsp->ulpCommand & CMD_IOCB_MASK;
|
||||||
type = lpfc_sli_iocb_cmd_type(iocb_cmd_type);
|
type = lpfc_sli_iocb_cmd_type(iocb_cmd_type);
|
||||||
if (type == LPFC_SOL_IOCB) {
|
if (type == LPFC_SOL_IOCB) {
|
||||||
spin_unlock_irqrestore(&phba->hbalock,
|
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||||
iflag);
|
|
||||||
rc = lpfc_sli_process_sol_iocb(phba, pring,
|
rc = lpfc_sli_process_sol_iocb(phba, pring,
|
||||||
saveq);
|
saveq);
|
||||||
spin_lock_irqsave(&phba->hbalock, iflag);
|
spin_lock_irqsave(&phba->hbalock, iflag);
|
||||||
} else if (type == LPFC_UNSOL_IOCB) {
|
} else if (type == LPFC_UNSOL_IOCB) {
|
||||||
spin_unlock_irqrestore(&phba->hbalock,
|
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||||
iflag);
|
|
||||||
rc = lpfc_sli_process_unsol_iocb(phba, pring,
|
rc = lpfc_sli_process_unsol_iocb(phba, pring,
|
||||||
saveq);
|
saveq);
|
||||||
spin_lock_irqsave(&phba->hbalock, iflag);
|
spin_lock_irqsave(&phba->hbalock, iflag);
|
||||||
|
if (!rc)
|
||||||
|
free_saveq = 0;
|
||||||
} else if (type == LPFC_ABORT_IOCB) {
|
} else if (type == LPFC_ABORT_IOCB) {
|
||||||
if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
|
if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
|
||||||
((cmdiocbp =
|
((cmdiocbp =
|
||||||
|
@ -3238,6 +3240,7 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba)
|
||||||
INIT_LIST_HEAD(&pring->txq);
|
INIT_LIST_HEAD(&pring->txq);
|
||||||
INIT_LIST_HEAD(&pring->txcmplq);
|
INIT_LIST_HEAD(&pring->txcmplq);
|
||||||
INIT_LIST_HEAD(&pring->iocb_continueq);
|
INIT_LIST_HEAD(&pring->iocb_continueq);
|
||||||
|
INIT_LIST_HEAD(&pring->iocb_continue_saveq);
|
||||||
INIT_LIST_HEAD(&pring->postbufq);
|
INIT_LIST_HEAD(&pring->postbufq);
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef enum _lpfc_ctx_cmd {
|
||||||
struct lpfc_iocbq {
|
struct lpfc_iocbq {
|
||||||
/* lpfc_iocbqs are used in double linked lists */
|
/* lpfc_iocbqs are used in double linked lists */
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct list_head clist;
|
||||||
uint16_t iotag; /* pre-assigned IO tag */
|
uint16_t iotag; /* pre-assigned IO tag */
|
||||||
uint16_t rsvd1;
|
uint16_t rsvd1;
|
||||||
|
|
||||||
|
@ -160,6 +161,7 @@ struct lpfc_sli_ring {
|
||||||
struct list_head iocb_continueq;
|
struct list_head iocb_continueq;
|
||||||
uint16_t iocb_continueq_cnt; /* current length of queue */
|
uint16_t iocb_continueq_cnt; /* current length of queue */
|
||||||
uint16_t iocb_continueq_max; /* max length */
|
uint16_t iocb_continueq_max; /* max length */
|
||||||
|
struct list_head iocb_continue_saveq;
|
||||||
|
|
||||||
struct lpfc_sli_ring_mask prt[LPFC_MAX_RING_MASK];
|
struct lpfc_sli_ring_mask prt[LPFC_MAX_RING_MASK];
|
||||||
uint32_t num_mask; /* number of mask entries in prt array */
|
uint32_t num_mask; /* number of mask entries in prt array */
|
||||||
|
|
Loading…
Reference in a new issue