]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_sli.c
[SCSI] lpfc 8.1.2: Explicitly initialize the skip_post argument to lpfc_sli_send_reset
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_sli.c
index e74e224fd77c2ddb7323fcc57796918a826fda9b..cb4ccbba0652ab3e0f96e10ae0904523830d0d97 100644 (file)
@@ -65,6 +65,28 @@ typedef enum _lpfc_iocb_type {
        LPFC_ABORT_IOCB
 } lpfc_iocb_type;
 
+struct lpfc_iocbq *
+lpfc_sli_get_iocbq(struct lpfc_hba * phba)
+{
+       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+       struct lpfc_iocbq * iocbq = NULL;
+
+       list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list);
+       return iocbq;
+}
+
+void
+lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
+{
+       size_t start_clean = (size_t)(&((struct lpfc_iocbq *)NULL)->iocb);
+
+       /*
+        * Clean all volatile data fields, preserve iotag and node struct.
+        */
+       memset((char*)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean);
+       list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
+}
+
 /*
  * Translate the iocb command to an iocb command type used to decide the final
  * disposition of each completed IOCB.
@@ -265,41 +287,69 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
        return iocb;
 }
 
-static uint32_t
-lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_sli_ring * pring)
+uint16_t
+lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocbq)
 {
-       uint32_t search_start;
+       struct lpfc_iocbq ** new_arr;
+       struct lpfc_iocbq ** old_arr;
+       size_t new_len;
+       struct lpfc_sli *psli = &phba->sli;
+       uint16_t iotag;
 
-       if (pring->fast_lookup == NULL) {
-               pring->iotag_ctr++;
-               if (pring->iotag_ctr >= pring->iotag_max)
-                       pring->iotag_ctr = 1;
-               return pring->iotag_ctr;
+       spin_lock_irq(phba->host->host_lock);
+       iotag = psli->last_iotag;
+       if(++iotag < psli->iocbq_lookup_len) {
+               psli->last_iotag = iotag;
+               psli->iocbq_lookup[iotag] = iocbq;
+               spin_unlock_irq(phba->host->host_lock);
+               iocbq->iotag = iotag;
+               return iotag;
+       }
+       else if (psli->iocbq_lookup_len < (0xffff
+                                          - LPFC_IOCBQ_LOOKUP_INCREMENT)) {
+               new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT;
+               spin_unlock_irq(phba->host->host_lock);
+               new_arr = kmalloc(new_len * sizeof (struct lpfc_iocbq *),
+                                 GFP_KERNEL);
+               if (new_arr) {
+                       memset((char *)new_arr, 0,
+                              new_len * sizeof (struct lpfc_iocbq *));
+                       spin_lock_irq(phba->host->host_lock);
+                       old_arr = psli->iocbq_lookup;
+                       if (new_len <= psli->iocbq_lookup_len) {
+                               /* highly unprobable case */
+                               kfree(new_arr);
+                               iotag = psli->last_iotag;
+                               if(++iotag < psli->iocbq_lookup_len) {
+                                       psli->last_iotag = iotag;
+                                       psli->iocbq_lookup[iotag] = iocbq;
+                                       spin_unlock_irq(phba->host->host_lock);
+                                       iocbq->iotag = iotag;
+                                       return iotag;
+                               }
+                               spin_unlock_irq(phba->host->host_lock);
+                               return 0;
+                       }
+                       if (psli->iocbq_lookup)
+                               memcpy(new_arr, old_arr,
+                                      ((psli->last_iotag  + 1) *
+                                       sizeof (struct lpfc_iocbq *)));
+                       psli->iocbq_lookup = new_arr;
+                       psli->iocbq_lookup_len = new_len;
+                       psli->last_iotag = iotag;
+                       psli->iocbq_lookup[iotag] = iocbq;
+                       spin_unlock_irq(phba->host->host_lock);
+                       iocbq->iotag = iotag;
+                       kfree(old_arr);
+                       return iotag;
+               }
        }
 
-       search_start = pring->iotag_ctr;
-
-       do {
-               pring->iotag_ctr++;
-               if (pring->iotag_ctr >= pring->fast_iotag)
-                       pring->iotag_ctr = 1;
-
-               if (*(pring->fast_lookup + pring->iotag_ctr) == NULL)
-                       return pring->iotag_ctr;
-
-       } while (pring->iotag_ctr != search_start);
+       lpfc_printf_log(phba, KERN_ERR,LOG_SLI,
+                       "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n",
+                       phba->brd_no, psli->last_iotag);
 
-       /*
-        * Outstanding I/O count for ring <ringno> is at max <fast_iotag>
-        */
-       lpfc_printf_log(phba,
-               KERN_ERR,
-               LOG_SLI,
-               "%d:0318 Outstanding I/O count for ring %d is at max x%x\n",
-               phba->brd_no,
-               pring->ringno,
-               pring->fast_iotag);
-       return (0);
+       return 0;
 }
 
 static void
