Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89a93f2f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (102 commits)
  [SCSI] scsi_dh: fix kconfig related build errors
  [SCSI] sym53c8xx: Fix bogus sym_que_entry re-implementation of container_of
  [SCSI] scsi_cmnd.h: remove double inclusion of linux/blkdev.h
  [SCSI] make struct scsi_{host,target}_type static
  [SCSI] fix locking in host use of blk_plug_device()
  [SCSI] zfcp: Cleanup external header file
  [SCSI] zfcp: Cleanup code in zfcp_erp.c
  [SCSI] zfcp: zfcp_fsf cleanup.
  [SCSI] zfcp: consolidate sysfs things into one file.
  [SCSI] zfcp: Cleanup of code in zfcp_aux.c
  [SCSI] zfcp: Cleanup of code in zfcp_scsi.c
  [SCSI] zfcp: Move status accessors from zfcp to SCSI include file.
  [SCSI] zfcp: Small QDIO cleanups
  [SCSI] zfcp: Adapter reopen for large number of unsolicited status
  [SCSI] zfcp: Fix error checking for ELS ADISC requests
  [SCSI] zfcp: wait until adapter is finished with ERP during auto-port
  [SCSI] ibmvfc: IBM Power Virtual Fibre Channel Adapter Client Driver
  [SCSI] sg: Add target reset support
  [SCSI] lib: Add support for the T10 (SCSI) Data Integrity Field CRC
  [SCSI] sd: Move scsi_disk() accessor function to sd.h
  ...
parents 260eddf4 fe9233fb
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -56,19 +56,33 @@ Supported Cards/Chipsets
	9005:0285:9005:02d1	Adaptec	5405 (Voodoo40)
	9005:0285:15d9:02d2	SMC	AOC-USAS-S8i-LP
	9005:0285:15d9:02d3	SMC	AOC-USAS-S8iR-LP
	9005:0285:9005:02d4	Adaptec	2045 (Voodoo04 Lite)
	9005:0285:9005:02d5	Adaptec	2405 (Voodoo40 Lite)
	9005:0285:9005:02d6	Adaptec	2445 (Voodoo44 Lite)
	9005:0285:9005:02d7	Adaptec	2805 (Voodoo80 Lite)
	9005:0285:9005:02d4	Adaptec	ASR-2045 (Voodoo04 Lite)
	9005:0285:9005:02d5	Adaptec	ASR-2405 (Voodoo40 Lite)
	9005:0285:9005:02d6	Adaptec	ASR-2445 (Voodoo44 Lite)
	9005:0285:9005:02d7	Adaptec	ASR-2805 (Voodoo80 Lite)
	9005:0285:9005:02d8	Adaptec	5405G (Voodoo40 PM)
	9005:0285:9005:02d9	Adaptec	5445G (Voodoo44 PM)
	9005:0285:9005:02da	Adaptec	5805G (Voodoo80 PM)
	9005:0285:9005:02db	Adaptec	5085G (Voodoo08 PM)
	9005:0285:9005:02dc	Adaptec	51245G (Voodoo124 PM)
	9005:0285:9005:02dd	Adaptec	51645G (Voodoo164 PM)
	9005:0285:9005:02de	Adaptec	52445G (Voodoo244 PM)
	9005:0285:9005:02df	Adaptec	ASR-2045G (Voodoo04 Lite PM)
	9005:0285:9005:02e0	Adaptec	ASR-2405G (Voodoo40 Lite PM)
	9005:0285:9005:02e1	Adaptec	ASR-2445G (Voodoo44 Lite PM)
	9005:0285:9005:02e2	Adaptec	ASR-2805G (Voodoo80 Lite PM)
	1011:0046:9005:0364	Adaptec	5400S (Mustang)
	1011:0046:9005:0365	Adaptec	5400S (Mustang)
	9005:0287:9005:0800	Adaptec	Themisto (Jupiter)
	9005:0200:9005:0200	Adaptec	Themisto (Jupiter)
	9005:0286:9005:0800	Adaptec	Callisto (Jupiter)
	1011:0046:9005:1364	Dell	PERC 2/QC (Quad Channel, Mustang)
	1011:0046:9005:1365	Dell	PERC 2/QC (Quad Channel, Mustang)
	1028:0001:1028:0001	Dell	PERC 2/Si (Iguana)
	1028:0003:1028:0003	Dell	PERC 3/Si (SlimFast)
	1028:0002:1028:0002	Dell	PERC 3/Di (Opal)
	1028:0004:1028:0004	Dell	PERC 3/DiF (Iguana)
	1028:0004:1028:0004	Dell	PERC 3/SiF (Iguana)
	1028:0004:1028:00d0	Dell	PERC 3/DiF (Iguana)
	1028:0002:1028:00d1	Dell	PERC 3/DiV (Viper)
	1028:0002:1028:00d9	Dell	PERC 3/DiL (Lexus)
	1028:000a:1028:0106	Dell	PERC 3/DiJ (Jaguar)
