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.c152
1 files changed, 24 insertions, 128 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index b4743a9ecc80..848fb2aa4ca3 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -2130,19 +2130,21 @@ iscsi_r2tpool_free(struct iscsi_session *session)
2130 2130
2131static int 2131static int
2132iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, 2132iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2133 uint32_t value) 2133 char *buf, int buflen)
2134{ 2134{
2135 struct iscsi_conn *conn = cls_conn->dd_data; 2135 struct iscsi_conn *conn = cls_conn->dd_data;
2136 struct iscsi_session *session = conn->session; 2136 struct iscsi_session *session = conn->session;
2137 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 2137 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2138 int value;
2138 2139
2139 switch(param) { 2140 switch(param) {
2140 case ISCSI_PARAM_MAX_RECV_DLENGTH: { 2141 case ISCSI_PARAM_MAX_RECV_DLENGTH: {
2141 char *saveptr = tcp_conn->data; 2142 char *saveptr = tcp_conn->data;
2142 gfp_t flags = GFP_KERNEL; 2143 gfp_t flags = GFP_KERNEL;
2143 2144
2145 sscanf(buf, "%d", &value);
2144 if (tcp_conn->data_size >= value) { 2146 if (tcp_conn->data_size >= value) {
2145 conn->max_recv_dlength = value; 2147 iscsi_set_param(cls_conn, param, buf, buflen);
2146 break; 2148 break;
2147 } 2149 }
2148 2150
@@ -2165,15 +2167,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2165 else 2167 else
2166 free_pages((unsigned long)saveptr, 2168 free_pages((unsigned long)saveptr,
2167 get_order(tcp_conn->data_size)); 2169 get_order(tcp_conn->data_size));
2168 conn->max_recv_dlength = value; 2170 iscsi_set_param(cls_conn, param, buf, buflen);
2169 tcp_conn->data_size = value; 2171 tcp_conn->data_size = value;
2170 }
2171 break;
2172 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
2173 conn->max_xmit_dlength = value;
2174 break; 2172 break;
2173 }
2175 case ISCSI_PARAM_HDRDGST_EN: 2174 case ISCSI_PARAM_HDRDGST_EN:
2176 conn->hdrdgst_en = value; 2175 iscsi_set_param(cls_conn, param, buf, buflen);
2177 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 2176 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
2178 if (conn->hdrdgst_en) { 2177 if (conn->hdrdgst_en) {
2179 tcp_conn->hdr_size += sizeof(__u32); 2178 tcp_conn->hdr_size += sizeof(__u32);
@@ -2197,7 +2196,7 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2197 } 2196 }
2198 break; 2197 break;
2199 case ISCSI_PARAM_DATADGST_EN: 2198 case ISCSI_PARAM_DATADGST_EN:
2200 conn->datadgst_en = value; 2199 iscsi_set_param(cls_conn, param, buf, buflen);
2201 if (conn->datadgst_en) { 2200 if (conn->datadgst_en) {
2202 if (!tcp_conn->data_tx_tfm) 2201 if (!tcp_conn->data_tx_tfm)
2203 tcp_conn->data_tx_tfm = 2202 tcp_conn->data_tx_tfm =
@@ -2220,121 +2219,36 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2220 tcp_conn->sendpage = conn->datadgst_en ? 2219 tcp_conn->sendpage = conn->datadgst_en ?
2221 sock_no_sendpage : tcp_conn->sock->ops->sendpage; 2220 sock_no_sendpage : tcp_conn->sock->ops->sendpage;
2222 break; 2221 break;
2223 case ISCSI_PARAM_INITIAL_R2T_EN:
2224 session->initial_r2t_en = value;
2225 break;
2226 case ISCSI_PARAM_MAX_R2T: 2222 case ISCSI_PARAM_MAX_R2T:
2223 sscanf(buf, "%d", &value);
2227 if (session->max_r2t == roundup_pow_of_two(value)) 2224 if (session->max_r2t == roundup_pow_of_two(value))
2228 break; 2225 break;
2229 iscsi_r2tpool_free(session); 2226 iscsi_r2tpool_free(session);
2230 session->max_r2t = value; 2227 iscsi_set_param(cls_conn, param, buf, buflen);
2231 if (session->max_r2t & (session->max_r2t - 1)) 2228 if (session->max_r2t & (session->max_r2t - 1))
2232 session->max_r2t = roundup_pow_of_two(session->max_r2t); 2229 session->max_r2t = roundup_pow_of_two(session->max_r2t);
2233 if (iscsi_r2tpool_alloc(session)) 2230 if (iscsi_r2tpool_alloc(session))
2234 return -ENOMEM; 2231 return -ENOMEM;
2235 break; 2232 break;
2236 case ISCSI_PARAM_IMM_DATA_EN:
2237 session->imm_data_en = value;
2238 break;
2239 case ISCSI_PARAM_FIRST_BURST:
2240 session->first_burst = value;
2241 break;
2242 case ISCSI_PARAM_MAX_BURST:
2243 session->max_burst = value;
2244 break;
2245 case ISCSI_PARAM_PDU_INORDER_EN:
2246 session->pdu_inorder_en = value;
2247 break;
2248 case ISCSI_PARAM_DATASEQ_INORDER_EN:
2249 session->dataseq_inorder_en = value;
2250 break;
2251 case ISCSI_PARAM_ERL:
2252 session->erl = value;
2253 break;
2254 case ISCSI_PARAM_IFMARKER_EN:
2255 BUG_ON(value);
2256 session->ifmarker_en = value;
2257 break;
2258 case ISCSI_PARAM_OFMARKER_EN:
2259 BUG_ON(value);
2260 session->ofmarker_en = value;
2261 break;
2262 case ISCSI_PARAM_EXP_STATSN:
2263 conn->exp_statsn = value;
2264 break;
2265 default:
2266 break;
2267 }
2268
2269 return 0;
2270}
2271
2272static int
2273iscsi_session_get_param(struct iscsi_cls_session *cls_session,
2274 enum iscsi_param param, uint32_t *value)
2275{
2276 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
2277 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
2278
2279 switch(param) {
2280 case ISCSI_PARAM_INITIAL_R2T_EN:
2281 *value = session->initial_r2t_en;
2282 break;
2283 case ISCSI_PARAM_MAX_R2T:
2284 *value = session->max_r2t;
2285 break;
2286 case ISCSI_PARAM_IMM_DATA_EN:
2287 *value = session->imm_data_en;
2288 break;
2289 case ISCSI_PARAM_FIRST_BURST:
2290 *value = session->first_burst;
2291 break;
2292 case ISCSI_PARAM_MAX_BURST:
2293 *value = session->max_burst;
2294 break;
2295 case ISCSI_PARAM_PDU_INORDER_EN:
2296 *value = session->pdu_inorder_en;
2297 break;
2298 case ISCSI_PARAM_DATASEQ_INORDER_EN:
2299 *value = session->dataseq_inorder_en;
2300 break;
2301 case ISCSI_PARAM_ERL:
2302 *value = session->erl;
2303 break;
2304 case ISCSI_PARAM_IFMARKER_EN:
2305 *value = session->ifmarker_en;
2306 break;
2307 case ISCSI_PARAM_OFMARKER_EN:
2308 *value = session->ofmarker_en;
2309 break;
2310 default: 2233 default:
2311 return -EINVAL; 2234 return iscsi_set_param(cls_conn, param, buf, buflen);
2312 } 2235 }
2313 2236
2314 return 0; 2237 return 0;
2315} 2238}
2316 2239
2317static int 2240static int
2318iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, 2241iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
2319 enum iscsi_param param, uint32_t *value) 2242 enum iscsi_param param, char *buf)
2320{ 2243{
2321 struct iscsi_conn *conn = cls_conn->dd_data; 2244 struct iscsi_conn *conn = cls_conn->dd_data;
2322 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 2245 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2323 struct inet_sock *inet; 2246 struct inet_sock *inet;
2247 struct ipv6_pinfo *np;
2248 struct sock *sk;
2249 int len;
2324 2250
2325 switch(param) { 2251 switch(param) {
2326 case ISCSI_PARAM_MAX_RECV_DLENGTH:
2327 *value = conn->max_recv_dlength;
2328 break;
2329 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
2330 *value = conn->max_xmit_dlength;
2331 break;
2332 case ISCSI_PARAM_HDRDGST_EN:
2333 *value = conn->hdrdgst_en;
2334 break;
2335 case ISCSI_PARAM_DATADGST_EN:
2336 *value = conn->datadgst_en;
2337 break;
2338 case ISCSI_PARAM_CONN_PORT: 2252 case ISCSI_PARAM_CONN_PORT:
2339 mutex_lock(&conn->xmitmutex); 2253 mutex_lock(&conn->xmitmutex);
2340 if (!tcp_conn->sock) { 2254 if (!tcp_conn->sock) {
@@ -2343,30 +2257,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
2343 } 2257 }
2344 2258
2345 inet = inet_sk(tcp_conn->sock->sk); 2259 inet = inet_sk(tcp_conn->sock->sk);
2346 *value = be16_to_cpu(inet->dport); 2260 len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport));
2347 mutex_unlock(&conn->xmitmutex); 2261 mutex_unlock(&conn->xmitmutex);
2348 case ISCSI_PARAM_EXP_STATSN:
2349 *value = conn->exp_statsn;
2350 break; 2262 break;
2351 default:
2352 return -EINVAL;
2353 }
2354
2355 return 0;
2356}
2357
2358static int
2359iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
2360 enum iscsi_param param, char *buf)
2361{
2362 struct iscsi_conn *conn = cls_conn->dd_data;
2363 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
2364 struct sock *sk;
2365 struct inet_sock *inet;
2366 struct ipv6_pinfo *np;
2367 int len = 0;
2368
2369 switch (param) {
2370 case ISCSI_PARAM_CONN_ADDRESS: 2263 case ISCSI_PARAM_CONN_ADDRESS:
2371 mutex_lock(&conn->xmitmutex); 2264 mutex_lock(&conn->xmitmutex);
2372 if (!tcp_conn->sock) { 2265 if (!tcp_conn->sock) {
@@ -2388,7 +2281,7 @@ iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
2388 mutex_unlock(&conn->xmitmutex); 2281 mutex_unlock(&conn->xmitmutex);
2389 break; 2282 break;
2390 default: 2283 default:
2391 return -EINVAL; 2284 return iscsi_conn_get_param(cls_conn, param, buf);
2392 } 2285 }
2393 2286
2394 return len; 2287 return len;
@@ -2501,7 +2394,11 @@ static struct iscsi_transport iscsi_tcp_transport = {
2501 ISCSI_ERL | 2394 ISCSI_ERL |
2502 ISCSI_CONN_PORT | 2395 ISCSI_CONN_PORT |
2503 ISCSI_CONN_ADDRESS | 2396 ISCSI_CONN_ADDRESS |
2504 ISCSI_EXP_STATSN, 2397 ISCSI_EXP_STATSN |
2398 ISCSI_PERSISTENT_PORT |
2399 ISCSI_PERSISTENT_ADDRESS |
2400 ISCSI_TARGET_NAME |
2401 ISCSI_TPGT,
2505 .host_template = &iscsi_sht, 2402 .host_template = &iscsi_sht,
2506 .conndata_size = sizeof(struct iscsi_conn), 2403 .conndata_size = sizeof(struct iscsi_conn),
2507 .max_conn = 1, 2404 .max_conn = 1,
@@ -2514,8 +2411,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
2514 .bind_conn = iscsi_tcp_conn_bind, 2411 .bind_conn = iscsi_tcp_conn_bind,
2515 .destroy_conn = iscsi_tcp_conn_destroy, 2412 .destroy_conn = iscsi_tcp_conn_destroy,
2516 .set_param = iscsi_conn_set_param, 2413 .set_param = iscsi_conn_set_param,
2517 .get_conn_param = iscsi_conn_get_param, 2414 .get_conn_param = iscsi_tcp_conn_get_param,
2518 .get_conn_str_param = iscsi_conn_get_str_param,
2519 .get_session_param = iscsi_session_get_param, 2415 .get_session_param = iscsi_session_get_param,
2520 .start_conn = iscsi_conn_start, 2416 .start_conn = iscsi_conn_start,
2521 .stop_conn = iscsi_conn_stop, 2417 .stop_conn = iscsi_conn_stop,