/*
 * This file is part of the zfcp device driver for
 * FCP adapters for IBM System z9 and zSeries.
 *
 * (C) Copyright IBM Corp. 2002, 2006
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "zfcp_ext.h"

static int zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *);
static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_open_port_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_close_port_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_fcp_command_task_management_handler(
	struct zfcp_fsf_req *);
static int zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_status_read_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_control_file_handler(struct zfcp_fsf_req *);
static inline int zfcp_fsf_req_sbal_check(
	unsigned long *, struct zfcp_qdio_queue *, int);
static inline int zfcp_use_one_sbal(
	struct scatterlist *, int, struct scatterlist *, int);
static struct zfcp_fsf_req *zfcp_fsf_req_alloc(mempool_t *, int);
static int zfcp_fsf_req_send(struct zfcp_fsf_req *);
static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *, u8,
	struct fsf_link_down_info *);
static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);

/* association between FSF command and FSF QTCB type */
static u32 fsf_qtcb_type[] = {
	[FSF_QTCB_FCP_CMND] =             FSF_IO_COMMAND,
	[FSF_QTCB_ABORT_FCP_CMND] =       FSF_SUPPORT_COMMAND,
	[FSF_QTCB_OPEN_PORT_WITH_DID] =   FSF_SUPPORT_COMMAND,
	[FSF_QTCB_OPEN_LUN] =             FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_LUN] =            FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_PORT] =           FSF_SUPPORT_COMMAND,
	[FSF_QTCB_CLOSE_PHYSICAL_PORT] =  FSF_SUPPORT_COMMAND,
	[FSF_QTCB_SEND_ELS] =             FSF_SUPPORT_COMMAND,
	[FSF_QTCB_SEND_GENERIC] =         FSF_SUPPORT_COMMAND,
	[FSF_QTCB_EXCHANGE_CONFIG_DATA] = FSF_CONFIG_COMMAND,
	[FSF_QTCB_EXCHANGE_PORT_DATA] =   FSF_PORT_COMMAND,
	[FSF_QTCB_DOWNLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND,
	[FSF_QTCB_UPLOAD_CONTROL_FILE] =  FSF_SUPPORT_COMMAND
};

static const char zfcp_act_subtable_type[5][8] = {
	"unknown", "OS", "WWPN", "DID", "LUN"
};

/****************************************************************/
/*************** FSF related Functions  *************************/
/****************************************************************/

#define ZFCP_LOG_AREA			ZFCP_LOG_AREA_FSF

/*
 * function:	zfcp_fsf_req_alloc
 *
 * purpose:     Obtains an fsf_req and potentially a qtcb (for all but
 *              unsolicited requests) via helper functions
 *              Does some initial fsf request set-up.
 *
 * returns:	pointer to allocated fsf_req if successfull
 *              NULL otherwise
 *
 * locks:       none
 *
 */
static struct zfcp_fsf_req *
zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
{
	size_t size;
	void *ptr;
	struct zfcp_fsf_req *fsf_req = NULL;

	if (req_flags & ZFCP_REQ_NO_QTCB)
		size = sizeof(struct zfcp_fsf_req);
	else
		size = sizeof(struct zfcp_fsf_req_qtcb);

	if (likely(pool))
		ptr = mempool_alloc(pool, GFP_ATOMIC);
	else {
		if (req_flags & ZFCP_REQ_NO_QTCB)
			ptr = kmalloc(size, GFP_ATOMIC);
		else
			ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
					       GFP_ATOMIC);
	}

	if (unlikely(!ptr))
		goto out;

	memset(ptr, 0, size);

	if (req_flags & ZFCP_REQ_NO_QTCB) {
		fsf_req = (struct zfcp_fsf_req *) ptr;
	} else {
		fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req;
		fsf_req->qtcb =	&((struct zfcp_fsf_req_qtcb *) ptr)->qtcb;
	}

	fsf_req->pool = pool;

 out:
	return fsf_req;
}

/*
 * function:	zfcp_fsf_req_free
 *
 * purpose:     Frees the memory of an fsf_req (and potentially a qtcb) or
 *              returns it into the pool via helper functions.
 *
 * returns:     sod all
 *
 * locks:       none
 */
void
zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
{
	if (likely(fsf_req->pool)) {
		mempool_free(fsf_req, fsf_req->pool);
		return;
	}

	if (fsf_req->qtcb) {
		kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req);
		return;
	}

	kfree(fsf_req);
}

/*
 * Never ever call this without shutting down the adapter first.
 * Otherwise the adapter would continue using and corrupting s390 storage.
 * Included BUG_ON() call to ensure this is done.
 * ERP is supposed to be the only user of this function.
 */
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
	struct zfcp_fsf_req *fsf_req, *tmp;
	unsigned long flags;
	LIST_HEAD(remove_queue);
	unsigned int i;

	BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
	spin_lock_irqsave(&adapter->req_list_lock, flags);
	atomic_set(&adapter->reqs_active, 0);
	for (i = 0; i < REQUEST_LIST_SIZE; i++)
		list_splice_init(&adapter->req_list[i], &remove_queue);
	spin_unlock_irqrestore(&adapter->req_list_lock, flags);

	list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
		list_del(&fsf_req->list);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
		zfcp_fsf_req_complete(fsf_req);
	}
}

/*
 * function:    zfcp_fsf_req_complete
 *
 * purpose:	Updates active counts and timers for openfcp-reqs
 *              May cleanup request after req_eval returns
 *
 * returns:	0 - success
 *		!0 - failure
 *
 * context:
 */
int
zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;
	int cleanup;

	if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
		ZFCP_LOG_DEBUG("Status read response received\n");
		/*
		 * Note: all cleanup handling is done in the callchain of
		 * the function call-chain below.
		 */
		zfcp_fsf_status_read_handler(fsf_req);
		goto out;
	} else {
		del_timer(&fsf_req->timer);
		zfcp_fsf_protstatus_eval(fsf_req);
	}

	/*
	 * fsf_req may be deleted due to waking up functions, so
	 * cleanup is saved here and used later
	 */
	if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
		cleanup = 1;
	else
		cleanup = 0;

	fsf_req->status |= ZFCP_STATUS_FSFREQ_COMPLETED;

	/* cleanup request if requested by initiator */
	if (likely(cleanup)) {
		ZFCP_LOG_TRACE("removing FSF request %p\n", fsf_req);
		/*
		 * lock must not be held here since it will be
		 * grabed by the called routine, too
		 */
		zfcp_fsf_req_free(fsf_req);
	} else {
		/* notify initiator waiting for the requests completion */
		ZFCP_LOG_TRACE("waking initiator of FSF request %p\n",fsf_req);
		/*
		 * FIXME: Race! We must not access fsf_req here as it might have been
		 * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED
		 * flag. It's an improbable case. But, we have the same paranoia for
		 * the cleanup flag already.
		 * Might better be handled using complete()?
		 * (setting the flag and doing wakeup ought to be atomic
		 *  with regard to checking the flag as long as waitqueue is
		 *  part of the to be released structure)
		 */
		wake_up(&fsf_req->completion_wq);
	}

 out:
	return retval;
}

/*
 * function:    zfcp_fsf_protstatus_eval
 *
 * purpose:	evaluates the QTCB of the finished FSF request
 *		and initiates appropriate actions
 *		(usually calling FSF command specific handlers)
 *
 * returns:
 *
 * context:
 *
 * locks:
 */
static int
zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct fsf_qtcb *qtcb = fsf_req->qtcb;
	union fsf_prot_status_qual *prot_status_qual =
		&qtcb->prefix.prot_status_qual;

	zfcp_hba_dbf_event_fsf_response(fsf_req);

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
		ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n",
			       (unsigned long) fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */
		goto skip_protstatus;
	}

	/* evaluate FSF Protocol Status */
	switch (qtcb->prefix.prot_status) {

	case FSF_PROT_GOOD:
	case FSF_PROT_FSF_STATUS_PRESENTED:
		break;

	case FSF_PROT_QTCB_VERSION_ERROR:
		ZFCP_LOG_NORMAL("error: The adapter %s contains "
				"microcode of version 0x%x, the device driver "
				"only supports 0x%x. Aborting.\n",
				zfcp_get_busid_by_adapter(adapter),
				prot_status_qual->version_error.fsf_version,
				ZFCP_QTCB_VERSION);
		zfcp_erp_adapter_shutdown(adapter, 0, 117, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_SEQ_NUMB_ERROR:
		ZFCP_LOG_NORMAL("bug: Sequence number mismatch between "
				"driver (0x%x) and adapter %s (0x%x). "
				"Restarting all operations on this adapter.\n",
				qtcb->prefix.req_seq_no,
				zfcp_get_busid_by_adapter(adapter),
				prot_status_qual->sequence_error.exp_req_seq_no);
		zfcp_erp_adapter_reopen(adapter, 0, 98, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_UNSUPP_QTCB_TYPE:
		ZFCP_LOG_NORMAL("error: Packet header type used by the "
				"device driver is incompatible with "
				"that used on adapter %s. "
				"Stopping all operations on this adapter.\n",
				zfcp_get_busid_by_adapter(adapter));
		zfcp_erp_adapter_shutdown(adapter, 0, 118, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_HOST_CONNECTION_INITIALIZING:
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
				&(adapter->status));
		break;

	case FSF_PROT_DUPLICATE_REQUEST_ID:
			ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx "
					"to the adapter %s is ambiguous. "
				"Stopping all operations on this adapter.\n",
				*(unsigned long long*)
				(&qtcb->bottom.support.req_handle),
					zfcp_get_busid_by_adapter(adapter));
		zfcp_erp_adapter_shutdown(adapter, 0, 78, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_LINK_DOWN:
		zfcp_fsf_link_down_info_eval(fsf_req, 37,
					     &prot_status_qual->link_down_info);
		/* FIXME: reopening adapter now? better wait for link up */
		zfcp_erp_adapter_reopen(adapter, 0, 79, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_REEST_QUEUE:
		ZFCP_LOG_NORMAL("The local link to adapter with "
			      "%s was re-plugged. "
			      "Re-starting 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, 28, NULL,
					       ZFCP_STATUS_COMMON_RUNNING,
					       ZFCP_SET);
		zfcp_erp_adapter_reopen(adapter,
					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
					| ZFCP_STATUS_COMMON_ERP_FAILED,
					99, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PROT_ERROR_STATE:
		ZFCP_LOG_NORMAL("error: The adapter %s "
				"has entered the error state. "
				"Restarting all operations on this "
				"adapter.\n",
				zfcp_get_busid_by_adapter(adapter));
		zfcp_erp_adapter_reopen(adapter, 0, 100, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: Transfer protocol status information "
				"provided by the adapter %s "
				"is not compatible with the device driver. "
				"Stopping all operations on this adapter. "
				"(debug info 0x%x).\n",
				zfcp_get_busid_by_adapter(adapter),
				qtcb->prefix.prot_status);
		zfcp_erp_adapter_shutdown(adapter, 0, 119, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
	}

 skip_protstatus:
	/*
	 * always call specific handlers to give them a chance to do
	 * something meaningful even in error cases
	 */
	zfcp_fsf_fsfstatus_eval(fsf_req);
	return retval;
}

/*
 * function:	zfcp_fsf_fsfstatus_eval
 *
 * purpose:	evaluates FSF status of completed FSF request
 *		and acts accordingly
 *
 * returns:
 */
static int
zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;

	if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
		goto skip_fsfstatus;
	}

	/* evaluate FSF Status */
	switch (fsf_req->qtcb->header.fsf_status) {
	case FSF_UNKNOWN_COMMAND:
		ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
				"not known by the adapter %s "
				"Stopping all operations on this adapter. "
				"(debug info 0x%x).\n",
				zfcp_get_busid_by_adapter(fsf_req->adapter),
				fsf_req->qtcb->header.fsf_command);
		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 120, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_FCP_RSP_AVAILABLE:
		ZFCP_LOG_DEBUG("FCP Sense data will be presented to the "
			       "SCSI stack.\n");
		break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		zfcp_fsf_fsfstatus_qual_eval(fsf_req);
		break;
	}

 skip_fsfstatus:
	/*
	 * always call specific handlers to give them a chance to do
	 * something meaningful even in error cases
	 */
	zfcp_fsf_req_dispatch(fsf_req);

	return retval;
}

/*
 * function:	zfcp_fsf_fsfstatus_qual_eval
 *
 * purpose:	evaluates FSF status-qualifier of completed FSF request
 *		and acts accordingly
 *
 * returns:
 */
static int
zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;

	switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
	case FSF_SQ_FCP_RSP_AVAILABLE:
		break;
	case FSF_SQ_RETRY_IF_POSSIBLE:
		/* The SCSI-stack may now issue retries or escalate */
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_SQ_COMMAND_ABORTED:
		/* Carry the aborted state on to upper layer */
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED;
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_SQ_NO_RECOM:
		ZFCP_LOG_NORMAL("bug: No recommendation could be given for a "
				"problem on the adapter %s "
				"Stopping all operations on this adapter. ",
				zfcp_get_busid_by_adapter(fsf_req->adapter));
		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 121, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_SQ_ULP_PROGRAMMING_ERROR:
		ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer "
				"(adapter %s)\n",
				zfcp_get_busid_by_adapter(fsf_req->adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
	case FSF_SQ_NO_RETRY_POSSIBLE:
	case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
		/* dealt with in the respective functions */
		break;
	default:
		ZFCP_LOG_NORMAL("bug: Additional status info could "
				"not be interpreted properly.\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
			      sizeof (union fsf_status_qual));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	}

	return retval;
}

