/*
 * Copyright (c) 2005 Cisco Systems.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/parser.h>
#include <linux/random.h>
#include <linux/jiffies.h>

#include <asm/atomic.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_dbg.h>
#include <scsi/srp.h>

#include <rdma/ib_cache.h>

#include "ib_srp.h"

#define DRV_NAME	"ib_srp"
#define PFX		DRV_NAME ": "
#define DRV_VERSION	"0.2"
#define DRV_RELDATE	"November 1, 2005"

MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator "
		   "v" DRV_VERSION " (" DRV_RELDATE ")");
MODULE_LICENSE("Dual BSD/GPL");

static int topspin_workarounds = 1;

module_param(topspin_workarounds, int, 0444);
MODULE_PARM_DESC(topspin_workarounds,
		 "Enable workarounds for Topspin/Cisco SRP target bugs if != 0");

static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };

static void srp_add_one(struct ib_device *device);
static void srp_remove_one(struct ib_device *device);
static void srp_completion(struct ib_cq *cq, void *target_ptr);
static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);

static struct ib_client srp_client = {
	.name   = "srp",
	.add    = srp_add_one,
	.remove = srp_remove_one
};

static inline struct srp_target_port *host_to_target(struct Scsi_Host *host)
{
	return (struct srp_target_port *) host->hostdata;
}

static const char *srp_target_info(struct Scsi_Host *host)
{
	return host_to_target(host)->target_name;
}

static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
				   gfp_t gfp_mask,
				   enum dma_data_direction direction)
{
	struct srp_iu *iu;

	iu = kmalloc(sizeof *iu, gfp_mask);
	if (!iu)
		goto out;

	iu->buf = kzalloc(size, gfp_mask);
	if (!iu->buf)
		goto out_free_iu;

	iu->dma = dma_map_single(host->dev->dma_device, iu->buf, size, direction);
	if (dma_mapping_error(iu->dma))
		goto out_free_buf;

	iu->size      = size;
	iu->direction = direction;

	return iu;

out_free_buf:
	kfree(iu->buf);
out_free_iu:
	kfree(iu);
out:
	return NULL;
}

static void srp_free_iu(struct srp_host *host, struct srp_iu *iu)
{
	if (!iu)
		return;

	dma_unmap_single(host->dev->dma_device, iu->dma, iu->size, iu->direction);
	kfree(iu->buf);
	kfree(iu);
}

static void srp_qp_event(struct ib_event *event, void *context)
{
	printk(KERN_ERR PFX "QP event %d\n", event->event);
}

static int srp_init_qp(struct srp_target_port *target,
		       struct ib_qp *qp)
{
	struct ib_qp_attr *attr;
	int ret;

	attr = kmalloc(sizeof *attr, GFP_KERNEL);
	if (!attr)
		return -ENOMEM;

	ret = ib_find_cached_pkey(target->srp_host->dev,
				  target->srp_host->port,
				  be16_to_cpu(target->path.pkey),
				  &attr->pkey_index);
	if (ret)
		goto out;

	attr->qp_state        = IB_QPS_INIT;
	attr->qp_access_flags = (IB_ACCESS_REMOTE_READ |
				    IB_ACCESS_REMOTE_WRITE);
	attr->port_num        = target->srp_host->port;

	ret = ib_modify_qp(qp, attr,
			   IB_QP_STATE		|
			   IB_QP_PKEY_INDEX	|
			   IB_QP_ACCESS_FLAGS	|
			   IB_QP_PORT);

out:
	kfree(attr);
	return ret;
}

static int srp_create_target_ib(struct srp_target_port *target)
{
	struct ib_qp_init_attr *init_attr;
	int ret;

	init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL);
	if (!init_attr)
		return -ENOMEM;

	target->cq = ib_create_cq(target->srp_host->dev, srp_completion,
				  NULL, target, SRP_CQ_SIZE);
	if (IS_ERR(target->cq)) {
		ret = PTR_ERR(target->cq);
		goto out;
	}

	ib_req_notify_cq(target->cq, IB_CQ_NEXT_COMP);

	init_attr->event_handler       = srp_qp_event;
	init_attr->cap.max_send_wr     = SRP_SQ_SIZE;
	init_attr->cap.max_recv_wr     = SRP_RQ_SIZE;
	init_attr->cap.max_recv_sge    = 1;
	init_attr->cap.max_send_sge    = 1;
	init_attr->sq_sig_type         = IB_SIGNAL_ALL_WR;
	init_attr->qp_type             = IB_QPT_RC;
	init_attr->send_cq             = target->cq;
	init_attr->recv_cq             = target->cq;

	target->qp = ib_create_qp(target->srp_host->pd, init_attr);
	if (IS_ERR(target->qp)) {
		ret = PTR_ERR(target->qp);
		ib_destroy_cq(target->cq);
		goto out;
	}

	ret = srp_init_qp(target, target->qp);
	if (ret) {
		ib_destroy_qp(target->qp);
		ib_destroy_cq(target->cq);
		goto out;
	}

out:
	kfree(init_attr);
	return ret;
}

static void srp_free_target_ib(struct srp_target_port *target)
{
	int i;

	ib_destroy_qp(target->qp);
	ib_destroy_cq(target->cq);

	for (i = 0; i < SRP_RQ_SIZE; ++i)
		srp_free_iu(target->srp_host, target->rx_ring[i]);
	for (i = 0; i < SRP_SQ_SIZE + 1; ++i)
		srp_free_iu(target->srp_host, target->tx_ring[i]);
}

static void srp_path_rec_completion(int status,
				    struct ib_sa_path_rec *pathrec,
				    void *target_ptr)
{
	struct srp_target_port *target = target_ptr;

	target->status = status;
	if (status)
		printk(KERN_ERR PFX "Got failed path rec status %d\n", status);
	else
		target->path = *pathrec;
	complete(&target->done);
}

static int srp_lookup_path(struct srp_target_port *target)
{
	target->path.numb_path = 1;

	init_completion(&target->done);

	target->path_query_id = ib_sa_path_rec_get(target->srp_host->dev,
						   target->srp_host->port,
						   &target->path,
						   IB_SA_PATH_REC_DGID		|
						   IB_SA_PATH_REC_SGID		|
						   IB_SA_PATH_REC_NUMB_PATH	|
						   IB_SA_PATH_REC_PKEY,
						   SRP_PATH_REC_TIMEOUT_MS,
						   GFP_KERNEL,
						   srp_path_rec_completion,
						   target, &target->path_query);
	if (target->path_query_id < 0)
		return target->path_query_id;

	wait_for_completion(&target->done);

	if (target->status < 0)
		printk(KERN_WARNING PFX "Path record query failed\n");

	return target->status;
}

static int srp_send_req(struct srp_target_port *target)
{
	struct {
		struct ib_cm_req_param param;
		struct srp_login_req   priv;
	} *req = NULL;
	int status;

	req = kzalloc(sizeof *req, GFP_KERNEL);
	if (!req)
		return -ENOMEM;

	req->param.primary_path 	      = &target->path;
	req->param.alternate_path 	      = NULL;
	req->param.service_id 		      = target->service_id;
	req->param.qp_num 		      = target->qp->qp_num;
	req->param.qp_type 		      = target->qp->qp_type;
	req->param.private_data 	      = &req->priv;
	req->param.private_data_len 	      = sizeof req->priv;
	req->param.flow_control 	      = 1;

	get_random_bytes(&req->param.starting_psn, 4);
	req->param.starting_psn 	     &= 0xffffff;

	/*
	 * Pick some arbitrary defaults here; we could make these
	 * module parameters if anyone cared about setting them.
	 */
	req->param.responder_resources	      = 4;
	req->param.remote_cm_response_timeout = 20;
	req->param.local_cm_response_timeout  = 20;
	req->param.retry_count 		      = 7;
	req->param.rnr_retry_count 	      = 7;
	req->param.max_cm_retries 	      = 15;

	req->priv.opcode     	= SRP_LOGIN_REQ;
	req->priv.tag        	= 0;
	req->priv.req_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);
	req->priv.req_buf_fmt 	= cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
					      SRP_BUF_FORMAT_INDIRECT);
	memcpy(req->priv.initiator_port_id, target->srp_host->initiator_port_id, 16);
	/*
	 * Topspin/Cisco SRP targets will reject our login unless we
	 * zero out the first 8 bytes of our initiator port ID.  The
	 * second 8 bytes must be our local node GUID, but we always
	 * use that anyway.
	 */
	if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
		printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
		       "activated for target GUID %016llx\n",
		       (unsigned long long) be64_to_cpu(target->ioc_guid));
		memset(req->priv.initiator_port_id, 0, 8);
	}
	memcpy(req->priv.target_port_id,     &target->id_ext, 8);
	memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);

	status = ib_send_cm_req(target->cm_id, &req->param);

	kfree(req);

	return status;
}

