[SCSI] lpfc: Adjust lpfc_scsi_buf allocation
[powerpc.git] / drivers / scsi / lpfc / lpfc_scsi.c
index c55ab1a..b903d3b 100644 (file)
@@ -56,6 +56,7 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
        struct ulp_bde64 *bpl;
        IOCB_t *iocb;
        dma_addr_t pdma_phys;
+       uint16_t iotag;
 
        psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
        if (!psb)
@@ -79,6 +80,15 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba)
        /* Initialize virtual ptrs to dma_buf region. */
        memset(psb->data, 0, phba->cfg_sg_dma_buf_size);
 
+       /* Allocate iotag for psb->cur_iocbq. */
+       iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
+       if (iotag == 0) {
+               pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
+                             psb->data, psb->dma_handle);
+               kfree (psb);
+               return NULL;
+       }
+
        psb->fcp_cmnd = psb->data;
        psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
        psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) +
@@ -626,14 +636,10 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
        list_remove_head(lpfc_iocb_list, iocbqrsp, struct lpfc_iocbq, list);
        if (!iocbqrsp)
                return FAILED;
-       memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
-
-       iocbq->iocb_flag |= LPFC_IO_POLL;
-       ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
-                    &phba->sli.ring[phba->sli.fcp_ring],
-                    iocbq, SLI_IOCB_HIGH_PRIORITY,
-                    iocbqrsp,
-                    lpfc_cmd->timeout);
+
+       ret = lpfc_sli_issue_iocb_wait(phba,
+                                      &phba->sli.ring[phba->sli.fcp_ring],
+                                      iocbq, iocbqrsp, lpfc_cmd->timeout);
        if (ret != IOCB_SUCCESS) {
                lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
                ret = FAILED;
@@ -655,8 +661,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba)
                            lpfc_cmd->pCmd->device->id,
                            lpfc_cmd->pCmd->device->lun, 0, LPFC_CTX_TGT);
 
-       /* Return response IOCB to free list. */
-       list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
+       lpfc_sli_release_iocbq(phba, iocbqrsp);
        return ret;
 }
 
@@ -818,9 +823,8 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
 
                list_del_init(&iocb->list);
                pring->txq_cnt--;
-               if (!iocb->iocb_cmpl) {
-                       list_add_tail(&iocb->list, lpfc_iocb_list);
-               }
+               if (!iocb->iocb_cmpl)
+                       lpfc_sli_release_iocbq(phba, iocb);
                else {
                        cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
                        cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
@@ -834,8 +838,6 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
        if (abtsiocb == NULL)
                return FAILED;
 
-       memset(abtsiocb, 0, sizeof (struct lpfc_iocbq));
-
        /*
         * The scsi command was not in the txq.  Check the txcmplq and if it is
         * found, send an abort to the FW.
@@ -861,7 +863,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
                abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
                if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) ==
                                                                IOCB_ERROR) {
-                       list_add_tail(&abtsiocb->list, lpfc_iocb_list);
+                       lpfc_sli_release_iocbq(phba, abtsiocb);
                        ret = IOCB_ERROR;
                        break;
                }
@@ -917,7 +919,6 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
        struct Scsi_Host *shost = cmnd->device->host;
        struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
-       struct lpfc_sli *psli = &phba->sli;
        struct lpfc_scsi_buf *lpfc_cmd = NULL;
        struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
        struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
@@ -964,14 +965,9 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
        if (iocbqrsp == NULL)
                goto out_free_scsi_buf;
 
-       memset(iocbqrsp, 0, sizeof (struct lpfc_iocbq));
-
-       iocbq->iocb_flag |= LPFC_IO_POLL;
-       iocbq->iocb_cmpl = lpfc_sli_wake_iocb_high_priority;
-
-       ret = lpfc_sli_issue_iocb_wait_high_priority(phba,
-                    &phba->sli.ring[psli->fcp_ring],
-                    iocbq, 0, iocbqrsp, 60);
+       ret = lpfc_sli_issue_iocb_wait(phba,
+                                      &phba->sli.ring[phba->sli.fcp_ring],
+                                      iocbq, iocbqrsp, lpfc_cmd->timeout);
        if (ret == IOCB_SUCCESS)
                ret = SUCCESS;
 
@@ -1011,7 +1007,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
                        phba->brd_no, cnt);
        }
 
-       list_add_tail(&iocbqrsp->list, lpfc_iocb_list);
+       lpfc_sli_release_iocbq(phba, iocbqrsp);
 
 out_free_scsi_buf:
        lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
@@ -1156,24 +1152,33 @@ lpfc_slave_alloc(struct scsi_device *sdev)
        /*
         * Populate the cmds_per_lun count scsi_bufs into this host's globally
         * available list of scsi buffers.  Don't allocate more than the
-        * HBA limit conveyed to the midlayer via the host structure.  Note
-        * that this list of scsi bufs exists for the lifetime of the driver.
+        * HBA limit conveyed to the midlayer via the host structure.  The
+        * formula accounts for the lun_queue_depth + error handlers + 1
+        * extra.  This list of scsi bufs exists for the lifetime of the driver.
         */
        total = phba->total_scsi_bufs;
-       num_to_alloc = LPFC_CMD_PER_LUN;
+       num_to_alloc = phba->cfg_lun_queue_depth + 2;
        if (total >= phba->cfg_hba_queue_depth) {
-               printk(KERN_WARNING "%s, At config limitation of "
-                      "%d allocated scsi_bufs\n", __FUNCTION__, total);
+               lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+                               "%d:0704 At limitation of %d preallocated "
+                               "command buffers\n", phba->brd_no, total);
                return 0;
        } else if (total + num_to_alloc > phba->cfg_hba_queue_depth) {
+               lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+                               "%d:0705 Allocation request of %d command "
+                               "buffers will exceed max of %d.  Reducing "
+                               "allocation request to %d.\n", phba->brd_no,
+                               num_to_alloc, phba->cfg_hba_queue_depth,
+                               (phba->cfg_hba_queue_depth - total));
                num_to_alloc = phba->cfg_hba_queue_depth - total;
        }
 
        for (i = 0; i < num_to_alloc; i++) {
                scsi_buf = lpfc_get_scsi_buf(phba);
                if (!scsi_buf) {
-                       printk(KERN_ERR "%s, failed to allocate "
-                              "scsi_buf\n", __FUNCTION__);
+                       lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+                                       "%d:0706 Failed to allocate command "
+                                       "buffer\n", phba->brd_no);
                        break;
                }