qla_gs.c
来自「linux 内核源代码」· C语言 代码 · 共 1,899 行 · 第 1/4 页
C
1,899 行
ha->host_no)); } return rval;}/** * qla2x00_fdmi_dhba() - * @ha: HA context * * Returns 0 on success. */static intqla2x00_fdmi_dhba(scsi_qla_host_t *ha){ int rval; ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; /* Issue RPA */ /* Prepare common MS IOCB */ ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE, DHBA_RSP_SIZE); /* Prepare CT request */ ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD, DHBA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare FDMI command arguments -- portname. */ memcpy(ct_req->req.dhba.port_name, ha->port_name, WWN_SIZE); DEBUG13(printk("%s(%ld): DHBA portname=" "%02x%02x%02x%02x%02x%02x%02x%02x.\n", __func__, ha->host_no, ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1], ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3], ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5], ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7])); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, sizeof(ms_iocb_entry_t)); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3(printk("scsi(%ld): DHBA issue IOCB failed (%d).\n", ha->host_no, rval)); } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "DHBA") != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; } else { DEBUG2(printk("scsi(%ld): DHBA exiting normally.\n", ha->host_no)); } return rval;}/** * qla2x00_fdmi_rpa() - * @ha: HA context * * Returns 0 on success. */static intqla2x00_fdmi_rpa(scsi_qla_host_t *ha){ int rval, alen; uint32_t size, max_frame_size; 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; /* Issue RPA */ /* Prepare common MS IOCB */ /* Request size adjusted after CT preparation */ ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE); /* Prepare CT request */ ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, RPA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare FDMI command arguments -- attribute block, attributes. */ memcpy(ct_req->req.rpa.port_name, ha->port_name, WWN_SIZE); size = WWN_SIZE + 4; /* Attributes */ ct_req->req.rpa.attrs.count = __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1); entries = ct_req->req.rpa.port_name; /* FC4 types. */ 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; DEBUG13(printk("%s(%ld): FC4_TYPES=%02x %02x.\n", __func__, ha->host_no, eiter->a.fc4_types[2], eiter->a.fc4_types[1])); /* Supported speed. */ 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_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(ha) || IS_QLA54XX(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; DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no, eiter->a.sup_speed)); /* Current 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; default: eiter->a.cur_speed = __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); break; } size += 4 + 4; DEBUG13(printk("%s(%ld): CURRENT_SPEED=%x.\n", __func__, ha->host_no, eiter->a.cur_speed)); /* Max frame size. */ 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) ? (uint32_t) icb24->frame_payload_size: (uint32_t) ha->init_cb->frame_payload_size; eiter->a.max_frame_size = cpu_to_be32(max_frame_size); size += 4 + 4; DEBUG13(printk("%s(%ld): MAX_FRAME_SIZE=%x.\n", __func__, ha->host_no, eiter->a.max_frame_size)); /* OS device name. */ 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; DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, eiter->a.os_dev_name)); /* Hostname. */ if (strlen(fc_host_system_hostname(ha->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(ha->host)); alen = strlen(eiter->a.host_name); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); size += 4 + alen; DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__, ha->host_no, eiter->a.host_name)); } /* Update MS request size. */ qla2x00_update_ms_fdmi_iocb(ha, size + 16); DEBUG13(printk("%s(%ld): RPA portname=" "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__, ha->host_no, 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)); DEBUG13(qla2x00_dump_buffer(entries, size)); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, sizeof(ms_iocb_entry_t)); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3(printk("scsi(%ld): RPA issue IOCB failed (%d).\n", ha->host_no, rval)); } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RPA") != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; } else { DEBUG2(printk("scsi(%ld): RPA exiting normally.\n", ha->host_no)); } return rval;}/** * qla2x00_fdmi_register() - * @ha: HA context * * Returns 0 on success. */intqla2x00_fdmi_register(scsi_qla_host_t *ha){ int rval; rval = qla2x00_mgmt_svr_login(ha); if (rval) return rval; rval = qla2x00_fdmi_rhba(ha); if (rval) { if (rval != QLA_ALREADY_REGISTERED) return rval; rval = qla2x00_fdmi_dhba(ha); if (rval) return rval; rval = qla2x00_fdmi_rhba(ha); if (rval) return rval; } rval = qla2x00_fdmi_rpa(ha); return rval;}/** * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. * @ha: HA context * @list: switch info entries to populate * * Returns 0 on success. */intqla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list){ int rval; uint16_t i; ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; if (!IS_IIDMA_CAPABLE(ha)) return QLA_FUNCTION_FAILED; for (i = 0; i < MAX_FIBRE_DEVICES; i++) { /* Issue GFPN_ID */ /* Prepare common MS IOCB */ ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, GFPN_ID_RSP_SIZE); /* Prepare CT request */ ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, GFPN_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id */ ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; /* Execute MS IOCB */ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, sizeof(ms_iocb_entry_t)); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB " "failed (%d).\n", ha->host_no, rval)); } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GFPN_ID") != QLA_SUCCESS) { rval = QLA_FUNCTION_FAILED; } else { /* Save fabric portname */ memcpy(list[i].fabric_port_name, ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); } /* Last device exit. */ if (list[i].d_id.b.rsvd_1 != 0) break; } return (rval);}static inline void *qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size){ struct ct_entry_24xx *ct_pkt; ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); ct_pkt->entry_type = CT_IOCB_TYPE; ct_pkt->entry_count = 1; ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); ct_pkt->timeout = __constant_cpu_to_le16(59); ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); ct_pkt->cmd_byte_count = cpu_to_le32(req_size); ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; ct_pkt->vp_index = ha->vp_idx; return ct_pkt;}static inline struct ct_sns_req *qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size){ memset(ct_req, 0, sizeof(struct ct_sns_pkt)); ct_req->header.revision = 0x01; ct_req->header.gs_type = 0xFA; ct_req->header.gs_subtype = 0x01; ct_req->command = cpu_to_be16(cmd); ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); return ct_req;}/** * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. * @ha: HA context * @list: switch info entries to populate * * Returns 0 on success. */intqla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list){ int rval; uint16_t i; ms_iocb_entry_t *ms_pkt; struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; if (!IS_IIDMA_CAPABLE(ha)) return QLA_FUNCTION_FAILED; if (!ha->flags.gpsc_supported) return QLA_FUNCTION_FAILED; rval = qla2x00_mgmt_svr_login(ha); if (rval) return rval; for (i = 0; i < MAX_FIBRE_DEVICES; i++) { /* Issue GFPN_ID */ /* Prepare common MS IOCB */ ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE, GPSC_RSP_SIZE); /* Prepare CT request */ ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, GPSC_CMD, GPSC_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_name */ memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, WWN_SIZE); /* Execute MS IOCB */ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, sizeof(ms_iocb_entry_t)); if (rval != QLA_SUCCESS) { /*EMPTY*/ DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " "failed (%d).\n", ha->host_no, rval)); } else if ((rval = qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GPSC")) != QLA_SUCCESS) { /* FM command unsupported? */ if (rval == QLA_INVALID_COMMAND && ct_rsp->header.reason_code == CT_REASON_INVALID_COMMAND_CODE) { DEBUG2(printk("scsi(%ld): GPSC command " "unsupported, disabling query...\n", ha->host_no)); ha->flags.gpsc_supported = 0; rval = QLA_FUNCTION_FAILED; break; } rval = QLA_FUNCTION_FAILED; } else { /* Save port-speed */ switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { case BIT_15: list[i].fp_speed = PORT_SPEED_1GB; break; case BIT_14: list[i].fp_speed = PORT_SPEED_2GB; break; case BIT_13: list[i].fp_speed = PORT_SPEED_4GB; break; case BIT_11: list[i].fp_speed = PORT_SPEED_8GB; break; } DEBUG2_3(printk("scsi(%ld): GPSC ext entry - " "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " "speed=%04x.\n", ha->host_no, list[i].fabric_port_name[0], list[i].fabric_port_name[1], list[i].fabric_port_name[2], list[i].fabric_port_name[3], list[i].fabric_port_name[4], list[i].fabric_port_name[5], list[i].fabric_port_name[6], list[i].fabric_port_name[7], be16_to_cpu(ct_rsp->rsp.gpsc.speeds), be16_to_cpu(ct_rsp->rsp.gpsc.speed))); } /* Last device exit. */ if (list[i].d_id.b.rsvd_1 != 0) break; } return (rval);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?