+6 −3
Original line number Diff line number Diff line
@@ -740,8 +740,13 @@ static int bsg_put_device(struct bsg_device *bd)
	mutex_lock(&bsg_mutex);

	do_free = atomic_dec_and_test(&bd->ref_count);
	if (!do_free)
	if (!do_free) {
		mutex_unlock(&bsg_mutex);
		goto out;
	}

	hlist_del(&bd->dev_list);
	mutex_unlock(&bsg_mutex);

	dprintk("%s: tearing down\n", bd->name);

@@ -757,10 +762,8 @@ static int bsg_put_device(struct bsg_device *bd)
	 */
	ret = bsg_complete_all_commands(bd);

	hlist_del(&bd->dev_list);
	kfree(bd);
out:
	mutex_unlock(&bsg_mutex);
	kref_put(&q->bsg_dev.ref, bsg_kref_release_function);
	if (do_free)
		blk_put_queue(q);
+198 −158
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@

#include "iscsi_iser.h"

static struct scsi_host_template iscsi_iser_sht;
static struct iscsi_transport iscsi_iser_transport;
static struct scsi_transport_template *iscsi_iser_scsi_transport;

static unsigned int iscsi_max_lun = 512;
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);

@@ -91,7 +95,6 @@ iscsi_iser_recv(struct iscsi_conn *conn,
		struct iscsi_hdr *hdr, char *rx_data, int rx_data_len)
{
	int rc = 0;
	uint32_t ret_itt;
	int datalen;
	int ahslen;

@@ -107,12 +110,7 @@ iscsi_iser_recv(struct iscsi_conn *conn,
	/* read AHS */
	ahslen = hdr->hlength * 4;

	/* verify itt (itt encoding: age+cid+itt) */
	rc = iscsi_verify_itt(conn, hdr, &ret_itt);

	if (!rc)
	rc = iscsi_complete_pdu(conn, hdr, rx_data, rx_data_len);

	if (rc && rc != ISCSI_ERR_NO_SCSI_CMD)
		goto error;

@@ -123,25 +121,33 @@ iscsi_iser_recv(struct iscsi_conn *conn,


/**
 * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
 * iscsi_iser_task_init - Initialize task
 * @task: iscsi task
 *
 **/
 * Initialize the task for the scsi command or mgmt command.
 */
static int
iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
iscsi_iser_task_init(struct iscsi_task *task)
{
	struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
	struct iscsi_iser_conn *iser_conn  = task->conn->dd_data;
	struct iscsi_iser_task *iser_task = task->dd_data;

	/* mgmt task */
	if (!task->sc) {
		iser_task->desc.data = task->data;
		return 0;
	}

	iser_ctask->command_sent = 0;
	iser_ctask->iser_conn    = iser_conn;
	iser_ctask_rdma_init(iser_ctask);
	iser_task->command_sent = 0;
	iser_task->iser_conn    = iser_conn;
	iser_task_rdma_init(iser_task);
	return 0;
}

/**
 * iscsi_mtask_xmit - xmit management(immediate) task
 * iscsi_iser_mtask_xmit - xmit management(immediate) task
 * @conn: iscsi connection
 * @mtask: task management task
 * @task: task management task
 *
 * Notes:
 *	The function can return -EAGAIN in which case caller must
@@ -150,20 +156,19 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
 *
 **/
static int
iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
		      struct iscsi_mgmt_task *mtask)
iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
{
	int error = 0;

	debug_scsi("mtask deq [cid %d itt 0x%x]\n", conn->id, mtask->itt);
	debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);

	error = iser_send_control(conn, mtask);
	error = iser_send_control(conn, task);

	/* since iser xmits control with zero copy, mtasks can not be recycled
	/* since iser xmits control with zero copy, tasks can not be recycled
	 * right after sending them.
	 * The recycling scheme is based on whether a response is expected
	 * - if yes, the mtask is recycled at iscsi_complete_pdu
	 * - if no,  the mtask is recycled at iser_snd_completion
	 * - if yes, the task is recycled at iscsi_complete_pdu
	 * - if no,  the task is recycled at iser_snd_completion
	 */
	if (error && error != -ENOBUFS)
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
@@ -172,98 +177,87 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn,
}

static int
iscsi_iser_ctask_xmit_unsol_data(struct iscsi_conn *conn,
				 struct iscsi_cmd_task *ctask)
iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
				 struct iscsi_task *task)
{
	struct iscsi_data  hdr;
	int error = 0;

