diff options
author | Roland Dreier <roland@purestorage.com> | 2011-07-05 16:34:52 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2011-07-22 05:37:47 -0400 |
commit | e22a7f075226c51f3f71b922e9eeb4f99fac1475 (patch) | |
tree | e0a04f974153136eafe13793ee59be58c37c5ffc /drivers/target | |
parent | b2eb705e00a9b9a9b3122192a7ab3e9058f0c48a (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>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_cdb.c | 17 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 13 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 3 |
4 files changed, 37 insertions, 0 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 1157e0c6dba..432253034de 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 */ | ||
539 | static int | ||
540 | target_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 */ |
539 | static int | 555 | static int |
540 | target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | 556 | target_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 8d2aba51fc8..6b00810b8dc 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); | |||
698 | DEF_DEV_ATTRIB(enforce_pr_isids); | 698 | DEF_DEV_ATTRIB(enforce_pr_isids); |
699 | SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); | 699 | SE_DEV_ATTR(enforce_pr_isids, S_IRUGO | S_IWUSR); |
700 | 700 | ||
701 | DEF_DEV_ATTRIB(is_nonrot); | ||
702 | SE_DEV_ATTR(is_nonrot, S_IRUGO | S_IWUSR); | ||
703 | |||
701 | DEF_DEV_ATTRIB_RO(hw_block_size); | 704 | DEF_DEV_ATTRIB_RO(hw_block_size); |
702 | SE_DEV_ATTR_RO(hw_block_size); | 705 | SE_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 f13e2941936..440e6b69d47 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 | ||
1121 | int 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 160c484fd3d..392e75fb108 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 | ||
201 | failed: | 204 | failed: |