diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_parameters.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 240f7aa76ed1..90b740048f26 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
@@ -334,6 +334,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) | |||
334 | if (!param) | 334 | if (!param) |
335 | goto out; | 335 | goto out; |
336 | 336 | ||
337 | param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH, | ||
338 | INITIAL_MAXXMITDATASEGMENTLENGTH, | ||
339 | PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, | ||
340 | TYPERANGE_512_TO_16777215, USE_ALL); | ||
341 | if (!param) | ||
342 | goto out; | ||
343 | |||
337 | param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH, | 344 | param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH, |
338 | INITIAL_MAXRECVDATASEGMENTLENGTH, | 345 | INITIAL_MAXRECVDATASEGMENTLENGTH, |
339 | PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, | 346 | PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, |
@@ -467,6 +474,8 @@ int iscsi_set_keys_to_negotiate( | |||
467 | SET_PSTATE_NEGOTIATE(param); | 474 | SET_PSTATE_NEGOTIATE(param); |
468 | } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { | 475 | } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { |
469 | SET_PSTATE_NEGOTIATE(param); | 476 | SET_PSTATE_NEGOTIATE(param); |
477 | } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { | ||
478 | continue; | ||
470 | } else if (!strcmp(param->name, MAXBURSTLENGTH)) { | 479 | } else if (!strcmp(param->name, MAXBURSTLENGTH)) { |
471 | SET_PSTATE_NEGOTIATE(param); | 480 | SET_PSTATE_NEGOTIATE(param); |
472 | } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) { | 481 | } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) { |
@@ -1056,7 +1065,8 @@ out: | |||
1056 | return proposer_values; | 1065 | return proposer_values; |
1057 | } | 1066 | } |
1058 | 1067 | ||
1059 | static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) | 1068 | static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value, |
1069 | struct iscsi_conn *conn) | ||
1060 | { | 1070 | { |
1061 | u8 acceptor_boolean_value = 0, proposer_boolean_value = 0; | 1071 | u8 acceptor_boolean_value = 0, proposer_boolean_value = 0; |
1062 | char *negoitated_value = NULL; | 1072 | char *negoitated_value = NULL; |
@@ -1131,8 +1141,35 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value) | |||
1131 | return -1; | 1141 | return -1; |
1132 | } | 1142 | } |
1133 | 1143 | ||
1134 | if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) | 1144 | if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { |
1135 | SET_PSTATE_REPLY_OPTIONAL(param); | 1145 | struct iscsi_param *param_mxdsl; |
1146 | unsigned long long tmp; | ||
1147 | int rc; | ||
1148 | |||
1149 | rc = strict_strtoull(param->value, 0, &tmp); | ||
1150 | if (rc < 0) | ||
1151 | return -1; | ||
1152 | |||
1153 | conn->conn_ops->MaxRecvDataSegmentLength = tmp; | ||
1154 | pr_debug("Saving op->MaxRecvDataSegmentLength from" | ||
1155 | " original initiator received value: %u\n", | ||
1156 | conn->conn_ops->MaxRecvDataSegmentLength); | ||
1157 | |||
1158 | param_mxdsl = iscsi_find_param_from_key( | ||
1159 | MAXXMITDATASEGMENTLENGTH, | ||
1160 | conn->param_list); | ||
1161 | if (!param_mxdsl) | ||
1162 | return -1; | ||
1163 | |||
1164 | rc = iscsi_update_param_value(param, | ||
1165 | param_mxdsl->value); | ||
1166 | if (rc < 0) | ||
1167 | return -1; | ||
1168 | |||
1169 | pr_debug("Updated %s to target MXDSL value: %s\n", | ||
1170 | param->name, param->value); | ||
1171 | } | ||
1172 | |||
1136 | } else if (IS_TYPE_NUMBER_RANGE(param)) { | 1173 | } else if (IS_TYPE_NUMBER_RANGE(param)) { |
1137 | negoitated_value = iscsi_get_value_from_number_range( | 1174 | negoitated_value = iscsi_get_value_from_number_range( |
1138 | param, value); | 1175 | param, value); |
@@ -1526,8 +1563,9 @@ int iscsi_decode_text_input( | |||
1526 | u8 sender, | 1563 | u8 sender, |
1527 | char *textbuf, | 1564 | char *textbuf, |
1528 | u32 length, | 1565 | u32 length, |
1529 | struct iscsi_param_list *param_list) | 1566 | struct iscsi_conn *conn) |
1530 | { | 1567 | { |
1568 | struct iscsi_param_list *param_list = conn->param_list; | ||
1531 | char *tmpbuf, *start = NULL, *end = NULL; | 1569 | char *tmpbuf, *start = NULL, *end = NULL; |
1532 | 1570 | ||
1533 | tmpbuf = kzalloc(length + 1, GFP_KERNEL); | 1571 | tmpbuf = kzalloc(length + 1, GFP_KERNEL); |
@@ -1585,7 +1623,7 @@ int iscsi_decode_text_input( | |||
1585 | } | 1623 | } |
1586 | SET_PSTATE_RESPONSE_GOT(param); | 1624 | SET_PSTATE_RESPONSE_GOT(param); |
1587 | } else { | 1625 | } else { |
1588 | if (iscsi_check_acceptor_state(param, value) < 0) { | 1626 | if (iscsi_check_acceptor_state(param, value, conn) < 0) { |
1589 | kfree(tmpbuf); | 1627 | kfree(tmpbuf); |
1590 | return -1; | 1628 | return -1; |
1591 | } | 1629 | } |
@@ -1720,6 +1758,18 @@ void iscsi_set_connection_parameters( | |||
1720 | pr_debug("---------------------------------------------------" | 1758 | pr_debug("---------------------------------------------------" |
1721 | "---------------\n"); | 1759 | "---------------\n"); |
1722 | list_for_each_entry(param, ¶m_list->param_list, p_list) { | 1760 | list_for_each_entry(param, ¶m_list->param_list, p_list) { |
1761 | /* | ||
1762 | * Special case to set MAXXMITDATASEGMENTLENGTH from the | ||
1763 | * target requested MaxRecvDataSegmentLength, even though | ||
1764 | * this key is not sent over the wire. | ||
1765 | */ | ||
1766 | if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { | ||
1767 | ops->MaxXmitDataSegmentLength = | ||
1768 | simple_strtoul(param->value, &tmpptr, 0); | ||
1769 | pr_debug("MaxXmitDataSegmentLength: %s\n", | ||
1770 | param->value); | ||
1771 | } | ||
1772 | |||
1723 | if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param)) | 1773 | if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param)) |
1724 | continue; | 1774 | continue; |
1725 | if (!strcmp(param->name, AUTHMETHOD)) { | 1775 | if (!strcmp(param->name, AUTHMETHOD)) { |
@@ -1734,10 +1784,13 @@ void iscsi_set_connection_parameters( | |||
1734 | pr_debug("DataDigest: %s\n", | 1784 | pr_debug("DataDigest: %s\n", |
1735 | param->value); | 1785 | param->value); |
1736 | } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { | 1786 | } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { |
1737 | ops->MaxRecvDataSegmentLength = | 1787 | /* |
1738 | simple_strtoul(param->value, &tmpptr, 0); | 1788 | * At this point iscsi_check_acceptor_state() will have |
1739 | pr_debug("MaxRecvDataSegmentLength: %s\n", | 1789 | * set ops->MaxRecvDataSegmentLength from the original |
1740 | param->value); | 1790 | * initiator provided value. |
1791 | */ | ||
1792 | pr_debug("MaxRecvDataSegmentLength: %u\n", | ||
1793 | ops->MaxRecvDataSegmentLength); | ||
1741 | } else if (!strcmp(param->name, OFMARKER)) { | 1794 | } else if (!strcmp(param->name, OFMARKER)) { |
1742 | ops->OFMarker = !strcmp(param->value, YES); | 1795 | ops->OFMarker = !strcmp(param->value, YES); |
1743 | pr_debug("OFMarker: %s\n", | 1796 | pr_debug("OFMarker: %s\n", |