summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/cam_xpt.c47
-rw-r--r--sys/cam/scsi/scsi_all.c56
-rw-r--r--sys/cam/scsi/scsi_all.h8
-rw-r--r--sys/cam/scsi/scsi_enc_ses.c9
-rw-r--r--sys/geom/geom_disk.c25
5 files changed, 132 insertions, 13 deletions
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 5f1300f..a4c83b1 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -1096,8 +1096,9 @@ xpt_announce_quirks(struct cam_periph *periph, int quirks, char *bit_string)
int
xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
{
- int ret = -1;
+ int ret = -1, l;
struct ccb_dev_advinfo cdai;
+ struct scsi_vpd_id_descriptor *idd;
mtx_assert(path->bus->sim->mtx, MA_OWNED);
@@ -1110,7 +1111,10 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
cdai.buftype = CDAI_TYPE_SERIAL_NUM;
else if (!strcmp(attr, "GEOM::physpath"))
cdai.buftype = CDAI_TYPE_PHYS_PATH;
- else
+ else if (!strcmp(attr, "GEOM::lunid")) {
+ cdai.buftype = CDAI_TYPE_SCSI_DEVID;
+ cdai.bufsiz = CAM_SCSI_DEVID_MAXLEN;
+ } else
goto out;
cdai.buf = malloc(cdai.bufsiz, M_CAMXPT, M_NOWAIT|M_ZERO);
@@ -1123,9 +1127,42 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
if (cdai.provsiz == 0)
goto out;
- ret = 0;
- if (strlcpy(buf, cdai.buf, len) >= len)
- ret = EFAULT;
+ if (cdai.buftype == CDAI_TYPE_SCSI_DEVID) {
+ idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ cdai.provsiz, scsi_devid_is_lun_naa);
+ if (idd == NULL)
+ idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ cdai.provsiz, scsi_devid_is_lun_eui64);
+ if (idd == NULL)
+ idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ cdai.provsiz, scsi_devid_is_lun_t10);
+ if (idd == NULL)
+ idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ cdai.provsiz, scsi_devid_is_lun_name);
+ if (idd == NULL)
+ goto out;
+ ret = 0;
+ if ((idd->proto_codeset & SVPD_ID_CODESET_MASK) == SVPD_ID_CODESET_ASCII ||
+ (idd->proto_codeset & SVPD_ID_CODESET_MASK) == SVPD_ID_CODESET_UTF8) {
+ l = strnlen(idd->identifier, idd->length);
+ if (l < len) {
+ bcopy(idd->identifier, buf, l);
+ buf[l] = 0;
+ } else
+ ret = EFAULT;
+ } else {
+ if (idd->length * 2 < len) {
+ for (l = 0; l < idd->length; l++)
+ sprintf(buf + l * 2, "%02x",
+ idd->identifier[l]);
+ } else
+ ret = EFAULT;
+ }
+ } else {
+ ret = 0;
+ if (strlcpy(buf, cdai.buf, len) >= len)
+ ret = EFAULT;
+ }
out:
if (cdai.buf != NULL)
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index 016aef2..3746312 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -5173,7 +5173,59 @@ scsi_devid_is_sas_target(uint8_t *bufp)
return 1;
}
-uint8_t *
+int
+scsi_devid_is_lun_eui64(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_EUI64)
+ return 0;
+ return 1;
+}
+
+int
+scsi_devid_is_lun_naa(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_NAA)
+ return 0;
+ return 1;
+}
+
+int
+scsi_devid_is_lun_t10(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_T10)
+ return 0;
+ return 1;
+}
+
+int
+scsi_devid_is_lun_name(uint8_t *bufp)
+{
+ struct scsi_vpd_id_descriptor *descr;
+
+ descr = (struct scsi_vpd_id_descriptor *)bufp;
+ if ((descr->id_type & SVPD_ID_ASSOC_MASK) != SVPD_ID_ASSOC_LUN)
+ return 0;
+ if ((descr->id_type & SVPD_ID_TYPE_MASK) != SVPD_ID_TYPE_SCSI_NAME)
+ return 0;
+ return 1;
+}
+
+struct scsi_vpd_id_descriptor *
scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len,
scsi_devid_checkfn_t ck_fn)
{
@@ -5194,7 +5246,7 @@ scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len,
+ desc->length)) {
if (ck_fn == NULL || ck_fn((uint8_t *)desc) != 0)
- return (desc->identifier);
+ return (desc);
}
return (NULL);
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index aff655e..61affec 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -1292,6 +1292,7 @@ struct scsi_vpd_id_descriptor
#define SVPD_ID_PROTO_SHIFT 4
#define SVPD_ID_CODESET_BINARY 0x01
#define SVPD_ID_CODESET_ASCII 0x02
+#define SVPD_ID_CODESET_UTF8 0x03
#define SVPD_ID_CODESET_MASK 0x0f
u_int8_t id_type;
#define SVPD_ID_PIV 0x80
@@ -2316,7 +2317,12 @@ u_int scsi_calc_syncparam(u_int period);
typedef int (*scsi_devid_checkfn_t)(uint8_t *);
int scsi_devid_is_naa_ieee_reg(uint8_t *bufp);
int scsi_devid_is_sas_target(uint8_t *bufp);
-uint8_t * scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
+int scsi_devid_is_lun_eui64(uint8_t *bufp);
+int scsi_devid_is_lun_naa(uint8_t *bufp);
+int scsi_devid_is_lun_name(uint8_t *bufp);
+int scsi_devid_is_lun_t10(uint8_t *bufp);
+struct scsi_vpd_id_descriptor *
+ scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t len,
scsi_devid_checkfn_t ck_fn);
void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c
index c4a8c49..2e51030 100644
--- a/sys/cam/scsi/scsi_enc_ses.c
+++ b/sys/cam/scsi/scsi_enc_ses.c
@@ -1056,7 +1056,8 @@ ses_set_physpath(enc_softc_t *enc, enc_element_t *elm,
ses_setphyspath_callback_args_t args;
int i, ret;
struct sbuf sb;
- uint8_t *devid, *elmaddr;
+ struct scsi_vpd_id_descriptor *idd;
+ uint8_t *devid;
ses_element_t *elmpriv;
const char *c;
@@ -1084,9 +1085,9 @@ ses_set_physpath(enc_softc_t *enc, enc_element_t *elm,
if (cdai.ccb_h.status != CAM_REQ_CMP)
goto out;
- elmaddr = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
+ idd = scsi_get_devid((struct scsi_vpd_device_id *)cdai.buf,
cdai.provsiz, scsi_devid_is_naa_ieee_reg);
- if (elmaddr == NULL)
+ if (idd == NULL)
goto out;
if (sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND) == NULL) {
@@ -1095,7 +1096,7 @@ ses_set_physpath(enc_softc_t *enc, enc_element_t *elm,
}
/* Next, generate the physical path string */
sbuf_printf(&sb, "id1,enc@n%jx/type@%x/slot@%x",
- scsi_8btou64(elmaddr), iter->type_index,
+ scsi_8btou64(idd->identifier), iter->type_index,
iter->type_element_index);
/* Append the element descriptor if one exists */
elmpriv = elm->elm_private;
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index b645040..a9f7048 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -427,8 +427,11 @@ g_disk_start(struct bio *bp)
static void
g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp)
{
+ struct bio *bp;
struct disk *dp;
struct g_disk_softc *sc;
+ char *buf;
+ int res = 0;
sc = gp->softc;
if (sc == NULL || (dp = sc->dp) == NULL)
@@ -443,7 +446,27 @@ g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g
indent, dp->d_fwheads);
sbuf_printf(sb, "%s<fwsectors>%u</fwsectors>\n",
indent, dp->d_fwsectors);
- sbuf_printf(sb, "%s<ident>%s</ident>\n", indent, dp->d_ident);
+ if (dp->d_getattr != NULL) {
+ buf = g_malloc(DISK_IDENT_SIZE, M_WAITOK);
+ bp = g_alloc_bio();
+ bp->bio_disk = dp;
+ bp->bio_attribute = "GEOM::ident";
+ bp->bio_length = DISK_IDENT_SIZE;
+ bp->bio_data = buf;
+ res = dp->d_getattr(bp);
+ sbuf_printf(sb, "%s<ident>%s</ident>\n", indent,
+ res == 0 ? buf: dp->d_ident);
+ bp->bio_attribute = "GEOM::lunid";
+ bp->bio_length = DISK_IDENT_SIZE;
+ bp->bio_data = buf;
+ if (dp->d_getattr(bp) == 0)
+ sbuf_printf(sb, "%s<lunid>%s</lunid>\n",
+ indent, buf);
+ g_destroy_bio(bp);
+ g_free(buf);
+ } else
+ sbuf_printf(sb, "%s<ident>%s</ident>\n", indent,
+ dp->d_ident);
sbuf_printf(sb, "%s<descr>%s</descr>\n", indent, dp->d_descr);
}
}
OpenPOWER on IntegriCloud