Skip to content

Commit

Permalink
[SCSI] iscsi: seperate iscsi interface from setup functions
Browse files Browse the repository at this point in the history
This is the second version of the patch to address Christoph's comments.
Instead of doing the lib, I just kept everything in scsi_trnapsort_iscsi.c
like the FC and SPI class. This was becuase the driver model and sysfs
class is tied to the session and connection setup so separating did not
buy very much at this time.

The reason for this patch was becuase HW iscsi LLDs like qla4xxx cannot
use the iscsi class becuase the scsi_host was tied to the interface and
class code. This patch just seperates the session from scsi host so
that LLDs that allocate the host per some resource like pci device
can still use the class.

This is also fixes a couple refcount bugs that can be triggered
when users have a sysfs file open, close the session, then
read or write to the file.

Signed-off-by: Alex Aizman <itn780@yahoo.com>
Signed-off-by: Dmitry Yusupov <dmitry_yus@yahoo.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
  • Loading branch information
Mike Christie authored and James Bottomley committed Jan 14, 2006
1 parent 7cae515 commit 7b8631b
Show file tree
Hide file tree
Showing 4 changed files with 583 additions and 461 deletions.
118 changes: 70 additions & 48 deletions drivers/scsi/iscsi_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2435,17 +2435,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
kfree(items);
}

static iscsi_connh_t
iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
static struct iscsi_cls_conn *
iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
{
struct iscsi_session *session = iscsi_ptr(sessionh);
struct iscsi_conn *conn = NULL;
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
struct iscsi_conn *conn;
struct iscsi_cls_conn *cls_conn;

conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
if (conn == NULL)
goto conn_alloc_fail;
memset(conn, 0, sizeof(struct iscsi_conn));
cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata),
conn_idx);
if (!cls_conn)
return NULL;
conn = cls_conn->dd_data;

memset(conn, 0, sizeof(struct iscsi_conn));
conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
conn->in_progress = IN_PROGRESS_WAIT_HEADER;
conn->id = conn_idx;
Expand Down Expand Up @@ -2507,7 +2510,7 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
mutex_init(&conn->xmitmutex);
init_waitqueue_head(&conn->ehwait);

return iscsi_handle(conn);
return cls_conn;

max_recv_dlenght_alloc_fail:
spin_lock_bh(&session->lock);
Expand All @@ -2523,15 +2526,14 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
writequeue_alloc_fail:
kfifo_free(conn->xmitqueue);
xmitqueue_alloc_fail:
kfree(conn);
conn_alloc_fail:
return iscsi_handle(NULL);
iscsi_destroy_conn(cls_conn);
return NULL;
}

static void
iscsi_conn_destroy(iscsi_connh_t connh)
iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
{
struct iscsi_conn *conn = iscsi_ptr(connh);
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
unsigned long flags;

Expand Down Expand Up @@ -2626,7 +2628,8 @@ iscsi_conn_destroy(iscsi_connh_t connh)
kfifo_free(conn->writequeue);
kfifo_free(conn->immqueue);
kfifo_free(conn->mgmtqueue);
kfree(conn);

iscsi_destroy_conn(cls_conn);
}

static int
Expand Down Expand Up @@ -3257,17 +3260,23 @@ static struct scsi_host_template iscsi_sht = {
.this_id = -1,
};

static iscsi_sessionh_t
iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
static struct iscsi_transport iscsi_tcp_transport;

static struct Scsi_Host *
iscsi_session_create(struct scsi_transport_template *scsit,
uint32_t initial_cmdsn)
{
int cmd_i;
struct Scsi_Host *shost;
struct iscsi_session *session;
int cmd_i;

session = iscsi_hostdata(host->hostdata);
memset(session, 0, sizeof(struct iscsi_session));
shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport);
if (!shost)
return NULL;

