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

Commit a4804cd6 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley
Browse files

[SCSI] iscsi: add iscsi host helpers



This finishes the host/session unbinding, by adding some helpers
to add and remove hosts and the session they manage.

Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 75613521
Loading
Loading
Loading
Loading
+6 −11
Original line number Original line Diff line number Diff line
@@ -371,10 +371,8 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
{
{
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);


	iscsi_session_teardown(cls_session);
	iscsi_host_remove(shost);
	scsi_remove_host(shost);
	iscsi_host_free(shost);
	iscsi_host_teardown(shost);
	scsi_host_put(shost);
}
}


static struct iscsi_cls_session *
static struct iscsi_cls_session *
@@ -396,7 +394,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost,
		return NULL;
		return NULL;
	}
	}


	shost = scsi_host_alloc(&iscsi_iser_sht, 0);
	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
	if (!shost)
	if (!shost)
		return NULL;
		return NULL;
	shost->transportt = iscsi_iser_scsi_transport;
	shost->transportt = iscsi_iser_scsi_transport;
@@ -405,9 +403,7 @@ iscsi_iser_session_create(struct Scsi_Host *shost,
	shost->max_channel = 0;
	shost->max_channel = 0;
	shost->max_cmd_len = 16;
	shost->max_cmd_len = 16;


	iscsi_host_setup(shost, qdepth);
	if (iscsi_host_add(shost, NULL))

	if (scsi_add_host(shost, NULL))
		goto free_host;
		goto free_host;
	*hostno = shost->host_no;
	*hostno = shost->host_no;


@@ -443,10 +439,9 @@ iscsi_iser_session_create(struct Scsi_Host *shost,
	return cls_session;
	return cls_session;


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


+7 −11
Original line number Original line Diff line number Diff line
@@ -1866,7 +1866,7 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
		return NULL;
		return NULL;
	}
	}


	shost = scsi_host_alloc(&iscsi_sht, sizeof(struct iscsi_host));
	shost = iscsi_host_alloc(&iscsi_sht, 0, qdepth);
	if (!shost)
	if (!shost)
		return NULL;
		return NULL;
	shost->transportt = iscsi_tcp_scsi_transport;
	shost->transportt = iscsi_tcp_scsi_transport;
@@ -1874,10 +1874,9 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
	shost->max_id = 0;
	shost->max_id = 0;
	shost->max_channel = 0;
	shost->max_channel = 0;
	shost->max_cmd_len = 16;
	shost->max_cmd_len = 16;
	shost->can_queue = cmds_max;


	iscsi_host_setup(shost, qdepth);
	if (iscsi_host_add(shost, NULL))

	if (scsi_add_host(shost, NULL))
		goto free_host;
		goto free_host;
	*hostno = shost->host_no;
	*hostno = shost->host_no;


@@ -1912,10 +1911,9 @@ iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
remove_session:
remove_session:
	iscsi_session_teardown(cls_session);
	iscsi_session_teardown(cls_session);
remove_host:
remove_host:
	scsi_remove_host(shost);
	iscsi_host_remove(shost);
free_host:
free_host:
	iscsi_host_teardown(shost);
	iscsi_host_free(shost);
	scsi_host_put(shost);
	return NULL;
	return NULL;
}
}


@@ -1924,11 +1922,9 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);


	iscsi_r2tpool_free(cls_session->dd_data);
	iscsi_r2tpool_free(cls_session->dd_data);
	iscsi_session_teardown(cls_session);


	scsi_remove_host(shost);
	iscsi_host_remove(shost);
	iscsi_host_teardown(shost);
	iscsi_host_free(shost);
	scsi_host_put(shost);
}
}


static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
+53 −7
Original line number Original line Diff line number Diff line
@@ -1764,8 +1764,39 @@ void iscsi_pool_free(struct iscsi_pool *q)
}
}
EXPORT_SYMBOL_GPL(iscsi_pool_free);
EXPORT_SYMBOL_GPL(iscsi_pool_free);


void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth)
/**
 * iscsi_host_add - add host to system
 * @shost: scsi host
 * @pdev: parent device
 *
 * This should be called by partial offload and software iscsi drivers
 * to add a host to the system.
 */
int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
{
	return scsi_add_host(shost, pdev);
}
EXPORT_SYMBOL_GPL(iscsi_host_add);

/**
 * iscsi_host_alloc - allocate a host and driver data
 * @sht: scsi host template
 * @dd_data_size: driver host data size
 * @qdepth: default device queue depth
 *
 * This should be called by partial offload and software iscsi drivers.
 * To access the driver specific memory use the iscsi_host_priv() macro.
 */
struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
				   int dd_data_size, uint16_t qdepth)
{
{
	struct Scsi_Host *shost;

	shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
	if (!shost)
		return NULL;
	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;

	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
	if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
		if (qdepth != 0)
		if (qdepth != 0)
			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
			printk(KERN_ERR "iscsi: invalid queue depth of %d. "
@@ -1773,22 +1804,37 @@ void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth)
			       qdepth, ISCSI_MAX_CMD_PER_LUN);
			       qdepth, ISCSI_MAX_CMD_PER_LUN);
		qdepth = ISCSI_DEF_CMD_PER_LUN;
		qdepth = ISCSI_DEF_CMD_PER_LUN;
	}
	}

	shost->transportt->create_work_queue = 1;
	shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
	shost->cmd_per_lun = qdepth;
	shost->cmd_per_lun = qdepth;
	return shost;
}
EXPORT_SYMBOL_GPL(iscsi_host_alloc);