	/* Send data-out PDUs while there's still unsolicited data to send */
	while (ctask->unsol_count > 0) {
		iscsi_prep_unsolicit_data_pdu(ctask, &hdr);
	while (task->unsol_count > 0) {
		iscsi_prep_unsolicit_data_pdu(task, &hdr);
		debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
			   hdr.itt, ctask->data_count);
			   hdr.itt, task->data_count);

		/* the buffer description has been passed with the command */
		/* Send the command */
		error = iser_send_data_out(conn, ctask, &hdr);
		error = iser_send_data_out(conn, task, &hdr);
		if (error) {
			ctask->unsol_datasn--;
			goto iscsi_iser_ctask_xmit_unsol_data_exit;
			task->unsol_datasn--;
			goto iscsi_iser_task_xmit_unsol_data_exit;
		}
		ctask->unsol_count -= ctask->data_count;
		task->unsol_count -= task->data_count;
		debug_scsi("Need to send %d more as data-out PDUs\n",
			   ctask->unsol_count);
			   task->unsol_count);
	}

iscsi_iser_ctask_xmit_unsol_data_exit:
iscsi_iser_task_xmit_unsol_data_exit:
	return error;
}

static int
iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
		      struct iscsi_cmd_task *ctask)
iscsi_iser_task_xmit(struct iscsi_task *task)
{
	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
	struct iscsi_conn *conn = task->conn;
	struct iscsi_iser_task *iser_task = task->dd_data;
	int error = 0;

	if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
		BUG_ON(scsi_bufflen(ctask->sc) == 0);
	if (!task->sc)
		return iscsi_iser_mtask_xmit(conn, task);

	if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
		BUG_ON(scsi_bufflen(task->sc) == 0);

		debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
			   ctask->itt, scsi_bufflen(ctask->sc),
			   ctask->imm_count, ctask->unsol_count);
			   task->itt, scsi_bufflen(task->sc),
			   task->imm_count, task->unsol_count);
	}

	debug_scsi("ctask deq [cid %d itt 0x%x]\n",
		   conn->id, ctask->itt);
	debug_scsi("task deq [cid %d itt 0x%x]\n",
		   conn->id, task->itt);

	/* Send the cmd PDU */
	if (!iser_ctask->command_sent) {
		error = iser_send_command(conn, ctask);
	if (!iser_task->command_sent) {
		error = iser_send_command(conn, task);
		if (error)
			goto iscsi_iser_ctask_xmit_exit;
		iser_ctask->command_sent = 1;
			goto iscsi_iser_task_xmit_exit;
		iser_task->command_sent = 1;
	}

	/* Send unsolicited data-out PDU(s) if necessary */
	if (ctask->unsol_count)
		error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);
	if (task->unsol_count)
		error = iscsi_iser_task_xmit_unsol_data(conn, task);

 iscsi_iser_ctask_xmit_exit:
 iscsi_iser_task_xmit_exit:
	if (error && error != -ENOBUFS)
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
	return error;
}

static void
iscsi_iser_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
{
	struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
	struct iscsi_iser_task *iser_task = task->dd_data;

	if (iser_ctask->status == ISER_TASK_STATUS_STARTED) {
		iser_ctask->status = ISER_TASK_STATUS_COMPLETED;
		iser_ctask_rdma_finalize(iser_ctask);
	}
}