@@ -307,10 +357,9 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                IOCB_t *iocb, struct lpfc_iocbq *nextiocb)
 {
        /*
-        * Allocate and set up an iotag
+        * Set up an iotag
         */
-       nextiocb->iocb.ulpIoTag =
-               lpfc_sli_next_iotag(phba, &phba->sli.ring[phba->sli.fcp_ring]);
+       nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0;
 
        /*
         * Issue iocb command to adapter
@@ -326,16 +375,15 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
         */
        if (nextiocb->iocb_cmpl)
                lpfc_sli_ringtxcmpl_put(phba, pring, nextiocb);
-       else {
-               list_add_tail(&nextiocb->list, &phba->lpfc_iocb_list);
-       }
+       else
+               lpfc_sli_release_iocbq(phba, nextiocb);
 
        /*
         * Let the HBA know what IOCB slot will be the next one the
         * driver will put a command into.
         */
        pring->cmdidx = pring->next_cmdidx;
-       writeb(pring->cmdidx, phba->MBslimaddr
+       writel(pring->cmdidx, phba->MBslimaddr
               + (SLIMOFF + (pring->ringno * 2)) * 4);
 }
 
@@ -752,80 +800,28 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 }
 
 static struct lpfc_iocbq *
-lpfc_sli_txcmpl_ring_search_slow(struct lpfc_sli_ring * pring,
-                                struct lpfc_iocbq * prspiocb)
-{
-       IOCB_t *icmd = NULL;
-       IOCB_t *irsp = NULL;
-       struct lpfc_iocbq *cmd_iocb;
-       struct lpfc_iocbq *iocb, *next_iocb;
-       uint16_t iotag;
-
-       irsp = &prspiocb->iocb;
-       iotag = irsp->ulpIoTag;
-       cmd_iocb = NULL;
-
-       /* Search through txcmpl from the begining */
-       list_for_each_entry_safe(iocb, next_iocb, &(pring->txcmplq), list) {
-               icmd = &iocb->iocb;
-               if (iotag == icmd->ulpIoTag) {
-                       /* Found a match.  */
-                       cmd_iocb = iocb;
-                       list_del(&iocb->list);
-                       pring->txcmplq_cnt--;
-                       break;
-               }
-       }
-
-       return (cmd_iocb);
-}
-
-static struct lpfc_iocbq *
-lpfc_sli_txcmpl_ring_iotag_lookup(struct lpfc_hba * phba,
-                       struct lpfc_sli_ring * pring,
-                       struct lpfc_iocbq * prspiocb)
+lpfc_sli_iocbq_lookup(struct lpfc_hba * phba,
+                     struct lpfc_sli_ring * pring,
+                     struct lpfc_iocbq * prspiocb)
 {
-       IOCB_t *irsp = NULL;
        struct lpfc_iocbq *cmd_iocb = NULL;
        uint16_t iotag;
 
-       if (unlikely(pring->fast_lookup == NULL))
-               return NULL;
-
-       /* Use fast lookup based on iotag for completion */
-       irsp = &prspiocb->iocb;
-       iotag = irsp->ulpIoTag;
-       if (iotag < pring->fast_iotag) {
-               cmd_iocb = *(pring->fast_lookup + iotag);
-               *(pring->fast_lookup + iotag) = NULL;
-               if (cmd_iocb) {
-                       list_del(&cmd_iocb->list);
-                       pring->txcmplq_cnt--;
-                       return cmd_iocb;
-               } else {
-                       /*
-                        * This is clearly an error.  A ring that uses iotags
-                        * should never have a interrupt for a completion that
-                        * is not on the ring.  Return NULL and log a error.
-                        */
-                       lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                               "%d:0327 Rsp ring %d error -  command "
-                               "completion for iotag x%x not found\n",
-                               phba->brd_no, pring->ringno, iotag);
-                       return NULL;
-               }
+       iotag = prspiocb->iocb.ulpIoTag;
+
+       if (iotag != 0 && iotag <= phba->sli.last_iotag) {
+               cmd_iocb = phba->sli.iocbq_lookup[iotag];
+               list_del(&cmd_iocb->list);
+               pring->txcmplq_cnt--;
+               return cmd_iocb;
        }
 
-       /*
-        * Rsp ring <ringno> get: iotag <iotag> greater then
-        * configured max <fast_iotag> wd0 <irsp>.  This is an
-        * error.  Just return NULL.
-        */
        lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                       "%d:0317 Rsp ring %d get: iotag x%x greater then "
-                       "configured max x%x wd0 x%x\n",
-                       phba->brd_no, pring->ringno, iotag, pring->fast_iotag,
-                       *(((uint32_t *) irsp) + 7));
+                       "%d:0317 iotag x%x is out off "
+                       "range: max iotag x%x wd0 x%x\n",
+                       phba->brd_no, iotag,
+                       phba->sli.last_iotag,
+                       *(((uint32_t *) &prspiocb->iocb) + 7));
        return NULL;
 }
 
@@ -839,7 +835,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
 
        /* Based on the iotag field, get the cmd IOCB from the txcmplq */
        spin_lock_irqsave(phba->host->host_lock, iflag);
