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 + -
显示快捷键?