/**
 * zfcp_fsf_link_down_info_eval - evaluate link down information block
 */
static void
zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *fsf_req, u8 id,
			     struct fsf_link_down_info *link_down)
{
	struct zfcp_adapter *adapter = fsf_req->adapter;

	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
	                     &adapter->status))
		return;

	atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);

	if (link_down == NULL)
		goto out;

	switch (link_down->error_code) {
	case FSF_PSQ_LINK_NO_LIGHT:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(no light detected)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_WRAP_PLUG:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(wrap plug detected)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_NO_FCP:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(adjacent node on link does not support FCP)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_FIRMWARE_UPDATE:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(firmware update in progress)\n",
				zfcp_get_busid_by_adapter(adapter));
			break;
	case FSF_PSQ_LINK_INVALID_WWPN:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(duplicate or invalid WWPN detected)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_NO_NPIV_SUPPORT:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(no support for NPIV by Fabric)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_NO_FCP_RESOURCES:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(out of resource in FCP daughtercard)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_NO_FABRIC_RESOURCES:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(out of resource in Fabric)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(unable to Fabric login)\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED:
		ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED:
		ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT:
		ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n",
				zfcp_get_busid_by_adapter(adapter));
		break;
	default:
		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
				"(warning: unknown reason code %d)\n",
				zfcp_get_busid_by_adapter(adapter),
				link_down->error_code);
	}

	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
		ZFCP_LOG_DEBUG("Debug information to link down: "
		               "primary_status=0x%02x "
		               "ioerr_code=0x%02x "
		               "action_code=0x%02x "
		               "reason_code=0x%02x "
		               "explanation_code=0x%02x "
		               "vendor_specific_code=0x%02x\n",
				link_down->primary_status,
				link_down->ioerr_code,
				link_down->action_code,
				link_down->reason_code,
				link_down->explanation_code,
				link_down->vendor_specific_code);

 out:
	zfcp_erp_adapter_failed(adapter, id, fsf_req);
}

/*
 * function:	zfcp_fsf_req_dispatch
 *
 * purpose:	calls the appropriate command specific handler
 *
 * returns:
 */
static int
zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
{
	struct zfcp_erp_action *erp_action = fsf_req->erp_action;
	struct zfcp_adapter *adapter = fsf_req->adapter;
	int retval = 0;


	switch (fsf_req->fsf_command) {

	case FSF_QTCB_FCP_CMND:
		zfcp_fsf_send_fcp_command_handler(fsf_req);
		break;

	case FSF_QTCB_ABORT_FCP_CMND:
		zfcp_fsf_abort_fcp_command_handler(fsf_req);
		break;

	case FSF_QTCB_SEND_GENERIC:
		zfcp_fsf_send_ct_handler(fsf_req);
		break;

	case FSF_QTCB_OPEN_PORT_WITH_DID:
		zfcp_fsf_open_port_handler(fsf_req);
		break;

	case FSF_QTCB_OPEN_LUN:
		zfcp_fsf_open_unit_handler(fsf_req);
		break;

	case FSF_QTCB_CLOSE_LUN:
		zfcp_fsf_close_unit_handler(fsf_req);
		break;

	case FSF_QTCB_CLOSE_PORT:
		zfcp_fsf_close_port_handler(fsf_req);
		break;

	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
		zfcp_fsf_close_physical_port_handler(fsf_req);
		break;

	case FSF_QTCB_EXCHANGE_CONFIG_DATA:
		zfcp_fsf_exchange_config_data_handler(fsf_req);
		break;

	case FSF_QTCB_EXCHANGE_PORT_DATA:
		zfcp_fsf_exchange_port_data_handler(fsf_req);
		break;

	case FSF_QTCB_SEND_ELS:
		zfcp_fsf_send_els_handler(fsf_req);
		break;

	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
		zfcp_fsf_control_file_handler(fsf_req);
		break;

	case FSF_QTCB_UPLOAD_CONTROL_FILE:
		zfcp_fsf_control_file_handler(fsf_req);
		break;

	default:
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
				"not supported by the adapter %s\n",
				zfcp_get_busid_by_adapter(adapter));
		if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command)
			ZFCP_LOG_NORMAL
			    ("bug: Command issued by the device driver differs "
			     "from the command returned by the adapter %s "
			     "(debug info 0x%x, 0x%x).\n",
			     zfcp_get_busid_by_adapter(adapter),
			     fsf_req->fsf_command,
			     fsf_req->qtcb->header.fsf_command);
	}

	if (!erp_action)
		return retval;

	zfcp_erp_async_handler(erp_action, 0);

	return retval;
}

/*
 * function:    zfcp_fsf_status_read
 *
 * purpose:	initiates a Status Read command at the specified adapter
 *
 * returns:
 */
int
zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
{
	struct zfcp_fsf_req *fsf_req;
	struct fsf_status_read_buffer *status_buffer;
	unsigned long lock_flags;
	volatile struct qdio_buffer_element *sbale;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS,
				     req_flags | ZFCP_REQ_NO_QTCB,
				     adapter->pool.fsf_req_status_read,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create unsolicited status "
			      "buffer for adapter %s.\n",
			      zfcp_get_busid_by_adapter(adapter));
		goto failed_req_create;
	}

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
        sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS;
        sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY;
        fsf_req->sbale_curr = 2;

	status_buffer =
		mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC);
	if (!status_buffer) {
		ZFCP_LOG_NORMAL("bug: could not get some buffer\n");
		goto failed_buf;
	}
	memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer));
	fsf_req->data = (unsigned long) status_buffer;

	/* insert pointer to respective buffer */
	sbale = zfcp_qdio_sbale_curr(fsf_req);
	sbale->addr = (void *) status_buffer;
	sbale->length = sizeof(struct fsf_status_read_buffer);

	retval = zfcp_fsf_req_send(fsf_req);
	if (retval) {
		ZFCP_LOG_DEBUG("error: Could not set-up unsolicited status "
			       "environment.\n");
		goto failed_req_send;
	}

	ZFCP_LOG_TRACE("Status Read request initiated (adapter%s)\n",
		       zfcp_get_busid_by_adapter(adapter));
	goto out;

 failed_req_send:
	mempool_free(status_buffer, adapter->pool.data_status_read);

 failed_buf:
	zfcp_fsf_req_free(fsf_req);
 failed_req_create:
	zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
 out:
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
	return retval;
}

static int
zfcp_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%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:
		zfcp_erp_port_reopen(port, 0, 101, fsf_req);
		break;

	case FSF_STATUS_READ_SUB_ERROR_PORT:
		zfcp_erp_port_shutdown(port, 0, 122, fsf_req);
		break;

	default:
		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 int
zfcp_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(fsf_req, 38,
				(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(fsf_req, 39,
				(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(fsf_req, 40, 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(fsf_req, 41, 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, 30, NULL,
					       ZFCP_STATUS_COMMON_RUNNING,
					       ZFCP_SET);
		zfcp_erp_adapter_reopen(adapter,
					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
					| ZFCP_STATUS_COMMON_ERP_FAILED,
					102, fsf_req);
		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, 135, fsf_req);
		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, 136, fsf_req);
		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:
		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, 103, fsf_req);
		}
	}
 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;
	}

	if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
			&unit->status)))
		goto unit_blocked;

	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)
		goto out;

 unit_blocked:
		zfcp_fsf_req_free(fsf_req);
		fsf_req = NULL;

 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 int
zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_unit *unit;
	union fsf_status_qual *fsf_stat_qual =
		&new_fsf_req->qtcb->header.fsf_status_qual;

	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 (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
			/*
			 * 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 */
			zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104,
						new_fsf_req);
			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		}
		break;

	case FSF_LUN_HANDLE_NOT_VALID:
		if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
			/*
			 * 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 */
			zfcp_erp_port_reopen(unit->port, 0, 105, new_fsf_req);
			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		}
		break;

	case FSF_FCP_COMMAND_DOES_NOT_EXIST:
		retval = 0;
		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));
		zfcp_erp_port_boxed(unit->port, 47, new_fsf_req);
		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 "
                        "to be reopened\n",
                        unit->fcp_lun, unit->port->wwpn,
                        zfcp_get_busid_by_unit(unit));
		zfcp_erp_unit_boxed(unit, 48, new_fsf_req);
                new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
                        | ZFCP_STATUS_FSFREQ_RETRY;
                break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
			zfcp_test_link(unit->port);
			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* SCSI stack will escalate */
			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		default:
			ZFCP_LOG_NORMAL
			    ("bug: Wrong status qualifier 0x%x arrived.\n",
			     new_fsf_req->qtcb->header.fsf_status_qual.word[0]);
			break;
		}
		break;

	case FSF_GOOD:
		retval = 0;
		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				new_fsf_req->qtcb->header.fsf_status);
		break;
	}
 skip_fsfstatus:
	return retval;
}

/**
 * zfcp_use_one_sbal - checks whether req buffer and resp bother each fit into
 *	one SBALE
 * Two scatter-gather lists are passed, one for the reqeust and one for the
 * response.
 */
static inline int
zfcp_use_one_sbal(struct scatterlist *req, int req_count,
                  struct scatterlist *resp, int resp_count)
{
        return ((req_count == 1) &&
		(resp_count == 1) &&
                (((unsigned long) zfcp_sg_to_address(&req[0]) &
		  PAGE_MASK) ==
		 ((unsigned long) (zfcp_sg_to_address(&req[0]) +
				   req[0].length - 1) & PAGE_MASK)) &&
                (((unsigned long) zfcp_sg_to_address(&resp[0]) &
		  PAGE_MASK) ==
                 ((unsigned long) (zfcp_sg_to_address(&resp[0]) +
				   resp[0].length - 1) & PAGE_MASK)));
}

/**
 * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS)
 * @ct: pointer to struct zfcp_send_ct which conatins all needed data for
 *	the request
 * @pool: pointer to memory pool, if non-null this pool is used to allocate
 *	a struct zfcp_fsf_req
 * @erp_action: pointer to erp_action, if non-null the Generic Service request
 *	is sent within error recovery
 */
int
zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
		 struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_port *port;
	struct zfcp_adapter *adapter;
        struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int bytes;
	int ret = 0;

	port = ct->port;
	adapter = port->adapter;

	ret = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC,
				  ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				  pool, &lock_flags, &fsf_req);
	if (ret < 0) {
                ZFCP_LOG_INFO("error: Could not create CT request (FC-GS) for "
			      "adapter: %s\n",
			      zfcp_get_busid_by_adapter(adapter));
		goto failed_req;
	}

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
        if (zfcp_use_one_sbal(ct->req, ct->req_count,
                              ct->resp, ct->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(&ct->req[0]);
                sbale[2].length = ct->req[0].length;
                sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]);
                sbale[3].length = ct->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,
                                                ct->req, ct->req_count,
                                                ZFCP_MAX_SBALS_PER_CT_REQ);
                if (bytes <= 0) {
                        ZFCP_LOG_INFO("error: creation of CT request failed "
				      "on adapter %s\n",
				      zfcp_get_busid_by_adapter(adapter));
                        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,
                                                ct->resp, ct->resp_count,
                                                ZFCP_MAX_SBALS_PER_CT_REQ);
                if (bytes <= 0) {
                        ZFCP_LOG_INFO("error: creation of CT request failed "
				      "on adapter %s\n",
				      zfcp_get_busid_by_adapter(adapter));
                        if (bytes == 0)
                                ret = -ENOMEM;
                        else
                                ret = bytes;

                        goto failed_send;
                }
                fsf_req->qtcb->bottom.support.resp_buf_length = bytes;
        } else {
                /* reject send generic request */
		ZFCP_LOG_INFO(
			"error: microcode does not support chained SBALs,"
                        "CT request too big (adapter %s)\n",
			zfcp_get_busid_by_adapter(adapter));
                ret = -EOPNOTSUPP;
                goto failed_send;
        }

	/* settings in QTCB */
	fsf_req->qtcb->header.port_handle = port->handle;
	fsf_req->qtcb->bottom.support.service_class =
		ZFCP_FC_SERVICE_CLASS_DEFAULT;
	fsf_req->qtcb->bottom.support.timeout = ct->timeout;
        fsf_req->data = (unsigned long) ct;

	zfcp_san_dbf_event_ct_request(fsf_req);

	if (erp_action) {
		erp_action->fsf_req = fsf_req;
		fsf_req->erp_action = erp_action;
		zfcp_erp_start_timer(fsf_req);
	} else
		zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);

	ret = zfcp_fsf_req_send(fsf_req);
	if (ret) {
		ZFCP_LOG_DEBUG("error: initiation of CT request failed "
			       "(adapter %s, port 0x%016Lx)\n",
			       zfcp_get_busid_by_adapter(adapter), port->wwpn);
		goto failed_send;
	}

	ZFCP_LOG_DEBUG("CT request initiated (adapter %s, port 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(adapter), port->wwpn);
	goto out;

 failed_send:
	zfcp_fsf_req_free(fsf_req);
        if (erp_action != NULL) {
                erp_action->fsf_req = NULL;
        }
 failed_req:
 out:
        write_unlock_irqrestore(&adapter->request_queue.queue_lock,
				lock_flags);
	return ret;
}

