2 * Copyright (c) 2010 Cisco Systems, Inc.
4 * Portions based on tcm_loop_fabric_scsi.c and libfc/fc_fcp.c
6 * Copyright (c) 2007 Intel Corporation. All rights reserved.
7 * Copyright (c) 2008 Red Hat, Inc. All rights reserved.
8 * Copyright (c) 2008 Mike Christie
9 * Copyright (c) 2009 Rising Tide, Inc.
10 * Copyright (c) 2009 Linux-iSCSI.org
11 * Copyright (c) 2009 Nicholas A. Bellinger <nab@linux-iscsi.org>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms and conditions of the GNU General Public License,
15 * version 2, as published by the Free Software Foundation.
17 * This program is distributed in the hope it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * You should have received a copy of the GNU General Public License along with
23 * this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
27 /* XXX TBD some includes may be extraneous */
29 #include <linux/module.h>
30 #include <linux/moduleparam.h>
31 #include <linux/version.h>
32 #include <generated/utsrelease.h>
33 #include <linux/utsname.h>
34 #include <linux/init.h>
35 #include <linux/slab.h>
36 #include <linux/kthread.h>
37 #include <linux/types.h>
38 #include <linux/string.h>
39 #include <linux/configfs.h>
40 #include <linux/ctype.h>
41 #include <linux/hash.h>
42 #include <asm/unaligned.h>
43 #include <scsi/scsi.h>
44 #include <scsi/scsi_host.h>
45 #include <scsi/scsi_device.h>
46 #include <scsi/scsi_cmnd.h>
47 #include <scsi/libfc.h>
48 #include <scsi/fc_encode.h>
50 #include <target/target_core_base.h>
51 #include <target/target_core_transport.h>
52 #include <target/target_core_fabric_ops.h>
53 #include <target/target_core_device.h>
54 #include <target/target_core_tpg.h>
55 #include <target/target_core_configfs.h>
56 #include <target/target_core_base.h>
57 #include <target/configfs_macros.h>
62 * Deliver read data back to initiator.
63 * XXX TBD handle resource problems later.
65 int ft_queue_data_in(struct se_cmd
*se_cmd
)
67 struct ft_cmd
*cmd
= container_of(se_cmd
, struct ft_cmd
, se_cmd
);
68 struct se_transport_task
*task
;
69 struct fc_frame
*fp
= NULL
;
71 struct fc_lport
*lport
;
74 u32 f_ctl
= FC_FC_EX_CTX
| FC_FC_REL_OFF
;
89 ep
= fc_seq_exch(cmd
->seq
);
91 cmd
->seq
= lport
->tt
.seq_start_next(cmd
->seq
);
93 task
= T_TASK(se_cmd
);
95 remaining
= se_cmd
->data_length
;
98 * Setup to use first mem list entry if any.
100 if (task
->t_tasks_se_num
) {
101 mem
= list_first_entry(task
->t_mem_list
,
102 struct se_mem
, se_list
);
103 mem_len
= mem
->se_len
;
104 mem_off
= mem
->se_off
;
113 /* no scatter/gather in skb for odd word length due to fc_seq_send() */
114 use_sg
= !(remaining
% 4);
119 mem
= list_entry(mem
->se_list
.next
,
120 struct se_mem
, se_list
);
121 mem_len
= min((size_t)mem
->se_len
, remaining
);
122 mem_off
= mem
->se_off
;
127 * If lport's has capability of Large Send Offload LSO)
128 * , then allow 'frame_len' to be as big as 'lso_max'
129 * if indicated transfer length is >= lport->lso_max
131 frame_len
= (lport
->seq_offload
) ? lport
->lso_max
:
132 cmd
->sess
->max_frame
;
133 frame_len
= min(frame_len
, remaining
);
134 fp
= fc_frame_alloc(lport
, use_sg
? 0 : frame_len
);
137 to
= fc_frame_payload_get(fp
, 0);
139 frame_off
+= frame_len
;
141 * Setup the frame's max payload which is used by base
142 * driver to indicate HW about max frame size, so that
143 * HW can do fragmentation appropriately based on
144 * "gso_max_size" of underline netdev.
146 fr_max_payload(fp
) = cmd
->sess
->max_frame
;
148 tlen
= min(mem_len
, frame_len
);
152 BUG_ON(!task
->t_task_buf
);
153 page_addr
= task
->t_task_buf
+ mem_off
;
155 * In this case, offset is 'offset_in_page' of
156 * (t_task_buf + mem_off) instead of 'mem_off'.
158 off_in_page
= offset_in_page(page_addr
);
159 page
= virt_to_page(page_addr
);
160 tlen
= min(tlen
, PAGE_SIZE
- off_in_page
);
162 off_in_page
= mem_off
;
165 skb_fill_page_desc(fp_skb(fp
),
166 skb_shinfo(fp_skb(fp
))->nr_frags
,
167 page
, off_in_page
, tlen
);
169 fp_skb(fp
)->data_len
+= tlen
;
170 fp_skb(fp
)->truesize
+=
171 PAGE_SIZE
<< compound_order(page
);
174 from
= kmap_atomic(page
+ (mem_off
>> PAGE_SHIFT
),
177 from
+= mem_off
& ~PAGE_MASK
;
178 tlen
= min(tlen
, (size_t)(PAGE_SIZE
-
179 (mem_off
& ~PAGE_MASK
)));
180 memcpy(to
, from
, tlen
);
181 kunmap_atomic(page_addr
, KM_SOFTIRQ0
);
184 from
= task
->t_task_buf
+ mem_off
;
185 memcpy(to
, from
, tlen
);
195 (skb_shinfo(fp_skb(fp
))->nr_frags
< FC_FRAME_SG_LEN
))
198 f_ctl
|= FC_FC_END_SEQ
;
199 fc_fill_fc_hdr(fp
, FC_RCTL_DD_SOL_DATA
, ep
->did
, ep
->sid
,
200 FC_TYPE_FCP
, f_ctl
, fh_off
);
201 error
= lport
->tt
.seq_send(lport
, cmd
->seq
, fp
);
203 /* XXX For now, initiator will retry */
204 if (printk_ratelimit())
205 printk(KERN_ERR
"%s: Failed to send frame %p, "
206 "xid <0x%x>, remaining %zu, "
208 __func__
, fp
, ep
->xid
,
209 remaining
, lport
->lso_max
);
212 return ft_queue_status(se_cmd
);
216 * Receive write data frame.
218 void ft_recv_write_data(struct ft_cmd
*cmd
, struct fc_frame
*fp
)
220 struct se_cmd
*se_cmd
= &cmd
->se_cmd
;
221 struct fc_seq
*seq
= cmd
->seq
;
223 struct fc_lport
*lport
;
224 struct se_transport_task
*task
;
225 struct fc_frame_header
*fh
;
239 task
= T_TASK(se_cmd
);
242 fh
= fc_frame_header_get(fp
);
243 if (!(ntoh24(fh
->fh_f_ctl
) & FC_FC_REL_OFF
))
247 * Doesn't expect even single byte of payload. Payload
248 * is expected to be copied directly to user buffers
249 * due to DDP (Large Rx offload) feature, hence
250 * BUG_ON if BUF is non-NULL
252 buf
= fc_frame_payload_get(fp
, 1);
253 if (cmd
->was_ddp_setup
&& buf
) {
254 printk(KERN_INFO
"%s: When DDP was setup, not expected to"
255 "receive frame with payload, Payload shall be"
256 "copied directly to buffer instead of coming "
257 "via. legacy receive queues\n", __func__
);
262 * If ft_cmd indicated 'ddp_setup', in that case only the last frame
263 * should come with 'TSI bit being set'. If 'TSI bit is not set and if
264 * data frame appears here, means error condition. In both the cases
265 * release the DDP context (ddp_put) and in error case, as well
266 * initiate error recovery mechanism.
268 ep
= fc_seq_exch(seq
);
269 if (cmd
->was_ddp_setup
) {
274 if (cmd
->was_ddp_setup
&& ep
->xid
!= FC_XID_UNKNOWN
) {
275 f_ctl
= ntoh24(fh
->fh_f_ctl
);
277 * If TSI bit set in f_ctl, means last write data frame is
278 * received successfully where payload is posted directly
279 * to user buffer and only the last frame's header is posted
280 * in legacy receive queue
282 if (f_ctl
& FC_FC_SEQ_INIT
) { /* TSI bit set in FC frame */
283 cmd
->write_data_len
= lport
->tt
.ddp_done(lport
,
288 * Updating the write_data_len may be meaningless at
289 * this point, but just in case if required in future
290 * for debugging or any other purpose
292 printk(KERN_ERR
"%s: Received frame with TSI bit not"
293 " being SET, dropping the frame, "
294 "cmd->sg <%p>, cmd->sg_cnt <0x%x>\n",
295 __func__
, cmd
->sg
, cmd
->sg_cnt
);
296 cmd
->write_data_len
= lport
->tt
.ddp_done(lport
,
298 lport
->tt
.seq_exch_abort(cmd
->seq
, 0);
303 rel_off
= ntohl(fh
->fh_parm_offset
);
304 frame_len
= fr_len(fp
);
305 if (frame_len
<= sizeof(*fh
))
307 frame_len
-= sizeof(*fh
);
308 from
= fc_frame_payload_get(fp
, 0);
309 if (rel_off
>= se_cmd
->data_length
)
311 if (frame_len
+ rel_off
> se_cmd
->data_length
)
312 frame_len
= se_cmd
->data_length
- rel_off
;
315 * Setup to use first mem list entry if any.
317 if (task
->t_tasks_se_num
) {
318 mem
= list_first_entry(task
->t_mem_list
,
319 struct se_mem
, se_list
);
320 mem_len
= mem
->se_len
;
321 mem_off
= mem
->se_off
;
333 mem
= list_entry(mem
->se_list
.next
,
334 struct se_mem
, se_list
);
335 mem_len
= mem
->se_len
;
336 mem_off
= mem
->se_off
;
339 if (rel_off
>= mem_len
) {
348 tlen
= min(mem_len
, frame_len
);
351 to
= kmap_atomic(page
+ (mem_off
>> PAGE_SHIFT
),
354 to
+= mem_off
& ~PAGE_MASK
;
355 tlen
= min(tlen
, (size_t)(PAGE_SIZE
-
356 (mem_off
& ~PAGE_MASK
)));
357 memcpy(to
, from
, tlen
);
358 kunmap_atomic(page_addr
, KM_SOFTIRQ0
);
360 to
= task
->t_task_buf
+ mem_off
;
361 memcpy(to
, from
, tlen
);
367 cmd
->write_data_len
+= tlen
;
370 if (cmd
->write_data_len
== se_cmd
->data_length
)
371 transport_generic_handle_data(se_cmd
);