summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2005-07-29 16:01:31 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2005-07-29 16:01:31 +0000
commit66403d7b688dbb946e84aeb5eb81b0bbf1c04087 (patch)
tree1b235b302ff5e36baf0e75a790290e2767293570 /sbin
parentfe6ebae7b56098b265f77fe605c859f777c72443 (diff)
Redo bioctl because initial implementation was too complex.
tested and ok dlg@ beck@ get it in @deraadt
Diffstat (limited to 'sbin')
-rw-r--r--sbin/bioctl/Makefile5
-rw-r--r--sbin/bioctl/bioctl.848
-rw-r--r--sbin/bioctl/bioctl.c1050
-rw-r--r--sbin/bioctl/bioctl.h52
4 files changed, 112 insertions, 1043 deletions
diff --git a/sbin/bioctl/Makefile b/sbin/bioctl/Makefile
index aed3cb91772..a25143cfc1f 100644
--- a/sbin/bioctl/Makefile
+++ b/sbin/bioctl/Makefile
@@ -1,7 +1,8 @@
-# $OpenBSD: Makefile,v 1.5 2005/07/18 15:10:56 dlg Exp $
+# $OpenBSD: Makefile,v 1.6 2005/07/29 16:01:18 marco Exp $
PROG= bioctl
-LDADD= -lutil
+CFLAGS= -Wall
+LDADD= -lutil
MAN= bioctl.8
.include <bsd.prog.mk>
diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8
index d6941144000..8ced3a82e83 100644
--- a/sbin/bioctl/bioctl.8
+++ b/sbin/bioctl/bioctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bioctl.8,v 1.12 2005/07/18 15:10:56 dlg Exp $
+.\" $OpenBSD: bioctl.8,v 1.13 2005/07/29 16:01:18 marco Exp $
.\"
.\" Copyright (c) 2004, 2005 Marco Peereboom
.\"
@@ -32,12 +32,9 @@
.Sh SYNOPSIS
.Nm bioctl
.Bk -words
-.Op Fl Dehpt
-.Op Fl a Ar function
-.Op Fl b Ar function
-.Op Fl l Ar device-list
-.Op Fl u Ar function
-.Fl d Ar device
+.Op Fl Dhi
+.Fl d Ar device |
+.Fl f Ar device
.Ek
.Sh DESCRIPTION
.Nm
@@ -45,46 +42,21 @@ provides a generic interface for RAID management.
.Pp
The options are as follows:
.Bl -tag -width Ds
-.It Fl a Ar function
-Get or set alarm state.
-Supported functions are: silence/quiet, enable, disable, get, and test.
-Or use the first letter of the function.
-.It Fl b Ar function
-Blink or unblink hard drive LED, if supported by the enclosure.
-Supported functions are: blink, alarm (fault LED) and unblink.
-Or use the first letter of the function.
.It Fl D
Enable debug output.
.It Fl d Ar device
Select RAID controller e.g ami0.
-Use the -d option for controller operations.
-.It Fl e
-Enumerate drives.
-.It Fl f Ar disk
-Select disk device e.g sd0.
-Use the -f option for disk operations.
-Either -f or -d must be selected.
+Use the -d option for controller operations that impact all disk devices.
+.It Fl f Ar device
+Select RAID disk e.g sd0.
.It Fl h
Online help.
-.It Fl l Ar device-list
-Device list to what the operation/function applies to.
-The format is channel:target,channel:target etc. e.g. 0:1,1:3
-.It Fl p
-Verify that adapter accepts bioctl commands.
-This is a sort of a "device ping".
-.It Fl t
-Issue a pass-through function to
-.Aq device-list .
-Supported functions are:
-read capacity, inquiry, and test unit ready (TUR).
-Or use the first letter of the function name.
-.It Fl u Ar function
-Start or stop physical disk.
-Supported functions are: go and stop.
-Or use the first letter of the function.
+.It Fl i
+Depending on -d or -f enumerate all or only selected RAID device(s).
.El
.Sh SEE ALSO
.Xr bio 4 ,
+.Xr ami 4 ,
.Xr scsi 4
.Sh HISTORY
The
diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c
index 1395715eb61..08bc98bfa4a 100644
--- a/sbin/bioctl/bioctl.c
+++ b/sbin/bioctl/bioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioctl.c,v 1.15 2005/07/18 15:10:56 dlg Exp $ */
+/* $OpenBSD: bioctl.c,v 1.16 2005/07/29 16:01:18 marco Exp $ */
/*
* Copyright (c) 2004, 2005 Marco Peereboom
* All rights reserved.
@@ -26,33 +26,27 @@
*
*/
-#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>
#include <scsi/scsi_disk.h>
#include <scsi/scsi_all.h>
-#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 +57,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:hi")) != -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 */
@@ -159,92 +111,18 @@ main(int argc, char *argv[])
if (rv == -1)
errx(1, "Can't locate %s device via %s",
bl.name, bio_device);
- }
- else if (sd_dev) {
+ } else if (sd_dev) {
devh = opendev(sd_dev, O_RDWR, OPENDEV_PART, &realname);
if (devh == -1)
err(1, "Can't open %s", sd_dev);
- }
- else
+ } else
errx(1, "need -d or -f parameter");
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 +133,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 [-Dhi] [-d device | -f disk]\n", __progname);
exit(1);
}
@@ -265,855 +141,119 @@ 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;
+ bioc_inq bi;
+ bioc_vol bv;
+ bioc_disk bd;
- es = NULL;
- s = dl;
+ int rv, i, d;
- if (debug)
- printf("parse: %s\n", dl);
-
- 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;
-
- switch (arg[0]) {
- case 'q': /* silence alarm */
- /* FALLTHROUGH */
- case 's':
- if (debug)
- printf("silence\n");
- ba.opcode = BIOCSALARM_SILENCE;
- break;
-
- 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;
+ printf("bio_inq\n");
- case 'g': /* get alarm state */
- if (debug)
- printf("get state\n");
- ba.opcode = BIOCGALARM_STATE;
- break;
+ bi.cookie = bl.cookie;
- 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);
-
- str += tdh->type_desc_len;
- }
-}
+ printf("RAID volumes : %d\n", bi.novol);
+ printf("Physical disks : %d\n\n", bi.nodisk);
-void
-bio_blink_userland(u_int8_t opc, u_int8_t c, u_int8_t t)
-{
- struct dev *delm;
-
- /* 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))) {
- return;
- }
-
- esdp = (struct ses_enc_stat_diag_page *)rc2;
- desd = (struct ses_dev_elmt_status_diag *)
- (esdp->elmts + elements); /* FIXME do we need padding? */
-
- /* 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);
-
- if (t == desd->slot_addr) {
- found = 1;
- break;
- }
-
- desd += 1; /* next element */
- }
-
- if (!found) {
- printf("target: %d not found\n", t);
+ for (i = 0; i < bi.novol; i++) {
+ memset(&bv, 0, sizeof(bv));
+ bv.cookie = bl.cookie;
+ bv.volid = i;
+ rv = ioctl(devh, BIOCVOL, &bv);
+ if (rv == -1) {
+ warnx("bioc_ioctl() call failed");
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;
+ printf("\tvolume id: %d\n", bv.volid);
+ printf("\tstatus : ");
+ switch (bv.status) {
+ case BIOC_SVONLINE:
+ printf("%s\n", BIOC_SVONLINE_S);
break;
- case BIOCSBLINK_BLINK:
- cdp->elmts[i].byte3 = SDECD_RQST_IDENT;
- cdp->elmts[i].byte4 = 0x00;
+ case BIOC_SVOFFLINE:
+ printf("%s\n", BIOC_SVOFFLINE_S);
break;
- case BIOCSBLINK_UNBLINK:
- cdp->elmts[i].byte3 = 0x00;
- cdp->elmts[i].byte4 = 0x00;
+ case BIOC_SVDEGRADED:
+ printf("%s\n", BIOC_SVDEGRADED_S);
break;
+ case BIOC_SVINVALID:
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("%s\n", BIOC_SVINVALID_S);
}
- 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);
+ printf("\tsize : %lld\n", bv.size);
+ printf("\traid : %d\n", bv.level);
+ printf("\tnr disks : %d\n", bv.nodisk);
+
+ for (d = 0; d < bv.nodisk; d++) {
+ memset(&bd, 0, sizeof(bd));
+ bd.cookie = bl.cookie;
+ bd.diskid = d;
+ bd.volid = i;
+
+ rv = ioctl(devh, BIOCDISK, &bd);
+ if (rv == -1) {
+ warnx("bioc_ioctl() call failed");
+ return;
}
- } /* 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;
+ printf("\t\tdisk id : %d\n", bd.diskid);
+ printf("\t\tstatus : ");
+ switch (bd.status) {
+ case BIOC_SDONLINE:
+ printf("%s\n", BIOC_SDONLINE_S);
+ break;
- if (inqlen < INQSIZE) {
- /* INQUIRY shall return at least 36 bytes */
- printf("invalid INQUIRY buffer size\n");
- return;
- }
+ case BIOC_SDOFFLINE:
+ printf("%s\n", BIOC_SDOFFLINE_S);
+ break;
- if (SID_QUAL & inq[0]) {
- printf("invalid device\n");
- return;
- }
+ case BIOC_SDFAILED:
+ printf("%s\n", BIOC_SDFAILED_S);
+ break;
- switch (SID_TYPE & inq[0]) {
- case T_DIRECT:
- printf("disk ");
- break;
+ case BIOC_SDREBUILD:
+ printf("%s\n", BIOC_SDREBUILD_S);
+ break;
- case T_PROCESSOR:
- printf("proc ");
- break;
+ case BIOC_SDHOTSPARE:
+ printf("%s\n", BIOC_SDHOTSPARE_S);
+ break;
- default:
- printf("unsuported device type\n");
- return;
- }
+ case BIOC_SDUNUSED:
+ printf("%s\n", BIOC_SDUNUSED_S);
+ break;
- for (i = 0; i < inqlen; i++) {
- if (i < 8) {
- if ((flags & F_NOISY) || debug)
- printf("%02x ", inq[i]);
+ case BIOC_SDINVALID:
+ default:
+ printf("%s\n", BIOC_SDINVALID_S);
+ }
+ printf("\t\tvolume id: %d\n", bd.volid);
+ printf("\t\tsize : %lld\n", bd.size);
+ printf("\t\tvendor : %s\n", bd.vendor);
}
- 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);
+ printf("\n");
}
-
- return (1);
}
diff --git a/sbin/bioctl/bioctl.h b/sbin/bioctl/bioctl.h
index 51131f79948..411c3ab67a4 100644
--- a/sbin/bioctl/bioctl.h
+++ b/sbin/bioctl/bioctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioctl.h,v 1.8 2005/07/18 15:10:56 dlg Exp $ */
+/* $OpenBSD: bioctl.h,v 1.9 2005/07/29 16:01:18 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_ */