/**
 * zfcp_fsf_send_ct_handler - handler for Generic Service requests
 * @fsf_req: pointer to struct zfcp_fsf_req
 *
 * Data specific for the Generic Service request is passed using
 * fsf_req->data. There we find the pointer to struct zfcp_send_ct.
 * Usually a specific handler for the CT request is called which is
 * found in this structure.
 */
static int
zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
{
	struct zfcp_port *port;
	struct zfcp_adapter *adapter;
	struct zfcp_send_ct *send_ct;
	struct fsf_qtcb_header *header;
	struct fsf_qtcb_bottom_support *bottom;
	int retval = -EINVAL;
	u16 subtable, rule, counter;

	adapter = fsf_req->adapter;
	send_ct = (struct zfcp_send_ct *) fsf_req->data;
	port = send_ct->port;
	header = &fsf_req->qtcb->header;
	bottom = &fsf_req->qtcb->bottom.support;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
		goto skip_fsfstatus;

	/* evaluate FSF status in QTCB */
	switch (header->fsf_status) {

        case FSF_GOOD:
		zfcp_san_dbf_event_ct_response(fsf_req);
                retval = 0;
		break;

        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
		ZFCP_LOG_INFO("error: adapter %s does not support fc "
			      "class %d.\n",
			      zfcp_get_busid_by_port(port),
			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
		/* stop operation for this adapter */
		zfcp_erp_adapter_shutdown(adapter, 0, 123, fsf_req);
		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:
			/* reopening link to port */
			zfcp_test_link(port);
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
                case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
                default:
			ZFCP_LOG_INFO("bug: Wrong status qualifier 0x%x "
				      "arrived.\n",
				      header->fsf_status_qual.word[0]);
			break;
                }
                break;

	case FSF_ACCESS_DENIED:
		ZFCP_LOG_NORMAL("access denied, cannot send generic service "
				"command (adapter %s, port d_id=0x%06x)\n",
				zfcp_get_busid_by_port(port), port->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;
			}
		}
		zfcp_erp_port_access_denied(port, 55, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

        case FSF_GENERIC_COMMAND_REJECTED:
		ZFCP_LOG_INFO("generic service command rejected "
			      "(adapter %s, port d_id=0x%06x)\n",
			      zfcp_get_busid_by_port(port), port->d_id);
		ZFCP_LOG_INFO("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

        case FSF_PORT_HANDLE_NOT_VALID:
		ZFCP_LOG_DEBUG("Temporary port identifier 0x%x for port "
			       "0x%016Lx on adapter %s invalid. This may "
			       "happen occasionally.\n", port->handle,
			       port->wwpn, zfcp_get_busid_by_port(port));
		ZFCP_LOG_INFO("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(adapter, 0, 106, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

        case FSF_PORT_BOXED:
		ZFCP_LOG_INFO("port needs to be reopened "
			      "(adapter %s, port d_id=0x%06x)\n",
			      zfcp_get_busid_by_port(port), port->d_id);
		zfcp_erp_port_boxed(port, 49, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
		    | ZFCP_STATUS_FSFREQ_RETRY;
		break;

	/* following states should never occure, all cases avoided
	   in zfcp_fsf_send_ct - but who knows ... */
	case FSF_PAYLOAD_SIZE_MISMATCH:
		ZFCP_LOG_INFO("payload size 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_REQUEST_SIZE_TOO_LARGE:
		ZFCP_LOG_INFO("request size too large (adapter: %s, "
			      "req_buf_length=%d)\n",
			      zfcp_get_busid_by_adapter(adapter),
			      bottom->req_buf_length);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_RESPONSE_SIZE_TOO_LARGE:
		ZFCP_LOG_INFO("response size too large (adapter: %s, "
			      "resp_buf_length=%d)\n",
			      zfcp_get_busid_by_adapter(adapter),
			      bottom->resp_buf_length);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	case FSF_SBAL_MISMATCH:
		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;

       default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n", header->fsf_status);
		break;
	}

skip_fsfstatus:
	send_ct->status = retval;

	if (send_ct->handler != NULL)
		send_ct->handler(send_ct->handler_data);

	return retval;
}

/**
 * zfcp_fsf_send_els - initiate an ELS command (FC-FS)
 * @els: pointer to struct zfcp_send_els which contains all needed data for
 *	the command.
 */
int
zfcp_fsf_send_els(struct zfcp_send_els *els)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	u32 d_id;
	struct zfcp_adapter *adapter;
	unsigned long lock_flags;
        int bytes;
	int ret = 0;

	d_id = els->d_id;
	adapter = els->adapter;

        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%06x)\n",
                              zfcp_get_busid_by_adapter(adapter), d_id);
                goto failed_req;
	}

	if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
			&els->port->status))) {
		ret = -EBUSY;
		goto port_blocked;
	}

	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%06x)\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%06x)\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%06x)\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 =
		ZFCP_FC_SERVICE_CLASS_DEFAULT;
	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);

	zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
	ret = zfcp_fsf_req_send(fsf_req);
	if (ret) {
		ZFCP_LOG_DEBUG("error: initiation of ELS request failed "
			       "(adapter %s, port d_id: 0x%06x)\n",
			       zfcp_get_busid_by_adapter(adapter), d_id);
		goto failed_send;
	}

	ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: "
		       "0x%06x)\n", zfcp_get_busid_by_adapter(adapter), d_id);
	goto out;

 port_blocked:
 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:
		ZFCP_LOG_INFO("error: adapter %s does not support fc "
			      "class %d.\n",
			      zfcp_get_busid_by_adapter(adapter),
			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
		/* stop operation for this adapter */
		zfcp_erp_adapter_shutdown(adapter, 0, 124, fsf_req);
		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:
			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:
			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:
			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%06x)\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%06x)\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;
			}
		}
		if (port != NULL)
			zfcp_erp_port_access_denied(port, 56, fsf_req);
		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);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;
	}

skip_fsfstatus:
	send_els->status = retval;

	if (send_els->handler)
		send_els->handler(send_els->handler_data);

	return retval;
}

int
zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	struct zfcp_adapter *adapter = erp_action->adapter;
	unsigned long lock_flags;
	int retval;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter,
				     FSF_QTCB_EXCHANGE_CONFIG_DATA,
				     ZFCP_REQ_AUTO_CLEANUP,
				     adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not create exchange configuration "
			      "data request for adapter %s.\n",
			      zfcp_get_busid_by_adapter(adapter));
		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
					lock_flags);
		return retval;
	}

	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->qtcb->bottom.config.feature_selection =
			FSF_FEATURE_CFDC |
			FSF_FEATURE_LUN_SHARING |
			FSF_FEATURE_NOTIFICATION_LOST |
			FSF_FEATURE_UPDATE_ALERT;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(fsf_req);
	write_unlock_irqrestore(&adapter->request_queue.queue_lock,
				lock_flags);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send exchange configuration "
			      "data command on the adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
	}
	else
		ZFCP_LOG_DEBUG("exchange configuration data request initiated "
			       "(adapter %s)\n",
			       zfcp_get_busid_by_adapter(adapter));

	return retval;
}

int
zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
				struct fsf_qtcb_bottom_config *data)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
				     ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags,
				     &fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not create exchange configuration "
			      "data request for adapter %s.\n",
			      zfcp_get_busid_by_adapter(adapter));
		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
					lock_flags);
		return retval;
	}

	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->qtcb->bottom.config.feature_selection =
			FSF_FEATURE_CFDC |
			FSF_FEATURE_LUN_SHARING |
			FSF_FEATURE_NOTIFICATION_LOST |
			FSF_FEATURE_UPDATE_ALERT;

	if (data)
		fsf_req->data = (unsigned long) data;

	zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(fsf_req);
	write_unlock_irqrestore(&adapter->request_queue.queue_lock,
				lock_flags);
	if (retval)
		ZFCP_LOG_INFO("error: Could not send exchange configuration "
			      "data command on the adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
	else
		wait_event(fsf_req->completion_wq,
			   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

	zfcp_fsf_req_free(fsf_req);

	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 int
zfcp_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) {

		if (fsf_req->data)
			memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data,
				bottom, sizeof (struct fsf_qtcb_bottom_config));

		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->hydra_version = bottom->adapter_type;
		if (fc_host_permanent_port_name(shost) == -1)
			fc_host_permanent_port_name(shost) =
				fc_host_port_name(shost);
		if (bottom->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;
			fc_host_port_type(shost) = FC_PORTTYPE_PTP;
		} else if (bottom->fc_topology == FSF_TOPO_FABRIC)
			fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
		else if (bottom->fc_topology == FSF_TOPO_AL)
			fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
		else
			fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
	} 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;
		fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
		adapter->hydra_version = 0;
	}

	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));
	}

	if (fsf_req->erp_action)
		ZFCP_LOG_NORMAL("The adapter %s reported the following "
				"characteristics:\n"
				"WWNN 0x%016Lx, WWPN 0x%016Lx, "
				"S_ID 0x%06x,\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_host_port_id(shost),
				adapter->hydra_version,
				adapter->fsf_lic_version,
				fc_host_speed(shost));
	if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) {
		ZFCP_LOG_NORMAL("error: the adapter %s "
				"only supports newer control block "
				"versions in comparison to this device "
				"driver (try updated device driver)\n",
				zfcp_get_busid_by_adapter(adapter));
		zfcp_erp_adapter_shutdown(adapter, 0, 125, fsf_req);
		return -EIO;
	}
	if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) {
		ZFCP_LOG_NORMAL("error: the adapter %s "
				"only supports older control block "
				"versions than this device driver uses"
				"(consider a microcode upgrade)\n",
				zfcp_get_busid_by_adapter(adapter));
		zfcp_erp_adapter_shutdown(adapter, 0, 126, fsf_req);
		return -EIO;
	}
	return 0;
}

/**
 * function:    zfcp_fsf_exchange_config_data_handler
 *
 * purpose:     is called for finished Exchange Configuration Data command
 *
 * returns:
 */
static int
zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
{
	struct fsf_qtcb_bottom_config *bottom;
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct fsf_qtcb *qtcb = fsf_req->qtcb;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
		return -EIO;

	switch (qtcb->header.fsf_status) {

	case FSF_GOOD:
		if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
			return -EIO;

		switch (fc_host_port_type(adapter->scsi_host)) {
		case FC_PORTTYPE_PTP:
			ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
					"configuration detected at adapter %s\n"
					"Peer WWNN 0x%016llx, "
					"peer WWPN 0x%016llx, "
					"peer d_id 0x%06x\n",
					zfcp_get_busid_by_adapter(adapter),
					adapter->peer_wwnn,
					adapter->peer_wwpn,
					adapter->peer_d_id);
			break;
		case FC_PORTTYPE_NLPORT:
			ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
					"topology detected at adapter %s "
					"unsupported, shutting down adapter\n",
					zfcp_get_busid_by_adapter(adapter));
			zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req);
			return -EIO;
		case FC_PORTTYPE_NPORT:
			if (fsf_req->erp_action)
				ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
						"network detected at adapter "
						"%s.\n",
					zfcp_get_busid_by_adapter(adapter));
			break;
		default:
			ZFCP_LOG_NORMAL("bug: The fibrechannel topology "
					"reported by the exchange "
					"configuration command for "
					"the adapter %s is not "
					"of a type known to the zfcp "
					"driver, shutting down adapter\n",
					zfcp_get_busid_by_adapter(adapter));
			zfcp_erp_adapter_shutdown(adapter, 0, 128, fsf_req);
			return -EIO;
		}
		bottom = &qtcb->bottom.config;
		if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) {
			ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) "
					"allowed by the adapter %s "
					"is lower than the minimum "
					"required by the driver (%ld bytes).\n",
					bottom->max_qtcb_size,
					zfcp_get_busid_by_adapter(adapter),
					sizeof(struct fsf_qtcb));
			zfcp_erp_adapter_shutdown(adapter, 0, 129, fsf_req);
			return -EIO;
		}
		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
				&adapter->status);
		break;
	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
		if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
			return -EIO;

		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
				&adapter->status);

		zfcp_fsf_link_down_info_eval(fsf_req, 42,
			&qtcb->header.fsf_status_qual.link_down_info);
		break;
	default:
		zfcp_erp_adapter_shutdown(adapter, 0, 130, fsf_req);
		return -EIO;
	}
	return 0;
}

/**
 * zfcp_fsf_exchange_port_data - request information about local port
 * @erp_action: ERP action for the adapter for which port data is requested
 */
