diff options
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_hwi.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 131 |
1 files changed, 90 insertions, 41 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 68a8217032d0..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) @@ -1364,7 +1370,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, /*Update the PI to the firmware*/ pm8001_cw32(pm8001_ha, circularQ->pi_pci_bar, circularQ->pi_offset, circularQ->producer_idx); - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n", responseQueue, opCode, circularQ->producer_idx, circularQ->consumer_index)); @@ -1436,6 +1442,10 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, /* read header */ header_tmp = pm8001_read_32(msgHeader); msgHeader_tmp = cpu_to_le32(header_tmp); + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( + "outbound opcode msgheader:%x ci=%d pi=%d\n", + msgHeader_tmp, circularQ->consumer_idx, + circularQ->producer_index)); if (0 != (le32_to_cpu(msgHeader_tmp) & 0x80000000)) { if (OPC_OUB_SKIP_ENTRY != (le32_to_cpu(msgHeader_tmp) & 0xfff)) { @@ -1604,7 +1614,8 @@ void pm8001_work_fn(struct work_struct *work) break; default: - pm8001_printk("...query task failed!!!\n"); + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( + "...query task failed!!!\n")); break; }); @@ -1758,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); @@ -1831,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); @@ -1890,6 +1903,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk("SAS Address of IO Failure Drive:" "%016llx", SAS_ADDR(t->dev->sas_addr))); + if (status) + PM8001_IOERR_DBG(pm8001_ha, pm8001_printk( + "status:0x%x, tag:0x%x, task:0x%p\n", + status, tag, t)); + switch (status) { case IO_SUCCESS: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS" @@ -2072,7 +2090,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; break; default: - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", status)); /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; @@ -2125,7 +2143,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) if (unlikely(!t || !t->lldd_task || !t->dev)) return; ts = &t->task_status; - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("port_id = %x,device_id = %x\n", port_id, dev_id)); switch (event) { @@ -2263,7 +2281,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk(" IO_XFER_CMD_FRAME_ISSUED\n")); return; default: - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", event)); /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; @@ -2352,6 +2370,12 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("ts null\n")); return; } + + if (status) + PM8001_IOERR_DBG(pm8001_ha, pm8001_printk( + "status:0x%x, tag:0x%x, task::0x%p\n", + status, tag, t)); + /* Print sas address of IO failed device */ if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && (status != IO_UNDERFLOW)) { @@ -2652,7 +2676,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; break; default: - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", status)); /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; @@ -2723,7 +2747,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) if (unlikely(!t || !t->lldd_task || !t->dev)) return; ts = &t->task_status; - PM8001_IO_DBG(pm8001_ha, pm8001_printk( + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n", port_id, dev_id, tag, event)); switch (event) { @@ -2872,7 +2896,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_OPEN_TO; break; default: - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", event)); /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; @@ -2917,9 +2941,13 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) t = ccb->task; ts = &t->task_status; pm8001_dev = ccb->device; - if (status) + if (status) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("smp IO status 0x%x\n", status)); + PM8001_IOERR_DBG(pm8001_ha, + pm8001_printk("status:0x%x, tag:0x%x, task:0x%p\n", + status, tag, t)); + } if (unlikely(!t || !t->lldd_task || !t->dev)) return; @@ -3070,7 +3098,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; break; default: - PM8001_IO_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", status)); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_DEV_NO_RESPONSE; @@ -3355,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, @@ -3416,7 +3445,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_get_lrate_mode(phy, link_rate); break; default: - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("unknown device type(%x)\n", deviceType)); break; } @@ -3463,7 +3492,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; unsigned long flags; - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; @@ -3541,7 +3570,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) break; default: port->port_attached = 0; - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk(" phy Down and(default) = %x\n", portstate)); break; @@ -3689,7 +3718,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, pm8001_printk(": FLASH_UPDATE_DISABLED\n")); break; default: - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("No matched status = %d\n", status)); break; } @@ -3805,8 +3834,9 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) struct sas_ha_struct *sas_ha = pm8001_ha->sas; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("outbound queue HW event & event type : ")); + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( + "SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n", + port_id, phy_id, eventType, status)); switch (eventType) { case HW_EVENT_PHY_START_STATUS: PM8001_MSG_DBG(pm8001_ha, @@ -3990,7 +4020,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n")); break; default: - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown event type = %x\n", eventType)); break; } @@ -4161,7 +4191,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n")); break; default: - PM8001_MSG_DBG(pm8001_ha, + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk("Unknown outbound Queue IOMB OPC = %x\n", opc)); break; @@ -4284,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; @@ -4352,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; } @@ -4461,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; } @@ -4496,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; } @@ -4518,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; } @@ -4577,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; } @@ -4598,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; } @@ -4621,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; } @@ -4649,6 +4686,9 @@ static irqreturn_t pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) { pm8001_chip_interrupt_disable(pm8001_ha, vec); + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( + "irq vec %d, ODMR:0x%x\n", + vec, pm8001_cr32(pm8001_ha, 0, 0x30))); process_oq(pm8001_ha, vec); pm8001_chip_interrupt_enable(pm8001_ha, vec); return IRQ_HANDLED; @@ -4672,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; } @@ -4729,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; } @@ -4819,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); @@ -4903,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); @@ -4938,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; } @@ -4960,6 +5005,8 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, if (!fw_control_context) return -ENOMEM; fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; + PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk( + "dma fw_control context input length :%x\n", fw_control->len)); memcpy(buffer, fw_control->buffer, fw_control->len); flash_update_info.sgl.addr = cpu_to_le64(phys_addr); flash_update_info.sgl.im_len.len = cpu_to_le32(fw_control->len); @@ -5083,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; } @@ -5108,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; |