zfcp_fsf.c

来自「linux 内核源代码」· C语言 代码 · 共 2,033 行 · 第 1/5 页

C
2,033
字号
	if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) {		ZFCP_LOG_NORMAL("bug: Reopen port indication received for"				"nonexisting port with d_id 0x%06x on "				"adapter %s. Ignored.\n",				status_buffer->d_id & ZFCP_DID_MASK,				zfcp_get_busid_by_adapter(adapter));		goto out;	}	switch (status_buffer->status_subtype) {	case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:		debug_text_event(adapter->erp_dbf, 3, "unsol_pc_phys:");		zfcp_erp_port_reopen(port, 0);		break;	case FSF_STATUS_READ_SUB_ERROR_PORT:		debug_text_event(adapter->erp_dbf, 1, "unsol_pc_err:");		zfcp_erp_port_shutdown(port, 0);		break;	default:		debug_text_event(adapter->erp_dbf, 0, "unsol_unk_sub:");		debug_exception(adapter->erp_dbf, 0,				&status_buffer->status_subtype, sizeof (u32));		ZFCP_LOG_NORMAL("bug: Undefined status subtype received "				"for a reopen indication on port with "				"d_id 0x%06x on the adapter %s. "				"Ignored. (debug info 0x%x)\n",				status_buffer->d_id,				zfcp_get_busid_by_adapter(adapter),				status_buffer->status_subtype);	} out:	return 0;}/* * function:    zfcp_fsf_status_read_handler * * purpose:	is called for finished Open Port command * * returns: */static intzfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req){	int retval = 0;	struct zfcp_adapter *adapter = fsf_req->adapter;	struct fsf_status_read_buffer *status_buffer =		(struct fsf_status_read_buffer *) fsf_req->data;	struct fsf_bit_error_payload *fsf_bit_error;	if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {		zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer);		mempool_free(status_buffer, adapter->pool.data_status_read);		zfcp_fsf_req_free(fsf_req);		goto out;	}	zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer);	switch (status_buffer->status_type) {	case FSF_STATUS_READ_PORT_CLOSED:		zfcp_fsf_status_read_port_closed(fsf_req);		break;	case FSF_STATUS_READ_INCOMING_ELS:		zfcp_fsf_incoming_els(fsf_req);		break;	case FSF_STATUS_READ_SENSE_DATA_AVAIL:		ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n",			      zfcp_get_busid_by_adapter(adapter));		break;	case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:		fsf_bit_error = (struct fsf_bit_error_payload *)			status_buffer->payload;		ZFCP_LOG_NORMAL("Warning: bit error threshold data "		    "received (adapter %s, "		    "link failures = %i, loss of sync errors = %i, "		    "loss of signal errors = %i, "		    "primitive sequence errors = %i, "		    "invalid transmission word errors = %i, "		    "CRC errors = %i)\n",		    zfcp_get_busid_by_adapter(adapter),		    fsf_bit_error->link_failure_error_count,		    fsf_bit_error->loss_of_sync_error_count,		    fsf_bit_error->loss_of_signal_error_count,		    fsf_bit_error->primitive_sequence_error_count,		    fsf_bit_error->invalid_transmission_word_error_count,		    fsf_bit_error->crc_error_count);		ZFCP_LOG_INFO("Additional bit error threshold data "		    "(adapter %s, "		    "primitive sequence event time-outs = %i, "		    "elastic buffer overrun errors = %i, "		    "advertised receive buffer-to-buffer credit = %i, "		    "current receice buffer-to-buffer credit = %i, "		    "advertised transmit buffer-to-buffer credit = %i, "		    "current transmit buffer-to-buffer credit = %i)\n",		    zfcp_get_busid_by_adapter(adapter),		    fsf_bit_error->primitive_sequence_event_timeout_count,		    fsf_bit_error->elastic_buffer_overrun_error_count,		    fsf_bit_error->advertised_receive_b2b_credit,		    fsf_bit_error->current_receive_b2b_credit,		    fsf_bit_error->advertised_transmit_b2b_credit,		    fsf_bit_error->current_transmit_b2b_credit);		break;	case FSF_STATUS_READ_LINK_DOWN:		switch (status_buffer->status_subtype) {		case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:			ZFCP_LOG_INFO("Physical link to adapter %s is down\n",				      zfcp_get_busid_by_adapter(adapter));			zfcp_fsf_link_down_info_eval(adapter,				(struct fsf_link_down_info *)				&status_buffer->payload);			break;		case FSF_STATUS_READ_SUB_FDISC_FAILED:			ZFCP_LOG_INFO("Local link to adapter %s is down "				      "due to failed FDISC login\n",				      zfcp_get_busid_by_adapter(adapter));			zfcp_fsf_link_down_info_eval(adapter,				(struct fsf_link_down_info *)				&status_buffer->payload);			break;		case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:			ZFCP_LOG_INFO("Local link to adapter %s is down "				      "due to firmware update on adapter\n",				      zfcp_get_busid_by_adapter(adapter));			zfcp_fsf_link_down_info_eval(adapter, NULL);			break;		default:			ZFCP_LOG_INFO("Local link to adapter %s is down "				      "due to unknown reason\n",				      zfcp_get_busid_by_adapter(adapter));			zfcp_fsf_link_down_info_eval(adapter, NULL);		};		break;	case FSF_STATUS_READ_LINK_UP:		ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "				"Restarting operations on this adapter\n",				zfcp_get_busid_by_adapter(adapter));		/* All ports should be marked as ready to run again */		zfcp_erp_modify_adapter_status(adapter,					       ZFCP_STATUS_COMMON_RUNNING,					       ZFCP_SET);		zfcp_erp_adapter_reopen(adapter,					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED					| ZFCP_STATUS_COMMON_ERP_FAILED);		break;	case FSF_STATUS_READ_NOTIFICATION_LOST:		ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: "				"adapter %s%s%s%s%s%s%s%s%s\n",				zfcp_get_busid_by_adapter(adapter),				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_INCOMING_ELS) ?					", incoming ELS" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_SENSE_DATA) ?					", sense data" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_LINK_STATUS) ?					", link status change" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_PORT_CLOSED) ?					", port close" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ?					", bit error exception" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_ACT_UPDATED) ?					", ACT update" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_ACT_HARDENED) ?					", ACT hardening" : "",				(status_buffer->status_subtype &					FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ?					", adapter feature change" : "");		if (status_buffer->status_subtype &		    FSF_STATUS_READ_SUB_ACT_UPDATED)			zfcp_erp_adapter_access_changed(adapter);		break;	case FSF_STATUS_READ_CFDC_UPDATED:		ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",			      zfcp_get_busid_by_adapter(adapter));		zfcp_erp_adapter_access_changed(adapter);		break;	case FSF_STATUS_READ_CFDC_HARDENED:		switch (status_buffer->status_subtype) {		case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE:			ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n",				      zfcp_get_busid_by_adapter(adapter));			break;		case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2:			ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied "				      "to the secondary SE\n",				zfcp_get_busid_by_adapter(adapter));			break;		default:			ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n",				      zfcp_get_busid_by_adapter(adapter));		}		break;	case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:		debug_text_event(adapter->erp_dbf, 2, "unsol_features:");		ZFCP_LOG_INFO("List of supported features on adapter %s has "			      "been changed from 0x%08X to 0x%08X\n",			      zfcp_get_busid_by_adapter(adapter),			      *(u32*) (status_buffer->payload + 4),			      *(u32*) (status_buffer->payload));		adapter->adapter_features = *(u32*) status_buffer->payload;		break;	default:		ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown "				"type was received (debug info 0x%x)\n",				status_buffer->status_type);		ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n",			       status_buffer);		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,			      (char *) status_buffer,			      sizeof (struct fsf_status_read_buffer));		break;	}	mempool_free(status_buffer, adapter->pool.data_status_read);	zfcp_fsf_req_free(fsf_req);	/*	 * recycle buffer and start new request repeat until outbound	 * queue is empty or adapter shutdown is requested	 */	/*	 * FIXME(qdio):	 * we may wait in the req_create for 5s during shutdown, so	 * qdio_cleanup will have to wait at least that long before returning	 * with failure to allow us a proper cleanup under all circumstances	 */	/*	 * FIXME:	 * allocation failure possible? (Is this code needed?)	 */	retval = zfcp_fsf_status_read(adapter, 0);	if (retval < 0) {		ZFCP_LOG_INFO("Failed to create unsolicited status read "			      "request for the adapter %s.\n",			      zfcp_get_busid_by_adapter(adapter));		/* temporary fix to avoid status read buffer shortage */		adapter->status_read_failed++;		if ((ZFCP_STATUS_READS_RECOM - adapter->status_read_failed)		    < ZFCP_STATUS_READ_FAILED_THRESHOLD) {			ZFCP_LOG_INFO("restart adapter %s due to status read "				      "buffer shortage\n",				      zfcp_get_busid_by_adapter(adapter));			zfcp_erp_adapter_reopen(adapter, 0);		}	} out:	return retval;}/* * function:    zfcp_fsf_abort_fcp_command * * purpose:	tells FSF to abort a running SCSI command * * returns:	address of initiated FSF request *		NULL - request could not be initiated * * FIXME(design): should be watched by a timeout !!! * FIXME(design) shouldn't this be modified to return an int *               also...don't know how though */struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,			   struct zfcp_adapter *adapter,			   struct zfcp_unit *unit, int req_flags){	volatile struct qdio_buffer_element *sbale;	struct zfcp_fsf_req *fsf_req = NULL;	unsigned long lock_flags;	int retval = 0;	/* setup new FSF request */	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,				     req_flags, adapter->pool.fsf_req_abort,				     &lock_flags, &fsf_req);	if (retval < 0) {		ZFCP_LOG_INFO("error: Failed to create an abort command "			      "request for lun 0x%016Lx on port 0x%016Lx "			      "on adapter %s.\n",			      unit->fcp_lun,			      unit->port->wwpn,			      zfcp_get_busid_by_adapter(adapter));		goto out;	}	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);        sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;        sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;	fsf_req->data = (unsigned long) unit;	/* set handles of unit and its parent port in QTCB */	fsf_req->qtcb->header.lun_handle = unit->handle;	fsf_req->qtcb->header.port_handle = unit->port->handle;	/* set handle of request which should be aborted */	fsf_req->qtcb->bottom.support.req_handle = (u64) old_req_id;	zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);	retval = zfcp_fsf_req_send(fsf_req);	if (retval) {		ZFCP_LOG_INFO("error: Failed to send abort command request "			      "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",			      zfcp_get_busid_by_adapter(adapter),			      unit->port->wwpn, unit->fcp_lun);		zfcp_fsf_req_free(fsf_req);		fsf_req = NULL;		goto out;	}	ZFCP_LOG_DEBUG("Abort FCP Command request initiated "		       "(adapter%s, port d_id=0x%06x, "		       "unit x%016Lx, old_req_id=0x%lx)\n",		       zfcp_get_busid_by_adapter(adapter),		       unit->port->d_id,		       unit->fcp_lun, old_req_id); out:	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);	return fsf_req;}/* * function:    zfcp_fsf_abort_fcp_command_handler * * purpose:	is called for finished Abort FCP Command request * * returns: */static intzfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req){	int retval = -EINVAL;	struct zfcp_unit *unit;	unsigned char status_qual =	    new_fsf_req->qtcb->header.fsf_status_qual.word[0];	if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {		/* do not set ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED */		goto skip_fsfstatus;	}	unit = (struct zfcp_unit *) new_fsf_req->data;	/* evaluate FSF status in QTCB */	switch (new_fsf_req->qtcb->header.fsf_status) {	case FSF_PORT_HANDLE_NOT_VALID:		if (status_qual >> 4 != status_qual % 0xf) {			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,					 "fsf_s_phand_nv0");			/*			 * In this case a command that was sent prior to a port			 * reopen was aborted (handles are different). This is			 * fine.			 */		} else {			ZFCP_LOG_INFO("Temporary port identifier 0x%x for "				      "port 0x%016Lx on adapter %s invalid. "				      "This may happen occasionally.\n",				      unit->port->handle,				      unit->port->wwpn,				      zfcp_get_busid_by_unit(unit));			ZFCP_LOG_INFO("status qualifier:\n");			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,				      (char *) &new_fsf_req->qtcb->header.				      fsf_status_qual,				      sizeof (union fsf_status_qual));			/* Let's hope this sorts out the mess */			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,					 "fsf_s_phand_nv1");			zfcp_erp_adapter_reopen(unit->port->adapter, 0);			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		}		break;	case FSF_LUN_HANDLE_NOT_VALID:		if (status_qual >> 4 != status_qual % 0xf) {			/* 2 */			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,					 "fsf_s_lhand_nv0");			/*			 * In this case a command that was sent prior to a unit			 * reopen was aborted (handles are different).			 * This is fine.			 */		} else {			ZFCP_LOG_INFO			    ("Warning: Temporary LUN identifier 0x%x of LUN "

⌨️ 快捷键说明

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