int
zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	struct zfcp_adapter *adapter = erp_action->adapter;
	unsigned long lock_flags;
	int retval;

	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
		ZFCP_LOG_INFO("error: exchange port data "
			      "command not supported by adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
		return -EOPNOTSUPP;
	}

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
				     ZFCP_REQ_AUTO_CLEANUP,
				     adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Out of resources. Could not create an "
			      "exchange port data request for "
			      "the adapter %s.\n",
			      zfcp_get_busid_by_adapter(adapter));
		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
					lock_flags);
		return retval;
	}

	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;

	erp_action->fsf_req = fsf_req;
	fsf_req->erp_action = erp_action;
	zfcp_erp_start_timer(fsf_req);

	retval = zfcp_fsf_req_send(fsf_req);
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);

	if (retval) {
		ZFCP_LOG_INFO("error: Could not send an exchange port data "
			      "command on the adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
	}
	else
		ZFCP_LOG_DEBUG("exchange port data request initiated "
			       "(adapter %s)\n",
			       zfcp_get_busid_by_adapter(adapter));
	return retval;
}


/**
 * zfcp_fsf_exchange_port_data_sync - request information about local port
 * and wait until information is ready
 */
int
zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
				struct fsf_qtcb_bottom_port *data)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval;

	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
		ZFCP_LOG_INFO("error: exchange port data "
			      "command not supported by adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
		return -EOPNOTSUPP;
	}

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
				0, NULL, &lock_flags, &fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Out of resources. Could not create an "
			      "exchange port data request for "
			      "the adapter %s.\n",
			      zfcp_get_busid_by_adapter(adapter));
		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
					lock_flags);
		return retval;
	}

	if (data)
		fsf_req->data = (unsigned long) data;

	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;

	zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(fsf_req);
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);

	if (retval)
		ZFCP_LOG_INFO("error: Could not send an exchange port data "
			      "command on the adapter %s\n",
			      zfcp_get_busid_by_adapter(adapter));
	else
		wait_event(fsf_req->completion_wq,
			   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

	zfcp_fsf_req_free(fsf_req);

	return retval;
}

/**
 * zfcp_fsf_exchange_port_evaluate
 * @fsf_req: fsf_req which belongs to xchg port data request
 * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1)
 */
static void
zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
{
	struct zfcp_adapter *adapter;
	struct fsf_qtcb_bottom_port *bottom;
	struct Scsi_Host *shost;

	adapter = fsf_req->adapter;
	bottom = &fsf_req->qtcb->bottom.port;
	shost = adapter->scsi_host;

	if (fsf_req->data)
		memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom,
			sizeof(struct fsf_qtcb_bottom_port));

	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
		fc_host_permanent_port_name(shost) = bottom->wwpn;
	else
		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
	fc_host_supported_speeds(shost) = bottom->supported_speed;
}

/**
 * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request
 * @fsf_req: pointer to struct zfcp_fsf_req
 */
static void
zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
{
	struct zfcp_adapter *adapter;
	struct fsf_qtcb *qtcb;

	adapter = fsf_req->adapter;
	qtcb = fsf_req->qtcb;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
		return;

	switch (qtcb->header.fsf_status) {
        case FSF_GOOD:
		zfcp_fsf_exchange_port_evaluate(fsf_req, 1);
		atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
		break;
	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
		zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
		atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
		zfcp_fsf_link_down_info_eval(fsf_req, 43,
			&qtcb->header.fsf_status_qual.link_down_info);
                break;
	}
}


/*
 * function:    zfcp_fsf_open_port
 *
 * purpose:
 *
 * returns:	address of initiated FSF request
 *		NULL - request could not be initiated
 */
int
zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(erp_action->adapter,
				     FSF_QTCB_OPEN_PORT_WITH_DID,
				     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				     erp_action->adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create open port request "
			      "for port 0x%016Lx on adapter %s.\n",
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->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->qtcb->bottom.support.d_id = erp_action->port->d_id;
	atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status);
	fsf_req->data = (unsigned long) erp_action->port;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send open port request for "
			      "port 0x%016Lx on adapter %s.\n",
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->adapter));
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_DEBUG("open port request initiated "
		       "(adapter %s,  port 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(erp_action->adapter),
		       erp_action->port->wwpn);
 out:
	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,
				lock_flags);
	return retval;
}

/*
 * function:    zfcp_fsf_open_port_handler
 *
 * purpose:	is called for finished Open Port command
 *
 * returns:
 */
static int
zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_port *port;
	struct fsf_plogi *plogi;
	struct fsf_qtcb_header *header;
	u16 subtable, rule, counter;

	port = (struct zfcp_port *) fsf_req->data;
	header = &fsf_req->qtcb->header;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		/* don't change port status in our bookkeeping */
		goto skip_fsfstatus;
	}

	/* evaluate FSF status in QTCB */
	switch (header->fsf_status) {

	case FSF_PORT_ALREADY_OPEN:
		ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s "
				"is already open.\n",
				port->wwpn, zfcp_get_busid_by_port(port));
		/*
		 * This is a bug, however operation should continue normally
		 * if it is simply ignored
		 */
		break;

	case FSF_ACCESS_DENIED:
		ZFCP_LOG_NORMAL("Access denied, cannot open port 0x%016Lx "
				"on adapter %s\n",
				port->wwpn, zfcp_get_busid_by_port(port));
		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;
			}
		}
		zfcp_erp_port_access_denied(port, 57, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
		ZFCP_LOG_INFO("error: The FSF adapter is out of resources. "
			      "The remote port 0x%016Lx on adapter %s "
			      "could not be opened. Disabling it.\n",
			      port->wwpn, zfcp_get_busid_by_port(port));
		zfcp_erp_port_failed(port, 31, fsf_req);
		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:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_NO_RETRY_POSSIBLE:
			ZFCP_LOG_NORMAL("The remote port 0x%016Lx on "
					"adapter %s could not be opened. "
					"Disabling it.\n",
					port->wwpn,
					zfcp_get_busid_by_port(port));
			zfcp_erp_port_failed(port, 32, fsf_req);
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		default:
			ZFCP_LOG_NORMAL
			    ("bug: Wrong status qualifier 0x%x arrived.\n",
			     header->fsf_status_qual.word[0]);
			break;
		}
		break;

	case FSF_GOOD:
		/* save port handle assigned by FSF */
		port->handle = header->port_handle;
		ZFCP_LOG_INFO("The remote port 0x%016Lx via adapter %s "
			      "was opened, it's port handle is 0x%x\n",
			      port->wwpn, zfcp_get_busid_by_port(port),
			      port->handle);
		/* mark port as open */
		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN |
				ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
		atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
		                  ZFCP_STATUS_COMMON_ACCESS_BOXED,
		                  &port->status);
		retval = 0;
		/* check whether D_ID has changed during open */
		/*
		 * FIXME: This check is not airtight, as the FCP channel does
		 * not monitor closures of target port connections caused on
		 * the remote side. Thus, they might miss out on invalidating
		 * locally cached WWPNs (and other N_Port parameters) of gone
		 * target ports. So, our heroic attempt to make things safe
		 * could be undermined by 'open port' response data tagged with
		 * obsolete WWPNs. Another reason to monitor potential
		 * connection closures ourself at least (by interpreting
		 * incoming ELS' and unsolicited status). It just crosses my
		 * mind that one should be able to cross-check by means of
		 * another GID_PN straight after a port has been opened.
		 * Alternately, an ADISC/PDISC ELS should suffice, as well.
		 */
		plogi = (struct fsf_plogi *) fsf_req->qtcb->bottom.support.els;
		if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status))
		{
			if (fsf_req->qtcb->bottom.support.els1_length <
			    sizeof (struct fsf_plogi)) {
				ZFCP_LOG_INFO(
					"warning: insufficient length of "
					"PLOGI payload (%i)\n",
					fsf_req->qtcb->bottom.support.els1_length);
				/* skip sanity check and assume wwpn is ok */
			} else {
				if (plogi->serv_param.wwpn != port->wwpn) {
					ZFCP_LOG_INFO("warning: d_id of port "
						      "0x%016Lx changed during "
						      "open\n", port->wwpn);
					atomic_clear_mask(
						ZFCP_STATUS_PORT_DID_DID,
						&port->status);
				} else {
					port->wwnn = plogi->serv_param.wwnn;
					zfcp_plogi_evaluate(port, plogi);
				}
			}
		}
		break;

	case FSF_UNKNOWN_OP_SUBTYPE:
		/* should never occure, subtype not set in zfcp_fsf_open_port */
		ZFCP_LOG_INFO("unknown operation subtype (adapter: %s, "
			      "op_subtype=0x%x)\n",
			      zfcp_get_busid_by_port(port),
			      fsf_req->qtcb->bottom.support.operation_subtype);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				header->fsf_status);
		break;
	}

 skip_fsfstatus:
	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &port->status);
	return retval;
}

/*
 * function:    zfcp_fsf_close_port
 *
 * purpose:     submit FSF command "close port"
 *
 * returns:     address of initiated FSF request
 *              NULL - request could not be initiated
 */
int
zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(erp_action->adapter,
				     FSF_QTCB_CLOSE_PORT,
				     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				     erp_action->adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create a close port request "
			      "for port 0x%016Lx on adapter %s.\n",
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->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;

	atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status);
	fsf_req->data = (unsigned long) erp_action->port;
	fsf_req->erp_action = erp_action;
	fsf_req->qtcb->header.port_handle = erp_action->port->handle;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send a close port request for "
			      "port 0x%016Lx on adapter %s.\n",
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->adapter));
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_TRACE("close port request initiated "
		       "(adapter %s, port 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(erp_action->adapter),
		       erp_action->port->wwpn);
 out:
	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,
				lock_flags);
	return retval;
}

/*
 * function:    zfcp_fsf_close_port_handler
 *
 * purpose:     is called for finished Close Port FSF command
 *
 * returns:
 */
static int
zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_port *port;

	port = (struct zfcp_port *) fsf_req->data;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		/* don't change port status in our bookkeeping */
		goto skip_fsfstatus;
	}

	/* evaluate FSF status in QTCB */
	switch (fsf_req->qtcb->header.fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
			      "0x%016Lx on adapter %s invalid. This may happen "
			      "occasionally.\n", port->handle,
			      port->wwpn, zfcp_get_busid_by_port(port));
		ZFCP_LOG_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(port->adapter, 0, 107, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		/* Note: FSF has actually closed the port in this case.
		 * The status code is just daft. Fingers crossed for a change
		 */
		retval = 0;
		break;

	case FSF_GOOD:
		ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, "
			       "port handle 0x%x\n", port->wwpn,
			       zfcp_get_busid_by_port(port), port->handle);
		zfcp_erp_modify_port_status(port, 33, fsf_req,
					    ZFCP_STATUS_COMMON_OPEN,
					    ZFCP_CLEAR);
		retval = 0;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				fsf_req->qtcb->header.fsf_status);
		break;
	}

 skip_fsfstatus:
	atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &port->status);
	return retval;
}

/*
 * function:    zfcp_fsf_close_physical_port
 *
 * purpose:     submit FSF command "close physical port"
 *
 * returns:     address of initiated FSF request
 *              NULL - request could not be initiated
 */
int
zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(erp_action->adapter,
				     FSF_QTCB_CLOSE_PHYSICAL_PORT,
				     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				     erp_action->adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create close physical port "
			      "request (adapter %s, port 0x%016Lx)\n",
			      zfcp_get_busid_by_adapter(erp_action->adapter),
			      erp_action->port->wwpn);

		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;

	/* mark port as being closed */
	atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
			&erp_action->port->status);
	/* save a pointer to this port */
	fsf_req->data = (unsigned long) erp_action->port;
	fsf_req->qtcb->header.port_handle = erp_action->port->handle;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send close physical port "
			      "request (adapter %s, port 0x%016Lx)\n",
			      zfcp_get_busid_by_adapter(erp_action->adapter),
			      erp_action->port->wwpn);
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_TRACE("close physical port request initiated "
		       "(adapter %s, port 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(erp_action->adapter),
		       erp_action->port->wwpn);
 out:
	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,
				lock_flags);
	return retval;
}

/*
 * function:    zfcp_fsf_close_physical_port_handler
 *
 * purpose:     is called for finished Close Physical Port FSF command
 *
 * returns:
 */
