aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
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