diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 07:10:32 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 07:10:32 +0400 |
commit | 6b22df74f7af62137772c280791c932855f7635b (patch) | |
tree | 1ae52bc548b48eb9d243c41363b5c39fb93a5ca6 /drivers/scsi/pm8001/pm8001_hwi.c | |
parent | 930e0312bcdc96d15f02ed6812d4a6c947855a2d (diff) | |
parent | a93cb871cdeace7de7d865555ed492e8bc8075b5 (diff) | |
download | linux-6b22df74f7af62137772c280791c932855f7635b.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This patch set consists of the usual driver updates (ufs, storvsc,
pm8001 hpsa). It also has removal of the user space target driver
code (everyone is using LIO now), a partial PCI MSI-X update, more
multi-queue updates, conversion to 64 bit LUNs (so we could
theoretically cope with any LUN returned by a device) and placeholder
support for the ZBC device type (Shingle drives), plus an assortment
of minor updates and bug fixes"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (143 commits)
scsi: do not issue SCSI RSOC command to Promise Vtrak E610f
vmw_pvscsi: Use pci_enable_msix_exact() instead of pci_enable_msix()
pm8001: Fix invalid return when request_irq() failed
lpfc: Remove superfluous call to pci_disable_msix()
isci: Use pci_enable_msix_exact() instead of pci_enable_msix()
bfa: Use pci_enable_msix_exact() instead of pci_enable_msix()
bfa: Cleanup bfad_setup_intr() function
bfa: Do not call pci_enable_msix() after it failed once
fnic: Use pci_enable_msix_exact() instead of pci_enable_msix()
scsi: use short driver name for per-driver cmd slab caches
scsi_debug: support scsi-mq, queues and locks
Drivers: add blist flags
scsi: ufs: fix endianness sparse warnings
scsi: ufs: make undeclared functions static
bnx2i: Update driver version to 2.7.10.1
pm8001: fix a memory leak in nvmd_resp
pm8001: fix update_flash
pm8001: fix a memory leak in flash_update
pm8001: Cleaning up uninitialized variables
pm8001: Fix to remove null pointer checks that could never happen
...
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_hwi.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index a97be015e52e..173831016f5f 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1346,7 +1346,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, &pMessage) < 0) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("No free mpi buffer\n")); - return -1; + return -ENOMEM; } BUG_ON(!payload); /*Copy to the payload*/ @@ -1751,6 +1751,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, task_abort.tag = cpu_to_le32(ccb_tag); ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); + if (ret) + pm8001_tag_free(pm8001_ha, ccb_tag); } @@ -1778,6 +1780,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); if (res) { + sas_free_task(task); PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot allocate tag !!!\n")); return; @@ -1788,14 +1791,14 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, */ dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); if (!dev) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Domain device cannot be allocated\n")); - sas_free_task(task); return; - } else { - task->dev = dev; - task->dev->lldd_dev = pm8001_ha_dev; } + task->dev = dev; + task->dev->lldd_dev = pm8001_ha_dev; ccb = &pm8001_ha->ccb_info[ccb_tag]; ccb->device = pm8001_ha_dev; @@ -1821,7 +1824,11 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); - + if (res) { + sas_free_task(task); + pm8001_tag_free(pm8001_ha, ccb_tag); + kfree(dev); + } } /** @@ -3100,7 +3107,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, complete(pm8001_dev->setds_completion); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; - pm8001_ccb_free(pm8001_ha, tag); + pm8001_tag_free(pm8001_ha, tag); } void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) @@ -3119,13 +3126,12 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) } ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; - pm8001_ccb_free(pm8001_ha, tag); + pm8001_tag_free(pm8001_ha, tag); } void pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { - struct fw_control_ex *fw_control_context; struct get_nvm_data_resp *pPayload = (struct get_nvm_data_resp *)(piomb + 4); u32 tag = le32_to_cpu(pPayload->tag); @@ -3134,7 +3140,6 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 ir_tds_bn_dps_das_nvm = le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm); void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr; - fw_control_context = ccb->fw_control_context; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n")); if ((dlen_status & NVMD_STAT) != 0) { @@ -3175,13 +3180,11 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n", (dlen_status & NVMD_LEN) >> 24)); } - memcpy(fw_control_context->usrAddr, - pm8001_ha->memoryMap.region[NVMD].virt_ptr, - fw_control_context->len); - complete(pm8001_ha->nvmd_completion); + kfree(ccb->fw_control_context); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; - pm8001_ccb_free(pm8001_ha, tag); + pm8001_tag_free(pm8001_ha, tag); + complete(pm8001_ha->nvmd_completion); } int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) @@ -3588,7 +3591,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) complete(pm8001_dev->dcompletion); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; - pm8001_ccb_free(pm8001_ha, htag); + pm8001_tag_free(pm8001_ha, htag); return 0; } @@ -3617,15 +3620,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { u32 status; - struct fw_control_ex fw_control_context; struct fw_flash_Update_resp *ppayload = (struct fw_flash_Update_resp *)(piomb + 4); u32 tag = le32_to_cpu(ppayload->tag); struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; status = le32_to_cpu(ppayload->status); - memcpy(&fw_control_context, - ccb->fw_control_context, - sizeof(fw_control_context)); switch (status) { case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: PM8001_MSG_DBG(pm8001_ha, @@ -3668,11 +3667,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, pm8001_printk("No matched status = %d\n", status)); break; } - ccb->fw_control_context->fw_control->retcode = status; - complete(pm8001_ha->nvmd_completion); + kfree(ccb->fw_control_context); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; - pm8001_ccb_free(pm8001_ha, tag); + pm8001_tag_free(pm8001_ha, tag); + complete(pm8001_ha->nvmd_completion); return 0; } @@ -4257,7 +4256,11 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha, smp_cmd.long_smp_req.long_resp_size = cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4); build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, + (u32 *)&smp_cmd, 0); + if (rc) + goto err_out_2; + return 0; err_out_2: @@ -4398,7 +4401,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, /* Check for read log for failed drive and return */ if (sata_cmd.sata_fis.command == 0x2f) { - if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || + if (((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) || (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) { struct task_status_struct *ts; @@ -4789,6 +4792,10 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, break; } rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + if (rc) { + kfree(fw_control_context); + pm8001_tag_free(pm8001_ha, tag); + } return rc; } @@ -4869,6 +4876,10 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, break; } rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + if (rc) { + kfree(fw_control_context); + pm8001_tag_free(pm8001_ha, tag); + } return rc; } @@ -5061,7 +5072,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) memset(&payload, 0, sizeof(payload)); rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) - return -1; + return -ENOMEM; ccb = &pm8001_ha->ccb_info[tag]; ccb->ccb_tag = tag; circularQ = &pm8001_ha->inbnd_q_tbl[0]; @@ -5070,6 +5081,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) payload.sata_hol_tmo = cpu_to_le32(80); payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff); rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + if (rc) + pm8001_tag_free(pm8001_ha, tag); return rc; } |