-       cmdiocbp = lpfc_sli_txcmpl_ring_search_slow(pring, saveq);
+       cmdiocbp = lpfc_sli_iocbq_lookup(phba, pring, saveq);
        if (cmdiocbp) {
                if (cmdiocbp->iocb_cmpl) {
                        /*
@@ -853,17 +849,13 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
                                spin_lock_irqsave(phba->host->host_lock, iflag);
                        }
                        else {
-                               if (cmdiocbp->iocb_flag & LPFC_IO_POLL)
-                                       rc = 0;
-
                                spin_unlock_irqrestore(phba->host->host_lock,
                                                       iflag);
                                (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq);
                                spin_lock_irqsave(phba->host->host_lock, iflag);
                        }
-               } else {
-                       list_add_tail(&cmdiocbp->list, &phba->lpfc_iocb_list);
-               }
+               } else
+                       lpfc_sli_release_iocbq(phba, cmdiocbp);
        } else {
                /*
                 * Unknown initiating command based on the response iotag.
@@ -889,10 +881,187 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring,
                                saveq->iocb.ulpContext);
                }
        }
+
        spin_unlock_irqrestore(phba->host->host_lock, iflag);
        return rc;
 }
 
+static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
+                                       struct lpfc_sli_ring * pring)
+{
+       struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
+       /*
+        * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
+        * rsp ring <portRspMax>
+        */
+       lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                       "%d:0312 Ring %d handler: portRspPut %d "
+                       "is bigger then rsp ring %d\n",
+                       phba->brd_no, pring->ringno,
+                       le32_to_cpu(pgp->rspPutInx),
+                       pring->numRiocb);
+
+       phba->hba_state = LPFC_HBA_ERROR;
+
+       /*
+        * All error attention handlers are posted to
+        * worker thread
+        */
+       phba->work_ha |= HA_ERATT;
+       phba->work_hs = HS_FFER3;
+       if (phba->work_wait)
+               wake_up(phba->work_wait);
+
+       return;
+}
+
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
+{
+       struct lpfc_sli      * psli   = &phba->sli;
+       struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING];
+       IOCB_t *irsp = NULL;
+       IOCB_t *entry = NULL;
+       struct lpfc_iocbq *cmdiocbq = NULL;
+       struct lpfc_iocbq rspiocbq;
+       struct lpfc_pgp *pgp;
+       uint32_t status;
+       uint32_t portRspPut, portRspMax;
+       int type;
+       uint32_t rsp_cmpl = 0;
+       void __iomem *to_slim;
+       uint32_t ha_copy;
+
+       pring->stats.iocb_event++;
+
+       /* The driver assumes SLI-2 mode */
+       pgp =  &phba->slim2p->mbx.us.s2.port[pring->ringno];
+
+       /*
+        * The next available response entry should never exceed the maximum
+        * entries.  If it does, treat it as an adapter hardware error.
+        */
+       portRspMax = pring->numRiocb;
+       portRspPut = le32_to_cpu(pgp->rspPutInx);
+       if (unlikely(portRspPut >= portRspMax)) {
+               lpfc_sli_rsp_pointers_error(phba, pring);
+               return;
+       }
+
+       rmb();
+       while (pring->rspidx != portRspPut) {
+
+               entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+               if (++pring->rspidx >= portRspMax)
+                       pring->rspidx = 0;
+
+               lpfc_sli_pcimem_bcopy((uint32_t *) entry,
+                                     (uint32_t *) &rspiocbq.iocb,
+                                     sizeof (IOCB_t));
+               irsp = &rspiocbq.iocb;
+               type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
+               pring->stats.iocb_rsp++;
+               rsp_cmpl++;
+
+               if (unlikely(irsp->ulpStatus)) {
+                       /* Rsp ring <ringno> error: IOCB */
+                       lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+                                       "%d:0326 Rsp Ring %d error: IOCB Data: "
+                                       "x%x x%x x%x x%x x%x x%x x%x x%x\n",
+                                       phba->brd_no, pring->ringno,
+                                       irsp->un.ulpWord[0],
+                                       irsp->un.ulpWord[1],
+                                       irsp->un.ulpWord[2],
+                                       irsp->un.ulpWord[3],
+                                       irsp->un.ulpWord[4],
+                                       irsp->un.ulpWord[5],
+                                       *(((uint32_t *) irsp) + 6),
+                                       *(((uint32_t *) irsp) + 7));
+               }
+
+               switch (type) {
+               case LPFC_ABORT_IOCB:
+               case LPFC_SOL_IOCB:
+                       /*
+                        * Idle exchange closed via ABTS from port.  No iocb
+                        * resources need to be recovered.
+                        */
+                       if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
+                               printk(KERN_INFO "%s: IOCB cmd 0x%x processed."
+                                      " Skipping completion\n", __FUNCTION__,
+                                      irsp->ulpCommand);
+                               break;
+                       }
+
+                       cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+                                                        &rspiocbq);
+                       if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
+                               (cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+                                                     &rspiocbq);
+                       }
+                       break;
+               default:
+                       if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
+                               char adaptermsg[LPFC_MAX_ADPTMSG];
+                               memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
+                               memcpy(&adaptermsg[0], (uint8_t *) irsp,
+                                      MAX_MSG_DATA);
+                               dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+                                        phba->brd_no, adaptermsg);
+                       } else {
+                               /* Unknown IOCB command */
+                               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                                               "%d:0321 Unknown IOCB command "
+                                               "Data: x%x, x%x x%x x%x x%x\n",
+                                               phba->brd_no, type,
+                                               irsp->ulpCommand,
+                                               irsp->ulpStatus,
+                                               irsp->ulpIoTag,
+                                               irsp->ulpContext);
+                       }
+                       break;
+               }
+
+               /*
+                * The response IOCB has been processed.  Update the ring
+                * pointer in SLIM.  If the port response put pointer has not
+                * been updated, sync the pgp->rspPutInx and fetch the new port
+                * response put pointer.
+                */
+               to_slim = phba->MBslimaddr +
+                       (SLIMOFF + (pring->ringno * 2) + 1) * 4;
+               writeb(pring->rspidx, to_slim);
+
+               if (pring->rspidx == portRspPut)
+                       portRspPut = le32_to_cpu(pgp->rspPutInx);
+       }
+
+       ha_copy = readl(phba->HAregaddr);
+       ha_copy >>= (LPFC_FCP_RING * 4);
+
+       if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
+               pring->stats.iocb_rsp_full++;
+               status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
+               writel(status, phba->CAregaddr);
+               readl(phba->CAregaddr);
+       }
+       if ((ha_copy & HA_R0CE_RSP) &&
+           (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
+               pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
+               pring->stats.iocb_cmd_empty++;
+
+               /* Force update of the local copy of cmdGetInx */
+               pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+               lpfc_sli_resume_iocb(phba, pring);
+
+               if ((pring->lpfc_sli_cmd_available))
+                       (pring->lpfc_sli_cmd_available) (phba, pring);
+
+       }
+
+       return;
+}
+
 /*
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
  * to check it explicitly.
@@ -924,24 +1093,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
        portRspMax = pring->numRiocb;
        portRspPut = le32_to_cpu(pgp->rspPutInx);
        if (unlikely(portRspPut >= portRspMax)) {
-               /*
-                * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
-                * rsp ring <portRspMax>
-                */
-               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-                               "%d:0312 Ring %d handler: portRspPut %d "
-                               "is bigger then rsp ring %d\n",
-                               phba->brd_no, pring->ringno, portRspPut,
-                               portRspMax);
-
-               phba->hba_state = LPFC_HBA_ERROR;
-
-               /* All error attention handlers are posted to worker thread */
-               phba->work_ha |= HA_ERATT;
-               phba->work_hs = HS_FFER3;
-               if (phba->work_wait)
-                       wake_up(phba->work_wait);
-
+               lpfc_sli_rsp_pointers_error(phba, pring);
                spin_unlock_irqrestore(phba->host->host_lock, iflag);
                return 1;
        }