session->host = host;
session->id = host->host_no;
session = iscsi_hostdata(shost->hostdata);
memset(session, 0, sizeof(struct iscsi_session));
session->host = shost;
session->state = ISCSI_STATE_LOGGED_IN;
session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
session->cmds_max = ISCSI_XMIT_CMDS_MAX;
Expand Down Expand Up @@ -3311,7 +3320,7 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
if (iscsi_r2tpool_alloc(session))
goto r2tpool_alloc_fail;

return iscsi_handle(session);
return shost;

r2tpool_alloc_fail:
for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
Expand All @@ -3321,15 +3330,15 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
mgmtpool_alloc_fail:
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
cmdpool_alloc_fail:
return iscsi_handle(NULL);
return NULL;
}

static void
iscsi_session_destroy(iscsi_sessionh_t sessionh)
iscsi_session_destroy(struct Scsi_Host *shost)
{
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
int cmd_i;
struct iscsi_data_task *dtask, *n;
struct iscsi_session *session = iscsi_ptr(sessionh);

for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
Expand All @@ -3345,6 +3354,8 @@ iscsi_session_destroy(iscsi_sessionh_t sessionh)
iscsi_r2tpool_free(session);
iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);

iscsi_transport_destroy_session(shost);
}

static int
Expand Down Expand Up @@ -3493,25 +3504,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
}

static int
iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
uint32_t *value)
iscsi_session_get_param(struct Scsi_Host *shost,
enum iscsi_param param, uint32_t *value)
{
struct iscsi_conn *conn = iscsi_ptr(connh);
struct iscsi_session *session = conn->session;
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);

switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH:
*value = conn->max_recv_dlength;
break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
*value = conn->max_xmit_dlength;
break;
case ISCSI_PARAM_HDRDGST_EN:
*value = conn->hdrdgst_en;
break;
case ISCSI_PARAM_DATADGST_EN:
*value = conn->datadgst_en;
break;
case ISCSI_PARAM_INITIAL_R2T_EN:
*value = session->initial_r2t_en;
break;
Expand Down Expand Up @@ -3549,6 +3547,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
return 0;
}

static int
iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
{
struct iscsi_conn *conn = data;

switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH:
*value = conn->max_recv_dlength;
break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
*value = conn->max_xmit_dlength;
break;
case ISCSI_PARAM_HDRDGST_EN:
*value = conn->hdrdgst_en;
break;
case ISCSI_PARAM_DATADGST_EN:
*value = conn->datadgst_en;
break;
default:
return ISCSI_ERR_PARAM_NOT_FOUND;
}

return 0;
}

static void
iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
{
Expand Down Expand Up @@ -3593,6 +3616,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
| CAP_DATADGST,
.host_template = &iscsi_sht,
.hostdata_size = sizeof(struct iscsi_session),
.conndata_size = sizeof(struct iscsi_conn),
.max_conn = 1,
.max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
.create_session = iscsi_session_create,
Expand All @@ -3601,7 +3625,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
.bind_conn = iscsi_conn_bind,
.destroy_conn = iscsi_conn_destroy,
.set_param = iscsi_conn_set_param,
.get_param = iscsi_conn_get_param,
.get_conn_param = iscsi_conn_get_param,
.get_session_param = iscsi_session_get_param,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
.send_pdu = iscsi_conn_send_pdu,
Expand All @@ -3611,8 +3636,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
static int __init
iscsi_tcp_init(void)
{
int error;

if (iscsi_max_lun < 1) {
printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
return -EINVAL;
Expand All @@ -3625,11 +3648,10 @@ iscsi_tcp_init(void)
if (!taskcache)
return -ENOMEM;

error = iscsi_register_transport(&iscsi_tcp_transport);
if (error)
if (!iscsi_register_transport(&iscsi_tcp_transport))
kmem_cache_destroy(taskcache);

return error;
return 0;
}

static void __exit
Expand Down
Loading

0 comments on commit 7b8631b

Please sign in to comment.