⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfcp_fsf.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
        ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,				  ZFCP_REQ_AUTO_CLEANUP,				  NULL, &lock_flags, &fsf_req);	if (ret < 0) {                ZFCP_LOG_INFO("error: creation of ELS request failed "			      "(adapter %s, port d_id: 0x%08x)\n",                              zfcp_get_busid_by_adapter(adapter), d_id);                goto failed_req;	}	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);        if (zfcp_use_one_sbal(els->req, els->req_count,                              els->resp, els->resp_count)){                /* both request buffer and response buffer                   fit into one sbale each */                sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;                sbale[2].addr = zfcp_sg_to_address(&els->req[0]);                sbale[2].length = els->req[0].length;                sbale[3].addr = zfcp_sg_to_address(&els->resp[0]);                sbale[3].length = els->resp[0].length;                sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;	} else if (adapter->adapter_features &                   FSF_FEATURE_ELS_CT_CHAINED_SBALS) {                /* try to use chained SBALs */                bytes = zfcp_qdio_sbals_from_sg(fsf_req,                                                SBAL_FLAGS0_TYPE_WRITE_READ,                                                els->req, els->req_count,                                                ZFCP_MAX_SBALS_PER_ELS_REQ);                if (bytes <= 0) {                        ZFCP_LOG_INFO("error: creation of ELS request failed "				      "(adapter %s, port d_id: 0x%08x)\n",				      zfcp_get_busid_by_adapter(adapter), d_id);                        if (bytes == 0) {                                ret = -ENOMEM;                        } else {                                ret = bytes;                        }                        goto failed_send;                }                fsf_req->qtcb->bottom.support.req_buf_length = bytes;                fsf_req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;                bytes = zfcp_qdio_sbals_from_sg(fsf_req,                                                SBAL_FLAGS0_TYPE_WRITE_READ,                                                els->resp, els->resp_count,                                                ZFCP_MAX_SBALS_PER_ELS_REQ);                if (bytes <= 0) {                        ZFCP_LOG_INFO("error: creation of ELS request failed "				      "(adapter %s, port d_id: 0x%08x)\n",				      zfcp_get_busid_by_adapter(adapter), d_id);                        if (bytes == 0) {                                ret = -ENOMEM;                        } else {                                ret = bytes;                        }                        goto failed_send;                }                fsf_req->qtcb->bottom.support.resp_buf_length = bytes;        } else {                /* reject request */		ZFCP_LOG_INFO("error: microcode does not support chained SBALs"                              ", ELS request too big (adapter %s, "			      "port d_id: 0x%08x)\n",			      zfcp_get_busid_by_adapter(adapter), d_id);                ret = -EOPNOTSUPP;                goto failed_send;        }	/* settings in QTCB */	fsf_req->qtcb->bottom.support.d_id = d_id;	fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;	fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT;	fsf_req->data = (unsigned long) els;	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);	zfcp_san_dbf_event_els_request(fsf_req);	/* start QDIO request for this FSF request */	ret = zfcp_fsf_req_send(fsf_req, els->timer);	if (ret) {		ZFCP_LOG_DEBUG("error: initiation of ELS request failed "			       "(adapter %s, port d_id: 0x%08x)\n",			       zfcp_get_busid_by_adapter(adapter), d_id);		goto failed_send;	}	ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: "		       "0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id);	goto out; failed_send:	zfcp_fsf_req_free(fsf_req); failed_req: out:	write_unlock_irqrestore(&adapter->request_queue.queue_lock,				lock_flags);        return ret;}/** * zfcp_fsf_send_els_handler - handler for ELS commands * @fsf_req: pointer to struct zfcp_fsf_req * * Data specific for the ELS command is passed using * fsf_req->data. There we find the pointer to struct zfcp_send_els. * Usually a specific handler for the ELS command is called which is * found in this structure. */static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req){	struct zfcp_adapter *adapter;	struct zfcp_port *port;	u32 d_id;	struct fsf_qtcb_header *header;	struct fsf_qtcb_bottom_support *bottom;	struct zfcp_send_els *send_els;	int retval = -EINVAL;	u16 subtable, rule, counter;	send_els = (struct zfcp_send_els *) fsf_req->data;	adapter = send_els->adapter;	port = send_els->port;	d_id = send_els->d_id;	header = &fsf_req->qtcb->header;	bottom = &fsf_req->qtcb->bottom.support;	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)		goto skip_fsfstatus;	switch (header->fsf_status) {	case FSF_GOOD:		zfcp_san_dbf_event_els_response(fsf_req);		retval = 0;		break;	case FSF_SERVICE_CLASS_NOT_SUPPORTED:		if (adapter->fc_service_class <= 3) {			ZFCP_LOG_INFO("error: adapter %s does "				      "not support fibrechannel class %d.\n",				      zfcp_get_busid_by_adapter(adapter),				      adapter->fc_service_class);		} else {			ZFCP_LOG_INFO("bug: The fibrechannel class at "				      "adapter %s is invalid. "				      "(debug info %d)\n",				      zfcp_get_busid_by_adapter(adapter),				      adapter->fc_service_class);		}		/* stop operation for this adapter */		debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");		zfcp_erp_adapter_shutdown(adapter, 0);		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		break;	case FSF_ADAPTER_STATUS_AVAILABLE:		switch (header->fsf_status_qual.word[0]){		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");			if (port && (send_els->ls_code != ZFCP_LS_ADISC))				zfcp_test_link(port);			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;			break;		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;			retval =			  zfcp_handle_els_rjt(header->fsf_status_qual.word[1],					      (struct zfcp_ls_rjt_par *)					      &header->fsf_status_qual.word[2]);			break;		case FSF_SQ_RETRY_IF_POSSIBLE:			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_retry");			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;			break;		default:			ZFCP_LOG_INFO("bug: Wrong status qualifier 0x%x\n",				      header->fsf_status_qual.word[0]);			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,				(char*)header->fsf_status_qual.word, 16);		}		break;	case FSF_ELS_COMMAND_REJECTED:		ZFCP_LOG_INFO("ELS has been rejected because command filter "			      "prohibited sending "			      "(adapter: %s, port d_id: 0x%08x)\n",			      zfcp_get_busid_by_adapter(adapter), d_id);		break;	case FSF_PAYLOAD_SIZE_MISMATCH:		ZFCP_LOG_INFO(			"ELS request size and ELS response size must be either "			"both 0, or both greater than 0 "			"(adapter: %s, req_buf_length=%d resp_buf_length=%d)\n",			zfcp_get_busid_by_adapter(adapter),			bottom->req_buf_length,			bottom->resp_buf_length);		break;	case FSF_REQUEST_SIZE_TOO_LARGE:		ZFCP_LOG_INFO(			"Length of the ELS request buffer, "			"specified in QTCB bottom, "			"exceeds the size of the buffers "			"that have been allocated for ELS request data "			"(adapter: %s, req_buf_length=%d)\n",			zfcp_get_busid_by_adapter(adapter),			bottom->req_buf_length);		break;	case FSF_RESPONSE_SIZE_TOO_LARGE:		ZFCP_LOG_INFO(			"Length of the ELS response buffer, "			"specified in QTCB bottom, "			"exceeds the size of the buffers "			"that have been allocated for ELS response data "			"(adapter: %s, resp_buf_length=%d)\n",			zfcp_get_busid_by_adapter(adapter),			bottom->resp_buf_length);		break;	case FSF_SBAL_MISMATCH:		/* should never occure, avoided in zfcp_fsf_send_els */		ZFCP_LOG_INFO("SBAL mismatch (adapter: %s, req_buf_length=%d, "			      "resp_buf_length=%d)\n",			      zfcp_get_busid_by_adapter(adapter),			      bottom->req_buf_length, bottom->resp_buf_length);		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		break;	case FSF_ACCESS_DENIED:		ZFCP_LOG_NORMAL("access denied, cannot send ELS command "				"(adapter %s, port d_id=0x%08x)\n",				zfcp_get_busid_by_adapter(adapter), d_id);		for (counter = 0; counter < 2; counter++) {			subtable = header->fsf_status_qual.halfword[counter * 2];			rule = header->fsf_status_qual.halfword[counter * 2 + 1];			switch (subtable) {			case FSF_SQ_CFDC_SUBTABLE_OS:			case FSF_SQ_CFDC_SUBTABLE_PORT_WWPN:			case FSF_SQ_CFDC_SUBTABLE_PORT_DID:			case FSF_SQ_CFDC_SUBTABLE_LUN:				ZFCP_LOG_INFO("Access denied (%s rule %d)\n",					zfcp_act_subtable_type[subtable], rule);				break;			}		}		debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");		if (port != NULL)			zfcp_erp_port_access_denied(port);		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		break;	default:		ZFCP_LOG_NORMAL(			"bug: An unknown FSF Status was presented "			"(adapter: %s, fsf_status=0x%08x)\n",			zfcp_get_busid_by_adapter(adapter),			header->fsf_status);		debug_text_event(adapter->erp_dbf, 0, "fsf_sq_inval");		debug_exception(adapter->erp_dbf, 0,			&header->fsf_status_qual.word[0], sizeof(u32));		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		break;	}skip_fsfstatus:	send_els->status = retval;	if (send_els->handler != 0)		send_els->handler(send_els->handler_data);	return retval;}/* * function: * * purpose: * * returns:	address of initiated FSF request *		NULL - request could not be initiated */intzfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action){	volatile struct qdio_buffer_element *sbale;	unsigned long lock_flags;	int retval = 0;	/* setup new FSF request */	retval = zfcp_fsf_req_create(erp_action->adapter,				     FSF_QTCB_EXCHANGE_CONFIG_DATA,				     ZFCP_REQ_AUTO_CLEANUP,				     erp_action->adapter->pool.fsf_req_erp,				     &lock_flags, &(erp_action->fsf_req));	if (retval < 0) {		ZFCP_LOG_INFO("error: Could not create exchange configuration "			      "data request for adapter %s.\n",			      zfcp_get_busid_by_adapter(erp_action->adapter));		goto out;	}	sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,                                    erp_action->fsf_req->sbal_curr, 0);        sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;        sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;	erp_action->fsf_req->erp_action = erp_action;	erp_action->fsf_req->qtcb->bottom.config.feature_selection =			FSF_FEATURE_CFDC |			FSF_FEATURE_LUN_SHARING |			FSF_FEATURE_UPDATE_ALERT;	/* start QDIO request for this FSF request */	retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);	if (retval) {		ZFCP_LOG_INFO		    ("error: Could not send exchange configuration data "		     "command on the adapter %s\n",		     zfcp_get_busid_by_adapter(erp_action->adapter));		zfcp_fsf_req_free(erp_action->fsf_req);		erp_action->fsf_req = NULL;		goto out;	}	ZFCP_LOG_DEBUG("exchange configuration data request initiated "		       "(adapter %s)\n",		       zfcp_get_busid_by_adapter(erp_action->adapter)); out:	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,				lock_flags);	return retval;}/** * zfcp_fsf_exchange_config_evaluate * @fsf_req: fsf_req which belongs to xchg config data request * @xchg_ok: specifies if xchg config data was incomplete or complete (0/1) * * returns: -EIO on error, 0 otherwise */static intzfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok){	struct fsf_qtcb_bottom_config *bottom;	struct zfcp_adapter *adapter = fsf_req->adapter;	struct Scsi_Host *shost = adapter->scsi_host;	bottom = &fsf_req->qtcb->bottom.config;	ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n",		       bottom->low_qtcb_version, bottom->high_qtcb_version);	adapter->fsf_lic_version = bottom->lic_version;	adapter->adapter_features = bottom->adapter_features;	adapter->connection_features = bottom->connection_features;	adapter->peer_wwpn = 0;	adapter->peer_wwnn = 0;	adapter->peer_d_id = 0;	if (xchg_ok) {		fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;		fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;		fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;		fc_host_speed(shost) = bottom->fc_link_speed;		fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;		adapter->fc_topology = bottom->fc_topology;		adapter->hydra_version = bottom->adapter_type;		if (adapter->physical_wwpn == 0)			adapter->physical_wwpn = fc_host_port_name(shost);		if (adapter->physical_s_id == 0)			adapter->physical_s_id = fc_host_port_id(shost);	} else {		fc_host_node_name(shost) = 0;		fc_host_port_name(shost) = 0;		fc_host_port_id(shost) = 0;		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;		adapter->fc_topology = 0;		adapter->hydra_version = 0;	}	if (adapter->fc_topology == FSF_TOPO_P2P) {		adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;		adapter->peer_wwpn = bottom->plogi_payload.wwpn;		adapter->peer_wwnn = bottom->plogi_payload.wwnn;	}	if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {		adapter->hardware_version = bottom->hardware_version;		memcpy(fc_host_serial_number(shost), bottom->serial_number,		       min(FC_SERIAL_NUMBER_SIZE, 17));		EBCASC(fc_host_serial_number(shost),		       min(FC_SERIAL_NUMBER_SIZE, 17));	}	ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n"			"WWNN 0x%016Lx, "			"WWPN 0x%016Lx, "			"S_ID 0x%08x,\n"			"adapter version 0x%x, "			"LIC version 0x%x, "			"FC link speed %d Gb/s\n",			zfcp_get_busid_by_adapter(adapter),			(wwn_t) fc_host_node_name(shost),			(wwn_t) fc_host_port_name(shost),			fc_hos

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -