Lines Matching +full:write +full:- +full:protect

1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * (c) Copyright 2002-2013 Datera, Inc.
13 #include <linux/crc-t10dif.h>
14 #include <linux/t10-pi.h>
34 struct se_device *dev = cmd->se_dev; in sbc_emulate_readcapacity()
35 unsigned char *cdb = cmd->t_task_cdb; in sbc_emulate_readcapacity()
36 unsigned long long blocks_long = dev->transport->get_blocks(dev); in sbc_emulate_readcapacity()
42 * SBC-2 says: in sbc_emulate_readcapacity()
49 * In SBC-3, these fields are obsolete, but some SCSI in sbc_emulate_readcapacity()
51 * follow SBC-2. in sbc_emulate_readcapacity()
62 put_unaligned_be32(dev->dev_attrib.block_size, &buf[4]); in sbc_emulate_readcapacity()
66 memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); in sbc_emulate_readcapacity()
77 struct se_device *dev = cmd->se_dev; in sbc_emulate_readcapacity_16()
78 struct se_session *sess = cmd->se_sess; in sbc_emulate_readcapacity_16()
79 int pi_prot_type = dev->dev_attrib.pi_prot_type; in sbc_emulate_readcapacity_16()
83 unsigned long long blocks = dev->transport->get_blocks(dev); in sbc_emulate_readcapacity_16()
87 put_unaligned_be32(dev->dev_attrib.block_size, &buf[8]); in sbc_emulate_readcapacity_16()
91 if (sess->sup_prot_ops & (TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS)) { in sbc_emulate_readcapacity_16()
93 * Only override a device's pi_prot_type if no T10-PI is in sbc_emulate_readcapacity_16()
97 pi_prot_type = sess->sess_prot_type; in sbc_emulate_readcapacity_16()
100 buf[12] = (pi_prot_type - 1) << 1 | 0x1; in sbc_emulate_readcapacity_16()
103 if (dev->transport->get_lbppbe) in sbc_emulate_readcapacity_16()
104 buf[13] = dev->transport->get_lbppbe(dev) & 0x0f; in sbc_emulate_readcapacity_16()
106 if (dev->transport->get_alignment_offset_lbas) { in sbc_emulate_readcapacity_16()
107 u16 lalba = dev->transport->get_alignment_offset_lbas(dev); in sbc_emulate_readcapacity_16()
116 if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) { in sbc_emulate_readcapacity_16()
121 * an UNMAP or WRITE SAME w/ unmap bit (sbc3r36 5.16.2) in sbc_emulate_readcapacity_16()
123 if (dev->dev_attrib.unmap_zeroes_data) in sbc_emulate_readcapacity_16()
129 memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); in sbc_emulate_readcapacity_16()
140 unsigned char *cdb = cmd->t_task_cdb; in sbc_emulate_startstop()
152 * POWER CONDITION 0h START_VALID - process START and LOEJ in sbc_emulate_startstop()
159 * LOEJ 0h - nothing to load or unload in sbc_emulate_startstop()
160 * START 1h - we are ready in sbc_emulate_startstop()
173 if (cmd->t_task_cdb[0] == WRITE_SAME) in sbc_get_write_same_sectors()
174 num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); in sbc_get_write_same_sectors()
175 else if (cmd->t_task_cdb[0] == WRITE_SAME_16) in sbc_get_write_same_sectors()
176 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); in sbc_get_write_same_sectors()
178 num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); in sbc_get_write_same_sectors()
182 * the remaining range based on ->get_blocks() - starting LBA. in sbc_get_write_same_sectors()
187 return cmd->se_dev->transport->get_blocks(cmd->se_dev) - in sbc_get_write_same_sectors()
188 cmd->t_task_lba + 1; in sbc_get_write_same_sectors()
195 struct sbc_ops *ops = cmd->protocol_data; in sbc_execute_write_same_unmap()
200 ret = ops->execute_unmap(cmd, cmd->t_task_lba, nolb); in sbc_execute_write_same_unmap()
218 return cmd->se_dev->dev_attrib.block_size * sectors; in sbc_get_size()
224 * Use 8-bit sector value. SBC-3 says: in transport_get_sectors_6()
284 struct se_device *dev = cmd->se_dev; in sbc_setup_write_same()
285 sector_t end_lba = dev->transport->get_blocks(dev) + 1; in sbc_setup_write_same()
295 if (sectors > cmd->se_dev->dev_attrib.max_write_same_len) { in sbc_setup_write_same()
297 sectors, cmd->se_dev->dev_attrib.max_write_same_len); in sbc_setup_write_same()
303 if (((cmd->t_task_lba + sectors) < cmd->t_task_lba) || in sbc_setup_write_same()
304 ((cmd->t_task_lba + sectors) > end_lba)) { in sbc_setup_write_same()
306 (unsigned long long)end_lba, cmd->t_task_lba, sectors); in sbc_setup_write_same()
312 pr_warn("WRITE SAME with ANCHOR not supported\n"); in sbc_setup_write_same()
320 if (!ops->execute_unmap) in sbc_setup_write_same()
323 if (!dev->dev_attrib.emulate_tpws) { in sbc_setup_write_same()
328 cmd->execute_cmd = sbc_execute_write_same_unmap; in sbc_setup_write_same()
331 if (!ops->execute_write_same) in sbc_setup_write_same()
334 ret = sbc_check_prot(dev, cmd, &cmd->t_task_cdb[0], sectors, true); in sbc_setup_write_same()
338 cmd->execute_cmd = ops->execute_write_same; in sbc_setup_write_same()
358 * 2) transfer logical blocks from the data-out buffer; in xdreadwrite_callback()
359 * 3) XOR the logical blocks transferred from the data-out buffer with in xdreadwrite_callback()
361 * 4) if the DISABLE WRITE bit is set to zero, then write the logical in xdreadwrite_callback()
362 * blocks transferred from the data-out buffer; and in xdreadwrite_callback()
363 * 5) transfer the resulting XOR data to the data-in buffer. in xdreadwrite_callback()
365 buf = kmalloc(cmd->data_length, GFP_KERNEL); in xdreadwrite_callback()
371 * Copy the scatterlist WRITE buffer located at cmd->t_data_sg in xdreadwrite_callback()
374 sg_copy_to_buffer(cmd->t_data_sg, in xdreadwrite_callback()
375 cmd->t_data_nents, in xdreadwrite_callback()
377 cmd->data_length); in xdreadwrite_callback()
381 * cmd->t_mem_bidi_list in xdreadwrite_callback()
385 for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) { in xdreadwrite_callback()
392 for (i = 0; i < sg->length; i++) in xdreadwrite_callback()
393 *(addr + sg->offset + i) ^= *(buf + offset + i); in xdreadwrite_callback()
395 offset += sg->length; in xdreadwrite_callback()
407 struct sbc_ops *ops = cmd->protocol_data; in sbc_execute_rw()
409 return ops->execute_rw(cmd, cmd->t_data_sg, cmd->t_data_nents, in sbc_execute_rw()
410 cmd->data_direction); in sbc_execute_rw()
416 struct se_device *dev = cmd->se_dev; in compare_and_write_post()
419 spin_lock_irq(&cmd->t_state_lock); in compare_and_write_post()
423 if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION) in compare_and_write_post()
426 spin_unlock_irq(&cmd->t_state_lock); in compare_and_write_post()
429 * Unlock ->caw_sem originally obtained during sbc_compare_and_write() in compare_and_write_post()
432 up(&dev->caw_sem); in compare_and_write_post()
440 struct se_device *dev = cmd->se_dev; in compare_and_write_callback()
446 unsigned int nlbas = cmd->t_task_nolb; in compare_and_write_callback()
447 unsigned int block_size = dev->dev_attrib.block_size; in compare_and_write_callback()
454 * which will not have taken ->caw_sem yet.. in compare_and_write_callback()
456 if (!success && (!cmd->t_data_sg || !cmd->t_bidi_data_sg)) in compare_and_write_callback()
459 * Handle special case for zero-length COMPARE_AND_WRITE in compare_and_write_callback()
461 if (!cmd->data_length) in compare_and_write_callback()
464 * Immediately exit + release dev->caw_sem if command has already in compare_and_write_callback()
465 * been failed with a non-zero SCSI status. in compare_and_write_callback()
467 if (cmd->scsi_status) { in compare_and_write_callback()
469 " 0x%02x\n", cmd->scsi_status); in compare_and_write_callback()
471 if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION) in compare_and_write_callback()
476 buf = kzalloc(cmd->data_length, GFP_KERNEL); in compare_and_write_callback()
483 if (sg_alloc_table(&write_tbl, cmd->t_data_nents, GFP_KERNEL) < 0) { in compare_and_write_callback()
490 * Setup verify and write data payloads from total NumberLBAs. in compare_and_write_callback()
492 rc = sg_copy_to_buffer(cmd->t_data_sg, cmd->t_data_nents, buf, in compare_and_write_callback()
493 cmd->data_length); in compare_and_write_callback()
502 for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, i) { in compare_and_write_callback()
509 len = min(sg->length, compare_len); in compare_and_write_callback()
520 compare_len -= len; in compare_and_write_callback()
526 len = cmd->t_task_nolb * block_size; in compare_and_write_callback()
527 sg_miter_start(&m, cmd->t_data_sg, cmd->t_data_nents, SG_MITER_TO_SG); in compare_and_write_callback()
536 m.piter.sg->offset + block_size); in compare_and_write_callback()
540 m.piter.sg->offset); in compare_and_write_callback()
542 len -= block_size; in compare_and_write_callback()
548 * assignments, to be released in transport_free_pages() -> in compare_and_write_callback()
551 cmd->t_data_sg_orig = cmd->t_data_sg; in compare_and_write_callback()
552 cmd->t_data_sg = write_sg; in compare_and_write_callback()
553 cmd->t_data_nents_orig = cmd->t_data_nents; in compare_and_write_callback()
554 cmd->t_data_nents = 1; in compare_and_write_callback()
556 cmd->sam_task_attr = TCM_HEAD_TAG; in compare_and_write_callback()
557 cmd->transport_complete_callback = compare_and_write_post; in compare_and_write_callback()
559 * Now reset ->execute_cmd() to the normal sbc_execute_rw() handler in compare_and_write_callback()
560 * for submitting the adjusted SGL to write instance user-data. in compare_and_write_callback()
562 cmd->execute_cmd = sbc_execute_rw; in compare_and_write_callback()
564 spin_lock_irq(&cmd->t_state_lock); in compare_and_write_callback()
565 cmd->t_state = TRANSPORT_PROCESSING; in compare_and_write_callback()
566 cmd->transport_state |= CMD_T_ACTIVE | CMD_T_SENT; in compare_and_write_callback()
567 spin_unlock_irq(&cmd->t_state_lock); in compare_and_write_callback()
576 dev->transport->name); in compare_and_write_callback()
580 * In the MISCOMPARE or failure case, unlock ->caw_sem obtained in in compare_and_write_callback()
583 up(&dev->caw_sem); in compare_and_write_callback()
592 struct sbc_ops *ops = cmd->protocol_data; in sbc_compare_and_write()
593 struct se_device *dev = cmd->se_dev; in sbc_compare_and_write()
598 * comparision using SGLs at cmd->t_bidi_data_sg.. in sbc_compare_and_write()
600 rc = down_interruptible(&dev->caw_sem); in sbc_compare_and_write()
602 cmd->transport_complete_callback = NULL; in sbc_compare_and_write()
606 * Reset cmd->data_length to individual block_size in order to not in sbc_compare_and_write()
610 cmd->data_length = cmd->t_task_nolb * dev->dev_attrib.block_size; in sbc_compare_and_write()
612 ret = ops->execute_rw(cmd, cmd->t_bidi_data_sg, cmd->t_bidi_data_nents, in sbc_compare_and_write()
615 cmd->transport_complete_callback = NULL; in sbc_compare_and_write()
616 up(&dev->caw_sem); in sbc_compare_and_write()
620 * Unlock of dev->caw_sem to occur in compare_and_write_callback() in sbc_compare_and_write()
622 * of WRITE instance user-data. in sbc_compare_and_write()
628 sbc_set_prot_op_checks(u8 protect, bool fabric_prot, enum target_prot_type prot_type, in sbc_set_prot_op_checks() argument
632 cmd->prot_op = fabric_prot ? TARGET_PROT_DOUT_STRIP : in sbc_set_prot_op_checks()
633 protect ? TARGET_PROT_DOUT_PASS : in sbc_set_prot_op_checks()
635 switch (protect) { in sbc_set_prot_op_checks()
638 cmd->prot_checks = 0; in sbc_set_prot_op_checks()
642 cmd->prot_checks = TARGET_DIF_CHECK_GUARD; in sbc_set_prot_op_checks()
644 cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG; in sbc_set_prot_op_checks()
648 cmd->prot_checks = TARGET_DIF_CHECK_REFTAG; in sbc_set_prot_op_checks()
651 cmd->prot_checks = TARGET_DIF_CHECK_GUARD; in sbc_set_prot_op_checks()
654 pr_err("Unsupported protect field %d\n", protect); in sbc_set_prot_op_checks()
655 return -EINVAL; in sbc_set_prot_op_checks()
658 cmd->prot_op = fabric_prot ? TARGET_PROT_DIN_INSERT : in sbc_set_prot_op_checks()
659 protect ? TARGET_PROT_DIN_PASS : in sbc_set_prot_op_checks()
661 switch (protect) { in sbc_set_prot_op_checks()
665 cmd->prot_checks = TARGET_DIF_CHECK_GUARD; in sbc_set_prot_op_checks()
667 cmd->prot_checks |= TARGET_DIF_CHECK_REFTAG; in sbc_set_prot_op_checks()
671 cmd->prot_checks = TARGET_DIF_CHECK_REFTAG; in sbc_set_prot_op_checks()
674 cmd->prot_checks = 0; in sbc_set_prot_op_checks()
677 cmd->prot_checks = TARGET_DIF_CHECK_GUARD; in sbc_set_prot_op_checks()
680 pr_err("Unsupported protect field %d\n", protect); in sbc_set_prot_op_checks()
681 return -EINVAL; in sbc_set_prot_op_checks()
692 u8 protect = cdb[1] >> 5; in sbc_check_prot() local
693 int sp_ops = cmd->se_sess->sup_prot_ops; in sbc_check_prot()
694 int pi_prot_type = dev->dev_attrib.pi_prot_type; in sbc_check_prot()
697 if (!cmd->t_prot_sg || !cmd->t_prot_nents) { in sbc_check_prot()
698 if (unlikely(protect && in sbc_check_prot()
699 !dev->dev_attrib.pi_prot_type && !cmd->se_sess->sess_prot_type)) { in sbc_check_prot()
700 pr_err("CDB contains protect bit, but device + fabric does" in sbc_check_prot()
701 " not advertise PROTECT=1 feature bit\n"); in sbc_check_prot()
704 if (cmd->prot_pto) in sbc_check_prot()
708 switch (dev->dev_attrib.pi_prot_type) { in sbc_check_prot()
710 cmd->reftag_seed = 0xffffffff; in sbc_check_prot()
713 if (protect) in sbc_check_prot()
716 cmd->reftag_seed = cmd->t_task_lba; in sbc_check_prot()
719 cmd->reftag_seed = cmd->t_task_lba; in sbc_check_prot()
723 * See if the fabric supports T10-PI, and the session has been in sbc_check_prot()
724 * configured to allow export PROTECT=1 feature bit with backend in sbc_check_prot()
725 * devices that don't support T10-PI. in sbc_check_prot()
731 if (fabric_prot && cmd->se_sess->sess_prot_type) { in sbc_check_prot()
732 pi_prot_type = cmd->se_sess->sess_prot_type; in sbc_check_prot()
735 if (!protect) in sbc_check_prot()
740 "PROTECT: 0x%02x\n", cdb[0], protect); in sbc_check_prot()
744 if (sbc_set_prot_op_checks(protect, fabric_prot, pi_prot_type, is_write, cmd)) in sbc_check_prot()
747 cmd->prot_type = pi_prot_type; in sbc_check_prot()
748 cmd->prot_length = dev->prot_length * sectors; in sbc_check_prot()
756 if (protect) in sbc_check_prot()
757 cmd->data_length = sectors * dev->dev_attrib.block_size; in sbc_check_prot()
761 __func__, cmd->prot_type, cmd->data_length, cmd->prot_length, in sbc_check_prot()
762 cmd->prot_op, cmd->prot_checks); in sbc_check_prot()
775 return -EINVAL; in sbc_check_dpofua()
781 " does not advertise support for FUA write\n", in sbc_check_dpofua()
783 return -EINVAL; in sbc_check_dpofua()
785 cmd->se_cmd_flags |= SCF_FUA; in sbc_check_dpofua()
793 struct se_device *dev = cmd->se_dev; in sbc_parse_cdb()
794 unsigned char *cdb = cmd->t_task_cdb; in sbc_parse_cdb()
799 cmd->protocol_data = ops; in sbc_parse_cdb()
804 cmd->t_task_lba = transport_lba_21(cdb); in sbc_parse_cdb()
805 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
806 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
810 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
819 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
820 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
824 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
833 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
834 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
838 cmd->t_task_lba = transport_lba_64(cdb); in sbc_parse_cdb()
847 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
848 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
852 cmd->t_task_lba = transport_lba_21(cdb); in sbc_parse_cdb()
853 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
854 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
859 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
868 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
869 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
873 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
882 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
883 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
888 cmd->t_task_lba = transport_lba_64(cdb); in sbc_parse_cdb()
897 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
898 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
901 if (cmd->data_direction != DMA_TO_DEVICE || in sbc_parse_cdb()
902 !(cmd->se_cmd_flags & SCF_BIDI)) in sbc_parse_cdb()
909 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
910 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
915 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
916 cmd->transport_complete_callback = &xdreadwrite_callback; in sbc_parse_cdb()
931 cmd->t_task_lba = transport_lba_64_ext(cdb); in sbc_parse_cdb()
932 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB; in sbc_parse_cdb()
938 cmd->execute_cmd = sbc_execute_rw; in sbc_parse_cdb()
939 cmd->transport_complete_callback = &xdreadwrite_callback; in sbc_parse_cdb()
950 cmd->t_task_lba = get_unaligned_be64(&cdb[12]); in sbc_parse_cdb()
964 if (!dev->dev_attrib.emulate_caw) { in sbc_parse_cdb()
966 dev->se_hba->backend->ops->name, in sbc_parse_cdb()
967 config_item_name(&dev->dev_group.cg_item), in sbc_parse_cdb()
968 dev->t10_wwn.unit_serial); in sbc_parse_cdb()
988 cmd->t_task_lba = get_unaligned_be64(&cdb[2]); in sbc_parse_cdb()
989 cmd->t_task_nolb = sectors; in sbc_parse_cdb()
990 cmd->se_cmd_flags |= SCF_SCSI_DATA_CDB | SCF_COMPARE_AND_WRITE; in sbc_parse_cdb()
991 cmd->execute_cmd = sbc_compare_and_write; in sbc_parse_cdb()
992 cmd->transport_complete_callback = compare_and_write_callback; in sbc_parse_cdb()
996 cmd->execute_cmd = sbc_emulate_readcapacity; in sbc_parse_cdb()
999 switch (cmd->t_task_cdb[1] & 0x1f) { in sbc_parse_cdb()
1001 cmd->execute_cmd = sbc_emulate_readcapacity_16; in sbc_parse_cdb()
1004 cmd->execute_cmd = target_emulate_report_referrals; in sbc_parse_cdb()
1008 cmd->t_task_cdb[1] & 0x1f); in sbc_parse_cdb()
1017 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
1020 cmd->t_task_lba = transport_lba_64(cdb); in sbc_parse_cdb()
1022 if (ops->execute_sync_cache) { in sbc_parse_cdb()
1023 cmd->execute_cmd = ops->execute_sync_cache; in sbc_parse_cdb()
1027 cmd->execute_cmd = sbc_emulate_noop; in sbc_parse_cdb()
1030 if (!ops->execute_unmap) in sbc_parse_cdb()
1033 if (!dev->dev_attrib.emulate_tpu) { in sbc_parse_cdb()
1039 cmd->execute_cmd = sbc_execute_unmap; in sbc_parse_cdb()
1049 cmd->t_task_lba = get_unaligned_be64(&cdb[2]); in sbc_parse_cdb()
1063 cmd->t_task_lba = get_unaligned_be32(&cdb[2]); in sbc_parse_cdb()
1078 cmd->t_task_lba = transport_lba_32(cdb); in sbc_parse_cdb()
1081 cmd->t_task_lba = transport_lba_64(cdb); in sbc_parse_cdb()
1083 cmd->execute_cmd = sbc_emulate_noop; in sbc_parse_cdb()
1089 * There are still clients out there which use these old SCSI-2 in sbc_parse_cdb()
1091 * guest systems, connected via SCSI command pass-through to in sbc_parse_cdb()
1095 cmd->execute_cmd = sbc_emulate_noop; in sbc_parse_cdb()
1099 cmd->execute_cmd = sbc_emulate_startstop; in sbc_parse_cdb()
1108 if (!cmd->execute_cmd) in sbc_parse_cdb()
1111 if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { in sbc_parse_cdb()
1114 end_lba = dev->transport->get_blocks(dev) + 1; in sbc_parse_cdb()
1115 if (((cmd->t_task_lba + sectors) < cmd->t_task_lba) || in sbc_parse_cdb()
1116 ((cmd->t_task_lba + sectors) > end_lba)) { in sbc_parse_cdb()
1119 end_lba, cmd->t_task_lba, sectors); in sbc_parse_cdb()
1123 if (!(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE)) in sbc_parse_cdb()
1140 struct sbc_ops *ops = cmd->protocol_data; in sbc_execute_unmap()
1141 struct se_device *dev = cmd->se_dev; in sbc_execute_unmap()
1150 if (cmd->t_task_cdb[1]) in sbc_execute_unmap()
1153 if (cmd->data_length == 0) { in sbc_execute_unmap()
1158 if (cmd->data_length < 8) { in sbc_execute_unmap()
1160 cmd->data_length); in sbc_execute_unmap()
1171 size = cmd->data_length - 8; in sbc_execute_unmap()
1174 cmd->data_length, bd_dl); in sbc_execute_unmap()
1178 if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) { in sbc_execute_unmap()
1186 " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr); in sbc_execute_unmap()
1194 if (range > dev->dev_attrib.max_unmap_lba_count) { in sbc_execute_unmap()
1199 if (lba + range > dev->transport->get_blocks(dev) + 1) { in sbc_execute_unmap()
1205 ret = ops->execute_unmap(cmd, lba, range); in sbc_execute_unmap()
1211 size -= 16; in sbc_execute_unmap()
1224 struct se_device *dev = cmd->se_dev; in sbc_dif_generate()
1226 struct scatterlist *dsg = cmd->t_data_sg, *psg; in sbc_dif_generate()
1227 sector_t sector = cmd->t_task_lba; in sbc_dif_generate()
1230 unsigned int block_size = dev->dev_attrib.block_size; in sbc_dif_generate()
1232 for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { in sbc_dif_generate()
1233 paddr = kmap_atomic(sg_page(psg)) + psg->offset; in sbc_dif_generate()
1234 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_generate()
1236 for (j = 0; j < psg->length; in sbc_dif_generate()
1241 if (offset >= dsg->length) { in sbc_dif_generate()
1242 offset -= dsg->length; in sbc_dif_generate()
1243 kunmap_atomic(daddr - dsg->offset); in sbc_dif_generate()
1246 kunmap_atomic(paddr - psg->offset); in sbc_dif_generate()
1249 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_generate()
1253 avail = min(block_size, dsg->length - offset); in sbc_dif_generate()
1256 kunmap_atomic(daddr - dsg->offset); in sbc_dif_generate()
1259 kunmap_atomic(paddr - psg->offset); in sbc_dif_generate()
1262 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_generate()
1263 offset = block_size - avail; in sbc_dif_generate()
1269 sdt->guard_tag = cpu_to_be16(crc); in sbc_dif_generate()
1270 if (cmd->prot_type == TARGET_DIF_TYPE1_PROT) in sbc_dif_generate()
1271 sdt->ref_tag = cpu_to_be32(sector & 0xffffffff); in sbc_dif_generate()
1272 sdt->app_tag = 0; in sbc_dif_generate()
1276 (cmd->data_direction == DMA_TO_DEVICE) ? in sbc_dif_generate()
1277 "WRITE" : "READ", (unsigned long long)sector, in sbc_dif_generate()
1278 sdt->guard_tag, sdt->app_tag, in sbc_dif_generate()
1279 be32_to_cpu(sdt->ref_tag)); in sbc_dif_generate()
1284 kunmap_atomic(daddr - dsg->offset); in sbc_dif_generate()
1285 kunmap_atomic(paddr - psg->offset); in sbc_dif_generate()
1295 if (!(cmd->prot_checks & TARGET_DIF_CHECK_GUARD)) in sbc_dif_v1_verify()
1300 if (sdt->guard_tag != csum) { in sbc_dif_v1_verify()
1303 be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); in sbc_dif_v1_verify()
1308 if (!(cmd->prot_checks & TARGET_DIF_CHECK_REFTAG)) in sbc_dif_v1_verify()
1311 if (cmd->prot_type == TARGET_DIF_TYPE1_PROT && in sbc_dif_v1_verify()
1312 be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { in sbc_dif_v1_verify()
1315 be32_to_cpu(sdt->ref_tag), (u32)(sector & 0xffffffff)); in sbc_dif_v1_verify()
1319 if (cmd->prot_type == TARGET_DIF_TYPE2_PROT && in sbc_dif_v1_verify()
1320 be32_to_cpu(sdt->ref_tag) != ei_lba) { in sbc_dif_v1_verify()
1323 be32_to_cpu(sdt->ref_tag), ei_lba); in sbc_dif_v1_verify()
1333 struct se_device *dev = cmd->se_dev; in sbc_dif_copy_prot()
1342 left = sectors * dev->prot_length; in sbc_dif_copy_prot()
1344 for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { in sbc_dif_copy_prot()
1347 paddr = kmap_atomic(sg_page(psg)) + psg->offset; in sbc_dif_copy_prot()
1348 psg_len = min(left, psg->length); in sbc_dif_copy_prot()
1350 len = min(psg_len, sg->length - offset); in sbc_dif_copy_prot()
1351 addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; in sbc_dif_copy_prot()
1358 left -= len; in sbc_dif_copy_prot()
1361 psg_len -= len; in sbc_dif_copy_prot()
1363 kunmap_atomic(addr - sg->offset - offset); in sbc_dif_copy_prot()
1365 if (offset >= sg->length) { in sbc_dif_copy_prot()
1370 kunmap_atomic(paddr - psg->offset); in sbc_dif_copy_prot()
1379 struct se_device *dev = cmd->se_dev; in sbc_dif_verify()
1381 struct scatterlist *dsg = cmd->t_data_sg; in sbc_dif_verify()
1387 unsigned int block_size = dev->dev_attrib.block_size; in sbc_dif_verify()
1390 paddr = kmap_atomic(sg_page(psg)) + psg->offset; in sbc_dif_verify()
1391 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_verify()
1393 for (i = psg_off; i < psg->length && in sbc_dif_verify()
1399 if (dsg_off >= dsg->length) { in sbc_dif_verify()
1400 dsg_off -= dsg->length; in sbc_dif_verify()
1401 kunmap_atomic(daddr - dsg->offset); in sbc_dif_verify()
1404 kunmap_atomic(paddr - psg->offset); in sbc_dif_verify()
1407 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_verify()
1414 (unsigned long long)sector, sdt->guard_tag, in sbc_dif_verify()
1415 sdt->app_tag, be32_to_cpu(sdt->ref_tag)); in sbc_dif_verify()
1417 if (sdt->app_tag == T10_PI_APP_ESCAPE) { in sbc_dif_verify()
1422 avail = min(block_size, dsg->length - dsg_off); in sbc_dif_verify()
1425 kunmap_atomic(daddr - dsg->offset); in sbc_dif_verify()
1428 kunmap_atomic(paddr - psg->offset); in sbc_dif_verify()
1431 daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; in sbc_dif_verify()
1432 dsg_off = block_size - avail; in sbc_dif_verify()
1440 kunmap_atomic(daddr - dsg->offset); in sbc_dif_verify()
1441 kunmap_atomic(paddr - psg->offset); in sbc_dif_verify()
1442 cmd->bad_sector = sector; in sbc_dif_verify()
1451 kunmap_atomic(daddr - dsg->offset); in sbc_dif_verify()
1452 kunmap_atomic(paddr - psg->offset); in sbc_dif_verify()