diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
new file mode 100644
index 0000000..eb702b9
--- /dev/null
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -0,0 +1,3910 @@
+/*
+ * ibmvfc.c -- driver for IBM Power Virtual Fibre Channel Adapter
+ *
+ * Written By: Brian King <brking@linux.vnet.ibm.com>, IBM Corporation
+ *
+ * Copyright (C) IBM Corporation, 2008
+ *
+ * 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 of the License, 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/of.h>
+#include <linux/stringify.h>
+#include <asm/firmware.h>
+#include <asm/irq.h>
+#include <asm/vio.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport_fc.h>
+#include "ibmvfc.h"
+
+static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT;
+static unsigned int default_timeout = IBMVFC_DEFAULT_TIMEOUT;
+static unsigned int max_lun = IBMVFC_MAX_LUN;
+static unsigned int max_targets = IBMVFC_MAX_TARGETS;
+static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT;
+static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS;
+static unsigned int dev_loss_tmo = IBMVFC_DEV_LOSS_TMO;
+static unsigned int ibmvfc_debug = IBMVFC_DEBUG;
+static unsigned int log_level = IBMVFC_DEFAULT_LOG_LEVEL;
+static LIST_HEAD(ibmvfc_head);
+static DEFINE_SPINLOCK(ibmvfc_driver_lock);
+static struct scsi_transport_template *ibmvfc_transport_template;
+
+MODULE_DESCRIPTION("IBM Virtual Fibre Channel Driver");
+MODULE_AUTHOR("Brian King <brking@linux.vnet.ibm.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(IBMVFC_DRIVER_VERSION);
+
+module_param_named(init_timeout, init_timeout, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(init_timeout, "Initialization timeout in seconds. "
+		 "[Default=" __stringify(IBMVFC_INIT_TIMEOUT) "]");
+module_param_named(default_timeout, default_timeout, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(default_timeout,
+		 "Default timeout in seconds for initialization and EH commands. "
+		 "[Default=" __stringify(IBMVFC_DEFAULT_TIMEOUT) "]");
+module_param_named(max_requests, max_requests, uint, S_IRUGO);
+MODULE_PARM_DESC(max_requests, "Maximum requests for this adapter. "
+		 "[Default=" __stringify(IBMVFC_MAX_REQUESTS_DEFAULT) "]");
+module_param_named(max_lun, max_lun, uint, S_IRUGO);
+MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. "
+		 "[Default=" __stringify(IBMVFC_MAX_LUN) "]");
+module_param_named(max_targets, max_targets, uint, S_IRUGO);
+MODULE_PARM_DESC(max_targets, "Maximum allowed targets. "
+		 "[Default=" __stringify(IBMVFC_MAX_TARGETS) "]");
+module_param_named(disc_threads, disc_threads, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. "
+		 "[Default=" __stringify(IBMVFC_MAX_DISC_THREADS) "]");
+module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable driver debug information. "
+		 "[Default=" __stringify(IBMVFC_DEBUG) "]");
+module_param_named(dev_loss_tmo, dev_loss_tmo, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC "
+		 "transport should insulate the loss of a remote port. Once this "
+		 "value is exceeded, the scsi target is removed. "
+		 "[Default=" __stringify(IBMVFC_DEV_LOSS_TMO) "]");
+module_param_named(log_level, log_level, uint, 0);
+MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver. "
+		 "[Default=" __stringify(IBMVFC_DEFAULT_LOG_LEVEL) "]");
+
+static const struct {
+	u16 status;
+	u16 error;
+	u8 result;
+	u8 retry;
+	int log;
+	char *name;
+} cmd_status [] = {
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_UNABLE_TO_ESTABLISH, DID_ERROR, 1, 1, "unable to establish" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_FAULT, DID_OK, 1, 0, "transport fault" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_CMD_TIMEOUT, DID_TIME_OUT, 1, 1, "command timeout" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_ENETDOWN, DID_NO_CONNECT, 1, 1, "network down" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_HW_FAILURE, DID_ERROR, 1, 1, "hardware failure" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_DOWN_ERR, DID_REQUEUE, 0, 0, "link down" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_DEAD_ERR, DID_ERROR, 0, 0, "link dead" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_UNABLE_TO_REGISTER, DID_ERROR, 1, 1, "unable to register" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_BUSY, DID_BUS_BUSY, 1, 0, "transport busy" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_DEAD, DID_ERROR, 0, 1, "transport dead" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_CONFIG_ERROR, DID_ERROR, 1, 1, "configuration error" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_NAME_SERVER_FAIL, DID_ERROR, 1, 1, "name server failure" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_LINK_HALTED, DID_REQUEUE, 0, 0, "link halted" },
+	{ IBMVFC_FABRIC_MAPPED, IBMVFC_XPORT_GENERAL, DID_OK, 1, 0, "general transport error" },
+
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_CRQ_FAILURE, DID_REQUEUE, 1, 1, "CRQ failure" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_SW_FAILURE, DID_ERROR, 0, 1, "software failure" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_INVALID_PARAMETER, DID_ABORT, 0, 1, "invalid parameter" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_MISSING_PARAMETER, DID_ABORT, 0, 1, "missing parameter" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_HOST_IO_BUS, DID_ERROR, 1, 1, "host I/O bus failure" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_TRANS_CANCELLED, DID_ABORT, 0, 1, "transaction cancelled" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_TRANS_CANCELLED_IMPLICIT, DID_ABORT, 0, 1, "transaction cancelled implicit" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_INSUFFICIENT_RESOURCE, DID_REQUEUE, 1, 1, "insufficient resources" },
+	{ IBMVFC_VIOS_FAILURE, IBMVFC_COMMAND_FAILED, DID_ERROR, 1, 1, "command failed" },
+
+	{ IBMVFC_FC_FAILURE, IBMVFC_INVALID_ELS_CMD_CODE, DID_ERROR, 0, 1, "invalid ELS command code" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_INVALID_VERSION, DID_ERROR, 0, 1, "invalid version level" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_LOGICAL_ERROR, DID_ERROR, 1, 1, "logical error" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_INVALID_CT_IU_SIZE, DID_ERROR, 0, 1, "invalid CT_IU size" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_LOGICAL_BUSY, DID_REQUEUE, 1, 0, "logical busy" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_PROTOCOL_ERROR, DID_ERROR, 1, 1, "protocol error" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_UNABLE_TO_PERFORM_REQ, DID_ERROR, 1, 1, "unable to perform request" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_CMD_NOT_SUPPORTED, DID_ERROR, 0, 0, "command not supported" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_SERVER_NOT_AVAIL, DID_ERROR, 0, 1, "server not available" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_CMD_IN_PROGRESS, DID_ERROR, 0, 1, "command already in progress" },
+	{ IBMVFC_FC_FAILURE, IBMVFC_VENDOR_SPECIFIC, DID_ERROR, 1, 1, "vendor specific" },
+
+	{ IBMVFC_FC_SCSI_ERROR, 0, DID_OK, 1, 0, "SCSI error" },
+};
+
+static void ibmvfc_npiv_login(struct ibmvfc_host *);
+static void ibmvfc_tgt_send_prli(struct ibmvfc_target *);
+static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *);
+static void ibmvfc_tgt_query_target(struct ibmvfc_target *);
+
+static const char *unknown_error = "unknown error";
+
+#ifdef CONFIG_SCSI_IBMVFC_TRACE
+/**
+ * ibmvfc_trc_start - Log a start trace entry
+ * @evt:		ibmvfc event struct
+ *
+ **/
+static void ibmvfc_trc_start(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd;
+	struct ibmvfc_mad_common *mad = &evt->iu.mad_common;
+	struct ibmvfc_trace_entry *entry;
+
+	entry = &vhost->trace[vhost->trace_index++];
+	entry->evt = evt;
+	entry->time = jiffies;
+	entry->fmt = evt->crq.format;
+	entry->type = IBMVFC_TRC_START;
+
+	switch (entry->fmt) {
+	case IBMVFC_CMD_FORMAT:
+		entry->op_code = vfc_cmd->iu.cdb[0];
+		entry->scsi_id = vfc_cmd->tgt_scsi_id;
+		entry->lun = scsilun_to_int(&vfc_cmd->iu.lun);
+		entry->tmf_flags = vfc_cmd->iu.tmf_flags;
+		entry->u.start.xfer_len = vfc_cmd->iu.xfer_len;
+		break;
+	case IBMVFC_MAD_FORMAT:
+		entry->op_code = mad->opcode;
+		break;
+	default:
+		break;
+	};
+}
+
+/**
+ * ibmvfc_trc_end - Log an end trace entry
+ * @evt:		ibmvfc event struct
+ *
+ **/
+static void ibmvfc_trc_end(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
+	struct ibmvfc_mad_common *mad = &evt->xfer_iu->mad_common;
+	struct ibmvfc_trace_entry *entry = &vhost->trace[vhost->trace_index++];
+
+	entry->evt = evt;
+	entry->time = jiffies;
+	entry->fmt = evt->crq.format;
+	entry->type = IBMVFC_TRC_END;
+
+	switch (entry->fmt) {
+	case IBMVFC_CMD_FORMAT:
+		entry->op_code = vfc_cmd->iu.cdb[0];
+		entry->scsi_id = vfc_cmd->tgt_scsi_id;
+		entry->lun = scsilun_to_int(&vfc_cmd->iu.lun);
+		entry->tmf_flags = vfc_cmd->iu.tmf_flags;
+		entry->u.end.status = vfc_cmd->status;
+		entry->u.end.error = vfc_cmd->error;
+		entry->u.end.fcp_rsp_flags = vfc_cmd->rsp.flags;
+		entry->u.end.rsp_code = vfc_cmd->rsp.data.info.rsp_code;
+		entry->u.end.scsi_status = vfc_cmd->rsp.scsi_status;
+		break;
+	case IBMVFC_MAD_FORMAT:
+		entry->op_code = mad->opcode;
+		entry->u.end.status = mad->status;
+		break;
+	default:
+		break;
+
+	};
+}
+
+#else
+#define ibmvfc_trc_start(evt) do { } while (0)
+#define ibmvfc_trc_end(evt) do { } while (0)
+#endif
+
+/**
+ * ibmvfc_get_err_index - Find the index into cmd_status for the fcp response
+ * @status:		status / error class
+ * @error:		error
+ *
+ * Return value:
+ *	index into cmd_status / -EINVAL on failure
+ **/
+static int ibmvfc_get_err_index(u16 status, u16 error)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cmd_status); i++)
+		if ((cmd_status[i].status & status) == cmd_status[i].status &&
+		    cmd_status[i].error == error)
+			return i;
+
+	return -EINVAL;
+}
+
+/**
+ * ibmvfc_get_cmd_error - Find the error description for the fcp response
+ * @status:		status / error class
+ * @error:		error
+ *
+ * Return value:
+ *	error description string
+ **/
+static const char *ibmvfc_get_cmd_error(u16 status, u16 error)
+{
+	int rc = ibmvfc_get_err_index(status, error);
+	if (rc >= 0)
+		return cmd_status[rc].name;
+	return unknown_error;
+}
+
+/**
+ * ibmvfc_get_err_result - Find the scsi status to return for the fcp response
+ * @vfc_cmd:	ibmvfc command struct
+ *
+ * Return value:
+ *	SCSI result value to return for completed command
+ **/
+static int ibmvfc_get_err_result(struct ibmvfc_cmd *vfc_cmd)
+{
+	int err;
+	struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
+	int fc_rsp_len = rsp->fcp_rsp_len;
+
+	if ((rsp->flags & FCP_RSP_LEN_VALID) &&
+	    ((!fc_rsp_len && fc_rsp_len != 4 && fc_rsp_len != 8) ||
+	     rsp->data.info.rsp_code))
+		return DID_ERROR << 16;
+
+	if (!vfc_cmd->status) {
+		if (rsp->flags & FCP_RESID_OVER)
+			return rsp->scsi_status | (DID_ERROR << 16);
+		else
+			return rsp->scsi_status | (DID_OK << 16);
+	}
+
+	err = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error);
+	if (err >= 0)
+		return rsp->scsi_status | (cmd_status[err].result << 16);
+	return rsp->scsi_status | (DID_ERROR << 16);
+}
+
+/**
+ * ibmvfc_retry_cmd - Determine if error status is retryable
+ * @status:		status / error class
+ * @error:		error
+ *
+ * Return value:
+ *	1 if error should be retried / 0 if it should not
+ **/
+static int ibmvfc_retry_cmd(u16 status, u16 error)
+{
+	int rc = ibmvfc_get_err_index(status, error);
+
+	if (rc >= 0)
+		return cmd_status[rc].retry;
+	return 1;
+}
+
+static const char *unknown_fc_explain = "unknown fc explain";
+
+static const struct {
+	u16 fc_explain;
+	char *name;
+} ls_explain [] = {
+	{ 0x00, "no additional explanation" },
+	{ 0x01, "service parameter error - options" },
+	{ 0x03, "service parameter error - initiator control" },
+	{ 0x05, "service parameter error - recipient control" },
+	{ 0x07, "service parameter error - received data field size" },
+	{ 0x09, "service parameter error - concurrent seq" },
+	{ 0x0B, "service parameter error - credit" },
+	{ 0x0D, "invalid N_Port/F_Port_Name" },
+	{ 0x0E, "invalid node/Fabric Name" },
+	{ 0x0F, "invalid common service parameters" },
+	{ 0x11, "invalid association header" },
+	{ 0x13, "association header required" },
+	{ 0x15, "invalid originator S_ID" },
+	{ 0x17, "invalid OX_ID-RX-ID combination" },
+	{ 0x19, "command (request) already in progress" },
+	{ 0x1E, "N_Port Login requested" },
+	{ 0x1F, "Invalid N_Port_ID" },
+};
+
+static const struct {
+	u16 fc_explain;
+	char *name;
+} gs_explain [] = {
+	{ 0x00, "no additional explanation" },
+	{ 0x01, "port identifier not registered" },
+	{ 0x02, "port name not registered" },
+	{ 0x03, "node name not registered" },
+	{ 0x04, "class of service not registered" },
+	{ 0x06, "initial process associator not registered" },
+	{ 0x07, "FC-4 TYPEs not registered" },
+	{ 0x08, "symbolic port name not registered" },
+	{ 0x09, "symbolic node name not registered" },
+	{ 0x0A, "port type not registered" },
+	{ 0xF0, "authorization exception" },
+	{ 0xF1, "authentication exception" },
+	{ 0xF2, "data base full" },
+	{ 0xF3, "data base empty" },
+	{ 0xF4, "processing request" },
+	{ 0xF5, "unable to verify connection" },
+	{ 0xF6, "devices not in a common zone" },
+};
+
+/**
+ * ibmvfc_get_ls_explain - Return the FC Explain description text
+ * @status:	FC Explain status
+ *
+ * Returns:
+ *	error string
+ **/
+static const char *ibmvfc_get_ls_explain(u16 status)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ls_explain); i++)
+		if (ls_explain[i].fc_explain == status)
+			return ls_explain[i].name;
+
+	return unknown_fc_explain;
+}
+
+/**
+ * ibmvfc_get_gs_explain - Return the FC Explain description text
+ * @status:	FC Explain status
+ *
+ * Returns:
+ *	error string
+ **/
+static const char *ibmvfc_get_gs_explain(u16 status)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gs_explain); i++)
+		if (gs_explain[i].fc_explain == status)
+			return gs_explain[i].name;
+
+	return unknown_fc_explain;
+}
+
+static const struct {
+	enum ibmvfc_fc_type fc_type;
+	char *name;
+} fc_type [] = {
+	{ IBMVFC_FABRIC_REJECT, "fabric reject" },
+	{ IBMVFC_PORT_REJECT, "port reject" },
+	{ IBMVFC_LS_REJECT, "ELS reject" },
+	{ IBMVFC_FABRIC_BUSY, "fabric busy" },
+	{ IBMVFC_PORT_BUSY, "port busy" },
+	{ IBMVFC_BASIC_REJECT, "basic reject" },
+};
+
+static const char *unknown_fc_type = "unknown fc type";
+
+/**
+ * ibmvfc_get_fc_type - Return the FC Type description text
+ * @status:	FC Type error status
+ *
+ * Returns:
+ *	error string
+ **/
+static const char *ibmvfc_get_fc_type(u16 status)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fc_type); i++)
+		if (fc_type[i].fc_type == status)
+			return fc_type[i].name;
+
+	return unknown_fc_type;
+}
+
+/**
+ * ibmvfc_set_tgt_action - Set the next init action for the target
+ * @tgt:		ibmvfc target struct
+ * @action:		action to perform
+ *
+ **/
+static void ibmvfc_set_tgt_action(struct ibmvfc_target *tgt,
+				  enum ibmvfc_target_action action)
+{
+	switch (tgt->action) {
+	case IBMVFC_TGT_ACTION_DEL_RPORT:
+		break;
+	default:
+		tgt->action = action;
+		break;
+	}
+}
+
+/**
+ * ibmvfc_set_host_state - Set the state for the host
+ * @vhost:		ibmvfc host struct
+ * @state:		state to set host to
+ *
+ * Returns:
+ *	0 if state changed / non-zero if not changed
+ **/
+static int ibmvfc_set_host_state(struct ibmvfc_host *vhost,
+				  enum ibmvfc_host_state state)
+{
+	int rc = 0;
+
+	switch (vhost->state) {
+	case IBMVFC_HOST_OFFLINE:
+		rc = -EINVAL;
+		break;
+	default:
+		vhost->state = state;
+		break;
+	};
+
+	return rc;
+}
+
+/**
+ * ibmvfc_set_host_action - Set the next init action for the host
+ * @vhost:		ibmvfc host struct
+ * @action:		action to perform
+ *
+ **/
+static void ibmvfc_set_host_action(struct ibmvfc_host *vhost,
+				   enum ibmvfc_host_action action)
+{
+	switch (action) {
+	case IBMVFC_HOST_ACTION_ALLOC_TGTS:
+		if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT)
+			vhost->action = action;
+		break;
+	case IBMVFC_HOST_ACTION_INIT_WAIT:
+		if (vhost->action == IBMVFC_HOST_ACTION_INIT)
+			vhost->action = action;
+		break;
+	case IBMVFC_HOST_ACTION_QUERY:
+		switch (vhost->action) {
+		case IBMVFC_HOST_ACTION_INIT_WAIT:
+		case IBMVFC_HOST_ACTION_NONE:
+		case IBMVFC_HOST_ACTION_TGT_ADD:
+			vhost->action = action;
+			break;
+		default:
+			break;
+		};
+		break;
+	case IBMVFC_HOST_ACTION_TGT_INIT:
+		if (vhost->action == IBMVFC_HOST_ACTION_ALLOC_TGTS)
+			vhost->action = action;
+		break;
+	case IBMVFC_HOST_ACTION_INIT:
+	case IBMVFC_HOST_ACTION_TGT_DEL:
+	case IBMVFC_HOST_ACTION_QUERY_TGTS:
+	case IBMVFC_HOST_ACTION_TGT_ADD:
+	case IBMVFC_HOST_ACTION_NONE:
+	default:
+		vhost->action = action;
+		break;
+	};
+}
+
+/**
+ * ibmvfc_reinit_host - Re-start host initialization (no NPIV Login)
+ * @vhost:		ibmvfc host struct
+ *
+ * Return value:
+ *	nothing
+ **/
+static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
+{
+	if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
+		scsi_block_requests(vhost->host);
+		ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING);
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
+	} else
+		vhost->reinit = 1;
+
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_link_down - Handle a link down event from the adapter
+ * @vhost:	ibmvfc host struct
+ * @state:	ibmvfc host state to enter
+ *
+ **/
+static void ibmvfc_link_down(struct ibmvfc_host *vhost,
+			     enum ibmvfc_host_state state)
+{
+	struct ibmvfc_target *tgt;
+
+	ENTER;
+	scsi_block_requests(vhost->host);
+	list_for_each_entry(tgt, &vhost->targets, queue)
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+	ibmvfc_set_host_state(vhost, state);
+	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL);
+	vhost->events_to_log |= IBMVFC_AE_LINKDOWN;
+	wake_up(&vhost->work_wait_q);
+	LEAVE;
+}
+
+/**
+ * ibmvfc_init_host - Start host initialization
+ * @vhost:		ibmvfc host struct
+ *
+ * Return value:
+ *	nothing
+ **/
+static void ibmvfc_init_host(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_target *tgt;
+
+	if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) {
+		if (++vhost->init_retries > IBMVFC_MAX_INIT_RETRIES) {
+			dev_err(vhost->dev,
+				"Host initialization retries exceeded. Taking adapter offline\n");
+			ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
+			return;
+		}
+	}
+
+	if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
+		list_for_each_entry(tgt, &vhost->targets, queue)
+			tgt->need_login = 1;
+		scsi_block_requests(vhost->host);
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+		vhost->job_step = ibmvfc_npiv_login;
+		wake_up(&vhost->work_wait_q);
+	}
+}
+
+/**
+ * ibmvfc_send_crq - Send a CRQ
+ * @vhost:	ibmvfc host struct
+ * @word1:	the first 64 bits of the data
+ * @word2:	the second 64 bits of the data
+ *
+ * Return value:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_send_crq(struct ibmvfc_host *vhost, u64 word1, u64 word2)
+{
+	struct vio_dev *vdev = to_vio_dev(vhost->dev);
+	return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2);
+}
+
+/**
+ * ibmvfc_send_crq_init - Send a CRQ init message
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_send_crq_init(struct ibmvfc_host *vhost)
+{
+	ibmvfc_dbg(vhost, "Sending CRQ init\n");
+	return ibmvfc_send_crq(vhost, 0xC001000000000000LL, 0);
+}
+
+/**
+ * ibmvfc_send_crq_init_complete - Send a CRQ init complete message
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_send_crq_init_complete(struct ibmvfc_host *vhost)
+{
+	ibmvfc_dbg(vhost, "Sending CRQ init complete\n");
+	return ibmvfc_send_crq(vhost, 0xC002000000000000LL, 0);
+}
+
+/**
+ * ibmvfc_release_crq_queue - Deallocates data and unregisters CRQ
+ * @vhost:	ibmvfc host struct
+ *
+ * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
+ * the crq with the hypervisor.
+ **/
+static void ibmvfc_release_crq_queue(struct ibmvfc_host *vhost)
+{
+	long rc;
+	struct vio_dev *vdev = to_vio_dev(vhost->dev);
+	struct ibmvfc_crq_queue *crq = &vhost->crq;
+
+	ibmvfc_dbg(vhost, "Releasing CRQ\n");
+	free_irq(vdev->irq, vhost);
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	vhost->state = IBMVFC_NO_CRQ;
+	dma_unmap_single(vhost->dev, crq->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL);
+	free_page((unsigned long)crq->msgs);
+}
+
+/**
+ * ibmvfc_reenable_crq_queue - reenables the CRQ
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
+{
+	int rc;
+	struct vio_dev *vdev = to_vio_dev(vhost->dev);
+
+	/* Re-enable the CRQ */
+	do {
+		rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
+	} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	if (rc)
+		dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc);
+
+	return rc;
+}
+
+/**
+ * ibmvfc_reset_crq - resets a crq after a failure
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
+{
+	int rc;
+	struct vio_dev *vdev = to_vio_dev(vhost->dev);
+	struct ibmvfc_crq_queue *crq = &vhost->crq;
+
+	/* Close the CRQ */
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+	vhost->state = IBMVFC_NO_CRQ;
+	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
+
+	/* Clean out the queue */
+	memset(crq->msgs, 0, PAGE_SIZE);
+	crq->cur = 0;
+
+	/* And re-open it again */
+	rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
+				crq->msg_token, PAGE_SIZE);
+
+	if (rc == H_CLOSED)
+		/* Adapter is good, but other end is not ready */
+		dev_warn(vhost->dev, "Partner adapter not ready\n");
+	else if (rc != 0)
+		dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc);
+
+	return rc;
+}
+
+/**
+ * ibmvfc_valid_event - Determines if event is valid.
+ * @pool:	event_pool that contains the event
+ * @evt:	ibmvfc event to be checked for validity
+ *
+ * Return value:
+ *	1 if event is valid / 0 if event is not valid
+ **/
+static int ibmvfc_valid_event(struct ibmvfc_event_pool *pool,
+			      struct ibmvfc_event *evt)
+{
+	int index = evt - pool->events;
+	if (index < 0 || index >= pool->size)	/* outside of bounds */
+		return 0;
+	if (evt != pool->events + index)	/* unaligned */
+		return 0;
+	return 1;
+}
+
+/**
+ * ibmvfc_free_event - Free the specified event
+ * @evt:	ibmvfc_event to be freed
+ *
+ **/
+static void ibmvfc_free_event(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_event_pool *pool = &vhost->pool;
+
+	BUG_ON(!ibmvfc_valid_event(pool, evt));
+	BUG_ON(atomic_inc_return(&evt->free) != 1);
+	list_add_tail(&evt->queue, &vhost->free);
+}
+
+/**
+ * ibmvfc_scsi_eh_done - EH done function for queuecommand commands
+ * @evt:	ibmvfc event struct
+ *
+ * This function does not setup any error status, that must be done
+ * before this function gets called.
+ **/
+static void ibmvfc_scsi_eh_done(struct ibmvfc_event *evt)
+{
+	struct scsi_cmnd *cmnd = evt->cmnd;
+
+	if (cmnd) {
+		scsi_dma_unmap(cmnd);
+		cmnd->scsi_done(cmnd);
+	}
+
+	ibmvfc_free_event(evt);
+}
+
+/**
+ * ibmvfc_fail_request - Fail request with specified error code
+ * @evt:		ibmvfc event struct
+ * @error_code:	error code to fail request with
+ *
+ * Return value:
+ *	none
+ **/
+static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
+{
+	if (evt->cmnd) {
+		evt->cmnd->result = (error_code << 16);
+		evt->done = ibmvfc_scsi_eh_done;
+	} else
+		evt->xfer_iu->mad_common.status = IBMVFC_MAD_DRIVER_FAILED;
+
+	list_del(&evt->queue);
+	del_timer(&evt->timer);
+	ibmvfc_trc_end(evt);
+	evt->done(evt);
+}
+
+/**
+ * ibmvfc_purge_requests - Our virtual adapter just shut down. Purge any sent requests
+ * @vhost:		ibmvfc host struct
+ * @error_code:	error code to fail requests with
+ *
+ * Return value:
+ *	none
+ **/
+static void ibmvfc_purge_requests(struct ibmvfc_host *vhost, int error_code)
+{
+	struct ibmvfc_event *evt, *pos;
+
+	ibmvfc_dbg(vhost, "Purging all requests\n");
+	list_for_each_entry_safe(evt, pos, &vhost->sent, queue)
+		ibmvfc_fail_request(evt, error_code);
+}
+
+/**
+ * __ibmvfc_reset_host - Reset the connection to the server (no locking)
+ * @vhost:	struct ibmvfc host to reset
+ **/
+static void __ibmvfc_reset_host(struct ibmvfc_host *vhost)
+{
+	int rc;
+
+	scsi_block_requests(vhost->host);
+	ibmvfc_purge_requests(vhost, DID_ERROR);
+	if ((rc = ibmvfc_reset_crq(vhost)) ||
+	    (rc = ibmvfc_send_crq_init(vhost)) ||
+	    (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
+		dev_err(vhost->dev, "Error after reset rc=%d\n", rc);
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+	} else
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
+}
+
+/**
+ * ibmvfc_reset_host - Reset the connection to the server
+ * @vhost:	struct ibmvfc host to reset
+ **/
+static void ibmvfc_reset_host(struct ibmvfc_host *vhost)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	__ibmvfc_reset_host(vhost);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
+/**
+ * ibmvfc_retry_host_init - Retry host initialization if allowed
+ * @vhost:	ibmvfc host struct
+ *
+ **/
+static void ibmvfc_retry_host_init(struct ibmvfc_host *vhost)
+{
+	if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) {
+		if (++vhost->init_retries > IBMVFC_MAX_INIT_RETRIES) {
+			dev_err(vhost->dev,
+				"Host initialization retries exceeded. Taking adapter offline\n");
+			ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
+		} else if (vhost->init_retries == IBMVFC_MAX_INIT_RETRIES)
+			__ibmvfc_reset_host(vhost);
+		else
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+	}
+
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * __ibmvfc_find_target - Find the specified scsi_target (no locking)
+ * @starget:	scsi target struct
+ *
+ * Return value:
+ *	ibmvfc_target struct / NULL if not found
+ **/
+static struct ibmvfc_target *__ibmvfc_find_target(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	struct ibmvfc_target *tgt;
+
+	list_for_each_entry(tgt, &vhost->targets, queue)
+		if (tgt->target_id == starget->id)
+			return tgt;
+	return NULL;
+}
+
+/**
+ * ibmvfc_find_target - Find the specified scsi_target
+ * @starget:	scsi target struct
+ *
+ * Return value:
+ *	ibmvfc_target struct / NULL if not found
+ **/
+static struct ibmvfc_target *ibmvfc_find_target(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ibmvfc_target *tgt;
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	tgt = __ibmvfc_find_target(starget);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return tgt;
+}
+
+/**
+ * ibmvfc_get_host_speed - Get host port speed
+ * @shost:		scsi host struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_get_host_speed(struct Scsi_Host *shost)
+{
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	if (vhost->state == IBMVFC_ACTIVE) {
+		switch (vhost->login_buf->resp.link_speed / 100) {
+		case 1:
+			fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
+			break;
+		case 2:
+			fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
+			break;
+		case 4:
+			fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
+			break;
+		case 8:
+			fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
+			break;
+		case 10:
+			fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
+			break;
+		case 16:
+			fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
+			break;
+		default:
+			ibmvfc_log(vhost, 3, "Unknown port speed: %ld Gbit\n",
+				   vhost->login_buf->resp.link_speed / 100);
+			fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+			break;
+		}
+	} else
+		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
+/**
+ * ibmvfc_get_host_port_state - Get host port state
+ * @shost:		scsi host struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_get_host_port_state(struct Scsi_Host *shost)
+{
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	switch (vhost->state) {
+	case IBMVFC_INITIALIZING:
+	case IBMVFC_ACTIVE:
+		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+		break;
+	case IBMVFC_LINK_DOWN:
+		fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
+		break;
+	case IBMVFC_LINK_DEAD:
+	case IBMVFC_HOST_OFFLINE:
+		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+		break;
+	case IBMVFC_HALTED:
+		fc_host_port_state(shost) = FC_PORTSTATE_BLOCKED;
+		break;
+	default:
+		ibmvfc_log(vhost, 3, "Unknown port state: %d\n", vhost->state);
+		fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
+		break;
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
+/**
+ * ibmvfc_set_rport_dev_loss_tmo - Set rport's device loss timeout
+ * @rport:		rport struct
+ * @timeout:	timeout value
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
+{
+	if (timeout)
+		rport->dev_loss_tmo = timeout;
+	else
+		rport->dev_loss_tmo = 1;
+}
+
+/**
+ * ibmvfc_get_starget_node_name - Get SCSI target's node name
+ * @starget:	scsi target struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_get_starget_node_name(struct scsi_target *starget)
+{
+	struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
+	fc_starget_port_name(starget) = tgt ? tgt->ids.node_name : 0;
+}
+
+/**
+ * ibmvfc_get_starget_port_name - Get SCSI target's port name
+ * @starget:	scsi target struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_get_starget_port_name(struct scsi_target *starget)
+{
+	struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
+	fc_starget_port_name(starget) = tgt ? tgt->ids.port_name : 0;
+}
+
+/**
+ * ibmvfc_get_starget_port_id - Get SCSI target's port ID
+ * @starget:	scsi target struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_get_starget_port_id(struct scsi_target *starget)
+{
+	struct ibmvfc_target *tgt = ibmvfc_find_target(starget);
+	fc_starget_port_id(starget) = tgt ? tgt->scsi_id : -1;
+}
+
+/**
+ * ibmvfc_wait_while_resetting - Wait while the host resets
+ * @vhost:		ibmvfc host struct
+ *
+ * Return value:
+ * 	0 on success / other on failure
+ **/
+static int ibmvfc_wait_while_resetting(struct ibmvfc_host *vhost)
+{
+	long timeout = wait_event_timeout(vhost->init_wait_q,
+					  (vhost->state == IBMVFC_ACTIVE ||
+					   vhost->state == IBMVFC_HOST_OFFLINE ||
+					   vhost->state == IBMVFC_LINK_DEAD),
+					  (init_timeout * HZ));
+
+	return timeout ? 0 : -EIO;
+}
+
+/**
+ * ibmvfc_issue_fc_host_lip - Re-initiate link initialization
+ * @shost:		scsi host struct
+ *
+ * Return value:
+ * 	0 on success / other on failure
+ **/
+static int ibmvfc_issue_fc_host_lip(struct Scsi_Host *shost)
+{
+	struct ibmvfc_host *vhost = shost_priv(shost);
+
+	dev_err(vhost->dev, "Initiating host LIP. Resetting connection\n");
+	ibmvfc_reset_host(vhost);
+	return ibmvfc_wait_while_resetting(vhost);
+}
+
+/**
+ * ibmvfc_gather_partition_info - Gather info about the LPAR
+ *
+ * Return value:
+ *	none
+ **/
+static void ibmvfc_gather_partition_info(struct ibmvfc_host *vhost)
+{
+	struct device_node *rootdn;
+	const char *name;
+	const unsigned int *num;
+
+	rootdn = of_find_node_by_path("/");
+	if (!rootdn)
+		return;
+
+	name = of_get_property(rootdn, "ibm,partition-name", NULL);
+	if (name)
+		strncpy(vhost->partition_name, name, sizeof(vhost->partition_name));
+	num = of_get_property(rootdn, "ibm,partition-no", NULL);
+	if (num)
+		vhost->partition_number = *num;
+	of_node_put(rootdn);
+}
+
+/**
+ * ibmvfc_set_login_info - Setup info for NPIV login
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ *	none
+ **/
+static void ibmvfc_set_login_info(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_npiv_login *login_info = &vhost->login_info;
+	struct device_node *of_node = vhost->dev->archdata.of_node;
+	const char *location;
+
+	memset(login_info, 0, sizeof(*login_info));
+
+	login_info->ostype = IBMVFC_OS_LINUX;
+	login_info->max_dma_len = IBMVFC_MAX_SECTORS << 9;
+	login_info->max_payload = sizeof(struct ibmvfc_fcp_cmd_iu);
+	login_info->max_response = sizeof(struct ibmvfc_fcp_rsp);
+	login_info->partition_num = vhost->partition_number;
+	login_info->vfc_frame_version = 1;
+	login_info->fcp_version = 3;
+	if (vhost->client_migrated)
+		login_info->flags = IBMVFC_CLIENT_MIGRATED;
+
+	login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ;
+	login_info->capabilities = IBMVFC_CAN_MIGRATE;
+	login_info->async.va = vhost->async_crq.msg_token;
+	login_info->async.len = vhost->async_crq.size;
+	strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME);
+	strncpy(login_info->device_name,
+		vhost->host->shost_gendev.bus_id, IBMVFC_MAX_NAME);
+
+	location = of_get_property(of_node, "ibm,loc-code", NULL);
+	location = location ? location : vhost->dev->bus_id;
+	strncpy(login_info->drc_name, location, IBMVFC_MAX_NAME);
+}
+
+/**
+ * ibmvfc_init_event_pool - Allocates and initializes the event pool for a host
+ * @vhost:	ibmvfc host who owns the event pool
+ *
+ * Returns zero on success.
+ **/
+static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost)
+{
+	int i;
+	struct ibmvfc_event_pool *pool = &vhost->pool;
+
+	ENTER;
+	pool->size = max_requests + IBMVFC_NUM_INTERNAL_REQ;
+	pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL);
+	if (!pool->events)
+		return -ENOMEM;
+
+	pool->iu_storage = dma_alloc_coherent(vhost->dev,
+					      pool->size * sizeof(*pool->iu_storage),
+					      &pool->iu_token, 0);
+
+	if (!pool->iu_storage) {
+		kfree(pool->events);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < pool->size; ++i) {
+		struct ibmvfc_event *evt = &pool->events[i];
+		atomic_set(&evt->free, 1);
+		evt->crq.valid = 0x80;
+		evt->crq.ioba = pool->iu_token + (sizeof(*evt->xfer_iu) * i);
+		evt->xfer_iu = pool->iu_storage + i;
+		evt->vhost = vhost;
+		evt->ext_list = NULL;
+		list_add_tail(&evt->queue, &vhost->free);
+	}
+
+	LEAVE;
+	return 0;
+}
+
+/**
+ * ibmvfc_free_event_pool - Frees memory of the event pool of a host
+ * @vhost:	ibmvfc host who owns the event pool
+ *
+ **/
+static void ibmvfc_free_event_pool(struct ibmvfc_host *vhost)
+{
+	int i;
+	struct ibmvfc_event_pool *pool = &vhost->pool;
+
+	ENTER;
+	for (i = 0; i < pool->size; ++i) {
+		list_del(&pool->events[i].queue);
+		BUG_ON(atomic_read(&pool->events[i].free) != 1);
+		if (pool->events[i].ext_list)
+			dma_pool_free(vhost->sg_pool,
+				      pool->events[i].ext_list,
+				      pool->events[i].ext_list_token);
+	}
+
+	kfree(pool->events);
+	dma_free_coherent(vhost->dev,
+			  pool->size * sizeof(*pool->iu_storage),
+			  pool->iu_storage, pool->iu_token);
+	LEAVE;
+}
+
+/**
+ * ibmvfc_get_event - Gets the next free event in pool
+ * @vhost:	ibmvfc host struct
+ *
+ * Returns a free event from the pool.
+ **/
+static struct ibmvfc_event *ibmvfc_get_event(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_event *evt;
+
+	BUG_ON(list_empty(&vhost->free));
+	evt = list_entry(vhost->free.next, struct ibmvfc_event, queue);
+	atomic_set(&evt->free, 0);
+	list_del(&evt->queue);
+	return evt;
+}
+
+/**
+ * ibmvfc_init_event - Initialize fields in an event struct that are always
+ *				required.
+ * @evt:	The event
+ * @done:	Routine to call when the event is responded to
+ * @format:	SRP or MAD format
+ **/
+static void ibmvfc_init_event(struct ibmvfc_event *evt,
+			      void (*done) (struct ibmvfc_event *), u8 format)
+{
+	evt->cmnd = NULL;
+	evt->sync_iu = NULL;
+	evt->crq.format = format;
+	evt->done = done;
+}
+
+/**
+ * ibmvfc_map_sg_list - Initialize scatterlist
+ * @scmd:	scsi command struct
+ * @nseg:	number of scatterlist segments
+ * @md:	memory descriptor list to initialize
+ **/
+static void ibmvfc_map_sg_list(struct scsi_cmnd *scmd, int nseg,
+			       struct srp_direct_buf *md)
+{
+	int i;
+	struct scatterlist *sg;
+
+	scsi_for_each_sg(scmd, sg, nseg, i) {
+		md[i].va = sg_dma_address(sg);
+		md[i].len = sg_dma_len(sg);
+		md[i].key = 0;
+	}
+}
+
+/**
+ * ibmvfc_map_sg_data - Maps dma for a scatterlist and initializes decriptor fields
+ * @scmd:		Scsi_Cmnd with the scatterlist
+ * @evt:		ibmvfc event struct
+ * @vfc_cmd:	vfc_cmd that contains the memory descriptor
+ * @dev:		device for which to map dma memory
+ *
+ * Returns:
+ *	0 on success / non-zero on failure
+ **/
+static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
+			      struct ibmvfc_event *evt,
+			      struct ibmvfc_cmd *vfc_cmd, struct device *dev)
+{
+
+	int sg_mapped;
+	struct srp_direct_buf *data = &vfc_cmd->ioba;
+	struct ibmvfc_host *vhost = dev_get_drvdata(dev);
+
+	sg_mapped = scsi_dma_map(scmd);
+	if (!sg_mapped) {
+		vfc_cmd->flags |= IBMVFC_NO_MEM_DESC;
+		return 0;
+	} else if (unlikely(sg_mapped < 0)) {
+		if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+			scmd_printk(KERN_ERR, scmd, "Failed to map DMA buffer for command\n");
+		return sg_mapped;
+	}
+
+	if (scmd->sc_data_direction == DMA_TO_DEVICE) {
+		vfc_cmd->flags |= IBMVFC_WRITE;
+		vfc_cmd->iu.add_cdb_len |= IBMVFC_WRDATA;
+	} else {
+		vfc_cmd->flags |= IBMVFC_READ;
+		vfc_cmd->iu.add_cdb_len |= IBMVFC_RDDATA;
+	}
+
+	if (sg_mapped == 1) {
+		ibmvfc_map_sg_list(scmd, sg_mapped, data);
+		return 0;
+	}
+
+	vfc_cmd->flags |= IBMVFC_SCATTERLIST;
+
+	if (!evt->ext_list) {
+		evt->ext_list = dma_pool_alloc(vhost->sg_pool, GFP_ATOMIC,
+					       &evt->ext_list_token);
+
+		if (!evt->ext_list) {
+			scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
+			return -ENOMEM;
+		}
+	}
+
+	ibmvfc_map_sg_list(scmd, sg_mapped, evt->ext_list);
+
+	data->va = evt->ext_list_token;
+	data->len = sg_mapped * sizeof(struct srp_direct_buf);
+	data->key = 0;
+	return 0;
+}
+
+/**
+ * ibmvfc_timeout - Internal command timeout handler
+ * @evt:	struct ibmvfc_event that timed out
+ *
+ * Called when an internally generated command times out
+ **/
+static void ibmvfc_timeout(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	dev_err(vhost->dev, "Command timed out (%p). Resetting connection\n", evt);
+	ibmvfc_reset_host(vhost);
+}
+
+/**
+ * ibmvfc_send_event - Transforms event to u64 array and calls send_crq()
+ * @evt:		event to be sent
+ * @vhost:		ibmvfc host struct
+ * @timeout:	timeout in seconds - 0 means do not time command
+ *
+ * Returns the value returned from ibmvfc_send_crq(). (Zero for success)
+ **/
+static int ibmvfc_send_event(struct ibmvfc_event *evt,
+			     struct ibmvfc_host *vhost, unsigned long timeout)
+{
+	u64 *crq_as_u64 = (u64 *) &evt->crq;
+	int rc;
+
+	/* Copy the IU into the transfer area */
+	*evt->xfer_iu = evt->iu;
+	if (evt->crq.format == IBMVFC_CMD_FORMAT)
+		evt->xfer_iu->cmd.tag = (u64)evt;
+	else if (evt->crq.format == IBMVFC_MAD_FORMAT)
+		evt->xfer_iu->mad_common.tag = (u64)evt;
+	else
+		BUG();
+
+	list_add_tail(&evt->queue, &vhost->sent);
+	init_timer(&evt->timer);
+
+	if (timeout) {
+		evt->timer.data = (unsigned long) evt;
+		evt->timer.expires = jiffies + (timeout * HZ);
+		evt->timer.function = (void (*)(unsigned long))ibmvfc_timeout;
+		add_timer(&evt->timer);
+	}
+
+	if ((rc = ibmvfc_send_crq(vhost, crq_as_u64[0], crq_as_u64[1]))) {
+		list_del(&evt->queue);
+		del_timer(&evt->timer);
+
+		/* If send_crq returns H_CLOSED, return SCSI_MLQUEUE_HOST_BUSY.
+		 * Firmware will send a CRQ with a transport event (0xFF) to
+		 * tell this client what has happened to the transport. This
+		 * will be handled in ibmvfc_handle_crq()
+		 */
+		if (rc == H_CLOSED) {
+			if (printk_ratelimit())
+				dev_warn(vhost->dev, "Send warning. Receive queue closed, will retry.\n");
+			if (evt->cmnd)
+				scsi_dma_unmap(evt->cmnd);
+			ibmvfc_free_event(evt);
+			return SCSI_MLQUEUE_HOST_BUSY;
+		}
+
+		dev_err(vhost->dev, "Send error (rc=%d)\n", rc);
+		if (evt->cmnd) {
+			evt->cmnd->result = DID_ERROR << 16;
+			evt->done = ibmvfc_scsi_eh_done;
+		} else
+			evt->xfer_iu->mad_common.status = IBMVFC_MAD_CRQ_ERROR;
+
+		evt->done(evt);
+	} else
+		ibmvfc_trc_start(evt);
+
+	return 0;
+}
+
+/**
+ * ibmvfc_log_error - Log an error for the failed command if appropriate
+ * @evt:	ibmvfc event to log
+ *
+ **/
+static void ibmvfc_log_error(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
+	struct scsi_cmnd *cmnd = evt->cmnd;
+	const char *err = unknown_error;
+	int index = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error);
+	int logerr = 0;
+	int rsp_code = 0;
+
+	if (index >= 0) {
+		logerr = cmd_status[index].log;
+		err = cmd_status[index].name;
+	}
+
+	if (!logerr && (vhost->log_level <= IBMVFC_DEFAULT_LOG_LEVEL))
+		return;
+
+	if (rsp->flags & FCP_RSP_LEN_VALID)
+		rsp_code = rsp->data.info.rsp_code;
+
+	scmd_printk(KERN_ERR, cmnd, "Command (%02X) failed: %s (%x:%x) "
+		    "flags: %x fcp_rsp: %x, resid=%d, scsi_status: %x\n",
+		    cmnd->cmnd[0], err, vfc_cmd->status, vfc_cmd->error,
+		    rsp->flags, rsp_code, scsi_get_resid(cmnd), rsp->scsi_status);
+}
+
+/**
+ * ibmvfc_scsi_done - Handle responses from commands
+ * @evt:	ibmvfc event to be handled
+ *
+ * Used as a callback when sending scsi cmds.
+ **/
+static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
+	struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
+	struct scsi_cmnd *cmnd = evt->cmnd;
+	int rsp_len = 0;
+	int sense_len = rsp->fcp_sense_len;
+
+	if (cmnd) {
+		if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID)
+			scsi_set_resid(cmnd, vfc_cmd->adapter_resid);
+		else if (rsp->flags & FCP_RESID_UNDER)
+			scsi_set_resid(cmnd, rsp->fcp_resid);
+		else
+			scsi_set_resid(cmnd, 0);
+
+		if (vfc_cmd->status) {
+			cmnd->result = ibmvfc_get_err_result(vfc_cmd);
+
+			if (rsp->flags & FCP_RSP_LEN_VALID)
+				rsp_len = rsp->fcp_rsp_len;
+			if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE)
+				sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len;
+			if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len)
+				memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len);
+
+			ibmvfc_log_error(evt);
+		}
+
+		if (!cmnd->result &&
+		    (scsi_bufflen(cmnd) - scsi_get_resid(cmnd) < cmnd->underflow))
+			cmnd->result = (DID_ERROR << 16);
+
+		scsi_dma_unmap(cmnd);
+		cmnd->scsi_done(cmnd);
+	}
+
+	ibmvfc_free_event(evt);
+}
+
+/**
+ * ibmvfc_host_chkready - Check if the host can accept commands
+ * @vhost:	 struct ibmvfc host
+ *
+ * Returns:
+ *	1 if host can accept command / 0 if not
+ **/
+static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost)
+{
+	int result = 0;
+
+	switch (vhost->state) {
+	case IBMVFC_LINK_DEAD:
+	case IBMVFC_HOST_OFFLINE:
+		result = DID_NO_CONNECT << 16;
+		break;
+	case IBMVFC_NO_CRQ:
+	case IBMVFC_INITIALIZING:
+	case IBMVFC_HALTED:
+	case IBMVFC_LINK_DOWN:
+		result = DID_REQUEUE << 16;
+		break;
+	case IBMVFC_ACTIVE:
+		result = 0;
+		break;
+	};
+
+	return result;
+}
+
+/**
+ * ibmvfc_queuecommand - The queuecommand function of the scsi template
+ * @cmnd:	struct scsi_cmnd to be executed
+ * @done:	Callback function to be called when cmnd is completed
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
+			       void (*done) (struct scsi_cmnd *))
+{
+	struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+	struct ibmvfc_cmd *vfc_cmd;
+	struct ibmvfc_event *evt;
+	u8 tag[2];
+	int rc;
+
+	if (unlikely((rc = fc_remote_port_chkready(rport))) ||
+	    unlikely((rc = ibmvfc_host_chkready(vhost)))) {
+		cmnd->result = rc;
+		done(cmnd);
+		return 0;
+	}
+
+	cmnd->result = (DID_OK << 16);
+	evt = ibmvfc_get_event(vhost);
+	ibmvfc_init_event(evt, ibmvfc_scsi_done, IBMVFC_CMD_FORMAT);
+	evt->cmnd = cmnd;
+	cmnd->scsi_done = done;
+	vfc_cmd = &evt->iu.cmd;
+	memset(vfc_cmd, 0, sizeof(*vfc_cmd));
+	vfc_cmd->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
+	vfc_cmd->resp.len = sizeof(vfc_cmd->rsp);
+	vfc_cmd->frame_type = IBMVFC_SCSI_FCP_TYPE;
+	vfc_cmd->payload_len = sizeof(vfc_cmd->iu);
+	vfc_cmd->resp_len = sizeof(vfc_cmd->rsp);
+	vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata;
+	vfc_cmd->tgt_scsi_id = rport->port_id;
+	if ((rport->supported_classes & FC_COS_CLASS3) &&
+	    (fc_host_supported_classes(vhost->host) & FC_COS_CLASS3))
+		vfc_cmd->flags = IBMVFC_CLASS_3_ERR;
+	vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd);
+	int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun);
+	memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len);
+
+	if (scsi_populate_tag_msg(cmnd, tag)) {
+		vfc_cmd->task_tag = tag[1];
+		switch (tag[0]) {
+		case MSG_SIMPLE_TAG:
+			vfc_cmd->iu.pri_task_attr = IBMVFC_SIMPLE_TASK;
+			break;
+		case MSG_HEAD_TAG:
+			vfc_cmd->iu.pri_task_attr = IBMVFC_HEAD_OF_QUEUE;
+			break;
+		case MSG_ORDERED_TAG:
+			vfc_cmd->iu.pri_task_attr = IBMVFC_ORDERED_TASK;
+			break;
+		};
+	}
+
+	if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev))))
+		return ibmvfc_send_event(evt, vhost, 0);
+
+	ibmvfc_free_event(evt);
+	if (rc == -ENOMEM)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+		scmd_printk(KERN_ERR, cmnd,
+			    "Failed to map DMA buffer for command. rc=%d\n", rc);
+
+	cmnd->result = DID_ERROR << 16;
+	done(cmnd);
+	return 0;
+}
+
+/**
+ * ibmvfc_sync_completion - Signal that a synchronous command has completed
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_sync_completion(struct ibmvfc_event *evt)
+{
+	/* copy the response back */
+	if (evt->sync_iu)
+		*evt->sync_iu = *evt->xfer_iu;
+
+	complete(&evt->comp);
+}
+
+/**
+ * ibmvfc_reset_device - Reset the device with the specified reset type
+ * @sdev:	scsi device to reset
+ * @type:	reset type
+ * @desc:	reset type description for log messages
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
+{
+	struct ibmvfc_host *vhost = shost_priv(sdev->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	struct ibmvfc_cmd *tmf;
+	struct ibmvfc_event *evt;
+	union ibmvfc_iu rsp_iu;
+	struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.rsp;
+	int rsp_rc = -EBUSY;
+	unsigned long flags;
+	int rsp_code = 0;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	if (vhost->state == IBMVFC_ACTIVE) {
+		evt = ibmvfc_get_event(vhost);
+		ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
+
+		tmf = &evt->iu.cmd;
+		memset(tmf, 0, sizeof(*tmf));
+		tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
+		tmf->resp.len = sizeof(tmf->rsp);
+		tmf->frame_type = IBMVFC_SCSI_FCP_TYPE;
+		tmf->payload_len = sizeof(tmf->iu);
+		tmf->resp_len = sizeof(tmf->rsp);
+		tmf->cancel_key = (unsigned long)sdev->hostdata;
+		tmf->tgt_scsi_id = rport->port_id;
+		int_to_scsilun(sdev->lun, &tmf->iu.lun);
+		tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF);
+		tmf->iu.tmf_flags = type;
+		evt->sync_iu = &rsp_iu;
+
+		init_completion(&evt->comp);
+		rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
+	}
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rsp_rc != 0) {
+		sdev_printk(KERN_ERR, sdev, "Failed to send %s reset event. rc=%d\n",
+			    desc, rsp_rc);
+		return -EIO;
+	}
+
+	sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc);
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.cmd.status) {
+		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
+			rsp_code = fc_rsp->data.info.rsp_code;
+
+		sdev_printk(KERN_ERR, sdev, "%s reset failed: %s (%x:%x) "
+			    "flags: %x fcp_rsp: %x, scsi_status: %x\n",
+			    desc, ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error),
+			    rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
+			    fc_rsp->scsi_status);
+		rsp_rc = -EIO;
+	} else
+		sdev_printk(KERN_INFO, sdev, "%s reset successful\n", desc);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return rsp_rc;
+}
+
+/**
+ * ibmvfc_abort_task_set - Abort outstanding commands to the device
+ * @sdev:	scsi device to abort commands
+ *
+ * This sends an Abort Task Set to the VIOS for the specified device. This does
+ * NOT send any cancel to the VIOS. That must be done separately.
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_abort_task_set(struct scsi_device *sdev)
+{
+	struct ibmvfc_host *vhost = shost_priv(sdev->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	struct ibmvfc_cmd *tmf;
+	struct ibmvfc_event *evt, *found_evt;
+	union ibmvfc_iu rsp_iu;
+	struct ibmvfc_fcp_rsp *fc_rsp = &rsp_iu.cmd.rsp;
+	int rsp_rc = -EBUSY;
+	unsigned long flags;
+	int rsp_code = 0;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	found_evt = NULL;
+	list_for_each_entry(evt, &vhost->sent, queue) {
+		if (evt->cmnd && evt->cmnd->device == sdev) {
+			found_evt = evt;
+			break;
+		}
+	}
+
+	if (!found_evt) {
+		if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+			sdev_printk(KERN_INFO, sdev, "No events found to abort\n");
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return 0;
+	}
+
+	if (vhost->state == IBMVFC_ACTIVE) {
+		evt = ibmvfc_get_event(vhost);
+		ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT);
+
+		tmf = &evt->iu.cmd;
+		memset(tmf, 0, sizeof(*tmf));
+		tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
+		tmf->resp.len = sizeof(tmf->rsp);
+		tmf->frame_type = IBMVFC_SCSI_FCP_TYPE;
+		tmf->payload_len = sizeof(tmf->iu);
+		tmf->resp_len = sizeof(tmf->rsp);
+		tmf->cancel_key = (unsigned long)sdev->hostdata;
+		tmf->tgt_scsi_id = rport->port_id;
+		int_to_scsilun(sdev->lun, &tmf->iu.lun);
+		tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF);
+		tmf->iu.tmf_flags = IBMVFC_ABORT_TASK_SET;
+		evt->sync_iu = &rsp_iu;
+
+		init_completion(&evt->comp);
+		rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
+	}
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rsp_rc != 0) {
+		sdev_printk(KERN_ERR, sdev, "Failed to send abort. rc=%d\n", rsp_rc);
+		return -EIO;
+	}
+
+	sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n");
+	wait_for_completion(&evt->comp);
+
+	if (rsp_iu.cmd.status) {
+		if (fc_rsp->flags & FCP_RSP_LEN_VALID)
+			rsp_code = fc_rsp->data.info.rsp_code;
+
+		sdev_printk(KERN_ERR, sdev, "Abort failed: %s (%x:%x) "
+			    "flags: %x fcp_rsp: %x, scsi_status: %x\n",
+			    ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error),
+			    rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
+			    fc_rsp->scsi_status);
+		rsp_rc = -EIO;
+	} else
+		sdev_printk(KERN_INFO, sdev, "Abort successful\n");
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return rsp_rc;
+}
+
+/**
+ * ibmvfc_cancel_all - Cancel all outstanding commands to the device
+ * @sdev:	scsi device to cancel commands
+ * @type:	type of error recovery being performed
+ *
+ * This sends a cancel to the VIOS for the specified device. This does
+ * NOT send any abort to the actual device. That must be done separately.
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
+{
+	struct ibmvfc_host *vhost = shost_priv(sdev->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	struct ibmvfc_tmf *tmf;
+	struct ibmvfc_event *evt, *found_evt;
+	union ibmvfc_iu rsp;
+	int rsp_rc = -EBUSY;
+	unsigned long flags;
+	u16 status;
+
+	ENTER;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	found_evt = NULL;
+	list_for_each_entry(evt, &vhost->sent, queue) {
+		if (evt->cmnd && evt->cmnd->device == sdev) {
+			found_evt = evt;
+			break;
+		}
+	}
+
+	if (!found_evt) {
+		if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+			sdev_printk(KERN_INFO, sdev, "No events found to cancel\n");
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		return 0;
+	}
+
+	if (vhost->state == IBMVFC_ACTIVE) {
+		evt = ibmvfc_get_event(vhost);
+		ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
+
+		tmf = &evt->iu.tmf;
+		memset(tmf, 0, sizeof(*tmf));
+		tmf->common.version = 1;
+		tmf->common.opcode = IBMVFC_TMF_MAD;
+		tmf->common.length = sizeof(*tmf);
+		tmf->scsi_id = rport->port_id;
+		int_to_scsilun(sdev->lun, &tmf->lun);
+		tmf->flags = (type | IBMVFC_TMF_LUA_VALID);
+		tmf->cancel_key = (unsigned long)sdev->hostdata;
+		tmf->my_cancel_key = (IBMVFC_TMF_CANCEL_KEY | (unsigned long)sdev->hostdata);
+
+		evt->sync_iu = &rsp;
+		init_completion(&evt->comp);
+		rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
+	}
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (rsp_rc != 0) {
+		sdev_printk(KERN_ERR, sdev, "Failed to send cancel event. rc=%d\n", rsp_rc);
+		return -EIO;
+	}
+
+	sdev_printk(KERN_INFO, sdev, "Cancelling outstanding commands.\n");
+
+	wait_for_completion(&evt->comp);
+	status = rsp.mad_common.status;
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_free_event(evt);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	if (status != IBMVFC_MAD_SUCCESS) {
+		sdev_printk(KERN_WARNING, sdev, "Cancel failed with rc=%x\n", status);
+		return -EIO;
+	}
+
+	sdev_printk(KERN_INFO, sdev, "Successfully cancelled outstanding commands\n");
+	return 0;
+}
+
+/**
+ * ibmvfc_eh_abort_handler - Abort a command
+ * @cmd:	scsi command to abort
+ *
+ * Returns:
+ *	SUCCESS / FAILED
+ **/
+static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
+{
+	struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
+	struct ibmvfc_event *evt, *pos;
+	int cancel_rc, abort_rc;
+	unsigned long flags;
+
+	ENTER;
+	ibmvfc_wait_while_resetting(vhost);
+	cancel_rc = ibmvfc_cancel_all(cmd->device, IBMVFC_TMF_ABORT_TASK_SET);
+	abort_rc = ibmvfc_abort_task_set(cmd->device);
+
+	if (!cancel_rc && !abort_rc) {
+		spin_lock_irqsave(vhost->host->host_lock, flags);
+		list_for_each_entry_safe(evt, pos, &vhost->sent, queue) {
+			if (evt->cmnd && evt->cmnd->device == cmd->device)
+				ibmvfc_fail_request(evt, DID_ABORT);
+		}
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		LEAVE;
+		return SUCCESS;
+	}
+
+	LEAVE;
+	return FAILED;
+}
+
+/**
+ * ibmvfc_eh_device_reset_handler - Reset a single LUN
+ * @cmd:	scsi command struct
+ *
+ * Returns:
+ *	SUCCESS / FAILED
+ **/
+static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
+{
+	struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
+	struct ibmvfc_event *evt, *pos;
+	int cancel_rc, reset_rc;
+	unsigned long flags;
+
+	ENTER;
+	ibmvfc_wait_while_resetting(vhost);
+	cancel_rc = ibmvfc_cancel_all(cmd->device, IBMVFC_TMF_LUN_RESET);
+	reset_rc = ibmvfc_reset_device(cmd->device, IBMVFC_LUN_RESET, "LUN");
+
+	if (!cancel_rc && !reset_rc) {
+		spin_lock_irqsave(vhost->host->host_lock, flags);
+		list_for_each_entry_safe(evt, pos, &vhost->sent, queue) {
+			if (evt->cmnd && evt->cmnd->device == cmd->device)
+				ibmvfc_fail_request(evt, DID_ABORT);
+		}
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		LEAVE;
+		return SUCCESS;
+	}
+
+	LEAVE;
+	return FAILED;
+}
+
+/**
+ * ibmvfc_dev_cancel_all - Device iterated cancel all function
+ * @sdev:	scsi device struct
+ * @data:	return code
+ *
+ **/
+static void ibmvfc_dev_cancel_all(struct scsi_device *sdev, void *data)
+{
+	unsigned long *rc = data;
+	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET);
+}
+
+/**
+ * ibmvfc_dev_abort_all - Device iterated abort task set function
+ * @sdev:	scsi device struct
+ * @data:	return code
+ *
+ **/
+static void ibmvfc_dev_abort_all(struct scsi_device *sdev, void *data)
+{
+	unsigned long *rc = data;
+	*rc |= ibmvfc_abort_task_set(sdev);
+}
+
+/**
+ * ibmvfc_eh_target_reset_handler - Reset the target
+ * @cmd:	scsi command struct
+ *
+ * Returns:
+ *	SUCCESS / FAILED
+ **/
+static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
+{
+	struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
+	struct scsi_target *starget = scsi_target(cmd->device);
+	struct ibmvfc_event *evt, *pos;
+	int reset_rc;
+	unsigned long cancel_rc = 0;
+	unsigned long flags;
+
+	ENTER;
+	ibmvfc_wait_while_resetting(vhost);
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	reset_rc = ibmvfc_reset_device(cmd->device, IBMVFC_TARGET_RESET, "target");
+
+	if (!cancel_rc && !reset_rc) {
+		spin_lock_irqsave(vhost->host->host_lock, flags);
+		list_for_each_entry_safe(evt, pos, &vhost->sent, queue) {
+			if (evt->cmnd && scsi_target(evt->cmnd->device) == starget)
+				ibmvfc_fail_request(evt, DID_ABORT);
+		}
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		LEAVE;
+		return SUCCESS;
+	}
+
+	LEAVE;
+	return FAILED;
+}
+
+/**
+ * ibmvfc_eh_host_reset_handler - Reset the connection to the server
+ * @cmd:	struct scsi_cmnd having problems
+ *
+ **/
+static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd)
+{
+	int rc;
+	struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
+
+	dev_err(vhost->dev, "Resetting connection due to error recovery\n");
+	rc = ibmvfc_issue_fc_host_lip(vhost->host);
+	return rc ? FAILED : SUCCESS;
+}
+
+/**
+ * ibmvfc_terminate_rport_io - Terminate all pending I/O to the rport.
+ * @rport:		rport struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
+{
+	struct scsi_target *starget = to_scsi_target(&rport->dev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	struct ibmvfc_event *evt, *pos;
+	unsigned long cancel_rc = 0;
+	unsigned long abort_rc = 0;
+	unsigned long flags;
+
+	ENTER;
+	starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all);
+	starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all);
+
+	if (!cancel_rc && !abort_rc) {
+		spin_lock_irqsave(shost->host_lock, flags);
+		list_for_each_entry_safe(evt, pos, &vhost->sent, queue) {
+			if (evt->cmnd && scsi_target(evt->cmnd->device) == starget)
+				ibmvfc_fail_request(evt, DID_ABORT);
+		}
+		spin_unlock_irqrestore(shost->host_lock, flags);
+	} else
+		ibmvfc_issue_fc_host_lip(shost);
+
+	scsi_target_unblock(&rport->dev);
+	LEAVE;
+}
+
+static const struct {
+	enum ibmvfc_async_event ae;
+	const char *desc;
+} ae_desc [] = {
+	{ IBMVFC_AE_ELS_PLOGI,		"PLOGI" },
+	{ IBMVFC_AE_ELS_LOGO,		"LOGO" },
+	{ IBMVFC_AE_ELS_PRLO,		"PRLO" },
+	{ IBMVFC_AE_SCN_NPORT,		"N-Port SCN" },
+	{ IBMVFC_AE_SCN_GROUP,		"Group SCN" },
+	{ IBMVFC_AE_SCN_DOMAIN,		"Domain SCN" },
+	{ IBMVFC_AE_SCN_FABRIC,		"Fabric SCN" },
+	{ IBMVFC_AE_LINK_UP,		"Link Up" },
+	{ IBMVFC_AE_LINK_DOWN,		"Link Down" },
+	{ IBMVFC_AE_LINK_DEAD,		"Link Dead" },
+	{ IBMVFC_AE_HALT,			"Halt" },
+	{ IBMVFC_AE_RESUME,		"Resume" },
+	{ IBMVFC_AE_ADAPTER_FAILED,	"Adapter Failed" },
+};
+
+static const char *unknown_ae = "Unknown async";
+
+/**
+ * ibmvfc_get_ae_desc - Get text description for async event
+ * @ae:	async event
+ *
+ **/
+static const char *ibmvfc_get_ae_desc(u64 ae)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ae_desc); i++)
+		if (ae_desc[i].ae == ae)
+			return ae_desc[i].desc;
+
+	return unknown_ae;
+}
+
+/**
+ * ibmvfc_handle_async - Handle an async event from the adapter
+ * @crq:	crq to process
+ * @vhost:	ibmvfc host struct
+ *
+ **/
+static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
+				struct ibmvfc_host *vhost)
+{
+	const char *desc = ibmvfc_get_ae_desc(crq->event);
+
+	ibmvfc_log(vhost, 2, "%s event received\n", desc);
+
+	switch (crq->event) {
+	case IBMVFC_AE_LINK_UP:
+	case IBMVFC_AE_RESUME:
+		vhost->events_to_log |= IBMVFC_AE_LINKUP;
+		ibmvfc_init_host(vhost);
+		break;
+	case IBMVFC_AE_SCN_FABRIC:
+		vhost->events_to_log |= IBMVFC_AE_RSCN;
+		ibmvfc_init_host(vhost);
+		break;
+	case IBMVFC_AE_SCN_NPORT:
+	case IBMVFC_AE_SCN_GROUP:
+	case IBMVFC_AE_SCN_DOMAIN:
+		vhost->events_to_log |= IBMVFC_AE_RSCN;
+	case IBMVFC_AE_ELS_LOGO:
+	case IBMVFC_AE_ELS_PRLO:
+	case IBMVFC_AE_ELS_PLOGI:
+		ibmvfc_reinit_host(vhost);
+		break;
+	case IBMVFC_AE_LINK_DOWN:
+	case IBMVFC_AE_ADAPTER_FAILED:
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
+		break;
+	case IBMVFC_AE_LINK_DEAD:
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		break;
+	case IBMVFC_AE_HALT:
+		ibmvfc_link_down(vhost, IBMVFC_HALTED);
+		break;
+	default:
+		dev_err(vhost->dev, "Unknown async event received: %ld\n", crq->event);
+		break;
+	};
+}
+
+/**
+ * ibmvfc_handle_crq - Handles and frees received events in the CRQ
+ * @crq:	Command/Response queue
+ * @vhost:	ibmvfc host struct
+ *
+ **/
+static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
+{
+	long rc;
+	struct ibmvfc_event *evt = (struct ibmvfc_event *)crq->ioba;
+
+	switch (crq->valid) {
+	case IBMVFC_CRQ_INIT_RSP:
+		switch (crq->format) {
+		case IBMVFC_CRQ_INIT:
+			dev_info(vhost->dev, "Partner initialized\n");
+			/* Send back a response */
+			rc = ibmvfc_send_crq_init_complete(vhost);
+			if (rc == 0)
+				ibmvfc_init_host(vhost);
+			else
+				dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc);
+			break;
+		case IBMVFC_CRQ_INIT_COMPLETE:
+			dev_info(vhost->dev, "Partner initialization complete\n");
+			ibmvfc_init_host(vhost);
+			break;
+		default:
+			dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format);
+		}
+		return;
+	case IBMVFC_CRQ_XPORT_EVENT:
+		vhost->state = IBMVFC_NO_CRQ;
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
+		if (crq->format == IBMVFC_PARTITION_MIGRATED) {
+			/* We need to re-setup the interpartition connection */
+			dev_info(vhost->dev, "Re-enabling adapter\n");
+			vhost->client_migrated = 1;
+			ibmvfc_purge_requests(vhost, DID_REQUEUE);
+			if ((rc = ibmvfc_reenable_crq_queue(vhost)) ||
+			    (rc = ibmvfc_send_crq_init(vhost))) {
+				ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+				dev_err(vhost->dev, "Error after enable (rc=%ld)\n", rc);
+			} else
+				ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
+		} else {
+			dev_err(vhost->dev, "Virtual adapter failed (rc=%d)\n", crq->format);
+
+			ibmvfc_purge_requests(vhost, DID_ERROR);
+			if ((rc = ibmvfc_reset_crq(vhost)) ||
+			    (rc = ibmvfc_send_crq_init(vhost))) {
+				ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+				dev_err(vhost->dev, "Error after reset (rc=%ld)\n", rc);
+			} else
+				ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
+		}
+		return;
+	case IBMVFC_CRQ_CMD_RSP:
+		break;
+	default:
+		dev_err(vhost->dev, "Got an invalid message type 0x%02x\n", crq->valid);
+		return;
+	}
+
+	if (crq->format == IBMVFC_ASYNC_EVENT)
+		return;
+
+	/* The only kind of payload CRQs we should get are responses to
+	 * things we send. Make sure this response is to something we
+	 * actually sent
+	 */
+	if (unlikely(!ibmvfc_valid_event(&vhost->pool, evt))) {
+		dev_err(vhost->dev, "Returned correlation_token 0x%08lx is invalid!\n",
+			crq->ioba);
+		return;
+	}
+
+	if (unlikely(atomic_read(&evt->free))) {
+		dev_err(vhost->dev, "Received duplicate correlation_token 0x%08lx!\n",
+			crq->ioba);
+		return;
+	}
+
+	del_timer(&evt->timer);
+	list_del(&evt->queue);
+	ibmvfc_trc_end(evt);
+	evt->done(evt);
+}
+
+/**
+ * ibmvfc_scan_finished - Check if the device scan is done.
+ * @shost:	scsi host struct
+ * @time:	current elapsed time
+ *
+ * Returns:
+ *	0 if scan is not done / 1 if scan is done
+ **/
+static int ibmvfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+	unsigned long flags;
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	int done = 0;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	if (time >= (init_timeout * HZ)) {
+		dev_info(vhost->dev, "Scan taking longer than %d seconds, "
+			 "continuing initialization\n", init_timeout);
+		done = 1;
+	}
+
+	if (vhost->state != IBMVFC_NO_CRQ && vhost->action == IBMVFC_HOST_ACTION_NONE)
+		done = 1;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return done;
+}
+
+/**
+ * ibmvfc_slave_alloc - Setup the device's task set value
+ * @sdev:	struct scsi_device device to configure
+ *
+ * Set the device's task set value so that error handling works as
+ * expected.
+ *
+ * Returns:
+ *	0 on success / -ENXIO if device does not exist
+ **/
+static int ibmvfc_slave_alloc(struct scsi_device *sdev)
+{
+	struct Scsi_Host *shost = sdev->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags = 0;
+
+	if (!rport || fc_remote_port_chkready(rport))
+		return -ENXIO;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	sdev->hostdata = (void *)(unsigned long)vhost->task_set++;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return 0;
+}
+
+/**
+ * ibmvfc_slave_configure - Configure the device
+ * @sdev:	struct scsi_device device to configure
+ *
+ * Enable allow_restart for a device if it is a disk. Adjust the
+ * queue_depth here also.
+ *
+ * Returns:
+ *	0
+ **/
+static int ibmvfc_slave_configure(struct scsi_device *sdev)
+{
+	struct Scsi_Host *shost = sdev->host;
+	struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	if (sdev->type == TYPE_DISK)
+		sdev->allow_restart = 1;
+
+	if (sdev->tagged_supported) {
+		scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
+		scsi_activate_tcq(sdev, sdev->queue_depth);
+	} else
+		scsi_deactivate_tcq(sdev, sdev->queue_depth);
+
+	rport->dev_loss_tmo = dev_loss_tmo;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return 0;
+}
+
+/**
+ * ibmvfc_change_queue_depth - Change the device's queue depth
+ * @sdev:	scsi device struct
+ * @qdepth:	depth to set
+ *
+ * Return value:
+ * 	actual depth set
+ **/
+static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth)
+{
+	if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
+		qdepth = IBMVFC_MAX_CMDS_PER_LUN;
+
+	scsi_adjust_queue_depth(sdev, 0, qdepth);
+	return sdev->queue_depth;
+}
+
+/**
+ * ibmvfc_change_queue_type - Change the device's queue type
+ * @sdev:		scsi device struct
+ * @tag_type:	type of tags to use
+ *
+ * Return value:
+ * 	actual queue type set
+ **/
+static int ibmvfc_change_queue_type(struct scsi_device *sdev, int tag_type)
+{
+	if (sdev->tagged_supported) {
+		scsi_set_tag_type(sdev, tag_type);
+
+		if (tag_type)
+			scsi_activate_tcq(sdev, sdev->queue_depth);
+		else
+			scsi_deactivate_tcq(sdev, sdev->queue_depth);
+	} else
+		tag_type = 0;
+
+	return tag_type;
+}
+
+static ssize_t ibmvfc_show_host_partition_name(struct device *dev,
+						 struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			vhost->login_buf->resp.partition_name);
+}
+
+static struct device_attribute ibmvfc_host_partition_name = {
+	.attr = {
+		.name = "partition_name",
+		.mode = S_IRUGO,
+	},
+	.show = ibmvfc_show_host_partition_name,
+};
+
+static ssize_t ibmvfc_show_host_device_name(struct device *dev,
+					    struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			vhost->login_buf->resp.device_name);
+}
+
+static struct device_attribute ibmvfc_host_device_name = {
+	.attr = {
+		.name = "device_name",
+		.mode = S_IRUGO,
+	},
+	.show = ibmvfc_show_host_device_name,
+};
+
+static ssize_t ibmvfc_show_host_loc_code(struct device *dev,
+					 struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			vhost->login_buf->resp.port_loc_code);
+}
+
+static struct device_attribute ibmvfc_host_loc_code = {
+	.attr = {
+		.name = "port_loc_code",
+		.mode = S_IRUGO,
+	},
+	.show = ibmvfc_show_host_loc_code,
+};
+
+static ssize_t ibmvfc_show_host_drc_name(struct device *dev,
+					 struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			vhost->login_buf->resp.drc_name);
+}
+
+static struct device_attribute ibmvfc_host_drc_name = {
+	.attr = {
+		.name = "drc_name",
+		.mode = S_IRUGO,
+	},
+	.show = ibmvfc_show_host_drc_name,
+};
+
+static ssize_t ibmvfc_show_host_npiv_version(struct device *dev,
+					     struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	return snprintf(buf, PAGE_SIZE, "%d\n", vhost->login_buf->resp.version);
+}
+
+static struct device_attribute ibmvfc_host_npiv_version = {
+	.attr = {
+		.name = "npiv_version",
+		.mode = S_IRUGO,
+	},
+	.show = ibmvfc_show_host_npiv_version,
+};
+
+/**
+ * ibmvfc_show_log_level - Show the adapter's error logging level
+ * @dev:	class device struct
+ * @buf:	buffer
+ *
+ * Return value:
+ * 	number of bytes printed to buffer
+ **/
+static ssize_t ibmvfc_show_log_level(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags = 0;
+	int len;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	len = snprintf(buf, PAGE_SIZE, "%d\n", vhost->log_level);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return len;
+}
+
+/**
+ * ibmvfc_store_log_level - Change the adapter's error logging level
+ * @dev:	class device struct
+ * @buf:	buffer
+ *
+ * Return value:
+ * 	number of bytes printed to buffer
+ **/
+static ssize_t ibmvfc_store_log_level(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	vhost->log_level = simple_strtoul(buf, NULL, 10);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return strlen(buf);
+}
+
+static struct device_attribute ibmvfc_log_level_attr = {
+	.attr = {
+		.name =		"log_level",
+		.mode =		S_IRUGO | S_IWUSR,
+	},
+	.show = ibmvfc_show_log_level,
+	.store = ibmvfc_store_log_level
+};
+
+#ifdef CONFIG_SCSI_IBMVFC_TRACE
+/**
+ * ibmvfc_read_trace - Dump the adapter trace
+ * @kobj:		kobject struct
+ * @bin_attr:	bin_attribute struct
+ * @buf:		buffer
+ * @off:		offset
+ * @count:		buffer size
+ *
+ * Return value:
+ *	number of bytes printed to buffer
+ **/
+static ssize_t ibmvfc_read_trace(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct ibmvfc_host *vhost = shost_priv(shost);
+	unsigned long flags = 0;
+	int size = IBMVFC_TRACE_SIZE;
+	char *src = (char *)vhost->trace;
+
+	if (off > size)
+		return 0;
+	if (off + count > size) {
+		size -= off;
+		count = size;
+	}
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	memcpy(buf, &src[off], count);
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return count;
+}
+
+static struct bin_attribute ibmvfc_trace_attr = {
+	.attr =	{
+		.name = "trace",
+		.mode = S_IRUGO,
+	},
+	.size = 0,
+	.read = ibmvfc_read_trace,
+};
+#endif
+
+static struct device_attribute *ibmvfc_attrs[] = {
+	&ibmvfc_host_partition_name,
+	&ibmvfc_host_device_name,
+	&ibmvfc_host_loc_code,
+	&ibmvfc_host_drc_name,
+	&ibmvfc_host_npiv_version,
+	&ibmvfc_log_level_attr,
+	NULL
+};
+
+static struct scsi_host_template driver_template = {
+	.module = THIS_MODULE,
+	.name = "IBM POWER Virtual FC Adapter",
+	.proc_name = IBMVFC_NAME,
+	.queuecommand = ibmvfc_queuecommand,
+	.eh_abort_handler = ibmvfc_eh_abort_handler,
+	.eh_device_reset_handler = ibmvfc_eh_device_reset_handler,
+	.eh_target_reset_handler = ibmvfc_eh_target_reset_handler,
+	.eh_host_reset_handler = ibmvfc_eh_host_reset_handler,
+	.slave_alloc = ibmvfc_slave_alloc,
+	.slave_configure = ibmvfc_slave_configure,
+	.scan_finished = ibmvfc_scan_finished,
+	.change_queue_depth = ibmvfc_change_queue_depth,
+	.change_queue_type = ibmvfc_change_queue_type,
+	.cmd_per_lun = 16,
+	.can_queue = IBMVFC_MAX_REQUESTS_DEFAULT,
+	.this_id = -1,
+	.sg_tablesize = SG_ALL,
+	.max_sectors = IBMVFC_MAX_SECTORS,
+	.use_clustering = ENABLE_CLUSTERING,
+	.shost_attrs = ibmvfc_attrs,
+};
+
+/**
+ * ibmvfc_next_async_crq - Returns the next entry in async queue
+ * @vhost:	ibmvfc host struct
+ *
+ * Returns:
+ *	Pointer to next entry in queue / NULL if empty
+ **/
+static struct ibmvfc_async_crq *ibmvfc_next_async_crq(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_async_crq_queue *async_crq = &vhost->async_crq;
+	struct ibmvfc_async_crq *crq;
+
+	crq = &async_crq->msgs[async_crq->cur];
+	if (crq->valid & 0x80) {
+		if (++async_crq->cur == async_crq->size)
+			async_crq->cur = 0;
+	} else
+		crq = NULL;
+
+	return crq;
+}
+
+/**
+ * ibmvfc_next_crq - Returns the next entry in message queue
+ * @vhost:	ibmvfc host struct
+ *
+ * Returns:
+ *	Pointer to next entry in queue / NULL if empty
+ **/
+static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_crq_queue *queue = &vhost->crq;
+	struct ibmvfc_crq *crq;
+
+	crq = &queue->msgs[queue->cur];
+	if (crq->valid & 0x80) {
+		if (++queue->cur == queue->size)
+			queue->cur = 0;
+	} else
+		crq = NULL;
+
+	return crq;
+}
+
+/**
+ * ibmvfc_interrupt - Interrupt handler
+ * @irq:		number of irq to handle, not used
+ * @dev_instance: ibmvfc_host that received interrupt
+ *
+ * Returns:
+ *	IRQ_HANDLED
+ **/
+static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
+{
+	struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance;
+	struct vio_dev *vdev = to_vio_dev(vhost->dev);
+	struct ibmvfc_crq *crq;
+	struct ibmvfc_async_crq *async;
+	unsigned long flags;
+	int done = 0;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	vio_disable_interrupts(to_vio_dev(vhost->dev));
+	while (!done) {
+		/* Pull all the valid messages off the CRQ */
+		while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
+			ibmvfc_handle_crq(crq, vhost);
+			crq->valid = 0;
+		}
+
+		/* Pull all the valid messages off the async CRQ */
+		while ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
+			ibmvfc_handle_async(async, vhost);
+			async->valid = 0;
+		}
+
+		vio_enable_interrupts(vdev);
+		if ((crq = ibmvfc_next_crq(vhost)) != NULL) {
+			vio_disable_interrupts(vdev);
+			ibmvfc_handle_crq(crq, vhost);
+			crq->valid = 0;
+		} else if ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
+			vio_disable_interrupts(vdev);
+			ibmvfc_handle_async(async, vhost);
+			crq->valid = 0;
+		} else
+			done = 1;
+	}
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return IRQ_HANDLED;
+}
+
+/**
+ * ibmvfc_init_tgt - Set the next init job step for the target
+ * @tgt:		ibmvfc target struct
+ * @job_step:	job step to perform
+ *
+ **/
+static void ibmvfc_init_tgt(struct ibmvfc_target *tgt,
+			    void (*job_step) (struct ibmvfc_target *))
+{
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT);
+	tgt->job_step = job_step;
+	wake_up(&tgt->vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_retry_tgt_init - Attempt to retry a step in target initialization
+ * @tgt:		ibmvfc target struct
+ * @job_step:	initialization job step
+ *
+ **/
+static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt,
+				  void (*job_step) (struct ibmvfc_target *))
+{
+	if (++tgt->init_retries > IBMVFC_MAX_INIT_RETRIES) {
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+		wake_up(&tgt->vhost->work_wait_q);
+	} else
+		ibmvfc_init_tgt(tgt, job_step);
+}
+
+/**
+ * ibmvfc_release_tgt - Free memory allocated for a target
+ * @kref:		kref struct
+ *
+ **/
+static void ibmvfc_release_tgt(struct kref *kref)
+{
+	struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref);
+	kfree(tgt);
+}
+
+/**
+ * ibmvfc_tgt_prli_done - Completion handler for Process Login
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_target *tgt = evt->tgt;
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli;
+	u32 status = rsp->common.status;
+
+	vhost->discovery_threads--;
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+	switch (status) {
+	case IBMVFC_MAD_SUCCESS:
+		tgt_dbg(tgt, "Process Login succeeded\n");
+		tgt->need_login = 0;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_ADD_RPORT);
+		break;
+	case IBMVFC_MAD_DRIVER_FAILED:
+		break;
+	case IBMVFC_MAD_CRQ_ERROR:
+		ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
+		break;
+	case IBMVFC_MAD_FAILED:
+	default:
+		tgt_err(tgt, "Process Login failed: %s (%x:%x) rc=0x%02X\n",
+			ibmvfc_get_cmd_error(rsp->status, rsp->error),
+			rsp->status, rsp->error, status);
+		if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+			ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
+		break;
+	};
+
+	kref_put(&tgt->kref, ibmvfc_release_tgt);
+	ibmvfc_free_event(evt);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_tgt_send_prli - Send a process login
+ * @tgt:	ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt)
+{
+	struct ibmvfc_process_login *prli;
+	struct ibmvfc_host *vhost = tgt->vhost;
+	struct ibmvfc_event *evt;
+
+	if (vhost->discovery_threads >= disc_threads)
+		return;
+
+	kref_get(&tgt->kref);
+	evt = ibmvfc_get_event(vhost);
+	vhost->discovery_threads++;
+	ibmvfc_init_event(evt, ibmvfc_tgt_prli_done, IBMVFC_MAD_FORMAT);
+	evt->tgt = tgt;
+	prli = &evt->iu.prli;
+	memset(prli, 0, sizeof(*prli));
+	prli->common.version = 1;
+	prli->common.opcode = IBMVFC_PROCESS_LOGIN;
+	prli->common.length = sizeof(*prli);
+	prli->scsi_id = tgt->scsi_id;
+
+	prli->parms.type = IBMVFC_SCSI_FCP_TYPE;
+	prli->parms.flags = IBMVFC_PRLI_EST_IMG_PAIR;
+	prli->parms.service_parms = IBMVFC_PRLI_INITIATOR_FUNC;
+
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
+	if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+		vhost->discovery_threads--;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+	} else
+		tgt_dbg(tgt, "Sent process login\n");
+}
+
+/**
+ * ibmvfc_tgt_plogi_done - Completion handler for Port Login
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_target *tgt = evt->tgt;
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_port_login *rsp = &evt->xfer_iu->plogi;
+	u32 status = rsp->common.status;
+
+	vhost->discovery_threads--;
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+	switch (status) {
+	case IBMVFC_MAD_SUCCESS:
+		tgt_dbg(tgt, "Port Login succeeded\n");
+		if (tgt->ids.port_name &&
+		    tgt->ids.port_name != wwn_to_u64(rsp->service_parms.port_name)) {
+			vhost->reinit = 1;
+			tgt_dbg(tgt, "Port re-init required\n");
+			break;
+		}
+		tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
+		tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
+		tgt->ids.port_id = tgt->scsi_id;
+		tgt->ids.roles = FC_PORT_ROLE_FCP_TARGET;
+		memcpy(&tgt->service_parms, &rsp->service_parms,
+		       sizeof(tgt->service_parms));
+		memcpy(&tgt->service_parms_change, &rsp->service_parms_change,
+		       sizeof(tgt->service_parms_change));
+		ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_prli);
+		break;
+	case IBMVFC_MAD_DRIVER_FAILED:
+		break;
+	case IBMVFC_MAD_CRQ_ERROR:
+		ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
+		break;
+	case IBMVFC_MAD_FAILED:
+	default:
+		tgt_err(tgt, "Port Login failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
+			ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error,
+			ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type,
+			ibmvfc_get_ls_explain(rsp->fc_explain), rsp->fc_explain, status);
+
+		if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+			ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
+		break;
+	};
+
+	kref_put(&tgt->kref, ibmvfc_release_tgt);
+	ibmvfc_free_event(evt);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_tgt_send_plogi - Send PLOGI to the specified target
+ * @tgt:	ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
+{
+	struct ibmvfc_port_login *plogi;
+	struct ibmvfc_host *vhost = tgt->vhost;
+	struct ibmvfc_event *evt;
+
+	if (vhost->discovery_threads >= disc_threads)
+		return;
+
+	kref_get(&tgt->kref);
+	evt = ibmvfc_get_event(vhost);
+	vhost->discovery_threads++;
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
+	ibmvfc_init_event(evt, ibmvfc_tgt_plogi_done, IBMVFC_MAD_FORMAT);
+	evt->tgt = tgt;
+	plogi = &evt->iu.plogi;
+	memset(plogi, 0, sizeof(*plogi));
+	plogi->common.version = 1;
+	plogi->common.opcode = IBMVFC_PORT_LOGIN;
+	plogi->common.length = sizeof(*plogi);
+	plogi->scsi_id = tgt->scsi_id;
+
+	if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+		vhost->discovery_threads--;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+	} else
+		tgt_dbg(tgt, "Sent port login\n");
+}
+
+/**
+ * ibmvfc_tgt_implicit_logout_done - Completion handler for Implicit Logout MAD
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_tgt_implicit_logout_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_target *tgt = evt->tgt;
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_implicit_logout *rsp = &evt->xfer_iu->implicit_logout;
+	u32 status = rsp->common.status;
+
+	vhost->discovery_threads--;
+	ibmvfc_free_event(evt);
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+
+	switch (status) {
+	case IBMVFC_MAD_SUCCESS:
+		tgt_dbg(tgt, "Implicit Logout succeeded\n");
+		break;
+	case IBMVFC_MAD_DRIVER_FAILED:
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+		wake_up(&vhost->work_wait_q);
+		return;
+	case IBMVFC_MAD_FAILED:
+	default:
+		tgt_err(tgt, "Implicit Logout failed: rc=0x%02X\n", status);
+		break;
+	};
+
+	if (vhost->action == IBMVFC_HOST_ACTION_TGT_INIT)
+		ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_plogi);
+	else if (vhost->action == IBMVFC_HOST_ACTION_QUERY_TGTS &&
+		 tgt->scsi_id != tgt->new_scsi_id)
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+	kref_put(&tgt->kref, ibmvfc_release_tgt);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_tgt_implicit_logout - Initiate an Implicit Logout for specified target
+ * @tgt:		ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
+{
+	struct ibmvfc_implicit_logout *mad;
+	struct ibmvfc_host *vhost = tgt->vhost;
+	struct ibmvfc_event *evt;
+
+	if (vhost->discovery_threads >= disc_threads)
+		return;
+
+	kref_get(&tgt->kref);
+	evt = ibmvfc_get_event(vhost);
+	vhost->discovery_threads++;
+	ibmvfc_init_event(evt, ibmvfc_tgt_implicit_logout_done, IBMVFC_MAD_FORMAT);
+	evt->tgt = tgt;
+	mad = &evt->iu.implicit_logout;
+	memset(mad, 0, sizeof(*mad));
+	mad->common.version = 1;
+	mad->common.opcode = IBMVFC_IMPLICIT_LOGOUT;
+	mad->common.length = sizeof(*mad);
+	mad->old_scsi_id = tgt->scsi_id;
+
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
+	if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+		vhost->discovery_threads--;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+	} else
+		tgt_dbg(tgt, "Sent Implicit Logout\n");
+}
+
+/**
+ * ibmvfc_tgt_query_target_done - Completion handler for Query Target MAD
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_target *tgt = evt->tgt;
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_query_tgt *rsp = &evt->xfer_iu->query_tgt;
+	u32 status = rsp->common.status;
+
+	vhost->discovery_threads--;
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+	switch (status) {
+	case IBMVFC_MAD_SUCCESS:
+		tgt_dbg(tgt, "Query Target succeeded\n");
+		tgt->new_scsi_id = rsp->scsi_id;
+		if (rsp->scsi_id != tgt->scsi_id)
+			ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
+		break;
+	case IBMVFC_MAD_DRIVER_FAILED:
+		break;
+	case IBMVFC_MAD_CRQ_ERROR:
+		ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target);
+		break;
+	case IBMVFC_MAD_FAILED:
+	default:
+		tgt_err(tgt, "Query Target failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
+			ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error,
+			ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type,
+			ibmvfc_get_gs_explain(rsp->fc_explain), rsp->fc_explain, status);
+
+		if ((rsp->status & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED &&
+		    rsp->error == IBMVFC_UNABLE_TO_PERFORM_REQ &&
+		    rsp->fc_explain == IBMVFC_PORT_NAME_NOT_REG)
+			ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
+		else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+			ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target);
+		break;
+	};
+
+	kref_put(&tgt->kref, ibmvfc_release_tgt);
+	ibmvfc_free_event(evt);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_tgt_query_target - Initiate a Query Target for specified target
+ * @tgt:	ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt)
+{
+	struct ibmvfc_query_tgt *query_tgt;
+	struct ibmvfc_host *vhost = tgt->vhost;
+	struct ibmvfc_event *evt;
+
+	if (vhost->discovery_threads >= disc_threads)
+		return;
+
+	kref_get(&tgt->kref);
+	evt = ibmvfc_get_event(vhost);
+	vhost->discovery_threads++;
+	evt->tgt = tgt;
+	ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT);
+	query_tgt = &evt->iu.query_tgt;
+	memset(query_tgt, 0, sizeof(*query_tgt));
+	query_tgt->common.version = 1;
+	query_tgt->common.opcode = IBMVFC_QUERY_TARGET;
+	query_tgt->common.length = sizeof(*query_tgt);
+	query_tgt->wwpn = tgt->ids.port_name;
+
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
+	if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+		vhost->discovery_threads--;
+		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+		kref_put(&tgt->kref, ibmvfc_release_tgt);
+	} else
+		tgt_dbg(tgt, "Sent Query Target\n");
+}
+
+/**
+ * ibmvfc_alloc_target - Allocate and initialize an ibmvfc target
+ * @vhost:		ibmvfc host struct
+ * @scsi_id:	SCSI ID to allocate target for
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
+{
+	struct ibmvfc_target *tgt;
+	unsigned long flags;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	list_for_each_entry(tgt, &vhost->targets, queue) {
+		if (tgt->scsi_id == scsi_id) {
+			if (tgt->need_login)
+				ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
+			goto unlock_out;
+		}
+	}
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	tgt = mempool_alloc(vhost->tgt_pool, GFP_KERNEL);
+	if (!tgt) {
+		dev_err(vhost->dev, "Target allocation failure for scsi id %08lx\n",
+			scsi_id);
+		return -ENOMEM;
+	}
+
+	tgt->scsi_id = scsi_id;
+	tgt->new_scsi_id = scsi_id;
+	tgt->vhost = vhost;
+	tgt->need_login = 1;
+	kref_init(&tgt->kref);
+	ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	list_add_tail(&tgt->queue, &vhost->targets);
+
+unlock_out:
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return 0;
+}
+
+/**
+ * ibmvfc_alloc_targets - Allocate and initialize ibmvfc targets
+ * @vhost:		ibmvfc host struct
+ *
+ * Returns:
+ *	0 on success / other on failure
+ **/
+static int ibmvfc_alloc_targets(struct ibmvfc_host *vhost)
+{
+	int i, rc;
+
+	for (i = 0, rc = 0; !rc && i < vhost->num_targets; i++)
+		rc = ibmvfc_alloc_target(vhost,
+					 vhost->disc_buf->scsi_id[i] & IBMVFC_DISC_TGT_SCSI_ID_MASK);
+
+	return rc;
+}
+
+/**
+ * ibmvfc_discover_targets_done - Completion handler for discover targets MAD
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_discover_targets_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	struct ibmvfc_discover_targets *rsp = &evt->xfer_iu->discover_targets;
+	u32 mad_status = rsp->common.status;
+
+	switch (mad_status) {
+	case IBMVFC_MAD_SUCCESS:
+		ibmvfc_dbg(vhost, "Discover Targets succeeded\n");
+		vhost->num_targets = rsp->num_written;
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_ALLOC_TGTS);
+		break;
+	case IBMVFC_MAD_FAILED:
+		dev_err(vhost->dev, "Discover Targets failed: %s (%x:%x)\n",
+			ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error);
+		ibmvfc_retry_host_init(vhost);
+		break;
+	case IBMVFC_MAD_DRIVER_FAILED:
+		break;
+	default:
+		dev_err(vhost->dev, "Invalid Discover Targets response: 0x%x\n", mad_status);
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		break;
+	}
+
+	ibmvfc_free_event(evt);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_discover_targets - Send Discover Targets MAD
+ * @vhost:	ibmvfc host struct
+ *
+ **/
+static void ibmvfc_discover_targets(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_discover_targets *mad;
+	struct ibmvfc_event *evt = ibmvfc_get_event(vhost);
+
+	ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT);
+	mad = &evt->iu.discover_targets;
+	memset(mad, 0, sizeof(*mad));
+	mad->common.version = 1;
+	mad->common.opcode = IBMVFC_DISC_TARGETS;
+	mad->common.length = sizeof(*mad);
+	mad->bufflen = vhost->disc_buf_sz;
+	mad->buffer.va = vhost->disc_buf_dma;
+	mad->buffer.len = vhost->disc_buf_sz;
+	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
+
+	if (!ibmvfc_send_event(evt, vhost, default_timeout))
+		ibmvfc_dbg(vhost, "Sent discover targets\n");
+	else
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+}
+
+/**
+ * ibmvfc_npiv_login_done - Completion handler for NPIV Login
+ * @evt:	ibmvfc event struct
+ *
+ **/
+static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
+{
+	struct ibmvfc_host *vhost = evt->vhost;
+	u32 mad_status = evt->xfer_iu->npiv_login.common.status;
+	struct ibmvfc_npiv_login_resp *rsp = &vhost->login_buf->resp;
+	unsigned int npiv_max_sectors;
+
+	switch (mad_status) {
+	case IBMVFC_MAD_SUCCESS:
+		ibmvfc_free_event(evt);
+		break;
+	case IBMVFC_MAD_FAILED:
+		dev_err(vhost->dev, "NPIV Login failed: %s (%x:%x)\n",
+			ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error);
+		if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+			ibmvfc_retry_host_init(vhost);
+		else
+			ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		ibmvfc_free_event(evt);
+		return;
+	case IBMVFC_MAD_CRQ_ERROR:
+		ibmvfc_retry_host_init(vhost);
+	case IBMVFC_MAD_DRIVER_FAILED:
+		ibmvfc_free_event(evt);
+		return;
+	default:
+		dev_err(vhost->dev, "Invalid NPIV Login response: 0x%x\n", mad_status);
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		ibmvfc_free_event(evt);
+		return;
+	}
+
+	vhost->client_migrated = 0;
+
+	if (!(rsp->flags & IBMVFC_NATIVE_FC)) {
+		dev_err(vhost->dev, "Virtual adapter does not support FC. %x\n",
+			rsp->flags);
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		wake_up(&vhost->work_wait_q);
+		return;
+	}
+
+	if (rsp->max_cmds <= IBMVFC_NUM_INTERNAL_REQ) {
+		dev_err(vhost->dev, "Virtual adapter supported queue depth too small: %d\n",
+			rsp->max_cmds);
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+		wake_up(&vhost->work_wait_q);
+		return;
+	}
+
+	npiv_max_sectors = min((uint)(rsp->max_dma_len >> 9), IBMVFC_MAX_SECTORS);
+	dev_info(vhost->dev, "Host partition: %s, device: %s %s %s max sectors %u\n",
+		 rsp->partition_name, rsp->device_name, rsp->port_loc_code,
+		 rsp->drc_name, npiv_max_sectors);
+
+	fc_host_fabric_name(vhost->host) = rsp->node_name;
+	fc_host_node_name(vhost->host) = rsp->node_name;
+	fc_host_port_name(vhost->host) = rsp->port_name;
+	fc_host_port_id(vhost->host) = rsp->scsi_id;
+	fc_host_port_type(vhost->host) = FC_PORTTYPE_NPIV;
+	fc_host_supported_classes(vhost->host) = 0;
+	if (rsp->service_parms.class1_parms[0] & 0x80000000)
+		fc_host_supported_classes(vhost->host) |= FC_COS_CLASS1;
+	if (rsp->service_parms.class2_parms[0] & 0x80000000)
+		fc_host_supported_classes(vhost->host) |= FC_COS_CLASS2;
+	if (rsp->service_parms.class3_parms[0] & 0x80000000)
+		fc_host_supported_classes(vhost->host) |= FC_COS_CLASS3;
+	fc_host_maxframe_size(vhost->host) =
+		rsp->service_parms.common.bb_rcv_sz & 0x0fff;
+
+	vhost->host->can_queue = rsp->max_cmds - IBMVFC_NUM_INTERNAL_REQ;
+	vhost->host->max_sectors = npiv_max_sectors;
+	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
+	wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_npiv_login - Sends NPIV login
+ * @vhost:	ibmvfc host struct
+ *
+ **/
+static void ibmvfc_npiv_login(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_npiv_login_mad *mad;
+	struct ibmvfc_event *evt = ibmvfc_get_event(vhost);
+
+	ibmvfc_gather_partition_info(vhost);
+	ibmvfc_set_login_info(vhost);
+	ibmvfc_init_event(evt, ibmvfc_npiv_login_done, IBMVFC_MAD_FORMAT);
+
+	memcpy(vhost->login_buf, &vhost->login_info, sizeof(vhost->login_info));
+	mad = &evt->iu.npiv_login;
+	memset(mad, 0, sizeof(struct ibmvfc_npiv_login_mad));
+	mad->common.version = 1;
+	mad->common.opcode = IBMVFC_NPIV_LOGIN;
+	mad->common.length = sizeof(struct ibmvfc_npiv_login_mad);
+	mad->buffer.va = vhost->login_buf_dma;
+	mad->buffer.len = sizeof(*vhost->login_buf);
+
+	memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
+	vhost->async_crq.cur = 0;
+	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
+
+	if (!ibmvfc_send_event(evt, vhost, default_timeout))
+		ibmvfc_dbg(vhost, "Sent NPIV login\n");
+	else
+		ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
+};
+
+/**
+ * ibmvfc_dev_init_to_do - Is there target initialization work to do?
+ * @vhost:		ibmvfc host struct
+ *
+ * Returns:
+ *	1 if work to do / 0 if not
+ **/
+static int ibmvfc_dev_init_to_do(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_target *tgt;
+
+	list_for_each_entry(tgt, &vhost->targets, queue) {
+		if (tgt->action == IBMVFC_TGT_ACTION_INIT ||
+		    tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT)
+			return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * __ibmvfc_work_to_do - Is there task level work to do? (no locking)
+ * @vhost:		ibmvfc host struct
+ *
+ * Returns:
+ *	1 if work to do / 0 if not
+ **/
+static int __ibmvfc_work_to_do(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_target *tgt;
+
+	if (kthread_should_stop())
+		return 1;
+	switch (vhost->action) {
+	case IBMVFC_HOST_ACTION_NONE:
+	case IBMVFC_HOST_ACTION_INIT_WAIT:
+		return 0;
+	case IBMVFC_HOST_ACTION_TGT_INIT:
+	case IBMVFC_HOST_ACTION_QUERY_TGTS:
+		if (vhost->discovery_threads == disc_threads)
+			return 0;
+		list_for_each_entry(tgt, &vhost->targets, queue)
+			if (tgt->action == IBMVFC_TGT_ACTION_INIT)
+				return 1;
+		list_for_each_entry(tgt, &vhost->targets, queue)
+			if (tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT)
+				return 0;
+		return 1;
+	case IBMVFC_HOST_ACTION_INIT:
+	case IBMVFC_HOST_ACTION_ALLOC_TGTS:
+	case IBMVFC_HOST_ACTION_TGT_ADD:
+	case IBMVFC_HOST_ACTION_TGT_DEL:
+	case IBMVFC_HOST_ACTION_QUERY:
+	default:
+		break;
+	};
+
+	return 1;
+}
+
+/**
+ * ibmvfc_work_to_do - Is there task level work to do?
+ * @vhost:		ibmvfc host struct
+ *
+ * Returns:
+ *	1 if work to do / 0 if not
+ **/
+static int ibmvfc_work_to_do(struct ibmvfc_host *vhost)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	rc = __ibmvfc_work_to_do(vhost);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+	return rc;
+}
+
+/**
+ * ibmvfc_log_ae - Log async events if necessary
+ * @vhost:		ibmvfc host struct
+ * @events:		events to log
+ *
+ **/
+static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int events)
+{
+	if (events & IBMVFC_AE_RSCN)
+		fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_RSCN, 0);
+	if ((events & IBMVFC_AE_LINKDOWN) &&
+	    vhost->state >= IBMVFC_HALTED)
+		fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
+	if ((events & IBMVFC_AE_LINKUP) &&
+	    vhost->state == IBMVFC_INITIALIZING)
+		fc_host_post_event(vhost->host, fc_get_event_number(), FCH_EVT_LINKUP, 0);
+}
+
+/**
+ * ibmvfc_tgt_add_rport - Tell the FC transport about a new remote port
+ * @tgt:		ibmvfc target struct
+ *
+ **/
+static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
+{
+	struct ibmvfc_host *vhost = tgt->vhost;
+	struct fc_rport *rport;
+	unsigned long flags;
+
+	tgt_dbg(tgt, "Adding rport\n");
+	rport = fc_remote_port_add(vhost->host, 0, &tgt->ids);
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	tgt->rport = rport;
+	ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+	if (rport) {
+		tgt_dbg(tgt, "rport add succeeded\n");
+		rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff;
+		rport->supported_classes = 0;
+		if (tgt->service_parms.class1_parms[0] & 0x80000000)
+			rport->supported_classes |= FC_COS_CLASS1;
+		if (tgt->service_parms.class2_parms[0] & 0x80000000)
+			rport->supported_classes |= FC_COS_CLASS2;
+		if (tgt->service_parms.class3_parms[0] & 0x80000000)
+			rport->supported_classes |= FC_COS_CLASS3;
+	} else
+		tgt_dbg(tgt, "rport add failed\n");
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
+/**
+ * ibmvfc_do_work - Do task level work
+ * @vhost:		ibmvfc host struct
+ *
+ **/
+static void ibmvfc_do_work(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_target *tgt;
+	unsigned long flags;
+	struct fc_rport *rport;
+
+	ibmvfc_log_ae(vhost, vhost->events_to_log);
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	vhost->events_to_log = 0;
+	switch (vhost->action) {
+	case IBMVFC_HOST_ACTION_NONE:
+	case IBMVFC_HOST_ACTION_INIT_WAIT:
+		break;
+	case IBMVFC_HOST_ACTION_INIT:
+		BUG_ON(vhost->state != IBMVFC_INITIALIZING);
+		vhost->job_step(vhost);
+		break;
+	case IBMVFC_HOST_ACTION_QUERY:
+		list_for_each_entry(tgt, &vhost->targets, queue)
+			ibmvfc_init_tgt(tgt, ibmvfc_tgt_query_target);
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY_TGTS);
+		break;
+	case IBMVFC_HOST_ACTION_QUERY_TGTS:
+		list_for_each_entry(tgt, &vhost->targets, queue) {
+			if (tgt->action == IBMVFC_TGT_ACTION_INIT) {
+				tgt->job_step(tgt);
+				break;
+			}
+		}
+
+		if (!ibmvfc_dev_init_to_do(vhost))
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL);
+		break;
+	case IBMVFC_HOST_ACTION_TGT_DEL:
+		list_for_each_entry(tgt, &vhost->targets, queue) {
+			if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
+				tgt_dbg(tgt, "Deleting rport\n");
+				rport = tgt->rport;
+				tgt->rport = NULL;
+				list_del(&tgt->queue);
+				spin_unlock_irqrestore(vhost->host->host_lock, flags);
+				if (rport)
+					fc_remote_port_delete(rport);
+				kref_put(&tgt->kref, ibmvfc_release_tgt);
+				return;
+			}
+		}
+
+		if (vhost->state == IBMVFC_INITIALIZING) {
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+			vhost->job_step = ibmvfc_discover_targets;
+		} else {
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
+			spin_unlock_irqrestore(vhost->host->host_lock, flags);
+			scsi_unblock_requests(vhost->host);
+			wake_up(&vhost->init_wait_q);
+			return;
+		}
+		break;
+	case IBMVFC_HOST_ACTION_ALLOC_TGTS:
+		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_INIT);
+		spin_unlock_irqrestore(vhost->host->host_lock, flags);
+		ibmvfc_alloc_targets(vhost);
+		spin_lock_irqsave(vhost->host->host_lock, flags);
+		break;
+	case IBMVFC_HOST_ACTION_TGT_INIT:
+		list_for_each_entry(tgt, &vhost->targets, queue) {
+			if (tgt->action == IBMVFC_TGT_ACTION_INIT) {
+				tgt->job_step(tgt);
+				break;
+			}
+		}
+
+		if (!ibmvfc_dev_init_to_do(vhost)) {
+			ibmvfc_set_host_state(vhost, IBMVFC_ACTIVE);
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_ADD);
+			vhost->init_retries = 0;
+			spin_unlock_irqrestore(vhost->host->host_lock, flags);
+			scsi_unblock_requests(vhost->host);
+			return;
+		}
+		break;
+	case IBMVFC_HOST_ACTION_TGT_ADD:
+		list_for_each_entry(tgt, &vhost->targets, queue) {
+			if (tgt->action == IBMVFC_TGT_ACTION_ADD_RPORT) {
+				spin_unlock_irqrestore(vhost->host->host_lock, flags);
+				ibmvfc_tgt_add_rport(tgt);
+				return;
+			} else if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
+				tgt_dbg(tgt, "Deleting rport\n");
+				rport = tgt->rport;
+				tgt->rport = NULL;
+				list_del(&tgt->queue);
+				spin_unlock_irqrestore(vhost->host->host_lock, flags);
+				if (rport)
+					fc_remote_port_delete(rport);
+				kref_put(&tgt->kref, ibmvfc_release_tgt);
+				return;
+			}
+		}
+
+		if (vhost->reinit) {
+			vhost->reinit = 0;
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
+		} else {
+			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
+			wake_up(&vhost->init_wait_q);
+		}
+		break;
+	default:
+		break;
+	};
+
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
+/**
+ * ibmvfc_work - Do task level work
+ * @data:		ibmvfc host struct
+ *
+ * Returns:
+ *	zero
+ **/
+static int ibmvfc_work(void *data)
+{
+	struct ibmvfc_host *vhost = data;
+	int rc;
+
+	set_user_nice(current, -20);
+
+	while (1) {
+		rc = wait_event_interruptible(vhost->work_wait_q,
+					      ibmvfc_work_to_do(vhost));
+
+		BUG_ON(rc);
+
+		if (kthread_should_stop())
+			break;
+
+		ibmvfc_do_work(vhost);
+	}
+
+	ibmvfc_dbg(vhost, "ibmvfc kthread exiting...\n");
+	return 0;
+}
+
+/**
+ * ibmvfc_init_crq - Initializes and registers CRQ with hypervisor
+ * @vhost:	ibmvfc host struct
+ *
+ * Allocates a page for messages, maps it for dma, and registers
+ * the crq with the hypervisor.
+ *
+ * Return value:
+ *	zero on success / other on failure
+ **/
+static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
+{
+	int rc, retrc = -ENOMEM;
+	struct device *dev = vhost->dev;
+	struct vio_dev *vdev = to_vio_dev(dev);
+	struct ibmvfc_crq_queue *crq = &vhost->crq;
+
+	ENTER;
+	crq->msgs = (struct ibmvfc_crq *)get_zeroed_page(GFP_KERNEL);
+
+	if (!crq->msgs)
+		return -ENOMEM;
+
+	crq->size = PAGE_SIZE / sizeof(*crq->msgs);
+	crq->msg_token = dma_map_single(dev, crq->msgs,
+					PAGE_SIZE, DMA_BIDIRECTIONAL);
+
+	if (dma_mapping_error(crq->msg_token))
+		goto map_failed;
+
+	retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
+					crq->msg_token, PAGE_SIZE);
+
+	if (rc == H_RESOURCE)
+		/* maybe kexecing and resource is busy. try a reset */
+		retrc = rc = ibmvfc_reset_crq(vhost);
+
+	if (rc == H_CLOSED)
+		dev_warn(dev, "Partner adapter not ready\n");
+	else if (rc) {
+		dev_warn(dev, "Error %d opening adapter\n", rc);
+		goto reg_crq_failed;
+	}
+
+	retrc = 0;
+
+	if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
+		dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
+		goto req_irq_failed;
+	}
+
+	if ((rc = vio_enable_interrupts(vdev))) {
+		dev_err(dev, "Error %d enabling interrupts\n", rc);
+		goto req_irq_failed;
+	}
+
+	crq->cur = 0;
+	LEAVE;
+	return retrc;
+
+req_irq_failed:
+	do {
+		rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
+	} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
+reg_crq_failed:
+	dma_unmap_single(dev, crq->msg_token, PAGE_SIZE, DMA_BIDIRECTIONAL);
+map_failed:
+	free_page((unsigned long)crq->msgs);
+	return retrc;
+}
+
+/**
+ * ibmvfc_free_mem - Free memory for vhost
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ * 	none
+ **/
+static void ibmvfc_free_mem(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_async_crq_queue *async_q = &vhost->async_crq;
+
+	ENTER;
+	mempool_destroy(vhost->tgt_pool);
+	kfree(vhost->trace);
+	dma_free_coherent(vhost->dev, vhost->disc_buf_sz, vhost->disc_buf,
+			  vhost->disc_buf_dma);
+	dma_free_coherent(vhost->dev, sizeof(*vhost->login_buf),
+			  vhost->login_buf, vhost->login_buf_dma);
+	dma_pool_destroy(vhost->sg_pool);
+	dma_unmap_single(vhost->dev, async_q->msg_token,
+			 async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL);
+	free_page((unsigned long)async_q->msgs);
+	LEAVE;
+}
+
+/**
+ * ibmvfc_alloc_mem - Allocate memory for vhost
+ * @vhost:	ibmvfc host struct
+ *
+ * Return value:
+ * 	0 on success / non-zero on failure
+ **/
+static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost)
+{
+	struct ibmvfc_async_crq_queue *async_q = &vhost->async_crq;
+	struct device *dev = vhost->dev;
+
+	ENTER;
+	async_q->msgs = (struct ibmvfc_async_crq *)get_zeroed_page(GFP_KERNEL);
+	if (!async_q->msgs) {
+		dev_err(dev, "Couldn't allocate async queue.\n");
+		goto nomem;
+	}
+
+	async_q->size = PAGE_SIZE / sizeof(struct ibmvfc_async_crq);
+	async_q->msg_token = dma_map_single(dev, async_q->msgs,
+					    async_q->size * sizeof(*async_q->msgs),
+					    DMA_BIDIRECTIONAL);
+
+	if (dma_mapping_error(async_q->msg_token)) {
+		dev_err(dev, "Failed to map async queue\n");
+		goto free_async_crq;
+	}
+
+	vhost->sg_pool = dma_pool_create(IBMVFC_NAME, dev,
+					 SG_ALL * sizeof(struct srp_direct_buf),
+					 sizeof(struct srp_direct_buf), 0);
+
+	if (!vhost->sg_pool) {
+		dev_err(dev, "Failed to allocate sg pool\n");
+		goto unmap_async_crq;
+	}
+
+	vhost->login_buf = dma_alloc_coherent(dev, sizeof(*vhost->login_buf),
+					      &vhost->login_buf_dma, GFP_KERNEL);
+
+	if (!vhost->login_buf) {
+		dev_err(dev, "Couldn't allocate NPIV login buffer\n");
+		goto free_sg_pool;
+	}
+
+	vhost->disc_buf_sz = sizeof(vhost->disc_buf->scsi_id[0]) * max_targets;
+	vhost->disc_buf = dma_alloc_coherent(dev, vhost->disc_buf_sz,
+					     &vhost->disc_buf_dma, GFP_KERNEL);
+
+	if (!vhost->disc_buf) {
+		dev_err(dev, "Couldn't allocate Discover Targets buffer\n");
+		goto free_login_buffer;
+	}
+
+	vhost->trace = kcalloc(IBMVFC_NUM_TRACE_ENTRIES,
+			       sizeof(struct ibmvfc_trace_entry), GFP_KERNEL);
+
+	if (!vhost->trace)
+		goto free_disc_buffer;
+
+	vhost->tgt_pool = mempool_create_kzalloc_pool(IBMVFC_TGT_MEMPOOL_SZ,
+						      sizeof(struct ibmvfc_target));
+
+	if (!vhost->tgt_pool) {
+		dev_err(dev, "Couldn't allocate target memory pool\n");
+		goto free_trace;
+	}
+
+	LEAVE;
+	return 0;
+
+free_trace:
+	kfree(vhost->trace);
+free_disc_buffer:
+	dma_free_coherent(dev, vhost->disc_buf_sz, vhost->disc_buf,
+			  vhost->disc_buf_dma);
+free_login_buffer:
+	dma_free_coherent(dev, sizeof(*vhost->login_buf),
+			  vhost->login_buf, vhost->login_buf_dma);
+free_sg_pool:
+	dma_pool_destroy(vhost->sg_pool);
+unmap_async_crq:
+	dma_unmap_single(dev, async_q->msg_token,
+			 async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL);
+free_async_crq:
+	free_page((unsigned long)async_q->msgs);
+nomem:
+	LEAVE;
+	return -ENOMEM;
+}
+
+/**
+ * ibmvfc_probe - Adapter hot plug add entry point
+ * @vdev:	vio device struct
+ * @id:	vio device id struct
+ *
+ * Return value:
+ * 	0 on success / non-zero on failure
+ **/
+static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
+{
+	struct ibmvfc_host *vhost;
+	struct Scsi_Host *shost;
+	struct device *dev = &vdev->dev;
+	int rc = -ENOMEM;
+
+	ENTER;
+	shost = scsi_host_alloc(&driver_template, sizeof(*vhost));
+	if (!shost) {
+		dev_err(dev, "Couldn't allocate host data\n");
+		goto out;
+	}
+
+	shost->transportt = ibmvfc_transport_template;
+	shost->can_queue = max_requests;
+	shost->max_lun = max_lun;
+	shost->max_id = max_targets;
+	shost->max_sectors = IBMVFC_MAX_SECTORS;
+	shost->max_cmd_len = IBMVFC_MAX_CDB_LEN;
+	shost->unique_id = shost->host_no;
+
+	vhost = shost_priv(shost);
+	INIT_LIST_HEAD(&vhost->sent);
+	INIT_LIST_HEAD(&vhost->free);
+	INIT_LIST_HEAD(&vhost->targets);
+	sprintf(vhost->name, IBMVFC_NAME);
+	vhost->host = shost;
+	vhost->dev = dev;
+	vhost->partition_number = -1;
+	vhost->log_level = log_level;
+	strcpy(vhost->partition_name, "UNKNOWN");
+	init_waitqueue_head(&vhost->work_wait_q);
+	init_waitqueue_head(&vhost->init_wait_q);
+
+	if ((rc = ibmvfc_alloc_mem(vhost)))
+		goto free_scsi_host;
+
+	vhost->work_thread = kthread_run(ibmvfc_work, vhost, "%s_%d", IBMVFC_NAME,
+					 shost->host_no);
+
+	if (IS_ERR(vhost->work_thread)) {
+		dev_err(dev, "Couldn't create kernel thread: %ld\n",
+			PTR_ERR(vhost->work_thread));
+		goto free_host_mem;
+	}
+
+	if ((rc = ibmvfc_init_crq(vhost))) {
+		dev_err(dev, "Couldn't initialize crq. rc=%d\n", rc);
+		goto kill_kthread;
+	}
+
+	if ((rc = ibmvfc_init_event_pool(vhost))) {
+		dev_err(dev, "Couldn't initialize event pool. rc=%d\n", rc);
+		goto release_crq;
+	}
+
+	if ((rc = scsi_add_host(shost, dev)))
+		goto release_event_pool;
+
+	if ((rc = ibmvfc_create_trace_file(&shost->shost_dev.kobj,
+					   &ibmvfc_trace_attr))) {
+		dev_err(dev, "Failed to create trace file. rc=%d\n", rc);
+		goto remove_shost;
+	}
+
+	dev_set_drvdata(dev, vhost);
+	spin_lock(&ibmvfc_driver_lock);
+	list_add_tail(&vhost->queue, &ibmvfc_head);
+	spin_unlock(&ibmvfc_driver_lock);
+
+	ibmvfc_send_crq_init(vhost);
+	scsi_scan_host(shost);
+	return 0;
+
+remove_shost:
+	scsi_remove_host(shost);
+release_event_pool:
+	ibmvfc_free_event_pool(vhost);
+release_crq:
+	ibmvfc_release_crq_queue(vhost);
+kill_kthread:
+	kthread_stop(vhost->work_thread);
+free_host_mem:
+	ibmvfc_free_mem(vhost);
+free_scsi_host:
+	scsi_host_put(shost);
+out:
+	LEAVE;
+	return rc;
+}
+
+/**
+ * ibmvfc_remove - Adapter hot plug remove entry point
+ * @vdev:	vio device struct
+ *
+ * Return value:
+ * 	0
+ **/
+static int ibmvfc_remove(struct vio_dev *vdev)
+{
+	struct ibmvfc_host *vhost = dev_get_drvdata(&vdev->dev);
+	unsigned long flags;
+
+	ENTER;
+	ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
+	kthread_stop(vhost->work_thread);
+	fc_remove_host(vhost->host);
+	scsi_remove_host(vhost->host);
+	ibmvfc_release_crq_queue(vhost);
+
+	spin_lock_irqsave(vhost->host->host_lock, flags);
+	ibmvfc_purge_requests(vhost, DID_ERROR);
+	ibmvfc_free_event_pool(vhost);
+	spin_unlock_irqrestore(vhost->host->host_lock, flags);
+
+	ibmvfc_free_mem(vhost);
+	spin_lock(&ibmvfc_driver_lock);
+	list_del(&vhost->queue);
+	spin_unlock(&ibmvfc_driver_lock);
+	scsi_host_put(vhost->host);
+	LEAVE;
+	return 0;
+}
+
+static struct vio_device_id ibmvfc_device_table[] __devinitdata = {
+	{"fcp", "IBM,vfc-client"},
+	{ "", "" }
+};
+MODULE_DEVICE_TABLE(vio, ibmvfc_device_table);
+
+static struct vio_driver ibmvfc_driver = {
+	.id_table = ibmvfc_device_table,
+	.probe = ibmvfc_probe,
+	.remove = ibmvfc_remove,
+	.driver = {
+		.name = IBMVFC_NAME,
+		.owner = THIS_MODULE,
+	}
+};
+
+static struct fc_function_template ibmvfc_transport_functions = {
+	.show_host_fabric_name = 1,
+	.show_host_node_name = 1,
+	.show_host_port_name = 1,
+	.show_host_supported_classes = 1,
+	.show_host_port_type = 1,
+	.show_host_port_id = 1,
+
+	.get_host_port_state = ibmvfc_get_host_port_state,
+	.show_host_port_state = 1,
+
+	.get_host_speed = ibmvfc_get_host_speed,
+	.show_host_speed = 1,
+
+	.issue_fc_host_lip = ibmvfc_issue_fc_host_lip,
+	.terminate_rport_io = ibmvfc_terminate_rport_io,
+
+	.show_rport_maxframe_size = 1,
+	.show_rport_supported_classes = 1,
+
+	.set_rport_dev_loss_tmo = ibmvfc_set_rport_dev_loss_tmo,
+	.show_rport_dev_loss_tmo = 1,
+
+	.get_starget_node_name = ibmvfc_get_starget_node_name,
+	.show_starget_node_name = 1,
+
+	.get_starget_port_name = ibmvfc_get_starget_port_name,
+	.show_starget_port_name = 1,
+
+	.get_starget_port_id = ibmvfc_get_starget_port_id,
+	.show_starget_port_id = 1,
+};
+
+/**
+ * ibmvfc_module_init - Initialize the ibmvfc module
+ *
+ * Return value:
+ * 	0 on success / other on failure
+ **/
+static int __init ibmvfc_module_init(void)
+{
+	int rc;
+
+	if (!firmware_has_feature(FW_FEATURE_VIO))
+		return -ENODEV;
+
+	printk(KERN_INFO IBMVFC_NAME": IBM Virtual Fibre Channel Driver version: %s %s\n",
+	       IBMVFC_DRIVER_VERSION, IBMVFC_DRIVER_DATE);
+
+	ibmvfc_transport_template = fc_attach_transport(&ibmvfc_transport_functions);
+	if (!ibmvfc_transport_template)
+		return -ENOMEM;
+
+	rc = vio_register_driver(&ibmvfc_driver);
+	if (rc)
+		fc_release_transport(ibmvfc_transport_template);
+	return rc;
+}
+
+/**
+ * ibmvfc_module_exit - Teardown the ibmvfc module
+ *
+ * Return value:
+ * 	nothing
+ **/
+static void __exit ibmvfc_module_exit(void)
+{
+	vio_unregister_driver(&ibmvfc_driver);
+	fc_release_transport(ibmvfc_transport_template);
+}
+
+module_init(ibmvfc_module_init);
+module_exit(ibmvfc_module_exit);
