diff options
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_hwi.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 2c1c722eca17..1cbcade747fe 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1336,10 +1336,13 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, * @circularQ: the inbound queue we want to transfer to HBA. * @opCode: the operation code represents commands which LLDD and fw recognized. * @payload: the command payload of each operation command. + * @nb: size in bytes of the command payload + * @responseQueue: queue to interrupt on w/ command response (if any) */ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, struct inbound_queue_table *circularQ, - u32 opCode, void *payload, u32 responseQueue) + u32 opCode, void *payload, size_t nb, + u32 responseQueue) { u32 Header = 0, hpriority = 0, bc = 1, category = 0x02; void *pMessage; @@ -1350,10 +1353,13 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, pm8001_printk("No free mpi buffer\n")); return -ENOMEM; } - BUG_ON(!payload); - /*Copy to the payload*/ - memcpy(pMessage, payload, (pm8001_ha->iomb_size - - sizeof(struct mpi_msg_hdr))); + + if (nb > (pm8001_ha->iomb_size - sizeof(struct mpi_msg_hdr))) + nb = pm8001_ha->iomb_size - sizeof(struct mpi_msg_hdr); + memcpy(pMessage, payload, nb); + if (nb + sizeof(struct mpi_msg_hdr) < pm8001_ha->iomb_size) + memset(pMessage + nb, 0, pm8001_ha->iomb_size - + (nb + sizeof(struct mpi_msg_hdr))); /*Build the header*/ Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24) @@ -1763,7 +1769,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id); task_abort.tag = cpu_to_le32(ccb_tag); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, + sizeof(task_abort), 0); if (ret) pm8001_tag_free(pm8001_ha, ccb_tag); @@ -1836,7 +1843,8 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9)); memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); - res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); + res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, + sizeof(sata_cmd), 0); if (res) { sas_free_task(task); pm8001_tag_free(pm8001_ha, ccb_tag); @@ -3375,7 +3383,8 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, ((phyId & 0x0F) << 4) | (port_id & 0x0F)); payload.param0 = cpu_to_le32(param0); payload.param1 = cpu_to_le32(param1); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); } static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, @@ -4305,7 +4314,7 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha, 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); rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, - (u32 *)&smp_cmd, 0); + &smp_cmd, sizeof(smp_cmd), 0); if (rc) goto err_out_2; @@ -4373,7 +4382,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.len = cpu_to_le32(task->total_xfer_len); ssp_cmd.esgl = 0; } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd, + sizeof(ssp_cmd), 0); return ret; } @@ -4482,7 +4492,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, + sizeof(sata_cmd), 0); return ret; } @@ -4517,7 +4528,8 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) memcpy(payload.sas_identify.sas_addr, pm8001_ha->sas_addr, SAS_ADDR_SIZE); payload.sas_identify.phy_id = phy_id; - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, + sizeof(payload), 0); return ret; } @@ -4539,7 +4551,8 @@ static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, memset(&payload, 0, sizeof(payload)); payload.tag = cpu_to_le32(tag); payload.phy_id = cpu_to_le32(phy_id); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, + sizeof(payload), 0); return ret; } @@ -4598,7 +4611,8 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, SAS_ADDR_SIZE); - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); return rc; } @@ -4619,7 +4633,8 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, payload.device_id = cpu_to_le32(device_id); PM8001_MSG_DBG(pm8001_ha, pm8001_printk("unregister device device_id = %d\n", device_id)); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); return ret; } @@ -4642,7 +4657,8 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, payload.tag = cpu_to_le32(1); payload.phyop_phyid = cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F)); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); return ret; } @@ -4696,7 +4712,8 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, task_abort.device_id = cpu_to_le32(dev_id); task_abort.tag = cpu_to_le32(cmd_tag); } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, + sizeof(task_abort), 0); return ret; } @@ -4753,7 +4770,8 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha, if (pm8001_ha->chip_id != chip_8001) sspTMCmd.ds_ads_m = 0x08; circularQ = &pm8001_ha->inbnd_q_tbl[0]; - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd, + sizeof(sspTMCmd), 0); return ret; } @@ -4843,7 +4861,8 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, default: break; } - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, + sizeof(nvmd_req), 0); if (rc) { kfree(fw_control_context); pm8001_tag_free(pm8001_ha, tag); @@ -4927,7 +4946,8 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, default: break; } - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, + sizeof(nvmd_req), 0); if (rc) { kfree(fw_control_context); pm8001_tag_free(pm8001_ha, tag); @@ -4962,7 +4982,8 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha, cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr))); payload.sgl_addr_hi = cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr))); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); return ret; } @@ -5109,7 +5130,8 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, payload.tag = cpu_to_le32(tag); payload.device_id = cpu_to_le32(pm8001_dev->device_id); payload.nds = cpu_to_le32(state); - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); return rc; } @@ -5134,7 +5156,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) payload.SSAHOLT = cpu_to_le32(0xd << 25); 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); + rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, + sizeof(payload), 0); if (rc) pm8001_tag_free(pm8001_ha, tag); return rc; |