@@ -953,7 +1105,11 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                 * structure.  The copy involves a byte-swap since the
                 * network byte order and pci byte orders are different.
                 */
-               entry = (IOCB_t *) IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+               entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+               if (++pring->rspidx >= portRspMax)
+                       pring->rspidx = 0;
+
                lpfc_sli_pcimem_bcopy((uint32_t *) entry,
                                      (uint32_t *) &rspiocbq.iocb,
                                      sizeof (IOCB_t));
@@ -990,9 +1146,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                                break;
                        }
 
-                       cmdiocbq = lpfc_sli_txcmpl_ring_iotag_lookup(phba,
-                                                               pring,
-                                                               &rspiocbq);
+                       cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+                                                        &rspiocbq);
                        if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
                                spin_unlock_irqrestore(
                                       phba->host->host_lock, iflag);
@@ -1028,12 +1183,9 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
                 * been updated, sync the pgp->rspPutInx and fetch the new port
                 * response put pointer.
                 */
-               if (++pring->rspidx >= portRspMax)
-                       pring->rspidx = 0;
-
                to_slim = phba->MBslimaddr +
                        (SLIMOFF + (pring->ringno * 2) + 1) * 4;
-               writeb(pring->rspidx, to_slim);
+               writel(pring->rspidx, to_slim);
 
                if (pring->rspidx == portRspPut)
                        portRspPut = le32_to_cpu(pgp->rspPutInx);
@@ -1073,7 +1225,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
        struct lpfc_iocbq *next_iocb;
        struct lpfc_iocbq *cmdiocbp;
        struct lpfc_iocbq *saveq;
-       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
        struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
        uint8_t iocb_cmd_type;
        lpfc_iocb_type type;
@@ -1115,7 +1266,6 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
        }
 
        rmb();
