summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-11-28 17:26:46 +0000
committermav <mav@FreeBSD.org>2015-11-28 17:26:46 +0000
commit7c2f90e37a292a6cb6d4d0efa2dacd5db7cc3fd8 (patch)
treeb9f2226710399ba324b64ac18336db36cfd9bd60 /sys/cam
parentd5f5ec6e1a6f9610da0df3ea5898e7111d06e79d (diff)
downloadFreeBSD-src-7c2f90e37a292a6cb6d4d0efa2dacd5db7cc3fd8.zip
FreeBSD-src-7c2f90e37a292a6cb6d4d0efa2dacd5db7cc3fd8.tar.gz
MFC r291126:
Add API to obtain primary enclosure name and ID for /dev/sesX devices. sesX device number may change between reboots, so to properly identify the instance we need more data. Name and ID reported here may mach ones reported by SCSI device, but that is not really required by specs. Sponsored by: iXsystems, Inc.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_enc.c4
-rw-r--r--sys/cam/scsi/scsi_enc.h2
-rw-r--r--sys/cam/scsi/scsi_enc_ses.c55
3 files changed, 58 insertions, 3 deletions
diff --git a/sys/cam/scsi/scsi_enc.c b/sys/cam/scsi/scsi_enc.c
index 2bf6b50..844f25a 100644
--- a/sys/cam/scsi/scsi_enc.c
+++ b/sys/cam/scsi/scsi_enc.c
@@ -407,6 +407,8 @@ enc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag,
case ENCIOC_GETELMSTAT:
case ENCIOC_GETELMDESC:
case ENCIOC_GETELMDEVNAMES:
+ case ENCIOC_GETENCNAME:
+ case ENCIOC_GETENCID:
break;
default:
if ((flag & FWRITE) == 0) {
@@ -461,6 +463,8 @@ enc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag,
case ENCIOC_GETSTRING:
case ENCIOC_SETSTRING:
+ case ENCIOC_GETENCNAME:
+ case ENCIOC_GETENCID:
if (enc->enc_vec.handle_string == NULL) {
error = EINVAL;
break;
diff --git a/sys/cam/scsi/scsi_enc.h b/sys/cam/scsi/scsi_enc.h
index a5345f2..1a97292 100644
--- a/sys/cam/scsi/scsi_enc.h
+++ b/sys/cam/scsi/scsi_enc.h
@@ -46,6 +46,8 @@
#define ENCIOC_GETELMDEVNAMES _IO(ENCIOC, 10)
#define ENCIOC_GETSTRING _IO(ENCIOC, 11)
#define ENCIOC_SETSTRING _IO(ENCIOC, 12)
+#define ENCIOC_GETENCNAME _IO(ENCIOC, 13)
+#define ENCIOC_GETENCID _IO(ENCIOC, 14)
/*
* Platform Independent Definitions for enclosure devices.
diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c
index 95d9105..34b0238 100644
--- a/sys/cam/scsi/scsi_enc_ses.c
+++ b/sys/cam/scsi/scsi_enc_ses.c
@@ -345,8 +345,9 @@ typedef struct ses_cache {
const struct ses_cfg_page *cfg_page;
/* References into the config page. */
+ int ses_nsubencs;
const struct ses_enc_desc * const *subencs;
- uint8_t ses_ntypes;
+ int ses_ntypes;
const ses_type_t *ses_types;
/* Source for all the status pointers */
@@ -1383,11 +1384,12 @@ ses_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
* The cast here is not required in C++ but C99 is not so
* sophisticated (see C99 6.5.16.1(1)).
*/
+ ses_cache->ses_nsubencs = ses_cfg_page_get_num_subenc(cfg_page);
ses_cache->subencs = subencs;
buf_subenc = cfg_page->subencs;
cur_subenc = subencs;
- last_subenc = &subencs[ses_cfg_page_get_num_subenc(cfg_page) - 1];
+ last_subenc = &subencs[ses_cache->ses_nsubencs - 1];
ntype = 0;
while (cur_subenc <= last_subenc) {
@@ -1421,6 +1423,7 @@ ses_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
* Type data is const after construction (i.e. when accessed via
* our cache object.
*/
+ ses_cache->ses_ntypes = ntype;
ses_cache->ses_types = ses_types;
cur_buf_type = (const struct ses_elm_type_desc *)
@@ -1457,7 +1460,6 @@ ses_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
err = ENOMEM;
goto out;
}
- ses_cache->ses_ntypes = (uint8_t)ntype;
enc_cache->nelms = nelm;
ses_iter_init(enc, enc_cache, &iter);
@@ -2712,9 +2714,22 @@ ses_get_elm_devnames(enc_softc_t *enc, encioc_elm_devnames_t *elmdn)
static int
ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, int ioc)
{
+ ses_softc_t *ses;
+ enc_cache_t *enc_cache;
+ ses_cache_t *ses_cache;
+ const struct ses_enc_desc *enc_desc;
int amt, payload, ret;
char cdb[6];
+ char str[32];
+ char vendor[9];
+ char product[17];
+ char rev[5];
uint8_t *buf;
+ size_t size, rsize;
+
+ ses = enc->enc_private;
+ enc_cache = &enc->enc_daemon_cache;
+ ses_cache = enc_cache->private;
/* Implement SES2r20 6.1.6 */
if (sstr->bufsiz > 0xffff)
@@ -2739,6 +2754,40 @@ ses_handle_string(enc_softc_t *enc, encioc_string_t *sstr, int ioc)
amt = payload;
ses_page_cdb(cdb, payload, SesStringIn, CAM_DIR_IN);
buf = sstr->buf;
+ } else if (ioc == ENCIOC_GETENCNAME) {
+ if (ses_cache->ses_nsubencs < 1)
+ return (ENODEV);
+ enc_desc = ses_cache->subencs[0];
+ cam_strvis(vendor, enc_desc->vendor_id,
+ sizeof(enc_desc->vendor_id), sizeof(vendor));
+ cam_strvis(product, enc_desc->product_id,
+ sizeof(enc_desc->product_id), sizeof(product));
+ cam_strvis(rev, enc_desc->product_rev,
+ sizeof(enc_desc->product_rev), sizeof(rev));
+ rsize = snprintf(str, sizeof(str), "%s %s %s",
+ vendor, product, rev) + 1;
+ if (rsize > sizeof(str))
+ rsize = sizeof(str);
+ copyout(&rsize, &sstr->bufsiz, sizeof(rsize));
+ size = rsize;
+ if (size > sstr->bufsiz)
+ size = sstr->bufsiz;
+ copyout(str, sstr->buf, size);
+ return (size == rsize ? 0 : ENOMEM);
+ } else if (ioc == ENCIOC_GETENCID) {
+ if (ses_cache->ses_nsubencs < 1)
+ return (ENODEV);
+ enc_desc = ses_cache->subencs[0];
+ rsize = snprintf(str, sizeof(str), "%16jx",
+ scsi_8btou64(enc_desc->logical_id)) + 1;
+ if (rsize > sizeof(str))
+ rsize = sizeof(str);
+ copyout(&rsize, &sstr->bufsiz, sizeof(rsize));
+ size = rsize;
+ if (size > sstr->bufsiz)
+ size = sstr->bufsiz;
+ copyout(str, sstr->buf, size);
+ return (size == rsize ? 0 : ENOMEM);
} else
return EINVAL;
OpenPOWER on IntegriCloud