static void srp_disconnect_target(struct srp_target_port *target)
{
	/* XXX should send SRP_I_LOGOUT request */

	init_completion(&target->done);
	ib_send_cm_dreq(target->cm_id, NULL, 0);
	wait_for_completion(&target->done);
}

static void srp_remove_work(void *target_ptr)
{
	struct srp_target_port *target = target_ptr;

	spin_lock_irq(target->scsi_host->host_lock);
	if (target->state != SRP_TARGET_DEAD) {
		spin_unlock_irq(target->scsi_host->host_lock);
		scsi_host_put(target->scsi_host);
		return;
	}
	target->state = SRP_TARGET_REMOVED;
	spin_unlock_irq(target->scsi_host->host_lock);

	mutex_lock(&target->srp_host->target_mutex);
	list_del(&target->list);
	mutex_unlock(&target->srp_host->target_mutex);

	scsi_remove_host(target->scsi_host);
	ib_destroy_cm_id(target->cm_id);
	srp_free_target_ib(target);
	scsi_host_put(target->scsi_host);
	/* And another put to really free the target port... */
	scsi_host_put(target->scsi_host);
}

static int srp_connect_target(struct srp_target_port *target)
{
	int ret;

	ret = srp_lookup_path(target);
	if (ret)
		return ret;

	while (1) {
		init_completion(&target->done);
		ret = srp_send_req(target);
		if (ret)
			return ret;
		wait_for_completion(&target->done);

		/*
		 * The CM event handling code will set status to
		 * SRP_PORT_REDIRECT if we get a port redirect REJ
		 * back, or SRP_DLID_REDIRECT if we get a lid/qp
		 * redirect REJ back.
		 */
		switch (target->status) {
		case 0:
			return 0;

		case SRP_PORT_REDIRECT:
			ret = srp_lookup_path(target);
			if (ret)
				return ret;
			break;

		case SRP_DLID_REDIRECT:
			break;

		default:
			return target->status;
		}
	}
}

static int srp_reconnect_target(struct srp_target_port *target)
{
	struct ib_cm_id *new_cm_id;
	struct ib_qp_attr qp_attr;
	struct srp_request *req;
	struct ib_wc wc;
	int ret;
	int i;

	spin_lock_irq(target->scsi_host->host_lock);
	if (target->state != SRP_TARGET_LIVE) {
		spin_unlock_irq(target->scsi_host->host_lock);
		return -EAGAIN;
	}
	target->state = SRP_TARGET_CONNECTING;
	spin_unlock_irq(target->scsi_host->host_lock);

	srp_disconnect_target(target);
	/*
	 * Now get a new local CM ID so that we avoid confusing the
	 * target in case things are really fouled up.
	 */
	new_cm_id = ib_create_cm_id(target->srp_host->dev,
				    srp_cm_handler, target);
	if (IS_ERR(new_cm_id)) {
		ret = PTR_ERR(new_cm_id);
		goto err;
	}
	ib_destroy_cm_id(target->cm_id);
	target->cm_id = new_cm_id;

	qp_attr.qp_state = IB_QPS_RESET;
	ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE);
	if (ret)
		goto err;

	ret = srp_init_qp(target, target->qp);
	if (ret)
		goto err;

	while (ib_poll_cq(target->cq, 1, &wc) > 0)
		; /* nothing */

	list_for_each_entry(req, &target->req_queue, list) {
		req->scmnd->result = DID_RESET << 16;
		req->scmnd->scsi_done(req->scmnd);
	}

	target->rx_head	 = 0;
	target->tx_head	 = 0;
	target->tx_tail  = 0;
	target->req_head = 0;
	for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
		target->req_ring[i].next = i + 1;
	target->req_ring[SRP_SQ_SIZE - 1].next = -1;
	INIT_LIST_HEAD(&target->req_queue);

	ret = srp_connect_target(target);
	if (ret)
		goto err;

	spin_lock_irq(target->scsi_host->host_lock);
	if (target->state == SRP_TARGET_CONNECTING) {
		ret = 0;
		target->state = SRP_TARGET_LIVE;
	} else
		ret = -EAGAIN;
	spin_unlock_irq(target->scsi_host->host_lock);

	return ret;