static struct iser_conn *
iscsi_iser_ib_conn_lookup(__u64 ep_handle)
{
	struct iser_conn *ib_conn;
	struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle;
	/* mgmt tasks do not need special cleanup */
	if (!task->sc)
		return;

	mutex_lock(&ig.connlist_mutex);
	list_for_each_entry(ib_conn, &ig.connlist, conn_list) {
		if (ib_conn == uib_conn) {
			mutex_unlock(&ig.connlist_mutex);
			return ib_conn;
	if (iser_task->status == ISER_TASK_STATUS_STARTED) {
		iser_task->status = ISER_TASK_STATUS_COMPLETED;
		iser_task_rdma_finalize(iser_task);
	}
}
	mutex_unlock(&ig.connlist_mutex);
	iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle);
	return NULL;
}

static struct iscsi_cls_conn *
iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
@@ -272,7 +266,7 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
	struct iscsi_cls_conn *cls_conn;
	struct iscsi_iser_conn *iser_conn;

	cls_conn = iscsi_conn_setup(cls_session, conn_idx);
	cls_conn = iscsi_conn_setup(cls_session, sizeof(*iser_conn), conn_idx);
	if (!cls_conn)
		return NULL;
	conn = cls_conn->dd_data;
@@ -283,21 +277,11 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
	 */
	conn->max_recv_dlength = 128;

	iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL);
	if (!iser_conn)
		goto conn_alloc_fail;

	/* currently this is the only field which need to be initiated */
	rwlock_init(&iser_conn->lock);

	iser_conn = conn->dd_data;
	conn->dd_data = iser_conn;
	iser_conn->iscsi_conn = conn;

	return cls_conn;

conn_alloc_fail:
	iscsi_conn_teardown(cls_conn);
	return NULL;
}

static void
@@ -305,11 +289,18 @@ iscsi_iser_conn_destroy(struct iscsi_cls_conn *cls_conn)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_iser_conn *iser_conn = conn->dd_data;
	struct iser_conn *ib_conn = iser_conn->ib_conn;

	iscsi_conn_teardown(cls_conn);
	if (iser_conn->ib_conn)
		iser_conn->ib_conn->iser_conn = NULL;
	kfree(iser_conn);
	/*
	 * Userspace will normally call the stop callback and
	 * already have freed the ib_conn, but if it goofed up then
	 * we free it here.
	 */
	if (ib_conn) {
		ib_conn->iser_conn = NULL;
		iser_conn_put(ib_conn);
	}
}

static int
@@ -320,6 +311,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_iser_conn *iser_conn;
	struct iser_conn *ib_conn;
	struct iscsi_endpoint *ep;
	int error;

	error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
@@ -328,12 +320,14 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,

	/* the transport ep handle comes from user space so it must be
	 * verified against the global ib connections list */
	ib_conn = iscsi_iser_ib_conn_lookup(transport_eph);
	if (!ib_conn) {
	ep = iscsi_lookup_endpoint(transport_eph);
	if (!ep) {
		iser_err("can't bind eph %llx\n",
			 (unsigned long long)transport_eph);
		return -EINVAL;
	}
	ib_conn = ep->dd_data;

	/* binds the iSER connection retrieved from the previously
	 * connected ep_handle to the iSCSI layer connection. exchanges
	 * connection pointers */
@@ -341,10 +335,30 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
	iser_conn = conn->dd_data;
	ib_conn->iser_conn = iser_conn;
	iser_conn->ib_conn  = ib_conn;
	iser_conn_get(ib_conn);
	return 0;
}

	conn->recv_lock = &iser_conn->lock;
static void
iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
	struct iscsi_conn *conn = cls_conn->dd_data;
	struct iscsi_iser_conn *iser_conn = conn->dd_data;
	struct iser_conn *ib_conn = iser_conn->ib_conn;

	return 0;
	/*
	 * Userspace may have goofed up and not bound the connection or
	 * might have only partially setup the connection.
	 */
	if (ib_conn) {
		iscsi_conn_stop(cls_conn, flag);
		/*
		 * There is no unbind event so the stop callback
		 * must release the ref from the bind.
		 */
		iser_conn_put(ib_conn);
	}
	iser_conn->ib_conn = NULL;
}

static int
@@ -360,55 +374,75 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
	return iscsi_conn_start(cls_conn);
}

static struct iscsi_transport iscsi_iser_transport;
static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
{
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);

	iscsi_host_remove(shost);
	iscsi_host_free(shost);
}