-       lpfc_iocb_list = &phba->lpfc_iocb_list;
        while (pring->rspidx != portRspPut) {
                /*
                 * Build a completion list and call the appropriate handler.
@@ -1131,8 +1281,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
                 * received.
                 */
                entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
-               list_remove_head(lpfc_iocb_list, rspiocbp, struct lpfc_iocbq,
-                                list);
+               rspiocbp = lpfc_sli_get_iocbq(phba);
                if (rspiocbp == NULL) {
                        printk(KERN_ERR "%s: out of buffers! Failing "
                               "completion.\n", __FUNCTION__);
@@ -1147,7 +1296,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
 
                to_slim = phba->MBslimaddr + (SLIMOFF + (pring->ringno * 2)
                                              + 1) * 4;
-               writeb(pring->rspidx, to_slim);
+               writel(pring->rspidx, to_slim);
 
                if (list_empty(&(pring->iocb_continueq))) {
                        list_add(&rspiocbp->list, &(pring->iocb_continueq));
@@ -1213,8 +1362,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
                        } else if (type == LPFC_ABORT_IOCB) {
                                if ((irsp->ulpCommand != CMD_XRI_ABORTED_CX) &&
                                    ((cmdiocbp =
-                                     lpfc_sli_txcmpl_ring_search_slow(pring,
-                                               saveq)))) {
+                                     lpfc_sli_iocbq_lookup(phba, pring,
+                                                           saveq)))) {
                                        /* Call the specified completion
                                           routine */
                                        if (cmdiocbp->iocb_cmpl) {
@@ -1226,10 +1375,9 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
                                                spin_lock_irqsave(
                                                          phba->host->host_lock,
                                                          iflag);
-                                       } else {
-                                               list_add_tail(&cmdiocbp->list,
-                                                               lpfc_iocb_list);
-                                       }
+                                       } else
+                                               lpfc_sli_release_iocbq(phba,
+                                                                     cmdiocbp);
                                }
                        } else if (type == LPFC_UNKNOWN_IOCB) {
                                if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
@@ -1264,12 +1412,12 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba,
                                                                 next_iocb,
                                                                 &saveq->list,
                                                                 list) {
-                                               list_add_tail(&rspiocbp->list,
-                                                             lpfc_iocb_list);
+                                               lpfc_sli_release_iocbq(phba,
+                                                                    rspiocbp);
                                        }
                                }
 
-                               list_add_tail(&saveq->list, lpfc_iocb_list);
+                               lpfc_sli_release_iocbq(phba, saveq);
                        }
                }
 
@@ -1314,7 +1462,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
        struct lpfc_iocbq *iocb, *next_iocb;
        IOCB_t *icmd = NULL, *cmd = NULL;
        int errcnt;
-       uint16_t iotag;
 
        errcnt = 0;
 
@@ -1331,9 +1478,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
                        spin_unlock_irq(phba->host->host_lock);
                        (iocb->iocb_cmpl) (phba, iocb, iocb);
                        spin_lock_irq(phba->host->host_lock);
-               } else {
-                       list_add_tail(&iocb->list, &phba->lpfc_iocb_list);
-               }
+               } else
+                       lpfc_sli_release_iocbq(phba, iocb);
        }
        pring->txq_cnt = 0;
        INIT_LIST_HEAD(&(pring->txq));
@@ -1343,13 +1489,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
                cmd = &iocb->iocb;
 
                /*
-                * Imediate abort of IOCB, clear fast_lookup entry,
-                * if any, deque and call compl
+                * Imediate abort of IOCB, deque and call compl
                 */
-               iotag = cmd->ulpIoTag;
-               if (iotag && pring->fast_lookup &&
-                   (iotag < pring->fast_iotag))
-                       pring->fast_lookup[iotag] = NULL;
 
                list_del_init(&iocb->list);
                pring->txcmplq_cnt--;
@@ -1360,9 +1501,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
                        spin_unlock_irq(phba->host->host_lock);
                        (iocb->iocb_cmpl) (phba, iocb, iocb);
                        spin_lock_irq(phba->host->host_lock);
-               } else {
-                       list_add_tail(&iocb->list, &phba->lpfc_iocb_list);
-               }
+               } else
+                       lpfc_sli_release_iocbq(phba, iocb);
        }
 
        INIT_LIST_HEAD(&pring->txcmplq);
@@ -2097,16 +2237,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                   !(phba->sli.sli_flag & LPFC_PROCESS_LA)))
                goto iocb_busy;
 
-       /*
-        * Check to see if this is a high priority command.
-        * If so bypass tx queue processing.
-        */
-       if (unlikely((flag & SLI_IOCB_HIGH_PRIORITY) &&
-                    (iocb = lpfc_sli_next_iocb_slot(phba, pring)))) {
-               lpfc_sli_submit_iocb(phba, pring, iocb, piocb);
-               piocb = NULL;
-       }
-
        while ((iocb = lpfc_sli_next_iocb_slot(phba, pring)) &&
               (nextiocb = lpfc_sli_next_iocb(phba, pring, &piocb)))
                lpfc_sli_submit_iocb(phba, pring, iocb, nextiocb);
@@ -2147,6 +2277,10 @@ lpfc_sli_setup(struct lpfc_hba *phba)
        psli->next_ring = LPFC_FCP_NEXT_RING;
        psli->ip_ring = LPFC_IP_RING;
 
