summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c116
1 files changed, 13 insertions, 103 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index e2b67e34d92e..bc9071d2d212 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -472,106 +472,6 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
/*
- * These functions are used only by software iscsi_transports
- * which do not allocate and more their scsi_hosts since this
- * is initiated from userspace.
- */
-
-/*
- * iSCSI Session's hostdata organization:
- *
- * *------------------* <== hostdata_session(host->hostdata)
- * | ptr to class sess|
- * |------------------| <== iscsi_hostdata(host->hostdata)
- * | transport's data |
- * *------------------*
- */
-
-#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \
- _t->hostdata_size % sizeof(unsigned long))
-
-#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
-
-/**
- * iscsi_transport_create_session - create iscsi cls session and host
- * scsit: scsi transport template
- * transport: iscsi transport template
- *
- * This can be used by software iscsi_transports that allocate
- * a session per scsi host.
- **/
-struct Scsi_Host *
-iscsi_transport_create_session(struct scsi_transport_template *scsit,
- struct iscsi_transport *transport)
-{
- struct iscsi_cls_session *session;
- struct Scsi_Host *shost;
- unsigned long flags;
-
- shost = scsi_host_alloc(transport->host_template,
- hostdata_privsize(transport));
- if (!shost) {
- printk(KERN_ERR "iscsi: can not allocate SCSI host for "
- "session\n");
- return NULL;
- }
-
- shost->max_id = 1;
- shost->max_channel = 0;
- shost->max_lun = transport->max_lun;
- shost->max_cmd_len = transport->max_cmd_len;
- shost->transportt = scsit;
- shost->transportt->create_work_queue = 1;
-
- if (scsi_add_host(shost, NULL))
- goto free_host;
-
- session = iscsi_create_session(shost, transport, 0);
- if (!session)
- goto remove_host;
-
- *(unsigned long*)shost->hostdata = (unsigned long)session;
- spin_lock_irqsave(&sesslock, flags);
- list_add(&session->sess_list, &sesslist);
- spin_unlock_irqrestore(&sesslock, flags);
- return shost;
-
-remove_host:
- scsi_remove_host(shost);
-free_host:
- scsi_host_put(shost);
- return NULL;
-}
-
-EXPORT_SYMBOL_GPL(iscsi_transport_create_session);
-
-/**
- * iscsi_transport_destroy_session - destroy session and scsi host
- * shost: scsi host
- *
- * This can be used by software iscsi_transports that allocate
- * a session per scsi host.
- **/
-int iscsi_transport_destroy_session(struct Scsi_Host *shost)
-{
- struct iscsi_cls_session *session;
- unsigned long flags;
-
- session = hostdata_session(shost->hostdata);
- spin_lock_irqsave(&sesslock, flags);
- list_del(&session->sess_list);
- spin_unlock_irqrestore(&sesslock, flags);
- iscsi_destroy_session(session);
-
- scsi_remove_host(shost);
- /* ref from host alloc */
- scsi_host_put(shost);
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session);
-
-/*
* iscsi interface functions
*/
static struct iscsi_internal *
@@ -857,14 +757,19 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)
{
struct iscsi_transport *transport = priv->iscsi_transport;
struct iscsi_cls_session *session;
+ unsigned long flags;
uint32_t hostno;
- session = transport->create_session(&priv->t,
+ session = transport->create_session(transport, &priv->t,
ev->u.c_session.initial_cmdsn,
&hostno);
if (!session)
return -ENOMEM;
+ spin_lock_irqsave(&sesslock, flags);
+ list_add(&session->sess_list, &sesslist);
+ spin_unlock_irqrestore(&sesslock, flags);
+
ev->r.c_session_ret.host_no = hostno;
ev->r.c_session_ret.sid = session->sid;
return 0;
@@ -1032,6 +937,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct iscsi_internal *priv;
struct iscsi_cls_session *session;
struct iscsi_cls_conn *conn;
+ unsigned long flags;
priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle));
if (!priv)
@@ -1047,9 +953,13 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
break;
case ISCSI_UEVENT_DESTROY_SESSION:
session = iscsi_session_lookup(ev->u.d_session.sid);
- if (session)
+ if (session) {
+ spin_lock_irqsave(&sesslock, flags);
+ list_del(&session->sess_list);
+ spin_unlock_irqrestore(&sesslock, flags);
+
transport->destroy_session(session);
- else
+ } else
err = -EINVAL;
break;
case ISCSI_UEVENT_CREATE_CONN: