diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2005-07-18 01:29:20 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2005-07-18 01:29:20 +0000 |
commit | 0a0c127ebff9b2eab4a05ec6ea5b9e1f166f3e3d (patch) | |
tree | 5b8b708463f89bad830a2450d17e8f36a099e4cf | |
parent | 55c922539f00e75ede1934fecab3da3ce9080b32 (diff) |
Kill initial implementation because it sucked. It was far too complex the new
paradigm is to virtualize the operations. Using physical data is really only
necessary on low end hardware or by advanced users.
For now only support the inquiry operation.
ok dlg@
-rw-r--r-- | sbin/bioctl/Makefile | 5 | ||||
-rw-r--r-- | sbin/bioctl/bioctl.c | 1018 | ||||
-rw-r--r-- | sbin/bioctl/bioctl.h | 52 |
3 files changed, 64 insertions, 1011 deletions
diff --git a/sbin/bioctl/Makefile b/sbin/bioctl/Makefile index 874902df84b..8c28a82ef3c 100644 --- a/sbin/bioctl/Makefile +++ b/sbin/bioctl/Makefile @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile,v 1.3 2005/07/01 21:53:40 marco Exp $ +# $OpenBSD: Makefile,v 1.4 2005/07/18 01:29:19 marco Exp $ PROG= bioctl -LDADD= -lutil +CFLAGS= -Wall +LDADD= -lutil MAN= bioctl.8 .include <bsd.prog.mk> diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c index 370c985efcb..7a49147047f 100644 --- a/sbin/bioctl/bioctl.c +++ b/sbin/bioctl/bioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.c,v 1.11 2005/07/01 21:53:40 marco Exp $ */ +/* $OpenBSD: bioctl.c,v 1.12 2005/07/18 01:29:19 marco Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom * All rights reserved. @@ -26,13 +26,6 @@ * */ -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <util.h> - #include <sys/ioctl.h> #include <sys/param.h> #include <sys/queue.h> @@ -41,18 +34,20 @@ #include <scsi/scsi_ses.h> #include <dev/biovar.h> +#include <errno.h> +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <util.h> + #include "bioctl.h" /* globals */ const char *bio_device = "/dev/bio"; -SLIST_HEAD(dev_list, dev); - -/* RAID card device list */ -struct dev_list devices = SLIST_HEAD_INITIALIZER(dev); -/* User provided device list*/ -struct dev_list ul = SLIST_HEAD_INITIALIZER(dev); - int devh = -1; int debug = 0; @@ -63,79 +58,37 @@ main(int argc, char *argv[]) { extern char *optarg; - bioc_capabilities bc; - bioc_alarm ba; + u_int64_t func = 0; + /* u_int64_t subfunc = 0; */ int ch; int rv; - unsigned char *pl; char *bioc_dev = NULL; char *sd_dev = NULL; char *realname = NULL; - char *al_arg = NULL; /* argument to alarm */ - char *ss_arg = NULL; /* argument to start/stop */ - char inq[INQSIZE]; - - struct dev *delm; - - u_int64_t func = 0, subfunc = 0; - u_int32_t devlist = 0; if (argc < 2) usage(); atexit(cleanup); - while ((ch = getopt(argc, argv, "a:b:Dd:ef:hl:pst:u:")) != -1) { + while ((ch = getopt(argc, argv, "Dd:f:i")) != -1) { switch (ch) { - case 'a': /* alarm */ - func |= BIOC_ALARM; - al_arg = optarg; - break; - case 'b': /* LED blink/unblink */ - func |= BIOC_BLINK; - al_arg = optarg; - break; - - case 'D': /* enable debug */ + case 'D': /* debug */ debug = 1; break; - case 'd': /* device */ + case 'd': /* bio device */ bioc_dev = optarg; break; - case 'e': /* enumerate */ - func |= BIOC_SCSICMD; - subfunc |= F_ENUM; - break; - - case 'f': /* device */ + case 'f': /* scsi device */ sd_dev = optarg; break; - case 'l': /* device list, separated for now use one dev only*/ - func |= PARSELIST; - pl = optarg; - break; - - case 'p': /* ping */ - func |= BIOC_PING; - break; - - case 's': /* status */ - func |= BIOC_STATUS; - break; - - case 't': - func |= BIOC_SCSICMD; - subfunc |= parse_passthru(optarg); - break; - - case 'u': /* start/stop */ - func |= BIOC_STARTSTOP; - ss_arg = optarg; + case 'i': /* inquiry */ + func |= BIOC_INQ; break; case 'h': /* help/usage */ @@ -171,80 +124,8 @@ main(int argc, char *argv[]) if (debug) warnx("cookie = %p", bl.cookie); - if (func & PARSELIST) - parse_devlist(pl); - - if (!bio_get_capabilities(&bc)) - warnx("could not retrieve capabilities."); - else { - /* we should have everything setup by now so get to work */ - if (func & BIOC_ALARM) - if (bc.ioctls & BIOC_ALARM) - bio_alarm(al_arg); - else - warnx("alarms are not supported."); - - if (func & BIOC_BLINK) - if (bc.ioctls & BIOC_BLINK) - SLIST_FOREACH(delm, &ul, next) { - bio_blink(al_arg, delm->channel, - delm->target); - } - else - warnx("blink is not supported."); - - if (func & BIOC_PING) - if (bc.ioctls & BIOC_PING) - bio_ping(); - else - warnx("ping not supported."); - - if (func & BIOC_STATUS) { - if (bc.ioctls & BIOC_STATUS) - bio_status(); - else - warnx("status function not supported."); - } - - if (func & BIOC_STARTSTOP) { - if (bc.ioctls & BIOC_STARTSTOP) { - SLIST_FOREACH(delm, &ul, next) { - bio_startstop(ss_arg, - delm->channel, delm->target); - } - } else - warnx("start/stop unit not supported."); - } - - if (func & BIOC_SCSICMD) { - if (bc.ioctls & BIOC_SCSICMD) { - if (subfunc & F_READCAP) { - SLIST_FOREACH(delm, &ul, next) { - bio_pt_readcap(delm->channel, - delm->target, F_NOISY); - } - } - - if (subfunc & F_INQUIRY) { - SLIST_FOREACH(delm, &ul, next) { - bio_pt_inquire(delm->channel, - delm->target, F_NOISY, - &inq[0]); - } - } - - if (subfunc & F_TUR) { - SLIST_FOREACH(delm, &ul, next) { - bio_pt_tur(delm->channel, - delm->target); - } - } - - if (subfunc & F_ENUM) - bio_pt_enum(); - } else - warnx("passthrough not supported."); - } + if (func & BIOC_INQ) { + bio_inq(); } return (0); @@ -255,9 +136,7 @@ usage(void) { extern char *__progname; - fprintf(stderr, "usage: %s [-Dehpt] [-a function] [-b function] " - "[-l device list]\n" - "\t[-u function] [-d device | -f disk]\n", __progname); + fprintf(stderr, "usage: %s [-Di] [-d device | -f disk]\n", __progname); exit(1); } @@ -265,855 +144,72 @@ usage(void) void cleanup(void) { - struct dev *delm; - if (debug) printf("atexit\n"); - while (devices.slh_first != NULL) { - delm = devices.slh_first; - SLIST_REMOVE_HEAD(&devices, next); - if (debug) - printf("free device: %p\n", delm); - free(delm); - } - - while (ul.slh_first != NULL) { - delm = ul.slh_first; - SLIST_REMOVE_HEAD(&ul, next); - if (debug) - printf("free ul: %p\n", delm); - free(delm); - } - if (devh != -1) close(devh); } -u_int64_t -parse_passthru(char *f) -{ - if (debug) - printf("get_subfunc: %s, ", f); - - switch (f[0]) { - case 'i': /* INQUIRY */ - if (debug) - printf("inquiry\n"); - return (F_INQUIRY); - - case 'e': /* ENUMERATE, not a pass through hmmm */ - if (debug) - printf("enumerate\n"); - return (F_ENUM); - - case 'r': /* READ CAPACITY */ - if (debug) - printf("read cap\n"); - return (F_READCAP); - - case 't': /* TUR */ - if (debug) - printf("TUR\n"); - return (F_TUR); - - default: - errx(1, "invalid pass through function"); - } -} - void -parse_devlist(char *dl) +bio_inq(void) { - u_int8_t c , t, done = 0; - char *es, *s; - struct dev *delm; - - es = NULL; - s = dl; + bioc_inq bi; + bioc_vol bv; + bioc_disk bd; - if (debug) - printf("parse: %s\n", dl); + int rv, i, d; - while (!done) { - c = strtol(s, &es, 10); - if (debug) - printf("%p %p %u %c\n", s, es, c, es[0]); - s = es; - if (es[0] == ':') { - s++; - t = strtol(s, &es, 10); - if (debug) - printf("%p %p %u %c\n", s, es, t, es[0]); - s = es; - - if (c > 4) - errx(1, "invalid channel number"); - if (t > 16) - errx(1, "invalid target number"); - - delm = malloc(sizeof(struct dev)); - if (!delm) - errx(1, "not enough memory"); - - delm->target = t; - delm->channel = c; - SLIST_INSERT_HEAD(&ul, delm, next); - } - if (es[0] == ',') { - s++; - continue; - } - if (es[0] == '\0') { - done = 1; - continue; - } - done = 2; - } - - if (done == 2) { - /* boink */ - errx(1, "invalid device list."); - } -} - -int -bio_get_capabilities(bioc_capabilities *bc) -{ - int rv; - - bc->cookie = bl.cookie; - rv = ioctl(devh, BIOCCAPABILITIES, bc); - if (rv == -1) { - warnx("Error calling bioc_ioctl() via bio_ioctl()"); - return 0; - } - - if (debug) { - printf("ioctls = %016llx\n", bc->ioctls); - printf("raid_types = %08lx\n", bc->raid_types); - } - - return (1); -} - -void -bio_alarm(char *arg) -{ - int rv; - bioc_alarm ba; + memset(&bi, 0, sizeof(bi)); if (debug) - printf("alarm in: %s, ", arg); - - ba.cookie = bl.cookie; + printf("bio_inq\n"); - switch (arg[0]) { - case 'q': /* silence alarm */ - /* FALLTHROUGH */ - case 's': - if (debug) - printf("silence\n"); - ba.opcode = BIOCSALARM_SILENCE; - break; + bi.cookie = bl.cookie; - case 'e': /* enable alarm */ - if (debug) - printf("enable\n"); - ba.opcode = BIOCSALARM_ENABLE; - break; - - case 'd': /* disable alarm */ - if (debug) - printf("disable\n"); - ba.opcode = BIOCSALARM_DISABLE; - break; - - case 't': /* test alarm */ - if (debug) - printf("test\n"); - ba.opcode = BIOCSALARM_TEST; - break; - - case 'g': /* get alarm state */ - if (debug) - printf("get state\n"); - ba.opcode = BIOCGALARM_STATE; - break; - - default: - warnx("invalid alarm function: %s", arg); - return; - } - - rv = ioctl(devh, BIOCALARM, &ba); + rv = ioctl(devh, BIOCINQ, &bi); if (rv == -1) { warnx("bioc_ioctl() call failed"); return; } - if (arg[0] == 'g') { - printf("alarm is currently %s\n", - ba.state ? "enabled" : "disabled"); - } -} - -void -ses_verbose(u_int8_t *rc, u_int8_t len) -{ - struct ses_config_page *scp; - struct ses_type_desc_hdr *tdh; - - char *str; - u_int8_t i; - - scp = (struct ses_config_page *)rc; - printf("element types: %d, id: %s\n", scp->nr_elem_typ, - scp->enc_vendor_id); - - str = (char *) - (&scp->enc_desc_len + scp->enc_desc_len + 1 + - (scp->nr_elem_typ * sizeof(struct ses_type_desc_hdr))); - - for (i = 0; i < scp->nr_elem_typ; i++) { - tdh = (struct ses_type_desc_hdr *) - (&scp->enc_desc_len + scp->enc_desc_len + 1 + - (i * sizeof(struct ses_type_desc_hdr))); - - printf("type: %d, count: %d, sub enclosure id: %d, " - "len: %d, text: %s\n", - tdh->elem_type, tdh->nr_elem, tdh->sub_enc_id, - tdh->type_desc_len, str); + printf("RAID volumes : %d\n", bi.novol); + printf("Physical disks : %d\n\n", bi.nodisk); - str += tdh->type_desc_len; - } -} - -void -bio_blink_userland(u_int8_t opc, u_int8_t c, u_int8_t t) -{ - struct dev *delm; + for (i = 0; i < bi.novol; i++) { + memset(&bv, 0, sizeof(bv)); + bv.cookie = bl.cookie; + bv.volid = i; - /* page 1 stuff */ - struct ses_enc_ctrl_diag_page *cdp; - struct ses_config_page *scp; - struct ses_type_desc_hdr *tdh; - - /* page 2 stuff */ - struct ses_enc_stat_diag_page *esdp; - struct ses_dev_elmt_status_diag *desd; - - u_int8_t rc[SESSIZE]; - u_int8_t rc2[SESSIZE]; - u_int8_t i, elements, found = 0; - - /* FIXME if the raid controllers are clustered we might have more - * than one proc device. */ - - bio_pt_enum(); - - SLIST_FOREACH(delm, &devices, next) { - if (delm->channel != c) - continue; - - if (delm->type != T_PROCESSOR) - continue; - - if (debug) - printf("proc at channel: %d target: %2d\n", - delm->channel, delm->target); - - /* figure out what we have */ - if (!get_ses_page(delm->channel, delm->target, - SES_CFG_DIAG_PAGE, &rc[0], sizeof(rc))) { - return; - } - - if (debug) - ses_verbose(&rc[0], sizeof(rc)); - - /* find first disk element */ - elements = 0; - scp = (struct ses_config_page *)rc; - for (i = 0; i < scp->nr_elem_typ; i++) { - tdh = (struct ses_type_desc_hdr *) - (&scp->enc_desc_len + scp->enc_desc_len + 1 + - (i * sizeof(struct ses_type_desc_hdr))); - - if (tdh->elem_type == STDH_DEVICE) { - found = 1; - break; - } - elements += tdh->nr_elem; - } - - if (debug) { - printf("tdh->elem_type: %d, tdh->nr_elem: %d, " - "elements: %d\n", - tdh->elem_type, tdh->nr_elem, elements); - } - - if (!found) { - if (debug) - printf("no devices found\n"); - - return; - } - - /* get ses page so that we can modify bits for blink */ - if (!get_ses_page(delm->channel, delm->target, - SES_CTRL_DIAG_PAGE, &rc2[0], sizeof(rc2))) { + rv = ioctl(devh, BIOCVOL, &bv); + if (rv == -1) { + warnx("bioc_ioctl() call failed"); return; } - esdp = (struct ses_enc_stat_diag_page *)rc2; - desd = (struct ses_dev_elmt_status_diag *) - (esdp->elmts + elements); /* FIXME do we need padding? */ + printf("\tvolume id: %d\n", bv.volid); + printf("\tstatus : %d\n", bv.status); + printf("\tsize : %lld\n", bv.size); + printf("\traid : %d\n", bv.level); + printf("\tnr disks : %d\n", bv.nodisk); - /* loop through all slots to see if target is available */ - found = 0; - for (i = 0; i < tdh->nr_elem; i++) { - if (debug) - printf("stat: %d, addr: %d, b3: %d, b4: %d\n", - desd->common_status, - desd->slot_addr, - desd->byte3, - desd->byte4); + for (d = 0; d < bv.nodisk; d++) { + memset(&bd, 0, sizeof(bd)); + bd.cookie = bl.cookie; + bd.diskid = 0; - if (t == desd->slot_addr) { - found = 1; - break; + rv = ioctl(devh, BIOCDISK, &bd); + if (rv == -1) { + warnx("bioc_ioctl() call failed"); + return; } - desd += 1; /* next element */ - } - - if (!found) { - printf("target: %d not found\n", t); - - return; - } - - cdp = (struct ses_enc_ctrl_diag_page *)rc2; - cdp->elmts[i].common_ctrl = SDECD_SELECT; - switch (opc) { - case BIOCSBLINK_ALERT: - cdp->elmts[i].byte4 = SDECD_RQST_FAULT; - cdp->elmts[i].byte3 = 0x00; - break; - - case BIOCSBLINK_BLINK: - cdp->elmts[i].byte3 = SDECD_RQST_IDENT; - cdp->elmts[i].byte4 = 0x00; - break; - - case BIOCSBLINK_UNBLINK: - cdp->elmts[i].byte3 = 0x00; - cdp->elmts[i].byte4 = 0x00; - break; - - default: - return; - } - - if (!set_ses_page(delm->channel, delm->target, - &rc2[0], sizeof(rc2))) { - return; - } - - return; /* done */ - } -} - -void -bio_blink(char * arg, u_int8_t c, u_int8_t t) -{ - int rv; - bioc_blink bb; - - if (debug) - printf("blink in: %s, ", arg); - - bb.cookie = bl.cookie; - - switch (arg[0]) { - case 'a': /* blink amber or alert led */ - if (debug) - printf("blink alert\n"); - bb.opcode = BIOCSBLINK_ALERT; - break; - - case 'b': /* blink hdd */ - if (debug) - printf("blink\n"); - bb.opcode = BIOCSBLINK_BLINK; - break; - - case 'u': /* unblink hdd */ - if (debug) - printf("unblink\n"); - bb.opcode = BIOCSBLINK_UNBLINK; - break; - - default: - warnx("invalid blink function: %s", arg); - return; - } - - rv = ioctl(devh, BIOCBLINK, &bb); - if (rv == -1) { - if (errno == EOPNOTSUPP) { - /* operation is not supported in kernel, do it here */ - if (debug) - printf("doing blink in userland\n"); - bio_blink_userland(bb.opcode, c, t); + printf("\t\tdisk id : %d\n", bd.diskid); + printf("\t\tstatus : %d\n", bd.status); + printf("\t\tvolume id: %d\n", bd.volid); + printf("\t\tsize : %lld\n", bd.size); + printf("\t\tvendor : %s\n", bd.vendor); } - else - warnx("bioc_ioctl() call failed"); - } -} - -void -bio_ping(void) -{ - int rv; - bioc_ping bp; - - bp.cookie = bl.cookie; - bp.x = 0; - rv = ioctl(devh, BIOCPING, &bp); - if (rv == -1) { - warnx("Error calling bioc_ioctl() via bio_ioctl()"); - return; - } - - printf("x after ioctl() = %i\n", bp.x); -} - -void -bio_startstop(char *arg, u_int8_t c, u_int8_t t) -{ - int rv; - bioc_startstop bs; - - if (debug) - printf("startstop in: %s, ", arg); - - bs.cookie = bl.cookie; - - switch (arg[0]) { - case 's': /* stop unit */ - if (debug) - printf("stop\n"); - bs.opcode = BIOCSUNIT_STOP; - break; - - case 'g': /* start or go unit */ - if (debug) - printf("start\n"); - bs.opcode = BIOCSUNIT_START; - break; - - default: - warnx("invalid start/stop function: %s", arg); - return; - } - - bs.channel = c; - bs.target = t; - - rv = ioctl(devh, BIOCSTARTSTOP, &bs); - if (rv == -1) { - warnx("bioc_ioctl() call failed"); - return; - } - - if (debug) - printf("startstop done\n"); -} - -/* get status, for now only do all */ -void -bio_status(void) -{ - int rv; - bioc_status bs; - - if (debug) - printf("status()\n"); - - bs.cookie = bl.cookie; - bs.opcode = BIOCGSTAT_ALL; - - rv = ioctl(devh, BIOCSTATUS, &bs); - if (rv == -1) { - warnx("bioc_ioctl() call failed"); - return; - } - - if (debug) - printf("status done\n"); -} - -/* read capacity for disk c,t */ -u_int64_t -bio_pt_readcap(u_int8_t c, u_int8_t t, u_int8_t flags) -{ - bioc_scsicmd bpt; - struct read_cap rc; - int rv; - u_int64_t size; - - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = c; - bpt.target = t; - bpt.cdblen = 10; - bpt.cdb[0] = READ_CAPACITY; - bpt.data = &rc; /* set up return data pointer */ - bpt.datalen = sizeof(rc); - bpt.direction = BIOC_DIRIN; - bpt.senselen = 32; /* silly since the kernel overrides it */ - - rv = ioctl(devh, BIOCSCSICMD, &bpt); - if (rv == -1) { - warnx("READ CAPACITY failed %x", bpt.status); - return (0); - } - else if (bpt.status) { - if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) - print_sense(&bpt.sensebuf[0], bpt.senselen); - else - printf("channel: %d target: %2d READ CAPACITY failed " - "without sense data\n", c, t); - - return (0); - } - - rc.maxlba = betoh32(rc.maxlba); - rc.bsize = betoh32(rc.bsize); - - size = (u_int64_t)rc.maxlba * (u_int64_t)rc.bsize; - - if (debug) - printf("\nREAD CAPACITY: %lu * %lu = %llu\n", - rc.maxlba, rc.bsize, size); - - if (flags & F_NOISY) { - printf("channel: %d target: %2d READ CAPACITY %llu", c, t, - size); - print_cap(size); - printf("\n"); - } - - return (size); -} - - -/* inquire device */ -u_int32_t -bio_pt_inquire(u_int8_t c, u_int8_t t, u_int8_t flags, u_int8_t *inq) -{ - bioc_scsicmd bpt; - int rv, i; - - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = c; - bpt.target = t; - bpt.cdblen = 6; - bpt.cdb[0] = INQUIRY; - bpt.cdb[4] = INQSIZE; /* LENGTH */ - bpt.data = inq; /* set up return data pointer */ - bpt.datalen = INQSIZE; /* minimum INQ size */ - bpt.direction = BIOC_DIRIN; - bpt.senselen = 32; /* silly since the kernel overrides it */ - - rv = ioctl(devh, BIOCSCSICMD, &bpt); - if (rv == -1) { - warnx("INQUIRY failed %x", bpt.status); - return 0; - } - else if (bpt.status) { - if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) - print_sense(&bpt.sensebuf[0], bpt.senselen); - else - if (flags & F_NOISY) - printf("device %d:%d did not respond to " - "INQUIRY command\n", c, t); - - return 0; - } - - printf("channel: %u target: %2u ", c, t); - print_inquiry(flags, inq, bpt.datalen); - - if (flags & F_NOISY) printf("\n"); - - return 1; -} - -/* TUR for disk c,t */ -u_int32_t -bio_pt_tur(u_int8_t c, u_int8_t t) -{ - bioc_scsicmd bpt; - int rv; - - if (debug) - printf("tur\n"); - - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = c; - bpt.target = t; - bpt.cdblen = 6; - bpt.cdb[0] = TEST_UNIT_READY; - bpt.direction = BIOC_DIRNONE; - rv = ioctl(devh, BIOCSCSICMD, &bpt); - if (rv == -1) { - warnx("passthrough failed"); - return (0); - } - - if (bpt.status) { - if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) - print_sense(&bpt.sensebuf[0], bpt.senselen); - else - printf("channel: %d target: %2d: TUR failed without " - "sense data\n", c, t); - - return (0); - } - - printf("channel: %d target: %2d: TUR completed\n", c, t); - - return (1); -} - - -/* enumerate all disks */ -void -bio_pt_enum(void) -{ - bioc_scsicmd bpt; - u_int32_t c, t, i, d; - int rv; - u_int8_t inq[INQSIZE]; - - struct dev *delm; - - d = 0; - for (c = 0; c < 4 /* FIXME */; c++) { - for (t = 0; t < 16 /* FIXME */; t++) { - if (bio_pt_inquire(c, t, F_SILENCE, &inq[0])) { - if (inq[0] & SID_QUAL) - continue; /* invalid device */ - - delm = malloc(sizeof(struct dev)); - if (delm == NULL) - errx(1, "not enough memory"); - delm->id = d++; - delm->target = t; - delm->channel = c; - delm->type = inq[0]; - if (delm->type == T_DIRECT) { - /* FIXME check the return value */ - delm->capacity = bio_pt_readcap( - delm->channel, delm->target, - F_SILENCE); - print_cap(delm->capacity); - } - printf("\n"); - - SLIST_INSERT_HEAD(&devices, delm, next); - } - } /* for t */ - } /* for c */ -} - -/* printf sense data */ -void -print_sense(u_int8_t *sensebuf, u_int8_t sensebuflen) -{ - u_int8_t i; - - if (debug) - printf("print_sense() %p, %u\n", sensebuf, sensebuflen); - - for (i = 0; i < sensebuflen; i++) { - printf("%02x ", sensebuf[i]); } - printf("\n"); - - /* FIXME add some pretty decoding here */ -} - -void -print_inquiry(u_int8_t flags, u_int8_t *inq, u_int8_t inqlen) -{ - u_int8_t i; - - if (inqlen < INQSIZE) { - /* INQUIRY shall return at least 36 bytes */ - printf("invalid INQUIRY buffer size\n"); - return; - } - - if (SID_QUAL & inq[0]) { - printf("invalid device\n"); - return; - } - - switch (SID_TYPE & inq[0]) { - case T_DIRECT: - printf("disk "); - break; - - case T_PROCESSOR: - printf("proc "); - break; - - default: - printf("unsuported device type\n"); - return; - } - - for (i = 0; i < inqlen; i++) { - if (i < 8) { - if ((flags & F_NOISY) || debug) - printf("%02x ", inq[i]); - } - else - printf("%c", inq[i] < ' ' ? ' ' : inq[i]); - } -} - -void print_cap(u_int64_t cap) -{ - if (cap / S_TERA > 1) { - printf(" %3llu TB", cap / S_TERA); - return; - } - - if (cap / S_GIGA > 1) { - printf(" %3llu GB", cap / S_GIGA); - return; - } - - if (cap / S_MEGA > 1) { - printf(" %3llu MB", cap / S_MEGA); - return; - } - - if (cap / S_KILO > 1) { - printf(" %3llu MB", cap / S_KILO); - return; - } - - printf(" %llu B", cap); -} - -#if 0 - /* in case we want to do SAFTE this is the format */ - /* SAF-TE */ - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = delm->channel; - bpt.target = delm->target; - bpt.cdblen = 10; - bpt.cdb[0] = 0x3c; /* READ BUFFER */ - bpt.cdb[1] = 0x01; /* SAF-TE command */ - bpt.cdb[8] = sizeof(rc); /* LSB size, FIXME */ - bpt.data = &rc[0]; /* set up return data pointer */ - bpt.datalen = sizeof(rc); - bpt.direction = BIOC_DIRIN; - bpt.senselen = 32; /* silly since the kernel overrides it */ -#endif - -int -get_ses_page(u_int8_t c, u_int8_t t, u_int8_t p, u_int8_t *buf, u_int8_t buflen) -{ - bioc_scsicmd bpt; - int rv; - - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = c; - bpt.target = t; - bpt.cdblen = 6; - bpt.cdb[0] = RECEIVE_DIAGNOSTIC; - /* FIXME add this cdb struct + #defines to scsi_all.h */ - bpt.cdb[1] = 0x01; /* set PCV bit for SES commands */ - bpt.cdb[2] = p; /* SES page nr */ - bpt.cdb[4] = buflen; - bpt.data = buf; /* set up return data pointer */ - bpt.datalen = buflen; - bpt.direction = BIOC_DIRIN; - bpt.senselen = 32; /* silly since the kernel overrides it */ - - rv = ioctl(devh, BIOCSCSICMD, &bpt); - if (rv == -1) { - warnx("RECEIVE_DIAGNOSTIC failed %x", bpt.status); - return (0); - } - else if (bpt.status) { - if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) - print_sense(&bpt.sensebuf[0], bpt.senselen); - else - printf("channel: %d target: %2d RECEIVE_DIAGNOSTIC " - "failed without sense data\n", c, t); - - return (0); - } - - if (debug) { - /* abuse print sense a little */ - print_sense(buf, bpt.datalen); - } - - return (1); -} - -int -set_ses_page(u_int8_t c, u_int8_t t, u_int8_t *buf, u_int8_t buflen) -{ - bioc_scsicmd bpt; - int rv; - - memset(&bpt, 0, sizeof(bpt)); - bpt.cookie = bl.cookie; - bpt.channel = c; - bpt.target = t; - bpt.cdblen = 6; - bpt.cdb[0] = SEND_DIAGNOSTIC; - bpt.cdb[1] = SSD_PF; - bpt.cdb[4] = buflen; - bpt.data = buf; /* set up return data pointer */ - bpt.datalen = buflen; - bpt.direction = BIOC_DIROUT; - bpt.senselen = 32; /* silly since the kernel overrides it */ - - rv = ioctl(devh, BIOCSCSICMD, &bpt); - if (rv == -1) { - warnx("SEND_DIAGNOSTIC failed %x", bpt.status); - return (0); - } - else if (bpt.status) { - if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) - print_sense(&bpt.sensebuf[0], bpt.senselen); - else - printf("channel: %d target: %2d SEND_DIAGNOSTIC " - "failed without sense data\n", c, t); - - return (0); - } - - if (debug) { - /* abuse print sense a little */ - print_sense(buf, bpt.datalen); - } - - return (1); } diff --git a/sbin/bioctl/bioctl.h b/sbin/bioctl/bioctl.h index bc6d41bfe65..6974eafabe1 100644 --- a/sbin/bioctl/bioctl.h +++ b/sbin/bioctl/bioctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.h,v 1.6 2005/04/12 20:49:19 marco Exp $ */ +/* $OpenBSD: bioctl.h,v 1.7 2005/07/18 01:29:19 marco Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom * All rights reserved. @@ -37,53 +37,9 @@ #define S_MEGA (1048576llu) #define S_KILO (1024llu) -/* functions */ -#define F_READCAP (0x01) -#define F_ENUM (0x02) -#define F_TUR (0x04) -#define F_INQUIRY (0x08) +void usage(void); +void cleanup(void); -/* flags */ -#define F_SILENCE (0x00) -#define F_NOISY (0x01) - -#define PARSELIST (0x8000000000000000llu) - -struct read_cap { - u_int32_t maxlba; - u_int32_t bsize; -}; - -struct dev { - SLIST_ENTRY(dev) next; - u_int16_t id; - u_int8_t channel; - u_int8_t target; - u_int8_t type; - u_int64_t capacity; -}; - -void usage(void); -void cleanup(void); -u_int64_t parse_passthru(char *); -void parse_devlist(char *); -void print_sense(u_int8_t *, u_int8_t); -void print_inquiry(u_int8_t, u_int8_t*, u_int8_t); -void print_cap(u_int64_t); -int get_ses_page(u_int8_t, u_int8_t, u_int8_t, u_int8_t*, u_int8_t); -int set_ses_page(u_int8_t, u_int8_t, u_int8_t*, u_int8_t); -void ses_verbose(u_int8_t *, u_int8_t); - -int bio_get_capabilities(bioc_capabilities *); -void bio_alarm(char *); -void bio_blink_userland(u_int8_t, u_int8_t, u_int8_t); -void bio_blink(char *, u_int8_t, u_int8_t); -void bio_ping(void); -void bio_startstop(char *, u_int8_t, u_int8_t); -void bio_status(void); -u_int64_t bio_pt_readcap(u_int8_t, u_int8_t, u_int8_t); -u_int32_t bio_pt_inquire(u_int8_t, u_int8_t, u_int8_t, u_int8_t *); -u_int32_t bio_pt_tur(u_int8_t, u_int8_t); -void bio_pt_enum(void); +void bio_inq(void); #endif /* _BIOCTL_H_ */ |