aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-01-13 19:05:50 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-14 11:55:20 -0500
commit7b8631b53bea286b68847a939b87135198335b66 (patch)
tree69a3d47f4d00f98771c4eb3cb6bc11fde0a6e0a1 /drivers/scsi/iscsi_tcp.c
parent7cae5159dd2623300cf9820865bfbf6dcdb7c1b9 (diff)
[SCSI] iscsi: seperate iscsi interface from setup functions
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>
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c118
1 files changed, 70 insertions, 48 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 0acc4b235d9b..e31d350e6b67 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -2435,17 +2435,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
2435 kfree(items); 2435 kfree(items);
2436} 2436}
2437 2437
2438static iscsi_connh_t 2438static struct iscsi_cls_conn *
2439iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) 2439iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
2440{ 2440{
2441 struct iscsi_session *session = iscsi_ptr(sessionh); 2441 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
2442 struct iscsi_conn *conn = NULL; 2442 struct iscsi_conn *conn;
2443 struct iscsi_cls_conn *cls_conn;
2443 2444
2444 conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL); 2445 cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata),
2445 if (conn == NULL) 2446 conn_idx);
2446 goto conn_alloc_fail; 2447 if (!cls_conn)
2447 memset(conn, 0, sizeof(struct iscsi_conn)); 2448 return NULL;
2449 conn = cls_conn->dd_data;
2448 2450
2451 memset(conn, 0, sizeof(struct iscsi_conn));
2449 conn->c_stage = ISCSI_CONN_INITIAL_STAGE; 2452 conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
2450 conn->in_progress = IN_PROGRESS_WAIT_HEADER; 2453 conn->in_progress = IN_PROGRESS_WAIT_HEADER;
2451 conn->id = conn_idx; 2454 conn->id = conn_idx;
@@ -2507,7 +2510,7 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
2507 mutex_init(&conn->xmitmutex); 2510 mutex_init(&conn->xmitmutex);
2508 init_waitqueue_head(&conn->ehwait); 2511 init_waitqueue_head(&conn->ehwait);
2509 2512
2510 return iscsi_handle(conn); 2513 return cls_conn;
2511 2514
2512max_recv_dlenght_alloc_fail: 2515max_recv_dlenght_alloc_fail:
2513 spin_lock_bh(&session->lock); 2516 spin_lock_bh(&session->lock);
@@ -2523,15 +2526,14 @@ immqueue_alloc_fail:
2523writequeue_alloc_fail: 2526writequeue_alloc_fail:
2524 kfifo_free(conn->xmitqueue); 2527 kfifo_free(conn->xmitqueue);
2525xmitqueue_alloc_fail: 2528xmitqueue_alloc_fail:
2526 kfree(conn); 2529 iscsi_destroy_conn(cls_conn);
2527conn_alloc_fail: 2530 return NULL;
2528 return iscsi_handle(NULL);
2529} 2531}
2530 2532
2531static void 2533static void
2532iscsi_conn_destroy(iscsi_connh_t connh) 2534iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
2533{ 2535{
2534 struct iscsi_conn *conn = iscsi_ptr(connh); 2536 struct iscsi_conn *conn = cls_conn->dd_data;
2535 struct iscsi_session *session = conn->session; 2537 struct iscsi_session *session = conn->session;
2536 unsigned long flags; 2538 unsigned long flags;
2537 2539
@@ -2626,7 +2628,8 @@ iscsi_conn_destroy(iscsi_connh_t connh)
2626 kfifo_free(conn->writequeue); 2628 kfifo_free(conn->writequeue);
2627 kfifo_free(conn->immqueue); 2629 kfifo_free(conn->immqueue);
2628 kfifo_free(conn->mgmtqueue); 2630 kfifo_free(conn->mgmtqueue);
2629 kfree(conn); 2631
2632 iscsi_destroy_conn(cls_conn);
2630} 2633}
2631 2634
2632static int 2635static int
@@ -3257,17 +3260,23 @@ static struct scsi_host_template iscsi_sht = {
3257 .this_id = -1, 3260 .this_id = -1,
3258}; 3261};
3259 3262
3260static iscsi_sessionh_t 3263static struct iscsi_transport iscsi_tcp_transport;
3261iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) 3264
3265static struct Scsi_Host *
3266iscsi_session_create(struct scsi_transport_template *scsit,
3267 uint32_t initial_cmdsn)
3262{ 3268{
3263 int cmd_i; 3269 struct Scsi_Host *shost;
3264 struct iscsi_session *session; 3270 struct iscsi_session *session;
3271 int cmd_i;
3265 3272
3266 session = iscsi_hostdata(host->hostdata); 3273 shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport);
3267 memset(session, 0, sizeof(struct iscsi_session)); 3274 if (!shost)
3275 return NULL;
3268 3276
3269 session->host = host; 3277 session = iscsi_hostdata(shost->hostdata);
3270 session->id = host->host_no; 3278 memset(session, 0, sizeof(struct iscsi_session));
3279 session->host = shost;
3271 session->state = ISCSI_STATE_LOGGED_IN; 3280 session->state = ISCSI_STATE_LOGGED_IN;
3272 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; 3281 session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
3273 session->cmds_max = ISCSI_XMIT_CMDS_MAX; 3282 session->cmds_max = ISCSI_XMIT_CMDS_MAX;
@@ -3311,7 +3320,7 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
3311 if (iscsi_r2tpool_alloc(session)) 3320 if (iscsi_r2tpool_alloc(session))
3312 goto r2tpool_alloc_fail; 3321 goto r2tpool_alloc_fail;
3313 3322
3314 return iscsi_handle(session); 3323 return shost;
3315 3324
3316r2tpool_alloc_fail: 3325r2tpool_alloc_fail:
3317 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) 3326 for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
@@ -3321,15 +3330,15 @@ immdata_alloc_fail:
3321mgmtpool_alloc_fail: 3330mgmtpool_alloc_fail:
3322 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 3331 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
3323cmdpool_alloc_fail: 3332cmdpool_alloc_fail:
3324 return iscsi_handle(NULL); 3333 return NULL;
3325} 3334}
3326 3335
3327static void 3336static void
3328iscsi_session_destroy(iscsi_sessionh_t sessionh) 3337iscsi_session_destroy(struct Scsi_Host *shost)
3329{ 3338{
3339 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
3330 int cmd_i; 3340 int cmd_i;
3331 struct iscsi_data_task *dtask, *n; 3341 struct iscsi_data_task *dtask, *n;
3332 struct iscsi_session *session = iscsi_ptr(sessionh);
3333 3342
3334 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { 3343 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
3335 struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; 3344 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
@@ -3345,6 +3354,8 @@ iscsi_session_destroy(iscsi_sessionh_t sessionh)
3345 iscsi_r2tpool_free(session); 3354 iscsi_r2tpool_free(session);
3346 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); 3355 iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
3347 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 3356 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
3357
3358 iscsi_transport_destroy_session(shost);
3348} 3359}
3349 3360
3350static int 3361static int
@@ -3493,25 +3504,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
3493} 3504}
3494 3505
3495static int 3506static int
3496iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, 3507iscsi_session_get_param(struct Scsi_Host *shost,
3497 uint32_t *value) 3508 enum iscsi_param param, uint32_t *value)
3498{ 3509{
3499 struct iscsi_conn *conn = iscsi_ptr(connh); 3510 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
3500 struct iscsi_session *session = conn->session;
3501 3511
3502 switch(param) { 3512 switch(param) {
3503 case ISCSI_PARAM_MAX_RECV_DLENGTH:
3504 *value = conn->max_recv_dlength;
3505 break;
3506 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
3507 *value = conn->max_xmit_dlength;
3508 break;
3509 case ISCSI_PARAM_HDRDGST_EN:
3510 *value = conn->hdrdgst_en;
3511 break;
3512 case ISCSI_PARAM_DATADGST_EN:
3513 *value = conn->datadgst_en;
3514 break;
3515 case ISCSI_PARAM_INITIAL_R2T_EN: 3513 case ISCSI_PARAM_INITIAL_R2T_EN:
3516 *value = session->initial_r2t_en; 3514 *value = session->initial_r2t_en;
3517 break; 3515 break;
@@ -3549,6 +3547,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
3549 return 0; 3547 return 0;
3550} 3548}
3551 3549
3550static int
3551iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
3552{
3553 struct iscsi_conn *conn = data;
3554
3555 switch(param) {
3556 case ISCSI_PARAM_MAX_RECV_DLENGTH:
3557 *value = conn->max_recv_dlength;
3558 break;
3559 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
3560 *value = conn->max_xmit_dlength;
3561 break;
3562 case ISCSI_PARAM_HDRDGST_EN:
3563 *value = conn->hdrdgst_en;
3564 break;
3565 case ISCSI_PARAM_DATADGST_EN:
3566 *value = conn->datadgst_en;
3567 break;
3568 default:
3569 return ISCSI_ERR_PARAM_NOT_FOUND;
3570 }
3571
3572 return 0;
3573}
3574
3552static void 3575static void
3553iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) 3576iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
3554{ 3577{
@@ -3593,6 +3616,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
3593 | CAP_DATADGST, 3616 | CAP_DATADGST,
3594 .host_template = &iscsi_sht, 3617 .host_template = &iscsi_sht,
3595 .hostdata_size = sizeof(struct iscsi_session), 3618 .hostdata_size = sizeof(struct iscsi_session),
3619 .conndata_size = sizeof(struct iscsi_conn),
3596 .max_conn = 1, 3620 .max_conn = 1,
3597 .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, 3621 .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
3598 .create_session = iscsi_session_create, 3622 .create_session = iscsi_session_create,
@@ -3601,7 +3625,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
3601 .bind_conn = iscsi_conn_bind, 3625 .bind_conn = iscsi_conn_bind,
3602 .destroy_conn = iscsi_conn_destroy, 3626 .destroy_conn = iscsi_conn_destroy,
3603 .set_param = iscsi_conn_set_param, 3627 .set_param = iscsi_conn_set_param,
3604 .get_param = iscsi_conn_get_param, 3628 .get_conn_param = iscsi_conn_get_param,
3629 .get_session_param = iscsi_session_get_param,
3605 .start_conn = iscsi_conn_start, 3630 .start_conn = iscsi_conn_start,
3606 .stop_conn = iscsi_conn_stop, 3631 .stop_conn = iscsi_conn_stop,
3607 .send_pdu = iscsi_conn_send_pdu, 3632 .send_pdu = iscsi_conn_send_pdu,
@@ -3611,8 +3636,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
3611static int __init 3636static int __init
3612iscsi_tcp_init(void) 3637iscsi_tcp_init(void)
3613{ 3638{
3614 int error;
3615
3616 if (iscsi_max_lun < 1) { 3639 if (iscsi_max_lun < 1) {
3617 printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); 3640 printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
3618 return -EINVAL; 3641 return -EINVAL;
@@ -3625,11 +3648,10 @@ iscsi_tcp_init(void)
3625 if (!taskcache) 3648 if (!taskcache)
3626 return -ENOMEM; 3649 return -ENOMEM;
3627 3650
3628 error = iscsi_register_transport(&iscsi_tcp_transport); 3651 if (!iscsi_register_transport(&iscsi_tcp_transport))
3629 if (error)
3630 kmem_cache_destroy(taskcache); 3652 kmem_cache_destroy(taskcache);
3631 3653
3632 return error; 3654 return 0;
3633} 3655}
3634 3656
3635static void __exit 3657static void __exit