/** * pm80xx_set_thermal_config - support the thermal configuration * @pm8001_ha: our hba card information. */ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha) { struct set_ctrl_cfg_req payload; struct inbound_queue_table *circularQ; int rc; u32 tag; u32 opc = OPC_INB_SET_CONTROLLER_CONFIG; memset(&payload, 0, sizeof(struct set_ctrl_cfg_req)); rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) return -1; circularQ = &pm8001_ha->inbnd_q_tbl[0]; payload.tag = cpu_to_le32(tag); payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) | (THERMAL_ENABLE << 8) | THERMAL_OP_CODE; payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8); rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); if (rc) pm8001_tag_free(pm8001_ha, tag); return rc; }
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);
/** * 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; }