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

📄 zfcp_fsf.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
}static intzfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req){	struct fsf_status_read_buffer *status_buffer;	struct zfcp_adapter *adapter;	struct zfcp_port *port;	unsigned long flags;	status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;	adapter = fsf_req->adapter;	read_lock_irqsave(&zfcp_data.config_lock, flags);	list_for_each_entry(port, &adapter->port_list_head, list)	    if (port->d_id == (status_buffer->d_id & ZFCP_DID_MASK))		break;	read_unlock_irqrestore(&zfcp_data.config_lock, flags);	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%08x 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%08x 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;	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:		ZFCP_LOG_NORMAL("Bit error threshold data received:\n");		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,			      (char *) status_buffer,			      sizeof (struct fsf_status_read_buffer));		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_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;	unsigned long lock_flags;	struct zfcp_fsf_req *fsf_req = NULL;	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;	/* start QDIO request for this FSF request */	zfcp_fsf_start_scsi_er_timer(adapter);	retval = zfcp_fsf_req_send(fsf_req, NULL);	if (retval) {		del_timer(&adapter->scsi_er_timer);		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%08x, "		       "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];	del_timer(&new_fsf_req->adapter->scsi_er_timer);	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 "			     "0x%016Lx on port 0x%016Lx on adapter %s is "			     "invalid. This may happen in rare cases. "			     "Trying to re-establish link.\n",			     unit->handle,			     unit->fcp_lun,			     unit->port->wwpn,			     zfcp_get_busid_by_unit(unit));			ZFCP_LOG_DEBUG("Status qualifier data:\n");			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,				      (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_lhand_nv1");			zfcp_erp_port_reopen(unit->port, 0);			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;		}		break;	case FSF_FCP_COMMAND_DOES_NOT_EXIST:		retval = 0;		debug_text_event(new_fsf_req->adapter->erp_dbf, 3,				 "fsf_s_no_exist");		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;		break;	case FSF_PORT_BOXED:		ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to "			      "be reopened\n", unit->port->wwpn,			      zfcp_get_busid_by_unit(unit));		debug_text_event(new_fsf_req->adapter->erp_dbf, 2,				 "fsf_s_pboxed");		zfcp_erp_port_boxed(unit->port);		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR		    | ZFCP_STATUS_FSFREQ_RETRY;		break;	case FSF_LUN_BOXED:                ZFCP_LOG_INFO(                        "unit 0x%016Lx on port 0x%016Lx on adapter %s needs "

⌨️ 快捷键说明

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