2 * cxgb3i_pdu.c: Chelsio S3xx iSCSI driver.
4 * Copyright (c) 2008 Chelsio Communications, Inc.
5 * Copyright (c) 2008 Mike Christie
6 * Copyright (c) 2008 Red Hat, Inc. All rights reserved.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
12 * Written by: Karen Xie (kxie@chelsio.com)
15 #include <linux/skbuff.h>
16 #include <linux/crypto.h>
17 #include <scsi/scsi_cmnd.h>
18 #include <scsi/scsi_host.h>
21 #include "cxgb3i_pdu.h"
23 #ifdef __DEBUG_CXGB3I_RX__
24 #define cxgb3i_rx_debug cxgb3i_log_debug
26 #define cxgb3i_rx_debug(fmt...)
29 #ifdef __DEBUG_CXGB3I_TX__
30 #define cxgb3i_tx_debug cxgb3i_log_debug
32 #define cxgb3i_tx_debug(fmt...)
35 static struct page
*pad_page
;
38 * pdu receive, interact with libiscsi_tcp
40 static inline int read_pdu_skb(struct iscsi_conn
*conn
, struct sk_buff
*skb
,
41 unsigned int offset
, int offloaded
)
46 bytes_read
= iscsi_tcp_recv_skb(conn
, skb
, offset
, offloaded
, &status
);
48 case ISCSI_TCP_CONN_ERR
:
50 case ISCSI_TCP_SUSPENDED
:
51 /* no transfer - just have caller flush queue */
53 case ISCSI_TCP_SKB_DONE
:
55 * pdus should always fit in the skb and we should get
56 * segment done notifcation.
58 iscsi_conn_printk(KERN_ERR
, conn
, "Invalid pdu or skb.");
60 case ISCSI_TCP_SEGMENT_DONE
:
63 iscsi_conn_printk(KERN_ERR
, conn
, "Invalid iscsi_tcp_recv_skb "
64 "status %d\n", status
);
69 static int cxgb3i_conn_read_pdu_skb(struct iscsi_conn
*conn
,
72 struct iscsi_tcp_conn
*tcp_conn
= conn
->dd_data
;
77 cxgb3i_rx_debug("conn 0x%p, skb 0x%p, len %u, flag 0x%x.\n",
78 conn
, skb
, skb
->len
, skb_ulp_mode(skb
));
80 if (!iscsi_tcp_recv_segment_is_hdr(tcp_conn
)) {
81 iscsi_conn_failure(conn
, ISCSI_ERR_PROTO
);
85 if (conn
->hdrdgst_en
&& (skb_ulp_mode(skb
) & ULP2_FLAG_HCRC_ERROR
)) {
86 iscsi_conn_failure(conn
, ISCSI_ERR_HDR_DGST
);
90 if (conn
->datadgst_en
&& (skb_ulp_mode(skb
) & ULP2_FLAG_DCRC_ERROR
)) {
91 iscsi_conn_failure(conn
, ISCSI_ERR_DATA_DGST
);
96 rc
= read_pdu_skb(conn
, skb
, 0, 0);
100 if (iscsi_tcp_recv_segment_is_hdr(tcp_conn
))
104 if (conn
->hdrdgst_en
)
105 offset
+= ISCSI_DIGEST_SIZE
;
108 if (skb_ulp_mode(skb
) & ULP2_FLAG_DATA_DDPED
) {
109 cxgb3i_rx_debug("skb 0x%p, opcode 0x%x, data %u, ddp'ed, "
112 tcp_conn
->in
.hdr
->opcode
& ISCSI_OPCODE_MASK
,
113 tcp_conn
->in
.datalen
,
114 ntohl(tcp_conn
->in
.hdr
->itt
));
117 cxgb3i_rx_debug("skb 0x%p, opcode 0x%x, data %u, NOT ddp'ed, "
120 tcp_conn
->in
.hdr
->opcode
& ISCSI_OPCODE_MASK
,
121 tcp_conn
->in
.datalen
,
122 ntohl(tcp_conn
->in
.hdr
->itt
));
123 offset
+= sizeof(struct cpl_iscsi_hdr_norss
);
126 rc
= read_pdu_skb(conn
, skb
, offset
, offloaded
);
134 * pdu transmit, interact with libiscsi_tcp
136 static inline void tx_skb_setmode(struct sk_buff
*skb
, int hcrc
, int dcrc
)
144 skb_ulp_mode(skb
) = (ULP_MODE_ISCSI
<< 4) | submode
;
147 void cxgb3i_conn_cleanup_task(struct iscsi_task
*task
)
149 struct iscsi_tcp_task
*tcp_task
= task
->dd_data
;
151 /* never reached the xmit task callout */
152 if (tcp_task
->dd_data
)
153 kfree_skb(tcp_task
->dd_data
);
154 tcp_task
->dd_data
= NULL
;
156 /* MNC - Do we need a check in case this is called but
157 * cxgb3i_conn_alloc_pdu has never been called on the task */
158 cxgb3i_release_itt(task
, task
->hdr_itt
);
159 iscsi_tcp_cleanup_task(task
);
163 * We do not support ahs yet
165 int cxgb3i_conn_alloc_pdu(struct iscsi_task
*task
, u8 opcode
)
167 struct iscsi_tcp_task
*tcp_task
= task
->dd_data
;
171 /* always allocate rooms for AHS */
172 skb
= alloc_skb(sizeof(struct iscsi_hdr
) + ISCSI_MAX_AHS_SIZE
+
173 TX_HEADER_LEN
, GFP_ATOMIC
);
177 cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n",
180 tcp_task
->dd_data
= skb
;
181 skb_reserve(skb
, TX_HEADER_LEN
);
182 task
->hdr
= (struct iscsi_hdr
*)skb
->data
;
183 task
->hdr_max
= sizeof(struct iscsi_hdr
);
185 /* data_out uses scsi_cmd's itt */
186 if (opcode
!= ISCSI_OP_SCSI_DATA_OUT
)
187 cxgb3i_reserve_itt(task
, &task
->hdr
->itt
);
192 int cxgb3i_conn_init_pdu(struct iscsi_task
*task
, unsigned int offset
,
195 struct iscsi_tcp_task
*tcp_task
= task
->dd_data
;
196 struct sk_buff
*skb
= tcp_task
->dd_data
;
197 struct iscsi_conn
*conn
= task
->conn
;
199 unsigned int datalen
= count
;
200 int i
, padlen
= iscsi_padding(count
);
203 cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n",
204 task
, task
->sc
, offset
, count
, skb
);
206 skb_put(skb
, task
->hdr_len
);
207 tx_skb_setmode(skb
, conn
->hdrdgst_en
, datalen
? conn
->datadgst_en
: 0);
212 struct scatterlist
*sg
;
213 struct scsi_data_buffer
*sdb
;
214 unsigned int sgoffset
= offset
;
218 sdb
= scsi_out(task
->sc
);
221 for_each_sg(sdb
->table
.sgl
, sg
, sdb
->table
.nents
, i
) {
222 cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n",
223 i
, sg_page(sg
), sg
->length
, sg
->offset
);
225 if (sgoffset
< sg
->length
)
227 sgoffset
-= sg
->length
;
230 sglen
= sg
->length
- sgoffset
;
233 int j
= skb_shinfo(skb
)->nr_frags
;
243 copy
= min(sglen
, datalen
);
244 if (j
&& skb_can_coalesce(skb
, j
, sgpg
,
245 sg
->offset
+ sgoffset
)) {
246 skb_shinfo(skb
)->frags
[j
- 1].size
+= copy
;
249 skb_fill_page_desc(skb
, j
, sgpg
,
250 sg
->offset
+ sgoffset
, copy
);
257 pg
= virt_to_page(task
->data
);
260 i
= skb_shinfo(skb
)->nr_frags
;
261 frag
= &skb_shinfo(skb
)->frags
[i
];
265 frag
->page_offset
= 0;
266 frag
->size
= min((unsigned int)PAGE_SIZE
, datalen
);
268 skb_shinfo(skb
)->nr_frags
++;
269 datalen
-= frag
->size
;
275 i
= skb_shinfo(skb
)->nr_frags
;
276 frag
= &skb_shinfo(skb
)->frags
[i
];
277 frag
->page
= pad_page
;
278 frag
->page_offset
= 0;
280 skb_shinfo(skb
)->nr_frags
++;
283 datalen
= count
+ padlen
;
284 skb
->data_len
+= datalen
;
285 skb
->truesize
+= datalen
;
290 int cxgb3i_conn_xmit_pdu(struct iscsi_task
*task
)
292 struct iscsi_tcp_task
*tcp_task
= task
->dd_data
;
293 struct sk_buff
*skb
= tcp_task
->dd_data
;
294 struct iscsi_tcp_conn
*tcp_conn
= task
->conn
->dd_data
;
295 struct cxgb3i_conn
*cconn
= tcp_conn
->dd_data
;
296 unsigned int datalen
;
302 datalen
= skb
->data_len
;
303 tcp_task
->dd_data
= NULL
;
304 err
= cxgb3i_c3cn_send_pdus(cconn
->cep
->c3cn
, skb
);
305 cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
306 task
, skb
, skb
->len
, skb
->data_len
, err
);
310 if (task
->conn
->hdrdgst_en
)
311 pdulen
+= ISCSI_DIGEST_SIZE
;
312 if (datalen
&& task
->conn
->datadgst_en
)
313 pdulen
+= ISCSI_DIGEST_SIZE
;
315 task
->conn
->txdata_octets
+= pdulen
;
319 if (err
< 0 && err
!= -EAGAIN
) {
321 cxgb3i_tx_debug("itt 0x%x, skb 0x%p, len %u/%u, xmit err %d.\n",
322 task
->itt
, skb
, skb
->len
, skb
->data_len
, err
);
323 iscsi_conn_printk(KERN_ERR
, task
->conn
, "xmit err %d.\n", err
);
324 iscsi_conn_failure(task
->conn
, ISCSI_ERR_XMIT_FAILED
);
327 /* reset skb to send when we are called again */
328 tcp_task
->dd_data
= skb
;
332 int cxgb3i_pdu_init(void)
334 pad_page
= alloc_page(GFP_KERNEL
);
337 memset(page_address(pad_page
), 0, PAGE_SIZE
);
341 void cxgb3i_pdu_cleanup(void)
344 __free_page(pad_page
);
349 void cxgb3i_conn_pdu_ready(struct s3_conn
*c3cn
)
352 unsigned int read
= 0;
353 struct iscsi_conn
*conn
= c3cn
->user_data
;
356 cxgb3i_rx_debug("cn 0x%p.\n", c3cn
);
358 read_lock(&c3cn
->callback_lock
);
359 if (unlikely(!conn
|| conn
->suspend_rx
)) {
360 cxgb3i_rx_debug("conn 0x%p, id %d, suspend_rx %lu!\n",
361 conn
, conn
? conn
->id
: 0xFF,
362 conn
? conn
->suspend_rx
: 0xFF);
363 read_unlock(&c3cn
->callback_lock
);
366 skb
= skb_peek(&c3cn
->receive_queue
);
367 while (!err
&& skb
) {
368 __skb_unlink(skb
, &c3cn
->receive_queue
);
369 read
+= skb_ulp_pdulen(skb
);
370 err
= cxgb3i_conn_read_pdu_skb(conn
, skb
);
372 skb
= skb_peek(&c3cn
->receive_queue
);
374 read_unlock(&c3cn
->callback_lock
);
376 c3cn
->copied_seq
+= read
;
377 cxgb3i_c3cn_rx_credits(c3cn
, read
);
379 conn
->rxdata_octets
+= read
;
382 void cxgb3i_conn_tx_open(struct s3_conn
*c3cn
)
384 struct iscsi_conn
*conn
= c3cn
->user_data
;
386 cxgb3i_tx_debug("cn 0x%p.\n", c3cn
);
388 cxgb3i_tx_debug("cn 0x%p, cid %d.\n", c3cn
, conn
->id
);
389 scsi_queue_work(conn
->session
->host
, &conn
->xmitwork
);
393 void cxgb3i_conn_closing(struct s3_conn
*c3cn
)
395 struct iscsi_conn
*conn
;
397 read_lock(&c3cn
->callback_lock
);
398 conn
= c3cn
->user_data
;
399 if (conn
&& c3cn
->state
!= C3CN_STATE_ESTABLISHED
)
400 iscsi_conn_failure(conn
, ISCSI_ERR_CONN_FAILED
);
401 read_unlock(&c3cn
->callback_lock
);