--- zzzz-none-000/linux-3.10.107/drivers/scsi/pm8001/pm8001_hwi.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/scsi/pm8001/pm8001_hwi.c 2021-02-04 17:41:59.000000000 +0000 @@ -644,7 +644,7 @@ pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); /* 8081 controllers need BAR shift to access MPI space * as this is shared with BIOS data */ - if (deviceid == 0x8081) { + if (deviceid == 0x8081 || deviceid == 0x0042) { if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Shift Bar4 to 0x%x failed\n", @@ -673,7 +673,7 @@ for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) update_outbnd_queue_table(pm8001_ha, i); /* 8081 controller donot require these operations */ - if (deviceid != 0x8081) { + if (deviceid != 0x8081 && deviceid != 0x0042) { mpi_set_phys_g3_with_ssc(pm8001_ha, 0); /* 7->130ms, 34->500ms, 119->1.5s */ mpi_set_open_retry_interval_reg(pm8001_ha, 119); @@ -701,7 +701,7 @@ u32 gst_len_mpistate; u16 deviceid; pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); - if (deviceid == 0x8081) { + if (deviceid == 0x8081 || deviceid == 0x0042) { if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Shift Bar4 to 0x%x failed\n", @@ -1346,7 +1346,7 @@ &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 @@ 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 @@ 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 @@ */ 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 @@ 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); + } } /** @@ -1868,6 +1875,13 @@ if (unlikely(!t || !t->lldd_task || !t->dev)) return; ts = &t->task_status; + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && + (status != IO_UNDERFLOW)) + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("SAS Address of IO Failure Drive:" + "%016llx", SAS_ADDR(t->dev->sas_addr))); + switch (status) { case IO_SUCCESS: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS" @@ -2276,6 +2290,11 @@ u32 param; u32 status; u32 tag; + int i, j; + u8 sata_addr_low[4]; + u32 temp_sata_addr_low; + u8 sata_addr_hi[4]; + u32 temp_sata_addr_hi; struct sata_completion_resp *psataPayload; struct task_status_struct *ts; struct ata_task_resp *resp ; @@ -2325,7 +2344,46 @@ pm8001_printk("ts null\n")); return; } - + /* Print sas address of IO failed device */ + if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) && + (status != IO_UNDERFLOW)) { + if (!((t->dev->parent) && + (DEV_IS_EXPANDER(t->dev->parent->dev_type)))) { + for (i = 0 , j = 4; j <= 7 && i <= 3; i++ , j++) + sata_addr_low[i] = pm8001_ha->sas_addr[j]; + for (i = 0 , j = 0; j <= 3 && i <= 3; i++ , j++) + sata_addr_hi[i] = pm8001_ha->sas_addr[j]; + memcpy(&temp_sata_addr_low, sata_addr_low, + sizeof(sata_addr_low)); + memcpy(&temp_sata_addr_hi, sata_addr_hi, + sizeof(sata_addr_hi)); + temp_sata_addr_hi = (((temp_sata_addr_hi >> 24) & 0xff) + |((temp_sata_addr_hi << 8) & + 0xff0000) | + ((temp_sata_addr_hi >> 8) + & 0xff00) | + ((temp_sata_addr_hi << 24) & + 0xff000000)); + temp_sata_addr_low = ((((temp_sata_addr_low >> 24) + & 0xff) | + ((temp_sata_addr_low << 8) + & 0xff0000) | + ((temp_sata_addr_low >> 8) + & 0xff00) | + ((temp_sata_addr_low << 24) + & 0xff000000)) + + pm8001_dev->attached_phy + + 0x10); + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("SAS Address of IO Failure Drive:" + "%08x%08x", temp_sata_addr_hi, + temp_sata_addr_low)); + } else { + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("SAS Address of IO Failure Drive:" + "%016llx", SAS_ADDR(t->dev->sas_addr))); + } + } switch (status) { case IO_SUCCESS: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); @@ -2451,11 +2509,7 @@ IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*in order to force CPU ordering*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2471,11 +2525,7 @@ IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2499,11 +2549,7 @@ IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2566,11 +2612,7 @@ IO_DS_NON_OPERATIONAL); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2590,11 +2632,7 @@ IO_DS_IN_ERROR); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2604,6 +2642,7 @@ ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + break; default: PM8001_IO_DBG(pm8001_ha, pm8001_printk("Unknown status 0x%x\n", status)); @@ -2623,20 +2662,9 @@ " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, status, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } else if (!t->uldd_task) { + } else { spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); } } @@ -2745,11 +2773,7 @@ IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); return; } break; @@ -2858,20 +2882,9 @@ " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, event, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } else if (!t->uldd_task) { + } else { spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); } } @@ -3087,15 +3100,15 @@ struct pm8001_device *pm8001_dev = ccb->device; u32 status = le32_to_cpu(pPayload->status); u32 device_id = le32_to_cpu(pPayload->device_id); - u8 pds = le32_to_cpu(pPayload->pds_nds) | PDS_BITS; - u8 nds = le32_to_cpu(pPayload->pds_nds) | NDS_BITS; + u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS; + u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set device id = 0x%x state " "from 0x%x to 0x%x status = 0x%x!\n", device_id, pds, nds, status)); 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) @@ -3114,13 +3127,13 @@ } 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 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); @@ -3170,13 +3183,17 @@ pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n", (dlen_status & NVMD_LEN) >> 24)); } + /* Though fw_control_context is freed below, usrAddr still needs + * to be updated as this holds the response to the request function + */ 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) @@ -3247,6 +3264,10 @@ struct sas_phy *sas_phy = phy->sas_phy.phy; switch (link_rate) { + case PHY_SPEED_120: + phy->sas_phy.linkrate = SAS_LINK_RATE_12_0_GBPS; + phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_12_0_GBPS; + break; case PHY_SPEED_60: phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS; phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS; @@ -3352,6 +3373,7 @@ unsigned long flags; u8 deviceType = pPayload->sas_identify.dev_type; port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; PM8001_MSG_DBG(pm8001_ha, pm8001_printk("HW_EVENT_SAS_PHY_UP port id = %d, phy id = %d\n", port_id, phy_id)); @@ -3432,6 +3454,7 @@ pm8001_printk("HW_EVENT_SATA_PHY_UP port id = %d," " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; + phy->phy_state = PHY_STATE_LINK_UP_SPC; port->port_attached = 1; pm8001_get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; @@ -3581,7 +3604,7 @@ 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; } @@ -3610,15 +3633,11 @@ 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, @@ -3661,11 +3680,11 @@ 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; } @@ -3740,7 +3759,7 @@ pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb(); - if ((pm8001_dev->id & NCQ_ABORT_ALL_FLAG) && t) { + if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) { pm8001_tag_free(pm8001_ha, tag); sas_free_task(t); /* clear the flag */ @@ -4250,7 +4269,11 @@ 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: @@ -4291,7 +4314,8 @@ ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); - memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); + memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, + task->ssp_task.cmd->cmd_len); circularQ = &pm8001_ha->inbnd_q_tbl[0]; /* fill in PRD (scatter/gather) table, if any */ @@ -4348,7 +4372,7 @@ PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); } if (task->ata_task.use_ncq && - dev->sata_dev.command_set != ATAPI_COMMAND_SET) { + dev->sata_dev.class != ATA_DEV_ATAPI) { ATAP = 0x07; /* FPDMA */ PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); } @@ -4390,7 +4414,7 @@ /* 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; @@ -4413,23 +4437,11 @@ " stat 0x%x but aborted by upper layer " "\n", task, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - } else if (task->uldd_task) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); - return 0; - } else if (!task->uldd_task) { + } else { spin_unlock_irqrestore(&task->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); + pm8001_ccb_task_free_done(pm8001_ha, task, + ccb, tag); return 0; } } @@ -4699,6 +4711,8 @@ sspTMCmd.tmf = cpu_to_le32(tmf->tmf); memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8); sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag); + 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); return ret; @@ -4777,10 +4791,24 @@ cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo); break; } + case IOP_RDUMP: { + nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | IOP_RDUMP); + nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length); + nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset); + nvmd_req.resp_addr_hi = + cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi); + nvmd_req.resp_addr_lo = + cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo); + break; + } default: 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; } @@ -4809,7 +4837,7 @@ rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) { kfree(fw_control_context); - return rc; + return -EBUSY; } ccb = &pm8001_ha->ccb_info[tag]; ccb->fw_control_context = fw_control_context; @@ -4861,6 +4889,10 @@ 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; } @@ -4927,7 +4959,7 @@ rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) { kfree(fw_control_context); - return rc; + return -EBUSY; } ccb = &pm8001_ha->ccb_info[tag]; ccb->fw_control_context = fw_control_context; @@ -4937,6 +4969,84 @@ return rc; } +ssize_t +pm8001_get_gsm_dump(struct device *cdev, u32 length, char *buf) +{ + u32 value, rem, offset = 0, bar = 0; + u32 index, work_offset, dw_length; + u32 shift_value, gsm_base, gsm_dump_offset; + char *direct_data; + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + + direct_data = buf; + gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset; + + /* check max is 1 Mbytes */ + if ((length > 0x100000) || (gsm_dump_offset & 3) || + ((gsm_dump_offset + length) > 0x1000000)) + return -EINVAL; + + if (pm8001_ha->chip_id == chip_8001) + bar = 2; + else + bar = 1; + + work_offset = gsm_dump_offset & 0xFFFF0000; + offset = gsm_dump_offset & 0x0000FFFF; + gsm_dump_offset = work_offset; + /* adjust length to dword boundary */ + rem = length & 3; + dw_length = length >> 2; + + for (index = 0; index < dw_length; index++) { + if ((work_offset + offset) & 0xFFFF0000) { + if (pm8001_ha->chip_id == chip_8001) + shift_value = ((gsm_dump_offset + offset) & + SHIFT_REG_64K_MASK); + else + shift_value = (((gsm_dump_offset + offset) & + SHIFT_REG_64K_MASK) >> + SHIFT_REG_BIT_SHIFT); + + if (pm8001_ha->chip_id == chip_8001) { + gsm_base = GSM_BASE; + if (-1 == pm8001_bar4_shift(pm8001_ha, + (gsm_base + shift_value))) + return -EIO; + } else { + gsm_base = 0; + if (-1 == pm80xx_bar4_shift(pm8001_ha, + (gsm_base + shift_value))) + return -EIO; + } + gsm_dump_offset = (gsm_dump_offset + offset) & + 0xFFFF0000; + work_offset = 0; + offset = offset & 0x0000FFFF; + } + value = pm8001_cr32(pm8001_ha, bar, (work_offset + offset) & + 0x0000FFFF); + direct_data += sprintf(direct_data, "%08x ", value); + offset += 4; + } + if (rem != 0) { + value = pm8001_cr32(pm8001_ha, bar, (work_offset + offset) & + 0x0000FFFF); + /* xfr for non_dw */ + direct_data += sprintf(direct_data, "%08x ", value); + } + /* Shift back to BAR4 original address */ + if (-1 == pm8001_bar4_shift(pm8001_ha, 0)) + return -EIO; + pm8001_ha->fatal_forensic_shift_offset += 1024; + + if (pm8001_ha->fatal_forensic_shift_offset >= 0x100000) + pm8001_ha->fatal_forensic_shift_offset = 0; + return direct_data - buf; +} + int pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u32 state) @@ -4975,7 +5085,7 @@ 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]; @@ -4984,6 +5094,8 @@ 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; }