aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2011-07-05 16:34:52 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-07-22 05:37:47 -0400
commite22a7f075226c51f3f71b922e9eeb4f99fac1475 (patch)
treee0a04f974153136eafe13793ee59be58c37c5ffc
parentb2eb705e00a9b9a9b3122192a7ab3e9058f0c48a (diff)
target: Implement Block Device Characteristics VPD page
Implement page B1h, Block Device Characteristics, so that we can report a medium rotation rate of 1 (non-rotating / solid state) if the is_nonrot device attribute is set; we update the iblock backend to set this attribute if the underlying Linux block device has its nonrot flag set. Signed-off-by: Roland Dreier <roland@purestorage.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_cdb.c17
-rw-r--r--drivers/target/target_core_configfs.c4
-rw-r--r--drivers/target/target_core_device.c13
-rw-r--r--drivers/target/target_core_iblock.c3
-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
7 files changed, 41 insertions, 0 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
index 1157e0c6dba6..432253034de0 100644
--- a/drivers/target/target_core_cdb.c
+++ b/drivers/target/target_core_cdb.c
@@ -535,6 +535,22 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
535 return 0; 535 return 0;
536} 536}
537 537
538/* Block Device Characteristics VPD page */
539static int
540target_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
541{
542 struct se_device *dev = cmd->se_dev;
543
544 buf[0] = dev->transport->get_device_type(dev);
545 buf[3] = 0x3c;
546
547 if (cmd->data_length >= 5 &&
548 dev->se_sub_dev->se_dev_attrib.is_nonrot)
549 buf[5] = 1;
550
551 return 0;
552}
553
538/* Thin Provisioning VPD */ 554/* Thin Provisioning VPD */
539static int 555static int
540target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) 556target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
@@ -599,6 +615,7 @@ static struct {
599 { .page = 0x83, .emulate = target_emulate_evpd_83 }, 615 { .page = 0x83, .emulate = target_emulate_evpd_83 },
600 { .page = 0x86, .emulate = target_emulate_evpd_86 }, 616 { .page = 0x86, .emulate = target_emulate_evpd_86 },
601 { .page = 0xb0, .emulate = target_emulate_evpd_b0 }, 617 { .page = 0xb0, .emulate = target_emulate_evpd_b0 },
618 { .page = 0xb1, .emulate = target_emulate_evpd_b1 },
602 { .page = 0xb2, .emulate = target_emulate_evpd_b2 }, 619 { .page = 0xb2, .emulate = target_emulate_evpd_b2 },
603}; 620};
604 621
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 8d2aba51fc8b..6b00810b8dcb 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -698,6 +698,9 @@ SE_DEV_ATTR(emulate_tpws, S_IRUGO | S_IWUSR);
698DEF_DEV_ATTRIB(enforce_pr_isids); 698DEF_DEV_ATTRIB(enforce_pr_isids);
699SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); 699SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR);
700 700
701DEF_DEV_ATTRIB(is_nonrot);
702SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR);
703
701DEF_DEV_ATTRIB_RO(hw_block_size); 704DEF_DEV_ATTRIB_RO(hw_block_size);
702SE_DEV_ATTR_RO(hw_block_size); 705SE_DEV_ATTR_RO(hw_block_size);
703 706
@@ -746,6 +749,7 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
746 &target_core_dev_attrib_emulate_tpu.attr, 749 &target_core_dev_attrib_emulate_tpu.attr,
747 &target_core_dev_attrib_emulate_tpws.attr, 750 &target_core_dev_attrib_emulate_tpws.attr,
748 &target_core_dev_attrib_enforce_pr_isids.attr, 751 &target_core_dev_attrib_enforce_pr_isids.attr,
752 &target_core_dev_attrib_is_nonrot.attr,
749 &target_core_dev_attrib_hw_block_size.attr, 753 &target_core_dev_attrib_hw_block_size.attr,
750 &target_core_dev_attrib_block_size.attr, 754 &target_core_dev_attrib_block_size.attr,
751 &target_core_dev_attrib_hw_max_sectors.attr, 755 &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 f13e2941936c..440e6b69d47b 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -853,6 +853,7 @@ void se_dev_set_default_attribs(
853 dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS; 853 dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
854 dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA; 854 dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
855 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; 855 dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
856 dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
856 /* 857 /*
857 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK 858 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
858 * iblock_create_virtdevice() from struct queue_limits values 859 * iblock_create_virtdevice() from struct queue_limits values
@@ -1117,6 +1118,18 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag)
1117 return 0; 1118 return 0;
1118} 1119}
1119 1120
1121int se_dev_set_is_nonrot(struct se_device *dev, int flag)
1122{
1123 if ((flag != 0) && (flag != 1)) {
1124 printk(KERN_ERR "Illegal value %d\n", flag);
1125 return -EINVAL;
1126 }
1127 dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
1128 printk(KERN_INFO "dev[%p]: SE Device is_nonrot bit: %d\n",
1129 dev, flag);
1130 return 0;
1131}
1132
1120/* 1133/*
1121 * Note, this can only be called on unexported SE Device Object. 1134 * Note, this can only be called on unexported SE Device Object.
1122 */ 1135 */
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 160c484fd3da..392e75fb1087 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -196,6 +196,9 @@ static struct se_device *iblock_create_virtdevice(
196 " disabled by default\n"); 196 " disabled by default\n");
197 } 197 }
198 198
199 if (blk_queue_nonrot(q))
200 dev->se_sub_dev->se_dev_attrib.is_nonrot = 1;
201
199 return dev; 202 return dev;
200 203
201failed: 204failed:
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index cd163dd94cd4..81deb399bf6a 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -661,6 +661,7 @@ struct se_dev_attrib {
661 int emulate_reservations; 661 int emulate_reservations;
662 int emulate_alua; 662 int emulate_alua;
663 int enforce_pr_isids; 663 int enforce_pr_isids;
664 int is_nonrot;
664 u32 hw_block_size; 665 u32 hw_block_size;
665 u32 block_size; 666 u32 block_size;
666 u32 hw_max_sectors; 667 u32 hw_max_sectors;
diff --git a/include/target/target_core_device.h b/include/target/target_core_device.h
index 96586cc94984..f3b6ae655454 100644
--- a/include/target/target_core_device.h
+++ b/include/target/target_core_device.h
@@ -39,6 +39,7 @@ extern int se_dev_set_emulate_tas(struct se_device *, int);
39extern int se_dev_set_emulate_tpu(struct se_device *, int); 39extern 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_queue_depth(struct se_device *, u32); 43extern int se_dev_set_queue_depth(struct se_device *, u32);
43extern int se_dev_set_max_sectors(struct se_device *, u32); 44extern int se_dev_set_max_sectors(struct se_device *, u32);
44extern int se_dev_set_optimal_sectors(struct se_device *, u32); 45extern 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 2aae76412377..b27ce1af698b 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -101,6 +101,8 @@
101#define DA_ENFORCE_PR_ISIDS 1 101#define DA_ENFORCE_PR_ISIDS 1
102#define DA_STATUS_MAX_SECTORS_MIN 16 102#define DA_STATUS_MAX_SECTORS_MIN 16
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 */
105#define DA_IS_NONROT 0
104 106
105#define SE_MODE_PAGE_BUF 512 107#define SE_MODE_PAGE_BUF 512
106 108