diff --git a/share/examples/ses/srcs/getencstat.c b/share/examples/ses/srcs/getencstat.c index 9048f73553a0..7cdde90dc74b 100644 --- a/share/examples/ses/srcs/getencstat.c +++ b/share/examples/ses/srcs/getencstat.c @@ -48,12 +48,14 @@ int main(int a, char **v) { + encioc_string_t stri; encioc_element_t *objp; encioc_elm_status_t ob; encioc_elm_desc_t objd; encioc_elm_devnames_t objdn; int fd, nobj, f, i, verbose, quiet, errors; u_char estat; + char str[32]; if (a < 2) { fprintf(stderr, "usage: %s [ -v ] device [ device ... ]\n", *v); @@ -78,6 +80,16 @@ main(int a, char **v) perror(*v); continue; } + if (verbose > 1) { + stri.bufsiz = sizeof(str); + stri.buf = &str[0]; + if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0) + printf("%s: Enclosure Name: %s\n", *v, stri.buf); + stri.bufsiz = sizeof(str); + stri.buf = &str[0]; + if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0) + printf("%s: Enclosure ID: %s\n", *v, stri.buf); + } if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { perror("ENCIOC_GETNELM"); (void) close(fd); diff --git a/sys/cam/scsi/scsi_enc.c b/sys/cam/scsi/scsi_enc.c index 2bf6b50acea5..844f25aef572 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 a5345f239489..1a97292d33a0 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 223e0e413785..f2593d2e1cbf 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 */ @@ -1382,11 +1383,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) { @@ -1420,6 +1422,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 *) @@ -1456,7 +1459,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); @@ -2709,9 +2711,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) @@ -2736,6 +2751,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;