diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_nego.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_nego.c | 167 |
1 files changed, 19 insertions, 148 deletions
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 3cbdccd77e0b..879a0cb44bc3 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <scsi/iscsi_proto.h> | 22 | #include <scsi/iscsi_proto.h> |
23 | #include <target/target_core_base.h> | 23 | #include <target/target_core_base.h> |
24 | #include <target/target_core_fabric.h> | 24 | #include <target/target_core_fabric.h> |
25 | #include <target/iscsi/iscsi_transport.h> | ||
25 | 26 | ||
26 | #include "iscsi_target_core.h" | 27 | #include "iscsi_target_core.h" |
27 | #include "iscsi_target_parameters.h" | 28 | #include "iscsi_target_parameters.h" |
@@ -169,7 +170,7 @@ static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn) | |||
169 | kfree(conn->auth_protocol); | 170 | kfree(conn->auth_protocol); |
170 | } | 171 | } |
171 | 172 | ||
172 | static int iscsi_target_check_login_request( | 173 | int iscsi_target_check_login_request( |
173 | struct iscsi_conn *conn, | 174 | struct iscsi_conn *conn, |
174 | struct iscsi_login *login) | 175 | struct iscsi_login *login) |
175 | { | 176 | { |
@@ -352,11 +353,8 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log | |||
352 | 353 | ||
353 | padding = ((-login->rsp_length) & 3); | 354 | padding = ((-login->rsp_length) & 3); |
354 | 355 | ||
355 | if (iscsi_login_tx_data( | 356 | if (conn->conn_transport->iscsit_put_login_tx(conn, login, |
356 | conn, | 357 | login->rsp_length + padding) < 0) |
357 | login->rsp, | ||
358 | login->rsp_buf, | ||
359 | login->rsp_length + padding) < 0) | ||
360 | return -1; | 358 | return -1; |
361 | 359 | ||
362 | login->rsp_length = 0; | 360 | login->rsp_length = 0; |
@@ -368,72 +366,12 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log | |||
368 | return 0; | 366 | return 0; |
369 | } | 367 | } |
370 | 368 | ||
371 | static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) | ||
372 | { | ||
373 | u32 padding = 0, payload_length; | ||
374 | struct iscsi_login_req *login_req; | ||
375 | |||
376 | if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0) | ||
377 | return -1; | ||
378 | |||
379 | login_req = (struct iscsi_login_req *) login->req; | ||
380 | payload_length = ntoh24(login_req->dlength); | ||
381 | |||
382 | pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," | ||
383 | " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n", | ||
384 | login_req->flags, login_req->itt, login_req->cmdsn, | ||
385 | login_req->exp_statsn, login_req->cid, payload_length); | ||
386 | |||
387 | if (iscsi_target_check_login_request(conn, login) < 0) | ||
388 | return -1; | ||
389 | |||
390 | padding = ((-payload_length) & 3); | ||
391 | memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS); | ||
392 | |||
393 | if (iscsi_login_rx_data( | ||
394 | conn, | ||
395 | login->req_buf, | ||
396 | payload_length + padding) < 0) | ||
397 | return -1; | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login) | 369 | static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login) |
403 | { | 370 | { |
404 | if (iscsi_target_do_tx_login_io(conn, login) < 0) | 371 | if (iscsi_target_do_tx_login_io(conn, login) < 0) |
405 | return -1; | 372 | return -1; |
406 | 373 | ||
407 | if (iscsi_target_do_rx_login_io(conn, login) < 0) | 374 | if (conn->conn_transport->iscsit_get_login_rx(conn, login) < 0) |
408 | return -1; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int iscsi_target_get_initial_payload( | ||
414 | struct iscsi_conn *conn, | ||
415 | struct iscsi_login *login) | ||
416 | { | ||
417 | u32 padding = 0, payload_length; | ||
418 | struct iscsi_login_req *login_req; | ||
419 | |||
420 | login_req = (struct iscsi_login_req *) login->req; | ||
421 | payload_length = ntoh24(login_req->dlength); | ||
422 | |||
423 | pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x," | ||
424 | " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", | ||
425 | login_req->flags, login_req->itt, login_req->cmdsn, | ||
426 | login_req->exp_statsn, payload_length); | ||
427 | |||
428 | if (iscsi_target_check_login_request(conn, login) < 0) | ||
429 | return -1; | ||
430 | |||
431 | padding = ((-payload_length) & 3); | ||
432 | |||
433 | if (iscsi_login_rx_data( | ||
434 | conn, | ||
435 | login->req_buf, | ||
436 | payload_length + padding) < 0) | ||
437 | return -1; | 375 | return -1; |
438 | 376 | ||
439 | return 0; | 377 | return 0; |
@@ -693,6 +631,7 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo | |||
693 | return -1; | 631 | return -1; |
694 | if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { | 632 | if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { |
695 | login->tsih = conn->sess->tsih; | 633 | login->tsih = conn->sess->tsih; |
634 | login->login_complete = 1; | ||
696 | if (iscsi_target_do_tx_login_io(conn, | 635 | if (iscsi_target_do_tx_login_io(conn, |
697 | login) < 0) | 636 | login) < 0) |
698 | return -1; | 637 | return -1; |
@@ -736,7 +675,7 @@ static void iscsi_initiatorname_tolower( | |||
736 | /* | 675 | /* |
737 | * Processes the first Login Request.. | 676 | * Processes the first Login Request.. |
738 | */ | 677 | */ |
739 | static int iscsi_target_locate_portal( | 678 | int iscsi_target_locate_portal( |
740 | struct iscsi_np *np, | 679 | struct iscsi_np *np, |
741 | struct iscsi_conn *conn, | 680 | struct iscsi_conn *conn, |
742 | struct iscsi_login *login) | 681 | struct iscsi_login *login) |
@@ -798,6 +737,8 @@ static int iscsi_target_locate_portal( | |||
798 | start += strlen(key) + strlen(value) + 2; | 737 | start += strlen(key) + strlen(value) + 2; |
799 | } | 738 | } |
800 | 739 | ||
740 | printk("i_buf: %s, s_buf: %s, t_buf: %s\n", i_buf, s_buf, t_buf); | ||
741 | |||
801 | /* | 742 | /* |
802 | * See 5.3. Login Phase. | 743 | * See 5.3. Login Phase. |
803 | */ | 744 | */ |
@@ -956,100 +897,30 @@ out: | |||
956 | return ret; | 897 | return ret; |
957 | } | 898 | } |
958 | 899 | ||
959 | struct iscsi_login *iscsi_target_init_negotiation( | ||
960 | struct iscsi_np *np, | ||
961 | struct iscsi_conn *conn, | ||
962 | char *login_pdu) | ||
963 | { | ||
964 | struct iscsi_login *login; | ||
965 | |||
966 | login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL); | ||
967 | if (!login) { | ||
968 | pr_err("Unable to allocate memory for struct iscsi_login.\n"); | ||
969 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
970 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
971 | return NULL; | ||
972 | } | ||
973 | |||
974 | login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL); | ||
975 | if (!login->req) { | ||
976 | pr_err("Unable to allocate memory for Login Request.\n"); | ||
977 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
978 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
979 | goto out; | ||
980 | } | ||
981 | |||
982 | login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); | ||
983 | if (!login->req_buf) { | ||
984 | pr_err("Unable to allocate memory for response buffer.\n"); | ||
985 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
986 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
987 | goto out; | ||
988 | } | ||
989 | /* | ||
990 | * SessionType: Discovery | ||
991 | * | ||
992 | * Locates Default Portal | ||
993 | * | ||
994 | * SessionType: Normal | ||
995 | * | ||
996 | * Locates Target Portal from NP -> Target IQN | ||
997 | */ | ||
998 | if (iscsi_target_locate_portal(np, conn, login) < 0) { | ||
999 | goto out; | ||
1000 | } | ||
1001 | |||
1002 | return login; | ||
1003 | out: | ||
1004 | kfree(login->req); | ||
1005 | kfree(login->req_buf); | ||
1006 | kfree(login); | ||
1007 | |||
1008 | return NULL; | ||
1009 | } | ||
1010 | |||
1011 | int iscsi_target_start_negotiation( | 900 | int iscsi_target_start_negotiation( |
1012 | struct iscsi_login *login, | 901 | struct iscsi_login *login, |
1013 | struct iscsi_conn *conn) | 902 | struct iscsi_conn *conn) |
1014 | { | 903 | { |
1015 | int ret = -1; | 904 | int ret; |
1016 | |||
1017 | login->rsp = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | ||
1018 | if (!login->rsp) { | ||
1019 | pr_err("Unable to allocate memory for" | ||
1020 | " Login Response.\n"); | ||
1021 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1022 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
1023 | ret = -1; | ||
1024 | goto out; | ||
1025 | } | ||
1026 | |||
1027 | login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); | ||
1028 | if (!login->rsp_buf) { | ||
1029 | pr_err("Unable to allocate memory for" | ||
1030 | " request buffer.\n"); | ||
1031 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
1032 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
1033 | ret = -1; | ||
1034 | goto out; | ||
1035 | } | ||
1036 | 905 | ||
1037 | ret = iscsi_target_do_login(conn, login); | 906 | ret = iscsi_target_do_login(conn, login); |
1038 | out: | ||
1039 | if (ret != 0) | 907 | if (ret != 0) |
1040 | iscsi_remove_failed_auth_entry(conn); | 908 | iscsi_remove_failed_auth_entry(conn); |
1041 | 909 | ||
1042 | iscsi_target_nego_release(login, conn); | 910 | iscsi_target_nego_release(conn); |
1043 | return ret; | 911 | return ret; |
1044 | } | 912 | } |
1045 | 913 | ||
1046 | void iscsi_target_nego_release( | 914 | void iscsi_target_nego_release(struct iscsi_conn *conn) |
1047 | struct iscsi_login *login, | ||
1048 | struct iscsi_conn *conn) | ||
1049 | { | 915 | { |
1050 | kfree(login->req); | 916 | struct iscsi_login *login = conn->conn_login; |
1051 | kfree(login->rsp); | 917 | |
918 | if (!login) | ||
919 | return; | ||
920 | |||
1052 | kfree(login->req_buf); | 921 | kfree(login->req_buf); |
1053 | kfree(login->rsp_buf); | 922 | kfree(login->rsp_buf); |
1054 | kfree(login); | 923 | kfree(login); |
924 | |||
925 | conn->conn_login = NULL; | ||
1055 | } | 926 | } |