diff --git a/Makefile b/Makefile index a8dc73bf2..44627e333 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,6 @@ SRP_DIR=srpt SCST_LOCAL_DIR=scst_local MVSAS_DIR=mvsas_tgt FCST_DIR=fcst -EMULEX_DIR=emulex ISCSI_DIR=iscsi-scst @@ -95,12 +94,6 @@ help: @echo " iscsi_install : ISCSI target: install" @echo " iscsi_uninstall : ISCSI target: uninstall" @echo "" - @echo " emulex : make Emulex target" - @echo " emulex_clean : Emulex target: clean " - @echo " emulex_extraclean : Emulex target: clean + clean dependencies" - @echo " emulex_install : Emulex target: install" - @echo " emulex_uninstall : Emulex target: uninstall" - @echo "" @echo " lsi : make LSI MPT target" @echo " lsi_clean : lsi target: clean " @echo " lsi_extraclean : lsi target: clean + clean dependencies" @@ -155,7 +148,6 @@ all: @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi install: cd $(SCST_DIR) && $(MAKE) $@ @@ -167,7 +159,6 @@ install: @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi uninstall: cd $(SCST_DIR) && $(MAKE) $@ @@ -179,7 +170,6 @@ uninstall: @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi clean: cd $(SCST_DIR) && $(MAKE) $@ @@ -193,7 +183,6 @@ clean: @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi extraclean: -rm -f TAGS @@ -208,7 +197,6 @@ extraclean: @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(EMULEX_DIR) ]; then cd $(EMULEX_DIR) && $(MAKE) $@; fi tags: find . -type f -name "*.[ch]" | ctags --c-kinds=+p --fields=+iaS --extra=+q -e -L- @@ -302,21 +290,6 @@ iscsi_clean: iscsi_extraclean: cd $(ISCSI_DIR) && $(MAKE) extraclean -emulex: - cd $(EMULEX_DIR) && $(MAKE) all - -emulex_install: - cd $(EMULEX_DIR) && $(MAKE) install - -emulex_uninstall: - cd $(EMULEX_DIR) && $(MAKE) uninstall - -emulex_clean: - cd $(EMULEX_DIR) && $(MAKE) clean - -emulex_extraclean: - cd $(EMULEX_DIR) && $(MAKE) extraclean - lsi: cd $(LSI_DIR) && $(MAKE) all @@ -533,7 +506,6 @@ disable_proc: extraclean qla_old qla_old_install qla_old_uninstall qla_old_clean qla_old_extraclean \ lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \ iscsi iscsi_install iscsi_uninstall iscsi_clean iscsi_extraclean \ - emulex emulex_install emulex_uninstall emulex_clean emulex_extraclean \ scst scst_install scst_uninstall scst_clean scst_extraclean \ docs docs_clean docs_extraclean \ scstadm scstadm_install scstadm_uninstall scstadm_clean scstadm_extraclean \ diff --git a/fcst/ft_cmd.c b/fcst/ft_cmd.c index 3900e425d..8c3509a78 100644 --- a/fcst/ft_cmd.c +++ b/fcst/ft_cmd.c @@ -57,8 +57,7 @@ void ft_cmd_dump(struct scst_cmd *cmd, const char *caller) prefix, cmd, fcmd->write_data_len, fcmd->read_data_len); pr_info("%s exp_dir %x exp_xfer_len %d exp_in_len %d\n", prefix, cmd->expected_data_direction, - cmd->expected_transfer_len_full, - cmd->expected_out_transfer_len); + cmd->expected_transfer_len, cmd->expected_out_transfer_len); pr_info("%s dir %x data_len %lld bufflen %d out_bufflen %d\n", prefix, cmd->data_direction, cmd->data_len, cmd->bufflen, cmd->out_bufflen); diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index 8916ce211..be2611b3d 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -1270,18 +1270,18 @@ void iscsi_dump_pdu(struct iscsi_pdu *pdu) int i; buf = (void *)&pdu->bhs; - pr_debug("BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs)); + printk(KERN_DEBUG "BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs)); for (i = 0; i < (int)sizeof(pdu->bhs); i++) iscsi_dump_char(*buf++, text, &pos); iscsi_dump_char(-1, text, &pos); buf = (void *)pdu->ahs; - pr_debug("AHS: (%p,%d)\n", buf, pdu->ahssize); + printk(KERN_DEBUG "AHS: (%p,%d)\n", buf, pdu->ahssize); for (i = 0; i < pdu->ahssize; i++) iscsi_dump_char(*buf++, text, &pos); iscsi_dump_char(-1, text, &pos); - pr_debug("Data: (%d)\n", pdu->datasize); + printk(KERN_DEBUG "Data: (%d)\n", pdu->datasize); } } diff --git a/qla2x00t/qla_isr.c b/qla2x00t/qla_isr.c index eccce01db..a1595cb10 100644 --- a/qla2x00t/qla_isr.c +++ b/qla2x00t/qla_isr.c @@ -1723,7 +1723,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) return; } - lscsi_status = scsi_status & STATUS_MASK; + lscsi_status = scsi_status & STATUS_MASK; fcport = sp->fcport; diff --git a/scst/README b/scst/README index 91e831661..479f583a3 100644 --- a/scst/README +++ b/scst/README @@ -331,11 +331,6 @@ in/out in Makefile and scst.h: can clear already measured results by writing 0 in each file. Note, you need a non-preemptible kernel to have correct results. - - CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection - of corrupted DIF tags according to the Oracle specification. This - functionality is working only if dif_mode doesn't contain dev_store - and dif_type is 1. - HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons, except for scst_user, where they are not supported, because this module deals with user supplied memory on a @@ -618,17 +613,6 @@ Every target should have at least the following entries: particular target driver or not, you can find out by checking traces or the target driver's source code. - - dif_capabilities - if this target supports T10-PI, returns which - exact DIF capabilities this target supports. - - - dif_checks_failed - if this target supports T10-PI, returns - statistics how many DIF errors have been detected on the - corresponding processing stages on this target. It returns 3 rows of - numbers with 3 numbers in each row: for target driver stage, for SCST - stage and for dev handler stage. Numbers in each row: how many errors - detected checking application, reference and guard tags - correspondingly. Writing to this attribute resets the numbers. - - cpu_mask - defines CPU affinity mask for threads serving this target. For threads serving LUNs it is used only for devices with threads_pool_type "per_initiator". @@ -688,17 +672,6 @@ Each session subdirectory contains the following entries: - commands - contains overall number of SCSI commands in this session. - - dif_checks_failed - if target of this session supports T10-PI, returns - statistics how many DIF errors have been detected on the - corresponding processing stages on all DIF-enabled LUNs in this - session. It returns 3 rows of numbers with 3 numbers in each row: for - target driver stage, for SCST stage and for dev handler stage. - Numbers in each row: how many errors detected checking application, - reference and guard tags correspondingly. Writing to this attribute - resets the numbers. Similar statistics returned in attribute with the - same name for each LUN in this session in this LUN's subdirectory, if - its device configured with dif_type > 0. - - latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency statistics for this session. @@ -996,47 +969,6 @@ cache. The following parameters possible for vdisk_fileio: - zero_copy - if set, then this device uses zero copy access to the page cache. At the moment, only read side zero copy is implemented. - - dif_mode - specifies which T10-PI, or DIF, mode this device will use. - See SCSI standards from more info about T10-PI. Available DIF modes - (can be combined using '|'): - - * tgt - DIF tags are checked on the target hardware, if supported - - * scst - DIF tags are checked inside SCST core - - * dev_check - DIF tags are checked inside backend device - - * dev_store - DIF tags are stored inside backend device on the WRITE - path and read from it on the READ path - - For instance, if only tgt DIF mode specified, then target driver, - serving this device, will inside hardware check, then STRIP DIF tags - from SCSI commands on the WRITE path and generate, then INSERT DIF - tags into SCSI commands on the READ path, so neither SCST core, nor - dev handler will see them. - - Similarly, if only scst DIF mode specified, then target driver will - PASS DIF tags into SCST core, which then check/STRIP/generate/INSERT - them, so dev handler will not see them. - - If only dev_check DIF mode specified, then both target driver and - SCST core will PASS DIF tags into the dev handler, which is then - responsible to check them in the backend hardware. If only dev_store - specified, then DIF tags will only be stored by the dev handler in - the backend hardware without checking at any level. - - If all "tgt|scst|dev_check|dev_store" DIF mode specified, then all - target driver, SCST core and dev handler will check DIF tags, then - dev handler will store them in the backend hardware. - - - dif_type - specifies which DIF SCSI type this device will use. - - - dif_static_app_tag - specifies fixed (static) DIF application tag for - this device. - - - dif_filename - specifies full path to filename, where DIF tags will - be stored. - Handler vdisk_blockio provides BLOCKIO mode to create virtual devices. This mode performs direct block I/O with a block device, bypassing the page cache for all operations. This mode works ideally with high-end @@ -1044,10 +976,10 @@ storage HBAs and for applications that either do not need caching between application and disk or need the large block throughput. See below for more info. -The following parameters possible for vdisk_blockio: filename, -blocksize, nv_cache, read_only, removable, rotational, thin_provisioned, -tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See -vdisk_fileio above for description of those parameters. +The following common with vdisk_fileio parameters are possible for +vdisk_blockio: filename, blocksize, nv_cache, write_through, read_only, +removable, rotational, thin_provisioned, tst. See vdisk_fileio above for +description of those parameters. Handler vdisk_nullio provides NULLIO mode to create virtual devices. In this mode no real I/O is done, but success returned to initiators. diff --git a/scst/README_in-tree b/scst/README_in-tree index aebe86dbc..55e81d947 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -233,11 +233,6 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig": can clear already measured results by writing 0 in each file. Note, you need a non-preemptible kernel to have correct results. - - CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection - of corrupted DIF tags according to the Oracle specification. This - functionality is working only if dif_mode doesn't contain dev_store - and dif_type is 1. - HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons. @@ -494,17 +489,6 @@ Every target should have at least the following entries: particular target driver or not, you can find out by checking traces or the target driver's source code. - - dif_capabilities - if this target supports T10-PI, returns which - exact DIF capabilities this target supports. - - - dif_checks_failed - if this target supports T10-PI, returns - statistics how many DIF errors have been detected on the - corresponding processing stages on this target. It returns 3 rows of - numbers with 3 numbers in each row: for target driver stage, for SCST - stage and for dev handler stage. Numbers in each row: how many errors - detected checking application, reference and guard tags - correspondingly. Writing to this attribute resets the numbers. - - cpu_mask - defines CPU affinity mask for threads serving this target. For threads serving LUNs it is used only for devices with threads_pool_type "per_initiator". @@ -564,17 +548,6 @@ Each session subdirectory contains the following entries: - commands - contains overall number of SCSI commands in this session. - - dif_checks_failed - if target of this session supports T10-PI, returns - statistics how many DIF errors have been detected on the - corresponding processing stages on all DIF-enabled LUNs in this - session. It returns 3 rows of numbers with 3 numbers in each row: for - target driver stage, for SCST stage and for dev handler stage. - Numbers in each row: how many errors detected checking application, - reference and guard tags correspondingly. Writing to this attribute - resets the numbers. Similar statistics returned in attribute with the - same name for each LUN in this session in this LUN's subdirectory, if - its device configured with dif_type > 0. - - latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency statistics for this session. @@ -868,47 +841,6 @@ cache. The following parameters possible for vdisk_fileio: - zero_copy - if set, then this device uses zero copy access to the page cache. At the moment, only read side zero copy is implemented. - - dif_mode - specifies which T10-PI, or DIF, mode this device will use. - See SCSI standards from more info about T10-PI. Available DIF modes - (can be combined using '|'): - - * tgt - DIF tags are checked on the target hardware, if supported - - * scst - DIF tags are checked inside SCST core - - * dev_check - DIF tags are checked inside backend device - - * dev_store - DIF tags are stored inside backend device on the WRITE - path and read from it on the READ path - - For instance, if only tgt DIF mode specified, then target driver, - serving this device, will inside hardware check, then STRIP DIF tags - from SCSI commands on the WRITE path and generate, then INSERT DIF - tags into SCSI commands on the READ path, so neither SCST core, nor - dev handler will see them. - - Similarly, if only scst DIF mode specified, then target driver will - PASS DIF tags into SCST core, which then check/STRIP/generate/INSERT - them, so dev handler will not see them. - - If only dev_check DIF mode specified, then both target driver and - SCST core will PASS DIF tags into the dev handler, which is then - responsible to check them in the backend hardware. If only dev_store - specified, then DIF tags will only be stored by the dev handler in - the backend hardware without checking at any level. - - If all "tgt|scst|dev_check|dev_store" DIF mode specified, then all - target driver, SCST core and dev handler will check DIF tags, then - dev handler will store them in the backend hardware. - - - dif_type - specifies which DIF SCSI type this device will use. - - - dif_static_app_tag - specifies fixed (static) DIF application tag for - this device. - - - dif_filename - specifies full path to filename, where DIF tags will - be stored. - Handler vdisk_blockio provides BLOCKIO mode to create virtual devices. This mode performs direct block I/O with a block device, bypassing the page cache for all operations. This mode works ideally with high-end @@ -916,10 +848,10 @@ storage HBAs and for applications that either do not need caching between application and disk or need the large block throughput. See below for more info. -The following parameters possible for vdisk_blockio: filename, -blocksize, nv_cache, read_only, removable, rotational, thin_provisioned, -tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See -vdisk_fileio above for description of those parameters. +The following common with vdisk_fileio parameters are possible for +vdisk_blockio: filename, blocksize, nv_cache, write_through, read_only, +removable, rotational, thin_provisioned, tst. See vdisk_fileio above for +description of those parameters. Handler vdisk_nullio provides NULLIO mode to create virtual devices. In this mode no real I/O is done, but success returned to initiators. diff --git a/scst/include/scst.h b/scst/include/scst.h index e244db665..20e2c6685 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -27,9 +27,6 @@ /* #define CONFIG_SCST_DEBUG_TM */ /* #define CONFIG_SCST_TM_DBG_GO_OFFLINE */ -/** See README for description of those conditional defines **/ -#define CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - #include #ifndef INSIDE_KERNEL_TREE #include @@ -753,159 +750,6 @@ enum scst_exec_context { SCST_SENSE_ASC_VALID | \ SCST_SENSE_ASCQ_VALID) -/************************************************************* - ** T10-PI (DIF) support - *************************************************************/ - -struct scst_dif_tuple { - __be16 guard_tag; - __be16 app_tag; - __be32 ref_tag; -}; - -/* - * Defines where and how to deal with DIF tags. Can be OR'ed to get - * multilevel checks - */ -enum scst_dif_mode { - SCST_DIF_MODE_NONE = 0, - - /* STRIP/INSERT/CHECK inside target HW */ - SCST_DIF_MODE_TGT = 1, - - /* SCST checking or creating tags on the fly */ - SCST_DIF_MODE_SCST = 2, - - /* Backend device checking tags */ - SCST_DIF_MODE_DEV_CHECK = 4, - - /* Backend device storing tags, creating them on writes, if needed */ - SCST_DIF_MODE_DEV_STORE = 8, -}; -#define SCST_DIF_MODE_DEV (SCST_DIF_MODE_DEV_CHECK|SCST_DIF_MODE_DEV_STORE) - -#define SCST_DIF_MODE_TGT_STR "tgt" -#define SCST_DIF_MODE_SCST_STR "scst" -#define SCST_DIF_MODE_DEV_CHECK_STR "dev_check" -#define SCST_DIF_MODE_DEV_STORE_STR "dev_store" - -/* - * T10-PI actions. - * - * Don't use masks and shifts directly! Use helper functions instead! - */ -enum scst_dif_actions { - SCST_DIF_ACTION_NONE = 0, /* do nothing */ - -#define SCST_DIF_CHECKS_SHIFT 0 - /* OR'able tags to check */ - SCST_DIF_CHECK_GUARD_TAG = 1, - SCST_DIF_CHECK_APP_TAG = 2, - SCST_DIF_CHECK_REF_TAG = 4, -#define SCST_DIF_CHECKS_MASK (SCST_DIF_CHECK_GUARD_TAG|SCST_DIF_CHECK_APP_TAG| \ - SCST_DIF_CHECK_REF_TAG) - -#define SCST_DIF_ACTION_SHIFT 4 - /* How to handle PI */ - SCST_DIF_ACTION_STRIP = (1 << SCST_DIF_ACTION_SHIFT), /* check then strip, if OK */ - SCST_DIF_ACTION_INSERT = (2 << SCST_DIF_ACTION_SHIFT), - SCST_DIF_ACTION_PASS_CHECK = (3 << SCST_DIF_ACTION_SHIFT), /* check then pass, if OK */ - SCST_DIF_ACTION_PASS = (4 << SCST_DIF_ACTION_SHIFT), /* just pass, no check */ - -#define SCST_DIF_ACTION_MASK (SCST_DIF_ACTION_STRIP|SCST_DIF_ACTION_INSERT| \ - SCST_DIF_ACTION_PASS_CHECK|SCST_DIF_ACTION_PASS) -}; - -/* Shift for target driver DIF actions */ -#define SCST_DIF_TGT_ACTION_SHIFT 0 - -/* Shift for SCST DIF actions */ -#define SCST_DIF_SCST_ACTION_SHIFT (SCST_DIF_TGT_ACTION_SHIFT+4) - -/* Shift for dev handler DIF actions */ -#define SCST_DIF_DEV_ACTION_SHIFT (SCST_DIF_SCST_ACTION_SHIFT+4) - -/* Returns DIF checks by stripping the action part from a */ -static inline enum scst_dif_actions scst_get_dif_checks(enum scst_dif_actions a) -{ - return (a & SCST_DIF_CHECKS_MASK); -} - -/* Sets the DIF checks part in a */ -static inline void scst_set_dif_checks(enum scst_dif_actions *a, - enum scst_dif_actions checks) -{ - checks &= ~SCST_DIF_CHECKS_MASK; - *a |= checks << SCST_DIF_CHECKS_SHIFT; - return; -} - -/* Returns DIF action by stripping the checks part from a */ -static inline enum scst_dif_actions scst_get_dif_action(enum scst_dif_actions a) -{ - return (a & SCST_DIF_ACTION_MASK); -} - -/* Sets the DIF action part in a */ -static inline void scst_set_dif_action(enum scst_dif_actions *a, - enum scst_dif_actions action) -{ - action &= ~SCST_DIF_ACTION_MASK; - *a |= action; - return; -} - -/* Returns TGT DIF actions from a, including checks */ -static inline enum scst_dif_actions scst_get_tgt_dif_actions(enum scst_dif_actions a) -{ - BUILD_BUG_ON(SCST_DIF_CHECKS_SHIFT != 0); - return ((a >> SCST_DIF_TGT_ACTION_SHIFT) & SCST_DIF_ACTION_MASK) | - (a & SCST_DIF_CHECKS_MASK); -} - -/* Sets TGT DIF action in a. DIF checks in a are not affected by this function. */ -static inline void scst_set_tgt_dif_action(enum scst_dif_actions *a, - enum scst_dif_actions tgt_a) -{ - tgt_a &= SCST_DIF_ACTION_MASK; - *a |= tgt_a << SCST_DIF_TGT_ACTION_SHIFT; - return; -} - -/* Returns SCST DIF actions from a, including checks */ -static inline enum scst_dif_actions scst_get_scst_dif_actions(enum scst_dif_actions a) -{ - BUILD_BUG_ON(SCST_DIF_CHECKS_SHIFT != 0); - return ((a >> SCST_DIF_SCST_ACTION_SHIFT) & SCST_DIF_ACTION_MASK) | - (a & SCST_DIF_CHECKS_MASK); -} - -/* Sets SCST DIF action in a. DIF checks in a are not affected by this function. */ -static inline void scst_set_scst_dif_action(enum scst_dif_actions *a, - enum scst_dif_actions scst_a) -{ - scst_a &= SCST_DIF_ACTION_MASK; - *a |= scst_a << SCST_DIF_SCST_ACTION_SHIFT; - return; -} - -/* Returns DEV DIF actions from a, including checks */ -static inline enum scst_dif_actions scst_get_dev_dif_actions(enum scst_dif_actions a) -{ - BUILD_BUG_ON(SCST_DIF_CHECKS_SHIFT != 0); - return ((a >> SCST_DIF_DEV_ACTION_SHIFT) & SCST_DIF_ACTION_MASK) | - (a & SCST_DIF_CHECKS_MASK); -} - -/* Sets SCST DIF action in a. DIF checks in a are not affected by this function. */ -static inline void scst_set_dev_dif_action(enum scst_dif_actions *a, - enum scst_dif_actions dev_a) -{ - dev_a &= SCST_DIF_ACTION_MASK; - *a |= dev_a << SCST_DIF_DEV_ACTION_SHIFT; - return; -} - /************************************************************* * TYPES *************************************************************/ @@ -941,33 +785,6 @@ typedef enum dma_data_direction scst_data_direction; struct scst_tgt_template { /* public: */ - /* - * If not NULL, points to 0-terminated array of integers listing all - * supported for T10-PI DIF-enabled devices block sizes. SCST will not - * allow to add DIF-enabled devices with another block sizes to this - * target driver's initiator groups. - * - * Can be overiden by scst_tgt_set_supported_dif_block_sizes() - * - * OPTIONAL - */ - const int *const supported_dif_block_sizes; - - /* - * Preferred SCSI LUN addressing method. - */ - enum scst_lun_addr_method preferred_addr_method; - - /* - * The maximum time in seconds cmd can stay inside the target - * hardware, i.e. after rdy_to_xfer() and xmit_response(), before - * on_hw_pending_cmd_timeout() will be called, if defined. - * - * In the current implementation a cmd will be aborted in time t - * max_hw_pending_time <= t < 2*max_hw_pending_time. - */ - int max_hw_pending_time; - /* * SG tablesize allows to check whether scatter/gather can be used * or not. @@ -1019,62 +836,19 @@ struct scst_tgt_template { unsigned multithreaded_init_done:1; /* - * True, if this target driver supports T10-PI (DIF), i.e. sending and - * receiving DIF PI tags. If false, SCST will not allow to add - * DIF-enabled devices to this target driver's initiator groups. - * - * Can be overriden per target by scst_tgt_set_dif_supported() + * Preferred SCSI LUN addressing method. */ - unsigned dif_supported:1; + enum scst_lun_addr_method preferred_addr_method; /* - * True, if this target driver supports T10-PI (DIF), i.e. INSERT/STRIPE - * mode, in hardware for type 1 protection. If false, SCST will not - * allow to add type 1 devices with TGT DIF mode to this target driver's - * initiator groups. + * The maximum time in seconds cmd can stay inside the target + * hardware, i.e. after rdy_to_xfer() and xmit_response(), before + * on_hw_pending_cmd_timeout() will be called, if defined. * - * Can be overriden per target by scst_tgt_set_hw_dif_type1_supported() + * In the current implementation a cmd will be aborted in time t + * max_hw_pending_time <= t < 2*max_hw_pending_time. */ - unsigned hw_dif_type1_supported:1; - - /* - * True, if this target driver supports T10-PI (DIF), i.e. INSERT/STRIPE - * mode, in hardware for type 2 protection. If false, SCST will not - * allow to add type 2 devices with TGT DIF mode to this target driver's - * initiator groups. - * - * Can be overriden per target by scst_tgt_set_hw_dif_type2_supported() - */ - unsigned hw_dif_type2_supported:1; - - /* - * True, if this target driver supports T10-PI (DIF), i.e. INSERT/STRIPE - * mode, in hardware for type 3 protection. If false, SCST will not - * allow to add type 3 devices with TGT DIF mode to this target driver's - * initiator groups. - * - * Can be overriden per target by scst_tgt_set_hw_dif_type3_supported() - */ - unsigned hw_dif_type3_supported:1; - - /* - * True, if this target driver supports IP checksum format of T10-PI - * (DIF) guard tags, i.e. hardware translation of guard tags between IP - * and CRC on SCST/target driver boundary for better performance, - * because IP checksums are much cheaper for CPU, than CRC. - * - * Can be overriden per target by scst_tgt_set_hw_dif_ip_supported() - */ - unsigned hw_dif_ip_supported:1; - - /* - * True, if this target driver requires the same layout for both data - * and DIF tags SG vectors. Otherwise, for DIF tags minimally possible - * SG vector size will be allocated. - * - * Can be overriden per target by scst_tgt_set_hw_dif_same_sg_layout_required() - */ - unsigned hw_dif_same_sg_layout_required:1; + int max_hw_pending_time; /* * This function is equivalent to the SCSI @@ -1926,15 +1700,6 @@ struct scst_tgt { struct list_head tgt_acg_list; /* target ACG groups */ #endif - /* Per target analog of the corresponding driver's fields */ - unsigned tgt_dif_supported:1; - unsigned tgt_hw_dif_type1_supported:1; - unsigned tgt_hw_dif_type2_supported:1; - unsigned tgt_hw_dif_type3_supported:1; - unsigned tgt_hw_dif_ip_supported:1; - unsigned tgt_hw_dif_same_sg_layout_required:1; - const int *tgt_supported_dif_block_sizes; - /* * Maximum SG table size. Needed here, since different cards on the * same target template can have different SG table limitations. @@ -1972,11 +1737,6 @@ struct scst_tgt { uint16_t rel_tgt_id; - /* How many DIF failures detected on this target on the corresponding stage */ - atomic_t tgt_dif_app_failed_tgt, tgt_dif_ref_failed_tgt, tgt_dif_guard_failed_tgt; - atomic_t tgt_dif_app_failed_scst, tgt_dif_ref_failed_scst, tgt_dif_guard_failed_scst; - atomic_t tgt_dif_app_failed_dev, tgt_dif_ref_failed_dev, tgt_dif_guard_failed_dev; - #ifdef CONFIG_SCST_PROC /* Name of the default security group ("Default_target_name") */ char *default_group_name; @@ -2309,9 +2069,6 @@ struct scst_cmd { /* Set if this command was sent in double UA possible state */ unsigned int double_ua_possible:1; - /* Set if DIF check for just read data was deferred to thread context */ - unsigned int deferred_dif_read_check:1; - /* Set if this command contains status */ unsigned int is_send_status:1; @@ -2349,21 +2106,12 @@ struct scst_cmd { /* Set if custom data buffer allocated by dev handler */ unsigned int dh_data_buf_alloced:1; - /* - * Set length of each member of dif_sg was normalized to match - * tgtt->hw_dif_same_sg_layout_required requirements - */ - unsigned int dif_sg_normalized:1; - /* Set if the target driver called scst_set_expected() */ unsigned int expected_values_set:1; - /* Set if the SG buffer was modified by scst_adjust_sg*() */ + /* Set if the SG buffer was modified by scst_adjust_sg() */ unsigned int sg_buff_modified:1; - /* Set if the DIF SG buffer was modified by scst_adjust_sg*() */ - unsigned int dif_sg_buff_modified:1; - /* * Set if cmd buffer was vmallocated and copied from more * then one sg chunk @@ -2404,9 +2152,6 @@ struct scst_cmd { /* Set if any direction residual is possible */ unsigned int resid_possible:1; - /* Set if DIF data should be included in the residual considerations */ - unsigned int tgt_dif_data_expected:1; - /* Set if cmd is done */ unsigned int done:1; @@ -2500,7 +2245,7 @@ struct scst_cmd { /* Values supplied by the initiator in the transport layer header, if any */ scst_data_direction expected_data_direction; - int expected_transfer_len_full; /* both data and DIF tags, if any */ + int expected_transfer_len; int expected_out_transfer_len; /* for bidi writes */ int64_t lba; /* LBA of this cmd */ @@ -2516,15 +2261,11 @@ struct scst_cmd { void (*scst_cmd_done)(struct scst_cmd *cmd, int next_state, enum scst_exec_context pref_context); - struct sgv_pool_obj *sgv; /* data sgv object */ + struct sgv_pool_obj *sgv; /* sgv object */ int bufflen; /* cmd buffer length */ int sg_cnt; /* SG segments count */ struct scatterlist *sg; /* cmd data buffer SG vector */ - struct sgv_pool_obj *dif_sgv; /* DIF sgv object */ - struct scatterlist *dif_sg; /* cmd DIF tags buffer SG vector */ - int dif_sg_cnt; /* DIF SG segments count */ - /* * Response data length in data buffer. Must not be set * directly, use scst_set_resp_data_len() for that. @@ -2560,7 +2301,6 @@ struct scst_cmd { struct sgv_pool_obj *out_sgv; /* WRITE sgv object */ struct scatterlist *out_sg; /* WRITE data buffer SG vector */ int out_sg_cnt; /* WRITE SG segments count */ - /* No out DIF tags buffer, because there's no BIDI command with them */ /* * Used if both target driver or SCST core for internal commands and @@ -2573,15 +2313,8 @@ struct scst_cmd { */ struct scatterlist *tgt_i_sg; int tgt_i_sg_cnt; - int tgt_i_dif_sg_cnt; - struct scatterlist *tgt_i_dif_sg; /* DIF tags */ - /* - * There's no tgt_i_dif_sg_cnt, because it's supposed to be strictly - * bound to tgt_i_sg_cnt. - */ struct scatterlist *tgt_out_sg; /* bidirectional */ int tgt_out_sg_cnt; /* bidirectional */ - /* No out DIF tags buffer, because there's no BIDI command with them */ /* * The status fields in case of errors must be set using @@ -2592,12 +2325,6 @@ struct scst_cmd { uint8_t host_status; /* set by low-level driver to indicate status */ uint8_t driver_status; /* set by mid-level */ - /* DIF actions on this cmd */ - enum scst_dif_actions cmd_dif_actions; -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - uint32_t cmd_corrupt_dif_tag; -#endif - uint8_t *sense; /* pointer to sense buffer */ unsigned short sense_valid_len; /* length of valid sense data */ unsigned short sense_buflen; /* length of the sense buffer, if any */ @@ -2623,8 +2350,8 @@ struct scst_cmd { */ struct list_head mgmt_cmd_list; - /* Used to restore sg if it was modified by scst_adjust_sg*() */ - struct scst_orig_sg_data orig_sg, orig_dif_sg; + /* Used to restore sg if it was modified by scst_adjust_sg() */ + struct scst_orig_sg_data orig_sg; /* Per opcode stuff */ union { @@ -2803,9 +2530,6 @@ struct scst_device { */ unsigned int dev_unregistering:1; - /* Set if this device does not support DIF IP checking */ - unsigned int dev_dif_ip_not_supported:1; - /**************************************************************/ /************************************************************* @@ -2823,8 +2547,6 @@ struct scst_device { unsigned int tas:1; unsigned int swp:1; unsigned int d_sense:1; - unsigned int dpicz:1; - unsigned int ato:1; /** ** Saved and default versions of them, which supported. TST is not @@ -2853,9 +2575,6 @@ struct scst_device { unsigned int d_sense_saved:1; unsigned int d_sense_default:1; - unsigned int dpicz_saved:1; - unsigned int dpicz_default:1; - /* * Set if device implements own ordered commands management. If not set * and queue_alg is SCST_QUEUE_ALG_0_RESTRICTED_REORDER, expected_sn @@ -2865,22 +2584,6 @@ struct scst_device { /**************************************************************/ - /* - * SCST_DIF_CHECK_APP_TAG (to match usage in the xPROTECT parsing - * routines), if app tag is checked, or 0 otherwise. Might be used - * as bool. - */ - unsigned int dif_app_chk; - - /* - * SCST_DIF_CHECK_REF_TAG (to match usage in the xPROTECT parsing - * routines), if ref tag is checked, or 0 otherwise. Might be used - * as bool. - */ - unsigned int dif_ref_chk; - - /**************************************************************/ - /* * Device block size and block shift if fixed size blocks used. Supposed * to be read-only or serialized the same way as MODE pages changes. @@ -2922,34 +2625,6 @@ struct scst_device { /* List of commands with lock, if dedicated threads are used */ struct scst_cmd_threads dev_cmd_threads; - /************************************************************* - ** T10-PI fields. Read-only, hence no protection. - *************************************************************/ - - enum scst_dif_mode dev_dif_mode; - int dev_dif_type; /* SCSI DIF type */ - - /* - * Callback to process DIF tags by SCST as required by device - * formatting and *protect cmd's bits. Supposed to return 0 on - * success, i.e. when cmd processing should proceed normally, or - * negative error code otherwise, i.e. when cmd processing should - * be stopped and status send to its initiator. - */ - int (*dev_dif_fn)(struct scst_cmd *cmd); - - __be16 dev_dif_static_app_tag; /* fixed APP TAG for all blocks in dev */ - __be32 dev_dif_static_app_ref_tag; /* fixed APP TAG part from REF - * TAG for all blocks in dev. - * Valid only with dif type 3 */ - - /* Cache to optimize scst_parse_*protect() routines */ - enum scst_dif_actions dev_dif_rd_actions; - enum scst_dif_actions dev_dif_wr_actions; - enum scst_dif_actions dev_dif_rd_prot0_actions; - enum scst_dif_actions dev_dif_wr_prot0_actions; - enum scst_dif_actions dev_dif_vr_actions; - /* Set if reserved via the SPC-2 SCSI RESERVE command. */ struct scst_session *reserved_by; @@ -3102,9 +2777,6 @@ struct scst_tgt_dev { /* Set if tgt_dev uses clustered SGV pool */ unsigned int tgt_dev_clust_pool:1; - /* Taken from the target on initialization to save a cache miss */ - unsigned hw_dif_same_sg_layout_required:1; - /**************************************************************/ /* @@ -3116,15 +2788,6 @@ struct scst_tgt_dev { /* Used for storage of dev handler private stuff */ void *dh_priv; - /* Pointer to function to compute DIF guard tag */ - __be16 (*tgt_dev_dif_crc_fn)(const void *buffer, unsigned int len); - - /* - * Guard tags format, one of SCST_DIF_GUARD_FORMAT_* constants. - * Put here to save extra dereferences, this space isn't used anyway. - */ - int tgt_dev_dif_guard_format; - /* How many cmds alive on this dev in this session */ atomic_t tgt_dev_cmd_count ____cacheline_aligned_in_smp; @@ -3170,11 +2833,6 @@ struct scst_tgt_dev { /* Set if INQUIRY DATA HAS CHANGED UA is needed */ unsigned int inq_changed_ua_needed:1; - /* How many DIF failures detected on this tgt_dev on the corresponding stage */ - atomic_t tgt_dev_dif_app_failed_tgt, tgt_dev_dif_ref_failed_tgt, tgt_dev_dif_guard_failed_tgt; - atomic_t tgt_dev_dif_app_failed_scst, tgt_dev_dif_ref_failed_scst, tgt_dev_dif_guard_failed_scst; - atomic_t tgt_dev_dif_app_failed_dev, tgt_dev_dif_ref_failed_dev, tgt_dev_dif_guard_failed_dev; - /* * Stored Unit Attention sense and its length for possible * subsequent REQUEST SENSE. Both protected by tgt_dev_lock. @@ -3210,9 +2868,6 @@ struct scst_acg_dev { /* If set, the corresponding LU is read only */ unsigned int acg_dev_rd_only:1; - /* Guard tags format, one of SCST_DIF_GUARD_FORMAT_* constants */ - int acg_dev_dif_guard_format; - struct scst_acg *acg; /* parent acg */ /* List entry in dev->dev_acg_dev_list */ @@ -3705,99 +3360,6 @@ static inline void scst_tgt_set_tgt_priv(struct scst_tgt *tgt, void *val) tgt->tgt_priv = val; } -/* - * Get/Set functions for tgt's tgt_dif_supported - */ -static inline bool scst_tgt_get_dif_supported(struct scst_tgt *tgt) -{ - return tgt->tgt_dif_supported; -} - -static inline void scst_tgt_set_dif_supported(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_dif_supported = !!val; -} - -/* - * Get/Set functions for tgt's tgt_hw_dif_type1_supported - */ -static inline bool scst_tgt_get_hw_dif_type1_supported(struct scst_tgt *tgt) -{ - return tgt->tgt_hw_dif_type1_supported; -} - -static inline void scst_tgt_set_hw_dif_type1_supported(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_hw_dif_type1_supported = !!val; -} - -/* - * Get/Set functions for tgt's tgt_hw_dif_type2_supported - */ -static inline bool scst_tgt_get_hw_dif_type2_supported(struct scst_tgt *tgt) -{ - return tgt->tgt_hw_dif_type2_supported; -} - -static inline void scst_tgt_set_hw_dif_type2_supported(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_hw_dif_type2_supported = !!val; -} - -/* - * Get/Set functions for tgt's tgt_hw_dif_type3_supported - */ -static inline bool scst_tgt_get_hw_dif_type3_supported(struct scst_tgt *tgt) -{ - return tgt->tgt_hw_dif_type3_supported; -} - -static inline void scst_tgt_set_hw_dif_type3_supported(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_hw_dif_type3_supported = !!val; -} - -/* - * Get/Set functions for tgt's tgt_hw_dif_ip_supported - */ -static inline bool scst_tgt_get_hw_dif_ip_supported(struct scst_tgt *tgt) -{ - return tgt->tgt_hw_dif_ip_supported; -} - -static inline void scst_tgt_set_hw_dif_ip_supported(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_hw_dif_ip_supported = !!val; -} - -/* - * Get/Set functions for tgt's tgt_hw_dif_same_sg_layout_required - */ -static inline bool scst_tgt_get_hw_dif_same_sg_layout_required(struct scst_tgt *tgt) -{ - return tgt->tgt_hw_dif_same_sg_layout_required; -} - -static inline void scst_tgt_set_hw_dif_same_sg_layout_required(struct scst_tgt *tgt, bool val) -{ - tgt->tgt_hw_dif_same_sg_layout_required = !!val; -} - -/* - * Get/Set functions for tgt's tgt_supported_dif_block_sizes - */ -static inline const int *scst_tgt_get_supported_dif_block_sizes( - struct scst_tgt *tgt) -{ - return tgt->tgt_supported_dif_block_sizes; -} - -static inline void scst_tgt_set_supported_dif_block_sizes(struct scst_tgt *tgt, - const int *const val) -{ - tgt->tgt_supported_dif_block_sizes = val; -} - void scst_update_hw_pending_start(struct scst_cmd *cmd); /* @@ -3819,115 +3381,6 @@ bool scst_impl_alua_configured(struct scst_device *dev); int scst_tg_get_group_info(void **buf, uint32_t *response_length, struct scst_device *dev, uint8_t data_format); -/* - * Get/set functions for dev's static DIF APP TAG - */ -static inline __be16 scst_dev_get_dif_static_app_tag(struct scst_device *dev) -{ - return dev->dev_dif_static_app_tag; -} - -static inline __be32 scst_dev_get_dif_static_app_ref_tag(struct scst_device *dev) -{ - return dev->dev_dif_static_app_ref_tag; -} - -static inline __be64 scst_dev_get_dif_static_app_tag_combined( - struct scst_device *dev) -{ - uint64_t a = (((uint64_t)be32_to_cpu(dev->dev_dif_static_app_ref_tag)) << 16) | - be16_to_cpu(dev->dev_dif_static_app_tag); - return cpu_to_be64(a); -} - -void scst_dev_set_dif_static_app_tag_combined(struct scst_device *dev, - __be64 app_tag); - -/* - * Get/set functions for dev's DIF APP TAG checking - */ -static inline bool scst_dev_get_dif_app_tag_check(struct scst_device *dev) -{ - return dev->dif_app_chk == SCST_DIF_CHECK_APP_TAG; -} - -int scst_set_dif_params(struct scst_device *dev, - enum scst_dif_mode dif_mode, int dif_type); - -/* - * Functions to account detected DIF errors on the corresponding stages - */ -static inline void scst_dif_acc_app_check_failed_tgt(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_app_failed_tgt); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_app_failed_tgt); -} - -static inline void scst_dif_acc_ref_check_failed_tgt(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_ref_failed_tgt); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_ref_failed_tgt); -} - -static inline void scst_dif_acc_guard_check_failed_tgt(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_guard_failed_tgt); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_guard_failed_tgt); -} - -static inline void scst_dif_acc_app_check_failed_scst(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_app_failed_scst); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_app_failed_scst); -} - -static inline void scst_dif_acc_ref_check_failed_scst(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_ref_failed_scst); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_ref_failed_scst); -} - -static inline void scst_dif_acc_guard_check_failed_scst(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_guard_failed_scst); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_guard_failed_scst); -} - -static inline void scst_dif_acc_app_check_failed_dev(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_app_failed_dev); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_app_failed_dev); -} - -static inline void scst_dif_acc_ref_check_failed_dev(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_ref_failed_dev); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_ref_failed_dev); -} - -static inline void scst_dif_acc_guard_check_failed_(struct scst_cmd *cmd) -{ - atomic_inc(&cmd->tgt->tgt_dif_guard_failed_dev); - atomic_inc(&cmd->tgt_dev->tgt_dev_dif_guard_failed_dev); -} - -/* - * Functions to process DIF tags by SCST as required by device - * formatting and *protect cmd's bits. - * - * Return 0 on success, i.e. when cmd processing should proceed normally, - * or negative error code otherwise, i.e. when cmd processing should be - * stopped and status send to its initiator. - */ -static inline int scst_dif_process_read(struct scst_cmd *cmd) -{ - return cmd->dev->dev_dif_fn(cmd); -} -static inline int scst_dif_process_write(struct scst_cmd *cmd) -{ - return cmd->dev->dev_dif_fn(cmd); -} - /** * Returns TRUE if cmd is being executed in atomic context. * @@ -4061,28 +3514,6 @@ static inline int scst_cmd_get_sg_cnt(struct scst_cmd *cmd) return cmd->sg_cnt; } -/* - * Returns pointer to cmd's DIF tags SG data buffer. - * - * Usage of this function is not recommended, use scst_get_dif_buf() - * function instead. - */ -static inline struct scatterlist *scst_cmd_get_dif_sg(struct scst_cmd *cmd) -{ - return cmd->dif_sg; -} - -/* - * Returns pointer to cmd's DIF tags SG data buffer elements count. - * - * Usage of this function is not recommended, use scst_get_dif_buf() - * function instead. - */ -static inline int scst_cmd_get_dif_sg_cnt(struct scst_cmd *cmd) -{ - return cmd->dif_sg_cnt; -} - /* Returns cmd's LBA */ static inline int64_t scst_cmd_get_lba(struct scst_cmd *cmd) { @@ -4110,27 +3541,6 @@ static inline int64_t scst_cmd_get_data_len(struct scst_cmd *cmd) return cmd->data_len; } -/* Returns true, if cmd needs DIF buffer */ -static inline bool scst_cmd_needs_dif_buf(struct scst_cmd *cmd) -{ - return (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE) || - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE); -} - -/* Returns length of DIF buffer of this cmd */ -static inline int __scst_cmd_get_bufflen_dif(struct scst_cmd *cmd) -{ - return (cmd->bufflen >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; -} - -static inline int scst_cmd_get_bufflen_dif(struct scst_cmd *cmd) -{ - if (scst_cmd_needs_dif_buf(cmd)) - return __scst_cmd_get_bufflen_dif(cmd); - else - return 0; -} - /* * Returns pointer to cmd's bidirectional in (WRITE) SG data buffer. * @@ -4158,7 +3568,7 @@ void scst_restore_sg_buff(struct scst_cmd *cmd); /* Restores modified sg buffer in the original state, if necessary */ static inline void scst_check_restore_sg_buff(struct scst_cmd *cmd) { - if (unlikely(cmd->sg_buff_modified || cmd->dif_sg_buff_modified)) + if (unlikely(cmd->sg_buff_modified)) scst_restore_sg_buff(cmd); } @@ -4204,35 +3614,6 @@ static inline void scst_cmd_set_tgt_sg(struct scst_cmd *cmd, cmd->tgt_i_data_buf_alloced = 1; } -/* - * Returns pointer to cmd's target's DIF tags SG data buffer. Since it's - * for target drivers, the "_i_" part is omitted. - */ -static inline struct scatterlist *scst_cmd_get_tgt_dif_sg(struct scst_cmd *cmd) -{ - return cmd->tgt_i_dif_sg; -} - -/* - * Returns cmd's target's DIF tags SG data buffer elements count. Since it's - * for target drivers, the "_i_" part is omitted. - */ -static inline int scst_cmd_get_tgt_dif_sg_cnt(struct scst_cmd *cmd) -{ - return cmd->tgt_i_dif_sg_cnt; -} - -/* - * Sets cmd's target's DIF tags SG data buffer. Since it's for target - * drivers, the "_i_" part is omitted. - */ -static inline void scst_cmd_set_tgt_dif_sg(struct scst_cmd *cmd, - struct scatterlist *dif_sg, int cnt) -{ - cmd->tgt_i_dif_sg = dif_sg; - cmd->tgt_i_dif_sg_cnt = cnt; -} - /* Returns pointer to cmd's target's OUT SG data buffer */ static inline struct scatterlist *scst_cmd_get_out_tgt_sg(struct scst_cmd *cmd) { @@ -4495,19 +3876,12 @@ static inline scst_data_direction scst_cmd_get_expected_data_direction( return cmd->expected_data_direction; } -/* - * Returns full expected transfer length, i.e. including both data and - * DIF tags, if any. - */ -static inline int scst_cmd_get_expected_transfer_len_full( +static inline int scst_cmd_get_expected_transfer_len( struct scst_cmd *cmd) { - return cmd->expected_transfer_len_full; + return cmd->expected_transfer_len; } -int scst_cmd_get_expected_transfer_len_data(struct scst_cmd *cmd); -int scst_cmd_get_expected_transfer_len_dif(struct scst_cmd *cmd); - static inline int scst_cmd_get_expected_out_transfer_len( struct scst_cmd *cmd) { @@ -4516,10 +3890,10 @@ static inline int scst_cmd_get_expected_out_transfer_len( static inline void scst_cmd_set_expected(struct scst_cmd *cmd, scst_data_direction expected_data_direction, - int expected_transfer_len_full) + int expected_transfer_len) { cmd->expected_data_direction = expected_data_direction; - cmd->expected_transfer_len_full = expected_transfer_len_full; + cmd->expected_transfer_len = expected_transfer_len; cmd->expected_values_set = 1; } @@ -4559,168 +3933,6 @@ static inline void scst_set_delivery_status(struct scst_cmd *cmd, cmd->delivery_status = delivery_status; } -/* - * Returns T10-PI actions, including checks, which target driver should do - * with this command on READ direction transfers (xmit_response()). Might - * be different from WRITE direction for BIDI commands. - */ -static inline enum scst_dif_actions scst_get_read_dif_tgt_actions( - struct scst_cmd *cmd) -{ - return scst_get_tgt_dif_actions(cmd->cmd_dif_actions); -} - -/* - * Returns T10-PI actions, including checks, which target driver should do - * with this command on WRITE direction transfers (rdy_to_xfer()). Might - * be different from READ direction for BIDI commands. - */ -static inline enum scst_dif_actions scst_get_write_dif_tgt_actions( - struct scst_cmd *cmd) -{ - return scst_get_tgt_dif_actions(cmd->cmd_dif_actions); -} - -/* - * Returns T10-PI actions, including checks, which dev handler should do - * with this command on READ direction transfers. Might be different - * from WRITE direction for BIDI commands. - */ -static inline enum scst_dif_actions scst_get_read_dif_dev_actions( - struct scst_cmd *cmd) -{ - return scst_get_dev_dif_actions(cmd->cmd_dif_actions); -} - -/* - * Returns T10-PI actions, including checks, which dev handler should do - * with this command on WRITE direction transfers. Might be different - * from READ direction for BIDI commands. - */ -static inline enum scst_dif_actions scst_get_write_dif_dev_actions( - struct scst_cmd *cmd) -{ - return scst_get_dev_dif_actions(cmd->cmd_dif_actions); -} - -/* - * Returns T10-PI protection type for this cmd's device. Supposed to be used - * by target drivers. - */ -static inline int scst_cmd_get_dif_prot_type(struct scst_cmd *cmd) -{ - return cmd->dev->dev_dif_type; -} - -/* - * Returns T10-PI application tag for this cmd's device's lba. - * - * If SCST_DIF_NO_CHECK_APP_TAG returned, the target driver should not - * check app tag for this lba (SCSI requirement). - * - * Parameter out_lba_end returns end LBA of the area, where this app tag - * is valid. Then, if necessary, the target driver supposed to call - * this function again for the next app tag area. This is intended to - * support Application Tag mode page. ToDo, not implemented yet. - */ -static inline __be16 scst_cmd_get_dif_app_tag(struct scst_cmd *cmd, - uint64_t lba_start/*, uint64_t *out_lba_end*/) -{ -#ifdef CONFIG_SCST_EXTRACHECKS - WARN_ON(!(scst_get_dif_checks(cmd->cmd_dif_actions) & SCST_DIF_CHECK_APP_TAG)); -#endif - return cmd->dev->dev_dif_static_app_tag; -} - -/* - * Returns T10-PI type 2 expected initial reference tag as LBA, i.e. converted - * into CPU endianness. Valid only with protection type 2. - */ -static inline uint32_t scst_cmd_get_dif_exp_ref_tag(struct scst_cmd *cmd) -{ -#ifdef CONFIG_SCST_EXTRACHECKS - BUG_ON(cmd->dev->dev_dif_type != 2); - WARN_ON(cmd->cdb_len > 32); -#endif - if (cmd->cdb_len == 32) - return get_unaligned_be32(&cmd->cdb[20]); - else - return cmd->lba & 0xFFFFFFFF; -} - -/* - * Returns T10-PI type 2 expected logical block application tag converted - * into CPU endianness. Valid only with protection type 2. - */ -static inline uint16_t scst_cmd_get_dif_exp_app_tag(struct scst_cmd *cmd) -{ -#ifdef CONFIG_SCST_EXTRACHECKS - BUG_ON(cmd->dev->dev_dif_type != 2); - WARN_ON(cmd->cdb_len > 32); -#endif - if (cmd->cdb_len == 32) - return get_unaligned_be16(&cmd->cdb[24]); - else { - /* cmd->dev must be alive at this point */ - return be16_to_cpu(cmd->dev->dev_dif_static_app_tag); - } -} - -/* - * Returns T10-PI type 2 logical block application tag mask converted - * into CPU endianness. Valid only with protection type 2. - */ -static inline uint16_t scst_cmd_get_dif_app_tag_mask(struct scst_cmd *cmd) -{ -#ifdef CONFIG_SCST_EXTRACHECKS - BUG_ON(cmd->dev->dev_dif_type != 2); - WARN_ON(cmd->cdb_len > 32); -#endif - if (cmd->cdb_len == 32) - return get_unaligned_be16(&cmd->cdb[26]); - else { - if (scst_get_dif_checks(cmd->cmd_dif_actions) & SCST_DIF_CHECK_APP_TAG) - return 0xFFFF; - else - return 0; - } -} - -/* - * Returns T10-PI type 3 application/reference tag. Valid only with type 3 - * protection type. Alternatively, scst_dev_get_dif_static_app_tag_combined() - * can be used. - * - * If SCST_DIF_NO_CHECK_ALL_REF_TAG returned, the target driver should not - * check the tag for this lba (SCSI requirement). - */ -static inline __be32 scst_cmd_get_dif_app_ref_tag(struct scst_cmd *cmd) -{ -#ifdef CONFIG_SCST_EXTRACHECKS - BUG_ON(cmd->dev->dev_dif_type != 3); - WARN_ON(!(scst_get_dif_checks(cmd->cmd_dif_actions) & SCST_DIF_CHECK_REF_TAG)); -#endif - return cmd->dev->dev_dif_static_app_ref_tag; -} - -/* - * Returns format of T10-PI GUARD TAGs as one of SCST_DIF_GUARD_FORMAT_* - * constants - */ -static inline int scst_cmd_get_dif_guard_format(struct scst_cmd *cmd) -{ - return cmd->tgt_dev->tgt_dev_dif_guard_format; -} - -/* - * Returns block size of this cmd's device. Supposed to be used - * by target drivers during T10-PI processing. - */ -static inline int scst_cmd_get_block_size(struct scst_cmd *cmd) -{ - return cmd->dev->block_size; -} - static inline unsigned int scst_get_active_cmd_count(struct scst_cmd *cmd) { if (likely(cmd->tgt_dev != NULL)) @@ -4994,45 +4206,6 @@ static inline void scst_put_buf(struct scst_cmd *cmd, void *buf) /* Nothing to do */ } -/* - * Functions for access to the commands DIF tags (SG) buffer. It doesn't - * return any error code, because this buffer is strictly connected to the - * data buffer, so for each block in that buffer, there must be tag here. - * - * Parameter psg on entrance specifies previous DIF tags SG in the access. - * Must point to NULL for the first access. On exit returns current DIF - * tags SG. - * - * The "put" function unmaps the buffer. - * - * !!! NOTE: this function does not check DIF SG cnt, hence must be used !!! - * !!! only inside code bound to the corresponding data SG cnt! !!! - */ -static inline uint8_t *scst_get_dif_buf(struct scst_cmd *cmd, - struct scatterlist **psg, int *length) -{ - uint8_t *buf; - struct scatterlist *sg; - - if (*psg == NULL) - sg = cmd->dif_sg; - else - sg = __sg_next_inline(*psg); - - buf = page_address(sg_page(sg)); - buf += sg->offset; - *length = sg->length; - - *psg = sg; - - return buf; -} - -static inline void scst_put_dif_buf(struct scst_cmd *cmd, void *buf) -{ - /* Nothing to do */ -} - static inline int scst_get_out_buf_first(struct scst_cmd *cmd, uint8_t **buf) { if (unlikely(cmd->out_sg == NULL)) { diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index b028e826c..e0aae987e 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -334,9 +334,6 @@ static inline int scst_sense_response_code(const uint8_t *sense) /* ABORTED_COMMAND is 0xb */ #define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0 -#define scst_logical_block_guard_check_failed ABORTED_COMMAND, 0x10, 1 -#define scst_logical_block_app_tag_check_failed ABORTED_COMMAND, 0x10, 2 -#define scst_logical_block_ref_tag_check_failed ABORTED_COMMAND, 0x10, 3 #define scst_sense_internal_failure ABORTED_COMMAND, 0x44, 0 /* retriable */ /* MISCOMPARE is 0xe */ @@ -430,13 +427,6 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define UNMAP 0x42 #endif -/* Subcodes of VARIABLE_LENGTH_CMD (0x7F) */ -#define SUBCODE_READ_32 0x09 -#define SUBCODE_VERIFY_32 0x0a -#define SUBCODE_WRITE_32 0x0b -#define SUBCODE_WRITE_VERIFY_32 0x0c -#define SUBCODE_WRITE_SAME_32 0x0d - #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) /* * From . See also commit @@ -455,6 +445,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define BLKDISCARD _IO(0x12,119) #endif + /************************************************************* ** SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft ** T10/1561-D Revision 4 Draft dated 7th November 2002. @@ -529,44 +520,6 @@ enum { #define SCST_QERR_2_RESERVED 2 #define SCST_QERR_3_ABORT_THIS_NEXUS_ONLY 3 -/************************************************************* - ** Values for the control mode page ATO field - *************************************************************/ - -/* I.e., app tags owned by storage */ -#define SCST_ATO_0_MODIFIED_BY_STORAGE 0 - -/* I.e., app tags owned by application */ -#define SCST_ATO_1_NOT_MODIFIED_BY_STORAGE 1 - -/************************************************************* - ** Values for the control mode page DPICZ field - *************************************************************/ -#define SCST_DPICZ_CHECK_ON_xPROT_0 0 -#define SCST_DPICZ_NO_CHECK_ON_xPROT_0 1 - -/************************************************************* - ** APP/REF TAG DIF constants - *************************************************************/ - -/* Skip all guards checks for this block */ -#define SCST_DIF_NO_CHECK_ALL_APP_TAG cpu_to_be16(0xFFFF) -#define SCST_DIF_NO_CHECK_ALL_REF_TAG cpu_to_be32(0xFFFFFFFF) - -/* Don't check app tag for this block */ -#define SCST_DIF_NO_CHECK_APP_TAG 0 - -/************************************************************* - ** Shift of size of DIF tag (8 bytes) - *************************************************************/ -#define SCST_DIF_TAG_SHIFT 3 - -/************************************************************* - ** Formats of DIF guard tags - *************************************************************/ -#define SCST_DIF_GUARD_FORMAT_CRC 0 -#define SCST_DIF_GUARD_FORMAT_IP 1 - /************************************************************* ** TransportID protocol identifiers *************************************************************/ diff --git a/scst/src/Makefile b/scst/src/Makefile index 28107ff99..1535e6db6 100644 --- a/scst/src/Makefile +++ b/scst/src/Makefile @@ -121,7 +121,6 @@ install: all install -m 644 $(MODULE_SYMVERS) $(INSTALL_DIR_H) -/sbin/depmod -b $(INSTALL_MOD_PATH)/ -a $(KVER) mkdir -p $(DESTDIR)/var/lib/scst/pr - mkdir -p $(DESTDIR)/var/lib/scst/dif_tags mkdir -p $(DESTDIR)/var/lib/scst/vdev_mode_pages @echo "****************************************************************" @echo "*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*" diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 12ef87e71..f5e8003dc 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -814,7 +814,7 @@ static int dev_user_parse(struct scst_cmd *cmd) ucmd->user_cmd.parse_cmd.expected_data_direction = cmd->expected_data_direction; ucmd->user_cmd.parse_cmd.expected_transfer_len = - cmd->expected_transfer_len_full; + cmd->expected_transfer_len; ucmd->user_cmd.parse_cmd.expected_out_transfer_len = cmd->expected_out_transfer_len; ucmd->user_cmd.parse_cmd.sn = cmd->tgt_sn; diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 4e74dadad..da49cbd64 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -134,10 +134,6 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = { #define DEF_TAS 0 #define DEF_DSENSE SCST_D_SENSE_0_FIXED_SENSE -#define DEF_DPICZ SCST_DPICZ_CHECK_ON_xPROT_0 - -#define DEF_DIF_FILENAME_TMPL (SCST_VAR_DIR "/dif_tags/%s.dif") - #ifdef CONFIG_SCST_PROC #define VDISK_PROC_HELP "help" #endif @@ -166,7 +162,6 @@ struct scst_vdisk_dev { unsigned int prevent_allow_medium_removal:1; unsigned int nullio:1; unsigned int blockio:1; - unsigned int blk_integrity:1; unsigned int cdrom_empty:1; unsigned int dummy:1; unsigned int read_zero:1; @@ -181,7 +176,6 @@ struct scst_vdisk_dev { unsigned int discard_zeroes_data:1; struct file *fd; - struct file *dif_fd; struct block_device *bdev; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) struct bio_set *vdisk_bioset; @@ -233,13 +227,8 @@ struct scst_vdisk_dev { int tgt_dev_cnt; - char *dif_filename; - - /* Only to pass it to attach() callback. Don't use them anywhere else! */ + /* Only to pass it to attach() callback. Don't use it anywhere else! */ int blk_shift; - enum scst_dif_mode dif_mode; - int dif_type; - __be64 dif_static_app_tag_combined; }; struct vdisk_cmd_params { @@ -278,12 +267,6 @@ static int num_threads = DEF_NUM_THREADS; module_param_named(num_threads, num_threads, int, S_IRUGO); MODULE_PARM_DESC(num_threads, "vdisk threads count"); -/* - * Used to serialize sense setting between blockio data and DIF tags - * unsuccessful readings/writings - */ -static spinlock_t vdev_err_lock; - static int vdisk_attach(struct scst_device *dev); static void vdisk_detach(struct scst_device *dev); static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev); @@ -308,9 +291,6 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p); static enum compl_status_e nullio_exec_write(struct vdisk_cmd_params *p); static enum compl_status_e blockio_exec_write(struct vdisk_cmd_params *p); static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p); -static enum compl_status_e nullio_exec_var_len_cmd(struct vdisk_cmd_params *p); -static enum compl_status_e blockio_exec_var_len_cmd(struct vdisk_cmd_params *p); -static enum compl_status_e fileio_exec_var_len_cmd(struct vdisk_cmd_params *p); static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua); static int vdisk_blockio_flush(struct block_device *bdev, gfp_t gfp_mask, bool report_error, struct scst_cmd *cmd, bool async); @@ -441,8 +421,6 @@ static ssize_t vdev_sysfs_inq_vend_specific_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); static ssize_t vdev_zero_copy_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); -static ssize_t vdev_dif_filename_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf); static ssize_t vcdrom_sysfs_filename_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); @@ -517,8 +495,6 @@ static struct kobj_attribute vdev_inq_vend_specific_attr = vdev_sysfs_inq_vend_specific_store); static struct kobj_attribute vdev_zero_copy_attr = __ATTR(zero_copy, S_IRUGO, vdev_zero_copy_show, NULL); -static struct kobj_attribute vdev_dif_filename_attr = - __ATTR(dif_filename, S_IRUGO, vdev_dif_filename_show, NULL); static struct kobj_attribute vcdrom_filename_attr = __ATTR(filename, S_IRUGO|S_IWUSR, vdev_sysfs_filename_show, @@ -681,11 +657,7 @@ static struct scst_dev_type vdisk_file_devtype = { "thin_provisioned, " "tst, " "write_through, " - "zero_copy, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, " - "dif_filename", + "zero_copy", #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -723,10 +695,6 @@ static struct scst_dev_type vdisk_blk_devtype = { .dev_attrs = vdisk_blockio_attrs, .add_device_parameters = "blocksize, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, " - "dif_filename, " "filename, " "nv_cache, " "read_only, " @@ -771,9 +739,6 @@ static struct scst_dev_type vdisk_null_devtype = { .add_device_parameters = "blocksize, " "dummy, " - "dif_mode, " - "dif_type, " - "dif_static_app_tag, ", "read_only, " "removable, " "rotational, " @@ -857,14 +822,14 @@ static const char *vdev_get_filename(const struct scst_vdisk_dev *virt_dev) /* Returns fd, use IS_ERR(fd) to get error status */ static struct file *vdev_open_fd(const struct scst_vdisk_dev *virt_dev, - const char *name, bool read_only) + bool read_only) { int open_flags = 0; struct file *fd; TRACE_ENTRY(); - sBUG_ON(!name); + sBUG_ON(!virt_dev->filename); if (read_only) open_flags |= O_RDONLY; @@ -874,11 +839,9 @@ static struct file *vdev_open_fd(const struct scst_vdisk_dev *virt_dev, open_flags |= O_DIRECT; if (virt_dev->wt_flag && !virt_dev->nv_cache) open_flags |= O_DSYNC; - - TRACE_DBG("Opening file %s, flags 0x%x", name, open_flags); - fd = filp_open(name, O_LARGEFILE | open_flags, 0600); - if (IS_ERR(fd)) - PRINT_ERROR("filp_open(%s) failed: %d", name, (int)PTR_ERR(fd)); + TRACE_DBG("Opening file %s, flags 0x%x", + virt_dev->filename, open_flags); + fd = filp_open(virt_dev->filename, O_LARGEFILE | open_flags, 0600); TRACE_EXIT(); return fd; @@ -1346,112 +1309,6 @@ out: return res; } -#if defined(CONFIG_BLK_DEV_INTEGRITY) -static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) -{ - int res; - struct scst_device *dev = virt_dev->dev; - struct inode *inode; - struct file *fd; - struct blk_integrity *bi; - - TRACE_ENTRY(); - - fd = vdev_open_fd(virt_dev, virt_dev->filename, virt_dev->rd_only); - if (IS_ERR(fd)) { - res = -EINVAL; - goto out; - } - - inode = file_inode(fd); - - if (!S_ISBLK(inode->i_mode)) { - PRINT_ERROR("%s is NOT a block device!", virt_dev->filename); - res = -EINVAL; - goto out_close; - } - - bi = bdev_get_integrity(inode->i_bdev); - if (bi == NULL) { - TRACE_DBG("Block integrity not supported"); - goto out_no_bi; - } - - TRACE_DBG("BI name %s", bi->name); - - if (!strcmp(bi->name, "T10-DIF-TYPE1-CRC")) { - dev->dev_dif_ip_not_supported = 1; - if (virt_dev->dif_type != 1) { - PRINT_ERROR("Integrity type mismatch, %d expected, " - "but block device has 1 (dev %s)", - virt_dev->dif_type, dev->virt_name); - res = -EINVAL; - goto out_close; - } - } else if (!strcmp(bi->name, "T10-DIF-TYPE1-IP")) { - if (virt_dev->dif_type != 1) { - PRINT_ERROR("Integrity type mismatch, %d expected, " - "but block device has 1 (dev %s)", - virt_dev->dif_type, dev->virt_name); - res = -EINVAL; - goto out_close; - } - } else if (!strcmp(bi->name, "T10-DIF-TYPE3-CRC")) { - dev->dev_dif_ip_not_supported = 1; - if (virt_dev->dif_type != 3) { - PRINT_ERROR("Integrity type mismatch, %d expected, " - "but block device has 1 (dev %s)", - virt_dev->dif_type, dev->virt_name); - res = -EINVAL; - goto out_close; - } - } else if (!strcmp(bi->name, "T10-DIF-TYPE3-IP")) { - if (virt_dev->dif_type != 3) { - PRINT_ERROR("Integrity type mismatch, %d expected, " - "but block device has 3 (dev %s)", - virt_dev->dif_type, dev->virt_name); - res = -EINVAL; - goto out_close; - } - } else { - PRINT_ERROR("Unable to understand integrity name %s" - "(dev %s)", bi->name, dev->virt_name); - res = -EINVAL; - goto out_close; - } - - virt_dev->blk_integrity = 1; - - if ((virt_dev->dif_mode & SCST_DIF_MODE_DEV_CHECK) && - !(virt_dev->dif_mode & SCST_DIF_MODE_DEV_STORE)) { - PRINT_ERROR("Blockio dev_check is not possible without " - "dev_store (dev %s)", dev->virt_name); - res = -EINVAL; - goto out_close; - } - - if (!(virt_dev->dif_mode & SCST_DIF_MODE_DEV_CHECK)) - PRINT_WARNING("Blk integrity implies dev_check (dev %s)", - dev->virt_name); - -out_no_bi: - res = 0; - -out_close: - filp_close(fd, NULL); - -out: - TRACE_EXIT_RES(res); - return res; -} -#else /* defined(CONFIG_BLK_DEV_INTEGRITY) */ -static int vdisk_init_block_integrity(struct scst_vdisk_dev *virt_dev) -{ - PRINT_ERROR("Kernel does not support block device integrity"); - return -EINVAL; -} -#endif /* defined(CONFIG_BLK_DEV_INTEGRITY) */ - /* * Reexamine size, flush support and thin provisioning support for * vdisk_fileio, vdisk_blockio and vdisk_cdrom devices. Do not modify the size @@ -1512,74 +1369,6 @@ static int vdisk_attach(struct scst_device *dev) dev->block_shift = virt_dev->blk_shift; dev->block_size = 1 << dev->block_shift; - if ((virt_dev->dif_type == 0) && - ((virt_dev->dif_mode != SCST_DIF_MODE_NONE) || - (virt_dev->dif_filename != NULL))) { - PRINT_ERROR("Device %s cannot have DIF TYPE 0 if DIF MODE is " - "not NONE or DIF FILENAME is not NULL", virt_dev->name); - res = -EINVAL; - goto out; - } - - if (virt_dev->blockio) { - if (!(virt_dev->dif_mode & SCST_DIF_MODE_DEV)) - goto next; - - res = vdisk_init_block_integrity(virt_dev); - if (res != 0) - goto out; - } else if (virt_dev->dif_mode & SCST_DIF_MODE_DEV_CHECK) { - PRINT_ERROR("dev_check supported only for BLOCKIO devices " - "(dev %s)!", dev->virt_name); - res = -EINVAL; - goto out; - } - -next: - if ((virt_dev->dif_mode & SCST_DIF_MODE_DEV_STORE) && - (virt_dev->dif_filename == NULL) && !virt_dev->blk_integrity) { - virt_dev->dif_filename = kasprintf(GFP_KERNEL, - DEF_DIF_FILENAME_TMPL, dev->virt_name); - if (virt_dev->dif_filename == NULL) { - PRINT_ERROR("Allocation of default dif_filename " - "failed (dev %s)", dev->virt_name); - res = -ENOMEM; - goto out; - } - } - - if (virt_dev->dif_filename != NULL) { - /* Check if it can be used */ - struct file *dfd = vdev_open_fd(virt_dev, virt_dev->dif_filename, - virt_dev->rd_only); - if (IS_ERR(dfd)) { - res = PTR_ERR(dfd); - goto out; - } - filp_close(dfd, NULL); - } - - res = scst_set_dif_params(dev, virt_dev->dif_mode, virt_dev->dif_type); - if (res != 0) - goto out; - - if (virt_dev->dif_type != 2) - scst_dev_set_dif_static_app_tag_combined(dev, - virt_dev->dif_static_app_tag_combined); - else if (virt_dev->dif_static_app_tag_combined != SCST_DIF_NO_CHECK_APP_TAG) - PRINT_WARNING("Device %s: static app tag is ignored for DIF " - "mode 2", dev->virt_name); - - if (virt_dev->dif_filename != NULL) { - res = scst_create_dev_attr(dev, &vdev_dif_filename_attr); - if (res != 0) { - PRINT_ERROR("Can't create attr %s for dev %s", - vdev_dif_filename_attr.attr.name, - dev->virt_name); - goto out; - } - } - if (virt_dev->zero_copy && virt_dev->o_direct_flag) { PRINT_ERROR("%s: combining zero_copy with o_direct is not" " supported", virt_dev->filename); @@ -1633,13 +1422,6 @@ next: dev->tas = DEF_TAS; dev->tas_saved = DEF_TAS; dev->tas_default = DEF_TAS; - dev->dpicz = DEF_DPICZ; - dev->dpicz_saved = DEF_DPICZ; - dev->dpicz_default = DEF_DPICZ; - if ((virt_dev->dif_filename == NULL) && !virt_dev->blk_integrity) - dev->ato = SCST_ATO_0_MODIFIED_BY_STORAGE; - else - dev->ato = SCST_ATO_1_NOT_MODIFIED_BY_STORAGE; if (vdev_saved_mode_pages_enabled) vdev_load_mode_pages(virt_dev); @@ -1677,7 +1459,7 @@ static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) lockdep_assert_held(&scst_mutex); sBUG_ON(!virt_dev->filename); - virt_dev->fd = vdev_open_fd(virt_dev, virt_dev->filename, read_only); + virt_dev->fd = vdev_open_fd(virt_dev, read_only); if (IS_ERR(virt_dev->fd)) { res = PTR_ERR(virt_dev->fd); virt_dev->fd = NULL; @@ -1689,23 +1471,8 @@ static int vdisk_open_fd(struct scst_vdisk_dev *virt_dev, bool read_only) NULL; res = 0; - if (virt_dev->dif_filename != NULL) { - virt_dev->dif_fd = vdev_open_fd(virt_dev, - virt_dev->dif_filename, read_only); - if (IS_ERR(virt_dev->dif_fd)) { - res = PTR_ERR(virt_dev->dif_fd); - virt_dev->dif_fd = NULL; - goto out_close_fd; - } - } - out: return res; - -out_close_fd: - filp_close(virt_dev->fd, NULL); - virt_dev->fd = NULL; - goto out; } static void vdisk_close_fd(struct scst_vdisk_dev *virt_dev) @@ -1717,10 +1484,6 @@ static void vdisk_close_fd(struct scst_vdisk_dev *virt_dev) virt_dev->fd = NULL; virt_dev->bdev = NULL; } - if (virt_dev->dif_fd) { - filp_close(virt_dev->dif_fd, NULL); - virt_dev->dif_fd = NULL; - } } /* Invoked with scst_mutex held, so no further locking is necessary here. */ @@ -1742,10 +1505,8 @@ static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev) virt_dev->tgt_dev_cnt--; goto out; } - } else { + } else virt_dev->fd = NULL; - virt_dev->dif_fd = NULL; - } out: TRACE_EXIT_RES(res); @@ -1859,119 +1620,6 @@ static enum compl_status_e vdisk_exec_send_diagnostic(struct vdisk_cmd_params *p return CMD_SUCCEEDED; } -static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, - uint64_t blocks) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - loff_t loff; - mm_segment_t old_fs; - loff_t err = 0; - ssize_t full_len; - struct file *fd = virt_dev->dif_fd; - struct iovec *iv; - int max_iv_count, iv_count, i; - struct page *iv_page, *data_page; - uint8_t *data_buf; - int64_t left, done; - - TRACE_ENTRY(); - - if (virt_dev->dif_fd == NULL) - goto out; - - EXTRACHECKS_BUG_ON(!(dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE)); - - iv_page = alloc_page(GFP_KERNEL); - if (iv_page == NULL) { - PRINT_ERROR("Unable to allocate iv page"); - scst_set_busy(cmd); - res = -ENOMEM; - goto out; - } - - data_page = alloc_page(GFP_KERNEL); - if (data_page == NULL) { - PRINT_ERROR("Unable to allocate tags data page"); - scst_set_busy(cmd); - res = -ENOMEM; - goto out_free_iv; - } - - data_buf = page_address(data_page); - memset(data_buf, 0xFF, PAGE_SIZE); - - iv = page_address(iv_page); - max_iv_count = min_t(int, UIO_MAXIOV, (int)PAGE_SIZE/sizeof(*iv)); - - for (i = 0; i < max_iv_count; i++) - iv[i].iov_base = (uint8_t __force __user *)data_buf; - - old_fs = get_fs(); - set_fs(get_ds()); - - loff = start_lba << SCST_DIF_TAG_SHIFT; - left = blocks << SCST_DIF_TAG_SHIFT; - done = 0; - while (left > 0) { - iv_count = 0; - full_len = 0; - i = -1; - while (1) { - int len = min_t(size_t, (size_t)left, PAGE_SIZE); - full_len += len; - i++; - iv_count++; - iv[i].iov_len = len; - left -= len; - done += len; - EXTRACHECKS_BUG_ON(left < 0); - if ((iv_count == max_iv_count) || (left == 0)) - break; - } - - TRACE_DBG("Formatting DIF: full_len %zd, off %lld", - full_len, (long long)loff); - - /* WRITE */ - err = vfs_writev(fd, (struct iovec __force __user *)iv, iv_count, - &loff); - if (err < 0) { - PRINT_ERROR("Formatting DIF write() returned %lld from " - "%zd", (long long unsigned int)err, full_len); - if (err == -EAGAIN) - scst_set_busy(cmd); - else - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_write_error)); - res = err; - goto out_set_fs; - } else if (err < full_len) { - /* - * Probably that's wrong, but sometimes write() returns - * value less, than requested. Let's restart. - */ - left += full_len - err; - done -= full_len - err; - } - - virt_dev->format_progress_done = done; - }; - -out_set_fs: - set_fs(old_fs); - - __free_page(data_page); - -out_free_iv: - __free_page(iv_page); - -out: - TRACE_EXIT_RES(res); - return res; -} - static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) { int res = CMD_SUCCEEDED; @@ -1979,7 +1627,7 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; uint8_t *buf; - int prot_type = dev->dev_dif_type, pinfo; + int prot_type = 0, pinfo; bool immed = false; TRACE_ENTRY(); @@ -2105,7 +1753,7 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) TRACE_DBG("prot_type %d, pinfo %d, immed %d (cmd %p)", prot_type, pinfo, immed, cmd); - if (prot_type != dev->dev_dif_type) { + if (prot_type != 0) { PRINT_ERROR("FORMAT UNIT: DIF type %d not supported (dev %s)", prot_type, dev->virt_name); scst_set_invalid_field_in_cdb(cmd, 1, @@ -2125,7 +1773,7 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) spin_unlock(&virt_dev->flags_lock); virt_dev->format_progress_done = 0; - virt_dev->format_progress_to_do = virt_dev->nblocks << SCST_DIF_TAG_SHIFT; + virt_dev->format_progress_to_do = 100; if (virt_dev->thin_provisioned) { int rc = vdisk_unmap_range(cmd, virt_dev, 0, virt_dev->nblocks); @@ -2133,9 +1781,6 @@ static enum compl_status_e vdisk_exec_format_unit(struct vdisk_cmd_params *p) goto finished; } - if (pinfo != 0) - vdisk_format_dif(cmd, 0, virt_dev->nblocks); - finished: spin_lock(&virt_dev->flags_lock); virt_dev->format_active = 0; @@ -2159,9 +1804,9 @@ static enum compl_status_e vdisk_invalid_opcode(struct vdisk_cmd_params *p) return INVALID_OPCODE; } -#define VDEV_DEF_RDPROTECT 0xE0 -#define VDEV_DEF_WRPROTECT 0xE0 -#define VDEV_DEF_VRPROTECT 0xE0 +#define VDEV_DEF_RDPROTECT 0 +#define VDEV_DEF_WRPROTECT 0 +#define VDEV_DEF_VRPROTECT 0 #define VDEF_DEF_GROUP_NUM 0 @@ -2253,22 +1898,6 @@ static const struct scst_opcode_descriptor scst_op_descr_read16 = { SCST_OD_DEFAULT_CONTROL_BYTE }, }; -static const struct scst_opcode_descriptor scst_op_descr_read32 = { - .od_opcode = VARIABLE_LENGTH_CMD, - .od_serv_action = SUBCODE_READ_32, - .od_serv_action_valid = 1, - .od_support = 3, /* supported as in the standard */ - .od_cdb_size = 32, - .od_nominal_timeout = SCST_DEFAULT_NOMINAL_TIMEOUT_SEC, - .od_recommended_timeout = SCST_GENERIC_DISK_REG_TIMEOUT/HZ, - .od_cdb_usage_bits = { VARIABLE_LENGTH_CMD, SCST_OD_DEFAULT_CONTROL_BYTE, - 0, 0, 0, 0, VDEF_DEF_GROUP_NUM, 0x18, 0, - SUBCODE_READ_32, VDEV_DEF_RDPROTECT | 0x18, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF }, -}; - static const struct scst_opcode_descriptor scst_op_descr_read_capacity = { .od_opcode = READ_CAPACITY, .od_support = 3, /* supported as in the standard */ @@ -2369,22 +1998,6 @@ static const struct scst_opcode_descriptor scst_op_descr_verify16 = { SCST_OD_DEFAULT_CONTROL_BYTE }, }; -static const struct scst_opcode_descriptor scst_op_descr_verify32 = { - .od_opcode = VARIABLE_LENGTH_CMD, - .od_serv_action = SUBCODE_VERIFY_32, - .od_serv_action_valid = 1, - .od_support = 3, /* supported as in the standard */ - .od_cdb_size = 32, - .od_nominal_timeout = SCST_DEFAULT_NOMINAL_TIMEOUT_SEC, - .od_recommended_timeout = SCST_GENERIC_DISK_REG_TIMEOUT/HZ, - .od_cdb_usage_bits = { VARIABLE_LENGTH_CMD, SCST_OD_DEFAULT_CONTROL_BYTE, - 0, 0, 0, 0, VDEF_DEF_GROUP_NUM, 0x18, 0, - SUBCODE_VERIFY_32, VDEV_DEF_VRPROTECT | 0x16, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF }, -}; - static const struct scst_opcode_descriptor scst_op_descr_write6 = { .od_opcode = WRITE_6, .od_support = 3, /* supported as in the standard */ @@ -2429,22 +2042,6 @@ static const struct scst_opcode_descriptor scst_op_descr_write16 = { SCST_OD_DEFAULT_CONTROL_BYTE }, }; -static const struct scst_opcode_descriptor scst_op_descr_write32 = { - .od_opcode = VARIABLE_LENGTH_CMD, - .od_serv_action = SUBCODE_WRITE_32, - .od_serv_action_valid = 1, - .od_support = 3, /* supported as in the standard */ - .od_cdb_size = 32, - .od_nominal_timeout = SCST_DEFAULT_NOMINAL_TIMEOUT_SEC, - .od_recommended_timeout = SCST_GENERIC_DISK_REG_TIMEOUT/HZ, - .od_cdb_usage_bits = { VARIABLE_LENGTH_CMD, SCST_OD_DEFAULT_CONTROL_BYTE, - 0, 0, 0, 0, VDEF_DEF_GROUP_NUM, 0x18, 0, - SUBCODE_WRITE_32, VDEV_DEF_WRPROTECT | 0x1A, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF }, -}; - static const struct scst_opcode_descriptor scst_op_descr_write_verify10 = { .od_opcode = WRITE_VERIFY, .od_support = 3, /* supported as in the standard */ @@ -2479,22 +2076,6 @@ static const struct scst_opcode_descriptor scst_op_descr_write_verify16 = { SCST_OD_DEFAULT_CONTROL_BYTE }, }; -static const struct scst_opcode_descriptor scst_op_descr_write_verify32 = { - .od_opcode = VARIABLE_LENGTH_CMD, - .od_serv_action = SUBCODE_WRITE_VERIFY_32, - .od_serv_action_valid = 1, - .od_support = 3, /* supported as in the standard */ - .od_cdb_size = 32, - .od_nominal_timeout = SCST_DEFAULT_NOMINAL_TIMEOUT_SEC, - .od_recommended_timeout = SCST_GENERIC_DISK_REG_TIMEOUT/HZ, - .od_cdb_usage_bits = { VARIABLE_LENGTH_CMD, SCST_OD_DEFAULT_CONTROL_BYTE, - 0, 0, 0, 0, VDEF_DEF_GROUP_NUM, 0x18, 0, - SUBCODE_WRITE_VERIFY_32, VDEV_DEF_WRPROTECT | 0x16, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF }, -}; - static const struct scst_opcode_descriptor scst_op_descr_write_same10 = { .od_opcode = WRITE_SAME, .od_support = 3, /* supported as in the standard */ @@ -2518,22 +2099,6 @@ static const struct scst_opcode_descriptor scst_op_descr_write_same16 = { SCST_OD_DEFAULT_CONTROL_BYTE }, }; -static const struct scst_opcode_descriptor scst_op_descr_write_same32 = { - .od_opcode = VARIABLE_LENGTH_CMD, - .od_serv_action = SUBCODE_WRITE_SAME_32, - .od_serv_action_valid = 1, - .od_support = 3, /* supported as in the standard */ - .od_cdb_size = 32, - .od_nominal_timeout = SCST_DEFAULT_NOMINAL_TIMEOUT_SEC, - .od_recommended_timeout = SCST_GENERIC_DISK_REG_TIMEOUT/HZ, - .od_cdb_usage_bits = { VARIABLE_LENGTH_CMD, SCST_OD_DEFAULT_CONTROL_BYTE, - 0, 0, 0, 0, VDEF_DEF_GROUP_NUM, 0x18, 0, - SUBCODE_WRITE_SAME_32, VDEV_DEF_WRPROTECT | 0x8, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF }, -}; - static const struct scst_opcode_descriptor scst_op_descr_read_toc = { .od_opcode = READ_TOC, .od_support = 3, /* supported as in the standard */ @@ -2601,14 +2166,6 @@ static const struct scst_opcode_descriptor scst_op_descr_read_toc = { &scst_op_descr_verify12, \ &scst_op_descr_verify16, -static const vdisk_op_fn blockio_var_len_ops[] = { - [SUBCODE_READ_32] = blockio_exec_read, - [SUBCODE_WRITE_32] = blockio_exec_write, - [SUBCODE_WRITE_VERIFY_32] = blockio_exec_write_verify, - [SUBCODE_VERIFY_32] = vdev_exec_verify, - [SUBCODE_WRITE_SAME_32] = vdisk_exec_write_same, -}; - static vdisk_op_fn blockio_ops[256] = { [READ_6] = blockio_exec_read, [READ_10] = blockio_exec_read, @@ -2621,21 +2178,12 @@ static vdisk_op_fn blockio_ops[256] = { [WRITE_VERIFY] = blockio_exec_write_verify, [WRITE_VERIFY_12] = blockio_exec_write_verify, [WRITE_VERIFY_16] = blockio_exec_write_verify, - [VARIABLE_LENGTH_CMD] = blockio_exec_var_len_cmd, [VERIFY] = vdev_exec_verify, [VERIFY_12] = vdev_exec_verify, [VERIFY_16] = vdev_exec_verify, SHARED_OPS }; -static const vdisk_op_fn fileio_var_len_ops[] = { - [SUBCODE_READ_32] = fileio_exec_read, - [SUBCODE_WRITE_32] = fileio_exec_write, - [SUBCODE_WRITE_VERIFY_32] = fileio_exec_write_verify, - [SUBCODE_VERIFY_32] = vdev_exec_verify, - [SUBCODE_WRITE_SAME_32] = vdisk_exec_write_same, -}; - static vdisk_op_fn fileio_ops[256] = { [READ_6] = fileio_exec_read, [READ_10] = fileio_exec_read, @@ -2648,20 +2196,12 @@ static vdisk_op_fn fileio_ops[256] = { [WRITE_VERIFY] = fileio_exec_write_verify, [WRITE_VERIFY_12] = fileio_exec_write_verify, [WRITE_VERIFY_16] = fileio_exec_write_verify, - [VARIABLE_LENGTH_CMD] = fileio_exec_var_len_cmd, [VERIFY] = vdev_exec_verify, [VERIFY_12] = vdev_exec_verify, [VERIFY_16] = vdev_exec_verify, SHARED_OPS }; -static const vdisk_op_fn nullio_var_len_ops[] = { - [SUBCODE_READ_32] = nullio_exec_read, - [SUBCODE_WRITE_32] = nullio_exec_write, - [SUBCODE_WRITE_VERIFY_32] = nullio_exec_write_verify, - [SUBCODE_WRITE_SAME_32] = vdisk_exec_write_same, -}; - static vdisk_op_fn nullio_ops[256] = { [READ_6] = nullio_exec_read, [READ_10] = nullio_exec_read, @@ -2674,7 +2214,6 @@ static vdisk_op_fn nullio_ops[256] = { [WRITE_VERIFY] = nullio_exec_write_verify, [WRITE_VERIFY_12] = nullio_exec_write_verify, [WRITE_VERIFY_16] = nullio_exec_write_verify, - [VARIABLE_LENGTH_CMD] = nullio_exec_var_len_cmd, [VERIFY] = nullio_exec_verify, [VERIFY_12] = nullio_exec_verify, [VERIFY_16] = nullio_exec_verify, @@ -2696,17 +2235,6 @@ static const struct scst_opcode_descriptor *vdisk_opcode_descriptors[] = { SCST_OPCODE_DESCRIPTORS }; -static const struct scst_opcode_descriptor *vdisk_opcode_descriptors_type2[] = { - SHARED_OPCODE_DESCRIPTORS - VDISK_OPCODE_DESCRIPTORS - &scst_op_descr_read32, - &scst_op_descr_write32, - &scst_op_descr_verify32, - &scst_op_descr_write_verify32, - &scst_op_descr_write_same32, - SCST_OPCODE_DESCRIPTORS -}; - static const struct scst_opcode_descriptor *vcdrom_opcode_descriptors[] = { SHARED_OPCODE_DESCRIPTORS &scst_op_descr_allow_medium_removal, @@ -2718,13 +2246,8 @@ static int vdisk_get_supported_opcodes(struct scst_cmd *cmd, const struct scst_opcode_descriptor ***out_supp_opcodes, int *out_supp_opcodes_cnt) { - if (cmd->dev->dev_dif_type != 2) { - *out_supp_opcodes = vdisk_opcode_descriptors; - *out_supp_opcodes_cnt = ARRAY_SIZE(vdisk_opcode_descriptors); - } else { - *out_supp_opcodes = vdisk_opcode_descriptors_type2; - *out_supp_opcodes_cnt = ARRAY_SIZE(vdisk_opcode_descriptors); - } + *out_supp_opcodes = vdisk_opcode_descriptors; + *out_supp_opcodes_cnt = ARRAY_SIZE(vdisk_opcode_descriptors); return 0; } @@ -2745,10 +2268,6 @@ static bool vdisk_use_zero_copy(const struct scst_cmd *cmd) return false; switch (cmd->cdb[0]) { - case VARIABLE_LENGTH_CMD: - if (cmd->cdb[9] != SUBCODE_READ_32) - break; - /* else go througth */ case READ_6: case READ_10: case READ_12: @@ -2834,15 +2353,6 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd) } switch (opcode) { - case VARIABLE_LENGTH_CMD: - if (cmd->cdb[9] == SUBCODE_WRITE_32) { - fua = (cdb[10] & 0x8); - if (fua) - TRACE(TRACE_ORDER, "FUA: loff=%lld, data_len=%lld", - (long long unsigned int)loff, - (long long unsigned int)data_len); - } - break; case WRITE_10: case WRITE_12: case WRITE_16: @@ -3620,12 +3130,6 @@ static int vdisk_unmap_range(struct scst_cmd *cmd, goto out; } - if (virt_dev->dif_fd != NULL) { - res = vdisk_format_dif(cmd, start_lba, blocks); - if (unlikely(res != 0)) - goto out; - } - success: res = 0; @@ -3694,27 +3198,34 @@ static enum compl_status_e vdisk_exec_write_same(struct vdisk_cmd_params *p) { struct scst_cmd *cmd = p->cmd; enum compl_status_e res = CMD_SUCCEEDED; - uint8_t ctrl_offs = (cmd->cdb_len < 32) ? 1 : 10; TRACE_ENTRY(); - if (unlikely(cmd->cdb[ctrl_offs] & 1)) { + if (unlikely(cmd->cdb[1] & 1)) { TRACE_DBG("%s", "ANCHOR not supported"); - scst_set_invalid_field_in_cdb(cmd, ctrl_offs, + scst_set_invalid_field_in_cdb(cmd, 1, SCST_INVAL_FIELD_BIT_OFFS_VALID | 0); goto out; } + if (unlikely(cmd->cdb[1] & 0xE0)) { + TRACE_DBG("%s", "WRPROTECT not supported"); + scst_set_invalid_field_in_cdb(cmd, 1, + SCST_INVAL_FIELD_BIT_OFFS_VALID | 5); + goto out; + } + if (unlikely(cmd->data_len <= 0)) { scst_set_invalid_field_in_cdb(cmd, cmd->len_off, 0); goto out; } - if (cmd->cdb[ctrl_offs] & 0x8) + if (cmd->cdb[1] & 0x8) { vdisk_exec_write_same_unmap(p); - else - scst_write_same(cmd); + goto out; + } + scst_write_same(cmd); res = RUNNING_ASYNC; out: @@ -3946,31 +3457,8 @@ static int vdisk_dev_id_vpd(uint8_t *buf, struct scst_cmd *cmd, static int vdisk_ext_inq(uint8_t *buf, struct scst_cmd *cmd, struct scst_vdisk_dev *virt_dev) { - struct scst_device *dev = cmd->dev; - buf[1] = 0x86; buf[3] = 0x3C; - if (dev->dev_dif_mode != SCST_DIF_MODE_NONE) { - switch (dev->dev_dif_type) { - case 1: - buf[4] = 0; /* SPT=0, type 1 only supported */ - break; - case 2: - buf[4] = 0x10; /* SPT=010, type 2 only supported */ - break; - case 3: - buf[4] = 0x20; /* SPT=100, type 3 only supported */ - break; - default: - sBUG_ON(1); - break; - } - buf[4] |= 4; /* GRD_CHK */ - if (dev->dif_app_chk) - buf[4] |= 2; /* APP_CHK */ - if (dev->dif_ref_chk) - buf[4] |= 1; /* REF_CHK */ - } buf[5] = 7; /* HEADSUP=1, ORDSUP=1, SIMPSUP=1 */ buf[6] = (virt_dev->wt_flag || virt_dev->nv_cache) ? 0 : 1; /* V_SUP */ buf[7] = 1; /* LUICLR=1 */ @@ -4068,10 +3556,8 @@ static int vdisk_inq(uint8_t *buf, struct scst_cmd *cmd, if (cmd->tgtt->fake_aca) buf[3] |= 0x20; buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */ - if (cmd->dev->dev_dif_mode != SCST_DIF_MODE_NONE) - buf[5] |= 1; /* PROTECT */ if (scst_impl_alua_configured(cmd->dev)) - buf[5] |= SCST_INQ_TPGS_MODE_IMPLICIT; + buf[5] = SCST_INQ_TPGS_MODE_IMPLICIT; buf[6] = 0x10; /* MultiP 1 */ buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */ @@ -4414,14 +3900,12 @@ static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol, switch (pcontrol) { case 0: /* current */ p[2] |= virt_dev->dev->tst << 5; - p[2] |= virt_dev->dev->d_sense << 2; - p[2] |= virt_dev->dev->dpicz << 3; p[2] |= virt_dev->dev->tmf_only << 4; + p[2] |= virt_dev->dev->d_sense << 2; p[3] |= virt_dev->dev->queue_alg << 4; p[3] |= virt_dev->dev->qerr << 1; p[4] |= virt_dev->dev->swp << 3; p[5] |= virt_dev->dev->tas << 6; - p[5] |= virt_dev->dev->ato << 7; break; case 1: /* changeable */ memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); @@ -4433,35 +3917,29 @@ static int vdisk_ctrl_m_pg(unsigned char *p, int pcontrol, p[2] |= 7 << 5; /* TST */ #endif p[2] |= 1 << 2; /* D_SENSE */ - p[2] |= 1 << 3; /* DPICZ */ p[2] |= 1 << 4; /* TMF_ONLY */ p[3] |= 0xF << 4; /* QUEUE ALGORITHM MODIFIER */ p[3] |= 3 << 1; /* QErr */ p[4] |= 1 << 3; /* SWP */ p[5] |= 1 << 6; /* TAS */ - p[5] |= 0 << 7; /* ATO */ break; case 2: /* default */ p[2] |= virt_dev->tst << 5; p[2] |= virt_dev->dev->d_sense_default << 2; - p[2] |= virt_dev->dev->dpicz_default << 3; p[2] |= virt_dev->dev->tmf_only_default << 4; p[3] |= virt_dev->dev->queue_alg_default << 4; p[3] |= virt_dev->dev->qerr_default << 1; p[4] |= virt_dev->dev->swp_default << 3; p[5] |= virt_dev->dev->tas_default << 6; - p[5] |= virt_dev->dev->ato << 7; break; case 3: /* saved */ p[2] |= virt_dev->dev->tst << 5; p[2] |= virt_dev->dev->d_sense_saved << 2; - p[2] |= virt_dev->dev->dpicz_saved << 3; p[2] |= virt_dev->dev->tmf_only_default << 4; p[3] |= virt_dev->dev->queue_alg_saved << 4; p[3] |= virt_dev->dev->qerr_saved << 1; p[4] |= virt_dev->dev->swp_saved << 3; p[5] |= virt_dev->dev->tas_saved << 6; - p[5] |= virt_dev->dev->ato << 7; break; default: sBUG(); @@ -4640,7 +4118,7 @@ out_not_sup: static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt, bool read_only) { int res = 0; - struct file *fd, *dif_fd = NULL; + struct file *fd; bool old_wt = virt_dev->wt_flag; TRACE_ENTRY(); @@ -4657,40 +4135,25 @@ static int vdisk_set_wt(struct scst_vdisk_dev *virt_dev, int wt, bool read_only) * to reopen fd. */ - fd = vdev_open_fd(virt_dev, virt_dev->filename, read_only); + fd = vdev_open_fd(virt_dev, read_only); if (IS_ERR(fd)) { + PRINT_ERROR("filp_open(%s) returned an error %ld", + virt_dev->filename, PTR_ERR(fd)); + spin_lock(&virt_dev->flags_lock); + virt_dev->wt_flag = old_wt; + spin_unlock(&virt_dev->flags_lock); res = PTR_ERR(fd); - goto out_err; - } - - if (virt_dev->dif_filename != NULL) { - dif_fd = vdev_open_fd(virt_dev, virt_dev->dif_filename, read_only); - if (IS_ERR(dif_fd)) { - res = PTR_ERR(dif_fd); - goto out_err_close_fd; - } + goto out; } if (virt_dev->fd) filp_close(virt_dev->fd, NULL); - if (virt_dev->dif_fd) - filp_close(virt_dev->dif_fd, NULL); virt_dev->fd = fd; - virt_dev->dif_fd = dif_fd; out: TRACE_EXIT_RES(res); return res; - -out_err_close_fd: - filp_close(fd, NULL); - -out_err: - spin_lock(&virt_dev->flags_lock); - virt_dev->wt_flag = old_wt; - spin_unlock(&virt_dev->flags_lock); - goto out; } static void vdisk_ctrl_m_pg_select(unsigned char *p, @@ -4699,9 +4162,9 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, { struct scst_device *dev = virt_dev->dev; int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense; - int old_queue_alg = dev->queue_alg, old_dpicz = dev->dpicz; + int old_queue_alg = dev->queue_alg; int rc, old_tmf_only = dev->tmf_only, old_qerr = dev->qerr; - int queue_alg, swp, tas, tmf_only, qerr, d_sense, dpicz; + int queue_alg, swp, tas, tmf_only, qerr, d_sense; TRACE_ENTRY(); @@ -4772,16 +4235,6 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, goto out; } - dpicz = (p[2] & 0x8) >> 3; - if (dpicz > 1) { - PRINT_WARNING("Attempt to set invalid Control mode page " - "dpicz value %d (initiator %s, dev %s)", dpicz, - cmd->sess->initiator_name, dev->virt_name); - scst_set_invalid_field_in_parm_list(cmd, param_offset + 2, - SCST_INVAL_FIELD_BIT_OFFS_VALID | 3); - goto out; - } - qerr = (p[3] & 0x6) >> 1; if ((qerr == SCST_QERR_2_RESERVED) || (qerr > SCST_QERR_3_ABORT_THIS_NEXUS_ONLY)) { @@ -4807,14 +4260,12 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, dev->swp = swp; dev->tas = tas; dev->tmf_only = tmf_only; - dev->dpicz = dpicz; dev->qerr = qerr; dev->d_sense = d_sense; if ((dev->swp == old_swp) && (dev->tas == old_tas) && (dev->d_sense == old_dsense) && (dev->queue_alg == old_queue_alg) && - (dev->qerr == old_qerr) && (dev->tmf_only == old_tmf_only) && - (dev->dpicz == old_dpicz)) + (dev->qerr == old_qerr) && (dev->tmf_only == old_tmf_only)) goto out; if (!save) @@ -4828,7 +4279,6 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, dev->queue_alg = old_queue_alg; dev->tmf_only = old_tmf_only; dev->qerr = old_qerr; - dev->dpicz = old_dpicz; /* Hopefully, the error is temporary */ scst_set_busy(cmd); goto out; @@ -4840,16 +4290,14 @@ static void vdisk_ctrl_m_pg_select(unsigned char *p, dev->queue_alg_saved = dev->queue_alg; dev->tmf_only_saved = dev->tmf_only; dev->qerr_saved = dev->qerr; - dev->dpicz_saved = dev->dpicz; out_ok: PRINT_INFO("Device %s: new control mode page parameters: SWP %x " "(was %x), TAS %x (was %x), TMF_ONLY %d (was %x), QErr %x " - "(was %x), D_SENSE %d (was %d), QUEUE ALG %d (was %d), " - "DPICZ %d (was %d)", virt_dev->name, dev->swp, old_swp, - dev->tas, old_tas, dev->tmf_only, old_tmf_only, dev->qerr, - old_qerr, dev->d_sense, old_dsense, dev->queue_alg, - old_queue_alg, dev->dpicz, old_dpicz); + "(was %x), D_SENSE %d (was %d), QUEUE ALG %d (was %d)", + virt_dev->name, dev->swp, old_swp, dev->tas, old_tas, + dev->tmf_only, old_tmf_only, dev->qerr, old_qerr, + dev->d_sense, old_dsense, dev->queue_alg, old_queue_alg); out: TRACE_EXIT(); @@ -5094,23 +4542,6 @@ static enum compl_status_e vdisk_exec_read_capacity16(struct vdisk_cmd_params *p put_unaligned_be64(nblocks, &buffer[0]); put_unaligned_be32(blocksize, &buffer[8]); - if (cmd->dev->dev_dif_mode != SCST_DIF_MODE_NONE) { - switch (cmd->dev->dev_dif_type) { - case 1: - buffer[12] = 1; - break; - case 2: - buffer[12] = 3; - break; - case 3: - buffer[12] = 5; - break; - default: - sBUG_ON(1); - break; - } - } - switch (blocksize) { case 512: buffer[13] = 3; @@ -5300,11 +4731,12 @@ static enum compl_status_e vdisk_exec_prevent_allow_medium_removal(struct vdisk_ return CMD_SUCCEEDED; } -static int __vdisk_fsync_fileio(loff_t loff, - loff_t len, struct scst_device *dev, struct scst_cmd *cmd, - struct file *file) +static int vdisk_fsync_blockio(loff_t loff, + loff_t len, struct scst_device *dev, gfp_t gfp_flags, + struct scst_cmd *cmd, bool async) { int res; + struct scst_vdisk_dev *virt_dev = dev->dh_priv; TRACE_ENTRY(); @@ -5313,7 +4745,32 @@ static int __vdisk_fsync_fileio(loff_t loff, ** anything without checking for NULL at first !!! **/ - /* BLOCKIO can be here for DIF tags fsync */ + EXTRACHECKS_BUG_ON(!virt_dev->blockio); + + res = vdisk_blockio_flush(virt_dev->bdev, gfp_flags, true, + cmd, async); + + TRACE_EXIT_RES(res); + return res; +} + +static int vdisk_fsync_fileio(loff_t loff, + loff_t len, struct scst_device *dev, struct scst_cmd *cmd, bool async) +{ + int res; + struct scst_vdisk_dev *virt_dev = dev->dh_priv; + struct file *file; + + TRACE_ENTRY(); + + /** + ** !!! CAUTION !!!: cmd can be NULL here! Don't use it for + ** anything without checking for NULL at first !!! + **/ + + EXTRACHECKS_BUG_ON(virt_dev->blockio); + + file = virt_dev->fd; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) res = sync_page_range(file_inode(file), file->f_mapping, loff, len); @@ -5335,69 +4792,6 @@ static int __vdisk_fsync_fileio(loff_t loff, } } - TRACE_EXIT_RES(res); - return res; -} - -static int vdisk_fsync_blockio(loff_t loff, - loff_t len, struct scst_device *dev, gfp_t gfp_flags, - struct scst_cmd *cmd, bool async) -{ - int res; - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - - TRACE_ENTRY(); - - /** - ** !!! CAUTION !!!: cmd can be NULL here! Don't use it for - ** anything without checking for NULL at first !!! - **/ - - EXTRACHECKS_BUG_ON(!virt_dev->blockio); - - /* Must be first, because vdisk_blockio_flush() can call scst_cmd_done()! */ - if (virt_dev->dif_fd != NULL) { - loff = (loff >> dev->block_shift) << SCST_DIF_TAG_SHIFT; - len = (len >> dev->block_shift) << SCST_DIF_TAG_SHIFT; - res = __vdisk_fsync_fileio(loff, len, dev, cmd, - virt_dev->dif_fd); - if (unlikely(res != 0)) - goto out; - } - - res = vdisk_blockio_flush(virt_dev->bdev, gfp_flags, true, - cmd, async); - -out: - TRACE_EXIT_RES(res); - return res; -} - -static int vdisk_fsync_fileio(loff_t loff, - loff_t len, struct scst_device *dev, struct scst_cmd *cmd, bool async) -{ - int res; - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - - TRACE_ENTRY(); - - /** - ** !!! CAUTION !!!: cmd can be NULL here! Don't use it for - ** anything without checking for NULL at first !!! - **/ - - res = __vdisk_fsync_fileio(loff, len, dev, cmd, virt_dev->fd); - if (unlikely(res != 0)) - goto done; - - if (virt_dev->dif_fd != NULL) { - loff = (loff >> dev->block_shift) << SCST_DIF_TAG_SHIFT; - len = (len >> dev->block_shift) << SCST_DIF_TAG_SHIFT; - res = __vdisk_fsync_fileio(loff, len, dev, cmd, - virt_dev->dif_fd); - } - -done: if (async) { if (cmd != NULL) { cmd->completed = 1; @@ -5496,302 +4890,10 @@ static enum compl_status_e nullio_exec_read(struct vdisk_cmd_params *p) } } - scst_dif_process_read(p->cmd); - TRACE_EXIT(); return CMD_SUCCEEDED; } -static int vdev_read_dif_tags(struct vdisk_cmd_params *p) -{ - int res = 0; - struct scst_cmd *cmd = p->cmd; - loff_t loff; - mm_segment_t old_fs; - loff_t err = 0; - ssize_t length, full_len; - uint8_t *address; - struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; - struct file *fd = virt_dev->dif_fd; - struct iovec *iv; - int iv_count, max_iv_count, i; - bool finished = false; - int tags_num, l; - struct scatterlist *tags_sg; - bool free_iv = false; - - TRACE_ENTRY(); - - /* - * !! Data for this cmd can be read simultaneously !! - */ - - EXTRACHECKS_BUG_ON(virt_dev->nullio); - -#if 0 /* no zero-copy (yet) */ - if (p->use_zero_copy) - goto out; -#endif - - EXTRACHECKS_BUG_ON(!(cmd->dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) || - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) == SCST_DIF_ACTION_NONE)); - - tags_num = (cmd->bufflen >> cmd->dev->block_shift); - if (unlikely(tags_num == 0)) - goto out; - - iv = p->iv; - if (iv == NULL) { - iv = vdisk_alloc_iv(cmd, p); - if (iv == NULL) { - unsigned long flags; - /* To protect sense setting against blockio data reads */ - spin_lock_irqsave(&vdev_err_lock, flags); - scst_set_busy(cmd); - spin_unlock_irqrestore(&vdev_err_lock, flags); - res = -ENOMEM; - goto out; - } - free_iv = true; - } - max_iv_count = p->iv_count; - - old_fs = get_fs(); - set_fs(get_ds()); - - tags_sg = NULL; - loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - while (1) { - iv_count = 0; - full_len = 0; - i = -1; - address = scst_get_dif_buf(cmd, &tags_sg, &l); - length = l; - EXTRACHECKS_BUG_ON(length <= 0); - while (1) { - full_len += length; - i++; - iv_count++; - iv[i].iov_base = (uint8_t __force __user *)address; - iv[i].iov_len = length; - tags_num -= length >> SCST_DIF_TAG_SHIFT; - EXTRACHECKS_BUG_ON(tags_num < 0); - if ((iv_count == max_iv_count) || (tags_num == 0)) - break; - address = scst_get_dif_buf(cmd, &tags_sg, &l); - length = l; - EXTRACHECKS_BUG_ON(length <= 0); - } - if (tags_num == 0) - finished = true; - - TRACE_DBG("Reading DIF iv_count %d, full_len %zd, loff %lld", - iv_count, full_len, (long long)loff); - - /* READ */ - err = vfs_readv(fd, (struct iovec __force __user *)iv, iv_count, - &loff); - if ((err < 0) || (err < full_len)) { - unsigned long flags; - PRINT_ERROR("DIF readv() returned %lld from %zd " - "(offs %lld, dev %s)", (long long)err, - full_len, (long long)loff, cmd->dev->virt_name); - /* To protect sense setting with blockio */ - spin_lock_irqsave(&vdev_err_lock, flags); - if (err == -EAGAIN) - scst_set_busy(cmd); - else { - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_read_error)); - } - spin_unlock_irqrestore(&vdev_err_lock, flags); - res = err; - goto out_set_fs; - } - - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - - if (finished) - break; - }; - - set_fs(old_fs); - -out_free_iv: - if (free_iv && (iv != p->small_iv)) - kfree(p->iv); - -out: - TRACE_EXIT_RES(res); - return res; - -out_set_fs: - set_fs(old_fs); - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - goto out_free_iv; -} - -static int vdev_write_dif_tags(struct vdisk_cmd_params *p) -{ - int res = 0; - struct scst_cmd *cmd = p->cmd; - loff_t loff; - mm_segment_t old_fs; - loff_t err = 0; - ssize_t length, full_len; - uint8_t *address; - struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; - struct file *fd = virt_dev->dif_fd; - struct iovec *iv, *eiv; - int iv_count, eiv_count, max_iv_count, i; - bool finished = false; - int tags_num, l; - struct scatterlist *tags_sg; - bool free_iv = false; - - TRACE_ENTRY(); - - /* - * !! Data for this cmd can be written simultaneously !! - */ - - EXTRACHECKS_BUG_ON(virt_dev->nullio); - -#if 0 /* no zero-copy (yet) */ - if (p->use_zero_copy) - goto out; -#endif - - EXTRACHECKS_BUG_ON(!(cmd->dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) || - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) == SCST_DIF_ACTION_NONE)); - - tags_num = (cmd->bufflen >> cmd->dev->block_shift); - if (unlikely(tags_num == 0)) - goto out; - - iv = p->iv; - if (iv == NULL) { - iv = vdisk_alloc_iv(cmd, p); - if (iv == NULL) { - unsigned long flags; - /* To protect sense setting against blockio data writes */ - spin_lock_irqsave(&vdev_err_lock, flags); - scst_set_busy(cmd); - spin_unlock_irqrestore(&vdev_err_lock, flags); - res = -ENOMEM; - goto out; - } - free_iv = true; - } - max_iv_count = p->iv_count; - - old_fs = get_fs(); - set_fs(get_ds()); - - tags_sg = NULL; - loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - while (1) { - iv_count = 0; - full_len = 0; - i = -1; - address = scst_get_dif_buf(cmd, &tags_sg, &l); - length = l; - EXTRACHECKS_BUG_ON(length <= 0); - while (1) { - full_len += length; - i++; - iv_count++; - iv[i].iov_base = (uint8_t __force __user *)address; - iv[i].iov_len = length; - tags_num -= length >> SCST_DIF_TAG_SHIFT; - EXTRACHECKS_BUG_ON(tags_num < 0); - if ((iv_count == max_iv_count) || (tags_num == 0)) - break; - address = scst_get_dif_buf(cmd, &tags_sg, &l); - length = l; - EXTRACHECKS_BUG_ON(length <= 0); - } - if (tags_num == 0) - finished = true; - - eiv = iv; - eiv_count = iv_count; -restart: - TRACE_DBG("Writing DIF: eiv_count %d, full_len %zd", eiv_count, full_len); - - /* WRITE */ - err = vfs_writev(fd, (struct iovec __force __user *)eiv, eiv_count, - &loff); - if (err < 0) { - unsigned long flags; - PRINT_ERROR("DIF write() returned %lld from %zd", - (long long unsigned int)err, full_len); - /* To protect sense setting with blockio */ - spin_lock_irqsave(&vdev_err_lock, flags); - if (err == -EAGAIN) - scst_set_busy(cmd); - else { - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_write_error)); - } - spin_unlock_irqrestore(&vdev_err_lock, flags); - res = err; - goto out_set_fs; - } else if (err < full_len) { - /* - * Probably that's wrong, but sometimes write() returns - * value less, than requested. Let's restart. - */ - int e = eiv_count; - TRACE_MGMT_DBG("DIF write() returned %d from %zd " - "(iv_count=%d)", (int)err, full_len, - eiv_count); - if (err == 0) { - PRINT_INFO("Suspicious: DIF write() returned 0 from " - "%zd (iv_count=%d)", full_len, eiv_count); - } - full_len -= err; - for (i = 0; i < e; i++) { - if ((long long)eiv->iov_len < err) { - err -= eiv->iov_len; - eiv++; - eiv_count--; - } else { - eiv->iov_base = - (uint8_t __force __user *)eiv->iov_base + err; - eiv->iov_len -= err; - break; - } - } - goto restart; - } - - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - - if (finished) - break; - }; - - set_fs(old_fs); - -out_free_iv: - if (free_iv && (iv != p->small_iv)) - kfree(iv); - -out: - TRACE_EXIT_RES(res); - return res; - -out_set_fs: - set_fs(old_fs); - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); - goto out_free_iv; -} - static enum compl_status_e blockio_exec_read(struct vdisk_cmd_params *p) { blockio_exec_rw(p, false, false); @@ -5806,11 +4908,10 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) loff_t err = 0; ssize_t length, full_len; uint8_t __user *address; - struct scst_device *dev = cmd->dev; - struct scst_vdisk_dev *virt_dev = dev->dh_priv; + struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->fd; struct iovec *iv; - int iv_count, i, max_iv_count; + int iv_count, i; bool finished = false; TRACE_ENTRY(); @@ -5818,14 +4919,12 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) EXTRACHECKS_BUG_ON(virt_dev->nullio); if (p->use_zero_copy) - goto out_dif; + goto out; iv = vdisk_alloc_iv(cmd, p); if (iv == NULL) goto out_nomem; - max_iv_count = p->iv_count; - length = scst_get_buf_first(cmd, (uint8_t __force **)&address); if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_first() failed: %zd", length); @@ -5847,7 +4946,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) iv_count++; iv[i].iov_base = address; iv[i].iov_len = length; - if (iv_count == max_iv_count) + if (iv_count == UIO_MAXIOV) break; length = scst_get_buf_next(cmd, (uint8_t __force **)&address); @@ -5863,11 +4962,12 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) goto out_set_fs; } - TRACE_DBG("Reading iv_count %d, full_len %zd", iv_count, full_len); + TRACE_DBG("(iv_count %d, full_len %zd)", iv_count, full_len); /* READ */ err = vfs_readv(fd, (struct iovec __force __user *)iv, iv_count, &loff); + if ((err < 0) || (err < full_len)) { PRINT_ERROR("readv() returned %lld from %zd", (unsigned long long int)err, @@ -5892,16 +4992,6 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) set_fs(old_fs); - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { - err = vdev_read_dif_tags(p); - if (err != 0) - goto out; - } - -out_dif: - scst_dif_process_read(cmd); - out: TRACE_EXIT(); return CMD_SUCCEEDED; @@ -5920,7 +5010,6 @@ out_nomem: static enum compl_status_e nullio_exec_write(struct vdisk_cmd_params *p) { - scst_dif_process_write(p->cmd); return CMD_SUCCEEDED; } @@ -5929,67 +5018,14 @@ static enum compl_status_e blockio_exec_write(struct vdisk_cmd_params *p) struct scst_cmd *cmd = p->cmd; struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; - int res, rc; - - TRACE_ENTRY(); - - rc = scst_dif_process_write(cmd); - if (unlikely(rc != 0)) { - res = CMD_SUCCEEDED; - goto out; - } blockio_exec_rw(p, true, p->fua || virt_dev->wt_flag); - res = RUNNING_ASYNC; - -out: - TRACE_EXIT_RES(res); - return res; -} - -static enum compl_status_e blockio_exec_var_len_cmd(struct vdisk_cmd_params *p) -{ - struct scst_cmd *cmd = p->cmd; - int res; - - TRACE_ENTRY(); - - res = blockio_var_len_ops[cmd->cdb[9]](p); - - TRACE_EXIT_RES(res); - return res; -} - -static enum compl_status_e nullio_exec_var_len_cmd(struct vdisk_cmd_params *p) -{ - struct scst_cmd *cmd = p->cmd; - int res; - - TRACE_ENTRY(); - - res = nullio_var_len_ops[cmd->cdb[9]](p); - - TRACE_EXIT_RES(res); - return res; -} - -static enum compl_status_e fileio_exec_var_len_cmd(struct vdisk_cmd_params *p) -{ - struct scst_cmd *cmd = p->cmd; - int res; - - TRACE_ENTRY(); - - res = fileio_var_len_ops[cmd->cdb[9]](p); - - TRACE_EXIT_RES(res); - return res; + return RUNNING_ASYNC; } static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) { struct scst_cmd *cmd = p->cmd; - struct scst_device *dev = cmd->dev; loff_t loff = p->loff; mm_segment_t old_fs; loff_t err = 0; @@ -5998,17 +5034,13 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->fd; struct iovec *iv, *eiv; - int rc, i, iv_count, eiv_count, max_iv_count; + int i, iv_count, eiv_count; bool finished = false; TRACE_ENTRY(); EXTRACHECKS_BUG_ON(virt_dev->nullio); - rc = scst_dif_process_write(cmd); - if (unlikely(rc != 0)) - goto out; - if (p->use_zero_copy) goto out_sync; @@ -6016,8 +5048,6 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) if (iv == NULL) goto out_nomem; - max_iv_count = p->iv_count; - length = scst_get_buf_first(cmd, &address); if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_first() failed: %zd", length); @@ -6039,7 +5069,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) iv_count++; iv[i].iov_base = (uint8_t __force __user *)address; iv[i].iov_len = length; - if (iv_count == max_iv_count) + if (iv_count == UIO_MAXIOV) break; length = scst_get_buf_next(cmd, &address); } @@ -6057,11 +5087,12 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) eiv = iv; eiv_count = iv_count; restart: - TRACE_DBG("Writing: eiv_count %d, full_len %zd", eiv_count, full_len); + TRACE_DBG("writing(eiv_count %d, full_len %zd)", eiv_count, full_len); /* WRITE */ err = vfs_writev(fd, (struct iovec __force __user *)eiv, eiv_count, &loff); + if (err < 0) { PRINT_ERROR("write() returned %lld from %zd", (unsigned long long int)err, @@ -6112,13 +5143,6 @@ restart: set_fs(old_fs); - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { - err = vdev_write_dif_tags(p); - if (err != 0) - goto out; - } - out_sync: /* O_DSYNC flag is used for WT devices */ if (p->fua) @@ -6153,21 +5177,9 @@ static inline void blockio_check_finish(struct scst_blockio_work *blockio_work) { /* Decrement the bios in processing, and if zero signal completion */ if (atomic_dec_and_test(&blockio_work->bios_inflight)) { - struct scst_cmd *cmd = blockio_work->cmd; - - if ((cmd->data_direction & SCST_DATA_READ) && - likely(cmd->status == SAM_STAT_GOOD)) { - /* - * We, most likely, on interrupt, so defer DIF - * checking to later stage in thread context - */ - cmd->deferred_dif_read_check = 1; - } - blockio_work->cmd->completed = 1; - blockio_work->cmd->scst_cmd_done(cmd, + blockio_work->cmd->scst_cmd_done(blockio_work->cmd, SCST_CMD_STATE_DEFAULT, scst_estimate_context()); - kmem_cache_free(blockio_work_cachep, blockio_work); } return; @@ -6204,16 +5216,14 @@ static void blockio_endio(struct bio *bio, int error) } if (unlikely(error != 0)) { + static DEFINE_SPINLOCK(blockio_endio_lock); unsigned long flags; PRINT_ERROR("BLOCKIO for cmd %p finished with error %d", blockio_work->cmd, error); - /* - * To protect from several bios finishing simultaneously + - * unsuccessful DIF tags reading/writing - */ - spin_lock_irqsave(&vdev_err_lock, flags); + /* To protect from several bios finishing simultaneously */ + spin_lock_irqsave(&blockio_endio_lock, flags); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) if (bio->bi_rw & (1 << BIO_RW)) @@ -6226,7 +5236,7 @@ static void blockio_endio(struct bio *bio, int error) scst_set_cmd_error(blockio_work->cmd, SCST_LOAD_SENSE(scst_sense_read_error)); - spin_unlock_irqrestore(&vdev_err_lock, flags); + spin_unlock_irqrestore(&blockio_endio_lock, flags); } #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)) || (LINUX_VERSION_CODE > KERNEL_VERSION(3, 6, 0)) @@ -6287,117 +5297,12 @@ static void vdisk_bio_set_hoq(struct bio *bio) #endif } -#if defined(CONFIG_BLK_DEV_INTEGRITY) -static void vdisk_blk_add_dif(struct bio *bio, gfp_t gfp_mask, - const struct scst_device *dev, struct scatterlist **pdsg, - int *pdsg_offs, int *pdsg_len, bool last) -{ - int block_shift = dev->block_shift; - struct scatterlist *orig_dsg = *pdsg; - struct scatterlist *sg; - int sg_offs = *pdsg_offs, sg_len = *pdsg_len; - int pages, left, len, tags_len, rc; - struct bio_integrity_payload *bip; - - TRACE_ENTRY(); - - tags_len = ((bio_sectors(bio) << 9) >> block_shift) << SCST_DIF_TAG_SHIFT; - - TRACE_DBG("bio %p, tags_len %d, pdsg %p, pdsg_offs %d, pdsg_len %d, " - "last %d", bio, tags_len, *pdsg, *pdsg_offs, *pdsg_len, last); - - pages = 0; - left = tags_len; - sg = orig_dsg; - len = sg->length; - while (1) { - pages++; - left -= len; - if (left <= 0) { - if (!last) { - left = -left; - sg = __sg_next_inline(sg); - *pdsg = sg; - *pdsg_offs = sg->offset + left; - *pdsg_len = sg->length - left; - TRACE_DBG("left %d, pdsg %p, pdsg_offs %d, pdsg_len %d", - left, *pdsg, *pdsg_offs, *pdsg_len); - } - break; - } - sg = __sg_next_inline(sg); - len = sg->length; - } - - bip = bio_integrity_alloc(bio, gfp_mask, pages); - if (unlikely(bip == NULL)) { - PRINT_WARNING("Allocation of %d pages for DIF tags " - "failed! (dev %s)", pages, dev->virt_name); - goto out; /* proceed without integrity */ - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) - bip->bip_iter.bi_size = tags_len; - bip->bip_iter.bi_sector = bio->bi_iter.bi_sector; -#else - bip->bip_size = tags_len; - bip->bip_sector = bio->bi_sector; -#endif - - left = tags_len; - sg = orig_dsg; - while (1) { - TRACE_DBG("page %p (buf %p), sg_len %d, sg_offs %d", - sg_page(sg), page_address(sg_page(sg)), - sg_len, sg_offs); - - rc = bio_integrity_add_page(bio, sg_page(sg), sg_len, sg_offs); - if (rc != sg_len) { - PRINT_WARNING("Can not add DIF tags page! " - "(dev %s)", dev->virt_name); - /* bio_integrity_free() will be called as part of bio_free() */ - goto out; /* proceed without integrity */ - } - - if (left < sg_len) { - TRACE_DBG("left %d, sg_len %d, sg_offs %d", - left, sg_len, sg_offs); - break; - } - - left -= sg_len; - EXTRACHECKS_BUG_ON(left < 0); - - TRACE_DBG("left %d", left); - - if (left == 0) - break; - - sg = __sg_next_inline(sg); - sg_len = sg->length; - sg_offs = sg->offset; - } - -out: - TRACE_EXIT(); - return; -} -#else /* defined(CONFIG_BLK_DEV_INTEGRITY) */ -static void vdisk_blk_add_dif(struct bio *bio, gfp_t gfp_mask, - const struct scst_device *dev, struct scatterlist **pdsg, - int *pdsg_offs, int *pdsg_len, bool last) -{ - BUG(); -} -#endif /* defined(CONFIG_BLK_DEV_INTEGRITY) */ - static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) { struct scst_cmd *cmd = p->cmd; u64 lba_start = scst_cmd_get_lba(cmd); - struct scst_device *dev = cmd->dev; - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - int block_shift = dev->block_shift; + struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; + int block_shift = cmd->dev->block_shift; struct block_device *bdev = virt_dev->bdev; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) struct bio_set *bs = virt_dev->vdisk_bioset; @@ -6413,21 +5318,11 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) struct blk_plug plug; #endif - struct scatterlist *dsg; - int dsg_offs, dsg_len; - bool dif = virt_dev->blk_integrity && - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE); TRACE_ENTRY(); WARN_ON(virt_dev->nullio); - if (dif) { - dsg = cmd->dif_sg; - dsg_offs = dsg->offset; - dsg_len = dsg->length; - } - /* Allocate and initialize blockio_work struct */ blockio_work = kmem_cache_alloc(blockio_work_cachep, gfp_mask); if (blockio_work == NULL) { @@ -6539,9 +5434,6 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) rc = bio_add_page(bio, pg, bytes, off); if (rc < bytes) { WARN_ON(rc != 0); - if (dif) - vdisk_blk_add_dif(bio, gfp_mask, dev, &dsg, - &dsg_offs, &dsg_len, false); need_new_bio = 1; lba_start0 += thislen >> block_shift; thislen = 0; @@ -6560,10 +5452,6 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) length = scst_get_sg_page_next(cmd, &page, &offset); } - if (dif) - vdisk_blk_add_dif(bio, gfp_mask, dev, &dsg, &dsg_offs, - &dsg_len, true); - /* +1 to prevent erroneous too early command completion */ atomic_set(&blockio_work->bios_inflight, bios+1); @@ -6575,7 +5463,6 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) bio = hbio; hbio = hbio->bi_next; bio->bi_next = NULL; - submit_bio((write != 0), bio); } @@ -6586,15 +5473,6 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) q->unplug_fn(q); #endif - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && - (virt_dev->dif_fd != NULL) && - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { - if (write) - vdev_write_dif_tags(p); - else - vdev_read_dif_tags(p); - } - blockio_check_finish(blockio_work); out: @@ -6920,7 +5798,6 @@ static enum compl_status_e vdev_exec_verify(struct vdisk_cmd_params *p) struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; uint8_t *mem_verify = NULL; int64_t data_len = scst_cmd_get_data_len(cmd); - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); TRACE_ENTRY(); @@ -6972,7 +5849,6 @@ static enum compl_status_e vdev_exec_verify(struct vdisk_cmd_params *p) scst_put_buf(cmd, address_sav); goto out_free; } - if (compare && memcmp(address, mem_verify, len_mem) != 0) { TRACE_DBG("Verify: error memcmp length %zd", length); scst_set_cmd_error(cmd, @@ -6980,11 +5856,6 @@ static enum compl_status_e vdev_exec_verify(struct vdisk_cmd_params *p) scst_put_buf(cmd, address_sav); goto out_free; } - - if (checks != 0) { - /* ToDo: check DIF tags as well */ - } - length -= len_mem; if (compare) address += len_mem; @@ -7145,7 +6016,6 @@ static enum compl_status_e fileio_exec_write_verify(struct vdisk_cmd_params *p) static enum compl_status_e nullio_exec_write_verify(struct vdisk_cmd_params *p) { - scst_dif_process_write(p->cmd); return CMD_SUCCEEDED; } @@ -7167,7 +6037,6 @@ static void vdisk_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd, dev->tmf_only = dev->tmf_only_saved; dev->d_sense = dev->d_sense_saved; - dev->dpicz = dev->dpicz_saved; dev->swp = dev->swp_saved; dev->tas = dev->tas_saved; dev->queue_alg = dev->queue_alg_saved; @@ -7251,18 +6120,6 @@ static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev) i += snprintf(&buf[i], buf_size - i, "%sTHIN_PROVISIONED", (j == i) ? "(" : ", "); - if (virt_dev->dif_mode != SCST_DIF_MODE_NONE) { - i += snprintf(&buf[i], buf_size - i, "%sDIF MODE %x, " - "DIF TYPE %d", (j == i) ? "(" : ", ", - virt_dev->dif_mode, virt_dev->dif_type); - if (virt_dev->dif_filename != NULL) - i += snprintf(&buf[i], buf_size - i, ", DIF FILENAME %s", - virt_dev->dif_filename); - else if (virt_dev->dif_static_app_tag_combined != SCST_DIF_NO_CHECK_APP_TAG) - i += snprintf(&buf[i], buf_size - i, ", DIF STATIC APP TAG %llx", - (long long)be64_to_cpu(virt_dev->dif_static_app_tag_combined)); - } - if (virt_dev->zero_copy) i += snprintf(&buf[i], buf_size - i, "%sZERO_COPY", (j == i) ? "(" : ", "); @@ -7335,25 +6192,10 @@ static int vdisk_create_bioset(struct scst_vdisk_dev *virt_dev) goto out; } - if (virt_dev->dif_mode & SCST_DIF_MODE_DEV) { - /* The same, pool size doesn't really matter */ - res = bioset_integrity_create(virt_dev->vdisk_bioset, 2); - if (res != 0) { - PRINT_ERROR("Failed to create integrity bioset " - "(dev %s)", virt_dev->name); - goto out_free; - } - } - res = 0; out: return res; - -out_free: - bioset_free(virt_dev->vdisk_bioset); - virt_dev->vdisk_bioset = NULL; - goto out; } static void vdisk_free_bioset(struct scst_vdisk_dev *virt_dev) @@ -7462,7 +6304,6 @@ static void vdev_destroy(struct scst_vdisk_dev *virt_dev) vdisk_free_bioset(virt_dev); #endif kfree(virt_dev->filename); - kfree(virt_dev->dif_filename); kfree(virt_dev); return; } @@ -7550,68 +6391,13 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, continue; } - if (!strcasecmp("dif_filename", p)) { - if (*pp != '/') { - PRINT_ERROR("DIF filename %s must be global " - "(device %s)", pp, virt_dev->name); - res = -EINVAL; - goto out; - } - - virt_dev->dif_filename = kstrdup(pp, GFP_KERNEL); - if (virt_dev->dif_filename == NULL) { - PRINT_ERROR("Unable to duplicate DIF filename %s " - "(device %s)", pp, virt_dev->name); - res = -ENOMEM; - goto out; - } - continue; - } - - if (!strcasecmp("dif_mode", p)) { - char *d = pp; - - while (1) { - char *dd; - - for (; (*d != '\0') && isspace(*d); d++) - ; - if (*d == '\0') - break; - - dd = strchr(d, '|'); - if (dd != NULL) - *dd = '\0'; - if (!strcasecmp(SCST_DIF_MODE_TGT_STR, d)) - virt_dev->dif_mode |= SCST_DIF_MODE_TGT; - else if (!strcasecmp(SCST_DIF_MODE_SCST_STR, d)) - virt_dev->dif_mode |= SCST_DIF_MODE_SCST; - else if (!strcasecmp(SCST_DIF_MODE_DEV_CHECK_STR, d)) { - virt_dev->dif_mode |= SCST_DIF_MODE_DEV_CHECK; - } else if (!strcasecmp(SCST_DIF_MODE_DEV_STORE_STR, d)) - virt_dev->dif_mode |= SCST_DIF_MODE_DEV_STORE; - else { - PRINT_ERROR("Error parsing DIF mode %s", pp); - res = -EINVAL; - goto out; - } - if (dd == NULL) - break; - else - *dd = '|'; - d = dd+1; - } - TRACE_DBG("DIF DEV mode %x", virt_dev->dif_mode); - continue; - } - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) res = kstrtoull(pp, 0, &val); #else res = strict_strtoull(pp, 0, &val); #endif if (res != 0) { - PRINT_ERROR("strtoull() for %s failed: %d (device %s)", + PRINT_ERROR("strtoul() for %s failed: %d (device %s)", pp, res, virt_dev->name); goto out; } @@ -7675,13 +6461,6 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, } TRACE_DBG("block size %lld, block shift %d", val, virt_dev->blk_shift); - } else if (!strcasecmp("dif_type", p)) { - virt_dev->dif_type = val; - TRACE_DBG("DIF type %d", virt_dev->dif_type); - } else if (!strcasecmp("dif_static_app_tag", p)) { - virt_dev->dif_static_app_tag_combined = cpu_to_be64(val); - TRACE_DBG("DIF static app tag %llx", - (long long)be64_to_cpu(virt_dev->dif_static_app_tag_combined)); } else { PRINT_ERROR("Unknown parameter %s (device %s)", p, virt_dev->name); @@ -7768,9 +6547,7 @@ static int vdev_blockio_add_device(const char *device_name, char *params) int res = 0; const char *const allowed_params[] = { "filename", "read_only", "write_through", "removable", "blocksize", "nv_cache", - "rotational", "thin_provisioned", "tst", - "dif_mode", "dif_type", "dif_static_app_tag", - "dif_filename", NULL }; + "rotational", "thin_provisioned", "tst", NULL }; struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -7834,7 +6611,6 @@ static int vdev_nullio_add_device(const char *device_name, char *params) int res = 0; static const char *const allowed_params[] = { "read_only", "dummy", "removable", "blocksize", "rotational", - "dif_mode", "dif_type", "dif_static_app_tag", "size", "size_mb", "tst", NULL }; struct scst_vdisk_dev *virt_dev; @@ -9457,26 +8233,6 @@ static ssize_t vdev_zero_copy_show(struct kobject *kobj, return pos; } -static ssize_t vdev_dif_filename_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_device *dev; - struct scst_vdisk_dev *virt_dev; - - TRACE_ENTRY(); - - dev = container_of(kobj, struct scst_device, dev_kobj); - virt_dev = dev->dh_priv; - - pos = sprintf(buf, "%s\n%s", virt_dev->dif_filename, - (virt_dev->dif_filename != NULL) ? - SCST_SYSFS_KEY_MARK "\n" : ""); - - TRACE_EXIT_RES(pos); - return pos; -} - #else /* CONFIG_SCST_PROC */ /* @@ -10239,8 +8995,6 @@ static int __init init_scst_vdisk_driver(void) { int res; - spin_lock_init(&vdev_err_lock); - init_ops(fileio_ops, ARRAY_SIZE(fileio_ops)); init_ops(blockio_ops, ARRAY_SIZE(blockio_ops)); init_ops(nullio_ops, ARRAY_SIZE(nullio_ops)); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index ec6b39b0d..669cafdb7 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -402,9 +400,7 @@ static int get_cdb_info_verify16(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); static int get_cdb_info_len_1(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_3_len_1_256_read(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_3_len_1_256_write(struct scst_cmd *cmd, +static int get_cdb_info_lba_3_len_1_256(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); static int get_cdb_info_bidi_lba_4_len_2(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); @@ -418,19 +414,13 @@ static int get_cdb_info_lba_2_none(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_read_10(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_4_len_2_wrprotect(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops); static int get_cdb_info_lba_4_none(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_4_len_4_rdprotect(struct scst_cmd *cmd, +static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_4_len_4_wrprotect(struct scst_cmd *cmd, +static int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_read_16(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops); -static int get_cdb_info_lba_8_len_4_wrprotect(struct scst_cmd *cmd, +static int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); static int get_cdb_info_lba_8_none(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); @@ -444,8 +434,6 @@ static int get_cdb_info_apt(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); static int get_cdb_info_min(struct scst_cmd *cmd, const struct scst_sdbops *sdbops); -static int get_cdb_info_var_len(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops); /* +=====================================-============-======- @@ -605,7 +593,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_EXCL_ALLOWED, .info_lba_off = 1, .info_lba_len = 3, .info_len_off = 4, .info_len_len = 1, - .get_cdb_info = get_cdb_info_lba_3_len_1_256_read}, + .get_cdb_info = get_cdb_info_lba_3_len_1_256}, {.ops = 0x08, .devkey = " MV O OV ", .info_op_name = "READ(6)", .info_data_direction = SCST_DATA_READ, @@ -635,7 +623,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_MEDIUM, .info_lba_off = 1, .info_lba_len = 3, .info_len_off = 4, .info_len_len = 1, - .get_cdb_info = get_cdb_info_lba_3_len_1_256_write}, + .get_cdb_info = get_cdb_info_lba_3_len_1_256}, {.ops = 0x0A, .devkey = " M O OV ", .info_op_name = "WRITE(6)", .info_data_direction = SCST_DATA_WRITE, @@ -832,7 +820,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_EXCL_ALLOWED, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 7, .info_len_len = 2, - .get_cdb_info = get_cdb_info_read_10}, + .get_cdb_info = get_cdb_info_lba_4_len_2}, {.ops = 0x28, .devkey = " O ", .info_op_name = "GET MESSAGE(10)", .info_data_direction = SCST_DATA_READ, @@ -855,7 +843,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 7, .info_len_len = 2, - .get_cdb_info = get_cdb_info_lba_4_len_2_wrprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_2}, {.ops = 0x2A, .devkey = " O ", .info_op_name = "SEND MESSAGE(10)", .info_data_direction = SCST_DATA_WRITE, @@ -900,7 +888,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 7, .info_len_len = 2, - .get_cdb_info = get_cdb_info_lba_4_len_2_wrprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_2}, {.ops = 0x2F, .devkey = "O OO O ", .info_op_name = "VERIFY(10)", .info_data_direction = SCST_DATA_UNKNOWN, @@ -1098,7 +1086,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { .info_op_flags = SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 7, .info_len_len = 2, - .get_cdb_info = get_cdb_info_lba_4_len_2_wrprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_2}, {.ops = 0x51, .devkey = " O ", .info_op_name = "READ DISC INFORMATION", .info_data_direction = SCST_DATA_READ, @@ -1199,13 +1187,6 @@ static const struct scst_sdbops scst_scsi_op_table[] = { .info_len_off = 5, .info_len_len = 4, .get_cdb_info = get_cdb_info_len_4}, - /* Variable length CDBs */ - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "VAR LEN CDB", - .info_data_direction = SCST_DATA_UNKNOWN, - .info_op_flags = 0, - .get_cdb_info = get_cdb_info_var_len}, - /* 16-bytes length CDB */ {.ops = 0x80, .devkey = " O ", .info_op_name = "WRITE FILEMARKS(16)", @@ -1264,7 +1245,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_EXCL_ALLOWED, .info_lba_off = 2, .info_lba_len = 8, .info_len_off = 10, .info_len_len = 4, - .get_cdb_info = get_cdb_info_read_16}, + .get_cdb_info = get_cdb_info_lba_8_len_4}, {.ops = 0x89, .devkey = "O ", .info_op_name = "COMPARE AND WRITE", .info_data_direction = SCST_DATA_WRITE, @@ -1283,7 +1264,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 8, .info_len_off = 10, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_8_len_4_wrprotect}, + .get_cdb_info = get_cdb_info_lba_8_len_4}, {.ops = 0x8C, .devkey = " OOOOOOOOO ", .info_op_name = "READ ATTRIBUTE", .info_data_direction = SCST_DATA_READ, @@ -1302,7 +1283,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 8, .info_len_off = 10, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_8_len_4_wrprotect}, + .get_cdb_info = get_cdb_info_lba_8_len_4}, {.ops = 0x8F, .devkey = "O OO O ", .info_op_name = "VERIFY(16)", .info_data_direction = SCST_DATA_UNKNOWN, @@ -1443,7 +1424,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_EXCL_ALLOWED, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 6, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_4_len_4_rdprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_4}, {.ops = 0xA9, .devkey = " O ", .info_op_name = "PLAY TRACK RELATIVE(12)", .info_data_direction = SCST_DATA_NONE, @@ -1459,7 +1440,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 6, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_4_len_4_wrprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_4}, {.ops = 0xAA, .devkey = " O ", .info_op_name = "SEND MESSAGE(12)", .info_data_direction = SCST_DATA_WRITE, @@ -1488,7 +1469,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = { .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM, .info_lba_off = 2, .info_lba_len = 4, .info_len_off = 6, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_4_len_4_wrprotect}, + .get_cdb_info = get_cdb_info_lba_4_len_4}, {.ops = 0xAF, .devkey = "O OO O ", .info_op_name = "VERIFY(12)", .info_data_direction = SCST_DATA_UNKNOWN, @@ -3225,39 +3206,24 @@ static void scst_adjust_sg(struct scst_cmd *cmd, bool reg_sg, { struct scatterlist *sg; int *sg_cnt; - bool adjust_dif; TRACE_ENTRY(); - EXTRACHECKS_BUG_ON(cmd->sg_buff_modified || cmd->dif_sg_buff_modified); + EXTRACHECKS_BUG_ON(cmd->sg_buff_modified); if (reg_sg) { sg = cmd->sg; sg_cnt = &cmd->sg_cnt; - adjust_dif = (cmd->dif_sg != NULL); } else { sg = *cmd->write_sg; sg_cnt = cmd->write_sg_cnt; - if (sg == cmd->sg) - adjust_dif = (cmd->dif_sg != NULL); - else - adjust_dif = false; } - TRACE_DBG("reg_sg %d, adjust_len %d, adjust_dif %d", reg_sg, - adjust_len, adjust_dif); + TRACE_DBG("reg_sg %d, adjust_len %d", reg_sg, adjust_len); - cmd->sg_buff_modified = !!__scst_adjust_sg(cmd, sg, sg_cnt, adjust_len, + cmd->sg_buff_modified = __scst_adjust_sg(cmd, sg, sg_cnt, adjust_len, &cmd->orig_sg); - if (adjust_dif) { - adjust_len >>= (cmd->dev->block_shift - SCST_DIF_TAG_SHIFT); - TRACE_DBG("DIF adjust_len %d", adjust_len); - cmd->dif_sg_buff_modified = __scst_adjust_sg(cmd, cmd->dif_sg, - &cmd->dif_sg_cnt, adjust_len, - &cmd->orig_dif_sg); - } - TRACE_EXIT(); return; } @@ -3269,16 +3235,13 @@ static void scst_adjust_sg(struct scst_cmd *cmd, bool reg_sg, */ void scst_restore_sg_buff(struct scst_cmd *cmd) { - TRACE_DBG_FLAG(TRACE_DEBUG|TRACE_MEMORY, "cmd %p, sg %p, DATA: " + TRACE_DBG_FLAG(TRACE_DEBUG|TRACE_MEMORY, "cmd %p, sg %p, " "orig_sg_entry %p, orig_entry_offs %d, orig_entry_len %d, " - "orig_sg_cnt %d, DIF: orig_sg_entry %p, " - "orig_entry_offs %d, orig_entry_len %d, orig_sg_cnt %d", cmd, - cmd->sg, cmd->orig_sg.orig_sg_entry, cmd->orig_sg.orig_entry_offs, - cmd->orig_sg.orig_entry_len, cmd->orig_sg.orig_sg_cnt, - cmd->orig_dif_sg.orig_sg_entry, cmd->orig_dif_sg.orig_entry_offs, - cmd->orig_dif_sg.orig_entry_len, cmd->orig_dif_sg.orig_sg_cnt); + "orig_sg_cnt %d", cmd, cmd->sg, cmd->orig_sg.orig_sg_entry, + cmd->orig_sg.orig_entry_offs, cmd->orig_sg.orig_entry_len, + cmd->orig_sg.orig_sg_cnt); - EXTRACHECKS_BUG_ON(!(cmd->sg_buff_modified || cmd->dif_sg_buff_modified)); + EXTRACHECKS_BUG_ON(!cmd->sg_buff_modified); if (cmd->sg_buff_modified) { cmd->orig_sg.orig_sg_entry->offset = cmd->orig_sg.orig_entry_offs; @@ -3286,14 +3249,7 @@ void scst_restore_sg_buff(struct scst_cmd *cmd) *cmd->orig_sg.p_orig_sg_cnt = cmd->orig_sg.orig_sg_cnt; } - if (cmd->dif_sg_buff_modified) { - cmd->orig_dif_sg.orig_sg_entry->offset = cmd->orig_dif_sg.orig_entry_offs; - cmd->orig_dif_sg.orig_sg_entry->length = cmd->orig_dif_sg.orig_entry_len; - *cmd->orig_dif_sg.p_orig_sg_cnt = cmd->orig_dif_sg.orig_sg_cnt; - } - cmd->sg_buff_modified = 0; - cmd->dif_sg_buff_modified = 0; } EXPORT_SYMBOL(scst_restore_sg_buff); @@ -3354,71 +3310,6 @@ void scst_limit_sg_write_len(struct scst_cmd *cmd) return; } -static int scst_full_len_to_data_len(int full_len, int block_shift) -{ - int rem, res; - - res = full_len << block_shift; - rem = do_div(res, (1 << block_shift) + (1 << SCST_DIF_TAG_SHIFT)); - if (unlikely(rem != 0)) - TRACE(TRACE_MINOR, "Reminder %d for full len! (full len%d)", - rem, full_len); - - TRACE_DBG("data len %d (full %d)", res, full_len); - - return res; -} - -/* - * Returns data expected transfer length, i.e. expected transfer length, - * adjusted on DIF tags expected transfer length, if any. - * - * Very expensive, don't call on fast path! - */ -int scst_cmd_get_expected_transfer_len_data(struct scst_cmd *cmd) -{ - int rem, res; - - if (!cmd->tgt_dif_data_expected) - return cmd->expected_transfer_len_full; - - res = cmd->expected_transfer_len_full << cmd->dev->block_shift; - rem = do_div(res, cmd->dev->block_size + (1 << SCST_DIF_TAG_SHIFT)); - if (unlikely(rem != 0)) - TRACE(TRACE_MINOR, "Reminder %d for expected transfer len " - "data! (cmd %p, op %s, expected len full %d)", rem, - cmd, scst_get_opcode_name(cmd), - cmd->expected_transfer_len_full); - - TRACE_DBG("Expected transfer len data %d (cmd %p)", res, cmd); - - return res; -} - -/* - * Returns DIF tags expected transfer length. - * - * Very expensive, don't call on fast path! - */ -int scst_cmd_get_expected_transfer_len_dif(struct scst_cmd *cmd) -{ - int rem, res; - - if (!cmd->tgt_dif_data_expected) - return 0; - - res = cmd->expected_transfer_len_full << SCST_DIF_TAG_SHIFT; - rem = do_div(res, cmd->dev->block_size + (1 << SCST_DIF_TAG_SHIFT)); - if (unlikely(rem != 0)) - TRACE(TRACE_MINOR, "Reminder %d for expected transfer len dif! " - "(cmd %p, op %s, expected len full %d)", rem, cmd, - scst_get_opcode_name(cmd), cmd->expected_transfer_len_full); - - TRACE_DBG("Expected transfer len DIF %d (cmd %p)", res, cmd); - - return res; -} - void scst_adjust_resp_data_len(struct scst_cmd *cmd) { TRACE_ENTRY(); @@ -3429,7 +3320,7 @@ void scst_adjust_resp_data_len(struct scst_cmd *cmd) } cmd->adjusted_resp_data_len = min(cmd->resp_data_len, - scst_cmd_get_expected_transfer_len_data(cmd)); + cmd->expected_transfer_len); if (cmd->adjusted_resp_data_len != cmd->resp_data_len) { TRACE_MEM("Adjusting resp_data_len to %d (cmd %p, sg %p, " @@ -3474,10 +3365,7 @@ void scst_cmd_set_write_not_received_data_len(struct scst_cmd *cmd, if (cmd->write_len == cmd->out_bufflen) goto out; } else if (cmd->expected_data_direction & SCST_DATA_WRITE) { - cmd->write_len = cmd->expected_transfer_len_full - not_received; - if (cmd->tgt_dif_data_expected) - cmd->write_len = scst_full_len_to_data_len(cmd->write_len, - cmd->dev->block_shift); + cmd->write_len = cmd->expected_transfer_len - not_received; if (cmd->write_len == cmd->bufflen) goto out; } @@ -3512,7 +3400,7 @@ void scst_cmd_set_write_no_data_received(struct scst_cmd *cmd) (cmd->expected_data_direction & SCST_DATA_WRITE)) w = cmd->expected_out_transfer_len; else - w = cmd->expected_transfer_len_full; + w = cmd->expected_transfer_len; scst_cmd_set_write_not_received_data_len(cmd, w); @@ -3549,10 +3437,7 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) } if (cmd->expected_data_direction & SCST_DATA_READ) { - int resp = cmd->resp_data_len; - if (cmd->tgt_dif_data_expected) - resp += (resp >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - *resid = cmd->expected_transfer_len_full - resp; + *resid = cmd->expected_transfer_len - cmd->resp_data_len; if ((cmd->expected_data_direction & SCST_DATA_WRITE) && bidi_out_resid) { if (cmd->write_len < cmd->expected_out_transfer_len) *bidi_out_resid = cmd->expected_out_transfer_len - @@ -3561,34 +3446,18 @@ bool __scst_get_resid(struct scst_cmd *cmd, int *resid, int *bidi_out_resid) *bidi_out_resid = cmd->write_len - cmd->out_bufflen; } } else if (cmd->expected_data_direction & SCST_DATA_WRITE) { - int wl = cmd->write_len; - if (cmd->tgt_dif_data_expected) - wl += (wl >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - if (wl < cmd->expected_transfer_len_full) - *resid = cmd->expected_transfer_len_full - wl; - else { + if (cmd->write_len < cmd->expected_transfer_len) + *resid = cmd->expected_transfer_len - cmd->write_len; + else *resid = cmd->write_len - cmd->bufflen; - if (cmd->tgt_dif_data_expected) { - int r = *resid; - if (r < 0) - r = -r; - r += (r >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - if (*resid > 0) - *resid = r; - else - *resid = -r; - } - } } res = true; TRACE_DBG("cmd %p, resid %d, bidi_out_resid %d (resp_data_len %d, " - "expected_data_direction %d, write_len %d, bufflen %d, " - "tgt_dif_data_expected %d)", cmd, *resid, - bidi_out_resid ? *bidi_out_resid : 0, cmd->resp_data_len, - cmd->expected_data_direction, cmd->write_len, cmd->bufflen, - cmd->tgt_dif_data_expected); + "expected_data_direction %d, write_len %d, bufflen %d)", cmd, + *resid, bidi_out_resid ? *bidi_out_resid : 0, cmd->resp_data_len, + cmd->expected_data_direction, cmd->write_len, cmd->bufflen); out: TRACE_EXIT_RES(res); @@ -3852,27 +3721,11 @@ int scst_alloc_tgt(struct scst_tgt_template *tgtt, struct scst_tgt **tgt) init_waitqueue_head(&t->unreg_waitQ); t->tgtt = tgtt; t->sg_tablesize = tgtt->sg_tablesize; - t->tgt_dif_supported = tgtt->dif_supported; - t->tgt_hw_dif_type1_supported = tgtt->hw_dif_type1_supported; - t->tgt_hw_dif_type2_supported = tgtt->hw_dif_type2_supported; - t->tgt_hw_dif_type3_supported = tgtt->hw_dif_type3_supported; - t->tgt_hw_dif_ip_supported = tgtt->hw_dif_ip_supported; - t->tgt_hw_dif_same_sg_layout_required = tgtt->hw_dif_same_sg_layout_required; - t->tgt_supported_dif_block_sizes = tgtt->supported_dif_block_sizes; spin_lock_init(&t->tgt_lock); INIT_LIST_HEAD(&t->retry_cmd_list); init_timer(&t->retry_timer); t->retry_timer.data = (unsigned long)t; t->retry_timer.function = scst_tgt_retry_timer_fn; - atomic_set(&t->tgt_dif_app_failed_tgt, 0); - atomic_set(&t->tgt_dif_ref_failed_tgt, 0); - atomic_set(&t->tgt_dif_guard_failed_tgt, 0); - atomic_set(&t->tgt_dif_app_failed_scst, 0); - atomic_set(&t->tgt_dif_ref_failed_scst, 0); - atomic_set(&t->tgt_dif_guard_failed_scst, 0); - atomic_set(&t->tgt_dif_app_failed_dev, 0); - atomic_set(&t->tgt_dif_ref_failed_dev, 0); - atomic_set(&t->tgt_dif_guard_failed_dev, 0); #ifdef CONFIG_SCST_PROC res = gen_relative_target_port_id(&t->rel_tgt_id); @@ -3923,13 +3776,6 @@ static void scst_init_order_data(struct scst_order_data *order_data) return; } -static int scst_dif_none(struct scst_cmd *cmd); -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS -static int scst_dif_none_type1(struct scst_cmd *cmd); -#else -#define scst_dif_none_type1 scst_dif_none -#endif - /* Called under scst_mutex and suspended activity */ int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev) { @@ -3965,11 +3811,6 @@ int scst_alloc_device(gfp_t gfp_mask, struct scst_device **out_dev) dev->pr_type = TYPE_UNSPECIFIED; INIT_LIST_HEAD(&dev->dev_registrants_list); - BUILD_BUG_ON(SCST_DIF_NO_CHECK_APP_TAG != 0); - dev->dev_dif_static_app_tag = SCST_DIF_NO_CHECK_APP_TAG; - dev->dev_dif_static_app_ref_tag = SCST_DIF_NO_CHECK_APP_TAG; - dev->dev_dif_fn = scst_dif_none; - scst_init_order_data(&dev->dev_order_data); scst_init_threads(&dev->dev_cmd_threads); @@ -4086,82 +3927,12 @@ static void scst_del_free_acg_dev(struct scst_acg_dev *acg_dev, bool del_sysfs) return; } -static int scst_check_dif_compatibility(const struct scst_acg *acg, - const struct scst_device *dev) -{ - int res = -EINVAL; - struct scst_tgt *tgt; - const int *p; - bool supported; - - TRACE_ENTRY(); - - if (dev->dev_dif_mode == SCST_DIF_MODE_NONE) - goto out_ok; - - tgt = acg->tgt; - - if (!tgt->tgt_dif_supported) { - PRINT_ERROR("Target %s doesn't support T10-PI (device %s)", - tgt->tgt_name, dev->virt_name); - goto out; - } - - if (dev->dev_dif_mode & SCST_DIF_MODE_TGT) { - if ((dev->dev_dif_type == 1) && !tgt->tgt_hw_dif_type1_supported) { - PRINT_ERROR("Target %s doesn't support type 1 " - "protection TGT mode (device %s)", tgt->tgt_name, - dev->virt_name); - goto out; - } - - if ((dev->dev_dif_type == 2) && !tgt->tgt_hw_dif_type2_supported) { - PRINT_ERROR("Target %s doesn't support type 2 " - "protection TGT mode (device %s)", tgt->tgt_name, - dev->virt_name); - goto out; - } - - if ((dev->dev_dif_type == 3) && !tgt->tgt_hw_dif_type3_supported) { - PRINT_ERROR("Target %s doesn't support type 3 " - "protection TGT mode (device %s)", tgt->tgt_name, - dev->virt_name); - goto out; - } - } - - if (tgt->tgt_supported_dif_block_sizes == NULL) - goto out_ok; - - p = tgt->tgt_supported_dif_block_sizes; - supported = false; - while (*p != 0) { - if (*p == dev->block_size) { - supported = true; - break; - } - p++; - } - if (!supported) { - PRINT_ERROR("Target %s doesn't support block size %d of " - "device %s", tgt->tgt_name, dev->block_size, dev->virt_name); - goto out; - } - -out_ok: - res = 0; - -out: - TRACE_EXIT_RES(res); - return res; -} - /* The activity supposed to be suspended and scst_mutex held */ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent, struct scst_device *dev, uint64_t lun, int read_only, bool gen_scst_report_luns_changed, struct scst_acg_dev **out_acg_dev) { - int res; + int res = 0; struct scst_acg_dev *acg_dev; struct scst_tgt_dev *tgt_dev; struct scst_session *sess; @@ -4171,24 +3942,12 @@ int scst_acg_add_lun(struct scst_acg *acg, struct kobject *parent, INIT_LIST_HEAD(&tmp_tgt_dev_list); - res = scst_check_dif_compatibility(acg, dev); - if (res != 0) - goto out; - acg_dev = scst_alloc_acg_dev(acg, dev, lun); if (acg_dev == NULL) { res = -ENOMEM; goto out; } acg_dev->acg_dev_rd_only = read_only; - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) { - /* Devices are allowed to store only CRCs */ - acg_dev->acg_dev_dif_guard_format = SCST_DIF_GUARD_FORMAT_CRC; - } else - acg_dev->acg_dev_dif_guard_format = - acg->tgt->tgt_hw_dif_ip_supported && !dev->dev_dif_ip_not_supported ? - SCST_DIF_GUARD_FORMAT_IP : - SCST_DIF_GUARD_FORMAT_CRC; TRACE_DBG("Adding acg_dev %p to acg_dev_list and dev_acg_dev_list", acg_dev); @@ -4825,9 +4584,6 @@ out_deinit: return; } -static __be16 scst_dif_crc_fn(const void *data, unsigned int len); -static __be16 scst_dif_ip_fn(const void *data, unsigned int len); - /* * scst_mutex supposed to be held, there must not be parallel activity in this * session. May be invoked from inside scst_check_reassign_sessions() which @@ -4858,24 +4614,6 @@ static int scst_alloc_add_tgt_dev(struct scst_session *sess, tgt_dev->lun = acg_dev->lun; tgt_dev->acg_dev = acg_dev; tgt_dev->tgt_dev_rd_only = acg_dev->acg_dev_rd_only || dev->dev_rd_only; - tgt_dev->hw_dif_same_sg_layout_required = sess->tgt->tgt_hw_dif_same_sg_layout_required; - tgt_dev->tgt_dev_dif_guard_format = acg_dev->acg_dev_dif_guard_format; - if (tgt_dev->tgt_dev_dif_guard_format == SCST_DIF_GUARD_FORMAT_IP) - tgt_dev->tgt_dev_dif_crc_fn = scst_dif_ip_fn; - else { - EXTRACHECKS_BUG_ON(tgt_dev->tgt_dev_dif_guard_format != SCST_DIF_GUARD_FORMAT_CRC); - tgt_dev->tgt_dev_dif_crc_fn = scst_dif_crc_fn; - } - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_dev, 0); - tgt_dev->sess = sess; atomic_set(&tgt_dev->tgt_dev_cmd_count, 0); if (acg_dev->acg->acg_black_hole_type != SCST_ACG_BLACK_HOLE_NONE) @@ -4898,9 +4636,7 @@ static int scst_alloc_add_tgt_dev(struct scst_session *sess, tgt_dev->max_sg_cnt = min(ini_sg, sess->tgt->sg_tablesize); if ((sess->tgt->tgtt->use_clustering || ini_use_clustering) && - !sess->tgt->tgtt->no_clustering && - !(sess->tgt->tgt_hw_dif_same_sg_layout_required && - (tgt_dev->dev->dev_dif_type != 0))) + !sess->tgt->tgtt->no_clustering) scst_sgv_pool_use_norm_clust(tgt_dev); if (sess->tgt->tgtt->unchecked_isa_dma || ini_unchecked_isa_dma) @@ -5316,24 +5052,6 @@ out: return res; } -static void scst_prelim_finish_internal_cmd(struct scst_cmd *cmd) -{ - unsigned long flags; - - TRACE_ENTRY(); - - sBUG_ON(!cmd->internal); - - spin_lock_irqsave(&cmd->sess->sess_list_lock, flags); - list_del(&cmd->sess_cmd_list_entry); - spin_unlock_irqrestore(&cmd->sess->sess_list_lock, flags); - - __scst_cmd_put(cmd); - - TRACE_EXIT(); - return; -} - int scst_prepare_request_sense(struct scst_cmd *orig_cmd) { int res = 0; @@ -5361,7 +5079,7 @@ int scst_prepare_request_sense(struct scst_cmd *orig_cmd) rs_cmd->cdb[1] |= scst_get_cmd_dev_d_sense(orig_cmd); rs_cmd->expected_data_direction = SCST_DATA_READ; - rs_cmd->expected_transfer_len_full = SCST_SENSE_BUFFERSIZE; + rs_cmd->expected_transfer_len = SCST_SENSE_BUFFERSIZE; rs_cmd->expected_values_set = 1; TRACE_MGMT_DBG("Adding REQUEST SENSE cmd %p to head of active " @@ -5440,12 +5158,6 @@ struct scst_write_same_priv { int64_t ws_cur_lba; /* in blocks */ int ws_left_to_send; /* in blocks */ - __be16 guard_tag; - __be16 app_tag; - uint32_t ref_tag; - unsigned int dif_valid:1; - unsigned int inc_ref_tag:1; - int ws_max_each;/* in blocks */ int ws_cur_in_flight; @@ -5458,14 +5170,11 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, int64_t lba, int blocks) { struct scst_cmd *ws_cmd = wsp->ws_orig_cmd; - struct scst_device *dev = ws_cmd->dev; struct scatterlist *ws_sg = wsp->ws_sg; int res; - uint8_t write_cdb[32]; - int write_cdb_len; + uint8_t write16_cdb[16]; int len = blocks << ws_cmd->dev->block_shift; struct scst_cmd *cmd; - bool needs_dif = wsp->dif_valid; TRACE_ENTRY(); @@ -5480,98 +5189,24 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, goto out; } - if (!needs_dif || (dev->dev_dif_type != 2)) { - memset(write_cdb, 0, sizeof(write_cdb)); - write_cdb[0] = WRITE_16; - write_cdb_len = 16; - write_cdb[1] = ws_cmd->cdb[1]; - if (needs_dif) { - uint8_t wrprotect = ws_cmd->cdb[1] & 0xE0; - if (wrprotect == 0) - wrprotect = 0x20; - write_cdb[1] |= wrprotect; - } - put_unaligned_be64(lba, &write_cdb[2]); - put_unaligned_be32(blocks, &write_cdb[10]); - } else { - /* There might be WRITE SAME(16) with WRPROTECT 0 here */ - uint8_t wrprotect; - if (ws_cmd->cdb_len != 32) - wrprotect = ws_cmd->cdb[1] & 0xE0; - else - wrprotect = ws_cmd->cdb[10] & 0xE0; - if (wrprotect == 0) - wrprotect = 0x20; - write_cdb[0] = VARIABLE_LENGTH_CMD; - put_unaligned_be16(SUBCODE_WRITE_32, &write_cdb[8]); - write_cdb[7] = 0x18; - write_cdb_len = 32; - write_cdb[10] = ws_cmd->cdb[10]; - write_cdb[10] |= wrprotect; - put_unaligned_be64(lba, &write_cdb[12]); - put_unaligned_be32(blocks, &write_cdb[28]); - put_unaligned_be32(wsp->ref_tag, &write_cdb[20]); - put_unaligned(wsp->app_tag, &write_cdb[24]); - write_cdb[26] = ws_cmd->cdb[26]; - write_cdb[27] = ws_cmd->cdb[27]; - } + memset(write16_cdb, 0, sizeof(write16_cdb)); + write16_cdb[0] = WRITE_16; + put_unaligned_be64(lba, &write16_cdb[2]); + put_unaligned_be32(blocks, &write16_cdb[10]); - cmd = scst_create_prepare_internal_cmd(ws_cmd, write_cdb, - write_cdb_len, SCST_CMD_QUEUE_SIMPLE); + cmd = scst_create_prepare_internal_cmd(ws_cmd, write16_cdb, + sizeof(write16_cdb), SCST_CMD_QUEUE_SIMPLE); if (cmd == NULL) { res = -ENOMEM; goto out_busy; } cmd->expected_data_direction = SCST_DATA_WRITE; - cmd->expected_transfer_len_full = len; + cmd->expected_transfer_len = len; cmd->expected_values_set = 1; cmd->tgt_i_priv = wsp; - if (needs_dif) { - struct scatterlist *dif_sg, *s; - struct sgv_pool_obj *dif_sgv = NULL; - int dif_bufflen, i, dif_sg_cnt = 0; - - TRACE_DBG("Allocating and filling DIF buff for cmd %p " - "(ws_cmd %p)", cmd, ws_cmd); - - dif_bufflen = blocks << SCST_DIF_TAG_SHIFT; - cmd->expected_transfer_len_full += dif_bufflen; - - dif_sg = sgv_pool_alloc(ws_cmd->tgt_dev->pool, - dif_bufflen, GFP_KERNEL, 0, &dif_sg_cnt, &dif_sgv, - &cmd->dev->dev_mem_lim, NULL); - if (unlikely(dif_sg == NULL)) { - TRACE(TRACE_OUT_OF_MEM, "Unable to alloc DIF sg " - "for %d blocks", blocks); - res = -ENOMEM; - goto out_free_cmd; - } - cmd->out_sgv = dif_sgv; /* hacky, but it isn't used for WRITE(16/32) */ - cmd->tgt_i_dif_sg = dif_sg; - cmd->tgt_i_dif_sg_cnt = dif_sg_cnt; - - TRACE_DBG("dif_sg %p, cnt %d", dif_sg, dif_sg_cnt); - - for_each_sg(dif_sg, s, dif_sg_cnt, i) { - int left = (s->length - s->offset) >> SCST_DIF_TAG_SHIFT; - struct scst_dif_tuple *t = sg_virt(s); - TRACE_DBG("sg %p, offset %d, length %d, left %d", s, - s->offset, s->length, left); - while (left > 0) { - t->app_tag = wsp->app_tag; - t->ref_tag = cpu_to_be32(wsp->ref_tag); - if (wsp->inc_ref_tag) - wsp->ref_tag++; - t->guard_tag = wsp->guard_tag; - t++; - left--; - } - } - } - cmd->tgt_i_sg = ws_sg; cmd->tgt_i_sg_cnt = blocks; cmd->tgt_i_data_buf_alloced = 1; @@ -5591,9 +5226,6 @@ out: TRACE_EXIT_RES(res); return res; -out_free_cmd: - scst_prelim_finish_internal_cmd(cmd); - out_busy: scst_set_busy(ws_cmd); goto out; @@ -5631,9 +5263,6 @@ static void scst_ws_write_cmd_finished(struct scst_cmd *cmd) TRACE_DBG("Write cmd %p finished (ws cmd %p, ws_cur_in_flight %d)", cmd, ws_cmd, wsp->ws_cur_in_flight); - if (cmd->out_sgv != NULL) - sgv_pool_free(cmd->out_sgv, &cmd->dev->dev_mem_lim); - cmd->sg = NULL; cmd->sg_cnt = 0; @@ -5737,8 +5366,7 @@ out_err: void scst_write_same(struct scst_cmd *cmd) { struct scst_write_same_priv *wsp; - int i, rc; - uint8_t ctrl_offs = (cmd->cdb_len < 32) ? 1 : 10; + int i; TRACE_ENTRY(); @@ -5754,10 +5382,10 @@ void scst_write_same(struct scst_cmd *cmd) goto out_done; } - if (unlikely((cmd->cdb[ctrl_offs] & 0x6) != 0)) { + if (unlikely((cmd->cdb[1] & 0x6) != 0)) { TRACE(TRACE_MINOR, "LBDATA and/or PBDATA (ctrl %x) are not " - "supported", cmd->cdb[ctrl_offs]); - scst_set_invalid_field_in_cdb(cmd, ctrl_offs, + "supported", cmd->cdb[1]); + scst_set_invalid_field_in_cdb(cmd, 1, SCST_INVAL_FIELD_BIT_OFFS_VALID | 1); goto out_done; } @@ -5770,10 +5398,6 @@ void scst_write_same(struct scst_cmd *cmd) goto out_done; } - rc = scst_dif_process_write(cmd); - if (unlikely(rc != 0)) - goto out_done; - wsp = kzalloc(sizeof(*wsp), GFP_KERNEL); if (wsp == NULL) { PRINT_ERROR("Unable to allocate ws_priv (size %zd, cmd %p)", @@ -5802,34 +5426,6 @@ void scst_write_same(struct scst_cmd *cmd) cmd->sg->length, cmd->sg->offset); } - if (scst_cmd_needs_dif_buf(cmd)) { - struct scst_dif_tuple *t; - struct scatterlist *tags_sg = NULL; - int tags_len = 0; - - t = (struct scst_dif_tuple *)scst_get_dif_buf(cmd, &tags_sg, &tags_len); - - wsp->app_tag = t->app_tag; - wsp->ref_tag = be32_to_cpu(t->ref_tag); - wsp->guard_tag = t->guard_tag; - wsp->dif_valid = 1; - - switch (cmd->dev->dev_dif_type) { - case 1: - case 2: - wsp->inc_ref_tag = 1; - break; - case 3: - wsp->inc_ref_tag = 0; - break; - default: - sBUG_ON(1); - break; - } - - scst_put_dif_buf(cmd, t); - } - scst_ws_gen_writes(wsp); out: @@ -6525,29 +6121,6 @@ failed: goto out; } -static void scst_restore_dif_sg(struct scst_cmd *cmd) -{ - int left = cmd->bufflen; - struct scatterlist *sg = cmd->dif_sg; - - TRACE_ENTRY(); - - if (!cmd->dif_sg_normalized) - goto out; - - do { - sg->length = min_t(int, PAGE_SIZE, left); - left -= sg->length; - TRACE_DBG("DIF sg %p, restored len %d (left %d)", sg, - sg->length, left); - sg = __sg_next_inline(sg); - } while (left > 0); - -out: - TRACE_EXIT(); - return; -} - int scst_alloc_space(struct scst_cmd *cmd) { gfp_t gfp_mask; @@ -6573,42 +6146,6 @@ int scst_alloc_space(struct scst_cmd *cmd) if (!scst_on_sg_tablesize_low(cmd, false)) goto out_sg_free; - if ((scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE) || - (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { - int dif_bufflen; - bool same_layout; - - same_layout = tgt_dev->hw_dif_same_sg_layout_required; - if (!same_layout) - dif_bufflen = __scst_cmd_get_bufflen_dif(cmd); - else - dif_bufflen = cmd->bufflen; - - cmd->dif_sg = sgv_pool_alloc(tgt_dev->pool, dif_bufflen, gfp_mask, flags, - &cmd->dif_sg_cnt, &cmd->dif_sgv, &cmd->dev->dev_mem_lim, NULL); - if (unlikely(cmd->dif_sg == NULL)) - goto out_sg_free; - - if (same_layout) { - int left = dif_bufflen; - struct scatterlist *sgd = cmd->sg; - struct scatterlist *sgt = cmd->dif_sg; - int block_shift = cmd->dev->block_shift; - - EXTRACHECKS_BUG_ON(left != cmd->bufflen); - - do { - left -= sgt->length; - sgt->length = (sgd->length >> block_shift) << SCST_DIF_TAG_SHIFT; - TRACE_SG("sgt %p, new len %d", sgt, sgt->length); - sgd = __sg_next_inline(sgd); - sgt = __sg_next_inline(sgt); - } while (left > 0); - - cmd->dif_sg_normalized = 1; - } - } - if (cmd->data_direction != SCST_DATA_BIDI) goto success; @@ -6616,7 +6153,7 @@ int scst_alloc_space(struct scst_cmd *cmd) flags, &cmd->out_sg_cnt, &cmd->out_sgv, &cmd->dev->dev_mem_lim, NULL); if (unlikely(cmd->out_sg == NULL)) - goto out_dif_sg_free; + goto out_sg_free; if (unlikely(cmd->out_sg_cnt > tgt_dev->max_sg_cnt)) if (!scst_on_sg_tablesize_low(cmd, true)) @@ -6635,15 +6172,6 @@ out_out_sg_free: cmd->out_sg = NULL; cmd->out_sg_cnt = 0; -out_dif_sg_free: - if (cmd->dif_sgv != NULL) { - scst_restore_dif_sg(cmd); - sgv_pool_free(cmd->dif_sgv, &cmd->dev->dev_mem_lim); - cmd->dif_sgv = NULL; - cmd->dif_sg = NULL; - cmd->dif_sg_cnt = 0; - } - out_sg_free: sgv_pool_free(cmd->sgv, &cmd->dev->dev_mem_lim); cmd->sgv = NULL; @@ -6680,20 +6208,12 @@ static void scst_release_space(struct scst_cmd *cmd) cmd->out_bufflen = 0; } - if (cmd->dif_sgv != NULL) { - scst_restore_dif_sg(cmd); - sgv_pool_free(cmd->dif_sgv, &cmd->dev->dev_mem_lim); - } - sgv_pool_free(cmd->sgv, &cmd->dev->dev_mem_lim); out_zero: cmd->sgv = NULL; cmd->sg_cnt = 0; cmd->sg = NULL; - cmd->dif_sgv = NULL; - cmd->dif_sg = NULL; - cmd->dif_sg_cnt = 0; cmd->bufflen = 0; cmd->data_len = 0; @@ -7353,15 +6873,13 @@ EXPORT_SYMBOL(scst_scsi_exec_async); /** * scst_copy_sg() - copy data between the command's SGs * - * Copies data between cmd->tgt_i_sg and cmd->sg as well as - * cmd->tgt_i_dif_sg and cmd->dif_sg in direction defined by + * Copies data between cmd->tgt_i_sg and cmd->sg in direction defined by * copy_dir parameter. */ void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir copy_dir) { struct scatterlist *src_sg, *dst_sg; - struct scatterlist *src_sg_dif, *dst_sg_dif; - unsigned int to_copy, to_copy_dif; + unsigned int to_copy; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) int atomic = scst_cmd_atomic(cmd); #endif @@ -7373,31 +6891,20 @@ void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir copy_dir) src_sg = cmd->tgt_i_sg; dst_sg = cmd->sg; to_copy = cmd->bufflen; - src_sg_dif = cmd->tgt_i_dif_sg; - dst_sg_dif = cmd->dif_sg; - to_copy_dif = scst_cmd_get_bufflen_dif(cmd); } else { TRACE_MEM("BIDI cmd %p", cmd); src_sg = cmd->tgt_out_sg; dst_sg = cmd->out_sg; to_copy = cmd->out_bufflen; - src_sg_dif = NULL; - dst_sg_dif = NULL; - to_copy_dif = 0; } } else { src_sg = cmd->sg; dst_sg = cmd->tgt_i_sg; to_copy = cmd->adjusted_resp_data_len; - src_sg_dif = cmd->dif_sg; - dst_sg_dif = cmd->tgt_i_dif_sg; - to_copy_dif = scst_cmd_get_bufflen_dif(cmd); } - TRACE_MEM("cmd %p, copy_dir %d, src_sg %p, dst_sg %p, to_copy %lld, " - "src_sg_dif %p, dst_sg_dif %p, to_copy_dif %lld", - cmd, copy_dir, src_sg, dst_sg, (long long)to_copy, - src_sg_dif, dst_sg_dif, (long long)to_copy_dif); + TRACE_MEM("cmd %p, copy_dir %d, src_sg %p, dst_sg %p, to_copy %lld", + cmd, copy_dir, src_sg, dst_sg, (long long)to_copy); if (unlikely(src_sg == NULL) || unlikely(dst_sg == NULL) || unlikely(to_copy == 0)) { @@ -7416,17 +6923,6 @@ void scst_copy_sg(struct scst_cmd *cmd, enum scst_sg_copy_dir copy_dir) sg_copy(dst_sg, src_sg, 0, to_copy); #endif - if ((src_sg_dif == NULL) || (dst_sg_dif == NULL) || (to_copy_dif == 0)) - goto out; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) - sg_copy(dst_sg_dif, src_sg_dif, 0, to_copy_dif, - atomic ? KM_SOFTIRQ0 : KM_USER0, - atomic ? KM_SOFTIRQ1 : KM_USER1); -#else - sg_copy(dst_sg_dif, src_sg_dif, 0, to_copy_dif); -#endif - out: TRACE_EXIT(); return; @@ -7577,1835 +7073,10 @@ out: } EXPORT_SYMBOL(scst_put_buf_full); -static __be16 scst_dif_crc_fn(const void *data, unsigned int len) -{ - return cpu_to_be16(crc_t10dif(data, len)); -} - -static __be16 scst_dif_ip_fn(const void *data, unsigned int len) -{ - return (__force __be16)ip_compute_csum(data, len); -} - -static int scst_verify_dif_type1(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - const struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - uint64_t lba = cmd->lba; - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 1); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_STRIP: - case SCST_DIF_ACTION_PASS_CHECK: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } - EXTRACHECKS_BUG_ON(checks == SCST_DIF_ACTION_NONE); -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - for (i = 0; i < (len >> block_shift); i++) { - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - TRACE_DBG("tags_buf %p", tags_buf); - TRACE_BUFF_FLAG(TRACE_DEBUG, "Tags to verify", - tags_buf, tags_len); - t = (struct scst_dif_tuple *)tags_buf; - } - - if (t->app_tag == SCST_DIF_NO_CHECK_ALL_APP_TAG) { - TRACE_DBG("Skipping tag %lld (cmd %p)", - (long long)lba, cmd); - goto next; - } - - if (checks & SCST_DIF_CHECK_APP_TAG) { - if (t->app_tag != dev->dev_dif_static_app_tag) { - PRINT_WARNING("APP TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), lba %lld, " - "dev %s)", dev->dev_dif_static_app_tag, - t->app_tag, cmd, scst_get_opcode_name(cmd), - (long long)lba, dev->virt_name); - scst_dif_acc_app_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_app_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - if (checks & SCST_DIF_CHECK_REF_TAG) { - if (t->ref_tag != cpu_to_be32(lba & 0xFFFFFFFF)) { - PRINT_WARNING("REF TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), lba %lld, " - "dev %s)", cpu_to_be32(lba & 0xFFFFFFFF), - t->ref_tag, cmd, scst_get_opcode_name(cmd), - (long long)lba, dev->virt_name); - scst_dif_acc_ref_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_ref_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - /* Skip CRC check for internal commands */ - if ((checks & SCST_DIF_CHECK_GUARD_TAG) && - !cmd->internal) { - __be16 crc = crc_fn(cur_buf, block_size); - if (t->guard_tag != crc) { - PRINT_WARNING("GUARD TAG check failed, " - "expected 0x%x, seeing 0x%x " - "(cmd %p (op %s), lba %lld, " - "dev %s)", crc, t->guard_tag, cmd, - scst_get_opcode_name(cmd), (long long)lba, - dev->virt_name); - scst_dif_acc_guard_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_guard_check_failed)); - res = -EIO; - goto out_put; - } - } - -next: - cur_buf += dev->block_size; - lba++; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - -out: - TRACE_EXIT_RES(res); - return res; - -out_put: - scst_put_buf(cmd, buf); - scst_put_dif_buf(cmd, tags_buf); - goto out; -} - -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS -static void scst_check_fail_ref_tag(struct scst_cmd *cmd) -{ - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - - if (((cmd->dev->dev_dif_mode & SCST_DIF_MODE_TGT) == 0) && - (checks & SCST_DIF_CHECK_REF_TAG)) { - TRACE(TRACE_SCSI|TRACE_MINOR, "No tgt dif_mode, failing " - "cmd %p with ref tag check failed", cmd); - scst_dif_acc_ref_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_ref_tag_check_failed)); - } - return; -} - -static void scst_check_fail_guard_tag(struct scst_cmd *cmd) -{ - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - - if (((cmd->dev->dev_dif_mode & SCST_DIF_MODE_TGT) == 0) && - (checks & SCST_DIF_CHECK_GUARD_TAG)) { - TRACE(TRACE_SCSI|TRACE_MINOR, "No tgt dif_mode, failing " - "cmd %p with guard tag check failed", cmd); - scst_dif_acc_guard_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_guard_check_failed)); - } - return; -} -#endif - -static int scst_generate_dif_type1(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - uint64_t lba = cmd->lba; - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 1); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_INSERT: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - TRACE_DBG("len %d", len); - - for (i = 0; i < (len >> block_shift); i++) { - TRACE_DBG("lba %lld, tags_len %d", (long long)lba, tags_len); - - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - TRACE_DBG("tags_sg %p, tags_buf %p, tags_len %d", - tags_sg, tags_buf, tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - t = (struct scst_dif_tuple *)tags_buf; - } - - t->app_tag = dev->dev_dif_static_app_tag; - t->ref_tag = cpu_to_be32(lba & 0xFFFFFFFF); - t->guard_tag = crc_fn(cur_buf, block_size); - -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - switch (cmd->cmd_corrupt_dif_tag) { - case 0: - break; - case 1: - if (lba == cmd->lba) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 2: - if (lba == (cmd->lba + 1)) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 3: - if (lba == (cmd->lba + 2)) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 4: - if (lba == (cmd->lba + ((cmd->data_len >> dev->block_shift) >> 1))) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 5: - if (lba == (cmd->lba + ((cmd->data_len >> dev->block_shift) - 3))) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 6: - if (lba == (cmd->lba + ((cmd->data_len >> dev->block_shift) - 2))) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - case 7: - if (lba == (cmd->lba + ((cmd->data_len >> dev->block_shift) - 1))) { - if (cmd->cdb[1] & 0x80) { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting ref tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->ref_tag = cpu_to_be32(0xebfeedad); - scst_check_fail_ref_tag(cmd); - } else { - TRACE(TRACE_SCSI|TRACE_MINOR, - "Corrupting guard tag at lba " - "%lld (case %d, cmd %p)", - (long long)lba, - cmd->cmd_corrupt_dif_tag, cmd); - t->guard_tag = cpu_to_be16(0xebed); - scst_check_fail_guard_tag(cmd); - } - } - break; - } -#endif - cur_buf += dev->block_size; - lba++; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_do_dif(struct scst_cmd *cmd, - int (*generate_fn)(struct scst_cmd *cmd), - int (*verify_fn)(struct scst_cmd *cmd)) -{ - int res; - enum scst_dif_actions action = scst_get_dif_action( - scst_get_scst_dif_actions(cmd->cmd_dif_actions)); - - TRACE_ENTRY(); - - TRACE_DBG("cmd %p, action %d", cmd, action); - - switch (action) { - case SCST_DIF_ACTION_PASS: - /* Nothing to do */ - TRACE_DBG("PASS DIF action, skipping (cmd %p)", cmd); - res = 0; - break; - - case SCST_DIF_ACTION_STRIP: - case SCST_DIF_ACTION_PASS_CHECK: - { - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - if (likely(checks != SCST_DIF_ACTION_NONE)) - res = verify_fn(cmd); - else - res = 0; - break; - } - - case SCST_DIF_ACTION_INSERT: - res = generate_fn(cmd); - break; - - default: - EXTRACHECKS_BUG_ON(1); - /* go through */ - case SCST_DIF_ACTION_NONE: - /* Nothing to do */ - TRACE_DBG("NONE DIF action, skipping (cmd %p)", cmd); - res = 0; - break; - } - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_dif_type1(struct scst_cmd *cmd) -{ - int res; - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(cmd->dev->dev_dif_type != 1); - - res = scst_do_dif(cmd, scst_generate_dif_type1, scst_verify_dif_type1); - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_verify_dif_type2(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - const struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - uint64_t lba = cmd->lba; - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - uint32_t ref_tag = scst_cmd_get_dif_exp_ref_tag(cmd); - /* Let's keep both in BE */ - __be16 app_tag_mask = cpu_to_be16(scst_cmd_get_dif_app_tag_mask(cmd)); - __be16 app_tag_masked = cpu_to_be16(scst_cmd_get_dif_exp_app_tag(cmd)) & app_tag_mask; - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 2); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_STRIP: - case SCST_DIF_ACTION_PASS_CHECK: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } - EXTRACHECKS_BUG_ON(checks == SCST_DIF_ACTION_NONE); -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - for (i = 0; i < (len >> block_shift); i++) { - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - t = (struct scst_dif_tuple *)tags_buf; - } - - if (t->app_tag == SCST_DIF_NO_CHECK_ALL_APP_TAG) { - TRACE_DBG("Skipping tag (cmd %p)", cmd); - goto next; - } - - if (checks & SCST_DIF_CHECK_APP_TAG) { - if ((t->app_tag & app_tag_mask) != app_tag_masked) { - PRINT_WARNING("APP TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), dev %s)", - app_tag_masked, t->app_tag & app_tag_mask, - cmd, scst_get_opcode_name(cmd), dev->virt_name); - scst_dif_acc_app_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_app_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - if (checks & SCST_DIF_CHECK_REF_TAG) { - if (t->ref_tag != cpu_to_be32(ref_tag)) { - PRINT_WARNING("REF TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), dev %s)", - cpu_to_be32(ref_tag), - t->ref_tag, cmd, scst_get_opcode_name(cmd), - dev->virt_name); - scst_dif_acc_ref_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_ref_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - /* Skip CRC check for internal commands */ - if ((checks & SCST_DIF_CHECK_GUARD_TAG) && - !cmd->internal) { - __be16 crc = crc_fn(cur_buf, block_size); - if (t->guard_tag != crc) { - PRINT_WARNING("GUARD TAG check failed, " - "expected 0x%x, seeing 0x%x " - "(cmd %p (op %s), lba %lld, " - "dev %s)", crc, t->guard_tag, cmd, - scst_get_opcode_name(cmd), (long long)lba, - dev->virt_name); - scst_dif_acc_guard_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_guard_check_failed)); - res = -EIO; - goto out_put; - } - } - -next: - cur_buf += dev->block_size; - lba++; - ref_tag++; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - -out: - TRACE_EXIT_RES(res); - return res; - -out_put: - scst_put_buf(cmd, buf); - scst_put_dif_buf(cmd, tags_buf); - goto out; -} - -static int scst_generate_dif_type2(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - uint32_t ref_tag = scst_cmd_get_dif_exp_ref_tag(cmd); - /* Let's keep both in BE */ - __be16 app_tag_mask = cpu_to_be16(scst_cmd_get_dif_app_tag_mask(cmd)); - __be16 app_tag_masked = cpu_to_be16(scst_cmd_get_dif_exp_app_tag(cmd)) & app_tag_mask; - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 2); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_INSERT: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - TRACE_DBG("len %d", len); - - for (i = 0; i < (len >> block_shift); i++) { - TRACE_DBG("tags_len %d", tags_len); - - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - TRACE_DBG("tags_sg %p, tags_buf %p, tags_len %d", - tags_sg, tags_buf, tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - t = (struct scst_dif_tuple *)tags_buf; - } - - t->app_tag = app_tag_masked; - t->ref_tag = cpu_to_be32(ref_tag); - t->guard_tag = crc_fn(cur_buf, block_size); - - cur_buf += dev->block_size; - ref_tag++; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_dif_type2(struct scst_cmd *cmd) -{ - int res; - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(cmd->dev->dev_dif_type != 2); - - res = scst_do_dif(cmd, scst_generate_dif_type2, scst_verify_dif_type2); - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_verify_dif_type3(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - enum scst_dif_actions checks = scst_get_dif_checks(cmd->cmd_dif_actions); - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - const struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - uint64_t lba = cmd->lba; - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 3); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_STRIP: - case SCST_DIF_ACTION_PASS_CHECK: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } - EXTRACHECKS_BUG_ON(checks == SCST_DIF_ACTION_NONE); -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - for (i = 0; i < (len >> block_shift); i++) { - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - t = (struct scst_dif_tuple *)tags_buf; - } - - if ((t->app_tag == SCST_DIF_NO_CHECK_ALL_APP_TAG) && - (t->ref_tag == SCST_DIF_NO_CHECK_ALL_REF_TAG)) { - TRACE_DBG("Skipping tag (cmd %p)", cmd); - goto next; - } - - if (checks & SCST_DIF_CHECK_APP_TAG) { - if (t->app_tag != dev->dev_dif_static_app_tag) { - PRINT_WARNING("APP TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), dev %s)", - dev->dev_dif_static_app_tag, - t->app_tag, cmd, scst_get_opcode_name(cmd), - dev->virt_name); - scst_dif_acc_app_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_app_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - if (checks & SCST_DIF_CHECK_REF_TAG) { - if (t->ref_tag != dev->dev_dif_static_app_ref_tag) { - PRINT_WARNING("REF TAG check failed, " - "expected 0x%x, seeing " - "0x%x (cmd %p (op %s), dev %s)", - dev->dev_dif_static_app_ref_tag, - t->ref_tag, cmd, scst_get_opcode_name(cmd), - dev->virt_name); - scst_dif_acc_ref_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_ref_tag_check_failed)); - res = -EIO; - goto out_put; - } - } - - /* Skip CRC check for internal commands */ - if ((checks & SCST_DIF_CHECK_GUARD_TAG) && - !cmd->internal) { - __be16 crc = crc_fn(cur_buf, block_size); - if (t->guard_tag != crc) { - PRINT_WARNING("GUARD TAG check failed, " - "expected 0x%x, seeing 0x%x " - "(cmd %p (op %s), lba %lld, " - "dev %s)", crc, t->guard_tag, cmd, - scst_get_opcode_name(cmd), (long long)lba, - dev->virt_name); - scst_dif_acc_guard_check_failed_scst(cmd); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_logical_block_guard_check_failed)); - res = -EIO; - goto out_put; - } - } - -next: - cur_buf += dev->block_size; - lba++; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - -out: - TRACE_EXIT_RES(res); - return res; - -out_put: - scst_put_buf(cmd, buf); - scst_put_dif_buf(cmd, tags_buf); - goto out; -} - -static int scst_generate_dif_type3(struct scst_cmd *cmd) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - int len, tags_len = 0, tag_size = 1 << SCST_DIF_TAG_SHIFT; - struct scatterlist *tags_sg = NULL; - uint8_t *buf, *tags_buf = NULL; - struct scst_dif_tuple *t = NULL; /* to silence compiler warning */ - int block_size = dev->block_size, block_shift = dev->block_shift; - __be16 (*crc_fn)(const void *buffer, unsigned int len); - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type != 3); - -#ifdef CONFIG_SCST_EXTRACHECKS - switch (scst_get_dif_action(scst_get_scst_dif_actions(cmd->cmd_dif_actions))) { - case SCST_DIF_ACTION_INSERT: - break; - default: - EXTRACHECKS_BUG_ON(1); - break; - } -#endif - - crc_fn = cmd->tgt_dev->tgt_dev_dif_crc_fn; - - len = scst_get_buf_first(cmd, &buf); - while (len > 0) { - int i; - uint8_t *cur_buf = buf; - - TRACE_DBG("len %d", len); - - for (i = 0; i < (len >> block_shift); i++) { - TRACE_DBG("tags_len %d", tags_len); - - if (tags_buf == NULL) { - tags_buf = scst_get_dif_buf(cmd, &tags_sg, &tags_len); - TRACE_DBG("tags_sg %p, tags_buf %p, tags_len %d", - tags_sg, tags_buf, tags_len); - EXTRACHECKS_BUG_ON(tags_len <= 0); - t = (struct scst_dif_tuple *)tags_buf; - } - - t->app_tag = dev->dev_dif_static_app_tag; - t->ref_tag = dev->dev_dif_static_app_ref_tag; - t->guard_tag = crc_fn(cur_buf, block_size); - - cur_buf += dev->block_size; - - t++; - tags_len -= tag_size; - if (tags_len == 0) { - scst_put_dif_buf(cmd, tags_buf); - tags_buf = NULL; - } - } - - scst_put_buf(cmd, buf); - len = scst_get_buf_next(cmd, &buf); - } - - EXTRACHECKS_BUG_ON(tags_buf != NULL); - - TRACE_EXIT_RES(res); - return res; -} - -static int scst_dif_type3(struct scst_cmd *cmd) -{ - int res; - - TRACE_ENTRY(); - - EXTRACHECKS_BUG_ON(cmd->dev->dev_dif_type != 3); - - res = scst_do_dif(cmd, scst_generate_dif_type3, scst_verify_dif_type3); - - TRACE_EXIT_RES(res); - return res; -} - -static void scst_init_dif_checks(struct scst_device *dev) -{ - switch (dev->dev_dif_type) { - case 0: - dev->dif_app_chk = 0; - dev->dif_ref_chk = 0; - break; - case 1: - if (scst_dev_get_dif_static_app_tag(dev) != SCST_DIF_NO_CHECK_APP_TAG) - dev->dif_app_chk = SCST_DIF_CHECK_APP_TAG; - else - dev->dif_app_chk = 0; - dev->dif_ref_chk = SCST_DIF_CHECK_REF_TAG; - break; - case 2: - dev->dif_app_chk = dev->ato ? SCST_DIF_CHECK_APP_TAG : 0; - dev->dif_ref_chk = SCST_DIF_CHECK_REF_TAG; - break; - case 3: - if (scst_dev_get_dif_static_app_tag_combined(dev) != SCST_DIF_NO_CHECK_APP_TAG) { - dev->dif_app_chk = SCST_DIF_CHECK_APP_TAG; - dev->dif_ref_chk = SCST_DIF_CHECK_REF_TAG; - } else { - dev->dif_app_chk = 0; - dev->dif_ref_chk = 0; - } - break; - default: - WARN_ON(1); - break; - } - return; -} - -/** - * scst_dev_set_dif_static_app_tag_combined() - sets static app tag - * - * Description: - * Sets static app tag for both APP TAG and REF TAG (DIF mode 3) - */ -void scst_dev_set_dif_static_app_tag_combined( - struct scst_device *dev, __be64 app_tag) -{ - uint64_t a = be64_to_cpu(app_tag); - - dev->dev_dif_static_app_tag = cpu_to_be16(a & 0xFFFF); - if (dev->dev_dif_type == 3) - dev->dev_dif_static_app_ref_tag = cpu_to_be32((a >> 16) & 0xFFFFFFFF); - scst_init_dif_checks(dev); - return; -} -EXPORT_SYMBOL_GPL(scst_dev_set_dif_static_app_tag_combined); - -static int scst_init_dif_actions(struct scst_device *dev) -{ - int res = 0; - - TRACE_ENTRY(); - - BUILD_BUG_ON(SCST_DIF_ACTION_NONE != 0); - - if ((dev->dev_dif_type == 0) || (dev->dev_dif_mode == 0)) { - dev->dev_dif_rd_actions = SCST_DIF_ACTION_NONE; - dev->dev_dif_wr_actions = SCST_DIF_ACTION_NONE; - dev->dev_dif_rd_prot0_actions = SCST_DIF_ACTION_NONE; - dev->dev_dif_wr_prot0_actions = SCST_DIF_ACTION_NONE; - goto out; - } - - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) && - !(dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE)) { - PRINT_ERROR("DEV CHECK is not allowed without DEV STORE! " - "(dev %s)", dev->virt_name); - res = -EINVAL; - goto out; - } - - /* - * COMMON RULES - * ============ - * - * 1. For SCST STRIP and PASS_CHECK as well as PASS and NONE are - * the same. - * - * 2. For dev handlers STRIP and INSERT are invalid, PASS and NONE are - * the same. Also, PASS and PASS_CHECK are equal regarding STORE, - * if STORE is configured. - */ - - BUILD_BUG_ON(SCST_DIF_MODE_DEV != (SCST_DIF_MODE_DEV_CHECK | SCST_DIF_MODE_DEV_STORE)); - - if (dev->dev_dif_mode & SCST_DIF_MODE_TGT) { - if (dev->dev_dif_mode & SCST_DIF_MODE_SCST) { - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV) { /* TGT, SCST, DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - - if (dev->dpicz) { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - } else { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_STRIP); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - } - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_INSERT); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS); - } else { /* TGT, SCST, no DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_INSERT); - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_NONE); - - if (dev->dpicz) { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - } else { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_STRIP); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_INSERT); - } - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_STRIP); - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_INSERT); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_STRIP); - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - } - } else { /* TGT, no SCST */ - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV) { /* TGT, no SCST, DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - } else { - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - } - - if (dev->dpicz) { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - } else { - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_STRIP); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - } - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_INSERT); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS); - } else { /* TGT, no SCST, no DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_INSERT); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - -#if 1 /* - * Workaround for Emulex ASIC errata to pass Oracle certification. - * - * Emulex ASIC in the STRIP mode can't distinguish between different types of - * PI tags mismatches (reference, guard, application), hence the Oracle - * certification fails. Workaround is to get the tags data in the memory, so - * then, if HW is signaling that there is some tag mismatch, manually recheck - * in the driver, then set correct tag mismatch sense. - */ - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); -#else - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_STRIP); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_NONE); -#endif - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - } - } - } else { /* No TGT */ - if (dev->dev_dif_mode & SCST_DIF_MODE_SCST) { /* No TGT, SCST */ - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV) { /* No TGT, SCST, DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - if (dev->dpicz) { - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - } else { - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_STRIP); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - } - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_INSERT); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS); - } else { /* No TGT, SCST, no DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_INSERT); - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_STRIP); - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_NONE); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - } - } else { /* No TGT, no SCST */ - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV) { /* No TGT, no SCST, DEV */ - scst_set_tgt_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - if (dev->dpicz) { - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_NONE); - } else { - scst_set_scst_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_rd_prot0_actions, SCST_DIF_ACTION_PASS); - } - - scst_set_tgt_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - scst_set_scst_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_actions, SCST_DIF_ACTION_PASS); - - scst_set_tgt_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_NONE); - scst_set_scst_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_INSERT); - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) { - /* STORE might be set as well */ - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS_CHECK); - } else - scst_set_dev_dif_action(&dev->dev_dif_wr_prot0_actions, SCST_DIF_ACTION_PASS); - } else { /* No TGT, no SCST, no DEV */ - sBUG_ON(1); - } - } - } - - TRACE_DBG("rd_actions %x, rd_prot0_actions %x, wr_actions %x, " - "wr_prot0_actions %x", dev->dev_dif_rd_actions, - dev->dev_dif_rd_prot0_actions, dev->dev_dif_wr_actions, - dev->dev_dif_wr_prot0_actions); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/** - * scst_set_dif_params() - sets DIF parameters - * - * Description: - * Sets DIF parameters for device - * - * Returns: 0 on success, negative error code otherwise. - */ -int scst_set_dif_params(struct scst_device *dev, enum scst_dif_mode dif_mode, - int dif_type) -{ - int res = -EINVAL; - - TRACE_ENTRY(); - - BUILD_BUG_ON(SCST_DIF_ACTION_NONE != 0); - - if (((dif_mode & ~(SCST_DIF_MODE_TGT|SCST_DIF_MODE_SCST|SCST_DIF_MODE_DEV)) != 0)) { - PRINT_ERROR("Invalid DIF mode %x", dif_mode); - goto out; - } - - if ((dif_type < 0) || (dif_type > 3)) { - PRINT_ERROR("DIF type %d not supported", dif_type); - goto out; - } - - if ((dif_mode == 0) && (dif_type != 0)) { - PRINT_ERROR("With DIF mode 0 DIF type must be 0 (dev %s)", - dev->virt_name); - goto out; - } - - dev->dev_dif_mode = dif_mode; - dev->dev_dif_type = dif_type; - - if (dif_type == 0) { - TRACE_DBG("DIF type 0, ignoring DIF mode"); - goto out_none; - } - - if (dif_mode == 0) { - TRACE_DBG("DIF mode 0"); - goto out_none; - } - - scst_init_dif_checks(dev); - - if (dif_mode & SCST_DIF_MODE_SCST) { - switch (dif_type) { - case 1: - dev->dev_dif_fn = scst_dif_type1; - break; - case 2: - dev->dev_dif_fn = scst_dif_type2; - break; - case 3: - dev->dev_dif_fn = scst_dif_type3; - break; - default: - sBUG_ON(1); - break; - } - } else { - if ((dif_type == 1) && !(dif_mode & SCST_DIF_MODE_TGT)) - dev->dev_dif_fn = scst_dif_type1; - else if ((dif_type == 1) && (dif_mode & SCST_DIF_MODE_TGT)) - dev->dev_dif_fn = scst_dif_none_type1; - else - dev->dev_dif_fn = scst_dif_none; - } - - res = scst_init_dif_actions(dev); - if (res != 0) - goto out; - - res = scst_dev_sysfs_dif_create(dev); - if (res != 0) - goto out; - - PRINT_INFO("device %s: DIF mode %x, DIF type %d", dev->virt_name, - dev->dev_dif_mode, dev->dev_dif_type); - TRACE_DBG("app_chk %x, ref_chk %x", dev->dif_app_chk, dev->dif_ref_chk); - -out: - TRACE_EXIT_RES(res); - return res; - -out_none: - dev->dif_app_chk = 0; - if (dev->dev_dif_type == 3) - dev->dif_ref_chk = 0; - dev->dev_dif_static_app_tag = SCST_DIF_NO_CHECK_APP_TAG; - dev->dev_dif_static_app_ref_tag = SCST_DIF_NO_CHECK_APP_TAG; - dev->dev_dif_fn = scst_dif_none; - res = scst_init_dif_actions(dev); - goto out; -} -EXPORT_SYMBOL_GPL(scst_set_dif_params); - -static int scst_dif_none(struct scst_cmd *cmd) -{ - int res = 0; - - TRACE_ENTRY(); - - /* Nothing to do */ - - TRACE_EXIT_RES(res); - return res; -} - -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS -static int scst_dif_none_type1(struct scst_cmd *cmd) -{ - int res = 0; - - TRACE_ENTRY(); - - if (unlikely(cmd->cmd_corrupt_dif_tag != 0)) { - EXTRACHECKS_BUG_ON(cmd->dev->dev_dif_type != 1); - res = scst_dif_type1(cmd); - } - - TRACE_EXIT_RES(res); - return res; -} -#endif - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int __scst_parse_rdprotect(struct scst_cmd *cmd, int rdprotect, - int rdprotect_offs) -{ - int res = 0; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - TRACE_DBG("rdprotect %x", rdprotect); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type == 0); - - switch (rdprotect) { - case 0: - cmd->cmd_dif_actions = dev->dev_dif_rd_prot0_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - break; - case 1: - case 5: - cmd->cmd_dif_actions = dev->dev_dif_rd_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - cmd->tgt_dif_data_expected = 1; - break; - case 2: - cmd->cmd_dif_actions = dev->dev_dif_rd_actions | - dev->dif_app_chk | dev->dif_ref_chk; - cmd->tgt_dif_data_expected = 1; - break; - case 3: - cmd->cmd_dif_actions = dev->dev_dif_rd_actions; - cmd->tgt_dif_data_expected = 1; - break; - case 4: - cmd->cmd_dif_actions = dev->dev_dif_rd_actions | - dev->dif_app_chk; - cmd->tgt_dif_data_expected = 1; - break; - default: - TRACE(TRACE_SCSI|TRACE_MINOR, "Invalid RDPROTECT value %x " - "(dev %s, cmd %p)", rdprotect, dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, rdprotect_offs, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - - TRACE_DBG("cmd_dif_actions %x, tgt_dif_data_expected %d (cmd %p)", - cmd->cmd_dif_actions, cmd->tgt_dif_data_expected, cmd); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_rdprotect(struct scst_cmd *cmd) -{ - int res = 0; - int rdprotect = (cmd->cdb[1] & 0xE0) >> 5; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (dev->dev_dif_mode == SCST_DIF_MODE_NONE) { - if (likely(rdprotect == 0)) - goto out; - - TRACE(TRACE_SCSI|TRACE_MINOR, "RDPROTECT %x and no DIF " - "device %s (cmd %p)", rdprotect, - dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, 1, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - - if (unlikely((dev->dev_dif_type == 2) && (rdprotect != 0))) { - TRACE(TRACE_SCSI|TRACE_MINOR, "Non-32-byte CDBs with non-zero " - "rdprotect (%d) are not allowed in DIF type 2 " - "(dev %s, cmd %p, op %s)", rdprotect, dev->virt_name, - cmd, scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if (unlikely(cmd->cmd_corrupt_dif_tag != 0)) { - if ((cmd->dev->dev_dif_type == 1) && - ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) == 0)) { - TRACE_DBG("cmd_corrupt_dif_tag %x, rdprotect %x, cmd %p", - cmd->cmd_corrupt_dif_tag, rdprotect, cmd); - /* Reset the highest bit used to choose which tag to corrupt */ - rdprotect &= 3; - } else { - /* Restore it */ - cmd->cmd_corrupt_dif_tag = 0; - } - } -#endif - - res = __scst_parse_rdprotect(cmd, rdprotect, 1); - -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if (unlikely(cmd->cmd_corrupt_dif_tag != 0)) { - if (res == 0) { - TRACE_DBG("Corrupt DIF tag, (re)set cmd_dif_actions " - "(cmd %p)", cmd); - /* - * Then (re)set it just in case if dif_mode is tgt-only. - * It's OK, because we have ensured that dif_mode - * doesn't contain dev_store. - */ - scst_set_scst_dif_action(&cmd->cmd_dif_actions, - SCST_DIF_ACTION_INSERT); - if (scst_get_dif_action(scst_get_read_dif_tgt_actions(cmd)) == SCST_DIF_ACTION_INSERT) - scst_set_tgt_dif_action(&cmd->cmd_dif_actions, - SCST_DIF_ACTION_PASS_CHECK); - } else - TRACE_DBG("parse rdprotect failed: %d", res); - } -#endif - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_rdprotect32(struct scst_cmd *cmd) -{ - int res = 0; - int rdprotect = (cmd->cdb[10] & 0xE0) >> 5; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (unlikely(dev->dev_dif_type != 2)) { - TRACE(TRACE_SCSI|TRACE_MINOR, "32-byte CDBs are not " - "allowed in DIF type %d (dev %s, cmd %p, op %s)", - dev->dev_dif_type, dev->virt_name, cmd, - scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - - res = __scst_parse_rdprotect(cmd, rdprotect, 10); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int __scst_parse_wrprotect(struct scst_cmd *cmd, int wrprotect, - int wrprotect_offs) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - TRACE_DBG("wrprotect %x", wrprotect); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type == 0); - - switch (wrprotect) { - case 0: - cmd->cmd_dif_actions = dev->dev_dif_wr_prot0_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - break; - case 1: - cmd->cmd_dif_actions = dev->dev_dif_wr_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - cmd->tgt_dif_data_expected = 1; - break; - case 2: - cmd->cmd_dif_actions = dev->dev_dif_wr_actions | - dev->dif_app_chk | dev->dif_ref_chk; - cmd->tgt_dif_data_expected = 1; - break; - case 3: - cmd->cmd_dif_actions = dev->dev_dif_wr_actions; - cmd->tgt_dif_data_expected = 1; - break; - case 4: - cmd->cmd_dif_actions = dev->dev_dif_wr_actions | - SCST_DIF_CHECK_GUARD_TAG; - cmd->tgt_dif_data_expected = 1; - break; - case 5: - cmd->cmd_dif_actions = dev->dev_dif_wr_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - cmd->tgt_dif_data_expected = 1; - break; - default: - TRACE(TRACE_SCSI|TRACE_MINOR, "Invalid WRPROTECT value %x " - "(dev %s, cmd %p)", wrprotect, dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, wrprotect_offs, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - - TRACE_DBG("cmd_dif_actions %x, tgt_dif_data_expected %d (cmd %p)", - cmd->cmd_dif_actions, cmd->tgt_dif_data_expected, cmd); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_wrprotect(struct scst_cmd *cmd) -{ - int res = 0; - int wrprotect = (cmd->cdb[1] & 0xE0) >> 5; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (dev->dev_dif_mode == SCST_DIF_MODE_NONE) { - if (likely(wrprotect == 0)) - goto out; - - TRACE(TRACE_SCSI|TRACE_MINOR, "WRPROTECT %x and no DIF " - "device %s (cmd %p)", wrprotect, - dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, 1, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - - if (unlikely((dev->dev_dif_type == 2) && (wrprotect != 0))) { - TRACE(TRACE_SCSI|TRACE_MINOR, "Non-32-byte CDBs with non-zero " - "wrprotect (%d) are not allowed in DIF type 2 " - "(dev %s, cmd %p, op %s)", wrprotect, dev->virt_name, - cmd, scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - - res = __scst_parse_wrprotect(cmd, wrprotect, 1); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_wrprotect32(struct scst_cmd *cmd) -{ - int res = 0; - int wrprotect = (cmd->cdb[10] & 0xE0) >> 5; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (unlikely(dev->dev_dif_type != 2)) { - TRACE(TRACE_SCSI|TRACE_MINOR, "32-byte CDBs are not " - "allowed in DIF type %d (dev %s, cmd %p, op %s)", - dev->dev_dif_type, dev->virt_name, cmd, - scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - - res = __scst_parse_wrprotect(cmd, wrprotect, 10); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int __scst_parse_vrprotect(struct scst_cmd *cmd, int vrprotect_offs) -{ - int res = 0; - struct scst_device *dev = cmd->dev; - int vrprotect = (cmd->cdb[vrprotect_offs] & 0xE0) >> 5; - int bytchk = (cmd->cdb[vrprotect_offs] & 6) >> 1; - - TRACE_ENTRY(); - - TRACE_DBG("vrprotect %x", vrprotect); - - EXTRACHECKS_BUG_ON(dev->dev_dif_type == 0); - - switch (bytchk) { - case 0: - switch (vrprotect) { - case 0: - if (dev->dpicz) { - cmd->cmd_dif_actions = 0; - break; - } - /* else go through */ - case 1: - case 5: - cmd->cmd_dif_actions = SCST_DIF_CHECK_GUARD_TAG | - dev->dif_app_chk | dev->dif_ref_chk; - break; - case 2: - cmd->cmd_dif_actions = dev->dif_app_chk | dev->dif_ref_chk; - break; - case 3: - cmd->cmd_dif_actions = 0; - break; - case 4: - cmd->cmd_dif_actions = SCST_DIF_CHECK_GUARD_TAG; - break; - default: - TRACE(TRACE_SCSI|TRACE_MINOR, "Invalid VRPROTECT value %x " - "(dev %s, cmd %p)", vrprotect, dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, vrprotect_offs, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - break; - case 1: - case 3: - switch (vrprotect) { - case 0: - if (dev->dpicz) - cmd->cmd_dif_actions = 0; - else - cmd->cmd_dif_actions = dev->dev_dif_wr_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - dev->dif_ref_chk; - break; - case 1: - case 2: - case 3: - case 4: - case 5: - cmd->cmd_dif_actions = 0; - break; - default: - TRACE(TRACE_SCSI|TRACE_MINOR, "Invalid VRPROTECT value %x " - "(dev %s, cmd %p)", vrprotect, dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, vrprotect_offs, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - break; - default: - sBUG_ON(1); - break; - } - - TRACE_DBG("cmd_dif_actions %x, tgt_dif_data_expected %d (cmd %p, " - "bytchk %d)", cmd->cmd_dif_actions, cmd->tgt_dif_data_expected, - cmd, bytchk); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_vrprotect(struct scst_cmd *cmd) -{ - int res = 0; - int vrprotect = (cmd->cdb[1] & 0xE0) >> 5; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (dev->dev_dif_mode == SCST_DIF_MODE_NONE) { - if (likely(vrprotect == 0)) - goto out; - - TRACE(TRACE_SCSI|TRACE_MINOR, "VRPROTECT %x and no DIF " - "device %s (cmd %p)", vrprotect, - dev->virt_name, cmd); - scst_set_invalid_field_in_cdb(cmd, 1, - 5|SCST_INVAL_FIELD_BIT_OFFS_VALID); - res = EINVAL; - goto out; - } - - if (unlikely((dev->dev_dif_type == 2) && (vrprotect != 0))) { - TRACE(TRACE_SCSI|TRACE_MINOR, "Non-32-byte CDBs with non-zero " - "vrprotect (%d) are not allowed in DIF type 2 " - "(dev %s, cmd %p, op %s)", vrprotect, - dev->virt_name, cmd, scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - - res = __scst_parse_vrprotect(cmd, 1); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * Returns 0 on success or POSITIVE error code otherwise (to match - * scst_get_cdb_info() semantic) - */ -static int scst_parse_vrprotect32(struct scst_cmd *cmd) -{ - int res = 0; - const struct scst_device *dev = cmd->dev; - - TRACE_ENTRY(); - - if (unlikely(dev->dev_dif_type != 2)) { - TRACE(TRACE_SCSI|TRACE_MINOR, "32-byte CDBs are not " - "allowed in DIF type %d (dev %s, cmd %p, op %s)", - dev->dev_dif_type, dev->virt_name, cmd, - scst_get_opcode_name(cmd)); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); - res = EINVAL; - goto out; - } - - res = __scst_parse_vrprotect(cmd, 10); - -out: - TRACE_EXIT_RES(res); - return res; -} - -/* - * So far we support the only variable length CDBs, 32 bytes SBC PI type 2 - * commands, so 32 on the forth place is OK. Don't forget to change it - * adding in this group new commands with other lengths! - */ -static const int scst_cdb_length[8] = { 6, 10, 10, 32, 16, 12, 0, 0 }; +static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, 0, 16, 12, 0, 0 }; #define SCST_CDB_GROUP(opcode) ((opcode >> 5) & 0x7) -#define SCST_GET_CDB_LEN(opcode) scst_cdb_length[SCST_CDB_GROUP(opcode)] +#define SCST_GET_CDB_LEN(opcode) SCST_CDB_LENGTH[SCST_CDB_GROUP(opcode)] static int get_cdb_info_len_10(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) @@ -9640,7 +7311,7 @@ static int get_cdb_info_verify10(struct scst_cmd *cmd, cmd->data_len = get_unaligned_be16(cmd->cdb + sdbops->info_len_off); cmd->data_direction = SCST_DATA_NONE; } - return scst_parse_vrprotect(cmd); + return 0; } static int get_cdb_info_verify6(struct scst_cmd *cmd, @@ -9696,7 +7367,7 @@ static int get_cdb_info_verify12(struct scst_cmd *cmd, cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); cmd->data_direction = SCST_DATA_NONE; } - return scst_parse_vrprotect(cmd); + return 0; } static int get_cdb_info_verify16(struct scst_cmd *cmd, @@ -9726,37 +7397,7 @@ static int get_cdb_info_verify16(struct scst_cmd *cmd, cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); cmd->data_direction = SCST_DATA_NONE; } - return scst_parse_vrprotect(cmd); -} - -static int get_cdb_info_verify32(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - if (unlikely(cmd->cdb[10] & 4)) { - PRINT_ERROR("VERIFY(16): BYTCHK 1x not supported (dev %s)", - cmd->dev ? cmd->dev->virt_name : NULL); - scst_set_invalid_field_in_cdb(cmd, 1, - 2 | SCST_INVAL_FIELD_BIT_OFFS_VALID); - return 1; - } - - cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); - if (cmd->cdb[10] & 2) { - cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", - cmd->bufflen, scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } - cmd->data_len = cmd->bufflen; - cmd->data_direction = SCST_DATA_WRITE; - } else { - cmd->bufflen = 0; - cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - cmd->data_direction = SCST_DATA_NONE; - } - return scst_parse_vrprotect32(cmd); + return 0; } static int get_cdb_info_len_1(struct scst_cmd *cmd, @@ -9770,7 +7411,7 @@ static int get_cdb_info_len_1(struct scst_cmd *cmd, return 0; } -static inline int get_cdb_info_lba_3_len_1_256(struct scst_cmd *cmd, +static int get_cdb_info_lba_3_len_1_256(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { cmd->lba = (cmd->cdb[sdbops->info_lba_off] & 0x1F) << 16; @@ -9791,40 +7432,6 @@ static inline int get_cdb_info_lba_3_len_1_256(struct scst_cmd *cmd, return 0; } -static int get_cdb_info_lba_3_len_1_256_read(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); - if (res != 0) - goto out; - else { - struct scst_device *dev = cmd->dev; - if ((dev->dev_dif_mode != SCST_DIF_MODE_NONE) && !dev->dpicz) - cmd->cmd_dif_actions = dev->dev_dif_rd_prot0_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - SCST_DIF_CHECK_REF_TAG; - } -out: - return res; -} - -static int get_cdb_info_lba_3_len_1_256_write(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_3_len_1_256(cmd, sdbops); - if (res != 0) - goto out; - else { - struct scst_device *dev = cmd->dev; - if (dev->dev_dif_mode != SCST_DIF_MODE_NONE) - cmd->cmd_dif_actions = dev->dev_dif_wr_prot0_actions | - SCST_DIF_CHECK_GUARD_TAG | dev->dif_app_chk | - SCST_DIF_CHECK_REF_TAG; - } -out: - return res; -} - static int get_cdb_info_len_2(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { @@ -9919,32 +7526,7 @@ static int get_cdb_info_lba_4_len_2(struct scst_cmd *cmd, return 0; } -static int get_cdb_info_read_10(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_4_len_2(cmd, sdbops); - if (res != 0) - return res; - else { -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - EXTRACHECKS_BUG_ON(cmd->cdb[0] != READ_10); - cmd->cmd_corrupt_dif_tag = (cmd->cdb[6] & 0xE0) >> 5; -#endif - return scst_parse_rdprotect(cmd); - } -} - -static int get_cdb_info_lba_4_len_2_wrprotect(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_4_len_2(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_wrprotect(cmd); -} - -static inline int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd, +static int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off); @@ -9959,27 +7541,7 @@ static inline int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd, return 0; } -static int get_cdb_info_lba_4_len_4_rdprotect(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_4_len_4(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_rdprotect(cmd); -} - -static int get_cdb_info_lba_4_len_4_wrprotect(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_4_len_4(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_wrprotect(cmd); -} - -static inline int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd, +static int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); @@ -9994,58 +7556,13 @@ static inline int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd, return 0; } -static int get_cdb_info_read_16(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_8_len_4(cmd, sdbops); - if (res != 0) - return res; - else { -#ifdef CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - EXTRACHECKS_BUG_ON(cmd->cdb[0] != READ_16); - cmd->cmd_corrupt_dif_tag = (cmd->cdb[14] & 0xE0) >> 5; -#endif - return scst_parse_rdprotect(cmd); - } -} - -static int get_cdb_info_lba_8_len_4_wrprotect(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_8_len_4(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_wrprotect(cmd); -} - -static int get_cdb_info_lba_8_len_4_wrprotect32(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_8_len_4(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_wrprotect32(cmd); -} - -static int get_cdb_info_lba_8_len_4_rdprotect32(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res = get_cdb_info_lba_8_len_4(cmd, sdbops); - if (res != 0) - return res; - else - return scst_parse_rdprotect32(cmd); -} - static int get_cdb_info_write_same10(struct scst_cmd *cmd, const struct scst_sdbops *sdbops) { cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off); cmd->bufflen = 1; cmd->data_len = get_unaligned_be16(cmd->cdb + sdbops->info_len_off); - return scst_parse_wrprotect(cmd); + return 0; } static int get_cdb_info_write_same16(struct scst_cmd *cmd, @@ -10054,132 +7571,7 @@ static int get_cdb_info_write_same16(struct scst_cmd *cmd, cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); cmd->bufflen = 1; cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - return scst_parse_wrprotect(cmd); -} - -static int get_cdb_info_write_same32(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); - cmd->bufflen = 1; - cmd->data_len = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - return scst_parse_wrprotect32(cmd); -} - -static int scst_set_cmd_from_cdb_info(struct scst_cmd *cmd, - const struct scst_sdbops *ptr) -{ - cmd->cdb_len = SCST_GET_CDB_LEN(cmd->cdb[0]); - cmd->cmd_naca = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT); - cmd->cmd_linked = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT); - cmd->op_name = ptr->info_op_name; - cmd->data_direction = ptr->info_data_direction; - cmd->op_flags = ptr->info_op_flags | SCST_INFO_VALID; - cmd->lba_off = ptr->info_lba_off; - cmd->lba_len = ptr->info_lba_len; - cmd->len_off = ptr->info_len_off; - cmd->len_len = ptr->info_len_len; - return (*ptr->get_cdb_info)(cmd, ptr); -} - -static int get_cdb_info_var_len(struct scst_cmd *cmd, - const struct scst_sdbops *sdbops) -{ - int res; - /* - * !! Indexed by (cdb[8-9] - SUBCODE_READ_32), the smallest subcode, - * !! hence all items in the array MUST be sorted and with NO HOLES - * !! in ops field! - */ - static const struct scst_sdbops scst_scsi_op32_table[] = { - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "READ(32)", - .info_data_direction = SCST_DATA_READ, - .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED| -#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ - SCST_TEST_IO_IN_SIRQ_ALLOWED| -#endif - SCST_WRITE_EXCL_ALLOWED, - .info_lba_off = 12, .info_lba_len = 8, - .info_len_off = 28, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_8_len_4_rdprotect32}, - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "VERIFY(32)", - .info_data_direction = SCST_DATA_UNKNOWN, - .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_EXCL_ALLOWED, - .info_lba_off = 12, .info_lba_len = 8, - .info_len_off = 28, .info_len_len = 4, - .get_cdb_info = get_cdb_info_verify32}, - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "WRITE(32)", - .info_data_direction = SCST_DATA_WRITE, - .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED| -#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ - SCST_TEST_IO_IN_SIRQ_ALLOWED| -#endif - SCST_WRITE_MEDIUM, - .info_lba_off = 12, .info_lba_len = 8, - .info_len_off = 28, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_8_len_4_wrprotect32}, - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "WRITE AND VERIFY(32)", - .info_data_direction = SCST_DATA_WRITE, - .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM, - .info_lba_off = 12, .info_lba_len = 8, - .info_len_off = 28, .info_len_len = 4, - .get_cdb_info = get_cdb_info_lba_8_len_4_wrprotect32}, - {.ops = 0x7F, .devkey = "O ", - .info_op_name = "WRITE SAME(32)", - .info_data_direction = SCST_DATA_WRITE, - .info_op_flags = SCST_TRANSFER_LEN_TYPE_FIXED|SCST_WRITE_MEDIUM, - .info_lba_off = 12, .info_lba_len = 8, - .info_len_off = 28, .info_len_len = 4, - .get_cdb_info = get_cdb_info_write_same32}, - }; - const struct scst_sdbops *ptr; - int subcode = be16_to_cpu(*(__be16 *)&cmd->cdb[8]); - unsigned int i = subcode - SUBCODE_READ_32; - - EXTRACHECKS_BUG_ON(cmd->cdb[0] != 0x7F); - EXTRACHECKS_BUG_ON(sdbops->ops != 0x7F); - - /* i is unsigned, so this will handle subcodes < READ_32 as well */ - if (unlikely(i >= ARRAY_SIZE(scst_scsi_op32_table))) { - TRACE(TRACE_MINOR, "Too big cmd index %d for 0x7F CDB (cmd %p)", - i, cmd); - goto out_unknown; - } - - ptr = &scst_scsi_op32_table[i]; -#if 0 /* not possible */ - if (unlikely(ptr == NULL)) - goto out_unknown; -#endif - - if (unlikely(cmd->cdb[7] != 0x18)) { - TRACE(TRACE_MINOR, "Incorrect ADDITIONAL CDB LENGTH %d for " - "0x7F CDB (cmd %p)", cmd->cdb[7], cmd); - cmd->op_flags |= SCST_LBA_NOT_VALID; - scst_set_invalid_field_in_cdb(cmd, 7, 0); - res = 1; /* command invalid */ - goto out; - } - - res = scst_set_cmd_from_cdb_info(cmd, ptr); - - cmd->cmd_naca = (cmd->cdb[1] & CONTROL_BYTE_NACA_BIT); - cmd->cmd_linked = (cmd->cdb[1] & CONTROL_BYTE_LINK_BIT); - -out: - TRACE_EXIT_RES(res); - return res; - -out_unknown: - TRACE(TRACE_MINOR, "Unknown opcode 0x%x, subcode %d for type %d", - cmd->cdb[0], subcode, cmd->dev->type); - cmd->op_flags &= ~SCST_INFO_VALID; - res = -1; /* command unknown */ - goto out; + return 0; } static int get_cdb_info_compare_and_write(struct scst_cmd *cmd, @@ -10188,7 +7580,7 @@ static int get_cdb_info_compare_and_write(struct scst_cmd *cmd, cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); cmd->data_len = cmd->cdb[sdbops->info_len_off]; cmd->bufflen = 2 * cmd->data_len; - return scst_parse_wrprotect(cmd); + return 0; } /** @@ -10377,7 +7769,17 @@ int scst_get_cdb_info(struct scst_cmd *cmd) goto out; } - res = scst_set_cmd_from_cdb_info(cmd, ptr); + cmd->cdb_len = SCST_GET_CDB_LEN(op); + cmd->cmd_naca = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT); + cmd->cmd_linked = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT); + cmd->op_name = ptr->info_op_name; + cmd->data_direction = ptr->info_data_direction; + cmd->op_flags = ptr->info_op_flags | SCST_INFO_VALID; + cmd->lba_off = ptr->info_lba_off; + cmd->lba_len = ptr->info_lba_len; + cmd->len_off = ptr->info_len_off; + cmd->len_len = ptr->info_len_len; + res = (*ptr->get_cdb_info)(cmd, ptr); out: TRACE_EXIT_RES(res); @@ -11899,7 +9301,6 @@ int scst_obtain_device_parameters(struct scst_device *dev, dev->tst = buffer[4+2] >> 5; dev->tmf_only = (buffer[4+2] & 0x10) >> 4; - dev->dpicz = (buffer[4+2] & 0x8) >> 3; q = buffer[4+3] >> 4; if (q > SCST_QUEUE_ALG_1_UNRESTRICTED_REORDER) { PRINT_ERROR("Too big QUEUE ALG %x, dev %s, " @@ -11922,11 +9323,11 @@ int scst_obtain_device_parameters(struct scst_device *dev, dev->has_own_order_mgmt = !dev->queue_alg; PRINT_INFO("Device %s: TST %x, TMF_ONLY %x, QUEUE ALG %x, " - "QErr %x, SWP %x, TAS %x, D_SENSE %d, DPICZ %d, " + "QErr %x, SWP %x, TAS %x, D_SENSE %d, " "has_own_order_mgmt %d", dev->virt_name, dev->tst, dev->tmf_only, dev->queue_alg, dev->qerr, dev->swp, dev->tas, dev->d_sense, - dev->dpicz, dev->has_own_order_mgmt); + dev->has_own_order_mgmt); goto out; } else { @@ -11985,10 +9386,10 @@ int scst_obtain_device_parameters(struct scst_device *dev, brk: PRINT_WARNING("Unable to get device's %s control mode page, using " "existing values/defaults: TST %x, TMF_ONLY %x, QUEUE ALG %x, " - "QErr %x, SWP %x, TAS %x, D_SENSE %d, DPICZ %d, " - "has_own_order_mgmt %d", dev->virt_name, dev->tst, - dev->tmf_only, dev->queue_alg, dev->qerr, dev->swp, dev->tas, - dev->d_sense, dev->dpicz, dev->has_own_order_mgmt); + "QErr %x, SWP %x, TAS %x, D_SENSE %d, has_own_order_mgmt %d", + dev->virt_name, dev->tst, dev->tmf_only, dev->queue_alg, + dev->qerr, dev->swp, dev->tas, dev->d_sense, + dev->has_own_order_mgmt); out: TRACE_EXIT(); @@ -12582,7 +9983,6 @@ static void scst_free_descriptors(struct scst_cmd *cmd) #define SCST_SWP_LABEL "SWP" #define SCST_DSENSE_LABEL "D_SENSE" #define SCST_QUEUE_ALG_LABEL "QUEUE_ALG" -#define SCST_DPICZ_LABEL "DPICZ" int scst_save_global_mode_pages(const struct scst_device *dev, uint8_t *buf, int size) @@ -12626,13 +10026,6 @@ int scst_save_global_mode_pages(const struct scst_device *dev, goto out_overflow; } - if (dev->dpicz != dev->dpicz_default) { - res += scnprintf(&buf[res], size - res, "%s=%d\n", - SCST_DPICZ_LABEL, dev->dpicz); - if (res >= size-1) - goto out_overflow; - } - if (dev->queue_alg != dev->queue_alg_default) { res += scnprintf(&buf[res], size - res, "%s=%d\n", SCST_QUEUE_ALG_LABEL, dev->queue_alg); @@ -12782,32 +10175,6 @@ out: return res; } -static int scst_restore_dpicz(struct scst_device *dev, unsigned int val) -{ - int res; - - TRACE_ENTRY(); - - if (val > 1) { - PRINT_ERROR("Invalid value %d for parameter %s (device %s)", - val, SCST_DPICZ_LABEL, dev->virt_name); - res = -EINVAL; - goto out; - } - - dev->dpicz = val; - dev->dpicz_saved = val; - - PRINT_INFO("%s restored to %d for device %s", SCST_DPICZ_LABEL, - dev->dpicz, dev->virt_name); - - res = 0; - -out: - TRACE_EXIT_RES(res); - return res; -} - static int scst_restore_queue_alg(struct scst_device *dev, unsigned int val) { int res; @@ -12879,8 +10246,6 @@ int scst_restore_global_mode_pages(struct scst_device *dev, char *params, res = scst_restore_swp(dev, val); else if (strcasecmp(SCST_DSENSE_LABEL, p) == 0) res = scst_restore_dsense(dev, val); - else if (strcasecmp(SCST_DPICZ_LABEL, p) == 0) - res = scst_restore_dpicz(dev, val); else if (strcasecmp(SCST_QUEUE_ALG_LABEL, p) == 0) res = scst_restore_queue_alg(dev, val); else { diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index a711ddb93..5f016fb08 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -520,11 +520,6 @@ static inline void scst_devt_dev_sysfs_del(struct scst_device *dev) { } static inline void scst_dev_sysfs_del(struct scst_device *dev) { } -static inline int scst_dev_sysfs_dif_create(struct scst_device *dev) -{ - return 0; -} - static inline int scst_tgt_dev_sysfs_create(struct scst_tgt_dev *tgt_dev) { return 0; @@ -573,7 +568,6 @@ int scst_devt_sysfs_create(struct scst_dev_type *devt); void scst_devt_sysfs_del(struct scst_dev_type *devt); int scst_dev_sysfs_create(struct scst_device *dev); void scst_dev_sysfs_del(struct scst_device *dev); -int scst_dev_sysfs_dif_create(struct scst_device *dev); int scst_tgt_dev_sysfs_create(struct scst_tgt_dev *tgt_dev); void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev); int scst_devt_dev_sysfs_create(struct scst_device *dev); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 2619f711f..7ac882963 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -1033,63 +1033,6 @@ static struct kobj_attribute scst_tgtt_mgmt = __ATTR(mgmt, S_IRUGO | S_IWUSR, scst_tgtt_mgmt_show, scst_tgtt_mgmt_store); -static ssize_t scst_tgtt_dif_capable_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_tgt_template *tgtt; - - TRACE_ENTRY(); - - tgtt = container_of(kobj, struct scst_tgt_template, tgtt_kobj); - - EXTRACHECKS_BUG_ON(!tgtt->dif_supported); - - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "dif_supported"); - - if (tgtt->hw_dif_type1_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type1_supported"); - - if (tgtt->hw_dif_type2_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type2_supported"); - - if (tgtt->hw_dif_type3_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type3_supported"); - - if (tgtt->hw_dif_ip_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_ip_supported"); - - if (tgtt->hw_dif_same_sg_layout_required) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_same_sg_layout_required"); - - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "\n"); - - if (tgtt->supported_dif_block_sizes) { - const int *p = tgtt->supported_dif_block_sizes; - int j; - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "Supported blocks: "); - j = pos; - while (*p != 0) { - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%d", (j == pos) ? "" : ", ", *p); - p++; - } - } - - TRACE_EXIT_RES(pos); - return pos; -} - -static struct kobj_attribute scst_tgtt_dif_capable_attr = - __ATTR(dif_capabilities, S_IRUGO, scst_tgtt_dif_capable_show, NULL); - /* * Creates an attribute entry for target driver. */ @@ -1142,16 +1085,6 @@ int scst_tgtt_sysfs_create(struct scst_tgt_template *tgtt) } } - if (tgtt->dif_supported) { - res = sysfs_create_file(&tgtt->tgtt_kobj, - &scst_tgtt_dif_capable_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't add attribute %s for target driver %s", - scst_tgtt_dif_capable_attr.attr.name, tgtt->name); - goto out; - } - } - #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) if (tgtt->trace_flags != NULL) { res = sysfs_create_file(&tgtt->tgtt_kobj, @@ -2591,114 +2524,6 @@ out: } EXPORT_SYMBOL(scst_create_tgt_attr); -static ssize_t scst_tgt_dif_capable_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_tgt *tgt; - - TRACE_ENTRY(); - - tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - - EXTRACHECKS_BUG_ON(!tgt->tgt_dif_supported); - - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "dif_supported"); - - if (tgt->tgt_hw_dif_type1_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type1_supported"); - - if (tgt->tgt_hw_dif_type2_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type2_supported"); - - if (tgt->tgt_hw_dif_type3_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_type3_supported"); - - if (tgt->tgt_hw_dif_ip_supported) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_ip_supported"); - - if (tgt->tgt_hw_dif_same_sg_layout_required) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - ", hw_dif_same_sg_layout_required"); - - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, "\n"); - - if (tgt->tgt_supported_dif_block_sizes) { - const int *p = tgt->tgt_supported_dif_block_sizes; - int j; - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "Supported blocks: "); - j = pos; - while (*p != 0) { - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%d", (j == pos) ? "" : ", ", *p); - p++; - } - } - - TRACE_EXIT_RES(pos); - return pos; -} - -static struct kobj_attribute scst_tgt_dif_capable_attr = - __ATTR(dif_capabilities, S_IRUGO, scst_tgt_dif_capable_show, NULL); - -static ssize_t scst_tgt_dif_checks_failed_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_tgt *tgt; - - tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - - pos = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "\tapp\tref\tguard\n" - "tgt\t%d\t%d\t%d\nscst\t%d\t%d\t%d\ndev\t%d\t%d\t%d\n", - atomic_read(&tgt->tgt_dif_app_failed_tgt), - atomic_read(&tgt->tgt_dif_ref_failed_tgt), - atomic_read(&tgt->tgt_dif_guard_failed_tgt), - atomic_read(&tgt->tgt_dif_app_failed_scst), - atomic_read(&tgt->tgt_dif_ref_failed_scst), - atomic_read(&tgt->tgt_dif_guard_failed_scst), - atomic_read(&tgt->tgt_dif_app_failed_dev), - atomic_read(&tgt->tgt_dif_ref_failed_dev), - atomic_read(&tgt->tgt_dif_guard_failed_dev)); - - return pos; -} - -static ssize_t scst_tgt_dif_checks_failed_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct scst_tgt *tgt; - - tgt = container_of(kobj, struct scst_tgt, tgt_kobj); - - PRINT_INFO("Zeroing DIF failures statistics for target %s", - tgt->tgt_name); - - atomic_set(&tgt->tgt_dif_app_failed_tgt, 0); - atomic_set(&tgt->tgt_dif_ref_failed_tgt, 0); - atomic_set(&tgt->tgt_dif_guard_failed_tgt, 0); - atomic_set(&tgt->tgt_dif_app_failed_scst, 0); - atomic_set(&tgt->tgt_dif_ref_failed_scst, 0); - atomic_set(&tgt->tgt_dif_guard_failed_scst, 0); - atomic_set(&tgt->tgt_dif_app_failed_dev, 0); - atomic_set(&tgt->tgt_dif_ref_failed_dev, 0); - atomic_set(&tgt->tgt_dif_guard_failed_dev, 0); - - return count; -} - -static struct kobj_attribute scst_tgt_dif_checks_failed_attr = - __ATTR(dif_checks_failed, S_IRUGO | S_IWUSR, - scst_tgt_dif_checks_failed_show, - scst_tgt_dif_checks_failed_store); - #define SCST_TGT_SYSFS_STAT_ATTR(member_name, attr, dir, result_op) \ static int scst_tgt_sysfs_##attr##_show_work_fn( \ struct scst_sysfs_work_item *work) \ @@ -2854,26 +2679,6 @@ int scst_tgt_sysfs_create(struct scst_tgt *tgt) goto out_err; } - if (tgt->tgt_dif_supported) { - res = sysfs_create_file(&tgt->tgt_kobj, - &scst_tgt_dif_capable_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't add attribute %s for tgt %s", - scst_tgt_dif_capable_attr.attr.name, - tgt->tgt_name); - goto out_err; - } - - res = sysfs_create_file(&tgt->tgt_kobj, - &scst_tgt_dif_checks_failed_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't add attribute %s for tgt %s", - scst_tgt_dif_checks_failed_attr.attr.name, - tgt->tgt_name); - goto out_err; - } - } - if (tgt->tgtt->tgt_attrs) { res = sysfs_create_files(&tgt->tgt_kobj, tgt->tgtt->tgt_attrs); if (res != 0) { @@ -3592,164 +3397,6 @@ void scst_dev_sysfs_del(struct scst_device *dev) return; } -static ssize_t scst_dev_dif_mode_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_device *dev; - - TRACE_ENTRY(); - - dev = container_of(kobj, struct scst_device, dev_kobj); - - if (dev->dev_dif_mode == SCST_DIF_MODE_NONE) - pos = sprintf(buf, "None\n"); - else { - int j = pos; - - if (dev->dev_dif_mode & SCST_DIF_MODE_TGT) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%s", (j == pos) ? "" : "|", SCST_DIF_MODE_TGT_STR); - - if (dev->dev_dif_mode & SCST_DIF_MODE_SCST) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%s", (j == pos) ? "" : "|", SCST_DIF_MODE_SCST_STR); - - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_CHECK) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%s", (j == pos) ? "" : "|", SCST_DIF_MODE_DEV_CHECK_STR); - - if (dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "%s%s", (j == pos) ? "" : "|", SCST_DIF_MODE_DEV_STORE_STR); - - pos += scnprintf(&buf[pos], SCST_SYSFS_BLOCK_SIZE - pos, - "\n%s", SCST_SYSFS_KEY_MARK "\n"); - } - - TRACE_EXIT_RES(pos); - return pos; -} - -static struct kobj_attribute scst_dev_dif_mode_attr = - __ATTR(dif_mode, S_IRUGO, scst_dev_dif_mode_show, NULL); - -static ssize_t scst_dev_dif_type_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_device *dev; - - TRACE_ENTRY(); - - dev = container_of(kobj, struct scst_device, dev_kobj); - - pos = sprintf(buf, "%d\n%s", dev->dev_dif_type, - (dev->dev_dif_type != 0) ? SCST_SYSFS_KEY_MARK "\n" : ""); - - TRACE_EXIT_RES(pos); - return pos; -} - -static struct kobj_attribute scst_dev_dif_type_attr = - __ATTR(dif_type, S_IRUGO, scst_dev_dif_type_show, NULL); - -static ssize_t scst_dev_sysfs_dif_static_app_tag_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int res; - struct scst_device *dev; - unsigned long long val; - - TRACE_ENTRY(); - - dev = container_of(kobj, struct scst_device, dev_kobj); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) - res = kstrtoull(buf, 0, &val); -#else - res = strict_strtoull(buf, 0, &val); -#endif - if (res != 0) { - PRINT_ERROR("strtoul() for %s failed: %d (device %s)", - buf, res, dev->virt_name); - goto out; - } - - scst_dev_set_dif_static_app_tag_combined(dev, cpu_to_be64(val)); - - res = count; - - PRINT_INFO("APP TAG for device %s changed to %llx", dev->virt_name, - (long long)be64_to_cpu(scst_dev_get_dif_static_app_tag_combined(dev))); - -out: - TRACE_EXIT_RES(res); - return res; -} - -static ssize_t scst_dev_sysfs_dif_static_app_tag_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_device *dev; - __be64 a; - - TRACE_ENTRY(); - - dev = container_of(kobj, struct scst_device, dev_kobj); - - a = scst_dev_get_dif_static_app_tag_combined(dev); - - pos = sprintf(buf, "0x%llx\n%s", (unsigned long long)be64_to_cpu(a), - (a != SCST_DIF_NO_CHECK_APP_TAG) ? SCST_SYSFS_KEY_MARK "\n" : ""); - - TRACE_EXIT_RES(pos); - return pos; -} - -static struct kobj_attribute scst_dev_dif_static_app_tag_attr = - __ATTR(dif_static_app_tag, S_IWUSR|S_IRUGO, - scst_dev_sysfs_dif_static_app_tag_show, - scst_dev_sysfs_dif_static_app_tag_store); - -int scst_dev_sysfs_dif_create(struct scst_device *dev) -{ - int res; - - TRACE_ENTRY(); - - /* - * On errors the caller supposed to unregister this device, hence, - * perform the cleanup. - */ - - res = sysfs_create_file(&dev->dev_kobj, &scst_dev_dif_mode_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't create attr %s for dev %s", - scst_dev_dif_mode_attr.attr.name, dev->virt_name); - goto out; - } - - res = sysfs_create_file(&dev->dev_kobj, &scst_dev_dif_type_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't create attr %s for dev %s", - scst_dev_dif_type_attr.attr.name, dev->virt_name); - goto out; - } - - res = sysfs_create_file(&dev->dev_kobj, &scst_dev_dif_static_app_tag_attr.attr); - if (res != 0) { - PRINT_ERROR("Can't create attr %s for dev %s", - scst_dev_dif_static_app_tag_attr.attr.name, dev->virt_name); - goto out; - } - -out: - TRACE_EXIT_RES(res); - return res; -} - /** ** Tgt_dev implementation **/ @@ -3907,58 +3554,6 @@ static struct kobj_attribute tgt_dev_active_commands_attr = __ATTR(active_commands, S_IRUGO, scst_tgt_dev_active_commands_show, NULL); -static ssize_t scst_tgt_dev_dif_checks_failed_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int pos = 0; - struct scst_tgt_dev *tgt_dev; - - tgt_dev = container_of(kobj, struct scst_tgt_dev, tgt_dev_kobj); - - pos = scnprintf(buf, SCST_SYSFS_BLOCK_SIZE, "\tapp\tref\tguard\n" - "tgt\t%d\t%d\t%d\nscst\t%d\t%d\t%d\ndev\t%d\t%d\t%d\n", - atomic_read(&tgt_dev->tgt_dev_dif_app_failed_tgt), - atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_tgt), - atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_tgt), - atomic_read(&tgt_dev->tgt_dev_dif_app_failed_scst), - atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_scst), - atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_scst), - atomic_read(&tgt_dev->tgt_dev_dif_app_failed_dev), - atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_dev), - atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_dev)); - - return pos; -} - -static ssize_t scst_tgt_dev_dif_checks_failed_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct scst_tgt_dev *tgt_dev; - - tgt_dev = container_of(kobj, struct scst_tgt_dev, tgt_dev_kobj); - - PRINT_INFO("Zeroing DIF failures statistics for initiator " - "%s, target %s, LUN %lld", tgt_dev->sess->initiator_name, - tgt_dev->sess->tgt->tgt_name, (unsigned long long)tgt_dev->lun); - - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_dev, 0); - - return count; -} - -static struct kobj_attribute tgt_dev_dif_checks_failed_attr = - __ATTR(dif_checks_failed, S_IRUGO | S_IWUSR, - scst_tgt_dev_dif_checks_failed_show, - scst_tgt_dev_dif_checks_failed_store); - static struct attribute *scst_tgt_dev_attrs[] = { &tgt_dev_thread_pid_attr.attr, &tgt_dev_active_commands_attr.attr, @@ -4003,25 +3598,9 @@ int scst_tgt_dev_sysfs_create(struct scst_tgt_dev *tgt_dev) goto out; } - if (tgt_dev->sess->tgt->tgt_dif_supported && (tgt_dev->dev->dev_dif_type != 0)) { - res = sysfs_create_file(&tgt_dev->tgt_dev_kobj, - &tgt_dev_dif_checks_failed_attr.attr); - if (res != 0) { - PRINT_ERROR("Adding %s sysfs attribute to tgt_dev %lld " - "failed (%d)", tgt_dev_dif_checks_failed_attr.attr.name, - (unsigned long long)tgt_dev->lun, res); - goto out_del; - } - } - out: TRACE_EXIT_RES(res); return res; - -out_del: - kobject_del(&tgt_dev->tgt_dev_kobj); - kobject_put(&tgt_dev->tgt_dev_kobj); - goto out; } /* @@ -4365,161 +3944,6 @@ static struct kobj_attribute session_active_commands_attr = __ATTR(active_commands, S_IRUGO, scst_sess_sysfs_active_commands_show, NULL); -static int scst_sysfs_sess_get_dif_checks_failed_work_fn(struct scst_sysfs_work_item *work) -{ - int res, t; - struct scst_session *sess = work->sess; - int app_failed_tgt = 0, ref_failed_tgt = 0, guard_failed_tgt = 0; - int app_failed_scst = 0, ref_failed_scst = 0, guard_failed_scst = 0; - int app_failed_dev = 0, ref_failed_dev = 0, guard_failed_dev = 0; - - TRACE_ENTRY(); - - res = mutex_lock_interruptible(&scst_mutex); - if (res != 0) - goto out_put; - - for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { - struct list_head *head = &sess->sess_tgt_dev_list[t]; - struct scst_tgt_dev *tgt_dev; - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { - app_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_app_failed_tgt); - ref_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_tgt); - guard_failed_tgt += atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_tgt); - app_failed_scst += atomic_read(&tgt_dev->tgt_dev_dif_app_failed_scst); - ref_failed_scst += atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_scst); - guard_failed_scst += atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_scst); - app_failed_dev += atomic_read(&tgt_dev->tgt_dev_dif_app_failed_dev); - ref_failed_dev += atomic_read(&tgt_dev->tgt_dev_dif_ref_failed_dev); - guard_failed_dev += atomic_read(&tgt_dev->tgt_dev_dif_guard_failed_dev); - } - } - - mutex_unlock(&scst_mutex); - - work->res_buf = kasprintf(GFP_KERNEL, "\tapp\tref\tguard\n" - "tgt\t%d\t%d\t%d\nscst\t%d\t%d\t%d\ndev\t%d\t%d\t%d\n", - app_failed_tgt, ref_failed_tgt, guard_failed_tgt, - app_failed_scst, ref_failed_scst, guard_failed_scst, - app_failed_dev, ref_failed_dev, guard_failed_dev); - res = work->res_buf ? 0 : -ENOMEM; - -out_put: - kobject_put(&sess->sess_kobj); - - TRACE_EXIT_RES(res); - return res; -} - -static ssize_t scst_sess_sysfs_dif_checks_failed_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - int res; - struct scst_session *sess; - struct scst_sysfs_work_item *work; - - sess = container_of(kobj, struct scst_session, sess_kobj); - - res = scst_alloc_sysfs_work(scst_sysfs_sess_get_dif_checks_failed_work_fn, - true, &work); - if (res != 0) - goto out; - - work->sess = sess; - - SCST_SET_DEP_MAP(work, &scst_sess_dep_map); - kobject_get(&sess->sess_kobj); - - scst_sysfs_work_get(work); - - res = scst_sysfs_queue_wait_work(work); - if (res != 0) - goto out_put; - - res = snprintf(buf, SCST_SYSFS_BLOCK_SIZE, "%s", work->res_buf); - -out_put: - scst_sysfs_work_put(work); - -out: - return res; -} - -static int scst_sess_zero_dif_checks_failed(struct scst_sysfs_work_item *work) -{ - int res, t; - struct scst_session *sess = work->sess; - - TRACE_ENTRY(); - - PRINT_INFO("Zeroing DIF failures statistics for initiator " - "%s, target %s", sess->initiator_name, sess->tgt->tgt_name); - - res = mutex_lock_interruptible(&scst_mutex); - if (res != 0) - goto out_put; - - for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) { - struct list_head *head = &sess->sess_tgt_dev_list[t]; - struct scst_tgt_dev *tgt_dev; - list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) { - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_tgt, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_scst, 0); - atomic_set(&tgt_dev->tgt_dev_dif_app_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_ref_failed_dev, 0); - atomic_set(&tgt_dev->tgt_dev_dif_guard_failed_dev, 0); - } - } - - mutex_unlock(&scst_mutex); - - res = 0; - -out_put: - kobject_put(&sess->sess_kobj); - - TRACE_EXIT_RES(res); - return res; -} - -static ssize_t scst_sess_sysfs_dif_checks_failed_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - int res; - struct scst_session *sess; - struct scst_sysfs_work_item *work; - - TRACE_ENTRY(); - - sess = container_of(kobj, struct scst_session, sess_kobj); - - res = scst_alloc_sysfs_work(scst_sess_zero_dif_checks_failed, false, &work); - if (res != 0) - goto out; - - work->sess = sess; - - SCST_SET_DEP_MAP(work, &scst_sess_dep_map); - kobject_get(&sess->sess_kobj); - - res = scst_sysfs_queue_wait_work(work); - if (res == 0) - res = count; - -out: - TRACE_EXIT_RES(res); - return res; -} - -static struct kobj_attribute session_dif_checks_failed_attr = - __ATTR(dif_checks_failed, S_IRUGO | S_IWUSR, - scst_sess_sysfs_dif_checks_failed_show, - scst_sess_sysfs_dif_checks_failed_store); - static ssize_t scst_sess_sysfs_initiator_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -4705,17 +4129,6 @@ int scst_sess_sysfs_create(struct scst_session *sess) } } - if (sess->tgt->tgt_dif_supported) { - res = sysfs_create_file(&sess->sess_kobj, - &session_dif_checks_failed_attr.attr); - if (res != 0) { - PRINT_ERROR("Adding %s sysfs attribute to session %s " - "failed (%d)", session_dif_checks_failed_attr.attr.name, - name, res); - goto out_del; - } - } - if (sess->tgt->tgtt->sess_attrs) { res = sysfs_create_files(&sess->sess_kobj, sess->tgt->tgtt->sess_attrs); diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 90a85a6d3..2bb613b5c 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -578,14 +578,12 @@ int scst_pre_parse(struct scst_cmd *cmd) TRACE_DBG("op_name <%s> (cmd %p), direction=%d " "(expected %d, set %s), lba %lld, bufflen=%d, data_len %lld, " - "out_bufflen=%d (expected len data %d, expected len DIF %d, " - "out expected len %d), flags=0x%x, , naca %d", - cmd->op_name, cmd, cmd->data_direction, + "out_bufflen=%d (expected len %d, out expected len %d), " + "flags=0x%x, naca %d", cmd->op_name, cmd, cmd->data_direction, cmd->expected_data_direction, scst_cmd_is_expected_set(cmd) ? "yes" : "no", (long long)cmd->lba, cmd->bufflen, (long long)cmd->data_len, - cmd->out_bufflen, scst_cmd_get_expected_transfer_len_data(cmd), - scst_cmd_get_expected_transfer_len_dif(cmd), + cmd->out_bufflen, cmd->expected_transfer_len, cmd->expected_out_transfer_len, cmd->op_flags, cmd->cmd_naca); res = 0; @@ -619,16 +617,6 @@ static bool scst_is_allowed_to_mismatch_cmd(struct scst_cmd *cmd) } #endif -static bool scst_bufflen_eq_expecten_len(struct scst_cmd *cmd) -{ - int b = cmd->bufflen; - - if (cmd->tgt_dif_data_expected) - b += (b >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; - - return b == cmd->expected_transfer_len_full; -} - static int scst_parse_cmd(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_RES_CONT_SAME; @@ -691,12 +679,12 @@ static int scst_parse_cmd(struct scst_cmd *cmd) #ifdef CONFIG_SCST_USE_EXPECTED_VALUES if (scst_cmd_is_expected_set(cmd)) { TRACE(TRACE_MINOR, "Using initiator supplied values: " - "direction %d, transfer_len %d/%d/%d", - scst_cmd_get_expected_transfer_len_data(cmd), - scst_cmd_get_expected_transfer_len_dif(cmd), + "direction %d, transfer_len %d/%d", + cmd->expected_data_direction, + cmd->expected_transfer_len, cmd->expected_out_transfer_len); cmd->data_direction = cmd->expected_data_direction; - cmd->bufflen = scst_cmd_get_expected_transfer_len_data(cmd); + cmd->bufflen = cmd->expected_transfer_len; cmd->data_len = cmd->bufflen; cmd->out_bufflen = cmd->expected_out_transfer_len; } else { @@ -734,7 +722,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd) * expected value, but limit it to some * reasonable value (15MB). */ - cmd->bufflen = min(scst_cmd_get_expected_transfer_len_data(cmd), + cmd->bufflen = min(cmd->expected_transfer_len, 15*1024*1024); cmd->data_len = cmd->bufflen; if (cmd->data_direction == SCST_DATA_BIDI) @@ -797,22 +785,21 @@ static int scst_parse_cmd(struct scst_cmd *cmd) if (scst_cmd_is_expected_set(cmd)) { #ifdef CONFIG_SCST_USE_EXPECTED_VALUES if (unlikely((cmd->data_direction != cmd->expected_data_direction) || - !scst_bufflen_eq_expecten_len(cmd) || + (cmd->bufflen != cmd->expected_transfer_len) || (cmd->out_bufflen != cmd->expected_out_transfer_len))) { TRACE(TRACE_MINOR, "Expected values don't match " "decoded ones: data_direction %d, " "expected_data_direction %d, " - "bufflen %d, expected len data %d, expected len " - "DIF %d, out_bufflen %d, expected_out_transfer_len %d", + "bufflen %d, expected_transfer_len %d, " + "out_bufflen %d, expected_out_transfer_len %d", cmd->data_direction, cmd->expected_data_direction, - cmd->bufflen, scst_cmd_get_expected_transfer_len_data(cmd), - scst_cmd_get_expected_transfer_len_dif(cmd), + cmd->bufflen, cmd->expected_transfer_len, cmd->out_bufflen, cmd->expected_out_transfer_len); PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB", cmd->cdb, cmd->cdb_len); cmd->data_direction = cmd->expected_data_direction; - cmd->bufflen = scst_cmd_get_expected_transfer_len_data(cmd); + cmd->bufflen = cmd->expected_transfer_len; cmd->data_len = cmd->bufflen; cmd->out_bufflen = cmd->expected_out_transfer_len; cmd->resid_possible = 1; @@ -836,15 +823,13 @@ static int scst_parse_cmd(struct scst_cmd *cmd) goto out_done; } } - if (unlikely(!scst_bufflen_eq_expecten_len(cmd))) { + if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) { TRACE(TRACE_MINOR, "Warning: expected " - "transfer length %d (DIF %d) for opcode %s " + "transfer length %d for opcode %s " "(handler %s, target %s) doesn't match " "decoded value %d", - scst_cmd_get_expected_transfer_len_data(cmd), - scst_cmd_get_expected_transfer_len_dif(cmd), - scst_get_opcode_name(cmd), devt->name, - cmd->tgtt->name, cmd->bufflen); + cmd->expected_transfer_len, scst_get_opcode_name(cmd), + devt->name, cmd->tgtt->name, cmd->bufflen); PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB", cmd->cdb, cmd->cdb_len); if ((cmd->expected_data_direction & SCST_DATA_READ) || @@ -893,16 +878,14 @@ set_res: TRACE(TRACE_SCSI, "op_name <%s> (cmd %p), direction=%d " "(expected %d, set %s), lba=%lld, bufflen=%d, data len %lld, " - "out_bufflen=%d, (expected len data %d, expected len DIF %d, " - "out expected len %d), flags=0x%x, internal %d, naca %d", - cmd->op_name, cmd, cmd->data_direction, cmd->expected_data_direction, + "out_bufflen=%d, (expected len %d, out expected len %d), " + "flags=0x%x, internal %d, naca %d", cmd->op_name, cmd, + cmd->data_direction, cmd->expected_data_direction, scst_cmd_is_expected_set(cmd) ? "yes" : "no", (unsigned long long)cmd->lba, cmd->bufflen, (long long)cmd->data_len, cmd->out_bufflen, - scst_cmd_get_expected_transfer_len_data(cmd), - scst_cmd_get_expected_transfer_len_dif(cmd), - cmd->expected_out_transfer_len, cmd->op_flags, cmd->internal, - cmd->cmd_naca); + cmd->expected_transfer_len, cmd->expected_out_transfer_len, + cmd->op_flags, cmd->internal, cmd->cmd_naca); #ifdef CONFIG_SCST_EXTRACHECKS switch (state) { @@ -1062,7 +1045,7 @@ static void scst_set_write_len(struct scst_cmd *cmd) goto out; } else { cmd->write_len = min(cmd->bufflen, - scst_cmd_get_expected_transfer_len_data(cmd)); + cmd->expected_transfer_len); if (cmd->write_len == cmd->bufflen) goto out; } @@ -1180,18 +1163,13 @@ alloc: TRACE_MEM("tgt_i_data_buf_alloced set (cmd %p)", cmd); cmd->sg = cmd->tgt_i_sg; cmd->sg_cnt = cmd->tgt_i_sg_cnt; - cmd->dif_sg = cmd->tgt_i_dif_sg; - cmd->dif_sg_cnt = cmd->tgt_i_dif_sg_cnt; cmd->out_sg = cmd->tgt_out_sg; cmd->out_sg_cnt = cmd->tgt_out_sg_cnt; r = 0; } else { TRACE_MEM("Both *_data_buf_alloced set (cmd %p, sg %p, " - "sg_cnt %d, dif_sg %p, dif_sg_cnt %d, tgt_i_sg %p, " - "tgt_i_sg_cnt %d, tgt_i_dif_sg %p, tgt_i_dif_sg_cnt %d)", - cmd, cmd->sg, cmd->sg_cnt, cmd->dif_sg, cmd->dif_sg_cnt, - cmd->tgt_i_sg, cmd->tgt_i_sg_cnt, cmd->tgt_i_dif_sg, - cmd->tgt_i_dif_sg_cnt); + "sg_cnt %d, tgt_i_sg %p, tgt_i_sg_cnt %d)", cmd, cmd->sg, + cmd->sg_cnt, cmd->tgt_i_sg, cmd->tgt_i_sg_cnt); r = 0; } @@ -3559,7 +3537,6 @@ static int scst_pre_dev_done(struct scst_cmd *cmd) TRACE_ENTRY(); -again: rc = scst_check_auto_sense(cmd); if (unlikely(rc)) { if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) @@ -3590,22 +3567,16 @@ next: goto out; } - if (likely(cmd->status == SAM_STAT_GOOD)) { - if (cmd->deferred_dif_read_check) { - int rc = scst_dif_process_read(cmd); - if (unlikely(rc != 0)) { - cmd->deferred_dif_read_check = 0; - goto again; - } - } - + rc = scsi_status_is_good(cmd->status); + if (likely(rc)) { + unsigned char type = cmd->dev->type; if (unlikely((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10)) && (cmd->tgt_dev->tgt_dev_rd_only || cmd->dev->swp) && - (cmd->dev->type == TYPE_DISK || - cmd->dev->type == TYPE_WORM || - cmd->dev->type == TYPE_MOD || - cmd->dev->type == TYPE_TAPE)) { + (type == TYPE_DISK || + type == TYPE_WORM || + type == TYPE_MOD || + type == TYPE_TAPE)) { int32_t length; uint8_t *address; bool err = false; diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 36cee5cc2..80993cbd3 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -3461,7 +3461,7 @@ static int srpt_xfer_data(struct srpt_rdma_ch *ch, len = scst_get_buf_next(cmd, &buf); } WARN_ON_ONCE(offset != - scst_cmd_get_expected_transfer_len_full(cmd)); + scst_cmd_get_expected_transfer_len(cmd)); } scst_rx_data(cmd, SCST_RX_STATUS_SUCCESS, in_irq() ? SCST_CONTEXT_TASKLET :