diff options
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 118 |
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 | ||
2438 | static iscsi_connh_t | 2438 | static struct iscsi_cls_conn * |
2439 | iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) | 2439 | iscsi_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 | ||
2512 | max_recv_dlenght_alloc_fail: | 2515 | max_recv_dlenght_alloc_fail: |
2513 | spin_lock_bh(&session->lock); | 2516 | spin_lock_bh(&session->lock); |
@@ -2523,15 +2526,14 @@ immqueue_alloc_fail: | |||
2523 | writequeue_alloc_fail: | 2526 | writequeue_alloc_fail: |
2524 | kfifo_free(conn->xmitqueue); | 2527 | kfifo_free(conn->xmitqueue); |
2525 | xmitqueue_alloc_fail: | 2528 | xmitqueue_alloc_fail: |
2526 | kfree(conn); | 2529 | iscsi_destroy_conn(cls_conn); |
2527 | conn_alloc_fail: | 2530 | return NULL; |
2528 | return iscsi_handle(NULL); | ||
2529 | } | 2531 | } |
2530 | 2532 | ||
2531 | static void | 2533 | static void |
2532 | iscsi_conn_destroy(iscsi_connh_t connh) | 2534 | iscsi_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 | ||
2632 | static int | 2635 | static int |
@@ -3257,17 +3260,23 @@ static struct scsi_host_template iscsi_sht = { | |||
3257 | .this_id = -1, | 3260 | .this_id = -1, |
3258 | }; | 3261 | }; |
3259 | 3262 | ||
3260 | static iscsi_sessionh_t | 3263 | static struct iscsi_transport iscsi_tcp_transport; |
3261 | iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) | 3264 | |
3265 | static struct Scsi_Host * | ||
3266 | iscsi_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 | ||
3316 | r2tpool_alloc_fail: | 3325 | r2tpool_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: | |||
3321 | mgmtpool_alloc_fail: | 3330 | mgmtpool_alloc_fail: |
3322 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 3331 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); |
3323 | cmdpool_alloc_fail: | 3332 | cmdpool_alloc_fail: |
3324 | return iscsi_handle(NULL); | 3333 | return NULL; |
3325 | } | 3334 | } |
3326 | 3335 | ||
3327 | static void | 3336 | static void |
3328 | iscsi_session_destroy(iscsi_sessionh_t sessionh) | 3337 | iscsi_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 | ||
3350 | static int | 3361 | static int |
@@ -3493,25 +3504,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, | |||
3493 | } | 3504 | } |
3494 | 3505 | ||
3495 | static int | 3506 | static int |
3496 | iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, | 3507 | iscsi_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 | ||
3550 | static int | ||
3551 | iscsi_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 | |||
3552 | static void | 3575 | static void |
3553 | iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) | 3576 | iscsi_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 = { | |||
3611 | static int __init | 3636 | static int __init |
3612 | iscsi_tcp_init(void) | 3637 | iscsi_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 | ||
3635 | static void __exit | 3657 | static void __exit |