Merge remote-tracking branches 'asoc/fix/ak4613', 'asoc/fix/atmel', 'asoc/fix/compres...
[sfrench/cifs-2.6.git] / drivers / scsi / qla2xxx / qla_os.c
index 1c79579032835af29aefa337448f50548f7fb37d..79f050256c55c735c612c4553124ccf9e80fda0c 100644 (file)
@@ -630,29 +630,34 @@ qla2x00_sp_free_dma(void *ptr)
                sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
        }
 
+       if (!ctx)
+               goto end;
+
        if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
                /* List assured to be having elements */
-               qla2x00_clean_dsd_pool(ha, sp, NULL);
+               qla2x00_clean_dsd_pool(ha, ctx);
                sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
        }
 
        if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-               dma_pool_free(ha->dl_dma_pool, ctx,
-                   ((struct crc_context *)ctx)->crc_ctx_dma);
+               struct crc_context *ctx0 = ctx;
+
+               dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
                sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
        }
 
        if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-               struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
+               struct ct6_dsd *ctx1 = ctx;
 
                dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
-                       ctx1->fcp_cmnd_dma);
+                   ctx1->fcp_cmnd_dma);
                list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
                ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
                ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
                mempool_free(ctx1, ha->ctx_mempool);
        }
 
+end:
        CMD_SP(cmd) = NULL;
        qla2x00_rel_sp(sp);
 }
@@ -699,21 +704,24 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
                sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
        }
 
+       if (!ctx)
+               goto end;
+
        if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
                /* List assured to be having elements */
-               qla2x00_clean_dsd_pool(ha, sp, NULL);
+               qla2x00_clean_dsd_pool(ha, ctx);
                sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
        }
 
        if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-               dma_pool_free(ha->dl_dma_pool, ctx,
-                   ((struct crc_context *)ctx)->crc_ctx_dma);
+               struct crc_context *ctx0 = ctx;
+
+               dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
                sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
        }
 
        if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-               struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
-
+               struct ct6_dsd *ctx1 = ctx;
                dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
                    ctx1->fcp_cmnd_dma);
                list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
@@ -721,7 +729,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
                ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
                mempool_free(ctx1, ha->ctx_mempool);
        }
-
+end:
        CMD_SP(cmd) = NULL;
        qla2xxx_rel_qpair_sp(sp->qpair, sp);
 }
@@ -1632,7 +1640,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 void
 qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
 {
-       int que, cnt;
+       int que, cnt, status;
        unsigned long flags;
        srb_t *sp;
        struct qla_hw_data *ha = vha->hw;
@@ -1662,8 +1670,12 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
                                         */
                                        sp_get(sp);
                                        spin_unlock_irqrestore(&ha->hardware_lock, flags);
-                                       qla2xxx_eh_abort(GET_CMD_SP(sp));
+                                       status = qla2xxx_eh_abort(GET_CMD_SP(sp));
                                        spin_lock_irqsave(&ha->hardware_lock, flags);
+                                       /* Get rid of extra reference if immediate exit
+                                        * from ql2xxx_eh_abort */
+                                       if (status == FAILED && (qla2x00_isp_reg_stat(ha)))
+                                               atomic_dec(&sp->ref_count);
                                }
                                req->outstanding_cmds[cnt] = NULL;
                                sp->done(sp, res);
@@ -2623,10 +2635,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        if (mem_only) {
                if (pci_enable_device_mem(pdev))
-                       goto probe_out;
+                       return ret;
        } else {
                if (pci_enable_device(pdev))
-                       goto probe_out;
+                       return ret;
        }
 
        /* This may fail but that's ok */
@@ -2636,7 +2648,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!ha) {
                ql_log_pci(ql_log_fatal, pdev, 0x0009,
                    "Unable to allocate memory for ha.\n");
-               goto probe_out;
+               goto disable_device;
        }
        ql_dbg_pci(ql_dbg_init, pdev, 0x000a,
            "Memory allocated for ha=%p.\n", ha);
@@ -3254,7 +3266,7 @@ iospace_config_failed:
        pci_release_selected_regions(ha->pdev, ha->bars);
        kfree(ha);
 
-probe_out:
+disable_device:
        pci_disable_device(pdev);
        return ret;
 }