err:
	printk(KERN_ERR PFX "reconnect failed (%d), removing target port.\n", ret);

	/*
	 * We couldn't reconnect, so kill our target port off.
	 * However, we have to defer the real removal because we might
	 * be in the context of the SCSI error handler now, which
	 * would deadlock if we call scsi_remove_host().
	 */
	spin_lock_irq(target->scsi_host->host_lock);
	if (target->state == SRP_TARGET_CONNECTING) {
		target->state = SRP_TARGET_DEAD;
		INIT_WORK(&target->work, srp_remove_work, target);
		schedule_work(&target->work);
	}
	spin_unlock_irq(target->scsi_host->host_lock);

	return ret;
}

static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
			struct srp_request *req)
{
	struct srp_cmd *cmd = req->cmd->buf;
	int len;
	u8 fmt;

	if (!scmnd->request_buffer || scmnd->sc_data_direction == DMA_NONE)
		return sizeof (struct srp_cmd);

	if (scmnd->sc_data_direction != DMA_FROM_DEVICE &&
	    scmnd->sc_data_direction != DMA_TO_DEVICE) {
		printk(KERN_WARNING PFX "Unhandled data direction %d\n",
		       scmnd->sc_data_direction);
		return -EINVAL;
	}

	if (scmnd->use_sg) {
		struct scatterlist *scat = scmnd->request_buffer;
		int n;
		int i;

		n = dma_map_sg(target->srp_host->dev->dma_device,
			       scat, scmnd->use_sg, scmnd->sc_data_direction);

		if (n == 1) {
			struct srp_direct_buf *buf = (void *) cmd->add_data;

			fmt = SRP_DATA_DESC_DIRECT;

			buf->va  = cpu_to_be64(sg_dma_address(scat));
			buf->key = cpu_to_be32(target->srp_host->mr->rkey);
			buf->len = cpu_to_be32(sg_dma_len(scat));

			len = sizeof (struct srp_cmd) +
				sizeof (struct srp_direct_buf);
		} else {
			struct srp_indirect_buf *buf = (void *) cmd->add_data;
			u32 datalen = 0;

			fmt = SRP_DATA_DESC_INDIRECT;

			if (scmnd->sc_data_direction == DMA_TO_DEVICE)
				cmd->data_out_desc_cnt = n;
			else
				cmd->data_in_desc_cnt = n;

			buf->table_desc.va  = cpu_to_be64(req->cmd->dma +
							  sizeof *cmd +
							  sizeof *buf);
			buf->table_desc.key =
				cpu_to_be32(target->srp_host->mr->rkey);
			buf->table_desc.len =
				cpu_to_be32(n * sizeof (struct srp_direct_buf));

			for (i = 0; i < n; ++i) {
				buf->desc_list[i].va  = cpu_to_be64(sg_dma_address(&scat[i]));
				buf->desc_list[i].key =
					cpu_to_be32(target->srp_host->mr->rkey);
				buf->desc_list[i].len = cpu_to_be32(sg_dma_len(&scat[i]));

				datalen += sg_dma_len(&scat[i]);
			}

			buf->len = cpu_to_be32(datalen);

			len = sizeof (struct srp_cmd) +
				sizeof (struct srp_indirect_buf) +
				n * sizeof (struct srp_direct_buf);
		}
	} else {
		struct srp_direct_buf *buf = (void *) cmd->add_data;
		dma_addr_t dma;

		dma = dma_map_single(target->srp_host->dev->dma_device,
				     scmnd->request_buffer, scmnd->request_bufflen,
				     scmnd->sc_data_direction);
		if (dma_mapping_error(dma)) {
			printk(KERN_WARNING PFX "unable to map %p/%d (dir %d)\n",
			       scmnd->request_buffer, (int) scmnd->request_bufflen,
			       scmnd->sc_data_direction);
			return -EINVAL;
		}

		pci_unmap_addr_set(req, direct_mapping, dma);

		buf->va  = cpu_to_be64(dma);
		buf->key = cpu_to_be32(target->srp_host->mr->rkey);
		buf->len = cpu_to_be32(scmnd->request_bufflen);

		fmt = SRP_DATA_DESC_DIRECT;

		len = sizeof (struct srp_cmd) + sizeof (struct srp_direct_buf);
	}

	if (scmnd->sc_data_direction == DMA_TO_DEVICE)
		cmd->buf_fmt = fmt << 4;
	else
		cmd->buf_fmt = fmt;


	return len;
}

static void srp_unmap_data(struct scsi_cmnd *scmnd,
			   struct srp_target_port *target,
			   struct srp_request *req)
{
	if (!scmnd->request_buffer ||
	    (scmnd->sc_data_direction != DMA_TO_DEVICE &&
	     scmnd->sc_data_direction != DMA_FROM_DEVICE))
	    return;

	if (scmnd->use_sg)
		dma_unmap_sg(target->srp_host->dev->dma_device,
			     (struct scatterlist *) scmnd->request_buffer,
			     scmnd->use_sg, scmnd->sc_data_direction);
	else
		dma_unmap_single(target->srp_host->dev->dma_device,
				 pci_unmap_addr(req, direct_mapping),
				 scmnd->request_bufflen,
				 scmnd->sc_data_direction);
}

