diff options
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 23808dfe22ba..b3e5e08e44ab 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>"); |
49 | MODULE_DESCRIPTION("iSCSI/TCP data-path"); | 49 | MODULE_DESCRIPTION("iSCSI/TCP data-path"); |
50 | MODULE_LICENSE("GPL"); | 50 | MODULE_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 | ||
59 | static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport; | 52 | static struct scsi_transport_template *iscsi_sw_tcp_scsi_transport; |
60 | static struct scsi_host_template iscsi_sw_tcp_sht; | 53 | static struct scsi_host_template iscsi_sw_tcp_sht; |
@@ -63,6 +56,21 @@ static struct iscsi_transport iscsi_sw_tcp_transport; | |||
63 | static unsigned int iscsi_max_lun = 512; | 56 | static unsigned int iscsi_max_lun = 512; |
64 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); | 57 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); |
65 | 58 | ||
59 | static int iscsi_sw_tcp_dbg; | ||
60 | module_param_named(debug_iscsi_tcp, iscsi_sw_tcp_dbg, int, | ||
61 | S_IRUGO | S_IWUSR); | ||
62 | MODULE_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 | ||
162 | static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn) | 172 | static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn) |
@@ -283,7 +293,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn) | |||
283 | } | 293 | } |
284 | } | 294 | } |
285 | 295 | ||
286 | debug_tcp("xmit %d bytes\n", consumed); | 296 | ISCSI_SW_TCP_DBG(conn, "xmit %d bytes\n", consumed); |
287 | 297 | ||
288 | conn->txdata_octets += consumed; | 298 | conn->txdata_octets += consumed; |
289 | return consumed; | 299 | return consumed; |
@@ -291,7 +301,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn) | |||
291 | error: | 301 | error: |
292 | /* Transmit error. We could initiate error recovery | 302 | /* Transmit error. We could initiate error recovery |
293 | * here. */ | 303 | * here. */ |
294 | debug_tcp("Error sending PDU, errno=%d\n", rc); | 304 | ISCSI_SW_TCP_DBG(conn, "Error sending PDU, errno=%d\n", rc); |
295 | iscsi_conn_failure(conn, rc); | 305 | iscsi_conn_failure(conn, rc); |
296 | return -EIO; | 306 | return -EIO; |
297 | } | 307 | } |
@@ -334,9 +344,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; | 344 | struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; |
335 | 345 | ||
336 | tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment; | 346 | tcp_sw_conn->out.segment = tcp_sw_conn->out.data_segment; |
337 | debug_tcp("Header done. Next segment size %u total_size %u\n", | 347 | ISCSI_SW_TCP_DBG(tcp_conn->iscsi_conn, |
338 | tcp_sw_conn->out.segment.size, | 348 | "Header done. Next segment size %u total_size %u\n", |
339 | tcp_sw_conn->out.segment.total_size); | 349 | tcp_sw_conn->out.segment.size, |
350 | tcp_sw_conn->out.segment.total_size); | ||
340 | return 0; | 351 | return 0; |
341 | } | 352 | } |
342 | 353 | ||
@@ -346,8 +357,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; | 357 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
347 | struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; | 358 | struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; |
348 | 359 | ||
349 | debug_tcp("%s(%p%s)\n", __func__, tcp_conn, | 360 | ISCSI_SW_TCP_DBG(conn, "%s\n", conn->hdrdgst_en ? |
350 | conn->hdrdgst_en? ", digest enabled" : ""); | 361 | "digest enabled" : "digest disabled"); |
351 | 362 | ||
352 | /* Clear the data segment - needs to be filled in by the | 363 | /* Clear the data segment - needs to be filled in by the |
353 | * caller using iscsi_tcp_send_data_prep() */ | 364 | * caller using iscsi_tcp_send_data_prep() */ |
@@ -389,9 +400,9 @@ iscsi_sw_tcp_send_data_prep(struct iscsi_conn *conn, struct scatterlist *sg, | |||
389 | struct hash_desc *tx_hash = NULL; | 400 | struct hash_desc *tx_hash = NULL; |
390 | unsigned int hdr_spec_len; | 401 | unsigned int hdr_spec_len; |
391 | 402 | ||
392 | debug_tcp("%s(%p, offset=%d, datalen=%d%s)\n", __func__, | 403 | ISCSI_SW_TCP_DBG(conn, "offset=%d, datalen=%d %s\n", offset, len, |
393 | tcp_conn, offset, len, | 404 | conn->datadgst_en ? |
394 | conn->datadgst_en? ", digest enabled" : ""); | 405 | "digest enabled" : "digest disabled"); |
395 | 406 | ||
396 | /* Make sure the datalen matches what the caller | 407 | /* Make sure the datalen matches what the caller |
397 | said he would send. */ | 408 | said he would send. */ |
@@ -415,8 +426,8 @@ iscsi_sw_tcp_send_linear_data_prep(struct iscsi_conn *conn, void *data, | |||
415 | struct hash_desc *tx_hash = NULL; | 426 | struct hash_desc *tx_hash = NULL; |
416 | unsigned int hdr_spec_len; | 427 | unsigned int hdr_spec_len; |
417 | 428 | ||
418 | debug_tcp("%s(%p, datalen=%d%s)\n", __func__, tcp_conn, len, | 429 | ISCSI_SW_TCP_DBG(conn, "datalen=%zd %s\n", len, conn->datadgst_en ? |
419 | conn->datadgst_en? ", digest enabled" : ""); | 430 | "digest enabled" : "digest disabled"); |
420 | 431 | ||
421 | /* Make sure the datalen matches what the caller | 432 | /* Make sure the datalen matches what the caller |
422 | said he would send. */ | 433 | said he would send. */ |
@@ -754,8 +765,7 @@ iscsi_sw_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, | |||
754 | 765 | ||
755 | static struct iscsi_cls_session * | 766 | static struct iscsi_cls_session * |
756 | iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, | 767 | iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, |
757 | uint16_t qdepth, uint32_t initial_cmdsn, | 768 | uint16_t qdepth, uint32_t initial_cmdsn) |
758 | uint32_t *hostno) | ||
759 | { | 769 | { |
760 | struct iscsi_cls_session *cls_session; | 770 | struct iscsi_cls_session *cls_session; |
761 | struct iscsi_session *session; | 771 | struct iscsi_session *session; |
@@ -766,10 +776,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, | |||
766 | return NULL; | 776 | return NULL; |
767 | } | 777 | } |
768 | 778 | ||
769 | shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, qdepth); | 779 | shost = iscsi_host_alloc(&iscsi_sw_tcp_sht, 0, 1); |
770 | if (!shost) | 780 | if (!shost) |
771 | return NULL; | 781 | return NULL; |
772 | shost->transportt = iscsi_sw_tcp_scsi_transport; | 782 | shost->transportt = iscsi_sw_tcp_scsi_transport; |
783 | shost->cmd_per_lun = qdepth; | ||
773 | shost->max_lun = iscsi_max_lun; | 784 | shost->max_lun = iscsi_max_lun; |
774 | shost->max_id = 0; | 785 | shost->max_id = 0; |
775 | shost->max_channel = 0; | 786 | shost->max_channel = 0; |
@@ -777,7 +788,6 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, | |||
777 | 788 | ||
778 | if (iscsi_host_add(shost, NULL)) | 789 | if (iscsi_host_add(shost, NULL)) |
779 | goto free_host; | 790 | goto free_host; |
780 | *hostno = shost->host_no; | ||
781 | 791 | ||
782 | cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost, | 792 | cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost, |
783 | cmds_max, | 793 | cmds_max, |
@@ -813,6 +823,12 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session) | |||
813 | iscsi_host_free(shost); | 823 | iscsi_host_free(shost); |
814 | } | 824 | } |
815 | 825 | ||
826 | static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev) | ||
827 | { | ||
828 | set_bit(QUEUE_FLAG_BIDI, &sdev->request_queue->queue_flags); | ||
829 | return 0; | ||
830 | } | ||
831 | |||
816 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) | 832 | static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) |
817 | { | 833 | { |
818 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); | 834 | blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); |
@@ -833,6 +849,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { | |||
833 | .eh_device_reset_handler= iscsi_eh_device_reset, | 849 | .eh_device_reset_handler= iscsi_eh_device_reset, |
834 | .eh_target_reset_handler= iscsi_eh_target_reset, | 850 | .eh_target_reset_handler= iscsi_eh_target_reset, |
835 | .use_clustering = DISABLE_CLUSTERING, | 851 | .use_clustering = DISABLE_CLUSTERING, |
852 | .slave_alloc = iscsi_sw_tcp_slave_alloc, | ||
836 | .slave_configure = iscsi_sw_tcp_slave_configure, | 853 | .slave_configure = iscsi_sw_tcp_slave_configure, |
837 | .proc_name = "iscsi_tcp", | 854 | .proc_name = "iscsi_tcp", |
838 | .this_id = -1, | 855 | .this_id = -1, |