Skip to content

Commit

Permalink
[SCSI] iscsi: remove session and host binding in libiscsi
Browse files Browse the repository at this point in the history
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: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Jul 12, 2008
1 parent 32c6e1b commit 7561352
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 216 deletions.
74 changes: 54 additions & 20 deletions drivers/infiniband/ulp/iser/iscsi_iser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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];
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand All @@ -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;
Expand Down
102 changes: 57 additions & 45 deletions drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 7561352

Please sign in to comment.