static int
zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_port *port;
	struct zfcp_unit *unit;
	struct fsf_qtcb_header *header;
	u16 subtable, rule, counter;

	port = (struct zfcp_port *) fsf_req->data;
	header = &fsf_req->qtcb->header;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		/* don't change port status in our bookkeeping */
		goto skip_fsfstatus;
	}

	/* evaluate FSF status in QTCB */
	switch (header->fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary port identifier 0x%x invalid"
			      "(adapter %s, port 0x%016Lx). "
			      "This may happen occasionally.\n",
			      port->handle,
			      zfcp_get_busid_by_port(port),
			      port->wwpn);
		ZFCP_LOG_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(port->adapter, 0, 108, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_ACCESS_DENIED:
		ZFCP_LOG_NORMAL("Access denied, cannot close "
				"physical port 0x%016Lx on adapter %s\n",
				port->wwpn, zfcp_get_busid_by_port(port));
		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;
			}
		}
		zfcp_erp_port_access_denied(port, 58, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PORT_BOXED:
		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter "
			       "%s needs to be reopened but it was attempted "
			       "to close it physically.\n",
			       port->wwpn,
			       zfcp_get_busid_by_port(port));
		zfcp_erp_port_boxed(port, 50, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;

		/* can't use generic zfcp_erp_modify_port_status because
		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
		list_for_each_entry(unit, &port->unit_list_head, list)
			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
					  &unit->status);
		break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
			/* This will now be escalated by ERP */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		default:
			ZFCP_LOG_NORMAL
			    ("bug: Wrong status qualifier 0x%x arrived.\n",
			     header->fsf_status_qual.word[0]);
			break;
		}
		break;

	case FSF_GOOD:
		ZFCP_LOG_DEBUG("Remote port 0x%016Lx via adapter %s "
			       "physically closed, port handle 0x%x\n",
			       port->wwpn,
			       zfcp_get_busid_by_port(port), port->handle);
		/* can't use generic zfcp_erp_modify_port_status because
		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port
		 */
		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
		list_for_each_entry(unit, &port->unit_list_head, list)
		    atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
		retval = 0;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				header->fsf_status);
		break;
	}

 skip_fsfstatus:
	atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, &port->status);
	return retval;
}

/*
 * function:    zfcp_fsf_open_unit
 *
 * purpose:
 *
 * returns:
 *
 * assumptions:	This routine does not check whether the associated
 *		remote port has already been opened. This should be
 *		done by calling routines. Otherwise some status
 *		may be presented by FSF
 */
int
zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(erp_action->adapter,
				     FSF_QTCB_OPEN_LUN,
				     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				     erp_action->adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create open unit request for "
			      "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n",
			      erp_action->unit->fcp_lun,
			      erp_action->unit->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->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->qtcb->header.port_handle = erp_action->port->handle;
	fsf_req->qtcb->bottom.support.fcp_lun =	erp_action->unit->fcp_lun;
	if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE))
		fsf_req->qtcb->bottom.support.option =
			FSF_OPEN_LUN_SUPPRESS_BOXING;
	atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
	fsf_req->data = (unsigned long) erp_action->unit;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(erp_action->fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send an open unit request "
			      "on the adapter %s, port 0x%016Lx for "
			      "unit 0x%016Lx\n",
			      zfcp_get_busid_by_adapter(erp_action->adapter),
			      erp_action->port->wwpn,
			      erp_action->unit->fcp_lun);
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_TRACE("Open LUN request initiated (adapter %s, "
		       "port 0x%016Lx, unit 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(erp_action->adapter),
		       erp_action->port->wwpn, erp_action->unit->fcp_lun);
 out:
	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,
				lock_flags);
	return retval;
}

/*
 * function:    zfcp_fsf_open_unit_handler
 *
 * purpose:	is called for finished Open LUN command
 *
 * returns:
 */
static int
zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_adapter *adapter;
	struct zfcp_unit *unit;
	struct fsf_qtcb_header *header;
	struct fsf_qtcb_bottom_support *bottom;
	struct fsf_queue_designator *queue_designator;
	u16 subtable, rule, counter;
	int exclusive, readwrite;

	unit = (struct zfcp_unit *) fsf_req->data;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		/* don't change unit status in our bookkeeping */
		goto skip_fsfstatus;
	}

	adapter = fsf_req->adapter;
	header = &fsf_req->qtcb->header;
	bottom = &fsf_req->qtcb->bottom.support;
	queue_designator = &header->fsf_status_qual.fsf_queue_designator;

	atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
			  ZFCP_STATUS_COMMON_ACCESS_BOXED |
			  ZFCP_STATUS_UNIT_SHARED |
			  ZFCP_STATUS_UNIT_READONLY,
			  &unit->status);

	/* evaluate FSF status in QTCB */
	switch (header->fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
		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_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_LUN_ALREADY_OPEN:
		ZFCP_LOG_NORMAL("bug: Attempted to open unit 0x%016Lx on "
				"remote port 0x%016Lx on adapter %s twice.\n",
				unit->fcp_lun,
				unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_ACCESS_DENIED:
		ZFCP_LOG_NORMAL("Access denied, cannot open unit 0x%016Lx on "
				"remote port 0x%016Lx on adapter %s\n",
				unit->fcp_lun, unit->port->wwpn,
				zfcp_get_busid_by_unit(unit));
		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;
			}
		}
		zfcp_erp_unit_access_denied(unit, 59, fsf_req);
		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
                atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PORT_BOXED:
		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
			       "needs to be reopened\n",
			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		zfcp_erp_port_boxed(unit->port, 51, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;

	case FSF_LUN_SHARING_VIOLATION:
		if (header->fsf_status_qual.word[0] != 0) {
			ZFCP_LOG_NORMAL("FCP-LUN 0x%Lx at the remote port "
					"with WWPN 0x%Lx "
					"connected to the adapter %s "
					"is already in use in LPAR%d, CSS%d\n",
					unit->fcp_lun,
					unit->port->wwpn,
					zfcp_get_busid_by_unit(unit),
					queue_designator->hla,
					queue_designator->cssid);
		} else {
			subtable = header->fsf_status_qual.halfword[4];
			rule = header->fsf_status_qual.halfword[5];
			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_NORMAL("Access to FCP-LUN 0x%Lx at the "
						"remote port with WWPN 0x%Lx "
						"connected to the adapter %s "
						"is denied (%s rule %d)\n",
						unit->fcp_lun,
						unit->port->wwpn,
						zfcp_get_busid_by_unit(unit),
						zfcp_act_subtable_type[subtable],
						rule);
				break;
			}
		}
		ZFCP_LOG_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_unit_access_denied(unit, 60, fsf_req);
		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
		atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED:
		ZFCP_LOG_INFO("error: The adapter ran out of resources. "
			      "There is no handle (temporary port identifier) "
			      "available for unit 0x%016Lx on port 0x%016Lx "
			      "on adapter %s\n",
			      unit->fcp_lun,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit));
		zfcp_erp_unit_failed(unit, 34, fsf_req);
		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:
			/* Re-establish link to port */
			zfcp_test_link(unit->port);
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		default:
			ZFCP_LOG_NORMAL
			    ("bug: Wrong status qualifier 0x%x arrived.\n",
			     header->fsf_status_qual.word[0]);
		}
		break;

	case FSF_INVALID_COMMAND_OPTION:
		ZFCP_LOG_NORMAL(
			"Invalid option 0x%x has been specified "
			"in QTCB bottom sent to the adapter %s\n",
			bottom->option,
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EINVAL;
		break;

	case FSF_GOOD:
		/* save LUN handle assigned by FSF */
		unit->handle = header->lun_handle;
		ZFCP_LOG_TRACE("unit 0x%016Lx on remote port 0x%016Lx on "
			       "adapter %s opened, port handle 0x%x\n",
			       unit->fcp_lun,
			       unit->port->wwpn,
			       zfcp_get_busid_by_unit(unit),
			       unit->handle);
		/* mark unit as open */
		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);

		if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) &&
		    (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) &&
		    (adapter->ccw_device->id.dev_model != ZFCP_DEVICE_MODEL_PRIV)) {
			exclusive = (bottom->lun_access_info &
					FSF_UNIT_ACCESS_EXCLUSIVE);
			readwrite = (bottom->lun_access_info &
					FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);

			if (!exclusive)
		                atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
						&unit->status);

			if (!readwrite) {
                		atomic_set_mask(ZFCP_STATUS_UNIT_READONLY,
						&unit->status);
                		ZFCP_LOG_NORMAL("read-only access for unit "
						"(adapter %s, wwpn=0x%016Lx, "
						"fcp_lun=0x%016Lx)\n",
						zfcp_get_busid_by_unit(unit),
						unit->port->wwpn,
						unit->fcp_lun);
        		}

        		if (exclusive && !readwrite) {
                		ZFCP_LOG_NORMAL("exclusive access of read-only "
						"unit not supported\n");
				zfcp_erp_unit_failed(unit, 35, fsf_req);
				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
				zfcp_erp_unit_shutdown(unit, 0, 80, fsf_req);
        		} else if (!exclusive && readwrite) {
                		ZFCP_LOG_NORMAL("shared access of read-write "
						"unit not supported\n");
				zfcp_erp_unit_failed(unit, 36, fsf_req);
				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
				zfcp_erp_unit_shutdown(unit, 0, 81, fsf_req);
        		}
		}

		retval = 0;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				header->fsf_status);
		break;
	}

 skip_fsfstatus:
	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &unit->status);
	return retval;
}

/*
 * function:    zfcp_fsf_close_unit
 *
 * purpose:
 *
 * returns:	address of fsf_req - request successfully initiated
 *		NULL -
 *
 * assumptions: This routine does not check whether the associated
 *              remote port/lun has already been opened. This should be
 *              done by calling routines. Otherwise some status
 *              may be presented by FSF
 */
int
zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req;
	unsigned long lock_flags;
	int retval = 0;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(erp_action->adapter,
				     FSF_QTCB_CLOSE_LUN,
				     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
				     erp_action->adapter->pool.fsf_req_erp,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create close unit request for "
			      "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n",
			      erp_action->unit->fcp_lun,
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->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->qtcb->header.port_handle = erp_action->port->handle;
	fsf_req->qtcb->header.lun_handle = erp_action->unit->handle;
	atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status);
	fsf_req->data = (unsigned long) erp_action->unit;
	fsf_req->erp_action = erp_action;
	erp_action->fsf_req = fsf_req;

	zfcp_erp_start_timer(fsf_req);
	retval = zfcp_fsf_req_send(erp_action->fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not send a close unit request for "
			      "unit 0x%016Lx on port 0x%016Lx onadapter %s.\n",
			      erp_action->unit->fcp_lun,
			      erp_action->port->wwpn,
			      zfcp_get_busid_by_adapter(erp_action->adapter));
		zfcp_fsf_req_free(fsf_req);
		erp_action->fsf_req = NULL;
		goto out;
	}

	ZFCP_LOG_TRACE("Close LUN request initiated (adapter %s, "
		       "port 0x%016Lx, unit 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(erp_action->adapter),
		       erp_action->port->wwpn, erp_action->unit->fcp_lun);
 out:
	write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock,
				lock_flags);
	return retval;
}

/*
 * function:    zfcp_fsf_close_unit_handler
 *
 * purpose:     is called for finished Close LUN FSF command
 *
 * returns:
 */
static int
zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_unit *unit;

	unit = (struct zfcp_unit *) fsf_req->data;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		/* don't change unit status in our bookkeeping */
		goto skip_fsfstatus;
	}

	/* evaluate FSF status in QTCB */
	switch (fsf_req->qtcb->header.fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
			      "0x%016Lx on adapter %s invalid. This may "
			      "happen in rare circumstances\n",
			      unit->port->handle,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit));
		ZFCP_LOG_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_LUN_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary LUN identifier 0x%x of unit "
			      "0x%016Lx on port 0x%016Lx on adapter %s is "
			      "invalid. This may happen occasionally.\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 *) &fsf_req->qtcb->header.fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_port_reopen(unit->port, 0, 111, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PORT_BOXED:
		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
			       "needs to be reopened\n",
			       unit->port->wwpn,
			       zfcp_get_busid_by_unit(unit));
		zfcp_erp_port_boxed(unit->port, 52, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
			/* re-establish link to port */
			zfcp_test_link(unit->port);
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* ERP strategy will escalate */
			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
			break;
		default:
			ZFCP_LOG_NORMAL
			    ("bug: Wrong status qualifier 0x%x arrived.\n",
			     fsf_req->qtcb->header.fsf_status_qual.word[0]);
			break;
		}
		break;

	case FSF_GOOD:
		ZFCP_LOG_TRACE("unit 0x%016Lx on port 0x%016Lx on adapter %s "
			       "closed, port handle 0x%x\n",
			       unit->fcp_lun,
			       unit->port->wwpn,
			       zfcp_get_busid_by_unit(unit),
			       unit->handle);
		/* mark unit as closed */
		atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
		retval = 0;
		break;

	default:
		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
				"(debug info 0x%x)\n",
				fsf_req->qtcb->header.fsf_status);
		break;
	}

 skip_fsfstatus:
	atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &unit->status);
	return retval;
}

/**
 * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
 * @adapter: adapter where scsi command is issued
 * @unit: unit where command is sent to
 * @scsi_cmnd: scsi command to be sent
 * @timer: timer to be started when request is initiated
 * @req_flags: flags for fsf_request
 */
