int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value) { u32 reg_val; unsigned long start; pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, shift_value); /* confirm the setting is written */ start = jiffies + HZ; /* 1 sec */ do { reg_val = pm8001_cr32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER); } while ((reg_val != shift_value) && time_before(jiffies, start)); if (reg_val != shift_value) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" " = 0x%x\n", reg_val)); return -1; } return 0; }
/** * pm8001_mem_alloc - allocate memory for pm8001. * @pdev: pci device. * @virt_addr: the allocated virtual address * @pphys_addr_hi: the physical address high byte address. * @pphys_addr_lo: the physical address low byte address. * @mem_size: memory size. */ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr, dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo, u32 mem_size, u32 align) { caddr_t mem_virt_alloc; dma_addr_t mem_dma_handle; u64 phys_align; u64 align_offset = 0; if (align) align_offset = (dma_addr_t)align - 1; mem_virt_alloc = pci_alloc_consistent(pdev, mem_size + align, &mem_dma_handle); if (!mem_virt_alloc) { pm8001_printk("memory allocation error\n"); return -1; } memset((void *)mem_virt_alloc, 0, mem_size+align); *pphys_addr = mem_dma_handle; phys_align = (*pphys_addr + align_offset) & ~align_offset; *virt_addr = (void *)mem_virt_alloc + phys_align - *pphys_addr; *pphys_addr_hi = upper_32_bits(phys_align); *pphys_addr_lo = lower_32_bits(phys_align); return 0; }
static int pm8001_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf) { struct domain_device *dev = task->dev; struct pm8001_hba_info *pm8001_ha; struct pm8001_device *pm8001_dev; struct pm8001_port *port = NULL; struct sas_task *t = task; struct pm8001_ccb_info *ccb; u32 tag = 0xdeadbeef, rc, n_elem = 0; u32 n = num; unsigned long flags = 0, flags_libsas = 0; if (!dev->port) { struct task_status_struct *tsm = &t->task_status; tsm->resp = SAS_TASK_UNDELIVERED; tsm->stat = SAS_PHY_DOWN; if (dev->dev_type != SATA_DEV) t->task_done(t); return 0; } pm8001_ha = pm8001_find_ha_by_dev(task->dev); PM8001_IO_DBG(pm8001_ha, pm8001_printk("pm8001_task_exec device \n ")); spin_lock_irqsave(&pm8001_ha->lock, flags); do { dev = t->dev; pm8001_dev = dev->lldd_dev; if (DEV_IS_GONE(pm8001_dev)) { if (pm8001_dev) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("device %d not ready.\n", pm8001_dev->device_id)); } else { PM8001_IO_DBG(pm8001_ha, pm8001_printk("device %016llx not " "ready.\n", SAS_ADDR(dev->sas_addr))); } rc = SAS_PHY_DOWN; goto out_done; } port = &pm8001_ha->port[sas_find_local_port_id(dev)]; if (!port->port_attached) { if (sas_protocol_ata(t->task_proto)) { struct task_status_struct *ts = &t->task_status; ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_PHY_DOWN; spin_unlock_irqrestore(&pm8001_ha->lock, flags); spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags_libsas); t->task_done(t); spin_lock_irqsave(dev->sata_dev.ap->lock, flags_libsas); spin_lock_irqsave(&pm8001_ha->lock, flags); if (n > 1) t = list_entry(t->list.next, struct sas_task, list); continue; } else { struct task_status_struct *ts = &t->task_status; ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_PHY_DOWN; t->task_done(t); if (n > 1) t = list_entry(t->list.next, struct sas_task, list); continue; } } rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) goto err_out; ccb = &pm8001_ha->ccb_info[tag]; if (!sas_protocol_ata(t->task_proto)) { if (t->num_scatter) { n_elem = dma_map_sg(pm8001_ha->dev, t->scatter, t->num_scatter, t->data_dir); if (!n_elem) { rc = -ENOMEM; goto err_out_tag; } } } else { n_elem = t->num_scatter; } t->lldd_task = ccb; ccb->n_elem = n_elem; ccb->ccb_tag = tag; ccb->task = t; switch (t->task_proto) { case SAS_PROTOCOL_SMP: rc = pm8001_task_prep_smp(pm8001_ha, ccb); break; case SAS_PROTOCOL_SSP: if (is_tmf) rc = pm8001_task_prep_ssp_tm(pm8001_ha, ccb, tmf); else rc = pm8001_task_prep_ssp(pm8001_ha, ccb); break; case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: rc = pm8001_task_prep_ata(pm8001_ha, ccb); break; default: dev_printk(KERN_ERR, pm8001_ha->dev, "unknown sas_task proto: 0x%x\n", t->task_proto); rc = -EINVAL; break; } if (rc) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("rc is %x\n", rc)); goto err_out_tag; } /* TODO: select normal or high priority */ spin_lock(&t->task_state_lock); t->task_state_flags |= SAS_TASK_AT_INITIATOR; spin_unlock(&t->task_state_lock); pm8001_dev->running_req++; if (n > 1) t = list_entry(t->list.next, struct sas_task, list); } while (--n);
static ssize_t pm8001_store_update_fw(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) { 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; char *cmd_ptr, *filename_ptr; int res, i; int flash_command = FLASH_CMD_NONE; int err = 0; if (!capable(CAP_SYS_ADMIN)) return -EACCES; cmd_ptr = kzalloc(count*2, GFP_KERNEL); if (!cmd_ptr) { err = FAIL_OUT_MEMORY; goto out; } filename_ptr = cmd_ptr + count; res = sscanf(buf, "%s %s", cmd_ptr, filename_ptr); if (res != 2) { err = FAIL_PARAMETERS; goto out1; } for (i = 0; flash_command_table[i].code != FLASH_CMD_NONE; i++) { if (!memcmp(flash_command_table[i].command, cmd_ptr, strlen(cmd_ptr))) { flash_command = flash_command_table[i].code; break; } } if (flash_command == FLASH_CMD_NONE) { err = FAIL_PARAMETERS; goto out1; } if (pm8001_ha->fw_status == FLASH_IN_PROGRESS) { err = FLASH_IN_PROGRESS; goto out1; } err = request_firmware(&pm8001_ha->fw_image, filename_ptr, pm8001_ha->dev); if (err) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Failed to load firmware image file %s," " error %d\n", filename_ptr, err)); err = FAIL_OPEN_BIOS_FILE; goto out1; } switch (flash_command) { case FLASH_CMD_UPDATE: pm8001_ha->fw_status = FLASH_IN_PROGRESS; err = pm8001_update_flash(pm8001_ha); break; case FLASH_CMD_SET_NVMD: pm8001_ha->fw_status = FLASH_IN_PROGRESS; err = pm8001_set_nvmd(pm8001_ha); break; default: pm8001_ha->fw_status = FAIL_PARAMETERS; err = FAIL_PARAMETERS; break; } release_firmware(pm8001_ha->fw_image); out1: kfree(cmd_ptr); out: pm8001_ha->fw_status = err; if (!err) return count; else return -err; }
/** * pm80xx_get_encrypt_info - Check for encryption * @pm8001_ha: our hba card information. */ static int pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha) { u32 scratch3_value; int ret = -1; /* Read encryption status from SCRATCH PAD 3 */ scratch3_value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3); if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == SCRATCH_PAD3_ENC_READY) { if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED) pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMF_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMA_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMB_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; pm8001_ha->encrypt_info.status = 0; PM8001_INIT_DBG(pm8001_ha, pm8001_printk( "Encryption: SCRATCH_PAD3_ENC_READY 0x%08X." "Cipher mode 0x%x Sec mode 0x%x status 0x%x\n", scratch3_value, pm8001_ha->encrypt_info.cipher_mode, pm8001_ha->encrypt_info.sec_mode, pm8001_ha->encrypt_info.status)); ret = 0; } else if ((scratch3_value & SCRATCH_PAD3_ENC_READY) == SCRATCH_PAD3_ENC_DISABLED) { PM8001_INIT_DBG(pm8001_ha, pm8001_printk( "Encryption: SCRATCH_PAD3_ENC_DISABLED 0x%08X\n", scratch3_value)); pm8001_ha->encrypt_info.status = 0xFFFFFFFF; pm8001_ha->encrypt_info.cipher_mode = 0; pm8001_ha->encrypt_info.sec_mode = 0; ret = 0; } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == SCRATCH_PAD3_ENC_DIS_ERR) { pm8001_ha->encrypt_info.status = (scratch3_value & SCRATCH_PAD3_ERR_CODE) >> 16; if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED) pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMF_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMA_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA; if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == SCRATCH_PAD3_SMB_ENABLED) pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; PM8001_INIT_DBG(pm8001_ha, pm8001_printk( "Encryption: SCRATCH_PAD3_DIS_ERR 0x%08X." "Cipher mode 0x%x sec mode 0x%x status 0x%x\n", scratch3_value, pm8001_ha->encrypt_info.cipher_mode, pm8001_ha->encrypt_info.sec_mode, pm8001_ha->encrypt_info.status)); } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
/** * pm80xx_set_sas_protocol_timer_config - support the SAS Protocol * Timer configuration page * @pm8001_ha: our hba card information. */ static int pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha) { struct set_ctrl_cfg_req payload; struct inbound_queue_table *circularQ; SASProtocolTimerConfig_t SASConfigPage; int rc; u32 tag; u32 opc = OPC_INB_SET_CONTROLLER_CONFIG; memset(&payload, 0, sizeof(struct set_ctrl_cfg_req)); memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t)); rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) return -1; circularQ = &pm8001_ha->inbnd_q_tbl[0]; payload.tag = cpu_to_le32(tag); SASConfigPage.pageCode = SAS_PROTOCOL_TIMER_CONFIG_PAGE; SASConfigPage.MST_MSI = 3 << 15; SASConfigPage.STP_SSP_MCT_TMO = (STP_MCT_TMO << 16) | SSP_MCT_TMO; SASConfigPage.STP_FRM_TMO = (SAS_MAX_OPEN_TIME << 24) | (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER; SASConfigPage.STP_IDLE_TMO = STP_IDLE_TIME; if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF) SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF; SASConfigPage.OPNRJT_RTRY_INTVL = (SAS_MFD << 16) | SAS_OPNRJT_RTRY_INTVL; SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO = (SAS_DOPNRJT_RTRY_TMO << 16) | SAS_COPNRJT_RTRY_TMO; SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR = (SAS_DOPNRJT_RTRY_THR << 16) | SAS_COPNRJT_RTRY_THR; SASConfigPage.MAX_AIP = SAS_MAX_AIP; PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.pageCode " "0x%08x\n", SASConfigPage.pageCode)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MST_MSI " " 0x%08x\n", SASConfigPage.MST_MSI)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.STP_SSP_MCT_TMO " " 0x%08x\n", SASConfigPage.STP_SSP_MCT_TMO)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.STP_FRM_TMO " " 0x%08x\n", SASConfigPage.STP_FRM_TMO)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.STP_IDLE_TMO " " 0x%08x\n", SASConfigPage.STP_IDLE_TMO)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.OPNRJT_RTRY_INTVL " " 0x%08x\n", SASConfigPage.OPNRJT_RTRY_INTVL)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO " " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR " " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MAX_AIP " " 0x%08x\n", SASConfigPage.MAX_AIP)); memcpy(&payload.cfg_pg, &SASConfigPage, sizeof(SASProtocolTimerConfig_t)); rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); if (rc) pm8001_tag_free(pm8001_ha, tag); return rc; }
ssize_t pm80xx_get_fatal_dump(struct device *cdev, struct device_attribute *attr, char *buf) { 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; void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr; u32 accum_len , reg_val, index, *temp; unsigned long start; u8 *direct_data; char *fatal_error_data = buf; pm8001_ha->forensic_info.data_buf.direct_data = buf; if (pm8001_ha->chip_id == chip_8001) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha->forensic_info.data_buf.direct_data, "Not supported for SPC controller"); return (char *)pm8001_ha->forensic_info.data_buf.direct_data - (char *)buf; } if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("forensic_info TYPE_NON_FATAL..............\n")); direct_data = (u8 *)fatal_error_data; pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL; pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET; pm8001_ha->forensic_info.data_buf.read_len = 0; pm8001_ha->forensic_info.data_buf.direct_data = direct_data; /* start to get data */ /* Program the MEMBASE II Shifting Register with 0x00.*/ pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, pm8001_ha->fatal_forensic_shift_offset); pm8001_ha->forensic_last_offset = 0; pm8001_ha->forensic_fatal_step = 0; pm8001_ha->fatal_bar_loc = 0; } /* Read until accum_len is retrived */ accum_len = pm8001_mr32(fatal_table_address, MPI_FATAL_EDUMP_TABLE_ACCUM_LEN); PM8001_IO_DBG(pm8001_ha, pm8001_printk("accum_len 0x%x\n", accum_len)); if (accum_len == 0xFFFFFFFF) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("Possible PCI issue 0x%x not expected\n", accum_len)); return -EIO; } if (accum_len == 0 || accum_len >= 0x100000) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha->forensic_info.data_buf.direct_data, "%08x ", 0xFFFFFFFF); return (char *)pm8001_ha->forensic_info.data_buf.direct_data - (char *)buf; } temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr; if (pm8001_ha->forensic_fatal_step == 0) { moreData: if (pm8001_ha->forensic_info.data_buf.direct_data) { /* Data is in bar, copy to host memory */ pm80xx_pci_mem_copy(pm8001_ha, pm8001_ha->fatal_bar_loc, pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr, pm8001_ha->forensic_info.data_buf.direct_len , 1); } pm8001_ha->fatal_bar_loc += pm8001_ha->forensic_info.data_buf.direct_len; pm8001_ha->forensic_info.data_buf.direct_offset += pm8001_ha->forensic_info.data_buf.direct_len; pm8001_ha->forensic_last_offset += pm8001_ha->forensic_info.data_buf.direct_len; pm8001_ha->forensic_info.data_buf.read_len = pm8001_ha->forensic_info.data_buf.direct_len; if (pm8001_ha->forensic_last_offset >= accum_len) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha->forensic_info.data_buf.direct_data, "%08x ", 3); for (index = 0; index < (SYSFS_OFFSET / 4); index++) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha-> forensic_info.data_buf.direct_data, "%08x ", *(temp + index)); } pm8001_ha->fatal_bar_loc = 0; pm8001_ha->forensic_fatal_step = 1; pm8001_ha->fatal_forensic_shift_offset = 0; pm8001_ha->forensic_last_offset = 0; return (char *)pm8001_ha-> forensic_info.data_buf.direct_data - (char *)buf; } if (pm8001_ha->fatal_bar_loc < (64 * 1024)) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha-> forensic_info.data_buf.direct_data, "%08x ", 2); for (index = 0; index < (SYSFS_OFFSET / 4); index++) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha-> forensic_info.data_buf.direct_data, "%08x ", *(temp + index)); } return (char *)pm8001_ha-> forensic_info.data_buf.direct_data - (char *)buf; } /* Increment the MEMBASE II Shifting Register value by 0x100.*/ pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha->forensic_info.data_buf.direct_data, "%08x ", 2); for (index = 0; index < 256; index++) { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha-> forensic_info.data_buf.direct_data, "%08x ", *(temp + index)); } pm8001_ha->fatal_forensic_shift_offset += 0x100; pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, pm8001_ha->fatal_forensic_shift_offset); pm8001_ha->fatal_bar_loc = 0; return (char *)pm8001_ha->forensic_info.data_buf.direct_data - (char *)buf; } if (pm8001_ha->forensic_fatal_step == 1) { pm8001_ha->fatal_forensic_shift_offset = 0; /* Read 64K of the debug data. */ pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, pm8001_ha->fatal_forensic_shift_offset); pm8001_mw32(fatal_table_address, MPI_FATAL_EDUMP_TABLE_HANDSHAKE, MPI_FATAL_EDUMP_HANDSHAKE_RDY); /* Poll FDDHSHK until clear */ start = jiffies + (2 * HZ); /* 2 sec */ do { reg_val = pm8001_mr32(fatal_table_address, MPI_FATAL_EDUMP_TABLE_HANDSHAKE); } while ((reg_val) && time_before(jiffies, start)); if (reg_val != 0) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" " = 0x%x\n", reg_val)); return -EIO; } /* Read the next 64K of the debug data. */ pm8001_ha->forensic_fatal_step = 0; if (pm8001_mr32(fatal_table_address, MPI_FATAL_EDUMP_TABLE_STATUS) != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) { pm8001_mw32(fatal_table_address, MPI_FATAL_EDUMP_TABLE_HANDSHAKE, 0); goto moreData; } else { pm8001_ha->forensic_info.data_buf.direct_data += sprintf(pm8001_ha-> forensic_info.data_buf.direct_data, "%08x ", 4); pm8001_ha->forensic_info.data_buf.read_len = 0xFFFFFFFF; pm8001_ha->forensic_info.data_buf.direct_len = 0; pm8001_ha->forensic_info.data_buf.direct_offset = 0; pm8001_ha->forensic_info.data_buf.read_len = 0; } } return (char *)pm8001_ha->forensic_info.data_buf.direct_data - (char *)buf; }
static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) { void __iomem *base_addr; u32 value; u32 offset; u32 pcibar; u32 pcilogic; value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0); offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */ PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Scratchpad 0 Offset: 0x%x value 0x%x\n", offset, value)); pcilogic = (value & 0xFC000000) >> 26; pcibar = get_pci_bar_index(pcilogic); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("Scratchpad 0 PCI BAR: %d\n", pcibar)); pm8001_ha->main_cfg_tbl_addr = base_addr = pm8001_ha->io_mem[pcibar].memvirtaddr + offset; pm8001_ha->general_stat_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) & 0xFFFFFF); pm8001_ha->inbnd_q_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C) & 0xFFFFFF); pm8001_ha->outbnd_q_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x20) & 0xFFFFFF); pm8001_ha->ivt_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C) & 0xFFFFFF); pm8001_ha->pspa_q_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x90) & 0xFFFFFF); pm8001_ha->fatal_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0xA0) & 0xFFFFFF); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("GST OFFSET 0x%x\n", pm8001_cr32(pm8001_ha, pcibar, offset + 0x18))); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("INBND OFFSET 0x%x\n", pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C))); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("OBND OFFSET 0x%x\n", pm8001_cr32(pm8001_ha, pcibar, offset + 0x20))); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("IVT OFFSET 0x%x\n", pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C))); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("PSPA OFFSET 0x%x\n", pm8001_cr32(pm8001_ha, pcibar, offset + 0x90))); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("addr - main cfg %p general status %p\n", pm8001_ha->main_cfg_tbl_addr, pm8001_ha->general_stat_tbl_addr)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("addr - inbnd %p obnd %p\n", pm8001_ha->inbnd_q_tbl_addr, pm8001_ha->outbnd_q_tbl_addr)); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("addr - pspa %p ivt %p\n", pm8001_ha->pspa_q_tbl_addr, pm8001_ha->ivt_tbl_addr)); }
/** * check_fw_ready - The LLDD check if the FW is ready, if not, return error. * @pm8001_ha: our hba card information */ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) { u32 value; u32 max_wait_count; u32 max_wait_time; int ret = 0; /* reset / PCIe ready */ max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */ do { udelay(1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while ((value == 0xFFFFFFFF) && (--max_wait_count)); /* check ila status */ max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */ do { udelay(1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_ILA_READY) != SCRATCH_PAD_ILA_READY) && (--max_wait_count)); if (!max_wait_count) ret = -1; else { PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" ila ready status in %d millisec\n", (max_wait_time - max_wait_count))); } /* check RAAE status */ max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */ do { udelay(1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_RAAE_READY) != SCRATCH_PAD_RAAE_READY) && (--max_wait_count)); if (!max_wait_count) ret = -1; else { PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" raae ready status in %d millisec\n", (max_wait_time - max_wait_count))); } /* check iop0 status */ max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */ do { udelay(1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) && (--max_wait_count)); if (!max_wait_count) ret = -1; else { PM8001_MSG_DBG(pm8001_ha, pm8001_printk(" iop0 ready status in %d millisec\n", (max_wait_time - max_wait_count))); } /* check iop1 status only for 16 port controllers */ if ((pm8001_ha->chip_id != chip_8008) && (pm8001_ha->chip_id != chip_8009)) { /* 200 milli sec */ max_wait_time = max_wait_count = 200 * 1000; do { udelay(1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_IOP1_READY) != SCRATCH_PAD_IOP1_READY) && (--max_wait_count)); if (!max_wait_count) ret = -1; else { PM8001_MSG_DBG(pm8001_ha, pm8001_printk( "iop1 ready status in %d millisec\n", (max_wait_time - max_wait_count))); } } return ret; }