Skip to content

Commit

Permalink
OS-1456 need a mechanism to detect solid state storage devices
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith M Wesolowski committed Aug 7, 2012
1 parent c4dae1d commit 281d692
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 5 deletions.
1 change: 1 addition & 0 deletions usr/src/lib/libdiskmgt/common/disks_private.h
Expand Up @@ -109,6 +109,7 @@ typedef struct disk {
int rpm;
int wide;
int cd_rom;
int solid_state;
} disk_t;

typedef struct descriptor {
Expand Down
36 changes: 36 additions & 0 deletions usr/src/lib/libdiskmgt/common/drive.c
Expand Up @@ -350,6 +350,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,
Expand Down Expand Up @@ -943,6 +944,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);
}

Expand Down Expand Up @@ -1197,6 +1208,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 ********
*/
Expand Down
1 change: 1 addition & 0 deletions usr/src/lib/libdiskmgt/common/findevs.c
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions usr/src/lib/libdiskmgt/common/libdiskmgt.h
Expand Up @@ -327,6 +327,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"
Expand Down
11 changes: 11 additions & 0 deletions usr/src/uts/common/io/blkdev/blkdev.c
Expand Up @@ -84,6 +84,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;
Expand Down Expand Up @@ -1102,6 +1103,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)) {
Expand Down Expand Up @@ -1245,6 +1254,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:
Expand Down Expand Up @@ -1360,6 +1370,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;
}

Expand Down
23 changes: 18 additions & 5 deletions usr/src/uts/common/io/cmlb.c
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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}
};

Expand Down Expand Up @@ -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;
Expand All @@ -5685,14 +5688,16 @@ 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;

/* get callers length, establish length of our dynamic prop */
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 */
Expand Down Expand Up @@ -5720,11 +5725,19 @@ 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;
}
return (DDI_PROP_SUCCESS);
}

Expand Down
12 changes: 12 additions & 0 deletions usr/src/uts/common/io/scsi/targets/sd.c
Expand Up @@ -26,6 +26,7 @@
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
*/
/*
* Copyright 2011 cyril.galibern@opensvc.com
Expand Down Expand Up @@ -22322,6 +22323,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:
Expand Down Expand Up @@ -22514,6 +22516,16 @@ sdioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, int *rval_p)
}
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;
Expand Down
2 changes: 2 additions & 0 deletions usr/src/uts/common/io/sdcard/impl/sda_mem.c
Expand Up @@ -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.
*/

/*
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions usr/src/uts/common/sys/blkdev.h
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions usr/src/uts/common/sys/dkio.h
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 281d692

Please sign in to comment.