static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
{
	struct srp_request *req;
	struct scsi_cmnd *scmnd;
	unsigned long flags;
	s32 delta;

	delta = (s32) be32_to_cpu(rsp->req_lim_delta);

	spin_lock_irqsave(target->scsi_host->host_lock, flags);

	target->req_lim += delta;

	req = &target->req_ring[rsp->tag & ~SRP_TAG_TSK_MGMT];

	if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) {
		if (be32_to_cpu(rsp->resp_data_len) < 4)
			req->tsk_status = -1;
		else
			req->tsk_status = rsp->data[3];
		complete(&req->done);
	} else {
		scmnd 	      = req->scmnd;
		if (!scmnd)
			printk(KERN_ERR "Null scmnd for RSP w/tag %016llx\n",
			       (unsigned long long) rsp->tag);
		scmnd->result = rsp->status;

		if (rsp->flags & SRP_RSP_FLAG_SNSVALID) {
			memcpy(scmnd->sense_buffer, rsp->data +
			       be32_to_cpu(rsp->resp_data_len),
			       min_t(int, be32_to_cpu(rsp->sense_data_len),
				     SCSI_SENSE_BUFFERSIZE));
		}

		if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER))
			scmnd->resid = be32_to_cpu(rsp->data_out_res_cnt);
		else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
			scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);

		srp_unmap_data(scmnd, target, req);

		if (!req->tsk_mgmt) {
			req->scmnd = NULL;
			scmnd->host_scribble = (void *) -1L;
			scmnd->scsi_done(scmnd);

			list_del(&req->list);
			req->next = target->req_head;
			target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT;
		} else
			req->cmd_done = 1;
	}

	spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
}

static void srp_reconnect_work(void *target_ptr)
{
	struct srp_target_port *target = target_ptr;

	srp_reconnect_target(target);
}

static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
{
	struct srp_iu *iu;
	u8 opcode;

	iu = target->rx_ring[wc->wr_id & ~SRP_OP_RECV];

	dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
				target->max_ti_iu_len, DMA_FROM_DEVICE);

	opcode = *(u8 *) iu->buf;

	if (0) {
		int i;

		printk(KERN_ERR PFX "recv completion, opcode 0x%02x\n", opcode);

		for (i = 0; i < wc->byte_len; ++i) {
			if (i % 8 == 0)
				printk(KERN_ERR "  [%02x] ", i);
			printk(" %02x", ((u8 *) iu->buf)[i]);
			if ((i + 1) % 8 == 0)
				printk("\n");
		}

		if (wc->byte_len % 8)
			printk("\n");
	}

	switch (opcode) {
	case SRP_RSP:
		srp_process_rsp(target, iu->buf);
		break;

	case SRP_T_LOGOUT:
		/* XXX Handle target logout */
		printk(KERN_WARNING PFX "Got target logout request\n");
		break;

	default:
		printk(KERN_WARNING PFX "Unhandled SRP opcode 0x%02x\n", opcode);
		break;
	}

	dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma,
				   target->max_ti_iu_len, DMA_FROM_DEVICE);
}

static void srp_completion(struct ib_cq *cq, void *target_ptr)
{
	struct srp_target_port *target = target_ptr;
	struct ib_wc wc;
	unsigned long flags;

	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
	while (ib_poll_cq(cq, 1, &wc) > 0) {
		if (wc.status) {
			printk(KERN_ERR PFX "failed %s status %d\n",
			       wc.wr_id & SRP_OP_RECV ? "receive" : "send",
			       wc.status);
			spin_lock_irqsave(target->scsi_host->host_lock, flags);
			if (target->state == SRP_TARGET_LIVE)
				schedule_work(&target->work);
			spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
			break;
		}

		if (wc.wr_id & SRP_OP_RECV)
			srp_handle_recv(target, &wc);
		else
			++target->tx_tail;
	}
}

static int __srp_post_recv(struct srp_target_port *target)
{
	struct srp_iu *iu;
	struct ib_sge list;
	struct ib_recv_wr wr, *bad_wr;
	unsigned int next;
	int ret;

	next 	 = target->rx_head & (SRP_RQ_SIZE - 1);
	wr.wr_id = next | SRP_OP_RECV;
	iu 	 = target->rx_ring[next];

	list.addr   = iu->dma;
	list.length = iu->size;
	list.lkey   = target->srp_host->mr->lkey;

	wr.next     = NULL;
	wr.sg_list  = &list;
	wr.num_sge  = 1;

	ret = ib_post_recv(target->qp, &wr, &bad_wr);
	if (!ret)
		++target->rx_head;

	return ret;
}

static int srp_post_recv(struct srp_target_port *target)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(target->scsi_host->host_lock, flags);
	ret = __srp_post_recv(target);
	spin_unlock_irqrestore(target->scsi_host->host_lock, flags);

	return ret;
}

/*
 * Must be called with target->scsi_host->host_lock held to protect
 * req_lim and tx_head.  Lock cannot be dropped between call here and
 * call to __srp_post_send().
 */
static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
{
	if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
		return NULL;

	if (unlikely(target->req_lim < 1)) {
		if (printk_ratelimit())
			printk(KERN_DEBUG PFX "Target has req_lim %d\n",
			       target->req_lim);
		return NULL;
	}

	return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
}

/*
 * Must be called with target->scsi_host->host_lock held to protect
 * req_lim and tx_head.
 */
static int __srp_post_send(struct srp_target_port *target,
			   struct srp_iu *iu, int len)
{
	struct ib_sge list;
	struct ib_send_wr wr, *bad_wr;
	int ret = 0;

	list.addr   = iu->dma;
	list.length = len;
	list.lkey   = target->srp_host->mr->lkey;

	wr.next       = NULL;
	wr.wr_id      = target->tx_head & SRP_SQ_SIZE;
	wr.sg_list    = &list;
	wr.num_sge    = 1;
	wr.opcode     = IB_WR_SEND;
	wr.send_flags = IB_SEND_SIGNALED;

	ret = ib_post_send(target->qp, &wr, &bad_wr);

	if (!ret) {
		++target->tx_head;
		--target->req_lim;
	}

	return ret;
}

