summaryrefslogtreecommitdiff
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
parentfe6ebae7b56098b265f77fe605c859f777c72443 (diff)
Redo bioctl because initial implementation was too complex.
tested and ok dlg@ beck@ get it in @deraadt
-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
-rw-r--r--sys/dev/biovar.h210
-rw-r--r--sys/dev/ic/ami.c503
-rw-r--r--sys/dev/ic/amireg.h8
-rw-r--r--sys/dev/ic/amivar.h2
8 files changed, 444 insertions, 1434 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_ */
diff --git a/sys/dev/biovar.h b/sys/dev/biovar.h
index 2fb76943011..d5f45aa85d5 100644
--- a/sys/dev/biovar.h
+++ b/sys/dev/biovar.h
@@ -1,7 +1,8 @@
-/* $OpenBSD: biovar.h,v 1.7 2005/07/18 15:10:57 dlg Exp $ */
+/* $OpenBSD: biovar.h,v 1.8 2005/07/29 16:01:29 marco Exp $ */
/*
* Copyright (c) 2002 Niklas Hallqvist. All rights reserved.
+ * Copyright (c) 2005 Marco Peereboom. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -50,147 +51,78 @@ int bio_register(struct device *, int (*)(struct device *, u_long,
/* RAID section */
-#define BIOC_MAX_CDB 16
-#define BIOC_MAX_SENSE 32
-#define BIOC_MAX_PHYSDISK 128 /* based on FC arrays */
-#define BIOC_MAX_VIRTDISK 128 /* based on FC arrays */
-
-/* ioctl tunnel defines */
-/* SHALL be implemented */
-#define BIOCPING _IOWR('B', 32, bioc_ping)
-typedef struct _bioc_ping {
+#define BIOCINQ _IOWR('B', 32, bioc_inq)
+typedef struct _bioc_inq {
void *cookie;
- int x;
-} bioc_ping;
-/* SHALL be implemented */
-#define BIOCCAPABILITIES _IOWR('B', 33, bioc_capabilities)
-typedef struct _bioc_capabilities {
- void *cookie;
- u_int64_t ioctls; /* bit field, 1 ioctl supported */
-#define BIOC_PING 0x01
-#define BIOC_ALARM 0x02
-#define BIOC_PREP_REMOVAL 0x04
-#define BIOC_REBUILD 0x08
-#define BIOC_STATUS 0x10
-#define BIOC_SCSICMD 0x20
-#define BIOC_STARTSTOP 0x40
-#define BIOC_BLINK 0x80
- u_int32_t raid_types; /* bit field, 1 supported raid type */
-#define BIOC_RAID0 0x01
-#define BIOC_RAID1 0x02
-#define BIOC_RAID3 0x04
-#define BIOC_RAID5 0x08
-#define BIOC_RAID10 0x10
-#define BIOC_RAID01 0x20
-#define BIOC_RAID50 0x40
-} bioc_capabilities;
-
-/* OPTIONAL */
-#define BIOCALARM _IOWR('B', 34, bioc_alarm)
-typedef struct _bioc_alarm {
- void *cookie;
- u_int32_t opcode;
-#define BIOCSALARM_DISABLE 0x00
-#define BIOCSALARM_ENABLE 0x01
-#define BIOCSALARM_SILENCE 0x02
-#define BIOCGALARM_STATE 0x03
-#define BIOCSALARM_TEST 0x04
- u_int8_t state; /* only used with GET function */
-} bioc_alarm;
-
-/* OPTIONAL */
-#define BIOCSCSICMD _IOWR('B', 35, bioc_scsicmd)
-typedef struct _bioc_scsicmd {
- void *cookie;
+ int novol; /* nr of volumes */
+ int nodisk; /* nr of total disks */
+} bioc_inq;
- /* in (kernel centric) */
- u_int8_t channel;
- u_int8_t target;
- u_int8_t cdb[BIOC_MAX_CDB];
- u_int8_t cdblen;
- u_int8_t direction; /* 0 = out, 1 = in, this is userland centric */
-#define BIOC_DIROUT 0x00
-#define BIOC_DIRIN 0x01
-#define BIOC_DIRNONE 0x02
-
- /* out (kernel centric) */
- u_int8_t status;
- u_int8_t sensebuf[BIOC_MAX_SENSE];
- u_int8_t senselen;
-
- /* in & out (kernel centric) */
- void *data;
- u_int32_t datalen; /* going in it governs the maximum buffer size
- going out it contains actual bytes transfered */
-} bioc_scsicmd;
-
-/* OPTIONAL */
-#define BIOCSTARTSTOP _IOWR('B', 36, bioc_startstop)
-typedef struct _bioc_startstop {
- void *cookie;
- u_int8_t opcode;
-#define BIOCSUNIT_START 0x00
-#define BIOCSUNIT_STOP 0x01
- u_int8_t channel;
- u_int8_t target;
-} bioc_startstop;
-
-/* SHALL be implemented */
-#define BIOCSTATUS _IOWR('B', 37, bioc_status)
-typedef struct _bioc_status {
+#define BIOCDISK _IOWR('B', 33, bioc_disk)
+/* structure that represents a disk in a RAID volume */
+typedef struct _bioc_disk {
void *cookie;
- u_int8_t opcode;
-#define BIOCGSTAT_CHANGE 0x00 /* any changes since last call? */
-#define BIOCGSTAT_ALL 0x01 /* get all status */
-#define BIOCGSTAT_PHYSDISK 0x02 /* get physical disk status only */
-#define BIOCGSTAT_VIRTDISK 0x03 /* get virtual disk status only */
-#define BIOCGSTAT_BATTERY 0x04 /* get battery status only */
-#define BIOCGSTAT_ENCLOSURE 0x05 /* get enclosure status only */
-#define BIOCGSTAT_TEMPERATURE 0x06 /* get temperature status only */
- u_int8_t status; /* global status flag */
-#define BIOC_STATOK 0x00 /* status is OK */
-#define BIOC_STATDEGRAD 0x01 /* status is degraded */
-#define BIOC_STATCRIT 0x02 /* status is critical */
-#define BIOC_STATBAT 0x04 /* something wrong with battery */
-#define BIOC_STATENC 0x08 /* something wrong with enclosure */
-#define BIOC_STATTEMP 0x10 /* something is over/under heating */
- /* return fields used per request define in opcode */
- u_int8_t channels; /* max channels */
- u_int8_t buswidth; /* max physical drives per channel */
- /* filled in when called with BIOCGSTAT_PHYSDISK set */
- u_int8_t pdcount; /* physical disk counter */
- u_int8_t physdisk[BIOC_MAX_PHYSDISK];
-#define BIOC_PDUNUSED 0x00 /* disk not present */
-#define BIOC_PDONLINE 0x01 /* disk present */
-#define BIOC_PDOFFLINE 0x02 /* disk present but offline */
-#define BIOC_PDINUSE 0x04 /* critical operation in progress */
- /* filled in when called with BIOCGSTAT_VIRTDISK set */
- u_int8_t vdcount; /* virtual disk counter */
- u_int8_t virtdisk[BIOC_MAX_VIRTDISK];
-#define BIOC_VDUNUSED 0x00 /* disk not present */
-#define BIOC_VDONLINE 0x01 /* disk present */
-#define BIOC_VDOFFLINE 0x02 /* disk present but offline */
-#define BIOC_VDINUSE 0x04 /* critical operation in progress */
- /* filled in when called with BIOCGSTAT_BATTERY set */
- u_int8_t batstat; /* battery status */
-#define BIOC_BATNOTPRES 0x00 /* battery not present */
-#define BIOC_BATMISSING 0x01 /* battery removed */
-#define BIOC_BATVOLTERR 0x02 /* battery low/high power */
-#define BIOC_BATTEMP 0x04 /* battery over/under temp*/
- /* NOTYET: encloure status & temperature status */
-} bioc_status;
-
-/* OPTIONAL */
-/* depending on the controller it is handled either in userland or in kernel */
-#define BIOCBLINK _IOWR('B', 38, bioc_blink)
-typedef struct _bioc_blink {
+
+ int volid; /* associate with volume, if -1 unused */
+ int diskid; /* virtual disk id */
+ int status; /* current status */
+#define BIOC_SDONLINE 0x00
+#define BIOC_SDONLINE_S "Online"
+#define BIOC_SDOFFLINE 0x01
+#define BIOC_SDOFFLINE_S "Offline"
+#define BIOC_SDFAILED 0x02
+#define BIOC_SDFAILED_S "Failed"
+#define BIOC_SDREBUILD 0x03
+#define BIOC_SDREBUILD_S "Rebuild"
+#define BIOC_SDHOTSPARE 0x04
+#define BIOC_SDHOTSPARE_S "Hot spare"
+#define BIOC_SDUNUSED 0x05
+#define BIOC_SDUNUSED_S "Unused"
+#define BIOC_SDINVALID 0xff
+#define BIOC_SDINVALID_S "Invalid"
+ int resv; /* align */
+
+ quad_t size; /* size of the disk */
+
+ /* this is provided by the physical disks if suported */
+ char vendor[8]; /* vendor string */
+ char product[16]; /* product string */
+ char revision[4]; /* revision string */
+ char pad[4]; /* zero terminate in here */
+
+ /* XXX get this too? */
+ /* serial number */
+} bioc_disk;
+
+#define BIOCVOL _IOWR('B', 34, bioc_vol)
+/* structure that represents a RAID volume */
+typedef struct _bioc_vol {
void *cookie;
- u_int8_t opcode;
-#define BIOCSBLINK_BLINK 0x00
-#define BIOCSBLINK_UNBLINK 0x01
-#define BIOCSBLINK_ALERT 0x02
- u_int8_t channel;
- u_int8_t target;
-} bioc_blink;
+ int volid; /* volume id */
+ int resv1; /* for binary compatibility */
+ int status; /* current status */
+#define BIOC_SVONLINE 0x00
+#define BIOC_SVONLINE_S "Online"
+#define BIOC_SVOFFLINE 0x01
+#define BIOC_SVOFFLINE_S "Offline"
+#define BIOC_SVDEGRADED 0x02
+#define BIOC_SVDEGRADED_S "Degraded"
+#define BIOC_SVINVALID 0xff
+#define BIOC_SVINVALID_S "Invalid"
+ int resv2; /* align */
+ quad_t size; /* size of the disk */
+ int level; /* raid level */
+ int nodisk; /* nr of drives */
+
+ /* this is provided by the RAID card */
+ char vendor[8]; /* vendor string */
+ char product[16]; /* product string */
+ char revision[4]; /* revision string */
+ char pad[4]; /* zero terminate in here */
+} bioc_vol;
+
+#define BIOC_INQ 0x01
+#define BIOC_DISK 0x02
+#define BIOC_VOL 0x04
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c
index 885a77eae3e..2a4075db29b 100644
--- a/sys/dev/ic/ami.c
+++ b/sys/dev/ic/ami.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ami.c,v 1.48 2005/07/18 15:10:56 dlg Exp $ */
+/* $OpenBSD: ami.c,v 1.49 2005/07/29 16:01:30 marco Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -136,11 +136,13 @@ void ami_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size);
int ami_inquire(struct ami_softc *sc, u_int8_t op);
#if NBIO > 0
+int ami_mgmt(struct ami_softc *, u_int8_t, u_int8_t, u_int8_t,
+ size_t, void *);
+int ami_drv_inq(struct ami_softc *, u_int8_t, u_int8_t, void *);
int ami_ioctl(struct device *, u_long, caddr_t);
-int ami_ioctl_alarm(struct ami_softc *, bioc_alarm *);
-int ami_ioctl_startstop( struct ami_softc *, bioc_startstop *);
-int ami_ioctl_status( struct ami_softc *, bioc_status *);
-int ami_ioctl_passthru(struct ami_softc *, bioc_scsicmd *);
+int ami_ioctl_inq(struct ami_softc *, bioc_inq *);
+int ami_ioctl_vol(struct ami_softc *, bioc_vol *);
+int ami_ioctl_disk(struct ami_softc *, bioc_disk *);
#endif /* NBIO > 0 */
struct ami_ccb *
@@ -1680,6 +1682,7 @@ ami_scsi_ioctl(struct scsi_link *link, u_long cmd,
caddr_t addr, int flag, struct proc *p)
{
struct ami_softc *sc = (struct ami_softc *)link->adapter_softc;
+ /* u_int8_t target = link->target; */
if (sc->sc_ioctl)
return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
@@ -1694,11 +1697,11 @@ ami_ioctl(dev, cmd, addr)
u_long cmd;
caddr_t addr;
{
- int error = 0;
struct ami_softc *sc = (struct ami_softc *)dev;
ami_lock_t lock;
+ int error = 0;
- /* FIXME do we need to test for sc_dis_poll? */
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: ioctl ", sc->sc_dev.dv_xname));
if (sc->sc_flags & AMI_BROKEN)
return ENODEV; /* can't do this to broken device for now */
@@ -1710,11 +1713,9 @@ ami_ioctl(dev, cmd, addr)
}
switch (cmd) {
- case BIOCALARM:
- case BIOCBLINK:
- case BIOCSTARTSTOP:
- case BIOCSTATUS:
- case BIOCSCSICMD:
+ case BIOCINQ:
+ case BIOCVOL:
+ case BIOCDISK:
sc->sc_flags |= AMI_CMDWAIT;
while (!TAILQ_EMPTY(&sc->sc_ccbq))
if (tsleep(&sc->sc_free_ccb, PRIBIO, "ami_ioctl",
@@ -1723,51 +1724,19 @@ ami_ioctl(dev, cmd, addr)
}
switch (cmd) {
- case BIOCPING:
- ((bioc_ping *)addr)->x++;
-
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocping: %x\n",
- sc->sc_dev.dv_xname, ((bioc_ping *)addr)->x));
- break;
-
- case BIOCCAPABILITIES:
- ((bioc_capabilities *)addr)->ioctls =
- BIOC_ALARM | BIOC_PING | BIOC_SCSICMD | BIOC_STARTSTOP |
- BIOC_STATUS | BIOC_BLINK;
-
- ((bioc_capabilities *)addr)->raid_types =
- BIOC_RAID0 | BIOC_RAID1 | BIOC_RAID5 |
- BIOC_RAID10 | BIOC_RAID50;
-
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: bioccapabilities: ioctls: "
- "%016llx raid_types: %08lx\n",
- sc->sc_dev.dv_xname,
- ((bioc_capabilities *)addr)->ioctls,
- ((bioc_capabilities *)addr)->raid_types));
- break;
-
- case BIOCALARM:
- error = ami_ioctl_alarm(sc, (bioc_alarm *)addr);
- break;
-
- case BIOCBLINK:
- error = EOPNOTSUPP; /* let userland land knows it must issue
- * a cdb to handle blinking. */
+ case BIOCINQ:
+ AMI_DPRINTF(AMI_D_IOCTL, ("inq "));
+ error = ami_ioctl_inq(sc, (bioc_inq *)addr);
break;
- case BIOCSTARTSTOP:
- AMI_DPRINTF(AMI_D_IOCTL, ("start stop unit\n"));
- error = ami_ioctl_startstop(sc, (bioc_startstop *)addr);
+ case BIOCVOL:
+ AMI_DPRINTF(AMI_D_IOCTL, ("vol "));
+ error = ami_ioctl_vol(sc, (bioc_vol *)addr);
break;
- case BIOCSTATUS:
- AMI_DPRINTF(AMI_D_IOCTL, ("status\n"));
- error = ami_ioctl_status(sc, (bioc_status *)addr);
- break;
-
- case BIOCSCSICMD:
- AMI_DPRINTF(AMI_D_IOCTL, ("scsi cmd\n"));
- error = ami_ioctl_passthru(sc, (bioc_scsicmd *)addr);
+ case BIOCDISK:
+ AMI_DPRINTF(AMI_D_IOCTL, ("disk "));
+ error = ami_ioctl_disk(sc, (bioc_disk *)addr);
break;
default:
@@ -1785,290 +1754,324 @@ ami_ioctl(dev, cmd, addr)
}
int
-ami_ioctl_alarm(sc, ra)
+ami_drv_inq(sc, ch, tg, inqbuf)
struct ami_softc *sc;
- bioc_alarm *ra;
+ u_int8_t ch;
+ u_int8_t tg;
+ void *inqbuf;
{
- int error = 0;
- struct ami_ccb *ccb;
+ struct ami_ccb *ccb;
struct ami_iocmd *cmd;
- void *idata;
+ struct ami_passthrough *ps;
+ struct scsi_inquiry_data *pp;
+ void *idata;
bus_dmamap_t idatamap;
bus_dma_segment_t idataseg[1];
paddr_t pa;
- u_int8_t *p;
-
+ int error = 0;
- if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data"))) {
- ami_freemem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data");
- return ENOMEM;
+ if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg, NBPG, 1,
+ "ami mgmt"))) {
+ error = ENOMEM;
+ goto bail;
}
pa = idataseg[0].ds_addr;
- p = idata;
+ ps = idata;
+ pp = idata + sizeof *ps;
ccb = ami_get_ccb(sc);
ccb->ccb_data = NULL;
cmd = ccb->ccb_cmd;
- cmd->acc_cmd = AMI_ALARM;
- cmd->acc_io.aio_channel = 0;
- cmd->acc_io.aio_param = 0;
- cmd->acc_io.aio_data = htole32(pa);
-
- switch(ra->opcode) {
- case BIOCSALARM_DISABLE:
- *p = AMI_ALARM_OFF;
- break;
-
- case BIOCSALARM_ENABLE:
- *p = AMI_ALARM_ON;
- break;
-
- case BIOCSALARM_SILENCE:
- *p = AMI_ALARM_QUIET;
- break;
-
- case BIOCGALARM_STATE:
- *p = AMI_ALARM_GET;
- break;
+ cmd->acc_cmd = AMI_PASSTHRU;
+ cmd->acc_passthru.apt_data = htole32(pa);
- case BIOCSALARM_TEST:
- *p = AMI_ALARM_TEST;
- break;
+ memset(ps, 0, sizeof *ps);
- default:
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocalarm invalid opcode %x\n",
- sc->sc_dev.dv_xname, ra->opcode));
- ami_put_ccb(ccb);
- return EINVAL;
- }
+ ps->apt_channel = ch;
+ ps->apt_target = tg;
+ ps->apt_ncdb = sizeof(struct scsi_inquiry);
+ ps->apt_nsense = sizeof(struct scsi_sense_data);
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocalarm: in: %x ",
- sc->sc_dev.dv_xname, *p));
+ ps->apt_cdb[0] = INQUIRY;
+ ps->apt_cdb[1] = 0;
+ ps->apt_cdb[2] = 0;
+ ps->apt_cdb[3] = 0;
+ ps->apt_cdb[4] = sizeof(struct scsi_inquiry_data); /* INQUIRY length */
+ ps->apt_cdb[5] = 0;
+ ps->apt_data = htole32(pa + sizeof *ps);
+ ps->apt_datalen = sizeof(struct scsi_inquiry_data);
- if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
- AMI_DPRINTF(AMI_D_IOCTL, ("out %x\n", *p));
- if (ra->opcode == BIOCGALARM_STATE)
- ra->state = *p;
- else
- ra->state = 0;
- }
- else {
- AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
+ if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0)
+ memcpy(inqbuf, pp, sizeof(struct scsi_inquiry_data));
+ else
error = EINVAL;
- }
- ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, 1, "ioctl data");
+bail:
+ ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, 1, "ami mgmt");
return (error);
}
int
-ami_ioctl_startstop(sc, bs)
+ami_mgmt(sc, opcode, par1, par2, size, buffer)
struct ami_softc *sc;
- bioc_startstop *bs;
+ u_int8_t opcode;
+ u_int8_t par1;
+ u_int8_t par2;
+ size_t size;
+ void *buffer;
{
- int error = 0;
- struct ami_ccb *ccb;
+ struct ami_ccb *ccb;
struct ami_iocmd *cmd;
+ void *idata;
+ bus_dmamap_t idatamap;
+ bus_dma_segment_t idataseg[1];
+ paddr_t pa;
+ int error = 0;
+
+ if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg, NBPG,
+ (size / NBPG) + 1, "ami mgmt"))) {
+ error = ENOMEM;
+ goto bail;
+ }
+
+ pa = idataseg[0].ds_addr;
ccb = ami_get_ccb(sc);
ccb->ccb_data = NULL;
cmd = ccb->ccb_cmd;
- AMI_DPRINTF(AMI_D_IOCTL, ("start/stop %d unit %d %d\n",
- bs->opcode, bs->channel, bs->target));
+ cmd->acc_cmd = opcode;
+ cmd->acc_io.aio_channel = par1;
+ cmd->acc_io.aio_param = par2;
+ cmd->acc_io.aio_data = htole32(pa);
- if (bs->opcode == BIOCSUNIT_START)
- cmd->acc_cmd = AMI_STARTU;
- else if (bs->opcode == BIOCSUNIT_STOP)
- cmd->acc_cmd = AMI_STOPU;
+ if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0)
+ memcpy(buffer, idata, size);
else
- return EINVAL;
-
- /* FIXME test if channel and target are in range */
- cmd->acc_io.aio_channel = bs->channel;
- cmd->acc_io.aio_param = bs->target;
- cmd->acc_io.aio_pad[0] = AMI_STARTU_SYNC;
- cmd->acc_io.aio_data = NULL;
-
- if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
- AMI_DPRINTF(AMI_D_IOCTL, ("%s\n",
- bs->opcode == BIOCSUNIT_START ? "started" : "stopped"));
- }
- else {
- AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
error = EINVAL;
- }
+
+bail:;
+ ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, (size / NBPG) + 1,
+ "ami mgmt");
return (error);
}
int
-ami_ioctl_status(sc, bs)
+ami_ioctl_inq(sc, bi)
struct ami_softc *sc;
- bioc_status *bs;
+ bioc_inq *bi;
{
+ char plist[AMI_BIG_MAX_PDRIVES];
+ struct ami_big_diskarray *p; /* struct too large for stack */
+ int i, s, t;
+ int off;
int error = 0;
- struct ami_ccb *ccb;
- struct ami_iocmd *cmd;
- void *idata;
- bus_dmamap_t idatamap;
- bus_dma_segment_t idataseg[1];
- paddr_t pa;
- u_int8_t *p;
- if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data"))) {
- ami_freemem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data");
- return ENOMEM;
+ p = malloc(sizeof *p, M_DEVBUF, M_NOWAIT);
+ if (!p) {
+ printf("%s: no memory for raw interface\n",sc->sc_dev.dv_xname);
+ return (ENOMEM);
}
- pa = idataseg[0].ds_addr;
- p = idata;
+ if (ami_mgmt(sc, AMI_FCOP, AMI_FC_RDCONF, 0, sizeof *p, p)) {
+ error = EINVAL;
+ goto bail;
+ }
- ccb = ami_get_ccb(sc);
- ccb->ccb_data = NULL;
- cmd = ccb->ccb_cmd;
+ memset(plist, 0, sizeof plist);
- cmd->acc_cmd = AMI_FCOP;
- cmd->acc_io.aio_channel = AMI_FC_EINQ3;
- cmd->acc_io.aio_param = AMI_FC_EINQ3_SOLICITED_FULL;
- cmd->acc_io.aio_data = htole32(pa);
+ bi->novol = p->ada_nld;
+ bi->nodisk = 0;
- AMI_DPRINTF(AMI_D_IOCTL, ("status %d\n", bs->opcode));
+ /* do we actually care how many disks we have at this point? */
+ for (i = 0; i < p->ada_nld; i++)
+ for (s = 0; s < p->ald[i].adl_spandepth; s++)
+ for (t = 0; t < p->ald[i].adl_nstripes; t++) {
+ off = p->ald[i].asp[s].adv[t].add_channel *
+ AMI_MAX_TARGET +
+ p->ald[i].asp[s].adv[t].add_target;
- if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
- AMI_DPRINTF(AMI_D_IOCTL, ("success\n"));
- }
- else {
- AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
- error = EINVAL;
- }
+ if (!plist[off]) {
+ plist[off] = 1;
+ bi->nodisk++;
+
+ }
+ }
- ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, 1, "ioctl data");
+bail:
+ free(p, M_DEVBUF);
return (error);
}
int
-ami_ioctl_passthru(sc, bp)
+ami_ioctl_vol(sc, bv)
struct ami_softc *sc;
- bioc_scsicmd *bp;
+ bioc_vol *bv;
{
+ struct ami_big_diskarray *p; /* struct too large for stack */
+ int i, s, t;
int error = 0;
- struct ami_ccb *ccb;
- struct ami_iocmd *cmd;
- struct ami_passthrough *ps;
- void *idata;
- bus_dmamap_t idatamap;
- bus_dma_segment_t idataseg[1];
- paddr_t pa;
-#ifdef AMI_DEBUG
- u_int8_t i = 0;
-#endif /* AMI_DEBUG */
+ p = malloc(sizeof *p, M_DEVBUF, M_NOWAIT);
+ if (!p) {
+ printf("%s: no memory for raw interface\n",sc->sc_dev.dv_xname);
+ return (ENOMEM);
+ }
- AMI_DPRINTF(AMI_D_IOCTL, ("in passthrough\n"));
+ if (ami_mgmt(sc, AMI_FCOP, AMI_FC_RDCONF, 0, sizeof *p, p)) {
+ error = EINVAL;
+ goto bail;
+ }
- /* FIXME: validate channel/target pair, or let the firmware bomb it?
- */
+ if (bv->volid > p->ada_nld) {
+ error = EINVAL;
+ goto bail;
+ }
- if (bp->cdblen > BIOC_MAX_CDB)
- return (EINVAL);
+ i = bv->volid;
- if (bp->direction == BIOC_DIRIN &&
- (bp->datalen == 0 || bp->data == NULL))
- /* if userland expects data give us a len and a pointer */
- return (EINVAL);
+ switch (p->ald[i].adl_status) {
+ case AMI_RDRV_OFFLINE:
+ bv->status = BIOC_SVOFFLINE;
+ break;
- if (bp->datalen > 1024)
- return (EINVAL); /* cap at 1k for now */
+ case AMI_RDRV_DEGRADED:
+ bv->status = BIOC_SVDEGRADED;
+ break;
- if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data"))) {
- ami_freemem(sc->dmat, &idatamap, idataseg,
- NBPG, 1, "ioctl data");
- return (ENOMEM);
+ case AMI_RDRV_OPTIMAL:
+ bv->status = BIOC_SVONLINE;
+ break;
+
+ default:
+ bv->status = BIOC_SVINVALID;
}
- pa = idataseg[0].ds_addr;
- ps = idata;
+ bv->size = 0;
+ bv->level = p->ald[i].adl_raidlvl;
+ bv->nodisk = 0;
- ccb = ami_get_ccb(sc);
- ccb->ccb_data = NULL;
- cmd = ccb->ccb_cmd;
+ for (s = 0; s < p->ald[i].adl_spandepth; s++) {
+ for (t = 0; t < p->ald[i].adl_nstripes; t++)
+ bv->nodisk++;
- cmd->acc_cmd = AMI_PASSTHRU;
- cmd->acc_passthru.apt_data = htole32(pa);
+ switch (bv->level) {
+ case 0:
+ bv->size += p->ald[i].asp[s].ads_length *
+ p->ald[i].adl_nstripes;
+ break;
- memset(ps, 0, sizeof *ps);
+ case 1:
+ bv->size += p->ald[i].asp[s].ads_length;
+ break;
- ps->apt_channel = bp->channel;
- ps->apt_target = bp->target;
- ps->apt_ncdb = bp->cdblen;
- ps->apt_nsense = BIOC_MAX_SENSE; /* do not let userland dictate this */
- memcpy(&ps->apt_cdb[0], &bp->cdb[0], bp->cdblen);
+ case 5:
+ bv->size += p->ald[i].asp[s].ads_length *
+ (p->ald[i].adl_nstripes - 1);
+ break;
+ }
+ }
- ps->apt_data = htole32(pa + sizeof *ps);
- ps->apt_datalen = bp->datalen;
+ if (p->ald[i].adl_spandepth > 1)
+ bv->level *= 10;
- if (bp->direction == BIOC_DIROUT) {
- /* userland sent us some data */
- copyin(bp->data, idata + sizeof *ps, ps->apt_datalen);
- }
+ bv->size *= (quad_t)512;
-#ifdef AMI_DEBUG
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: ps->apt_channel: %x, ps->apt_target: %x "
- "ps->apt_cdblen: %x ps->apt_data: %x ps->apt_datalen: %x\n%s: cdb: "
- , sc->sc_dev.dv_xname, ps->apt_channel, ps->apt_target,
- ps->apt_ncdb, ps->apt_data, ps->apt_datalen, sc->sc_dev.dv_xname));
+bail:
+ free(p, M_DEVBUF);
+
+ return (error);
+}
+
+int
+ami_ioctl_disk(sc, bd)
+ struct ami_softc *sc;
+ bioc_disk *bd;
+{
+ struct scsi_inquiry_data inqbuf;
+ struct ami_big_diskarray *p; /* struct too large for stack */
+ int i, s, t, d;
+ int off;
+ int error = 0;
- for (i = 0; i < ps->apt_ncdb; i++) {
- printf("%0x ", ps->apt_cdb[i]);
+ p = malloc(sizeof *p, M_DEVBUF, M_NOWAIT);
+ if (!p) {
+ printf("%s: no memory for raw interface\n",sc->sc_dev.dv_xname);
+ return (ENOMEM);
}
- printf("\n");
-#endif /* AMI_DEBUG */
- if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
- AMI_DPRINTF(AMI_D_IOCTL, ("cdb issued\n"));
- if (bp->direction == BIOC_DIRIN) {
- /* userland expects data */
- bp->datalen = ps->apt_datalen;
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: passthrough %x\n",
- sc->sc_dev.dv_xname, ps->apt_datalen));
- copyout(idata + sizeof *ps, bp->data, ps->apt_datalen);
- }
+ if (ami_mgmt(sc, AMI_FCOP, AMI_FC_RDCONF, 0, sizeof *p, p)) {
+ error = EINVAL;
+ goto bail;
}
- else {
- /* copy sense data back to user space */
- memcpy(&bp->sensebuf[0], &ps->apt_sense[0], ps->apt_nsense);
- bp->senselen = ps->apt_nsense;
- /*
- * this needs to be checked in userland since error can't
- * be set. Setting it prevents it from being coppied back to
- * userland
- */
- bp->status = 1;
-#ifdef AMI_DEBUG
- AMI_DPRINTF(AMI_D_IOCTL, ("%s: passthrough failed %x %x\n%s: ",
- sc->sc_dev.dv_xname, bp->status, bp->senselen,
- sc->sc_dev.dv_xname));
+ if (bd->volid > p->ada_nld) {
+ error = EINVAL;
+ goto bail;
+ }
- for (i = 0; i < bp->senselen; i++)
- printf("%0x ", bp->sensebuf[i]);
+ i = bd->volid;
+ error = EINVAL;
- printf("\n");
-#endif /* AMI_DEBUG */
+ for (s = 0, d = 0; s < p->ald[i].adl_spandepth; s++) {
+ for (t = 0; t < p->ald[i].adl_nstripes; t++) {
+ if (d != bd->diskid) {
+ d++;
+ continue;
+ }
+
+ off = p->ald[i].asp[s].adv[t].add_channel *
+ AMI_MAX_TARGET +
+ p->ald[i].asp[s].adv[t].add_target;
+
+ switch (p->apd[off].adp_ostatus) {
+ case AMI_PD_UNCNF:
+ bd->status = BIOC_SDUNUSED;
+ break;
+
+ case AMI_PD_ONLINE:
+ bd->status = BIOC_SDONLINE;
+ break;
+
+ case AMI_PD_FAILED:
+ bd->status = BIOC_SDFAILED;
+ break;
+
+ case AMI_PD_RBLD:
+ bd->status = BIOC_SDREBUILD;
+ break;
+
+ case AMI_PD_HOTSPARE:
+ bd->status = BIOC_SDHOTSPARE;
+ break;
+
+ default:
+ bd->status = BIOC_SDINVALID;
+ }
+
+ bd->size = (quad_t)p->apd[off].adp_size * (quad_t)512;
+
+ if (!ami_drv_inq(sc,
+ (p->ald[i].asp[s].adv[t].add_target >> 4),
+ (p->ald[i].asp[s].adv[t].add_target & 0x0f),
+ &inqbuf)) {
+ strlcpy(bd->vendor, inqbuf.vendor,
+ 8 + 16 + 4 + 1); /* vendor prod rev zero */
+ }
+
+ error = 0;
+ goto bail;
+ }
}
- ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, 1, "ioctl data");
+bail:
+ free(p, M_DEVBUF);
return (error);
}
diff --git a/sys/dev/ic/amireg.h b/sys/dev/ic/amireg.h
index 84841c2aea8..bb77476191c 100644
--- a/sys/dev/ic/amireg.h
+++ b/sys/dev/ic/amireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amireg.h,v 1.17 2005/07/18 15:10:57 dlg Exp $ */
+/* $OpenBSD: amireg.h,v 1.18 2005/07/29 16:01:30 marco Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@@ -223,6 +223,8 @@
#define AMI_HSPDIAG 0xb1
#define AMI_GESENSEINFO 0xb2 /* get extended sense info */
#define AMI_SYSFLUSH 0xfe /* flush system */
+/* this needs to be removed when the new bioctl goes in */
+#define AMI_GETINQ 0xcf /* get proc & drive inquiry data */
#define AMI_ALARM 0x51 /* alarm functions */
#define AMI_ALARM_OFF 0x00
#define AMI_ALARM_ON 0x01
@@ -570,6 +572,7 @@ struct ami_diskarray {
struct ami_big_diskarray {
u_int8_t ada_nld;
u_int8_t ada_pad[3];
+#define ald ada_ldrv
struct {
u_int8_t adl_spandepth;
u_int8_t adl_raidlvl;
@@ -579,15 +582,18 @@ struct ami_big_diskarray {
u_int8_t adl_wrpolicy;
u_int8_t adl_directio;
u_int8_t adl_nstripes;
+#define asp adl_spans
struct {
u_int32_t ads_start;
u_int32_t ads_length; /* blocks */
+#define adv ads_devs
struct {
u_int8_t add_channel;
u_int8_t add_target;
} ads_devs[AMI_BIG_MAX_DEVDEPTH];
} adl_spans[AMI_BIG_MAX_SPANDEPTH];
} ada_ldrv[AMI_BIG_MAX_LDRIVES];
+#define apd ada_pdrv
struct {
u_int8_t adp_type; /* SCSI device type */
u_int8_t adp_ostatus; /* status during config */
diff --git a/sys/dev/ic/amivar.h b/sys/dev/ic/amivar.h
index 68edd84a843..49197359608 100644
--- a/sys/dev/ic/amivar.h
+++ b/sys/dev/ic/amivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amivar.h,v 1.13 2005/07/18 15:10:57 dlg Exp $ */
+/* $OpenBSD: amivar.h,v 1.14 2005/07/29 16:01:30 marco Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff