static int qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) { int rval; struct qla_hw_data *ha = vha->hw; uint16_t i; uint8_t *entry; struct sns_cmd_pkt *sns_cmd; uint16_t gid_pt_sns_data_size; gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha); sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, gid_pt_sns_data_size); sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_disc, vha, 0x206d, "GID_PT Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gid_data[8] != 0x80 || sns_cmd->p.gid_data[9] != 0x02) { ql_dbg(ql_dbg_disc, vha, 0x202f, "GID_PT failed, rejected request, gid_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, sns_cmd->p.gid_data, 16); rval = QLA_FUNCTION_FAILED; } else { for (i = 0; i < ha->max_fibre_devices; i++) { entry = &sns_cmd->p.gid_data[(i * 4) + 16]; list[i].d_id.b.domain = entry[1]; list[i].d_id.b.area = entry[2]; list[i].d_id.b.al_pa = entry[3]; if (entry[0] & BIT_7) { list[i].d_id.b.rsvd_1 = entry[0]; break; } } if (i == ha->max_fibre_devices) rval = QLA_FUNCTION_FAILED; } return (rval); }
static int qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, struct ct_sns_rsp *ct_rsp, const char *routine) { int rval; uint16_t comp_status; struct qla_hw_data *ha = vha->hw; rval = QLA_FUNCTION_FAILED; if (ms_pkt->entry_status != 0) { ql_dbg(ql_dbg_disc, vha, 0x2031, "%s failed, error status (%x) on port_id: %02x%02x%02x.\n", routine, ms_pkt->entry_status, vha->d_id.b.domain, vha->d_id.b.area, vha->d_id.b.al_pa); } else { if (IS_FWI2_CAPABLE(ha)) comp_status = le16_to_cpu( ((struct ct_entry_24xx *)ms_pkt)->comp_status); else comp_status = le16_to_cpu(ms_pkt->status); switch (comp_status) { case CS_COMPLETE: case CS_DATA_UNDERRUN: case CS_DATA_OVERRUN: /* Overrun? */ if (ct_rsp->header.response != __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077, "%s failed rejected request on port_id: " "%02x%02x%02x.\n", routine, vha->d_id.b.domain, vha->d_id.b.area, vha->d_id.b.al_pa); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2078, (uint8_t *)&ct_rsp->header, sizeof(struct ct_rsp_hdr)); rval = QLA_INVALID_COMMAND; } else rval = QLA_SUCCESS; break; default: ql_dbg(ql_dbg_disc, vha, 0x2033, "%s failed, completion status (%x) on port_id: " "%02x%02x%02x.\n", routine, comp_status, vha->d_id.b.domain, vha->d_id.b.area, vha->d_id.b.al_pa); break; } } return rval; }
/** * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. * HBA. * @ha: HA context * * This command uses the old Exectute SNS Command mailbox routine. * * Returns 0 on success. */ static int qla2x00_sns_rnn_id(scsi_qla_host_t *vha) { int rval; struct qla_hw_data *ha = vha->hw; struct sns_cmd_pkt *sns_cmd; /* Issue RNN_ID. */ /* Prepare SNS command request. */ sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, RNN_ID_SNS_DATA_SIZE); /* Prepare SNS command arguments -- port_id, nodename. */ sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; sns_cmd->p.cmd.param[1] = vha->d_id.b.area; sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; sns_cmd->p.cmd.param[4] = vha->node_name[7]; sns_cmd->p.cmd.param[5] = vha->node_name[6]; sns_cmd->p.cmd.param[6] = vha->node_name[5]; sns_cmd->p.cmd.param[7] = vha->node_name[4]; sns_cmd->p.cmd.param[8] = vha->node_name[3]; sns_cmd->p.cmd.param[9] = vha->node_name[2]; sns_cmd->p.cmd.param[10] = vha->node_name[1]; sns_cmd->p.cmd.param[11] = vha->node_name[0]; /* Execute SNS command. */ rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { /*EMPTY*/ ql_dbg(ql_dbg_disc, vha, 0x204a, "RNN_ID Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.rnn_data[8] != 0x80 || sns_cmd->p.rnn_data[9] != 0x02) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b, "RNN_ID failed, rejected request, rnn_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c, sns_cmd->p.rnn_data, 16); rval = QLA_FUNCTION_FAILED; } else { ql_dbg(ql_dbg_disc, vha, 0x204c, "RNN_ID exiting normally.\n"); } return (rval); }
/** * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. * @ha: HA context * @list: switch info entries to populate * * This command uses the old Exectute SNS Command mailbox routine. * * Returns 0 on success. */ static int qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) { int rval = QLA_SUCCESS; struct qla_hw_data *ha = vha->hw; uint16_t i; struct sns_cmd_pkt *sns_cmd; for (i = 0; i < ha->max_fibre_devices; i++) { /* Issue GPN_ID */ /* Prepare SNS command request. */ sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD, GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); /* Prepare SNS command arguments -- port_id. */ sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; /* Execute SNS command. */ rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { /*EMPTY*/ ql_dbg(ql_dbg_disc, vha, 0x2032, "GPN_ID Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gpn_data[8] != 0x80 || sns_cmd->p.gpn_data[9] != 0x02) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e, "GPN_ID failed, rejected request, gpn_rsp:\n"); ql_dump_buffer(ql_dbg_disc, vha, 0x207f, sns_cmd->p.gpn_data, 16); rval = QLA_FUNCTION_FAILED; } else { /* Save portname */ memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], WWN_SIZE); } /* Last device exit. */ if (list[i].d_id.b.rsvd_1 != 0) break; } return (rval); }
/** * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. * @ha: HA context * * This command uses the old Exectute SNS Command mailbox routine. * * Returns 0 on success. */ static int qla2x00_sns_rft_id(scsi_qla_host_t *vha) { int rval; struct qla_hw_data *ha = vha->hw; struct sns_cmd_pkt *sns_cmd; /* Issue RFT_ID. */ /* Prepare SNS command request. */ sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, RFT_ID_SNS_DATA_SIZE); /* Prepare SNS command arguments -- port_id, FC-4 types */ sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; sns_cmd->p.cmd.param[1] = vha->d_id.b.area; sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ /* Execute SNS command. */ rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { /*EMPTY*/ ql_dbg(ql_dbg_disc, vha, 0x2060, "RFT_ID Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.rft_data[8] != 0x80 || sns_cmd->p.rft_data[9] != 0x02) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083, "RFT_ID failed, rejected request rft_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080, sns_cmd->p.rft_data, 16); rval = QLA_FUNCTION_FAILED; } else { ql_dbg(ql_dbg_disc, vha, 0x2073, "RFT_ID exiting normally.\n"); } return (rval); }
/** * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. * @ha: HA context * @list: switch info entries to populate * * This command uses the old Exectute SNS Command mailbox routine. * * NOTE: Non-Nx_Ports are not requested. * * Returns 0 on success. */ static int qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) { int rval; struct qla_hw_data *ha = vha->hw; uint16_t i; uint8_t *entry; struct sns_cmd_pkt *sns_cmd; uint16_t gid_pt_sns_data_size; gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha); /* Issue GID_PT. */ /* Prepare SNS command request. */ sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, gid_pt_sns_data_size); /* Prepare SNS command arguments -- port_type. */ sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; /* Execute SNS command. */ rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { /*EMPTY*/ ql_dbg(ql_dbg_disc, vha, 0x206d, "GID_PT Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gid_data[8] != 0x80 || sns_cmd->p.gid_data[9] != 0x02) { ql_dbg(ql_dbg_disc, vha, 0x202f, "GID_PT failed, rejected request, gid_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, sns_cmd->p.gid_data, 16); rval = QLA_FUNCTION_FAILED; } else { /* Set port IDs in switch info list. */ for (i = 0; i < ha->max_fibre_devices; i++) { entry = &sns_cmd->p.gid_data[(i * 4) + 16]; list[i].d_id.b.domain = entry[1]; list[i].d_id.b.area = entry[2]; list[i].d_id.b.al_pa = entry[3]; /* Last one exit. */ if (entry[0] & BIT_7) { list[i].d_id.b.rsvd_1 = entry[0]; break; } } /* * If we've used all available slots, then the switch is * reporting back more devices that we can handle with this * single call. Return a failed status, and let GA_NXT handle * the overload. */ if (i == ha->max_fibre_devices) rval = QLA_FUNCTION_FAILED; } return (rval); }
/** * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. * @ha: HA context * @fcport: fcport entry to updated * * This command uses the old Exectute SNS Command mailbox routine. * * Returns 0 on success. */ static int qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) { int rval = QLA_SUCCESS; struct qla_hw_data *ha = vha->hw; struct sns_cmd_pkt *sns_cmd; /* Issue GA_NXT. */ /* Prepare SNS command request. */ sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, GA_NXT_SNS_DATA_SIZE); /* Prepare SNS command arguments -- port_id. */ sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; /* Execute SNS command. */ rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { /*EMPTY*/ ql_dbg(ql_dbg_disc, vha, 0x205f, "GA_NXT Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gan_data[8] != 0x80 || sns_cmd->p.gan_data[9] != 0x02) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, "GA_NXT failed, rejected request ga_nxt_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, sns_cmd->p.gan_data, 16); rval = QLA_FUNCTION_FAILED; } else { /* Populate fc_port_t entry. */ fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; fcport->d_id.b.area = sns_cmd->p.gan_data[18]; fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) fcport->d_id.b.domain = 0xf0; ql_dbg(ql_dbg_disc, vha, 0x2061, "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x " "pn %02x%02x%02x%02x%02x%02x%02x%02x " "port_id=%02x%02x%02x.\n", fcport->node_name[0], fcport->node_name[1], fcport->node_name[2], fcport->node_name[3], fcport->node_name[4], fcport->node_name[5], fcport->node_name[6], fcport->node_name[7], fcport->port_name[0], fcport->port_name[1], fcport->port_name[2], fcport->port_name[3], fcport->port_name[4], fcport->port_name[5], fcport->port_name[6], fcport->port_name[7], fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); } return (rval); }
static int qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) { int rval = QLA_SUCCESS; struct qla_hw_data *ha = vha->hw; uint16_t i; struct sns_cmd_pkt *sns_cmd; for (i = 0; i < ha->max_fibre_devices; i++) { sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD, GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_disc, vha, 0x203f, "GNN_ID Send SNS failed (%d).\n", rval); } else if (sns_cmd->p.gnn_data[8] != 0x80 || sns_cmd->p.gnn_data[9] != 0x02) { ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082, "GNN_ID failed, rejected request, gnn_rsp:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a, sns_cmd->p.gnn_data, 16); rval = QLA_FUNCTION_FAILED; } else { memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], WWN_SIZE); ql_dbg(ql_dbg_disc, vha, 0x206e, "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x " "pn %02x%02x%02x%02x%02x%02x%02x%02x " "port_id=%02x%02x%02x.\n", list[i].node_name[0], list[i].node_name[1], list[i].node_name[2], list[i].node_name[3], list[i].node_name[4], list[i].node_name[5], list[i].node_name[6], list[i].node_name[7], list[i].port_name[0], list[i].port_name[1], list[i].port_name[2], list[i].port_name[3], list[i].port_name[4], list[i].port_name[5], list[i].port_name[6], list[i].port_name[7], list[i].d_id.b.domain, list[i].d_id.b.area, list[i].d_id.b.al_pa); } if (list[i].d_id.b.rsvd_1 != 0) break; } 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; }
static int qla2x00_fdmi_rhba(scsi_qla_host_t *vha) { int rval, alen; uint32_t size, sn; ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; uint8_t *entries; struct ct_fdmi_hba_attr *eiter; struct qla_hw_data *ha = vha->hw; ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, RHBA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE); ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1); memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE); size = 2 * WWN_SIZE + 4 + 4; ct_req->req.rhba.attrs.count = __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT); entries = ct_req->req.rhba.hba_identifier; eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME); eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE); memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); size += 4 + WWN_SIZE; ql_dbg(ql_dbg_disc, vha, 0x2025, "NodeName = %02x%02x%02x%02x%02x%02x%02x%02x.\n", eiter->a.node_name[0], eiter->a.node_name[1], eiter->a.node_name[2], eiter->a.node_name[3], eiter->a.node_name[4], eiter->a.node_name[5], eiter->a.node_name[6], eiter->a.node_name[7]); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER); strcpy(eiter->a.manufacturer, "QLogic Corporation"); alen = strlen(eiter->a.manufacturer); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x2026, "Manufacturer = %s.\n", eiter->a.manufacturer); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000); alen = strlen(eiter->a.serial_num); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x2027, "Serial no. = %s.\n", eiter->a.serial_num); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL); strcpy(eiter->a.model, ha->model_number); alen = strlen(eiter->a.model); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x2028, "Model Name = %s.\n", eiter->a.model); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); if (ha->model_desc) strncpy(eiter->a.model_desc, ha->model_desc, 80); alen = strlen(eiter->a.model_desc); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x2029, "Model Desc = %s.\n", eiter->a.model_desc); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); strcpy(eiter->a.hw_version, ha->adapter_id); alen = strlen(eiter->a.hw_version); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x202a, "Hardware ver = %s.\n", eiter->a.hw_version); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION); strcpy(eiter->a.driver_version, qla2x00_version_str); alen = strlen(eiter->a.driver_version); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x202b, "Driver ver = %s.\n", eiter->a.driver_version); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); strcpy(eiter->a.orom_version, "0.00"); alen = strlen(eiter->a.orom_version); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha , 0x202c, "Optrom vers = %s.\n", eiter->a.orom_version); eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); ha->isp_ops->fw_version_str(vha, eiter->a.fw_version); alen = strlen(eiter->a.fw_version); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; ql_dbg(ql_dbg_disc, vha, 0x202d, "Firmware vers = %s.\n", eiter->a.fw_version); qla2x00_update_ms_fdmi_iocb(vha, size + 16); ql_dbg(ql_dbg_disc, vha, 0x202e, "RHBA identifier = " "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", ct_req->req.rhba.hba_identifier[0], ct_req->req.rhba.hba_identifier[1], ct_req->req.rhba.hba_identifier[2], ct_req->req.rhba.hba_identifier[3], ct_req->req.rhba.hba_identifier[4], ct_req->req.rhba.hba_identifier[5], ct_req->req.rhba.hba_identifier[6], ct_req->req.rhba.hba_identifier[7], size); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076, 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, 0x2030, "RHBA issue IOCB failed (%d).\n", rval); } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && ct_rsp->header.explanation_code == CT_EXPL_ALREADY_REGISTERED) { ql_dbg(ql_dbg_disc, vha, 0x2034, "HBA already registered.\n"); rval = QLA_ALREADY_REGISTERED; } } else { ql_dbg(ql_dbg_disc, vha, 0x2035, "RHBA exiting normally.\n"); } return rval; }