static int srp_queuecommand(struct scsi_cmnd *scmnd,
			    void (*done)(struct scsi_cmnd *))
{
	struct srp_target_port *target = host_to_target(scmnd->device->host);
	struct srp_request *req;
	struct srp_iu *iu;
	struct srp_cmd *cmd;
	long req_index;
	int len;

	if (target->state == SRP_TARGET_CONNECTING)
		goto err;

	if (target->state == SRP_TARGET_DEAD ||
	    target->state == SRP_TARGET_REMOVED) {
		scmnd->result = DID_BAD_TARGET << 16;
		done(scmnd);
		return 0;
	}

	iu = __srp_get_tx_iu(target);
	if (!iu)
		goto err;

	dma_sync_single_for_cpu(target->srp_host->dev->dma_device, iu->dma,
				SRP_MAX_IU_LEN, DMA_TO_DEVICE);

	req_index = target->req_head;

	scmnd->scsi_done     = done;
	scmnd->result        = 0;
	scmnd->host_scribble = (void *) req_index;

	cmd = iu->buf;
	memset(cmd, 0, sizeof *cmd);

	cmd->opcode = SRP_CMD;
	cmd->lun    = cpu_to_be64((u64) scmnd->device->lun << 48);
	cmd->tag    = req_index;
	memcpy(cmd->cdb, scmnd->cmnd, scmnd->cmd_len);

	req = &target->req_ring[req_index];

	req->scmnd    = scmnd;
	req->cmd      = iu;
	req->cmd_done = 0;
	req->tsk_mgmt = NULL;

	len = srp_map_data(scmnd, target, req);
	if (len < 0) {
		printk(KERN_ERR PFX "Failed to map data\n");
		goto err;
	}

	if (__srp_post_recv(target)) {
		printk(KERN_ERR PFX "Recv failed\n");
		goto err_unmap;
	}

	dma_sync_single_for_device(target->srp_host->dev->dma_device, iu->dma,
				   SRP_MAX_IU_LEN, DMA_TO_DEVICE);

	if (__srp_post_send(target, iu, len)) {
		printk(KERN_ERR PFX "Send failed\n");
		goto err_unmap;
	}

	target->req_head = req->next;
	list_add_tail(&req->list, &target->req_queue);

	return 0;

err_unmap:
	srp_unmap_data(scmnd, target, req);

err:
	return SCSI_MLQUEUE_HOST_BUSY;
}

static int srp_alloc_iu_bufs(struct srp_target_port *target)
{
	int i;

	for (i = 0; i < SRP_RQ_SIZE; ++i) {
		target->rx_ring[i] = srp_alloc_iu(target->srp_host,
						  target->max_ti_iu_len,
						  GFP_KERNEL, DMA_FROM_DEVICE);
		if (!target->rx_ring[i])
			goto err;
	}

	for (i = 0; i < SRP_SQ_SIZE + 1; ++i) {
		target->tx_ring[i] = srp_alloc_iu(target->srp_host,
						  SRP_MAX_IU_LEN,
						  GFP_KERNEL, DMA_TO_DEVICE);
		if (!target->tx_ring[i])
			goto err;
	}

	return 0;

err:
	for (i = 0; i < SRP_RQ_SIZE; ++i) {
		srp_free_iu(target->srp_host, target->rx_ring[i]);
		target->rx_ring[i] = NULL;
	}

	for (i = 0; i < SRP_SQ_SIZE + 1; ++i) {
		srp_free_iu(target->srp_host, target->tx_ring[i]);
		target->tx_ring[i] = NULL;
	}

	return -ENOMEM;
}

static void srp_cm_rej_handler(struct ib_cm_id *cm_id,
			       struct ib_cm_event *event,
			       struct srp_target_port *target)
{
	struct ib_class_port_info *cpi;
	int opcode;

	switch (event->param.rej_rcvd.reason) {
	case IB_CM_REJ_PORT_CM_REDIRECT:
		cpi = event->param.rej_rcvd.ari;
		target->path.dlid = cpi->redirect_lid;
		target->path.pkey = cpi->redirect_pkey;
		cm_id->remote_cm_qpn = be32_to_cpu(cpi->redirect_qp) & 0x00ffffff;
		memcpy(target->path.dgid.raw, cpi->redirect_gid, 16);

		target->status = target->path.dlid ?
			SRP_DLID_REDIRECT : SRP_PORT_REDIRECT;
		break;

	case IB_CM_REJ_PORT_REDIRECT:
		if (topspin_workarounds &&
		    !memcmp(&target->ioc_guid, topspin_oui, 3)) {
			/*
			 * Topspin/Cisco SRP gateways incorrectly send
			 * reject reason code 25 when they mean 24
			 * (port redirect).
			 */
			memcpy(target->path.dgid.raw,
			       event->param.rej_rcvd.ari, 16);

			printk(KERN_DEBUG PFX "Topspin/Cisco redirect to target port GID %016llx%016llx\n",
			       (unsigned long long) be64_to_cpu(target->path.dgid.global.subnet_prefix),
			       (unsigned long long) be64_to_cpu(target->path.dgid.global.interface_id));

			target->status = SRP_PORT_REDIRECT;
		} else {
			printk(KERN_WARNING "  REJ reason: IB_CM_REJ_PORT_REDIRECT\n");
			target->status = -ECONNRESET;
		}
		break;

	case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID:
		printk(KERN_WARNING "  REJ reason: IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID\n");
		target->status = -ECONNRESET;
		break;

	case IB_CM_REJ_CONSUMER_DEFINED:
		opcode = *(u8 *) event->private_data;
		if (opcode == SRP_LOGIN_REJ) {
			struct srp_login_rej *rej = event->private_data;
			u32 reason = be32_to_cpu(rej->reason);

			if (reason == SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE)
				printk(KERN_WARNING PFX
				       "SRP_LOGIN_REJ: requested max_it_iu_len too large\n");
			else
				printk(KERN_WARNING PFX
				       "SRP LOGIN REJECTED, reason 0x%08x\n", reason);
		} else
			printk(KERN_WARNING "  REJ reason: IB_CM_REJ_CONSUMER_DEFINED,"
			       " opcode 0x%02x\n", opcode);
		target->status = -ECONNRESET;
		break;

	default:
		printk(KERN_WARNING "  REJ reason 0x%x\n",
		       event->param.rej_rcvd.reason);
		target->status = -ECONNRESET;
	}
}