+       psli->iocbq_lookup = NULL;
+       psli->iocbq_lookup_len = 0;
+       psli->last_iotag = 0;
+
        for (i = 0; i < psli->num_rings; i++) {
                pring = &psli->ring[i];
                switch (i) {
@@ -2222,7 +2356,7 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
 {
        struct lpfc_sli *psli;
        struct lpfc_sli_ring *pring;
-       int i, cnt;
+       int i;
 
        psli = &phba->sli;
        spin_lock_irq(phba->host->host_lock);
@@ -2238,19 +2372,6 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba)
                INIT_LIST_HEAD(&pring->txcmplq);
                INIT_LIST_HEAD(&pring->iocb_continueq);
                INIT_LIST_HEAD(&pring->postbufq);
-               cnt = pring->fast_iotag;
-               spin_unlock_irq(phba->host->host_lock);
-               if (cnt) {
-                       pring->fast_lookup =
-                               kmalloc(cnt * sizeof (struct lpfc_iocbq *),
-                                       GFP_KERNEL);
-                       if (pring->fast_lookup == 0) {
-                               return (0);
-                       }
-                       memset((char *)pring->fast_lookup, 0,
-                              cnt * sizeof (struct lpfc_iocbq *));
-               }
-               spin_lock_irq(phba->host->host_lock);
        }
        spin_unlock_irq(phba->host->host_lock);
        return (1);
@@ -2292,19 +2413,14 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
                                                       flags);
                                (iocb->iocb_cmpl) (phba, iocb, iocb);
                                spin_lock_irqsave(phba->host->host_lock, flags);
-                       } else {
-                               list_add_tail(&iocb->list,
-                                             &phba->lpfc_iocb_list);
-                       }
+                       } else
+                               lpfc_sli_release_iocbq(phba, iocb);
                }
 
                INIT_LIST_HEAD(&(pring->txq));
 
-               if (pring->fast_lookup) {
-                       kfree(pring->fast_lookup);
-                       pring->fast_lookup = NULL;
-               }
-
+               kfree(pring->fast_lookup);
+               pring->fast_lookup = NULL;
        }
 
        spin_unlock_irqrestore(phba->host->host_lock, flags);
@@ -2436,7 +2552,7 @@ lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                kfree(buf_ptr);
        }
 
-       list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+       lpfc_sli_release_iocbq(phba, cmdiocb);
        return;
 }
 
@@ -2445,16 +2561,14 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
                             struct lpfc_sli_ring * pring,
                             struct lpfc_iocbq * cmdiocb)
 {
-       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
-       struct lpfc_iocbq *abtsiocbp = NULL;
+       struct lpfc_iocbq *abtsiocbp;
        IOCB_t *icmd = NULL;
        IOCB_t *iabt = NULL;
 
        /* issue ABTS for this IOCB based on iotag */
-       list_remove_head(lpfc_iocb_list, abtsiocbp, struct lpfc_iocbq, list);
+       abtsiocbp = lpfc_sli_get_iocbq(phba);
        if (abtsiocbp == NULL)
                return 0;
-       memset(abtsiocbp, 0, sizeof (struct lpfc_iocbq));
 
        iabt = &abtsiocbp->iocb;
        icmd = &cmdiocb->iocb;
@@ -2473,7 +2587,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
                abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl;
                break;
        default:
-               list_add_tail(&abtsiocbp->list, lpfc_iocb_list);
+               lpfc_sli_release_iocbq(phba, abtsiocbp);
                return 0;
        }
 
@@ -2485,7 +2599,7 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
        iabt->ulpCommand = CMD_ABORT_MXRI64_CN;
 
        if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) {
-               list_add_tail(&abtsiocbp->list, lpfc_iocb_list);
+               lpfc_sli_release_iocbq(phba, abtsiocbp);
                return 0;
        }
 
@@ -2493,28 +2607,37 @@ lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba,
 }
 
 static int
-lpfc_sli_validate_iocb_cmd(struct lpfc_scsi_buf *lpfc_cmd, uint16_t tgt_id,
-                            uint64_t lun_id, struct lpfc_iocbq *iocb,
-                            uint32_t ctx, lpfc_ctx_cmd ctx_cmd)
+lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id,
+                          uint64_t lun_id, uint32_t ctx,
+                          lpfc_ctx_cmd ctx_cmd)
 {
+       struct lpfc_scsi_buf *lpfc_cmd;
+       struct scsi_cmnd *cmnd;
        int rc = 1;
 
-       if (lpfc_cmd == NULL)
+       if (!(iocbq->iocb_flag &  LPFC_IO_FCP))
+               return rc;
+
+       lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
+       cmnd = lpfc_cmd->pCmd;
+
+       if (cmnd == NULL)
                return rc;
 
        switch (ctx_cmd) {
        case LPFC_CTX_LUN:
-               if ((lpfc_cmd->pCmd->device->id == tgt_id) &&
-                   (lpfc_cmd->pCmd->device->lun == lun_id))
+               if ((cmnd->device->id == tgt_id) &&
+                   (cmnd->device->lun == lun_id))
                        rc = 0;
                break;
        case LPFC_CTX_TGT:
-               if (lpfc_cmd->pCmd->device->id == tgt_id)
+               if (cmnd->device->id == tgt_id)
                        rc = 0;
                break;
        case LPFC_CTX_CTX:
-               if (iocb->iocb.ulpContext == ctx)
+               if (iocbq->iocb.ulpContext == ctx)
                        rc = 0;
+               break;
        case LPFC_CTX_HOST:
                rc = 0;
                break;
@@ -2531,30 +2654,17 @@ int
 lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd)
 {
-       struct lpfc_iocbq *iocb, *next_iocb;
-       IOCB_t *cmd = NULL;
-       struct lpfc_scsi_buf *lpfc_cmd;
-       int sum = 0, ret_val = 0;
+       struct lpfc_iocbq *iocbq;
+       int sum, i;
 
-       /* Next check the txcmplq */
-       list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
-               cmd = &iocb->iocb;
-
-               /* Must be a FCP command */
-               if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) &&
-                   (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) &&
-                   (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) {
-                       continue;
-               }
+       for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) {
+               iocbq = phba->sli.iocbq_lookup[i];
 
-               /* context1 MUST be a struct lpfc_scsi_buf */
-               lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1);
-               ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id,
-                                                    NULL, 0, ctx_cmd);
-               if (ret_val != 0)
-                       continue;
-               sum++;
+               if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
+                                               0, ctx_cmd) == 0)
+                       sum++;
        }
