-/* $OpenBSD: chio.c,v 1.27 2021/06/26 15:42:58 deraadt Exp $ */
+/* $OpenBSD: chio.c,v 1.28 2021/08/31 05:29:55 robert Exp $ */
/* $NetBSD: chio.c,v 1.1.1.1 1996/04/03 00:34:38 thorpej Exp $ */
/*
static int parse_element_unit(char *);
static int parse_special(char *);
static int is_special(char *);
+static const char * element_type_name(int et);
static char *bits_to_string(int, const char *);
static void find_voltag(char *, int *, int *);
static void check_source_drive(int);
static char *changer_name;
static int avoltag;
static int pvoltag;
+static int sense;
+static int source;
int
main(int argc, char *argv[])
optreset = 1;
optind = 1;
- while ((c = getopt(argc, argv, "vVa")) != -1) {
+ while ((c = getopt(argc, argv, "SsvVa")) != -1) {
switch (c) {
+ case 's':
+ sense = 1;
+ break;
+ case 'S':
+ source = 1;
+ break;
case 'v':
pvoltag = 1;
break;
avoltag = 1;
break;
case 'a':
- pvoltag = avoltag = 1;
+ pvoltag = avoltag = source = sense = 1;
break;
default:
goto usage;
&(cmd.cesr_data[i]);
printf("%s %d: %s", description, i,
bits_to_string(ces->ces_flags, CESTATUS_BITS));
+ if (sense)
+ printf(" sense: <0x%02x/0x%02x>",
+ ces->ces_sensecode,
+ ces->ces_sensequal);
if (pvoltag)
printf(" voltag: <%s:%d>",
ces->ces_pvoltag.cv_volid,
printf(" avoltag: <%s:%d>",
ces->ces_avoltag.cv_volid,
ces->ces_avoltag.cv_serial);
+ if (source) {
+ if (ces->ces_flags & CESTATUS_ACCESS)
+ printf(" source: <%s %d>",
+ element_type_name(
+ ces->ces_source_type),
+ ces->ces_source_addr);
+ else
+ printf(" source: <>");
+ }
printf("\n");
}
errx(1, "invalid element type `%s'", cp);
}
+static const char *
+element_type_name(int et)
+{
+ int i;
+
+ for (i = 0; elements[i].et_name != NULL; i++)
+ if (elements[i].et_type == et)
+ return elements[i].et_name;
+
+ return "unknown";
+}
+
static int
parse_element_unit(char *cp)
{
-/* $OpenBSD: ch.c,v 1.68 2021/03/12 10:22:46 jsg Exp $ */
+/* $OpenBSD: ch.c,v 1.69 2021/08/31 05:29:55 robert Exp $ */
/* $NetBSD: ch.c,v 1.26 1997/02/21 22:06:52 thorpej Exp $ */
/*
* changer_element_status structure.
*/
static void
-copy_element_status(int flags, struct read_element_status_descriptor *desc,
+copy_element_status(struct ch_softc *sc, int flags,
+ struct read_element_status_descriptor *desc,
struct changer_element_status *ces)
{
+ u_int16_t eaddr = _2btol(desc->eaddr);
+ u_int16_t et;
+
+ for (et = CHET_MT; et <= CHET_DT; et++) {
+ if ((sc->sc_firsts[et] <= eaddr)
+ && ((sc->sc_firsts[et] + sc->sc_counts[et])
+ > eaddr)) {
+ ces->ces_addr = eaddr - sc->sc_firsts[et];
+ ces->ces_type = et;
+ break;
+ }
+ }
+
ces->ces_flags = desc->flags1;
+ ces->ces_sensecode = desc->sense_code;
+ ces->ces_sensequal = desc->sense_qual;
+
+ if (desc->flags2 & READ_ELEMENT_STATUS_INVERT)
+ ces->ces_flags |= READ_ELEMENT_STATUS_EXCEPT;
+
+ if (desc->flags2 & READ_ELEMENT_STATUS_SVALID) {
+ eaddr = _2btol(desc->ssea);
+
+ /* convert source address to logical format */
+ for (et = CHET_MT; et <= CHET_DT; et++) {
+ if ((sc->sc_firsts[et] <= eaddr)
+ && ((sc->sc_firsts[et] + sc->sc_counts[et])
+ > eaddr)) {
+ ces->ces_source_addr =
+ eaddr - sc->sc_firsts[et];
+ ces->ces_source_type = et;
+ ces->ces_flags |= READ_ELEMENT_STATUS_ACCESS;
+ break;
+ }
+ }
+
+ if (!(ces->ces_flags & READ_ELEMENT_STATUS_ACCESS))
+ printf("ch: warning: could not map element source "
+ "address %ud to a valid element type\n",
+ eaddr);
+ }
+
if (ISSET(flags, READ_ELEMENT_STATUS_PVOLTAG))
copy_voltag(&ces->ces_pvoltag, &desc->pvoltag);
if (ISSET(flags, READ_ELEMENT_STATUS_AVOLTAG))
desc = (caddr_t)(pg_hdr + 1);
for (i = 0; i < avail; ++i) {
struct changer_element_status *ces = &(user_data[i]);
- copy_element_status(pg_hdr->flags,
+ copy_element_status(sc, pg_hdr->flags,
(struct read_element_status_descriptor *)desc, ces);
desc += desclen;
}
-/* $OpenBSD: chio.h,v 1.7 2006/05/31 03:01:44 beck Exp $ */
+/* $OpenBSD: chio.h,v 1.8 2021/08/31 05:29:55 robert Exp $ */
/* $NetBSD: chio.h,v 1.8 1996/04/03 00:25:21 thorpej Exp $ */
/*
struct changer_element_status {
int ces_type; /* element type */
u_int8_t ces_flags; /* flags */
+ u_int16_t ces_addr; /* logical element address */
+ u_int8_t ces_sensecode; /* additional sense code for element */
+ u_int8_t ces_sensequal; /* additional sense code qualifier */
+ u_int8_t ces_source_type; /* element type of source address */
+ u_int16_t ces_source_addr; /* source address of medium */
struct changer_voltag ces_pvoltag; /* primary voltag */
struct changer_voltag ces_avoltag; /* alternate voltag */
};