static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event)
{
	struct srp_target_port *target = cm_id->context;
	struct ib_qp_attr *qp_attr = NULL;
	int attr_mask = 0;
	int comp = 0;
	int opcode = 0;

	switch (event->event) {
	case IB_CM_REQ_ERROR:
		printk(KERN_DEBUG PFX "Sending CM REQ failed\n");
		comp = 1;
		target->status = -ECONNRESET;
		break;

	case IB_CM_REP_RECEIVED:
		comp = 1;
		opcode = *(u8 *) event->private_data;

		if (opcode == SRP_LOGIN_RSP) {
			struct srp_login_rsp *rsp = event->private_data;

			target->max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len);
			target->req_lim       = be32_to_cpu(rsp->req_lim_delta);

			target->scsi_host->can_queue = min(target->req_lim,
							   target->scsi_host->can_queue);
		} else {
			printk(KERN_WARNING PFX "Unhandled RSP opcode %#x\n", opcode);
			target->status = -ECONNRESET;
			break;
		}

		target->status = srp_alloc_iu_bufs(target);
		if (target->status)
			break;

		qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL);
		if (!qp_attr) {
			target->status = -ENOMEM;
			break;
		}

		qp_attr->qp_state = IB_QPS_RTR;
		target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
		if (target->status)
			break;

		target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
		if (target->status)
			break;

		target->status = srp_post_recv(target);
		if (target->status)
			break;

		qp_attr->qp_state = IB_QPS_RTS;
		target->status = ib_cm_init_qp_attr(cm_id, qp_attr, &attr_mask);
		if (target->status)
			break;

		target->status = ib_modify_qp(target->qp, qp_attr, attr_mask);
		if (target->status)
			break;

		target->status = ib_send_cm_rtu(cm_id, NULL, 0);
		if (target->status)
			break;

		break;

	case IB_CM_REJ_RECEIVED:
		printk(KERN_DEBUG PFX "REJ received\n");
		comp = 1;

		srp_cm_rej_handler(cm_id, event, target);
		break;

	case IB_CM_MRA_RECEIVED:
		printk(KERN_ERR PFX "MRA received\n");
		break;

	case IB_CM_DREP_RECEIVED:
		break;

	case IB_CM_TIMEWAIT_EXIT:
		printk(KERN_ERR PFX "connection closed\n");

		comp = 1;
		target->status = 0;
		break;

	default:
		printk(KERN_WARNING PFX "Unhandled CM event %d\n", event->event);
		break;
	}

	if (comp)
		complete(&target->done);

	kfree(qp_attr);

	return 0;
}

