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.c90
1 files changed, 56 insertions, 34 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 23808dfe22ba..518dbd91df85 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -48,13 +48,6 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
48 "Alex Aizman <itn780@yahoo.com>"); 48 "Alex Aizman <itn780@yahoo.com>");
49MODULE_DESCRIPTION("iSCSI/TCP data-path"); 49MODULE_DESCRIPTION("iSCSI/TCP data-path");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51#undef DEBUG_TCP
52
53#ifdef DEBUG_TCP
54#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt)
55#else
56#define debug_tcp(fmt...)
57#endif
58 51
59static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport; 52static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport;
60static struct scsi_host_template iscsi_sw_tcp_sht; 53static struct scsi_host_template iscsi_sw_tcp_sht;
@@ -63,6 +56,21 @@ static struct iscsi_transport iscsi_sw_tcp_transport;
63static unsigned int iscsi_max_lun = 512; 56static unsigned int iscsi_max_lun = 512;
64module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); 57module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
65 58
59static int iscsi_sw_tcp_dbg;
60module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int,
61 S_IRUGO | S_IWUSR);
62MODULE_PARM_DESC(debug_iscsi_tcp, "Turn on debugging for iscsi_tcp module "
63 "Set to 1 to turn on, and zero to turn off. Default is off.");
64
65#define ISCSI_SW_TCP_DBG(_conn, dbg_fmt, arg...) \
66 do { \
67 if (iscsi_sw_tcp_dbg) \
68 iscsi_conn_printk(KERN_INFO, _conn, \
69 "%s " dbg_fmt, \
70 __func__, ##arg); \
71 } while (0);
72
73
66/** 74/**
67 * iscsi_sw_tcp_recv - TCP receive in sendfile fashion 75 * iscsi_sw_tcp_recv - TCP receive in sendfile fashion
68 * @rd_desc: read descriptor 76 * @rd_desc: read descriptor
@@ -77,7 +85,7 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
77 unsigned int consumed, total_consumed = 0; 85 unsigned int consumed, total_consumed = 0;
78 int status; 86 int status;
79 87
80 debug_tcp("in %d bytes\n", skb->len - offset); 88 ISCSI_SW_TCP_DBG(conn, "in %d bytes\n", skb->len - offset);
81 89
82 do { 90 do {
83 status = 0; 91 status = 0;
@@ -86,7 +94,8 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
86 total_consumed += consumed; 94 total_consumed += consumed;
87 } while (consumed != 0 && status != ISCSI_TCP_SKB_DONE); 95 } while (consumed != 0 && status != ISCSI_TCP_SKB_DONE);
88 96
89 debug_tcp("read %d bytes status %d\n", skb->len - offset, status); 97 ISCSI_SW_TCP_DBG(conn, "read %d bytes status %d\n",
98 skb->len - offset, status);
90 return total_consumed; 99 return total_consumed;
91} 100}
92 101
@@ -131,7 +140,8 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
131 if ((sk->sk_state == TCP_CLOSE_WAIT || 140 if ((sk->sk_state == TCP_CLOSE_WAIT ||
132 sk->sk_state == TCP_CLOSE) && 141 sk->sk_state == TCP_CLOSE) &&
133 !atomic_read(&sk->sk_rmem_alloc)) { 142 !atomic_read(&sk->sk_rmem_alloc)) {
134 debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n"); 143 ISCSI_SW_TCP_DBG(conn, "iscsi_tcp_state_change: "
144 "TCP_CLOSE|TCP_CLOSE_WAIT\n");
135 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 145 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
136 } 146 }
137 147
@@ -155,8 +165,8 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)
155 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 165 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
156 166
157 tcp_sw_conn->old_write_space(sk); 167 tcp_sw_conn->old_write_space(sk);
158 debug_tcp("iscsi_write_space: cid %d\n", conn->id); 168 ISCSI_SW_TCP_DBG(conn, "iscsi_write_space\n");
159 scsi_queue_work(conn->session->host, &conn->xmitwork); 169 iscsi_conn_queue_work(conn);
160} 170}
161 171
162static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn) 172static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
@@ -243,8 +253,6 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn,
243 253
244 if (r < 0) { 254 if (r < 0) {
245 iscsi_tcp_segment_unmap(segment); 255 iscsi_tcp_segment_unmap(segment);
246 if (copied || r == -EAGAIN)
247 break;
248 return r; 256 return r;
249 } 257 }
250 copied += r; 258 copied += r;
@@ -265,11 +273,17 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
265 273
266 while (1) { 274 while (1) {
267 rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment); 275 rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment);
268 if (rc < 0) { 276 /*
277 * We may not have been able to send data because the conn
278 * is getting stopped. libiscsi will know so propogate err
279 * for it to do the right thing.
280 */
281 if (rc == -EAGAIN)
282 return rc;
283 else if (rc < 0) {
269 rc = ISCSI_ERR_XMIT_FAILED; 284 rc = ISCSI_ERR_XMIT_FAILED;
270 goto error; 285 goto error;
271 } 286 } else if (rc == 0)
272 if (rc == 0)
273 break; 287 break;
274 288
275 consumed += rc; 289 consumed += rc;
@@ -283,7 +297,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
283 } 297 }
284 } 298 }
285 299
286 debug_tcp("xmit %d bytes\n", consumed); 300 ISCSI_SW_TCP_DBG(conn, "xmit %d bytes\n", consumed);
287 301
288 conn->txdata_octets += consumed; 302 conn->txdata_octets += consumed;
289 return consumed; 303 return consumed;
@@ -291,7 +305,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn)
291error: 305error:
292 /* Transmit error. We could initiate error recovery 306 /* Transmit error. We could initiate error recovery
293 * here. */ 307 * here. */
294 debug_tcp("Error sending PDU, errno=%d\n", rc); 308 ISCSI_SW_TCP_DBG(conn, "Error sending PDU, errno=%d\n", rc);
295 iscsi_conn_failure(conn, rc); 309 iscsi_conn_failure(conn, rc);
296 return -EIO; 310 return -EIO;
297} 311}
@@ -334,9 +348,10 @@ static int iscsi_sw_tcp_send_hdr_done(struct iscsi_tcp_conn *tcp_conn,
334 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 348 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
335 349
336 tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment; 350 tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment;
337 debug_tcp("Header done. Next segment size %u total_size %u\n", 351 ISCSI_SW_TCP_DBG(tcp_conn->iscsi_conn,
338 tcp_sw_conn->out.segment.size, 352 "Header done. Next segment size %u total_size %u\n",
339 tcp_sw_conn->out.segment.total_size); 353 tcp_sw_conn->out.segment.size,
354 tcp_sw_conn->out.segment.total_size);
340 return 0; 355 return 0;
341} 356}
342 357
@@ -346,8 +361,8 @@ static void iscsi_sw_tcp_send_hdr_prep(struct iscsi_conn *conn, void *hdr,
346 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 361 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
347 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; 362 struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
348 363
349 debug_tcp("%s(%p%s)\n", __func__, tcp_conn, 364 ISCSI_SW_TCP_DBG(conn, "%s\n", conn->hdrdgst_en ?
350 conn->hdrdgst_en? ", digest enabled" : ""); 365 "digest enabled" : "digest disabled");
351 366
352 /* Clear the data segment - needs to be filled in by the 367 /* Clear the data segment - needs to be filled in by the
353 * caller using iscsi_tcp_send_data_prep() */ 368 * caller using iscsi_tcp_send_data_prep() */
@@ -389,9 +404,9 @@ iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg,
389 struct hash_desc *tx_hash = NULL; 404 struct hash_desc *tx_hash = NULL;
390 unsigned int hdr_spec_len; 405 unsigned int hdr_spec_len;
391 406
392 debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__, 407 ISCSI_SW_TCP_DBG(conn, "offset=%d, datalen=%d %s\n", offset, len,
393 tcp_conn, offset, len, 408 conn->datadgst_en ?
394 conn->datadgst_en? ", digest enabled" : ""); 409 "digest enabled" : "digest disabled");
395 410
396 /* Make sure the datalen matches what the caller 411 /* Make sure the datalen matches what the caller
397 said he would send. */ 412 said he would send. */
@@ -415,8 +430,8 @@ iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data,
415 struct hash_desc *tx_hash = NULL; 430 struct hash_desc *tx_hash = NULL;
416 unsigned int hdr_spec_len; 431 unsigned int hdr_spec_len;
417 432
418 debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len, 433 ISCSI_SW_TCP_DBG(conn, "datalen=%zd %s\n", len, conn->datadgst_en ?
419 conn->datadgst_en? ", digest enabled" : ""); 434 "digest enabled" : "digest disabled");
420 435
421 /* Make sure the datalen matches what the caller 436 /* Make sure the datalen matches what the caller
422 said he would send. */ 437 said he would send. */
@@ -452,7 +467,7 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
452 } 467 }
453 468
454 if (err) { 469 if (err) {
455 iscsi_conn_failure(conn, err); 470 /* got invalid offset/len */
456 return -EIO; 471 return -EIO;
457 } 472 }
458 return 0; 473 return 0;
@@ -754,8 +769,7 @@ iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
754 769
755static struct iscsi_cls_session * 770static struct iscsi_cls_session *
756iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, 771iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
757 uint16_t qdepth, uint32_t initial_cmdsn, 772 uint16_t qdepth, uint32_t initial_cmdsn)
758 uint32_t *hostno)
759{ 773{
760 struct iscsi_cls_session *cls_session; 774 struct iscsi_cls_session *cls_session;
761 struct iscsi_session *session; 775 struct iscsi_session *session;
@@ -766,10 +780,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
766 return NULL; 780 return NULL;
767 } 781 }
768 782
769 shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, qdepth); 783 shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, 1);
770 if (!shost) 784 if (!shost)
771 return NULL; 785 return NULL;
772 shost->transportt = iscsi_sw_tcp_scsi_transport; 786 shost->transportt = iscsi_sw_tcp_scsi_transport;
787 shost->cmd_per_lun = qdepth;
773 shost->max_lun = iscsi_max_lun; 788 shost->max_lun = iscsi_max_lun;
774 shost->max_id = 0; 789 shost->max_id = 0;
775 shost->max_channel = 0; 790 shost->max_channel = 0;
@@ -777,7 +792,6 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
777 792
778 if (iscsi_host_add(shost, NULL)) 793 if (iscsi_host_add(shost, NULL))
779 goto free_host; 794 goto free_host;
780 *hostno = shost->host_no;
781 795
782 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost, 796 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost,
783 cmds_max, 797 cmds_max,
@@ -813,6 +827,12 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
813 iscsi_host_free(shost); 827 iscsi_host_free(shost);
814} 828}
815 829
830static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
831{
832 set_bit(QUEUE_FLAG_BIDI, &sdev->request_queue->queue_flags);
833 return 0;
834}
835
816static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) 836static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
817{ 837{
818 blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); 838 blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY);
@@ -833,7 +853,9 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
833 .eh_device_reset_handler= iscsi_eh_device_reset, 853 .eh_device_reset_handler= iscsi_eh_device_reset,
834 .eh_target_reset_handler= iscsi_eh_target_reset, 854 .eh_target_reset_handler= iscsi_eh_target_reset,
835 .use_clustering = DISABLE_CLUSTERING, 855 .use_clustering = DISABLE_CLUSTERING,
856 .slave_alloc = iscsi_sw_tcp_slave_alloc,
836 .slave_configure = iscsi_sw_tcp_slave_configure, 857 .slave_configure = iscsi_sw_tcp_slave_configure,
858 .target_alloc = iscsi_target_alloc,
837 .proc_name = "iscsi_tcp", 859 .proc_name = "iscsi_tcp",
838 .this_id = -1, 860 .this_id = -1,
839}; 861};