aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-07-17 05:57:58 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-07-22 05:37:49 -0400
commit5de619a31d9cb051d1f818e661af4e54def82316 (patch)
treebbdf282c42fe3818607fff4f3a4f7d1b74ee064e
parent1d20bb6147954d4fbd337a3d1b40c7eeae254cd7 (diff)
target: Update QUEUE ALGORITHM MODIFIER control page default
This patch adds the default 'Unrestricted reordering allowed' for SCSI control mode page QUEUE ALGORITHM MODIFIER on a per se_device basis in target_modesense_control() following spc4r23. This includes a new emuluate_rest_reord configfs attribute that currently (only) accepts zero to signal 'Unrestricted reordering allowed' in control mode page usage by the backend target device. Reported-by: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@risingtidesystems.com>
-rw-r--r--drivers/target/target_core_cdb.c29
-rw-r--r--drivers/target/target_core_configfs.c4
-rw-r--r--drivers/target/target_core_device.c15
-rw-r--r--include/target/target_core_base.h1
-rw-r--r--include/target/target_core_device.h1
-rw-r--r--include/target/target_core_transport.h2
6 files changed, 51 insertions, 1 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 982830023661..145739bcf752 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -775,6 +775,35 @@ target_modesense_control(struct se_device *dev, unsigned char *p)
775 p[1] = 0x0a; 775 p[1] = 0x0a;
776 p[2] = 2; 776 p[2] = 2;
777 /* 777 /*
778 * From spc4r23, 7.4.7 Control mode page
779 *
780 * The QUEUE ALGORITHM MODIFIER field (see table 368) specifies
781 * restrictions on the algorithm used for reordering commands
782 * having the SIMPLE task attribute (see SAM-4).
783 *
784 * Table 368 -- QUEUE ALGORITHM MODIFIER field
785 * Code Description
786 * 0h Restricted reordering
787 * 1h Unrestricted reordering allowed
788 * 2h to 7h Reserved
789 * 8h to Fh Vendor specific
790 *
791 * A value of zero in the QUEUE ALGORITHM MODIFIER field specifies that
792 * the device server shall order the processing sequence of commands
793 * having the SIMPLE task attribute such that data integrity is maintained
794 * for that I_T nexus (i.e., if the transmission of new SCSI transport protocol
795 * requests is halted at any time, the final value of all data observable
796 * on the medium shall be the same as if all the commands had been processed
797 * with the ORDERED task attribute).
798 *
799 * A value of one in the QUEUE ALGORITHM MODIFIER field specifies that the
800 * device server may reorder the processing sequence of commands having the
801 * SIMPLE task attribute in any manner. Any data integrity exposures related to
802 * command sequence order shall be explicitly handled by the application client
803 * through the selection of appropriate ommands and task attributes.
804 */
805 p[3] = (dev->se_sub_dev->se_dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10;
806 /*
778 * From spc4r17, section 7.4.6 Control mode Page 807 * From spc4r17, section 7.4.6 Control mode Page
779 * 808 *
780 * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b 809 * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index e56c39daeec6..a92176d2e187 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -701,6 +701,9 @@ SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);
701DEF_DEV_ATTRIB(is_nonrot); 701DEF_DEV_ATTRIB(is_nonrot);
702SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR); 702SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);
703 703
704DEF_DEV_ATTRIB(emulate_rest_reord);
705SE_DEV_ATTR(emulate_rest_reord, S_IRUGO | S_IWUSR);
706
704DEF_DEV_ATTRIB_RO(hw_block_size); 707DEF_DEV_ATTRIB_RO(hw_block_size);
705SE_DEV_ATTR_RO(hw_block_size); 708SE_DEV_ATTR_RO(hw_block_size);
706 709
@@ -750,6 +753,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
750 &target_core_dev_attrib_emulate_tpws.attr, 753 &target_core_dev_attrib_emulate_tpws.attr,
751 &target_core_dev_attrib_enforce_pr_isids.attr, 754 &target_core_dev_attrib_enforce_pr_isids.attr,
752 &target_core_dev_attrib_is_nonrot.attr, 755 &target_core_dev_attrib_is_nonrot.attr,
756 &target_core_dev_attrib_emulate_rest_reord.attr,
753 &target_core_dev_attrib_hw_block_size.attr, 757 &target_core_dev_attrib_hw_block_size.attr,
754 &target_core_dev_attrib_block_size.attr, 758 &target_core_dev_attrib_block_size.attr,
755 &target_core_dev_attrib_hw_max_sectors.attr, 759 &target_core_dev_attrib_hw_max_sectors.attr,
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 81860ddc7cc4..b38b6c993e65 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -857,6 +857,7 @@ void se_dev_set_default_attribs(
857 dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA; 857 dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
858 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 858 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
859 dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT; 859 dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
860 dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;
860 /* 861 /*
861 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK 862 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
862 * iblock_create_virtdevice() from struct queue_limits values 863 * iblock_create_virtdevice() from struct queue_limits values
@@ -1128,11 +1129,23 @@ int se_dev_set_is_nonrot(struct se_device *dev, int flag)
1128 return -EINVAL; 1129 return -EINVAL;
1129 } 1130 }
1130 dev->se_sub_dev->se_dev_attrib.is_nonrot = flag; 1131 dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
1131 printk(KERN_INFO "dev[%p]: SE Device is_nonrot bit: %d\n", 1132 pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n",
1132 dev, flag); 1133 dev, flag);
1133 return 0; 1134 return 0;
1134} 1135}
1135 1136
1137int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag)
1138{
1139 if (flag != 0) {
1140 printk(KERN_ERR "dev[%p]: SE Device emulatation of restricted"
1141 " reordering not implemented\n", dev);
1142 return -ENOSYS;
1143 }
1144 dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = flag;
1145 pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag);
1146 return 0;
1147}
1148
1136/* 1149/*
1137 * Note, this can only be called on unexported SE Device Object. 1150 * Note, this can only be called on unexported SE Device Object.
1138 */ 1151 */
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 8204c76ca12b..86ca35539b94 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -662,6 +662,7 @@ struct se_dev_attrib {
662 int emulate_alua; 662 int emulate_alua;
663 int enforce_pr_isids; 663 int enforce_pr_isids;
664 int is_nonrot; 664 int is_nonrot;
665 int emulate_rest_reord;
665 u32 hw_block_size; 666 u32 hw_block_size;
666 u32 block_size; 667 u32 block_size;
667 u32 hw_max_sectors; 668 u32 hw_max_sectors;
diff --git a/include/target/target_core_device.h b/include/target/target_core_device.h
index f3b6ae655454..46571912086c 100644
--- a/include/target/target_core_device.h
+++ b/include/target/target_core_device.h
@@ -40,6 +40,7 @@ extern int se_dev_set_emulate_tpu(struct se_device *, int);
40extern int se_dev_set_emulate_tpws(struct se_device *, int); 40extern int se_dev_set_emulate_tpws(struct se_device *, int);
41extern int se_dev_set_enforce_pr_isids(struct se_device *, int); 41extern int se_dev_set_enforce_pr_isids(struct se_device *, int);
42extern int se_dev_set_is_nonrot(struct se_device *, int); 42extern int se_dev_set_is_nonrot(struct se_device *, int);
43extern int se_dev_set_emulate_rest_reord(struct se_device *dev, int);
43extern int se_dev_set_queue_depth(struct se_device *, u32); 44extern int se_dev_set_queue_depth(struct se_device *, u32);
44extern int se_dev_set_max_sectors(struct se_device *, u32); 45extern int se_dev_set_max_sectors(struct se_device *, u32);
45extern int se_dev_set_optimal_sectors(struct se_device *, u32); 46extern int se_dev_set_optimal_sectors(struct se_device *, u32);
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index 54af39d8e3fb..f41b07c7401e 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -103,6 +103,8 @@
103#define DA_STATUS_MAX_SECTORS_MAX 8192 103#define DA_STATUS_MAX_SECTORS_MAX 8192
104/* By default don't report non-rotating (solid state) medium */ 104/* By default don't report non-rotating (solid state) medium */
105#define DA_IS_NONROT 0 105#define DA_IS_NONROT 0
106/* Queue Algorithm Modifier default for restricted reordering in control mode page */
107#define DA_EMULATE_REST_REORD 0
106 108
107#define SE_MODE_PAGE_BUF 512 109#define SE_MODE_PAGE_BUF 512
108 110