Commit 75613521 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] iscsi: remove session and host binding in libiscsi

bnx2i allocates a host per netdevice but will use libiscsi,
so this unbinds the session from the host in that code.

This will also be useful for the iser parent device dma settings
fixes.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 32c6e1b9
......@@ -74,6 +74,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);
......@@ -363,40 +367,64 @@ 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_session_teardown(cls_session);
scsi_remove_host(shost);
iscsi_host_teardown(shost);
scsi_host_put(shost);
}
static struct iscsi_cls_session *
iscsi_iser_session_create(struct iscsi_transport *iscsit,
struct scsi_transport_template *scsit,
struct Scsi_Host *shost,
uint16_t cmds_max, uint16_t qdepth,
uint32_t initial_cmdsn, uint32_t *hostno)
iscsi_iser_session_create(struct Scsi_Host *shost,
uint16_t cmds_max, uint16_t qdepth,
uint32_t initial_cmdsn, uint32_t *hostno)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
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;
if (shost) {
printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n",
shost->host_no);
return NULL;
}
shost = scsi_host_alloc(&iscsi_iser_sht, 0);
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;
iscsi_host_setup(shost, qdepth);
if (scsi_add_host(shost, 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);
initial_cmdsn);
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->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];
......@@ -413,6 +441,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit,
}
return cls_session;
remove_host:
scsi_remove_host(shost);
free_host:
iscsi_host_teardown(shost);
scsi_host_put(shost);
return NULL;
}
static int
......@@ -589,12 +624,11 @@ static struct iscsi_transport iscsi_iser_transport = {
.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,
.sessiondata_size = sizeof(struct iscsi_session),
/* 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,
......@@ -633,8 +667,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",
......@@ -650,7 +682,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;
......
......@@ -64,6 +64,10 @@ MODULE_LICENSE("GPL");
#define BUG_ON(expr)
#endif
static struct scsi_transport_template *iscsi_tcp_scsi_transport;
static struct scsi_host_template iscsi_sht;
static struct iscsi_transport iscsi_tcp_transport;
static unsigned int iscsi_max_lun = 512;
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
......@@ -1623,6 +1627,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
int is_leading)
{
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
struct iscsi_host *ihost = shost_priv(shost);
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct sock *sk;
......@@ -1646,8 +1652,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
if (err)
goto free_socket;
err = iscsi_tcp_get_addr(conn, sock, conn->local_address,
&conn->local_port, kernel_getsockname);
err = iscsi_tcp_get_addr(conn, sock, ihost->local_address,
&ihost->local_port, kernel_getsockname);
if (err)
goto free_socket;
......@@ -1821,29 +1827,6 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
return len;
}
static int
iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
char *buf)
{
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
int len;
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
spin_lock_bh(&session->lock);
if (!session->leadconn)
len = -ENODEV;
else
len = sprintf(buf, "%s\n",
session->leadconn->local_address);
spin_unlock_bh(&session->lock);
break;
default:
return iscsi_host_get_param(shost, param, buf);
}
return len;
}
static void
iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
{
......@@ -1869,26 +1852,44 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
}
static struct iscsi_cls_session *
iscsi_tcp_session_create(struct iscsi_transport *iscsit,
struct scsi_transport_template *scsit,
struct Scsi_Host *shost, uint16_t cmds_max,
iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
uint16_t qdepth, uint32_t initial_cmdsn,
uint32_t *hostno)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
uint32_t hn;
int cmd_i;
cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth,
sizeof(struct iscsi_tcp_cmd_task),
sizeof(struct iscsi_tcp_mgmt_task),
initial_cmdsn, &hn);
if (!cls_session)
if (shost) {
printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n",
shost->host_no);
return NULL;
}
shost = scsi_host_alloc(&iscsi_sht, sizeof(struct iscsi_host));
if (!shost)
return NULL;
*hostno = hn;
shost->transportt = iscsi_tcp_scsi_transport;
shost->max_lun = iscsi_max_lun;
shost->max_id = 0;
shost->max_channel = 0;
shost->max_cmd_len = 16;
iscsi_host_setup(shost, qdepth);
if (scsi_add_host(shost, NULL))
goto free_host;
*hostno = shost->host_no;
cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
sizeof(struct iscsi_tcp_cmd_task),
sizeof(struct iscsi_tcp_mgmt_task),
initial_cmdsn);
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
session = class_to_transport_session(cls_session);
shost->can_queue = session->cmds_max;
for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
......@@ -1904,20 +1905,30 @@ iscsi_tcp_session_create(struct iscsi_transport *iscsit,
mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
}
if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
goto r2tpool_alloc_fail;
if (iscsi_r2tpool_alloc(session))
goto remove_session;
return cls_session;
r2tpool_alloc_fail:
remove_session:
iscsi_session_teardown(cls_session);
remove_host:
scsi_remove_host(shost);
free_host:
iscsi_host_teardown(shost);
scsi_host_put(shost);
return NULL;
}
static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
{
iscsi_r2tpool_free(class_to_transport_session(cls_session));
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
iscsi_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
scsi_remove_host(shost);
iscsi_host_teardown(shost);
scsi_host_put(shost);
}
static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
......@@ -1976,8 +1987,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
.host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
ISCSI_HOST_INITIATOR_NAME |
ISCSI_HOST_NETDEV_NAME,
.host_template = &iscsi_sht,
.conndata_size = sizeof(struct iscsi_conn),
.sessiondata_size = sizeof(struct iscsi_session),
/* session management */
.create_session = iscsi_tcp_session_create,
.destroy_session = iscsi_tcp_session_destroy,
......@@ -1991,7 +2002,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_tcp_conn_stop,
/* iscsi host params */
.get_host_param = iscsi_tcp_host_get_param,
.get_host_param = iscsi_host_get_param,
.set_host_param = iscsi_host_set_param,
/* IO */
.send_pdu = iscsi_conn_send_pdu,
......@@ -2013,9 +2024,10 @@ iscsi_tcp_init(void)
iscsi_max_lun);
return -EINVAL;
}
iscsi_tcp_transport.max_lun = iscsi_max_lun;
if (!iscsi_register_transport(&iscsi_tcp_transport))
iscsi_tcp_scsi_transport = iscsi_register_transport(
&iscsi_tcp_transport);
if (!iscsi_tcp_scsi_transport)
return -ENODEV;
return 0;
......
This diff is collapsed.
......@@ -114,7 +114,6 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
ISCSI_HOST_IPADDRESS |
ISCSI_HOST_INITIATOR_NAME,
.sessiondata_size = sizeof(struct ddb_entry),
.host_template = &qla4xxx_driver_template,
.tgt_dscvr = qla4xxx_tgt_dscvr,
.get_conn_param = qla4xxx_conn_get_param,
......
......@@ -101,12 +101,10 @@ show_transport_##name(struct device *dev, \
static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
show_transport_attr(caps, "0x%x");
show_transport_attr(max_lun, "%d");
static struct attribute *iscsi_transport_attrs[] = {
&dev_attr_handle.attr,
&dev_attr_caps.attr,
&dev_attr_max_lun.attr,
NULL,
};
......@@ -1034,8 +1032,7 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev,
}
}
session = transport->create_session(transport, &priv->t, shost,
cmds_max, queue_depth,
session = transport->create_session(shost, cmds_max, queue_depth,
initial_cmdsn, &host_no);
if (shost)
scsi_host_put(shost);
......
......@@ -310,13 +310,6 @@ enum iscsi_host_param {
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
/**
* iscsi_hostdata - get LLD hostdata from scsi_host
* @_hostdata: pointer to scsi host's hostdata
**/
#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
/*
* These flags presents iSCSI Data-Path capabilities.
......
......@@ -209,9 +209,6 @@ struct iscsi_conn {
/* remote portal currently connected to */
int portal_port;
char portal_address[ISCSI_ADDRESS_BUF_LEN];
/* local address */
int local_port;
char local_address[ISCSI_ADDRESS_BUF_LEN];
/* MIB-statistics */
uint64_t txdata_octets;
......@@ -247,6 +244,7 @@ enum {
};
struct iscsi_session {
struct iscsi_cls_session *cls_session;
/*
* Syncs up the scsi eh thread with the iscsi eh thread when sending
* task management functions. This must be taken before the session
......@@ -282,10 +280,6 @@ struct iscsi_session {
char *password;
char *password_in;
char *targetname;
char *initiatorname;
/* hw address or netdev iscsi connection is bound to */
char *hwaddress;
char *netdev;
/* control data */
struct iscsi_transport *tt;
struct Scsi_Host *host;
......@@ -307,6 +301,16 @@ struct iscsi_session {
struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */
};
struct iscsi_host {
char *initiatorname;
/* hw address or netdev iscsi connection is bound to */
char *hwaddress;
char *netdev;
/* local address */
int local_port;
char local_address[ISCSI_ADDRESS_BUF_LEN];
};
/*
* scsi host template
*/
......@@ -326,27 +330,24 @@ extern int iscsi_host_set_param(struct Scsi_Host *shost,
int buflen);
extern int iscsi_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf);
extern void iscsi_host_setup(struct Scsi_Host *shost, uint16_t qdepth);
extern void iscsi_host_teardown(struct Scsi_Host *shost);
/*
* session management
*/
extern struct iscsi_cls_session *
iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *,
uint16_t, uint16_t, int, int, uint32_t, uint32_t *);
iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
uint16_t, int, int, uint32_t);
extern void iscsi_session_teardown(struct iscsi_cls_session *);
extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *);
extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf, int buflen);
extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
enum iscsi_param param, char *buf);
#define session_to_cls(_sess) \
hostdata_session(_sess->host->hostdata)
#define iscsi_session_printk(prefix, _sess, fmt, a...) \
iscsi_cls_session_printk(prefix, \
(struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a)
iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a)
/*
* connection management
......
......@@ -83,15 +83,13 @@ struct iscsi_transport {
/* LLD sets this to indicate what values it can export to sysfs */
uint64_t param_mask;
uint64_t host_param_mask;
struct scsi_host_template *host_template;
/* LLD connection data size */
int conndata_size;
/* LLD session data size */
int sessiondata_size;
int max_lun;
struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
struct scsi_transport_template *t, struct Scsi_Host *shost,
uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn);
struct iscsi_cls_session *(*create_session) (struct Scsi_Host *shost,
uint16_t cmds_max, uint16_t qdepth,
uint32_t sn, uint32_t *hn);
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment