diff options
author | Andrew Vasquez <andrewv@marvell.com> | 2019-07-26 18:07:35 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-08-08 00:08:12 +0200 |
commit | 26a77799195f4ff105f877042012c7fb355b3da1 (patch) | |
tree | e702e9162676270cf45f274d242ebd9dd01230a6 /drivers/scsi/qla2xxx/qla_os.c | |
parent | scsi: qla2xxx: Retry fabric Scan on IOCB queue full (diff) | |
download | linux-26a77799195f4ff105f877042012c7fb355b3da1.tar.xz linux-26a77799195f4ff105f877042012c7fb355b3da1.zip |
scsi: qla2xxx: Correct error handling during initialization failures
Current code misses or fails to account for proper recovery during early
initialization failures:
- Properly unwind allocations during probe() failures.
- Protect against non-initialization memory allocations during
unwinding.
- Propagate error status during HW initialization.
- Release SCSI host reference when memory allocations fail.
Signed-off-by: Andrew Vasquez <andrewv@marvell.com>
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 769a2ffea79f..73655c81ab77 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1809,8 +1809,13 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) int que; struct qla_hw_data *ha = vha->hw; + /* Continue only if initialization complete. */ + if (!ha->base_qpair) + return; __qla2x00_abort_all_cmds(ha->base_qpair, res); + if (!ha->queue_pair_map) + return; for (que = 0; que < ha->max_qpairs; que++) { if (!ha->queue_pair_map[que]) continue; @@ -3163,6 +3168,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql_log(ql_log_fatal, base_vha, 0x003d, "Failed to allocate memory for queue pointers..." "aborting.\n"); + ret = -ENODEV; goto probe_failed; } @@ -4717,7 +4723,7 @@ qla2x00_mem_free(struct qla_hw_data *ha) mempool_destroy(ha->ctx_mempool); ha->ctx_mempool = NULL; - if (ql2xenabledif) { + if (ql2xenabledif && ha->dif_bundl_pool) { struct dsd_dma *dsd, *nxt; list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head, @@ -4812,7 +4818,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, if (!vha->gnl.l) { ql_log(ql_log_fatal, vha, 0xd04a, "Alloc failed for name list.\n"); - scsi_remove_host(vha->host); + scsi_host_put(vha->host); return NULL; } @@ -4824,7 +4830,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, "Alloc failed for scan database.\n"); dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, vha->gnl.ldma); - scsi_remove_host(vha->host); + scsi_host_put(vha->host); return NULL; } INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); |