int
zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
			       struct zfcp_unit *unit,
			       struct scsi_cmnd * scsi_cmnd,
			       int use_timer, int req_flags)
{
	struct zfcp_fsf_req *fsf_req = NULL;
	struct fcp_cmnd_iu *fcp_cmnd_iu;
	unsigned int sbtype;
	unsigned long lock_flags;
	int real_bytes = 0;
	int retval = 0;
	int mask;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
				     adapter->pool.fsf_req_scsi,
				     &lock_flags, &fsf_req);
	if (unlikely(retval < 0)) {
		ZFCP_LOG_DEBUG("error: Could not create FCP command request "
			       "for unit 0x%016Lx on port 0x%016Lx on "
			       "adapter %s\n",
			       unit->fcp_lun,
			       unit->port->wwpn,
			       zfcp_get_busid_by_adapter(adapter));
		goto failed_req_create;
	}

	if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
			&unit->status))) {
		retval = -EBUSY;
		goto unit_blocked;
	}

	zfcp_unit_get(unit);
	fsf_req->unit = unit;

	/* associate FSF request with SCSI request (for look up on abort) */
	scsi_cmnd->host_scribble = (unsigned char *) fsf_req->req_id;

	/* associate SCSI command with FSF request */
	fsf_req->data = (unsigned long) scsi_cmnd;

	/* 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;

	/* FSF does not define the structure of the FCP_CMND IU */
	fcp_cmnd_iu = (struct fcp_cmnd_iu *)
	    &(fsf_req->qtcb->bottom.io.fcp_cmnd);

	/*
	 * set depending on data direction:
	 *      data direction bits in SBALE (SB Type)
	 *      data direction bits in QTCB
	 *      data direction bits in FCP_CMND IU
	 */
	switch (scsi_cmnd->sc_data_direction) {
	case DMA_NONE:
		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
		/*
		 * FIXME(qdio):
		 * what is the correct type for commands
		 * without 'real' data buffers?
		 */
		sbtype = SBAL_FLAGS0_TYPE_READ;
		break;
	case DMA_FROM_DEVICE:
		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
		sbtype = SBAL_FLAGS0_TYPE_READ;
		fcp_cmnd_iu->rddata = 1;
		break;
	case DMA_TO_DEVICE:
		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
		sbtype = SBAL_FLAGS0_TYPE_WRITE;
		fcp_cmnd_iu->wddata = 1;
		break;
	case DMA_BIDIRECTIONAL:
	default:
		/*
		 * dummy, catch this condition earlier
		 * in zfcp_scsi_queuecommand
		 */
		goto failed_scsi_cmnd;
	}

	/* set FC service class in QTCB (3 per default) */
	fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;

	/* set FCP_LUN in FCP_CMND IU in QTCB */
	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;

	mask = ZFCP_STATUS_UNIT_READONLY | ZFCP_STATUS_UNIT_SHARED;

	/* set task attributes in FCP_CMND IU in QTCB */
	if (likely((scsi_cmnd->device->simple_tags) ||
		   (atomic_test_mask(mask, &unit->status))))
		fcp_cmnd_iu->task_attribute = SIMPLE_Q;
	else
		fcp_cmnd_iu->task_attribute = UNTAGGED;

	/* set additional length of FCP_CDB in FCP_CMND IU in QTCB, if needed */
	if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) {
		fcp_cmnd_iu->add_fcp_cdb_length
		    = (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2;
		ZFCP_LOG_TRACE("SCSI CDB length is 0x%x, "
			       "additional FCP_CDB length is 0x%x "
			       "(shifted right 2 bits)\n",
			       scsi_cmnd->cmd_len,
			       fcp_cmnd_iu->add_fcp_cdb_length);
	}
	/*
	 * copy SCSI CDB (including additional length, if any) to
	 * FCP_CDB in FCP_CMND IU in QTCB
	 */
	memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);

	/* FCP CMND IU length in QTCB */
	fsf_req->qtcb->bottom.io.fcp_cmnd_length =
		sizeof (struct fcp_cmnd_iu) +
		fcp_cmnd_iu->add_fcp_cdb_length + sizeof (fcp_dl_t);

	/* generate SBALEs from data buffer */
	real_bytes = zfcp_qdio_sbals_from_scsicmnd(fsf_req, sbtype, scsi_cmnd);
	if (unlikely(real_bytes < 0)) {
		if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) {
			ZFCP_LOG_DEBUG(
				"Data did not fit into available buffer(s), "
			       "waiting for more...\n");
			retval = -EIO;
		} else {
			ZFCP_LOG_NORMAL("error: No truncation implemented but "
					"required. Shutting down unit "
					"(adapter %s, port 0x%016Lx, "
					"unit 0x%016Lx)\n",
					zfcp_get_busid_by_unit(unit),
					unit->port->wwpn,
					unit->fcp_lun);
			zfcp_erp_unit_shutdown(unit, 0, 131, fsf_req);
			retval = -EINVAL;
		}
		goto no_fit;
	}

	/* set length of FCP data length in FCP_CMND IU in QTCB */
	zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);

	ZFCP_LOG_DEBUG("Sending SCSI command:\n");
	ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
		      (char *) scsi_cmnd->cmnd, scsi_cmnd->cmd_len);

	if (use_timer)
		zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);

	retval = zfcp_fsf_req_send(fsf_req);
	if (unlikely(retval < 0)) {
		ZFCP_LOG_INFO("error: Could not send FCP command request "
			      "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
			      zfcp_get_busid_by_adapter(adapter),
			      unit->port->wwpn,
			      unit->fcp_lun);
		goto send_failed;
	}

	ZFCP_LOG_TRACE("Send FCP Command initiated (adapter %s, "
		       "port 0x%016Lx, unit 0x%016Lx)\n",
		       zfcp_get_busid_by_adapter(adapter),
		       unit->port->wwpn,
		       unit->fcp_lun);
	goto success;

 send_failed:
 no_fit:
 failed_scsi_cmnd:
	zfcp_unit_put(unit);
 unit_blocked:
	zfcp_fsf_req_free(fsf_req);
	fsf_req = NULL;
	scsi_cmnd->host_scribble = NULL;
 success:
 failed_req_create:
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
	return retval;
}

struct zfcp_fsf_req *
zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
					  struct zfcp_unit *unit,
					  u8 tm_flags, int req_flags)
{
	struct zfcp_fsf_req *fsf_req = NULL;
	int retval = 0;
	struct fcp_cmnd_iu *fcp_cmnd_iu;
	unsigned long lock_flags;
	volatile struct qdio_buffer_element *sbale;

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
				     adapter->pool.fsf_req_scsi,
				     &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create FCP command (task "
			      "management) request for adapter %s, port "
			      " 0x%016Lx, unit 0x%016Lx.\n",
			      zfcp_get_busid_by_adapter(adapter),
			      unit->port->wwpn, unit->fcp_lun);
		goto out;
	}

	if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
			&unit->status)))
		goto unit_blocked;

	/*
	 * Used to decide on proper handler in the return path,
	 * could be either zfcp_fsf_send_fcp_command_task_handler or
	 * zfcp_fsf_send_fcp_command_task_management_handler */

	fsf_req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;

	/*
	 * hold a pointer to the unit being target of this
	 * task management request
	 */
	fsf_req->data = (unsigned long) unit;

	/* set FSF related fields in QTCB */
	fsf_req->qtcb->header.lun_handle = unit->handle;
	fsf_req->qtcb->header.port_handle = unit->port->handle;
	fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
	fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
	fsf_req->qtcb->bottom.io.fcp_cmnd_length =
		sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t);

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;

	/* set FCP related fields in FCP_CMND IU in QTCB */
	fcp_cmnd_iu = (struct fcp_cmnd_iu *)
		&(fsf_req->qtcb->bottom.io.fcp_cmnd);
	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
	fcp_cmnd_iu->task_management_flags = tm_flags;

	zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);
	retval = zfcp_fsf_req_send(fsf_req);
	if (!retval)
		goto out;

 unit_blocked:
	zfcp_fsf_req_free(fsf_req);
	fsf_req = NULL;

 out:
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
	return fsf_req;
}

/*
 * function:    zfcp_fsf_send_fcp_command_handler
 *
 * purpose:	is called for finished Send FCP Command
 *
 * returns:
 */
static int
zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = -EINVAL;
	struct zfcp_unit *unit;
	struct fsf_qtcb_header *header;
	u16 subtable, rule, counter;

	header = &fsf_req->qtcb->header;

	if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT))
		unit = (struct zfcp_unit *) fsf_req->data;
	else
		unit = fsf_req->unit;

	if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
		/* go directly to calls of special handlers */
		goto skip_fsfstatus;
	}

	/* evaluate FSF status in QTCB */
	switch (header->fsf_status) {

	case FSF_PORT_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
			      "0x%016Lx on adapter %s invalid\n",
			      unit->port->handle,
			      unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_LUN_HANDLE_NOT_VALID:
		ZFCP_LOG_INFO("Temporary LUN identifier 0x%x for unit "
			      "0x%016Lx on port 0x%016Lx on adapter %s is "
			      "invalid. This may happen occasionally.\n",
			      unit->handle,
			      unit->fcp_lun,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit));
		ZFCP_LOG_NORMAL("Status qualifier data:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_port_reopen(unit->port, 0, 113, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_HANDLE_MISMATCH:
		ZFCP_LOG_NORMAL("bug: The port handle 0x%x has changed "
				"unexpectedly. (adapter %s, port 0x%016Lx, "
				"unit 0x%016Lx)\n",
				unit->port->handle,
				zfcp_get_busid_by_unit(unit),
				unit->port->wwpn,
				unit->fcp_lun);
		ZFCP_LOG_NORMAL("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 114, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
		ZFCP_LOG_INFO("error: adapter %s does not support fc "
			      "class %d.\n",
			      zfcp_get_busid_by_unit(unit),
			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
		/* stop operation for this adapter */
		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 132, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_FCPLUN_NOT_VALID:
		ZFCP_LOG_NORMAL("bug: unit 0x%016Lx on port 0x%016Lx on "
				"adapter %s does not have correct unit "
				"handle 0x%x\n",
				unit->fcp_lun,
				unit->port->wwpn,
				zfcp_get_busid_by_unit(unit),
				unit->handle);
		ZFCP_LOG_DEBUG("status qualifier:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (char *) &header->fsf_status_qual,
			      sizeof (union fsf_status_qual));
		zfcp_erp_port_reopen(unit->port, 0, 115, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_ACCESS_DENIED:
		ZFCP_LOG_NORMAL("Access denied, cannot send FCP command to "
				"unit 0x%016Lx on port 0x%016Lx on "
				"adapter %s\n",	unit->fcp_lun, unit->port->wwpn,
				zfcp_get_busid_by_unit(unit));
		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;
			}
		}
		zfcp_erp_unit_access_denied(unit, 61, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_DIRECTION_INDICATOR_NOT_VALID:
		ZFCP_LOG_INFO("bug: Invalid data direction given for unit "
			      "0x%016Lx on port 0x%016Lx on adapter %s "
			      "(debug info %d)\n",
			      unit->fcp_lun,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit),
			      fsf_req->qtcb->bottom.io.data_direction);
		/* stop operation for this adapter */
		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_CMND_LENGTH_NOT_VALID:
		ZFCP_LOG_NORMAL
		    ("bug: An invalid control-data-block length field "
		     "was found in a command for unit 0x%016Lx on port "
		     "0x%016Lx on adapter %s " "(debug info %d)\n",
		     unit->fcp_lun, unit->port->wwpn,
		     zfcp_get_busid_by_unit(unit),
		     fsf_req->qtcb->bottom.io.fcp_cmnd_length);
		/* stop operation for this adapter */
		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_PORT_BOXED:
		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
			       "needs to be reopened\n",
			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
		zfcp_erp_port_boxed(unit->port, 53, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
			ZFCP_STATUS_FSFREQ_RETRY;
		break;

	case FSF_LUN_BOXED:
		ZFCP_LOG_NORMAL("unit needs to be reopened (adapter %s, "
				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
				zfcp_get_busid_by_unit(unit),
				unit->port->wwpn, unit->fcp_lun);
		zfcp_erp_unit_boxed(unit, 54, fsf_req);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
			| ZFCP_STATUS_FSFREQ_RETRY;
		break;

	case FSF_ADAPTER_STATUS_AVAILABLE:
		switch (header->fsf_status_qual.word[0]) {
		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
			/* re-establish link to port */
 			zfcp_test_link(unit->port);
			break;
		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
			/* FIXME(hw) need proper specs for proper action */
			/* let scsi stack deal with retries and escalation */
			break;
		default:
			ZFCP_LOG_NORMAL
 			    ("Unknown status qualifier 0x%x arrived.\n",
			     header->fsf_status_qual.word[0]);
			break;
		}
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		break;

	case FSF_GOOD:
		break;

	case FSF_FCP_RSP_AVAILABLE:
		break;
	}

 skip_fsfstatus:
	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) {
		retval =
		    zfcp_fsf_send_fcp_command_task_management_handler(fsf_req);
	} else {
		retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req);
		fsf_req->unit = NULL;
		zfcp_unit_put(unit);
	}
	return retval;
}

/*
 * function:    zfcp_fsf_send_fcp_command_task_handler
 *
 * purpose:	evaluates FCP_RSP IU
 *
 * returns:
 */
