]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_els.c
Merge branch 'work'
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_els.c
index 2b1c9572dae728bfc50158ba82e1ee1f905c6ee4..20f1a0713db2dbd7d2210f4f85defa36deadd7c1 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 
+#include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_fc.h>
@@ -101,9 +102,8 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
                   uint16_t cmdSize,
                   uint8_t retry, struct lpfc_nodelist * ndlp, uint32_t elscmd)
 {
-       struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
        struct lpfc_sli_ring *pring;
-       struct lpfc_iocbq *elsiocb = NULL;
+       struct lpfc_iocbq *elsiocb;
        struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
        struct ulp_bde64 *bpl;
        IOCB_t *icmd;
@@ -113,15 +113,13 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
        if (phba->hba_state < LPFC_LINK_UP)
                return  NULL;
 
-
        /* Allocate buffer for  command iocb */
        spin_lock_irq(phba->host->host_lock);
-       list_remove_head(lpfc_iocb_list, elsiocb, struct lpfc_iocbq, list);
+       elsiocb = lpfc_sli_get_iocbq(phba);
        spin_unlock_irq(phba->host->host_lock);
 
        if (elsiocb == NULL)
                return NULL;
-       memset(elsiocb, 0, sizeof (struct lpfc_iocbq));
        icmd = &elsiocb->iocb;
 
        /* fill in BDEs for command */
@@ -129,10 +127,11 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
        if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
            ((pcmd->virt = lpfc_mbuf_alloc(phba,
                                           MEM_PRI, &(pcmd->phys))) == 0)) {
-               if (pcmd)
-                       kfree(pcmd);
+               kfree(pcmd);
 
-               list_add_tail(&elsiocb->list, lpfc_iocb_list);
+               spin_lock_irq(phba->host->host_lock);
+               lpfc_sli_release_iocbq(phba, elsiocb);
+               spin_unlock_irq(phba->host->host_lock);
                return NULL;
        }
 
@@ -145,11 +144,12 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
                        prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
                                                     &prsp->phys);
                if (prsp == 0 || prsp->virt == 0) {
-                       if (prsp)
-                               kfree(prsp);
+                       kfree(prsp);
                        lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
                        kfree(pcmd);
-                       list_add_tail(&elsiocb->list, lpfc_iocb_list);
+                       spin_lock_irq(phba->host->host_lock);
+                       lpfc_sli_release_iocbq(phba, elsiocb);
+                       spin_unlock_irq(phba->host->host_lock);
                        return NULL;
                }
                INIT_LIST_HEAD(&prsp->list);
@@ -163,13 +163,14 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
            pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
                                             &pbuflist->phys);
        if (pbuflist == 0 || pbuflist->virt == 0) {
-               list_add_tail(&elsiocb->list, lpfc_iocb_list);
+               spin_lock_irq(phba->host->host_lock);
+               lpfc_sli_release_iocbq(phba, elsiocb);
+               spin_unlock_irq(phba->host->host_lock);
                lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
                lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
                kfree(pcmd);
                kfree(prsp);
-               if (pbuflist)
-                       kfree(pbuflist);
+               kfree(pbuflist);
                return NULL;
        }
 
@@ -595,10 +596,8 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba)
                                        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);
                        }
                }
        }
@@ -721,6 +720,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
                }
@@ -870,6 +870,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
                }
@@ -1055,6 +1056,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
                }
@@ -1206,6 +1208,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
                /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
                   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+                  (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
                   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
                        goto out;
                }
@@ -1712,7 +1715,7 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb)
                kfree(buf_ptr);
        }
        spin_lock_irq(phba->host->host_lock);
-       list_add_tail(&elsiocb->list, &phba->lpfc_iocb_list);
+       lpfc_sli_release_iocbq(phba, elsiocb);
        spin_unlock_irq(phba->host->host_lock);
        return 0;
 }
@@ -2928,9 +2931,8 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba)
                        spin_unlock_irq(phba->host->host_lock);
                        (piocb->iocb_cmpl) (phba, piocb, piocb);
                        spin_lock_irq(phba->host->host_lock);
-               } else {
-                       list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
-               }
+               } else
+                       lpfc_sli_release_iocbq(phba, piocb);
        }
        if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) {
                phba->els_tmofunc.expires = jiffies + HZ * timeout;
@@ -2995,7 +2997,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                        spin_lock_irq(phba->host->host_lock);
                }
                else
-                       list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+                       lpfc_sli_release_iocbq(phba, piocb);
        }
 
        list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
@@ -3032,7 +3034,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
                        spin_lock_irq(phba->host->host_lock);
                }
                else
-                       list_add_tail(&piocb->list, &phba->lpfc_iocb_list);
+                       lpfc_sli_release_iocbq(phba, piocb);
        }
        spin_unlock_irq(phba->host->host_lock);
        return;