diff options
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, | |||
1346 | &pMessage) < 0) { | 1346 | &pMessage) < 0) { |
1347 | PM8001_IO_DBG(pm8001_ha, | 1347 | PM8001_IO_DBG(pm8001_ha, |
1348 | pm8001_printk("No free mpi buffer\n")); | 1348 | pm8001_printk("No free mpi buffer\n")); |
1349 | return -1; | 1349 | return -ENOMEM; |
1350 | } | 1350 | } |
1351 | BUG_ON(!payload); | 1351 | BUG_ON(!payload); |
1352 | /*Copy to the payload*/ | 1352 | /*Copy to the payload*/ |
@@ -1751,6 +1751,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, | |||
1751 | task_abort.tag = cpu_to_le32(ccb_tag); | 1751 | task_abort.tag = cpu_to_le32(ccb_tag); |
1752 | 1752 | ||
1753 | ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); | 1753 | ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); |
1754 | if (ret) | ||
1755 | pm8001_tag_free(pm8001_ha, ccb_tag); | ||
1754 | 1756 | ||
1755 | } | 1757 | } |
1756 | 1758 | ||
@@ -1778,6 +1780,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, | |||
1778 | 1780 | ||
1779 | res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); | 1781 | res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); |
1780 | if (res) { | 1782 | if (res) { |
1783 | sas_free_task(task); | ||
1781 | PM8001_FAIL_DBG(pm8001_ha, | 1784 | PM8001_FAIL_DBG(pm8001_ha, |
1782 | pm8001_printk("cannot allocate tag !!!\n")); | 1785 | pm8001_printk("cannot allocate tag !!!\n")); |
1783 | return; | 1786 | return; |
@@ -1788,14 +1791,14 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, | |||
1788 | */ | 1791 | */ |
1789 | dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); | 1792 | dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); |
1790 | if (!dev) { | 1793 | if (!dev) { |
1794 | sas_free_task(task); | ||
1795 | pm8001_tag_free(pm8001_ha, ccb_tag); | ||
1791 | PM8001_FAIL_DBG(pm8001_ha, | 1796 | PM8001_FAIL_DBG(pm8001_ha, |
1792 | pm8001_printk("Domain device cannot be allocated\n")); | 1797 | pm8001_printk("Domain device cannot be allocated\n")); |
1793 | sas_free_task(task); | ||
1794 | return; | 1798 | return; |
1795 | } else { | ||
1796 | task->dev = dev; | ||
1797 | task->dev->lldd_dev = pm8001_ha_dev; | ||
1798 | } | 1799 | } |
1800 | task->dev = dev; | ||
1801 | task->dev->lldd_dev = pm8001_ha_dev; | ||
1799 | 1802 | ||
1800 | ccb = &pm8001_ha->ccb_info[ccb_tag]; | 1803 | ccb = &pm8001_ha->ccb_info[ccb_tag]; |
1801 | ccb->device = pm8001_ha_dev; | 1804 | ccb->device = pm8001_ha_dev; |
@@ -1821,7 +1824,11 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, | |||
1821 | memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); | 1824 | memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); |
1822 | 1825 | ||
1823 | res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); | 1826 | res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); |
1824 | 1827 | if (res) { | |
1828 | sas_free_task(task); | ||
1829 | pm8001_tag_free(pm8001_ha, ccb_tag); | ||
1830 | kfree(dev); | ||
1831 | } | ||
1825 | } | 1832 | } |
1826 | 1833 | ||
1827 | /** | 1834 | /** |
@@ -3100,7 +3107,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, | |||
3100 | complete(pm8001_dev->setds_completion); | 3107 | complete(pm8001_dev->setds_completion); |
3101 | ccb->task = NULL; | 3108 | ccb->task = NULL; |
3102 | ccb->ccb_tag = 0xFFFFFFFF; | 3109 | ccb->ccb_tag = 0xFFFFFFFF; |
3103 | pm8001_ccb_free(pm8001_ha, tag); | 3110 | pm8001_tag_free(pm8001_ha, tag); |
3104 | } | 3111 | } |
3105 | 3112 | ||
3106 | void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | 3113 | 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) | |||
3119 | } | 3126 | } |
3120 | ccb->task = NULL; | 3127 | ccb->task = NULL; |
3121 | ccb->ccb_tag = 0xFFFFFFFF; | 3128 | ccb->ccb_tag = 0xFFFFFFFF; |
3122 | pm8001_ccb_free(pm8001_ha, tag); | 3129 | pm8001_tag_free(pm8001_ha, tag); |
3123 | } | 3130 | } |
3124 | 3131 | ||
3125 | void | 3132 | void |
3126 | pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | 3133 | pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) |
3127 | { | 3134 | { |
3128 | struct fw_control_ex *fw_control_context; | ||
3129 | struct get_nvm_data_resp *pPayload = | 3135 | struct get_nvm_data_resp *pPayload = |
3130 | (struct get_nvm_data_resp *)(piomb + 4); | 3136 | (struct get_nvm_data_resp *)(piomb + 4); |
3131 | u32 tag = le32_to_cpu(pPayload->tag); | 3137 | u32 tag = le32_to_cpu(pPayload->tag); |
@@ -3134,7 +3140,6 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3134 | u32 ir_tds_bn_dps_das_nvm = | 3140 | u32 ir_tds_bn_dps_das_nvm = |
3135 | le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm); | 3141 | le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm); |
3136 | void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr; | 3142 | void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr; |
3137 | fw_control_context = ccb->fw_control_context; | ||
3138 | 3143 | ||
3139 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n")); | 3144 | PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n")); |
3140 | if ((dlen_status & NVMD_STAT) != 0) { | 3145 | if ((dlen_status & NVMD_STAT) != 0) { |
@@ -3175,13 +3180,11 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
3175 | pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n", | 3180 | pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n", |
3176 | (dlen_status & NVMD_LEN) >> 24)); | 3181 | (dlen_status & NVMD_LEN) >> 24)); |
3177 | } | 3182 | } |
3178 | memcpy(fw_control_context->usrAddr, | 3183 | kfree(ccb->fw_control_context); |
3179 | pm8001_ha->memoryMap.region[NVMD].virt_ptr, | ||
3180 | fw_control_context->len); | ||
3181 | complete(pm8001_ha->nvmd_completion); | ||
3182 | ccb->task = NULL; | 3184 | ccb->task = NULL; |
3183 | ccb->ccb_tag = 0xFFFFFFFF; | 3185 | ccb->ccb_tag = 0xFFFFFFFF; |
3184 | pm8001_ccb_free(pm8001_ha, tag); | 3186 | pm8001_tag_free(pm8001_ha, tag); |
3187 | complete(pm8001_ha->nvmd_completion); | ||
3185 | } | 3188 | } |
3186 | 3189 | ||
3187 | int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) | 3190 | 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) | |||
3588 | complete(pm8001_dev->dcompletion); | 3591 | complete(pm8001_dev->dcompletion); |
3589 | ccb->task = NULL; | 3592 | ccb->task = NULL; |
3590 | ccb->ccb_tag = 0xFFFFFFFF; | 3593 | ccb->ccb_tag = 0xFFFFFFFF; |
3591 | pm8001_ccb_free(pm8001_ha, htag); | 3594 | pm8001_tag_free(pm8001_ha, htag); |
3592 | return 0; | 3595 | return 0; |
3593 | } | 3596 | } |
3594 | 3597 | ||
@@ -3617,15 +3620,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, | |||
3617 | void *piomb) | 3620 | void *piomb) |
3618 | { | 3621 | { |
3619 | u32 status; | 3622 | u32 status; |
3620 | struct fw_control_ex fw_control_context; | ||
3621 | struct fw_flash_Update_resp *ppayload = | 3623 | struct fw_flash_Update_resp *ppayload = |
3622 | (struct fw_flash_Update_resp *)(piomb + 4); | 3624 | (struct fw_flash_Update_resp *)(piomb + 4); |
3623 | u32 tag = le32_to_cpu(ppayload->tag); | 3625 | u32 tag = le32_to_cpu(ppayload->tag); |
3624 | struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; | 3626 | struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; |
3625 | status = le32_to_cpu(ppayload->status); | 3627 | status = le32_to_cpu(ppayload->status); |
3626 | memcpy(&fw_control_context, | ||
3627 | ccb->fw_control_context, | ||
3628 | sizeof(fw_control_context)); | ||
3629 | switch (status) { | 3628 | switch (status) { |
3630 | case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: | 3629 | case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: |
3631 | PM8001_MSG_DBG(pm8001_ha, | 3630 | PM8001_MSG_DBG(pm8001_ha, |
@@ -3668,11 +3667,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, | |||
3668 | pm8001_printk("No matched status = %d\n", status)); | 3667 | pm8001_printk("No matched status = %d\n", status)); |
3669 | break; | 3668 | break; |
3670 | } | 3669 | } |
3671 | ccb->fw_control_context->fw_control->retcode = status; | 3670 | kfree(ccb->fw_control_context); |
3672 | complete(pm8001_ha->nvmd_completion); | ||
3673 | ccb->task = NULL; | 3671 | ccb->task = NULL; |
3674 | ccb->ccb_tag = 0xFFFFFFFF; | 3672 | ccb->ccb_tag = 0xFFFFFFFF; |
3675 | pm8001_ccb_free(pm8001_ha, tag); | 3673 | pm8001_tag_free(pm8001_ha, tag); |
3674 | complete(pm8001_ha->nvmd_completion); | ||
3676 | return 0; | 3675 | return 0; |
3677 | } | 3676 | } |
3678 | 3677 | ||
@@ -4257,7 +4256,11 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha, | |||
4257 | smp_cmd.long_smp_req.long_resp_size = | 4256 | smp_cmd.long_smp_req.long_resp_size = |
4258 | cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4); | 4257 | cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4); |
4259 | build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); | 4258 | build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); |
4260 | pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0); | 4259 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, |
4260 | (u32 *)&smp_cmd, 0); | ||
4261 | if (rc) | ||
4262 | goto err_out_2; | ||
4263 | |||
4261 | return 0; | 4264 | return 0; |
4262 | 4265 | ||
4263 | err_out_2: | 4266 | err_out_2: |
@@ -4398,7 +4401,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, | |||
4398 | 4401 | ||
4399 | /* Check for read log for failed drive and return */ | 4402 | /* Check for read log for failed drive and return */ |
4400 | if (sata_cmd.sata_fis.command == 0x2f) { | 4403 | if (sata_cmd.sata_fis.command == 0x2f) { |
4401 | if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || | 4404 | if (((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || |
4402 | (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) || | 4405 | (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) || |
4403 | (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) { | 4406 | (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) { |
4404 | struct task_status_struct *ts; | 4407 | struct task_status_struct *ts; |
@@ -4789,6 +4792,10 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, | |||
4789 | break; | 4792 | break; |
4790 | } | 4793 | } |
4791 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); | 4794 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); |
4795 | if (rc) { | ||
4796 | kfree(fw_control_context); | ||
4797 | pm8001_tag_free(pm8001_ha, tag); | ||
4798 | } | ||
4792 | return rc; | 4799 | return rc; |
4793 | } | 4800 | } |
4794 | 4801 | ||
@@ -4869,6 +4876,10 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, | |||
4869 | break; | 4876 | break; |
4870 | } | 4877 | } |
4871 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); | 4878 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); |
4879 | if (rc) { | ||
4880 | kfree(fw_control_context); | ||
4881 | pm8001_tag_free(pm8001_ha, tag); | ||
4882 | } | ||
4872 | return rc; | 4883 | return rc; |
4873 | } | 4884 | } |
4874 | 4885 | ||
@@ -5061,7 +5072,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) | |||
5061 | memset(&payload, 0, sizeof(payload)); | 5072 | memset(&payload, 0, sizeof(payload)); |
5062 | rc = pm8001_tag_alloc(pm8001_ha, &tag); | 5073 | rc = pm8001_tag_alloc(pm8001_ha, &tag); |
5063 | if (rc) | 5074 | if (rc) |
5064 | return -1; | 5075 | return -ENOMEM; |
5065 | ccb = &pm8001_ha->ccb_info[tag]; | 5076 | ccb = &pm8001_ha->ccb_info[tag]; |
5066 | ccb->ccb_tag = tag; | 5077 | ccb->ccb_tag = tag; |
5067 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 5078 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
@@ -5070,6 +5081,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) | |||
5070 | payload.sata_hol_tmo = cpu_to_le32(80); | 5081 | payload.sata_hol_tmo = cpu_to_le32(80); |
5071 | payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff); | 5082 | payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff); |
5072 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); | 5083 | rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); |
5084 | if (rc) | ||
5085 | pm8001_tag_free(pm8001_ha, tag); | ||
5073 | return rc; | 5086 | return rc; |
5074 | 5087 | ||
5075 | } | 5088 | } |