+
        return sum;
 }
 
@@ -2563,7 +2673,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                           struct lpfc_iocbq * rspiocb)
 {
        spin_lock_irq(phba->host->host_lock);
-       list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+       lpfc_sli_release_iocbq(phba, cmdiocb);
        spin_unlock_irq(phba->host->host_lock);
        return;
 }
@@ -2573,39 +2683,27 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                    uint16_t tgt_id, uint64_t lun_id, uint32_t ctx,
                    lpfc_ctx_cmd abort_cmd)
 {
-       struct lpfc_iocbq *iocb, *next_iocb;
-       struct lpfc_iocbq *abtsiocb = NULL;
-       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
+       struct lpfc_iocbq *iocbq;
+       struct lpfc_iocbq *abtsiocb;
        IOCB_t *cmd = NULL;
-       struct lpfc_scsi_buf *lpfc_cmd;
        int errcnt = 0, ret_val = 0;
+       int i;
 
-       list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
-               cmd = &iocb->iocb;
-
-               /* Must be a FCP command */
-               if ((cmd->ulpCommand != CMD_FCP_ICMND64_CR) &&
-                   (cmd->ulpCommand != CMD_FCP_IWRITE64_CR) &&
-                   (cmd->ulpCommand != CMD_FCP_IREAD64_CR)) {
-                       continue;
-               }
+       for (i = 1; i <= phba->sli.last_iotag; i++) {
+               iocbq = phba->sli.iocbq_lookup[i];
 
-               /* context1 MUST be a struct lpfc_scsi_buf */
-               lpfc_cmd = (struct lpfc_scsi_buf *) (iocb->context1);
-               ret_val = lpfc_sli_validate_iocb_cmd(lpfc_cmd, tgt_id, lun_id,
-                                                    iocb, ctx, abort_cmd);
-               if (ret_val != 0)
+               if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
+                                               0, abort_cmd) != 0)
                        continue;
 
                /* issue ABTS for this IOCB based on iotag */
-               list_remove_head(lpfc_iocb_list, abtsiocb, struct lpfc_iocbq,
-                                list);
+               abtsiocb = lpfc_sli_get_iocbq(phba);
                if (abtsiocb == NULL) {
                        errcnt++;
                        continue;
                }
-               memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
 
+               cmd = &iocbq->iocb;
                abtsiocb->iocb.un.acxri.abortType = ABORT_TYPE_ABTS;
                abtsiocb->iocb.un.acxri.abortContextTag = cmd->ulpContext;
                abtsiocb->iocb.un.acxri.abortIoTag = cmd->ulpIoTag;
@@ -2621,7 +2719,7 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
                abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
                ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0);
                if (ret_val == IOCB_ERROR) {
-                       list_add_tail(&abtsiocb->list, lpfc_iocb_list);
+                       lpfc_sli_release_iocbq(phba, abtsiocb);
                        errcnt++;
                        continue;
                }
@@ -2630,83 +2728,114 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
        return errcnt;
 }
 
-void
-lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
-                                struct lpfc_iocbq * queue1,
-                                struct lpfc_iocbq * queue2)
+static void
+lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
+                       struct lpfc_iocbq *cmdiocbq,
+                       struct lpfc_iocbq *rspiocbq)
 {
-       if (queue1->context2 && queue2)
-               memcpy(queue1->context2, queue2, sizeof (struct lpfc_iocbq));
+       wait_queue_head_t *pdone_q;
+       unsigned long iflags;
 
-       /* The waiter is looking for LPFC_IO_HIPRI bit to be set
-          as a signal to wake up */
-       queue1->iocb_flag |= LPFC_IO_HIPRI;
+       spin_lock_irqsave(phba->host->host_lock, iflags);
+       cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
+       if (cmdiocbq->context2 && rspiocbq)
+               memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
+                      &rspiocbq->iocb, sizeof(IOCB_t));
+
+       pdone_q = cmdiocbq->context_un.wait_queue;
+       spin_unlock_irqrestore(phba->host->host_lock, iflags);
+       if (pdone_q)
+               wake_up(pdone_q);
        return;
 }
 
+/*
+ * Issue the caller's iocb and wait for its completion, but no longer than the
+ * caller's timeout.  Note that iocb_flags is cleared before the
+ * lpfc_sli_issue_call since the wake routine sets a unique value and by
+ * definition this is a wait function.
+ */
 int