static int
zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;
	struct scsi_cmnd *scpnt;
	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
	    &(fsf_req->qtcb->bottom.io.fcp_rsp);
	struct fcp_cmnd_iu *fcp_cmnd_iu = (struct fcp_cmnd_iu *)
	    &(fsf_req->qtcb->bottom.io.fcp_cmnd);
	u32 sns_len;
	char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
	unsigned long flags;
	struct zfcp_unit *unit = fsf_req->unit;

	read_lock_irqsave(&fsf_req->adapter->abort_lock, flags);
	scpnt = (struct scsi_cmnd *) fsf_req->data;
	if (unlikely(!scpnt)) {
		ZFCP_LOG_DEBUG
		    ("Command with fsf_req %p is not associated to "
		     "a scsi command anymore. Aborted?\n", fsf_req);
		goto out;
	}
	if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTED)) {
		/* FIXME: (design) mid-layer should handle DID_ABORT like
		 *        DID_SOFT_ERROR by retrying the request for devices
		 *        that allow retries.
		 */
		ZFCP_LOG_DEBUG("Setting DID_SOFT_ERROR and SUGGEST_RETRY\n");
		set_host_byte(&scpnt->result, DID_SOFT_ERROR);
		set_driver_byte(&scpnt->result, SUGGEST_RETRY);
		goto skip_fsfstatus;
	}

	if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
		ZFCP_LOG_DEBUG("Setting DID_ERROR\n");
		set_host_byte(&scpnt->result, DID_ERROR);
		goto skip_fsfstatus;
	}

	/* set message byte of result in SCSI command */
	scpnt->result |= COMMAND_COMPLETE << 8;

	/*
	 * copy SCSI status code of FCP_STATUS of FCP_RSP IU to status byte
	 * of result in SCSI command
	 */
	scpnt->result |= fcp_rsp_iu->scsi_status;
	if (unlikely(fcp_rsp_iu->scsi_status)) {
		/* DEBUG */
		ZFCP_LOG_DEBUG("status for SCSI Command:\n");
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      scpnt->cmnd, scpnt->cmd_len);
		ZFCP_LOG_DEBUG("SCSI status code 0x%x\n",
				fcp_rsp_iu->scsi_status);
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      (void *) fcp_rsp_iu, sizeof (struct fcp_rsp_iu));
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
			      zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu),
			      fcp_rsp_iu->fcp_sns_len);
	}

	/* check FCP_RSP_INFO */
	if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
		ZFCP_LOG_DEBUG("rsp_len is valid\n");
		switch (fcp_rsp_info[3]) {
		case RSP_CODE_GOOD:
			/* ok, continue */
			ZFCP_LOG_TRACE("no failure or Task Management "
				       "Function complete\n");
			set_host_byte(&scpnt->result, DID_OK);
			break;
		case RSP_CODE_LENGTH_MISMATCH:
			/* hardware bug */
			ZFCP_LOG_NORMAL("bug: FCP response code indictates "
					"that the fibrechannel protocol data "
					"length differs from the burst length. "
					"The problem occured on unit 0x%016Lx "
					"on port 0x%016Lx on adapter %s",
					unit->fcp_lun,
					unit->port->wwpn,
					zfcp_get_busid_by_unit(unit));
			/* dump SCSI CDB as prepared by zfcp */
			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
				      (char *) &fsf_req->qtcb->
				      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
			set_host_byte(&scpnt->result, DID_ERROR);
			goto skip_fsfstatus;
		case RSP_CODE_FIELD_INVALID:
			/* driver or hardware bug */
			ZFCP_LOG_NORMAL("bug: FCP response code indictates "
					"that the fibrechannel protocol data "
					"fields were incorrectly set up. "
					"The problem occured on the unit "
					"0x%016Lx on port 0x%016Lx on "
					"adapter %s",
					unit->fcp_lun,
					unit->port->wwpn,
					zfcp_get_busid_by_unit(unit));
			/* dump SCSI CDB as prepared by zfcp */
			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
				      (char *) &fsf_req->qtcb->
				      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
			set_host_byte(&scpnt->result, DID_ERROR);
			goto skip_fsfstatus;
		case RSP_CODE_RO_MISMATCH:
			/* hardware bug */
			ZFCP_LOG_NORMAL("bug: The FCP response code indicates "
					"that conflicting  values for the "
					"fibrechannel payload offset from the "
					"header were found. "
					"The problem occured on unit 0x%016Lx "
					"on port 0x%016Lx on adapter %s.\n",
					unit->fcp_lun,
					unit->port->wwpn,
					zfcp_get_busid_by_unit(unit));
			/* dump SCSI CDB as prepared by zfcp */
			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
				      (char *) &fsf_req->qtcb->
				      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
			set_host_byte(&scpnt->result, DID_ERROR);
			goto skip_fsfstatus;
		default:
			ZFCP_LOG_NORMAL("bug: An invalid FCP response "
					"code was detected for a command. "
					"The problem occured on the unit "
					"0x%016Lx on port 0x%016Lx on "
					"adapter %s (debug info 0x%x)\n",
					unit->fcp_lun,
					unit->port->wwpn,
					zfcp_get_busid_by_unit(unit),
					fcp_rsp_info[3]);
			/* dump SCSI CDB as prepared by zfcp */
			ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
				      (char *) &fsf_req->qtcb->
				      bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
			set_host_byte(&scpnt->result, DID_ERROR);
			goto skip_fsfstatus;
		}
	}

	/* check for sense data */
	if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) {
		sns_len = FSF_FCP_RSP_SIZE -
		    sizeof (struct fcp_rsp_iu) + fcp_rsp_iu->fcp_rsp_len;
		ZFCP_LOG_TRACE("room for %i bytes sense data in QTCB\n",
			       sns_len);
		sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE);
		ZFCP_LOG_TRACE("room for %i bytes sense data in SCSI command\n",
			       SCSI_SENSE_BUFFERSIZE);
		sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len);
		ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n",
			       scpnt->result);
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
			      scpnt->cmnd, scpnt->cmd_len);

		ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n",
			       fcp_rsp_iu->fcp_sns_len);
		memcpy(scpnt->sense_buffer,
		       zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len);
		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
			      (void *)scpnt->sense_buffer, sns_len);
	}

	/* check for overrun */
	if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_over)) {
		ZFCP_LOG_INFO("A data overrun was detected for a command. "
			      "unit 0x%016Lx, port 0x%016Lx, adapter %s. "
			      "The response data length is "
			      "%d, the original length was %d.\n",
			      unit->fcp_lun,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit),
			      fcp_rsp_iu->fcp_resid,
			      (int) zfcp_get_fcp_dl(fcp_cmnd_iu));
	}

	/* check for underrun */
	if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) {
		ZFCP_LOG_INFO("A data underrun was detected for a command. "
			      "unit 0x%016Lx, port 0x%016Lx, adapter %s. "
			      "The response data length is "
			      "%d, the original length was %d.\n",
			      unit->fcp_lun,
			      unit->port->wwpn,
			      zfcp_get_busid_by_unit(unit),
			      fcp_rsp_iu->fcp_resid,
			      (int) zfcp_get_fcp_dl(fcp_cmnd_iu));

		scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid);
		if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) <
		    scpnt->underflow)
			set_host_byte(&scpnt->result, DID_ERROR);
	}

 skip_fsfstatus:
	ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);

	if (scpnt->result != 0)
		zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req);
	else if (scpnt->retries > 0)
		zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req);
	else
		zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req);

	/* cleanup pointer (need this especially for abort) */
	scpnt->host_scribble = NULL;

	/* always call back */
	(scpnt->scsi_done) (scpnt);

	/*
	 * We must hold this lock until scsi_done has been called.
	 * Otherwise we may call scsi_done after abort regarding this
	 * command has completed.
	 * Note: scsi_done must not block!
	 */
 out:
	read_unlock_irqrestore(&fsf_req->adapter->abort_lock, flags);
	return retval;
}

/*
 * function:    zfcp_fsf_send_fcp_command_task_management_handler
 *
 * purpose:	evaluates FCP_RSP IU
 *
 * returns:
 */
static int
zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
{
	int retval = 0;
	struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
	    &(fsf_req->qtcb->bottom.io.fcp_rsp);
	char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
	struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
		goto skip_fsfstatus;
	}

	/* check FCP_RSP_INFO */
	switch (fcp_rsp_info[3]) {
	case RSP_CODE_GOOD:
		/* ok, continue */
		ZFCP_LOG_DEBUG("no failure or Task Management "
			       "Function complete\n");
		break;
	case RSP_CODE_TASKMAN_UNSUPP:
		ZFCP_LOG_NORMAL("bug: A reuested task management function "
				"is not supported on the target device "
				"unit 0x%016Lx, port 0x%016Lx, adapter %s\n ",
				unit->fcp_lun,
				unit->port->wwpn,
				zfcp_get_busid_by_unit(unit));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP;
		break;
	case RSP_CODE_TASKMAN_FAILED:
		ZFCP_LOG_NORMAL("bug: A reuested task management function "
				"failed to complete successfully. "
				"unit 0x%016Lx, port 0x%016Lx, adapter %s.\n",
				unit->fcp_lun,
				unit->port->wwpn,
				zfcp_get_busid_by_unit(unit));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
		break;
	default:
		ZFCP_LOG_NORMAL("bug: An invalid FCP response "
				"code was detected for a command. "
				"unit 0x%016Lx, port 0x%016Lx, adapter %s "
				"(debug info 0x%x)\n",
				unit->fcp_lun,
				unit->port->wwpn,
				zfcp_get_busid_by_unit(unit),
				fcp_rsp_info[3]);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
	}

      skip_fsfstatus:
	return retval;
}


/*
 * function:    zfcp_fsf_control_file
 *
 * purpose:     Initiator of the control file upload/download FSF requests
 *
 * returns:     0           - FSF request is successfuly created and queued
 *              -EOPNOTSUPP - The FCP adapter does not have Control File support
 *              -EINVAL     - Invalid direction specified
 *              -ENOMEM     - Insufficient memory
 *              -EPERM      - Cannot create FSF request or place it in QDIO queue
 */
int
zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                      struct zfcp_fsf_req **fsf_req_ptr,
                      u32 fsf_command,
                      u32 option,
                      struct zfcp_sg_list *sg_list)
{
	struct zfcp_fsf_req *fsf_req;
	struct fsf_qtcb_bottom_support *bottom;
	volatile struct qdio_buffer_element *sbale;
	unsigned long lock_flags;
	int req_flags = 0;
	int direction;
	int retval = 0;

	if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) {
		ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n",
			      zfcp_get_busid_by_adapter(adapter));
		retval = -EOPNOTSUPP;
		goto out;
	}

	switch (fsf_command) {

	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
		direction = SBAL_FLAGS0_TYPE_WRITE;
		if ((option != FSF_CFDC_OPTION_FULL_ACCESS) &&
		    (option != FSF_CFDC_OPTION_RESTRICTED_ACCESS))
			req_flags = ZFCP_WAIT_FOR_SBAL;
		break;

	case FSF_QTCB_UPLOAD_CONTROL_FILE:
		direction = SBAL_FLAGS0_TYPE_READ;
		break;

	default:
		ZFCP_LOG_INFO("Invalid FSF command code 0x%08x\n", fsf_command);
		retval = -EINVAL;
		goto out;
	}

	retval = zfcp_fsf_req_create(adapter, fsf_command, req_flags,
				     NULL, &lock_flags, &fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("error: Could not create FSF request for the "
			      "adapter %s\n",
			zfcp_get_busid_by_adapter(adapter));
		retval = -EPERM;
		goto unlock_queue_lock;
	}

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
	sbale[0].flags |= direction;

	bottom = &fsf_req->qtcb->bottom.support;
	bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
	bottom->option = option;

	if (sg_list->count > 0) {
		int bytes;

		bytes = zfcp_qdio_sbals_from_sg(fsf_req, direction,
						sg_list->sg, sg_list->count,
						ZFCP_MAX_SBALS_PER_REQ);
                if (bytes != ZFCP_CFDC_MAX_CONTROL_FILE_SIZE) {
			ZFCP_LOG_INFO(
				"error: Could not create sufficient number of "
				"SBALS for an FSF request to the adapter %s\n",
				zfcp_get_busid_by_adapter(adapter));
			retval = -ENOMEM;
			goto free_fsf_req;
		}
	} else
		sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;

	zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
	retval = zfcp_fsf_req_send(fsf_req);
	if (retval < 0) {
		ZFCP_LOG_INFO("initiation of cfdc up/download failed"
			      "(adapter %s)\n",
			      zfcp_get_busid_by_adapter(adapter));
		retval = -EPERM;
		goto free_fsf_req;
	}
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);

	ZFCP_LOG_NORMAL("Control file %s FSF request has been sent to the "
			"adapter %s\n",
			fsf_command == FSF_QTCB_DOWNLOAD_CONTROL_FILE ?
			"download" : "upload",
			zfcp_get_busid_by_adapter(adapter));

	wait_event(fsf_req->completion_wq,
	           fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

	*fsf_req_ptr = fsf_req;
	goto out;

 free_fsf_req:
	zfcp_fsf_req_free(fsf_req);
 unlock_queue_lock:
	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
 out:
	return retval;
}


/*
 * function:    zfcp_fsf_control_file_handler
 *
 * purpose:     Handler of the control file upload/download FSF requests
 *
 * returns:     0       - FSF request successfuly processed
 *              -EAGAIN - Operation has to be repeated because of a temporary problem
 *              -EACCES - There is no permission to execute an operation
 *              -EPERM  - The control file is not in a right format
 *              -EIO    - There is a problem with the FCP adapter
 *              -EINVAL - Invalid operation
 *              -EFAULT - User space memory I/O operation fault
 */