static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
{
	struct srp_target_port *target = host_to_target(scmnd->device->host);
	struct srp_request *req;
	struct srp_iu *iu;
	struct srp_tsk_mgmt *tsk_mgmt;
	int req_index;
	int ret = FAILED;

	spin_lock_irq(target->scsi_host->host_lock);

	if (scmnd->host_scribble == (void *) -1L)
		goto out;

	req_index = (long) scmnd->host_scribble;
	printk(KERN_ERR "Abort for req_index %d\n", req_index);

	req = &target->req_ring[req_index];
	init_completion(&req->done);

	iu = __srp_get_tx_iu(target);
	if (!iu)
		goto out;

	tsk_mgmt = iu->buf;
	memset(tsk_mgmt, 0, sizeof *tsk_mgmt);

	tsk_mgmt->opcode 	= SRP_TSK_MGMT;
	tsk_mgmt->lun 		= cpu_to_be64((u64) scmnd->device->lun << 48);
	tsk_mgmt->tag 		= req_index | SRP_TAG_TSK_MGMT;
	tsk_mgmt->tsk_mgmt_func = func;
	tsk_mgmt->task_tag 	= req_index;

	if (__srp_post_send(target, iu, sizeof *tsk_mgmt))
		goto out;

	req->tsk_mgmt = iu;

	spin_unlock_irq(target->scsi_host->host_lock);
	if (!wait_for_completion_timeout(&req->done,
					 msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
		return FAILED;
	spin_lock_irq(target->scsi_host->host_lock);

	if (req->cmd_done) {
		list_del(&req->list);
		req->next = target->req_head;
		target->req_head = req_index;

		scmnd->scsi_done(scmnd);
	} else if (!req->tsk_status) {
		scmnd->result = DID_ABORT << 16;
		ret = SUCCESS;
	}

out:
	spin_unlock_irq(target->scsi_host->host_lock);
	return ret;
}

static int srp_abort(struct scsi_cmnd *scmnd)
{
	printk(KERN_ERR "SRP abort called\n");

	return srp_send_tsk_mgmt(scmnd, SRP_TSK_ABORT_TASK);
}

static int srp_reset_device(struct scsi_cmnd *scmnd)
{
	printk(KERN_ERR "SRP reset_device called\n");

	return srp_send_tsk_mgmt(scmnd, SRP_TSK_LUN_RESET);
}

static int srp_reset_host(struct scsi_cmnd *scmnd)
{
	struct srp_target_port *target = host_to_target(scmnd->device->host);
	int ret = FAILED;

	printk(KERN_ERR PFX "SRP reset_host called\n");

	if (!srp_reconnect_target(target))
		ret = SUCCESS;

	return ret;
}

static struct scsi_host_template srp_template = {
	.module				= THIS_MODULE,
	.name				= DRV_NAME,
	.info				= srp_target_info,
	.queuecommand			= srp_queuecommand,
	.eh_abort_handler		= srp_abort,
	.eh_device_reset_handler	= srp_reset_device,
	.eh_host_reset_handler		= srp_reset_host,
	.can_queue			= SRP_SQ_SIZE,
	.this_id			= -1,
	.sg_tablesize			= SRP_MAX_INDIRECT,
	.cmd_per_lun			= SRP_SQ_SIZE,
	.use_clustering			= ENABLE_CLUSTERING
};

static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
{
	sprintf(target->target_name, "SRP.T10:%016llX",
		 (unsigned long long) be64_to_cpu(target->id_ext));

	if (scsi_add_host(target->scsi_host, host->dev->dma_device))
		return -ENODEV;

	mutex_lock(&host->target_mutex);
	list_add_tail(&target->list, &host->target_list);
	mutex_unlock(&host->target_mutex);

	target->state = SRP_TARGET_LIVE;

	/* XXX: are we supposed to have a definition of SCAN_WILD_CARD ?? */
	scsi_scan_target(&target->scsi_host->shost_gendev,
			 0, target->scsi_id, ~0, 0);

	return 0;
}

static void srp_release_class_dev(struct class_device *class_dev)
{
	struct srp_host *host =
		container_of(class_dev, struct srp_host, class_dev);

	complete(&host->released);
}

static struct class srp_class = {
	.name    = "infiniband_srp",
	.release = srp_release_class_dev
};

/*
 * Target ports are added by writing
 *
 *     id_ext=<SRP ID ext>,ioc_guid=<SRP IOC GUID>,dgid=<dest GID>,
 *     pkey=<P_Key>,service_id=<service ID>
 *
 * to the add_target sysfs attribute.
 */
enum {
	SRP_OPT_ERR		= 0,
	SRP_OPT_ID_EXT		= 1 << 0,
	SRP_OPT_IOC_GUID	= 1 << 1,
	SRP_OPT_DGID		= 1 << 2,
	SRP_OPT_PKEY		= 1 << 3,
	SRP_OPT_SERVICE_ID	= 1 << 4,
	SRP_OPT_MAX_SECT	= 1 << 5,
	SRP_OPT_ALL		= (SRP_OPT_ID_EXT	|
				   SRP_OPT_IOC_GUID	|
				   SRP_OPT_DGID		|
				   SRP_OPT_PKEY		|
				   SRP_OPT_SERVICE_ID),
};

static match_table_t srp_opt_tokens = {
	{ SRP_OPT_ID_EXT,	"id_ext=%s" 	},
	{ SRP_OPT_IOC_GUID,	"ioc_guid=%s" 	},
	{ SRP_OPT_DGID,		"dgid=%s" 	},
	{ SRP_OPT_PKEY,		"pkey=%x" 	},
	{ SRP_OPT_SERVICE_ID,	"service_id=%s" },
	{ SRP_OPT_MAX_SECT,     "max_sect=%d" 	},
	{ SRP_OPT_ERR,		NULL 		}
};

static int srp_parse_options(const char *buf, struct srp_target_port *target)
{
	char *options, *sep_opt;
	char *p;
	char dgid[3];
	substring_t args[MAX_OPT_ARGS];
	int opt_mask = 0;
	int token;
	int ret = -EINVAL;
	int i;

	options = kstrdup(buf, GFP_KERNEL);
	if (!options)
		return -ENOMEM;

	sep_opt = options;
	while ((p = strsep(&sep_opt, ",")) != NULL) {
		if (!*p)
			continue;

		token = match_token(p, srp_opt_tokens, args);
		opt_mask |= token;

		switch (token) {
		case SRP_OPT_ID_EXT:
			p = match_strdup(args);
			target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
			kfree(p);
			break;

		case SRP_OPT_IOC_GUID:
			p = match_strdup(args);
			target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16));
			kfree(p);
			break;

		case SRP_OPT_DGID:
			p = match_strdup(args);
			if (strlen(p) != 32) {
				printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
				goto out;
			}

			for (i = 0; i < 16; ++i) {
				strlcpy(dgid, p + i * 2, 3);
				target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16);
			}
			break;

		case SRP_OPT_PKEY:
			if (match_hex(args, &token)) {
				printk(KERN_WARNING PFX "bad P_Key parameter '%s'\n", p);
				goto out;
			}
			target->path.pkey = cpu_to_be16(token);
			break;

		case SRP_OPT_SERVICE_ID:
			p = match_strdup(args);
			target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16));
			kfree(p);
			break;

		case SRP_OPT_MAX_SECT:
			if (match_int(args, &token)) {
				printk(KERN_WARNING PFX "bad max sect parameter '%s'\n", p);
				goto out;
			}
			target->scsi_host->max_sectors = token;
			break;

		default:
			printk(KERN_WARNING PFX "unknown parameter or missing value "
			       "'%s' in target creation request\n", p);
			goto out;
		}
	}

	if ((opt_mask & SRP_OPT_ALL) == SRP_OPT_ALL)
		ret = 0;
	else
		for (i = 0; i < ARRAY_SIZE(srp_opt_tokens); ++i)
			if ((srp_opt_tokens[i].token & SRP_OPT_ALL) &&
			    !(srp_opt_tokens[i].token & opt_mask))
				printk(KERN_WARNING PFX "target creation request is "
				       "missing parameter '%s'\n",
				       srp_opt_tokens[i].pattern);

out:
	kfree(options);
	return ret;
}

static ssize_t srp_create_target(struct class_device *class_dev,
				 const char *buf, size_t count)
{
	struct srp_host *host =
		container_of(class_dev, struct srp_host, class_dev);
	struct Scsi_Host *target_host;
	struct srp_target_port *target;
	int ret;
	int i;

	target_host = scsi_host_alloc(&srp_template,
				      sizeof (struct srp_target_port));
	if (!target_host)
		return -ENOMEM;

	target_host->max_lun = SRP_MAX_LUN;

	target = host_to_target(target_host);
	memset(target, 0, sizeof *target);

	target->scsi_host  = target_host;
	target->srp_host   = host;

	INIT_WORK(&target->work, srp_reconnect_work, target);

	for (i = 0; i < SRP_SQ_SIZE - 1; ++i)
		target->req_ring[i].next = i + 1;
	target->req_ring[SRP_SQ_SIZE - 1].next = -1;
	INIT_LIST_HEAD(&target->req_queue);

	ret = srp_parse_options(buf, target);
	if (ret)
		goto err;

	ib_get_cached_gid(host->dev, host->port, 0, &target->path.sgid);

	printk(KERN_DEBUG PFX "new target: id_ext %016llx ioc_guid %016llx pkey %04x "
	       "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
	       (unsigned long long) be64_to_cpu(target->id_ext),
	       (unsigned long long) be64_to_cpu(target->ioc_guid),
	       be16_to_cpu(target->path.pkey),
	       (unsigned long long) be64_to_cpu(target->service_id),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]),
	       (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14]));

	ret = srp_create_target_ib(target);
	if (ret)
		goto err;

	target->cm_id = ib_create_cm_id(host->dev, srp_cm_handler, target);
	if (IS_ERR(target->cm_id)) {
		ret = PTR_ERR(target->cm_id);
		goto err_free;
	}

	ret = srp_connect_target(target);
	if (ret) {
		printk(KERN_ERR PFX "Connection failed\n");
		goto err_cm_id;
	}

	ret = srp_add_target(host, target);
	if (ret)
		goto err_disconnect;

	return count;

