summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2013-11-17 14:26:56 -0800
committerRobert Mustacchi <rm@joyent.com>2013-12-16 13:37:26 -0800
commit59d8f1005b65ef8ad2c9ce040497daf81dd65085 (patch)
treec20d3313e8319858158f3ee816ccda62ca909b1f /usr/src
parentd1b18d1a1255ac607d5e072515d727cdfe52f878 (diff)
downloadillumos-gate-59d8f1005b65ef8ad2c9ce040497daf81dd65085.tar.gz
4335 need a mechanism to detect solid state storage devices
Reviewed by: Keith M Wesolowski <wesolows@foobazco.org> Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com> Approved by: Dan McDonald <danmcd@nexenta.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/libdiskmgt/common/disks_private.h3
-rw-r--r--usr/src/lib/libdiskmgt/common/drive.c38
-rw-r--r--usr/src/lib/libdiskmgt/common/findevs.c1
-rw-r--r--usr/src/lib/libdiskmgt/common/libdiskmgt.h1
-rw-r--r--usr/src/uts/common/io/blkdev/blkdev.c11
-rw-r--r--usr/src/uts/common/io/cmlb.c24
-rw-r--r--usr/src/uts/common/io/scsi/targets/sd.c12
-rw-r--r--usr/src/uts/common/io/sdcard/impl/sda_mem.c2
-rw-r--r--usr/src/uts/common/sys/blkdev.h2
-rw-r--r--usr/src/uts/common/sys/dkio.h4
10 files changed, 89 insertions, 9 deletions
diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h
index 0f782bc383..2ef0c3af82 100644
--- a/usr/src/lib/libdiskmgt/common/disks_private.h
+++ b/usr/src/lib/libdiskmgt/common/disks_private.h
@@ -26,8 +26,6 @@
#ifndef _DISKS_PRIVATE_H
#define _DISKS_PRIVATE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -109,6 +107,7 @@ typedef struct disk {
int rpm;
int wide;
int cd_rom;
+ int solid_state;
} disk_t;
typedef struct descriptor {
diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c
index 825348ce9f..10bd06119b 100644
--- a/usr/src/lib/libdiskmgt/common/drive.c
+++ b/usr/src/lib/libdiskmgt/common/drive.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <fcntl.h>
#include <libdevinfo.h>
#include <stdio.h>
@@ -350,6 +348,7 @@ static int get_io_kstats(kstat_ctl_t *kc, char *diskname,
static int get_kstat_vals(kstat_t *ksp, nvlist_t *stats);
static char *get_err_attr_name(char *kstat_name);
static int get_rpm(disk_t *dp, int fd);
+static int get_solidstate(disk_t *dp, int fd);
static int update_stat64(nvlist_t *stats, char *attr,
uint64_t value);
static int update_stat32(nvlist_t *stats, char *attr,
@@ -943,6 +942,16 @@ get_attrs(disk_t *diskp, int fd, char *opath, nvlist_t *attrs)
}
}
+ if (diskp->solid_state < 0) {
+ diskp->solid_state = get_solidstate(diskp, fd);
+ }
+
+ if (diskp->solid_state > 0) {
+ if (nvlist_add_boolean(attrs, DM_SOLIDSTATE) != 0) {
+ return (ENOMEM);
+ }
+ }
+
return (0);
}
@@ -1197,6 +1206,31 @@ get_rpm(disk_t *dp, int fd)
return (rpm);
}
+static int
+get_solidstate(disk_t *dp, int fd)
+{
+ int opened_here = 0;
+ int solid_state = -1;
+
+ /* We may have already opened the device. */
+ if (fd < 0) {
+ fd = drive_open_disk(dp, NULL, 0);
+ opened_here = 1;
+ }
+
+ if (fd >= 0) {
+ if (ioctl(fd, DKIOCSOLIDSTATE, &solid_state) < 0) {
+ solid_state = -1;
+ }
+ }
+
+ if (opened_here) {
+ (void) close(fd);
+ }
+
+ return (solid_state);
+}
+
/*
* ******** the rest of this is uscsi stuff for the drv type ********
*/
diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c
index 9728eab65e..19089e8531 100644
--- a/usr/src/lib/libdiskmgt/common/findevs.c
+++ b/usr/src/lib/libdiskmgt/common/findevs.c
@@ -997,6 +997,7 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
diskp->cd_rom = 0;
diskp->rpm = 0;
+ diskp->solid_state = -1;
type = di_minor_nodetype(args->minor);
prod_id = get_str_prop(PROD_ID_PROP, args->node);
diff --git a/usr/src/lib/libdiskmgt/common/libdiskmgt.h b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
index d075746122..7a2be0f0e5 100644
--- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h
+++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
@@ -147,6 +147,7 @@ typedef enum {
#define DM_PRODUCT_ID "product_id"
#define DM_REMOVABLE "removable" /* also in media */
#define DM_RPM "rpm"
+#define DM_SOLIDSTATE "solid_state"
#define DM_STATUS "status"
#define DM_SYNC_SPEED "sync_speed"
#define DM_TEMPERATURE "temperature"
diff --git a/usr/src/uts/common/io/blkdev/blkdev.c b/usr/src/uts/common/io/blkdev/blkdev.c
index 4c5d87db23..003f06f7f0 100644
--- a/usr/src/uts/common/io/blkdev/blkdev.c
+++ b/usr/src/uts/common/io/blkdev/blkdev.c
@@ -85,6 +85,7 @@ struct bd {
kstat_io_t *d_kiop;
boolean_t d_rdonly;
+ boolean_t d_ssd;
boolean_t d_removable;
boolean_t d_hotpluggable;
boolean_t d_use_dma;
@@ -1118,6 +1119,14 @@ bd_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, int *rvalp)
}
return (0);
}
+ case DKIOCSOLIDSTATE: {
+ int i;
+ i = bd->d_ssd ? 1 : 0;
+ if (ddi_copyout(&i, ptr, sizeof (i), flag)) {
+ return (EFAULT);
+ }
+ return (0);
+ }
case DKIOCSTATE: {
enum dkio_state state;
if (ddi_copyin(ptr, &state, sizeof (state), flag)) {
@@ -1261,6 +1270,7 @@ bd_tg_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)
bd_update_state(bd);
((tg_attribute_t *)arg)->media_is_writable =
bd->d_rdonly ? B_FALSE : B_TRUE;
+ ((tg_attribute_t *)arg)->media_is_solid_state = bd->d_ssd;
return (0);
default:
@@ -1376,6 +1386,7 @@ bd_update_state(bd_t *bd)
bd->d_blkshift = ddi_ffs(media.m_blksize) - 1;
bd->d_numblks = media.m_nblks;
bd->d_rdonly = media.m_readonly;
+ bd->d_ssd = media.m_solidstate;
state = DKIO_INSERTED;
}
diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c
index 0d174501f5..f668380868 100644
--- a/usr/src/uts/common/io/cmlb.c
+++ b/usr/src/uts/common/io/cmlb.c
@@ -20,6 +20,7 @@
*/
/*
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -243,6 +244,7 @@ static i_ddi_prop_dyn_t cmlb_prop_dyn[] = {
{"Size", DDI_PROP_TYPE_INT64, S_IFCHR},
{"device-nblocks", DDI_PROP_TYPE_INT64},
{"device-blksize", DDI_PROP_TYPE_INT},
+ {"device-solid-state", DDI_PROP_TYPE_INT},
{NULL}
};
@@ -5657,11 +5659,12 @@ cmlb_prop_op(cmlb_handle_t cmlbhandle,
struct cmlb_lun *cl;
diskaddr_t capacity;
uint32_t lbasize;
- enum dp { DP_NBLOCKS, DP_BLKSIZE } dp;
+ enum dp { DP_NBLOCKS, DP_BLKSIZE, DP_SSD } dp;
int callers_length;
caddr_t buffer;
uint64_t nblocks64;
uint_t dblk;
+ tg_attribute_t tgattr;
/* Always fallback to ddi_prop_op... */
cl = (struct cmlb_lun *)cmlbhandle;
@@ -5685,6 +5688,8 @@ fallback: return (ddi_prop_op(dev, dip, prop_op, mod_flags,
dp = DP_NBLOCKS;
else if (strcmp(name, "device-blksize") == 0)
dp = DP_BLKSIZE;
+ else if (strcmp(name, "device-solid-state") == 0)
+ dp = DP_SSD;
else
goto fallback;
@@ -5692,7 +5697,7 @@ fallback: return (ddi_prop_op(dev, dip, prop_op, mod_flags,
callers_length = *lengthp;
if (dp == DP_NBLOCKS)
*lengthp = sizeof (uint64_t);
- else if (dp == DP_BLKSIZE)
+ else if ((dp == DP_BLKSIZE) || (dp == DP_SSD))
*lengthp = sizeof (uint32_t);
/* service request for the length of the property */
@@ -5720,11 +5725,20 @@ fallback: return (ddi_prop_op(dev, dip, prop_op, mod_flags,
}
/* transfer the value into the buffer */
- if (dp == DP_NBLOCKS)
+ switch (dp) {
+ case DP_NBLOCKS:
*((uint64_t *)buffer) = capacity;
- else if (dp == DP_BLKSIZE)
+ break;
+ case DP_BLKSIZE:
*((uint32_t *)buffer) = lbasize;
-
+ break;
+ case DP_SSD:
+ if (DK_TG_GETATTRIBUTE(cl, &tgattr, tg_cookie) != 0)
+ tgattr.media_is_solid_state = B_FALSE;
+ *((uint32_t *)buffer) =
+ tgattr.media_is_solid_state ? 1 : 0;
+ break;
+ }
return (DDI_PROP_SUCCESS);
}
diff --git a/usr/src/uts/common/io/scsi/targets/sd.c b/usr/src/uts/common/io/scsi/targets/sd.c
index 6687163bf9..67529e7759 100644
--- a/usr/src/uts/common/io/scsi/targets/sd.c
+++ b/usr/src/uts/common/io/scsi/targets/sd.c
@@ -26,6 +26,7 @@
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
*/
/*
* Copyright 2011 cyril.galibern@opensvc.com
@@ -22323,6 +22324,7 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p)
case DKIOCINFO:
case DKIOCGMEDIAINFO:
case DKIOCGMEDIAINFOEXT:
+ case DKIOCSOLIDSTATE:
case MHIOCENFAILFAST:
case MHIOCSTATUS:
case MHIOCTKOWN:
@@ -22515,6 +22517,16 @@ skip_ready_valid:
}
break;
+ case DKIOCSOLIDSTATE:
+ SD_TRACE(SD_LOG_IOCTL, un, "DKIOCSOLIDSTATE\n");
+ i = un->un_f_is_solid_state ? 1 : 0;
+ if (ddi_copyout(&i, (void *)arg, sizeof (int), flag) != 0) {
+ err = EFAULT;
+ } else {
+ err = 0;
+ }
+ break;
+
case DKIOCHOTPLUGGABLE:
SD_TRACE(SD_LOG_IOCTL, un, "DKIOCHOTPLUGGABLE\n");
i = un->un_f_is_hotpluggable ? 1 : 0;
diff --git a/usr/src/uts/common/io/sdcard/impl/sda_mem.c b/usr/src/uts/common/io/sdcard/impl/sda_mem.c
index 752a3b8a32..1b485cac24 100644
--- a/usr/src/uts/common/io/sdcard/impl/sda_mem.c
+++ b/usr/src/uts/common/io/sdcard/impl/sda_mem.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
*/
/*
@@ -207,6 +208,7 @@ sda_mem_bd_mediainfo(void *arg, bd_media_t *media)
media->m_nblks = slot->s_nblks;
media->m_blksize = slot->s_blksz;
media->m_readonly = slot->s_flags & SLOTF_WRITABLE ? B_FALSE : B_TRUE;
+ media->m_solidstate = B_TRUE;
sda_slot_exit(slot);
return (0);
}
diff --git a/usr/src/uts/common/sys/blkdev.h b/usr/src/uts/common/sys/blkdev.h
index 2307610bae..4ec50fbf3b 100644
--- a/usr/src/uts/common/sys/blkdev.h
+++ b/usr/src/uts/common/sys/blkdev.h
@@ -19,6 +19,7 @@
* CDDL HEADER END
*/
/*
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -116,6 +117,7 @@ struct bd_media {
uint64_t m_nblks;
uint32_t m_blksize;
boolean_t m_readonly;
+ boolean_t m_solidstate;
};
#define BD_INFO_FLAG_REMOVABLE (1U << 0)
diff --git a/usr/src/uts/common/sys/dkio.h b/usr/src/uts/common/sys/dkio.h
index eb4ddf34fe..a5b0c312f9 100644
--- a/usr/src/uts/common/sys/dkio.h
+++ b/usr/src/uts/common/sys/dkio.h
@@ -23,6 +23,7 @@
* Copyright (c) 1982, 2010, Oracle and/or its affiliates. All rights reserved.
*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
*/
#ifndef _SYS_DKIO_H
@@ -237,6 +238,9 @@ struct dk_callback {
#define DKIOCSETEXTPART (DKIOC|46)
#endif
+/* ioctl to report whether the disk is solid state or not - used for ZFS */
+#define DKIOCSOLIDSTATE (DKIOC|38)
+
/*
* Ioctl to force driver to re-read the alternate partition and rebuild
* the internal defect map.