/**
 * iscsi_host_remove - remove host and sessions
 * @shost: scsi host
 *
 * This will also remove any sessions attached to the host, but if userspace
 * is managing the session at the same time this will break. TODO: add
 * refcounting to the netlink iscsi interface so a rmmod or host hot unplug
 * does not remove the memory from under us.
 */
void iscsi_host_remove(struct Scsi_Host *shost)
{
	iscsi_host_for_each_session(shost, iscsi_session_teardown);
	scsi_remove_host(shost);
}
}
EXPORT_SYMBOL_GPL(iscsi_host_setup);
EXPORT_SYMBOL_GPL(iscsi_host_remove);


void iscsi_host_teardown(struct Scsi_Host *shost)
void iscsi_host_free(struct Scsi_Host *shost)
{
{
	struct iscsi_host *ihost = shost_priv(shost);
	struct iscsi_host *ihost = shost_priv(shost);


	kfree(ihost->netdev);
	kfree(ihost->netdev);
	kfree(ihost->hwaddress);
	kfree(ihost->hwaddress);
	kfree(ihost->initiatorname);
	kfree(ihost->initiatorname);
	scsi_host_put(shost);
}
}
EXPORT_SYMBOL_GPL(iscsi_host_teardown);
EXPORT_SYMBOL_GPL(iscsi_host_free);


/**
/**
 * iscsi_session_setup - create iscsi cls session and host and session
 * iscsi_session_setup - create iscsi cls session and host and session
+20 −0
Original line number Original line Diff line number Diff line
@@ -279,6 +279,24 @@ static int iscsi_is_session_dev(const struct device *dev)
	return dev->release == iscsi_session_release;
	return dev->release == iscsi_session_release;
}
}


static int iscsi_iter_session_fn(struct device *dev, void *data)
{
	void (* fn) (struct iscsi_cls_session *) = data;

	if (!iscsi_is_session_dev(dev))
		return 0;
	fn(iscsi_dev_to_session(dev));
	return 0;
}

void iscsi_host_for_each_session(struct Scsi_Host *shost,
				 void (*fn)(struct iscsi_cls_session *))
{
	device_for_each_child(&shost->shost_gendev, fn,
			      iscsi_iter_session_fn);
}
EXPORT_SYMBOL_GPL(iscsi_host_for_each_session);

/**
/**
 * iscsi_scan_finished - helper to report when running scans are done
 * iscsi_scan_finished - helper to report when running scans are done
 * @shost: scsi host
 * @shost: scsi host
@@ -1599,6 +1617,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
	priv->daemon_pid = -1;
	priv->daemon_pid = -1;
	priv->iscsi_transport = tt;
	priv->iscsi_transport = tt;
	priv->t.user_scan = iscsi_user_scan;
	priv->t.user_scan = iscsi_user_scan;
	if (!(tt->caps & CAP_DATA_PATH_OFFLOAD))
		priv->t.create_work_queue = 1;


	priv->dev.class = &iscsi_transport_class;
	priv->dev.class = &iscsi_transport_class;
	snprintf(priv->dev.bus_id, BUS_ID_SIZE, "%s", tt->name);
	snprintf(priv->dev.bus_id, BUS_ID_SIZE, "%s", tt->name);
+9 −2
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@
#include <scsi/iscsi_if.h>
#include <scsi/iscsi_if.h>


struct scsi_transport_template;
struct scsi_transport_template;
struct scsi_host_template;
struct scsi_device;
struct scsi_device;
struct Scsi_Host;
struct Scsi_Host;
struct scsi_cmnd;
struct scsi_cmnd;
@@ -41,6 +42,7 @@ struct iscsi_cls_session;
struct iscsi_cls_conn;
struct iscsi_cls_conn;
struct iscsi_session;
struct iscsi_session;
struct iscsi_nopin;
struct iscsi_nopin;
struct device;


/* #define DEBUG_SCSI */
/* #define DEBUG_SCSI */
#ifdef DEBUG_SCSI
#ifdef DEBUG_SCSI
@@ -311,6 +313,8 @@ struct iscsi_host {
	char			local_address[ISCSI_ADDRESS_BUF_LEN];
	char			local_address[ISCSI_ADDRESS_BUF_LEN];
};
};


#define iscsi_host_priv(_shost) \
	(shost_priv(_shost) + sizeof(struct iscsi_host))
/*
/*
 * scsi host template
 * scsi host template
 */
 */
@@ -330,8 +334,11 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost,
				int buflen);
				int buflen);
extern int iscsi_host_get_param(struct Scsi_Host *shost,
extern int iscsi_host_get_param(struct Scsi_Host *shost,
				enum iscsi_host_param param, char *buf);
				enum iscsi_host_param param, char *buf);
extern void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth);
extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
extern void iscsi_host_teardown(struct Scsi_Host *shost);
extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
					  int dd_data_size, uint16_t qdepth);
extern void iscsi_host_remove(struct Scsi_Host *shost);
extern void iscsi_host_free(struct Scsi_Host *shost);


/*
/*
 * session management
 * session management
Loading