err_disconnect:
	srp_disconnect_target(target);

err_cm_id:
	ib_destroy_cm_id(target->cm_id);

err_free:
	srp_free_target_ib(target);

err:
	scsi_host_put(target_host);

	return ret;
}

static CLASS_DEVICE_ATTR(add_target, S_IWUSR, NULL, srp_create_target);

static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
{
	struct srp_host *host =
		container_of(class_dev, struct srp_host, class_dev);

	return sprintf(buf, "%s\n", host->dev->name);
}

static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);

static ssize_t show_port(struct class_device *class_dev, char *buf)
{
	struct srp_host *host =
		container_of(class_dev, struct srp_host, class_dev);

	return sprintf(buf, "%d\n", host->port);
}

static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);

static struct srp_host *srp_add_port(struct ib_device *device, u8 port)
{
	struct srp_host *host;

	host = kzalloc(sizeof *host, GFP_KERNEL);
	if (!host)
		return NULL;

	INIT_LIST_HEAD(&host->target_list);
	mutex_init(&host->target_mutex);
	init_completion(&host->released);
	host->dev  = device;
	host->port = port;

	host->initiator_port_id[7] = port;
	memcpy(host->initiator_port_id + 8, &device->node_guid, 8);

	host->pd   = ib_alloc_pd(device);
	if (IS_ERR(host->pd))
		goto err_free;

	host->mr   = ib_get_dma_mr(host->pd,
				   IB_ACCESS_LOCAL_WRITE |
				   IB_ACCESS_REMOTE_READ |
				   IB_ACCESS_REMOTE_WRITE);
	if (IS_ERR(host->mr))
		goto err_pd;

	host->class_dev.class = &srp_class;
	host->class_dev.dev   = device->dma_device;
	snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
		 device->name, port);

	if (class_device_register(&host->class_dev))
		goto err_mr;
	if (class_device_create_file(&host->class_dev, &class_device_attr_add_target))
		goto err_class;
	if (class_device_create_file(&host->class_dev, &class_device_attr_ibdev))
		goto err_class;
	if (class_device_create_file(&host->class_dev, &class_device_attr_port))
		goto err_class;

	return host;

err_class:
	class_device_unregister(&host->class_dev);

err_mr:
	ib_dereg_mr(host->mr);

err_pd:
	ib_dealloc_pd(host->pd);

err_free:
	kfree(host);

	return NULL;
}

static void srp_add_one(struct ib_device *device)
{
	struct list_head *dev_list;
	struct srp_host *host;
	int s, e, p;

	dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
	if (!dev_list)
		return;

	INIT_LIST_HEAD(dev_list);

	if (device->node_type == IB_NODE_SWITCH) {
		s = 0;
		e = 0;
	} else {
		s = 1;
		e = device->phys_port_cnt;
	}

	for (p = s; p <= e; ++p) {
		host = srp_add_port(device, p);
		if (host)
			list_add_tail(&host->list, dev_list);
	}

	ib_set_client_data(device, &srp_client, dev_list);
}

static void srp_remove_one(struct ib_device *device)
{
	struct list_head *dev_list;
	struct srp_host *host, *tmp_host;
	LIST_HEAD(target_list);
	struct srp_target_port *target, *tmp_target;
	unsigned long flags;

	dev_list = ib_get_client_data(device, &srp_client);

	list_for_each_entry_safe(host, tmp_host, dev_list, list) {
		class_device_unregister(&host->class_dev);
		/*
		 * Wait for the sysfs entry to go away, so that no new
		 * target ports can be created.
		 */
		wait_for_completion(&host->released);

		/*
		 * Mark all target ports as removed, so we stop queueing
		 * commands and don't try to reconnect.
		 */
		mutex_lock(&host->target_mutex);
		list_for_each_entry_safe(target, tmp_target,
					 &host->target_list, list) {
			spin_lock_irqsave(target->scsi_host->host_lock, flags);
			if (target->state != SRP_TARGET_REMOVED)
				target->state = SRP_TARGET_REMOVED;
			spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
		}
		mutex_unlock(&host->target_mutex);

		/*
		 * Wait for any reconnection tasks that may have
		 * started before we marked our target ports as
		 * removed, and any target port removal tasks.
		 */
		flush_scheduled_work();

		list_for_each_entry_safe(target, tmp_target,
					 &host->target_list, list) {
			scsi_remove_host(target->scsi_host);
			srp_disconnect_target(target);
			ib_destroy_cm_id(target->cm_id);
			srp_free_target_ib(target);
			scsi_host_put(target->scsi_host);
		}

		ib_dereg_mr(host->mr);
		ib_dealloc_pd(host->pd);
		kfree(host);
	}

	kfree(dev_list);
}

static int __init srp_init_module(void)
{
	int ret;

	ret = class_register(&srp_class);
	if (ret) {
		printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
		return ret;
	}

	ret = ib_register_client(&srp_client);
	if (ret) {
		printk(KERN_ERR PFX "couldn't register IB client\n");
		class_unregister(&srp_class);
		return ret;
	}

	return 0;
}

static void __exit srp_cleanup_module(void)
{
	ib_unregister_client(&srp_client);
	class_unregister(&srp_class);
}

module_init(srp_init_module);
module_exit(srp_cleanup_module);