static struct iscsi_cls_session *
iscsi_iser_session_create(struct iscsi_transport *iscsit,
			 struct scsi_transport_template *scsit,
iscsi_iser_session_create(struct iscsi_endpoint *ep,
			  uint16_t cmds_max, uint16_t qdepth,
			  uint32_t initial_cmdsn, uint32_t *hostno)
{
	struct iscsi_cls_session *cls_session;
	struct iscsi_session *session;
	struct Scsi_Host *shost;
	int i;
	uint32_t hn;
	struct iscsi_cmd_task  *ctask;
	struct iscsi_mgmt_task *mtask;
	struct iscsi_iser_cmd_task *iser_ctask;
	struct iser_desc *desc;
	struct iscsi_task *task;
	struct iscsi_iser_task *iser_task;
	struct iser_conn *ib_conn;

	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
	if (!shost)
		return NULL;
	shost->transportt = iscsi_iser_scsi_transport;
	shost->max_lun = iscsi_max_lun;
	shost->max_id = 0;
	shost->max_channel = 0;
	shost->max_cmd_len = 16;

	/*
	 * older userspace tools (before 2.0-870) did not pass us
	 * the leading conn's ep so this will be NULL;
	 */
	if (ep)
		ib_conn = ep->dd_data;

	if (iscsi_host_add(shost,
			   ep ? ib_conn->device->ib_device->dma_device : NULL))
		goto free_host;
	*hostno = shost->host_no;

	/*
	 * we do not support setting can_queue cmd_per_lun from userspace yet
	 * because we preallocate so many resources
	 */
	cls_session = iscsi_session_setup(iscsit, scsit,
	cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
					  ISCSI_DEF_XMIT_CMDS_MAX,
					  ISCSI_MAX_CMD_PER_LUN,
					  sizeof(struct iscsi_iser_cmd_task),
					  sizeof(struct iser_desc),
					  initial_cmdsn, &hn);
					  sizeof(struct iscsi_iser_task),
					  initial_cmdsn, 0);
	if (!cls_session)
	return NULL;

	*hostno = hn;
	session = class_to_transport_session(cls_session);
		goto remove_host;
	session = cls_session->dd_data;

	shost->can_queue = session->scsi_cmds_max;
	/* libiscsi setup itts, data and pool so just set desc fields */
	for (i = 0; i < session->cmds_max; i++) {
		ctask      = session->cmds[i];
		iser_ctask = ctask->dd_data;
		ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;
		ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header);
		task = session->cmds[i];
		iser_task = task->dd_data;
		task->hdr = (struct iscsi_cmd *)&iser_task->desc.iscsi_header;
		task->hdr_max = sizeof(iser_task->desc.iscsi_header);
	}

	for (i = 0; i < session->mgmtpool_max; i++) {
		mtask      = session->mgmt_cmds[i];
		desc       = mtask->dd_data;
		mtask->hdr = &desc->iscsi_header;
		desc->data = mtask->data;
	}

	return cls_session;

remove_host:
	iscsi_host_remove(shost);
free_host:
	iscsi_host_free(shost);
	return NULL;
}

static int
@@ -481,34 +515,37 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s
	stats->custom[3].value = conn->fmr_unalign_cnt;
}

static int
iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking,
		      __u64 *ep_handle)
static struct iscsi_endpoint *
iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking)
{
	int err;
	struct iser_conn *ib_conn;
	struct iscsi_endpoint *ep;

	err = iser_conn_init(&ib_conn);
	if (err)
		goto out;
	ep = iscsi_create_endpoint(sizeof(*ib_conn));
	if (!ep)
		return ERR_PTR(-ENOMEM);

	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking);
	if (!err)
		*ep_handle = (__u64)(unsigned long)ib_conn;
	ib_conn = ep->dd_data;
	ib_conn->ep = ep;
	iser_conn_init(ib_conn);

out:
	return err;
	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr,
			   non_blocking);
	if (err) {
		iscsi_destroy_endpoint(ep);
		return ERR_PTR(err);
	}
	return ep;
}

static int
iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
{
	struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
	struct iser_conn *ib_conn;
	int rc;

	if (!ib_conn)
		return -EINVAL;

	ib_conn = ep->dd_data;
	rc = wait_event_interruptible_timeout(ib_conn->wait,
			     ib_conn->state == ISER_CONN_UP,
			     msecs_to_jiffies(timeout_ms));
@@ -530,13 +567,21 @@ iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
}