-lpfc_sli_issue_iocb_wait_high_priority(struct lpfc_hba * phba,
-                                      struct lpfc_sli_ring * pring,
-                                      struct lpfc_iocbq * piocb,
-                                      uint32_t flag,
-                                      struct lpfc_iocbq * prspiocbq,
-                                      uint32_t timeout)
+lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
+                        struct lpfc_sli_ring * pring,
+                        struct lpfc_iocbq * piocb,
+                        struct lpfc_iocbq * prspiocbq,
+                        uint32_t timeout)
 {
-       int j, delay_time,  retval = IOCB_ERROR;
-
-       /* The caller must left context1 empty.  */
-       if (piocb->context_un.hipri_wait_queue != 0) {
-               return IOCB_ERROR;
-       }
+       DECLARE_WAIT_QUEUE_HEAD(done_q);
+       long timeleft, timeout_req = 0;
+       int retval = IOCB_SUCCESS;
+       uint32_t creg_val;
 
        /*
-        * If the caller has provided a response iocbq buffer, context2 must
-        * be NULL or its an error.
+        * If the caller has provided a response iocbq buffer, then context2
+        * is NULL or its an error.
         */
-       if (prspiocbq && piocb->context2) {
-               return IOCB_ERROR;
+       if (prspiocbq) {
+               if (piocb->context2)
+                       return IOCB_ERROR;
+               piocb->context2 = prspiocbq;
        }
 
-       piocb->context2 = prspiocbq;
+       piocb->iocb_cmpl = lpfc_sli_wake_iocb_wait;
+       piocb->context_un.wait_queue = &done_q;
+       piocb->iocb_flag &= ~LPFC_IO_WAKE;
 
-       /* Setup callback routine and issue the command. */
-       piocb->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
-       retval = lpfc_sli_issue_iocb(phba, pring, piocb,
-                                       flag | SLI_IOCB_HIGH_PRIORITY);
-       if (retval != IOCB_SUCCESS) {
-               piocb->context2 = NULL;
-               return IOCB_ERROR;
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+               creg_val = readl(phba->HCregaddr);
+               creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+               writel(creg_val, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
        }
 
-       /*
-        * This high-priority iocb was sent out-of-band.  Poll for its
-        * completion rather than wait for a signal.  Note that the host_lock
-        * is held by the midlayer and must be released here to allow the
-        * interrupt handlers to complete the IO and signal this routine via
-        * the iocb_flag.
-        * Also, the delay_time is computed to be one second longer than
-        * the scsi command timeout to give the FW time to abort on
-        * timeout rather than the driver just giving up.  Typically,
-        * the midlayer does not specify a time for this command so the
-        * driver is free to enforce its own timeout.
-        */
+       retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
+       if (retval == IOCB_SUCCESS) {
+               timeout_req = timeout * HZ;
+               spin_unlock_irq(phba->host->host_lock);
+               timeleft = wait_event_timeout(done_q,
+                               piocb->iocb_flag & LPFC_IO_WAKE,
+                               timeout_req);
+               spin_lock_irq(phba->host->host_lock);
 
-       delay_time = ((timeout + 1) * 1000) >> 6;
-       retval = IOCB_ERROR;
-       spin_unlock_irq(phba->host->host_lock);
-       for (j = 0; j < 64; j++) {
-               msleep(delay_time);
-               if (piocb->iocb_flag & LPFC_IO_HIPRI) {
-                       piocb->iocb_flag &= ~LPFC_IO_HIPRI;
-                       retval = IOCB_SUCCESS;
-                       break;
+               if (timeleft == 0) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                                       "%d:0329 IOCB wait timeout error - no "
+                                       "wake response Data x%x\n",
+                                       phba->brd_no, timeout);
+                       retval = IOCB_TIMEDOUT;
+               } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) {
+                       lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                                       "%d:0330 IOCB wake NOT set, "
+                                       "Data x%x x%lx\n", phba->brd_no,
+                                       timeout, (timeleft / jiffies));
+                       retval = IOCB_TIMEDOUT;
+               } else {
+                       lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                                       "%d:0331 IOCB wake signaled\n",
+                                       phba->brd_no);
                }
+       } else {
+               lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+                               "%d:0332 IOCB wait issue failed, Data x%x\n",
+                               phba->brd_no, retval);
+               retval = IOCB_ERROR;
        }
 
-       spin_lock_irq(phba->host->host_lock);
-       piocb->context2 = NULL;
+       if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+               creg_val = readl(phba->HCregaddr);
+               creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+               writel(creg_val, phba->HCregaddr);
+               readl(phba->HCregaddr); /* flush */
+       }
+
+       if (prspiocbq)
+               piocb->context2 = NULL;
+
+       piocb->context_un.wait_queue = NULL;
+       piocb->iocb_cmpl = NULL;
        return retval;
 }
+
 int
 lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
                         uint32_t timeout)
@@ -2854,7 +2983,7 @@ lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
                         * to shutdown interrupt when there is a
                         * ERROR.
                         */
-                       lpfc_sli_send_reset(phba, phba->hba_state);
+                       lpfc_sli_send_reset(phba, 1);
                }
 
                spin_lock(phba->host->host_lock);