static int qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job) { struct Scsi_Host *host = bsg_job->shost; scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; int ret = 0; uint32_t len; uint32_t oper; bsg_job->reply->reply_payload_rcv_len = 0; if (!IS_QLA24XX_TYPE(ha) || !IS_QLA25XX(ha)) { ret = -EINVAL; goto exit_fcp_prio_cfg; } if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) || test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { ret = -EBUSY; goto exit_fcp_prio_cfg; } /* Get the sub command */ oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; /* Only set config is allowed if config memory is not allocated */ if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) { ret = -EINVAL; goto exit_fcp_prio_cfg; } switch (oper) { case QLFC_FCP_PRIO_DISABLE: if (ha->flags.fcp_prio_enabled) { ha->flags.fcp_prio_enabled = 0; ha->fcp_prio_cfg->attributes &= ~FCP_PRIO_ATTR_ENABLE; qla24xx_update_all_fcp_prio(vha); bsg_job->reply->result = DID_OK; } else { ret = -EINVAL; bsg_job->reply->result = (DID_ERROR << 16); goto exit_fcp_prio_cfg; } break; case QLFC_FCP_PRIO_ENABLE: if (!ha->flags.fcp_prio_enabled) { if (ha->fcp_prio_cfg) { ha->flags.fcp_prio_enabled = 1; ha->fcp_prio_cfg->attributes |= FCP_PRIO_ATTR_ENABLE; qla24xx_update_all_fcp_prio(vha); bsg_job->reply->result = DID_OK; } else { ret = -EINVAL; bsg_job->reply->result = (DID_ERROR << 16); goto exit_fcp_prio_cfg; } } break; case QLFC_FCP_PRIO_GET_CONFIG: len = bsg_job->reply_payload.payload_len; if (!len || len > FCP_PRIO_CFG_SIZE) { ret = -EINVAL; bsg_job->reply->result = (DID_ERROR << 16); goto exit_fcp_prio_cfg; } bsg_job->reply->result = DID_OK; bsg_job->reply->reply_payload_rcv_len = sg_copy_from_buffer( bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg, len); break; case QLFC_FCP_PRIO_SET_CONFIG: len = bsg_job->request_payload.payload_len; if (!len || len > FCP_PRIO_CFG_SIZE) { bsg_job->reply->result = (DID_ERROR << 16); ret = -EINVAL; goto exit_fcp_prio_cfg; } if (!ha->fcp_prio_cfg) { ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE); if (!ha->fcp_prio_cfg) { qla_printk(KERN_WARNING, ha, "Unable to allocate memory " "for fcp prio config data (%x).\n", FCP_PRIO_CFG_SIZE); bsg_job->reply->result = (DID_ERROR << 16); ret = -ENOMEM; goto exit_fcp_prio_cfg; } } memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE); sg_copy_to_buffer(bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg, FCP_PRIO_CFG_SIZE); /* validate fcp priority data */ if (!qla24xx_fcp_prio_cfg_valid( (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) { bsg_job->reply->result = (DID_ERROR << 16); ret = -EINVAL; /* If buffer was invalidatic int * fcp_prio_cfg is of no use */ vfree(ha->fcp_prio_cfg); ha->fcp_prio_cfg = NULL; goto exit_fcp_prio_cfg; } ha->flags.fcp_prio_enabled = 0; if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE) ha->flags.fcp_prio_enabled = 1; qla24xx_update_all_fcp_prio(vha); bsg_job->reply->result = DID_OK; break; default: ret = -EINVAL; break; } exit_fcp_prio_cfg: bsg_job->job_done(bsg_job); return ret; }
/* * qla2x00_initialize_adapter * Initialize board. * * Input: * ha = adapter block pointer. * * Returns: * 0 = success */ int qla2x00_initialize_adapter(scsi_qla_host_t *vha) { int rval; struct qla_hw_data *ha = vha->hw; struct req_que *req = ha->req_q_map[0]; /* Clear adapter flags. */ vha->flags.online = 0; ha->flags.chip_reset_done = 0; vha->flags.reset_active = 0; ha->flags.pci_channel_io_perm_failure = 0; ha->flags.eeh_busy = 0; ha->flags.thermal_supported = 1; atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); atomic_set(&vha->loop_state, LOOP_DOWN); vha->device_flags = DFLG_NO_CABLE; vha->dpc_flags = 0; vha->flags.management_server_logged_in = 0; vha->marker_needed = 0; ha->isp_abort_cnt = 0; ha->beacon_blink_led = 0; set_bit(0, ha->req_qid_map); set_bit(0, ha->rsp_qid_map); ql_dbg(ql_dbg_init, vha, 0x0040, "Configuring PCI space...\n"); rval = ha->isp_ops->pci_config(vha); if (rval) { ql_log(ql_log_warn, vha, 0x0044, "Unable to configure PCI space.\n"); return (rval); } ha->isp_ops->reset_chip(vha); rval = qla2xxx_get_flash_info(vha); if (rval) { ql_log(ql_log_fatal, vha, 0x004f, "Unable to validate FLASH data.\n"); return (rval); } ha->isp_ops->get_flash_version(vha, req->ring); ql_dbg(ql_dbg_init, vha, 0x0061, "Configure NVRAM parameters...\n"); ha->isp_ops->nvram_config(vha); if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ ql_log(ql_log_info, vha, 0x0077, "Masking HBA WWPN " "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n", vha->port_name[0], vha->port_name[1], vha->port_name[2], vha->port_name[3], vha->port_name[4], vha->port_name[5], vha->port_name[6], vha->port_name[7]); return QLA_FUNCTION_FAILED; } ql_dbg(ql_dbg_init, vha, 0x0078, "Verifying loaded RISC code...\n"); if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) { rval = ha->isp_ops->chip_diag(vha); if (rval) return (rval); rval = qla2x00_setup_chip(vha); if (rval) return (rval); } if (IS_QLA84XX(ha)) { ha->cs84xx = qla84xx_get_chip(vha); if (!ha->cs84xx) { ql_log(ql_log_warn, vha, 0x00d0, "Unable to configure ISP84XX.\n"); return QLA_FUNCTION_FAILED; } } if (qla_ini_mode_enabled(vha)) rval = qla2x00_init_rings(vha); ha->flags.chip_reset_done = 1; if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) { /* Issue verify 84xx FW IOCB to complete 84xx initialization */ rval = qla84xx_init_chip(vha); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x00d4, "Unable to initialize ISP84XX.\n"); qla84xx_put_chip(vha); } } if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) qla24xx_read_fcp_prio_cfg(vha); return (rval); }
static int qla2x00_fdmi_rpa(scsi_qla_host_t *vha) { int rval, alen; uint32_t size, max_frame_size; struct qla_hw_data *ha = vha->hw; ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; uint8_t *entries; struct ct_fdmi_port_attr *eiter; struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, RPA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE); size = WWN_SIZE + 4; ct_req->req.rpa.attrs.count = __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1); entries = ct_req->req.rpa.port_name; eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES); eiter->len = __constant_cpu_to_be16(4 + 32); eiter->a.fc4_types[2] = 0x01; size += 4 + 32; ql_dbg(ql_dbg_disc, vha, 0x2039, "FC4_TYPES=%02x %02x.\n", eiter->a.fc4_types[2], eiter->a.fc4_types[1]); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); eiter->len = __constant_cpu_to_be16(4 + 4); if (IS_CNA_CAPABLE(ha)) eiter->a.sup_speed = __constant_cpu_to_be32( FDMI_PORT_SPEED_10GB); else if (IS_QLA25XX(ha)) eiter->a.sup_speed = __constant_cpu_to_be32( FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); else if (IS_QLA24XX_TYPE(ha)) eiter->a.sup_speed = __constant_cpu_to_be32( FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| FDMI_PORT_SPEED_4GB); else if (IS_QLA23XX(ha)) eiter->a.sup_speed =__constant_cpu_to_be32( FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB); else eiter->a.sup_speed = __constant_cpu_to_be32( FDMI_PORT_SPEED_1GB); size += 4 + 4; ql_dbg(ql_dbg_disc, vha, 0x203a, "Supported_Speed=%x.\n", eiter->a.sup_speed); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); eiter->len = __constant_cpu_to_be16(4 + 4); switch (ha->link_data_rate) { case PORT_SPEED_1GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB); break; case PORT_SPEED_2GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB); break; case PORT_SPEED_4GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB); break; case PORT_SPEED_8GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB); break; case PORT_SPEED_10GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB); break; case PORT_SPEED_16GB: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB); break; default: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); break; } size += 4 + 4; ql_dbg(ql_dbg_disc, vha, 0x203b, "Current_Speed=%x.\n", eiter->a.cur_speed); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); eiter->len = __constant_cpu_to_be16(4 + 4); max_frame_size = IS_FWI2_CAPABLE(ha) ? le16_to_cpu(icb24->frame_payload_size): le16_to_cpu(ha->init_cb->frame_payload_size); eiter->a.max_frame_size = cpu_to_be32(max_frame_size); size += 4 + 4; ql_dbg(ql_dbg_disc, vha, 0x203c, "Max_Frame_Size=%x.\n", eiter->a.max_frame_size); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME); alen = strlen(eiter->a.os_dev_name); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x204b, "OS_Device_Name=%s.\n", eiter->a.os_dev_name); if (strlen(fc_host_system_hostname(vha->host))) { ct_req->req.rpa.attrs.count = __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); eiter = (struct ct_fdmi_port_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), "%s", fc_host_system_hostname(vha->host)); alen = strlen(eiter->a.host_name); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name); } qla2x00_update_ms_fdmi_iocb(vha, size + 16); ql_dbg(ql_dbg_disc, vha, 0x203e, "RPA portname= %02x%02x%02x%02x%02X%02x%02x%02x size=%d.\n", ct_req->req.rpa.port_name[0], ct_req->req.rpa.port_name[1], ct_req->req.rpa.port_name[2], ct_req->req.rpa.port_name[3], ct_req->req.rpa.port_name[4], ct_req->req.rpa.port_name[5], ct_req->req.rpa.port_name[6], ct_req->req.rpa.port_name[7], size); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079, entries, size); rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, sizeof(ms_iocb_entry_t)); if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_disc, vha, 0x2040, "RPA issue IOCB failed (%d).\n", rval); } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; } else { ql_dbg(ql_dbg_disc, vha, 0x2041, "RPA exiting nornally.\n"); } return rval; }