[PATCH v2] spc: implement spc 0xb1 and support rotation rate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Rotation rate is sensitive to some applications, typically database need to
recognize sdx device is HDD or SSD.

This patch implements basic vpd 0xb1, and supports parameter 'rotation_rate',
we can update rotation_rate by tgtadm command.

Test case 1:
T# tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 1 --params rotation_rate=1
I# cat /sys/block/sdb/queue/rotational
   0
I# sg_vpd -p 0xb1 /dev/sdb
   Block device characteristics VPD page (SBC):
     Non-rotating medium (e.g. solid state)

Test case 2:
T# tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 1 --params rotation_rate=15000
I# cat /sys/block/sdb/queue/rotational
   1
I# sg_vpd -p 0xb1 /dev/sdb
   Block device characteristics VPD page (SBC):
     Nominal rotation rate: 15000 rpm

All of testing case work well.

Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx>
---
 usr/spc.c  | 36 ++++++++++++++++++++++++++++++++++++
 usr/tgtd.h |  2 ++
 2 files changed, 38 insertions(+)

diff --git a/usr/spc.c b/usr/spc.c
index 902d5bf..a32eda7 100644
--- a/usr/spc.c
+++ b/usr/spc.c
@@ -192,6 +192,26 @@ static void update_vpd_83(struct scsi_lu *lu, void *id)
 	data[0] |= NAA_IEEE_REGD_EXTD << 4;
 }
 
+static void update_vpd_b1(struct scsi_lu *lu, void *id)
+{
+	struct vpd *vpd_pg = lu->attrs.lu_vpd[PCODE_OFFSET(0xb1)];
+	uint8_t	*data = vpd_pg->data;
+
+	if (lu->attrs.rotation_rate) {
+		data[0] = (lu->attrs.rotation_rate >> 8) & 0xff;
+		data[1] = lu->attrs.rotation_rate & 0xff;
+		data[2] = 0; /* PRODUCT TYPE */
+		data[3] = 0; /* WABEREQ | WACEREQ | NOMINAL FORM FACTOR */
+		data[4] = 0; /* VBULS */
+	} else {
+		data[0] = 0;
+		data[1] = 0;
+		data[2] = 0;
+		data[3] = 0;
+		data[4] = 0;
+	}
+}
+
 static void update_vpd_b2(struct scsi_lu *lu, void *id)
 {
 	struct vpd *vpd_pg = lu->attrs.lu_vpd[PCODE_OFFSET(0xb2)];
@@ -1910,6 +1930,7 @@ enum {
 	Opt_mode_page,
 	Opt_path, Opt_bsopts,
 	Opt_bsoflags, Opt_thinprovisioning,
+	Opt_rotation_rate,
 	Opt_err,
 };
 
@@ -1932,6 +1953,7 @@ static match_table_t tokens = {
 	{Opt_bsopts, "bsopts=%s"},
 	{Opt_bsoflags, "bsoflags=%s"},
 	{Opt_thinprovisioning, "thin_provisioning=%s"},
+	{Opt_rotation_rate, "rotation_rate=%s"},
 	{Opt_err, NULL},
 };
 
@@ -2030,6 +2052,12 @@ tgtadm_err lu_config(struct scsi_lu *lu, char *params, match_fn_t *fn)
 			lu_vpd[PCODE_OFFSET(0xb0)]->vpd_update(lu, NULL);
 			lu_vpd[PCODE_OFFSET(0xb2)]->vpd_update(lu, NULL);
 			break;
+		case Opt_rotation_rate:
+			match_strncpy(buf, &args[0], sizeof(buf));
+			attrs->rotation_rate = atoi(buf);
+			/* update the characteristics vpd page */
+			lu_vpd[PCODE_OFFSET(0xb1)]->vpd_update(lu, NULL);
+			break;
 		case Opt_online:
 			match_strncpy(buf, &args[0], sizeof(buf));
 			if (atoi(buf))
@@ -2107,6 +2135,14 @@ int spc_lu_init(struct scsi_lu *lu)
 	lu_vpd[pg]->vpd_update = update_vpd_b0;
 	lu_vpd[pg]->vpd_update(lu, NULL);
 
+	/* VPD page 0xb1 BLOCK DEVICE CHARACTERISTICS*/
+	pg = PCODE_OFFSET(0xb1);
+	lu_vpd[pg] = alloc_vpd(BDC_VPD_LEN);
+	if (!lu_vpd[pg])
+		return -ENOMEM;
+	lu_vpd[pg]->vpd_update = update_vpd_b1;
+	lu_vpd[pg]->vpd_update(lu, NULL);
+
 	/* VPD page 0xb2 LOGICAL BLOCK PROVISIONING*/
 	pg = PCODE_OFFSET(0xb2);
 	lu_vpd[pg] = alloc_vpd(LBP_VPD_LEN);
diff --git a/usr/tgtd.h b/usr/tgtd.h
index d8b2ac1..cf3ade3 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -20,6 +20,7 @@ struct concat_buf;
 #define PRODUCT_ID_LEN		16
 #define PRODUCT_REV_LEN		4
 #define BLOCK_LIMITS_VPD_LEN	0x3C
+#define BDC_VPD_LEN		0x40
 #define LBP_VPD_LEN		4
 
 #define PCODE_SHIFT		7
@@ -89,6 +90,7 @@ struct lu_phy_attr {
 	char no_auto_lbppbe;    /* Do not update it automatically when the
 				   backing file changes */
 	uint16_t la_lba;	/* Lowest aligned LBA */
+	uint16_t rotation_rate;	/* Block rotation rate */
 
 	/* VPD pages 0x80 -> 0xff masked with 0x80*/
 	struct vpd *lu_vpd[1 << PCODE_SHIFT];
-- 
2.11.0




[Index of Archives]     [Linux SCSI]     [Linux RAID]     [Linux Clusters]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]

  Powered by Linux