static void
iscsi_iser_ep_disconnect(__u64 ep_handle)
iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
{
	struct iser_conn *ib_conn;

	ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);
	if (!ib_conn)
		return;
	ib_conn = ep->dd_data;
	if (ib_conn->iser_conn)
		/*
		 * Must suspend xmit path if the ep is bound to the
		 * iscsi_conn, so we know we are not accessing the ib_conn
		 * when we free it.
		 *
		 * This may not be bound if the ep poll failed.
		 */
		iscsi_suspend_tx(ib_conn->iser_conn->iscsi_conn);


	iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state);
	iser_conn_terminate(ib_conn);
@@ -547,7 +592,6 @@ static struct scsi_host_template iscsi_iser_sht = {
	.name                   = "iSCSI Initiator over iSER, v." DRV_VER,
	.queuecommand           = iscsi_queuecommand,
	.change_queue_depth	= iscsi_change_queue_depth,
	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,
	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
	.max_sectors		= 1024,
	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
@@ -581,17 +625,14 @@ static struct iscsi_transport iscsi_iser_transport = {
				  ISCSI_USERNAME | ISCSI_PASSWORD |
				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
				  ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
				  ISCSI_PING_TMO | ISCSI_RECV_TMO,
				  ISCSI_PING_TMO | ISCSI_RECV_TMO |
				  ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
	.host_param_mask	= ISCSI_HOST_HWADDRESS |
				  ISCSI_HOST_NETDEV_NAME |
				  ISCSI_HOST_INITIATOR_NAME,
	.host_template          = &iscsi_iser_sht,
	.conndata_size		= sizeof(struct iscsi_conn),
	.max_lun                = ISCSI_ISER_MAX_LUN,
	.max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,
	/* session management */
	.create_session         = iscsi_iser_session_create,
	.destroy_session        = iscsi_session_teardown,
	.destroy_session        = iscsi_iser_session_destroy,
	/* connection management */
	.create_conn            = iscsi_iser_conn_create,
	.bind_conn              = iscsi_iser_conn_bind,
@@ -600,17 +641,16 @@ static struct iscsi_transport iscsi_iser_transport = {
	.get_conn_param		= iscsi_conn_get_param,
	.get_session_param	= iscsi_session_get_param,
	.start_conn             = iscsi_iser_conn_start,
	.stop_conn              = iscsi_conn_stop,
	.stop_conn              = iscsi_iser_conn_stop,
	/* iscsi host params */
	.get_host_param		= iscsi_host_get_param,
	.set_host_param		= iscsi_host_set_param,
	/* IO */
	.send_pdu		= iscsi_conn_send_pdu,
	.get_stats		= iscsi_iser_conn_get_stats,
	.init_cmd_task		= iscsi_iser_cmd_init,
	.xmit_cmd_task		= iscsi_iser_ctask_xmit,
	.xmit_mgmt_task		= iscsi_iser_mtask_xmit,
	.cleanup_cmd_task	= iscsi_iser_cleanup_ctask,
	.init_task		= iscsi_iser_task_init,
	.xmit_task		= iscsi_iser_task_xmit,
	.cleanup_task		= iscsi_iser_cleanup_task,
	/* recovery */
	.session_recovery_timedout = iscsi_session_recovery_timedout,

@@ -630,8 +670,6 @@ static int __init iser_init(void)
		return -EINVAL;
	}

	iscsi_iser_transport.max_lun = iscsi_max_lun;

	memset(&ig, 0, sizeof(struct iser_global));

	ig.desc_cache = kmem_cache_create("iser_descriptors",
@@ -647,7 +685,9 @@ static int __init iser_init(void)
	mutex_init(&ig.connlist_mutex);
	INIT_LIST_HEAD(&ig.connlist);

	if (!iscsi_register_transport(&iscsi_iser_transport)) {
	iscsi_iser_scsi_transport = iscsi_register_transport(
							&iscsi_iser_transport);
	if (!iscsi_iser_scsi_transport) {
		iser_err("iscsi_register_transport failed\n");
		err = -EINVAL;
		goto register_transport_failure;
+24 −20
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@
					/* support upto 512KB in one RDMA */
#define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> SHIFT_4K)
#define ISCSI_ISER_MAX_LUN		256
#define ISCSI_ISER_MAX_CMD_LEN		16

/* QP settings */
/* Maximal bounds on received asynchronous PDUs */
@@ -172,7 +171,8 @@ struct iser_data_buf {
/* fwd declarations */
struct iser_device;
struct iscsi_iser_conn;
struct iscsi_iser_cmd_task;
struct iscsi_iser_task;
struct iscsi_endpoint;

struct iser_mem_reg {
	u32  lkey;
@@ -196,7 +196,7 @@ struct iser_regd_buf {
#define MAX_REGD_BUF_VECTOR_LEN	2

struct iser_dto {
	struct iscsi_iser_cmd_task *ctask;
	struct iscsi_iser_task *task;
	struct iser_conn *ib_conn;
	int                        notify_enable;

@@ -240,7 +240,9 @@ struct iser_device {

struct iser_conn {
	struct iscsi_iser_conn       *iser_conn; /* iser conn for upcalls  */
	struct iscsi_endpoint	     *ep;
	enum iser_ib_conn_state	     state;	    /* rdma connection state   */
	atomic_t		     refcount;
	spinlock_t		     lock;	    /* used for state changes  */
	struct iser_device           *device;       /* device context          */
	struct rdma_cm_id            *cma_id;       /* CMA ID		       */
@@ -259,11 +261,9 @@ struct iser_conn {
struct iscsi_iser_conn {
	struct iscsi_conn            *iscsi_conn;/* ptr to iscsi conn */
	struct iser_conn             *ib_conn;   /* iSER IB conn      */

	rwlock_t		     lock;
};

struct iscsi_iser_cmd_task {
struct iscsi_iser_task {
	struct iser_desc             desc;
	struct iscsi_iser_conn	     *iser_conn;
	enum iser_task_status 	     status;
@@ -297,13 +297,13 @@ extern int iser_debug_level;
int iser_conn_set_full_featured_mode(struct iscsi_conn *conn);

int iser_send_control(struct iscsi_conn *conn,
		      struct iscsi_mgmt_task *mtask);
		      struct iscsi_task *task);

int iser_send_command(struct iscsi_conn *conn,
		      struct iscsi_cmd_task  *ctask);
		      struct iscsi_task *task);

int iser_send_data_out(struct iscsi_conn *conn,
		       struct iscsi_cmd_task *ctask,
		       struct iscsi_task *task,
		       struct iscsi_data *hdr);

void iscsi_iser_recv(struct iscsi_conn *conn,
@@ -311,7 +311,11 @@ void iscsi_iser_recv(struct iscsi_conn *conn,
		     char                   *rx_data,
		     int                    rx_data_len);

int  iser_conn_init(struct iser_conn **ib_conn);
void iser_conn_init(struct iser_conn *ib_conn);

void iser_conn_get(struct iser_conn *ib_conn);

void iser_conn_put(struct iser_conn *ib_conn);

void iser_conn_terminate(struct iser_conn *ib_conn);

@@ -320,9 +324,9 @@ void iser_rcv_completion(struct iser_desc *desc,

void iser_snd_completion(struct iser_desc *desc);

void iser_ctask_rdma_init(struct iscsi_iser_cmd_task     *ctask);
void iser_task_rdma_init(struct iscsi_iser_task *task);

void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *ctask);
void iser_task_rdma_finalize(struct iscsi_iser_task *task);

void iser_dto_buffs_release(struct iser_dto *dto);

@@ -332,10 +336,10 @@ void iser_reg_single(struct iser_device *device,
		     struct iser_regd_buf    *regd_buf,
		     enum dma_data_direction direction);

void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *ctask,
void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
				     enum iser_data_dir         cmd_dir);

int  iser_reg_rdma_mem(struct iscsi_iser_cmd_task *ctask,
int  iser_reg_rdma_mem(struct iscsi_iser_task *task,
		       enum   iser_data_dir        cmd_dir);

int  iser_connect(struct iser_conn   *ib_conn,
@@ -355,10 +359,10 @@ int iser_post_send(struct iser_desc *tx_desc);
int iser_conn_state_comp(struct iser_conn *ib_conn,
			 enum iser_ib_conn_state comp);

int iser_dma_map_task_data(struct iscsi_iser_cmd_task *iser_ctask,
int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
			    struct iser_data_buf       *data,
			    enum   iser_data_dir       iser_dir,
			    enum   dma_data_direction  dma_dir);

void iser_dma_unmap_task_data(struct iscsi_iser_cmd_task *iser_ctask);
void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
#endif
+104 −105

File changed.

Preview size limit exceeded, changes collapsed.

Loading