1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/ratelimit.h>
29#include <asm/unaligned.h>
30#include <scsi/scsi.h>
31
32#include <target/target_core_base.h>
33#include <target/target_core_backend.h>
34#include <target/target_core_fabric.h>
35
36#include "target_core_internal.h"
37#include "target_core_ua.h"
38
39
40static int sbc_emulate_readcapacity(struct se_cmd *cmd)
41{
42 struct se_device *dev = cmd->se_dev;
43 unsigned char *buf;
44 unsigned long long blocks_long = dev->transport->get_blocks(dev);
45 u32 blocks;
46
47 if (blocks_long >= 0x00000000ffffffff)
48 blocks = 0xffffffff;
49 else
50 blocks = (u32)blocks_long;
51
52 buf = transport_kmap_data_sg(cmd);
53
54 buf[0] = (blocks >> 24) & 0xff;
55 buf[1] = (blocks >> 16) & 0xff;
56 buf[2] = (blocks >> 8) & 0xff;
57 buf[3] = blocks & 0xff;
58 buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
59 buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
60 buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
61 buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
62
63 transport_kunmap_data_sg(cmd);
64
65 target_complete_cmd(cmd, GOOD);
66 return 0;
67}
68
69static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
70{
71 struct se_device *dev = cmd->se_dev;
72 unsigned char *buf;
73 unsigned long long blocks = dev->transport->get_blocks(dev);
74
75 buf = transport_kmap_data_sg(cmd);
76
77 buf[0] = (blocks >> 56) & 0xff;
78 buf[1] = (blocks >> 48) & 0xff;
79 buf[2] = (blocks >> 40) & 0xff;
80 buf[3] = (blocks >> 32) & 0xff;
81 buf[4] = (blocks >> 24) & 0xff;
82 buf[5] = (blocks >> 16) & 0xff;
83 buf[6] = (blocks >> 8) & 0xff;
84 buf[7] = blocks & 0xff;
85 buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
86 buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
87 buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
88 buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
89
90
91
92
93 if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
94 buf[14] = 0x80;
95
96 transport_kunmap_data_sg(cmd);
97
98 target_complete_cmd(cmd, GOOD);
99 return 0;
100}
101
102int spc_get_write_same_sectors(struct se_cmd *cmd)
103{
104 u32 num_blocks;
105
106 if (cmd->t_task_cdb[0] == WRITE_SAME)
107 num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]);
108 else if (cmd->t_task_cdb[0] == WRITE_SAME_16)
109 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]);
110 else
111 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]);
112
113
114
115
116
117 if (num_blocks)
118 return num_blocks;
119
120 return cmd->se_dev->transport->get_blocks(cmd->se_dev) -
121 cmd->t_task_lba + 1;
122}
123EXPORT_SYMBOL(spc_get_write_same_sectors);
124
125static int sbc_emulate_verify(struct se_cmd *cmd)
126{
127 target_complete_cmd(cmd, GOOD);
128 return 0;
129}
130
131static int sbc_emulate_noop(struct se_cmd *cmd)
132{
133 target_complete_cmd(cmd, GOOD);
134 return 0;
135}
136
137static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors)
138{
139 return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors;
140}
141
142static int sbc_check_valid_sectors(struct se_cmd *cmd)
143{
144 struct se_device *dev = cmd->se_dev;
145 unsigned long long end_lba;
146 u32 sectors;
147
148 sectors = cmd->data_length / dev->se_sub_dev->se_dev_attrib.block_size;
149 end_lba = dev->transport->get_blocks(dev) + 1;
150
151 if (cmd->t_task_lba + sectors > end_lba) {
152 pr_err("target: lba %llu, sectors %u exceeds end lba %llu\n",
153 cmd->t_task_lba, sectors, end_lba);
154 return -EINVAL;
155 }
156
157 return 0;
158}
159
160static inline u32 transport_get_sectors_6(unsigned char *cdb)
161{
162
163
164
165
166
167
168
169
170 return cdb[4] ? : 256;
171}
172
173static inline u32 transport_get_sectors_10(unsigned char *cdb)
174{
175 return (u32)(cdb[7] << 8) + cdb[8];
176}
177
178static inline u32 transport_get_sectors_12(unsigned char *cdb)
179{
180 return (u32)(cdb[6] << 24) + (cdb[7] << 16) + (cdb[8] << 8) + cdb[9];
181}
182
183static inline u32 transport_get_sectors_16(unsigned char *cdb)
184{
185 return (u32)(cdb[10] << 24) + (cdb[11] << 16) +
186 (cdb[12] << 8) + cdb[13];
187}
188
189
190
191
192static inline u32 transport_get_sectors_32(unsigned char *cdb)
193{
194 return (u32)(cdb[28] << 24) + (cdb[29] << 16) +
195 (cdb[30] << 8) + cdb[31];
196
197}
198
199static inline u32 transport_lba_21(unsigned char *cdb)
200{
201 return ((cdb[1] & 0x1f) << 16) | (cdb[2] << 8) | cdb[3];
202}
203
204static inline u32 transport_lba_32(unsigned char *cdb)
205{
206 return (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
207}
208
209static inline unsigned long long transport_lba_64(unsigned char *cdb)
210{
211 unsigned int __v1, __v2;
212
213 __v1 = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5];
214 __v2 = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
215
216 return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32;
217}
218
219
220
221
222static inline unsigned long long transport_lba_64_ext(unsigned char *cdb)
223{
224 unsigned int __v1, __v2;
225
226 __v1 = (cdb[12] << 24) | (cdb[13] << 16) | (cdb[14] << 8) | cdb[15];
227 __v2 = (cdb[16] << 24) | (cdb[17] << 16) | (cdb[18] << 8) | cdb[19];
228
229 return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32;
230}
231
232static int sbc_write_same_supported(struct se_device *dev,
233 unsigned char *flags)
234{
235 if ((flags[0] & 0x04) || (flags[0] & 0x02)) {
236 pr_err("WRITE_SAME PBDATA and LBDATA"
237 " bits not supported for Block Discard"
238 " Emulation\n");
239 return -ENOSYS;
240 }
241
242
243
244
245
246 if (!(flags[0] & 0x08)) {
247 pr_err("WRITE_SAME w/o UNMAP bit not"
248 " supported for Block Discard Emulation\n");
249 return -ENOSYS;
250 }
251
252 return 0;
253}
254
255static void xdreadwrite_callback(struct se_cmd *cmd)
256{
257 unsigned char *buf, *addr;
258 struct scatterlist *sg;
259 unsigned int offset;
260 int i;
261 int count;
262
263
264
265
266
267
268
269
270
271
272
273 buf = kmalloc(cmd->data_length, GFP_KERNEL);
274 if (!buf) {
275 pr_err("Unable to allocate xor_callback buf\n");
276 return;
277 }
278
279
280
281
282 sg_copy_to_buffer(cmd->t_data_sg,
283 cmd->t_data_nents,
284 buf,
285 cmd->data_length);
286
287
288
289
290
291
292 offset = 0;
293 for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) {
294 addr = kmap_atomic(sg_page(sg));
295 if (!addr)
296 goto out;
297
298 for (i = 0; i < sg->length; i++)
299 *(addr + sg->offset + i) ^= *(buf + offset + i);
300
301 offset += sg->length;
302 kunmap_atomic(addr);
303 }
304
305out:
306 kfree(buf);
307}
308
309int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops)
310{
311 struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
312 struct se_device *dev = cmd->se_dev;
313 unsigned char *cdb = cmd->t_task_cdb;
314 unsigned int size;
315 u32 sectors = 0;
316 int ret;
317
318 switch (cdb[0]) {
319 case READ_6:
320 sectors = transport_get_sectors_6(cdb);
321 cmd->t_task_lba = transport_lba_21(cdb);
322 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
323 cmd->execute_cmd = ops->execute_rw;
324 break;
325 case READ_10:
326 sectors = transport_get_sectors_10(cdb);
327 cmd->t_task_lba = transport_lba_32(cdb);
328 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
329 cmd->execute_cmd = ops->execute_rw;
330 break;
331 case READ_12:
332 sectors = transport_get_sectors_12(cdb);
333 cmd->t_task_lba = transport_lba_32(cdb);
334 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
335 cmd->execute_cmd = ops->execute_rw;
336 break;
337 case READ_16:
338 sectors = transport_get_sectors_16(cdb);
339 cmd->t_task_lba = transport_lba_64(cdb);
340 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
341 cmd->execute_cmd = ops->execute_rw;
342 break;
343 case WRITE_6:
344 sectors = transport_get_sectors_6(cdb);
345 cmd->t_task_lba = transport_lba_21(cdb);
346 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
347 cmd->execute_cmd = ops->execute_rw;
348 break;
349 case WRITE_10:
350 case WRITE_VERIFY:
351 sectors = transport_get_sectors_10(cdb);
352 cmd->t_task_lba = transport_lba_32(cdb);
353 if (cdb[1] & 0x8)
354 cmd->se_cmd_flags |= SCF_FUA;
355 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
356 cmd->execute_cmd = ops->execute_rw;
357 break;
358 case WRITE_12:
359 sectors = transport_get_sectors_12(cdb);
360 cmd->t_task_lba = transport_lba_32(cdb);
361 if (cdb[1] & 0x8)
362 cmd->se_cmd_flags |= SCF_FUA;
363 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
364 cmd->execute_cmd = ops->execute_rw;
365 break;
366 case WRITE_16:
367 sectors = transport_get_sectors_16(cdb);
368 cmd->t_task_lba = transport_lba_64(cdb);
369 if (cdb[1] & 0x8)
370 cmd->se_cmd_flags |= SCF_FUA;
371 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
372 cmd->execute_cmd = ops->execute_rw;
373 break;
374 case XDWRITEREAD_10:
375 if ((cmd->data_direction != DMA_TO_DEVICE) ||
376 !(cmd->se_cmd_flags & SCF_BIDI))
377 goto out_invalid_cdb_field;
378 sectors = transport_get_sectors_10(cdb);
379
380 cmd->t_task_lba = transport_lba_32(cdb);
381 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
382
383
384
385
386 cmd->execute_cmd = ops->execute_rw;
387 cmd->transport_complete_callback = &xdreadwrite_callback;
388 if (cdb[1] & 0x8)
389 cmd->se_cmd_flags |= SCF_FUA;
390 break;
391 case VARIABLE_LENGTH_CMD:
392 {
393 u16 service_action = get_unaligned_be16(&cdb[8]);
394 switch (service_action) {
395 case XDWRITEREAD_32:
396 sectors = transport_get_sectors_32(cdb);
397
398
399
400
401
402 cmd->t_task_lba = transport_lba_64_ext(cdb);
403 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB;
404
405
406
407
408
409 cmd->execute_cmd = ops->execute_rw;
410 cmd->transport_complete_callback = &xdreadwrite_callback;
411 if (cdb[1] & 0x8)
412 cmd->se_cmd_flags |= SCF_FUA;
413 break;
414 case WRITE_SAME_32:
415 if (!ops->execute_write_same)
416 goto out_unsupported_cdb;
417
418 sectors = transport_get_sectors_32(cdb);
419 if (!sectors) {
420 pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not"
421 " supported\n");
422 goto out_invalid_cdb_field;
423 }
424
425 size = sbc_get_size(cmd, 1);
426 cmd->t_task_lba = get_unaligned_be64(&cdb[12]);
427
428 if (sbc_write_same_supported(dev, &cdb[10]) < 0)
429 goto out_unsupported_cdb;
430 cmd->execute_cmd = ops->execute_write_same;
431 break;
432 default:
433 pr_err("VARIABLE_LENGTH_CMD service action"
434 " 0x%04x not supported\n", service_action);
435 goto out_unsupported_cdb;
436 }
437 break;
438 }
439 case READ_CAPACITY:
440 size = READ_CAP_LEN;
441 cmd->execute_cmd = sbc_emulate_readcapacity;
442 break;
443 case SERVICE_ACTION_IN:
444 switch (cmd->t_task_cdb[1] & 0x1f) {
445 case SAI_READ_CAPACITY_16:
446 cmd->execute_cmd = sbc_emulate_readcapacity_16;
447 break;
448 default:
449 pr_err("Unsupported SA: 0x%02x\n",
450 cmd->t_task_cdb[1] & 0x1f);
451 goto out_invalid_cdb_field;
452 }
453 size = (cdb[10] << 24) | (cdb[11] << 16) |
454 (cdb[12] << 8) | cdb[13];
455 break;
456 case SYNCHRONIZE_CACHE:
457 case SYNCHRONIZE_CACHE_16:
458 if (!ops->execute_sync_cache)
459 goto out_unsupported_cdb;
460
461
462
463
464 if (cdb[0] == SYNCHRONIZE_CACHE) {
465 sectors = transport_get_sectors_10(cdb);
466 cmd->t_task_lba = transport_lba_32(cdb);
467 } else {
468 sectors = transport_get_sectors_16(cdb);
469 cmd->t_task_lba = transport_lba_64(cdb);
470 }
471
472 size = sbc_get_size(cmd, sectors);
473
474
475
476
477
478 if (cmd->t_task_lba || sectors) {
479 if (sbc_check_valid_sectors(cmd) < 0)
480 goto out_invalid_cdb_field;
481 }
482 cmd->execute_cmd = ops->execute_sync_cache;
483 break;
484 case UNMAP:
485 if (!ops->execute_unmap)
486 goto out_unsupported_cdb;
487
488 size = get_unaligned_be16(&cdb[7]);
489 cmd->execute_cmd = ops->execute_unmap;
490 break;
491 case WRITE_SAME_16:
492 if (!ops->execute_write_same)
493 goto out_unsupported_cdb;
494
495 sectors = transport_get_sectors_16(cdb);
496 if (!sectors) {
497 pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n");
498 goto out_invalid_cdb_field;
499 }
500
501 size = sbc_get_size(cmd, 1);
502 cmd->t_task_lba = get_unaligned_be64(&cdb[2]);
503
504 if (sbc_write_same_supported(dev, &cdb[1]) < 0)
505 goto out_unsupported_cdb;
506 cmd->execute_cmd = ops->execute_write_same;
507 break;
508 case WRITE_SAME:
509 if (!ops->execute_write_same)
510 goto out_unsupported_cdb;
511
512 sectors = transport_get_sectors_10(cdb);
513 if (!sectors) {
514 pr_err("WSNZ=1, WRITE_SAME w/sectors=0 not supported\n");
515 goto out_invalid_cdb_field;
516 }
517
518 size = sbc_get_size(cmd, 1);
519 cmd->t_task_lba = get_unaligned_be32(&cdb[2]);
520
521
522
523
524
525 if (sbc_write_same_supported(dev, &cdb[1]) < 0)
526 goto out_unsupported_cdb;
527 cmd->execute_cmd = ops->execute_write_same;
528 break;
529 case VERIFY:
530 size = 0;
531 cmd->execute_cmd = sbc_emulate_verify;
532 break;
533 case REZERO_UNIT:
534 case SEEK_6:
535 case SEEK_10:
536
537
538
539
540
541
542 size = 0;
543 cmd->execute_cmd = sbc_emulate_noop;
544 break;
545 default:
546 ret = spc_parse_cdb(cmd, &size);
547 if (ret)
548 return ret;
549 }
550
551
552 if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->execute_cmd)
553 goto out_unsupported_cdb;
554
555 if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
556 unsigned long long end_lba;
557
558 if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) {
559 printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
560 " big sectors %u exceeds fabric_max_sectors:"
561 " %u\n", cdb[0], sectors,
562 su_dev->se_dev_attrib.fabric_max_sectors);
563 goto out_invalid_cdb_field;
564 }
565 if (sectors > su_dev->se_dev_attrib.hw_max_sectors) {
566 printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
567 " big sectors %u exceeds backend hw_max_sectors:"
568 " %u\n", cdb[0], sectors,
569 su_dev->se_dev_attrib.hw_max_sectors);
570 goto out_invalid_cdb_field;
571 }
572
573 end_lba = dev->transport->get_blocks(dev) + 1;
574 if (cmd->t_task_lba + sectors > end_lba) {
575 pr_err("cmd exceeds last lba %llu "
576 "(lba %llu, sectors %u)\n",
577 end_lba, cmd->t_task_lba, sectors);
578 goto out_invalid_cdb_field;
579 }
580
581 size = sbc_get_size(cmd, sectors);
582 }
583
584 ret = target_cmd_size_check(cmd, size);
585 if (ret < 0)
586 return ret;
587
588 return 0;
589
590out_unsupported_cdb:
591 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
592 cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
593 return -EINVAL;
594out_invalid_cdb_field:
595 cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
596 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
597 return -EINVAL;
598}
599EXPORT_SYMBOL(sbc_parse_cdb);
600