static int
zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
{
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct fsf_qtcb_header *header = &fsf_req->qtcb->header;
	struct fsf_qtcb_bottom_support *bottom = &fsf_req->qtcb->bottom.support;
	int retval = 0;

	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
		retval = -EINVAL;
		goto skip_fsfstatus;
	}

	switch (header->fsf_status) {

	case FSF_GOOD:
		ZFCP_LOG_NORMAL(
			"The FSF request has been successfully completed "
			"on the adapter %s\n",
			zfcp_get_busid_by_adapter(adapter));
		break;

	case FSF_OPERATION_PARTIALLY_SUCCESSFUL:
		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) {
			switch (header->fsf_status_qual.word[0]) {

			case FSF_SQ_CFDC_HARDENED_ON_SE:
				ZFCP_LOG_NORMAL(
					"CFDC on the adapter %s has being "
					"hardened on primary and secondary SE\n",
					zfcp_get_busid_by_adapter(adapter));
				break;

			case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE:
				ZFCP_LOG_NORMAL(
					"CFDC of the adapter %s could not "
					"be saved on the SE\n",
					zfcp_get_busid_by_adapter(adapter));
				break;

			case FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2:
				ZFCP_LOG_NORMAL(
					"CFDC of the adapter %s could not "
					"be copied to the secondary SE\n",
					zfcp_get_busid_by_adapter(adapter));
				break;

			default:
				ZFCP_LOG_NORMAL(
					"CFDC could not be hardened "
					"on the adapter %s\n",
					zfcp_get_busid_by_adapter(adapter));
			}
		}
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EAGAIN;
		break;

	case FSF_AUTHORIZATION_FAILURE:
		ZFCP_LOG_NORMAL(
			"Adapter %s does not accept privileged commands\n",
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EACCES;
		break;

	case FSF_CFDC_ERROR_DETECTED:
		ZFCP_LOG_NORMAL(
			"Error at position %d in the CFDC, "
			"CFDC is discarded by the adapter %s\n",
			header->fsf_status_qual.word[0],
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EPERM;
		break;

	case FSF_CONTROL_FILE_UPDATE_ERROR:
		ZFCP_LOG_NORMAL(
			"Adapter %s cannot harden the control file, "
			"file is discarded\n",
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EIO;
		break;

	case FSF_CONTROL_FILE_TOO_LARGE:
		ZFCP_LOG_NORMAL(
			"Control file is too large, file is discarded "
			"by the adapter %s\n",
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EIO;
		break;

	case FSF_ACCESS_CONFLICT_DETECTED:
		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
			ZFCP_LOG_NORMAL(
				"CFDC has been discarded by the adapter %s, "
				"because activation would impact "
				"%d active connection(s)\n",
				zfcp_get_busid_by_adapter(adapter),
				header->fsf_status_qual.word[0]);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EIO;
		break;

	case FSF_CONFLICTS_OVERRULED:
		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
			ZFCP_LOG_NORMAL(
				"CFDC has been activated on the adapter %s, "
				"but activation has impacted "
				"%d active connection(s)\n",
				zfcp_get_busid_by_adapter(adapter),
				header->fsf_status_qual.word[0]);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EIO;
		break;

	case FSF_UNKNOWN_OP_SUBTYPE:
		ZFCP_LOG_NORMAL("unknown operation subtype (adapter: %s, "
				"op_subtype=0x%x)\n",
				zfcp_get_busid_by_adapter(adapter),
				bottom->operation_subtype);
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EINVAL;
		break;

	case FSF_INVALID_COMMAND_OPTION:
		ZFCP_LOG_NORMAL(
			"Invalid option 0x%x has been specified "
			"in QTCB bottom sent to the adapter %s\n",
			bottom->option,
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EINVAL;
		break;

	default:
		ZFCP_LOG_NORMAL(
			"bug: An unknown/unexpected FSF status 0x%08x "
			"was presented on the adapter %s\n",
			header->fsf_status,
			zfcp_get_busid_by_adapter(adapter));
		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
		retval = -EINVAL;
		break;
	}

skip_fsfstatus:
	return retval;
}

static inline int
zfcp_fsf_req_sbal_check(unsigned long *flags,
			struct zfcp_qdio_queue *queue, int needed)
{
	write_lock_irqsave(&queue->queue_lock, *flags);
	if (likely(atomic_read(&queue->free_count) >= needed))
		return 1;
	write_unlock_irqrestore(&queue->queue_lock, *flags);
	return 0;
}

/*
 * set qtcb pointer in fsf_req and initialize QTCB
 */
static void
zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
{
	if (likely(fsf_req->qtcb != NULL)) {
		fsf_req->qtcb->prefix.req_seq_no =
			fsf_req->adapter->fsf_req_seq_no;
		fsf_req->qtcb->prefix.req_id = fsf_req->req_id;
		fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION;
		fsf_req->qtcb->prefix.qtcb_type =
			fsf_qtcb_type[fsf_req->fsf_command];
		fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION;
		fsf_req->qtcb->header.req_handle = fsf_req->req_id;
		fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command;
	}
}

/**
 * zfcp_fsf_req_sbal_get - try to get one SBAL in the request queue
 * @adapter: adapter for which request queue is examined
 * @req_flags: flags indicating whether to wait for needed SBAL or not
 * @lock_flags: lock_flags if queue_lock is taken
 * Return: 0 on success, otherwise -EIO, or -ERESTARTSYS
 * Locks: lock adapter->request_queue->queue_lock on success
 */
static int
zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter, int req_flags,
		      unsigned long *lock_flags)
{
        long ret;
        struct zfcp_qdio_queue *req_queue = &adapter->request_queue;

        if (unlikely(req_flags & ZFCP_WAIT_FOR_SBAL)) {
                ret = wait_event_interruptible_timeout(adapter->request_wq,
			zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1),
						       ZFCP_SBAL_TIMEOUT);
		if (ret < 0)
			return ret;
		if (!ret)
			return -EIO;
        } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1))
                return -EIO;

        return 0;
}

/*
 * function:    zfcp_fsf_req_create
 *
 * purpose:	create an FSF request at the specified adapter and
 *		setup common fields
 *
 * returns:	-ENOMEM if there was insufficient memory for a request
 *              -EIO if no qdio buffers could be allocate to the request
 *              -EINVAL/-EPERM on bug conditions in req_dequeue
 *              0 in success
 *
 * note:        The created request is returned by reference.
 *
 * locks:	lock of concerned request queue must not be held,
 *		but is held on completion (write, irqsave)
 */
int
zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
		    mempool_t *pool, unsigned long *lock_flags,
		    struct zfcp_fsf_req **fsf_req_p)
{
	volatile struct qdio_buffer_element *sbale;
	struct zfcp_fsf_req *fsf_req = NULL;
	int ret = 0;
	struct zfcp_qdio_queue *req_queue = &adapter->request_queue;

	/* allocate new FSF request */
	fsf_req = zfcp_fsf_req_alloc(pool, req_flags);
	if (unlikely(NULL == fsf_req)) {
		ZFCP_LOG_DEBUG("error: Could not put an FSF request into "
			       "the outbound (send) queue.\n");
		ret = -ENOMEM;
		goto failed_fsf_req;
	}

	fsf_req->adapter = adapter;
	fsf_req->fsf_command = fsf_cmd;
	INIT_LIST_HEAD(&fsf_req->list);
	init_timer(&fsf_req->timer);

	/* initialize waitqueue which may be used to wait on
	   this request completion */
	init_waitqueue_head(&fsf_req->completion_wq);

        ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags);
        if (ret < 0)
                goto failed_sbals;

	/* this is serialized (we are holding req_queue-lock of adapter) */
	if (adapter->req_no == 0)
		adapter->req_no++;
	fsf_req->req_id = adapter->req_no++;

	zfcp_fsf_req_qtcb_init(fsf_req);

	/*
	 * We hold queue_lock here. Check if QDIOUP is set and let request fail
	 * if it is not set (see also *_open_qdio and *_close_qdio).
	 */

	if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
		write_unlock_irqrestore(&req_queue->queue_lock, *lock_flags);
		ret = -EIO;
		goto failed_sbals;
	}

	if (fsf_req->qtcb) {
		fsf_req->seq_no = adapter->fsf_req_seq_no;
		fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
	}
	fsf_req->sbal_number = 1;
	fsf_req->sbal_first = req_queue->free_index;
	fsf_req->sbal_curr = req_queue->free_index;
        fsf_req->sbale_curr = 1;

	if (likely(req_flags & ZFCP_REQ_AUTO_CLEANUP)) {
		fsf_req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
	}

	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);

	/* setup common SBALE fields */
	sbale[0].addr = (void *) fsf_req->req_id;
	sbale[0].flags |= SBAL_FLAGS0_COMMAND;
	if (likely(fsf_req->qtcb != NULL)) {
		sbale[1].addr = (void *) fsf_req->qtcb;
		sbale[1].length = sizeof(struct fsf_qtcb);
	}

	ZFCP_LOG_TRACE("got %i free BUFFERs starting at index %i\n",
                       fsf_req->sbal_number, fsf_req->sbal_first);

	goto success;

 failed_sbals:
/* dequeue new FSF request previously enqueued */
	zfcp_fsf_req_free(fsf_req);
	fsf_req = NULL;

 failed_fsf_req:
	write_lock_irqsave(&req_queue->queue_lock, *lock_flags);
 success:
	*fsf_req_p = fsf_req;
	return ret;
}

/*
 * function:    zfcp_fsf_req_send
 *
 * purpose:	start transfer of FSF request via QDIO
 *
 * returns:	0 - request transfer succesfully started
 *		!0 - start of request transfer failed
 */
static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
{
	struct zfcp_adapter *adapter;
	struct zfcp_qdio_queue *req_queue;
	volatile struct qdio_buffer_element *sbale;
	int inc_seq_no;
	int new_distance_from_int;
	int retval = 0;

	adapter = fsf_req->adapter;
	req_queue = &adapter->request_queue,


	/* FIXME(debug): remove it later */
	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_first, 0);
	ZFCP_LOG_DEBUG("SBALE0 flags=0x%x\n", sbale[0].flags);
	ZFCP_LOG_TRACE("HEX DUMP OF SBALE1 PAYLOAD:\n");
	ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr,
		      sbale[1].length);

	/* put allocated FSF request into hash table */
	spin_lock(&adapter->req_list_lock);
	zfcp_reqlist_add(adapter, fsf_req);
	spin_unlock(&adapter->req_list_lock);

	inc_seq_no = (fsf_req->qtcb != NULL);

	ZFCP_LOG_TRACE("request queue of adapter %s: "
		       "next free SBAL is %i, %i free SBALs\n",
		       zfcp_get_busid_by_adapter(adapter),
		       req_queue->free_index,
		       atomic_read(&req_queue->free_count));

	ZFCP_LOG_DEBUG("calling do_QDIO adapter %s, flags=0x%x, queue_no=%i, "
		       "index_in_queue=%i, count=%i, buffers=%p\n",
		       zfcp_get_busid_by_adapter(adapter),
		       QDIO_FLAG_SYNC_OUTPUT,
		       0, fsf_req->sbal_first, fsf_req->sbal_number,
		       &req_queue->buffer[fsf_req->sbal_first]);

	/*
	 * adjust the number of free SBALs in request queue as well as
	 * position of first one
	 */
	atomic_sub(fsf_req->sbal_number, &req_queue->free_count);
	ZFCP_LOG_TRACE("free_count=%d\n", atomic_read(&req_queue->free_count));
	req_queue->free_index += fsf_req->sbal_number;	  /* increase */
	req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q;  /* wrap if needed */
	new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req);

	fsf_req->issued = get_clock();

	retval = do_QDIO(adapter->ccw_device,
			 QDIO_FLAG_SYNC_OUTPUT,
			 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);

	if (unlikely(retval)) {
		/* Queues are down..... */
		retval = -EIO;
		del_timer(&fsf_req->timer);
		spin_lock(&adapter->req_list_lock);
		zfcp_reqlist_remove(adapter, fsf_req);
		spin_unlock(&adapter->req_list_lock);
		/* undo changes in request queue made for this request */
		zfcp_qdio_zero_sbals(req_queue->buffer,
				     fsf_req->sbal_first, fsf_req->sbal_number);
		atomic_add(fsf_req->sbal_number, &req_queue->free_count);
		req_queue->free_index -= fsf_req->sbal_number;
		req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q;
		req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
		zfcp_erp_adapter_reopen(adapter, 0, 116, fsf_req);
	} else {
		req_queue->distance_from_int = new_distance_from_int;
		/*
		 * increase FSF sequence counter -
		 * this must only be done for request successfully enqueued to
		 * QDIO this rejected requests may be cleaned up by calling
		 * routines  resulting in missing sequence counter values
		 * otherwise,
		 */

		/* Don't increase for unsolicited status */
		if (inc_seq_no)
			adapter->fsf_req_seq_no++;

		/* count FSF requests pending */
		atomic_inc(&adapter->reqs_active);
	}
	return retval;
}

#undef ZFCP_LOG_AREA
