From 982bad256fc21a5e71968cc2f7d7eee826501621 Mon Sep 17 00:00:00 2001 From: bouyer Date: Tue, 1 May 2007 17:18:52 +0000 Subject: [PATCH] Add bio(4) and associated bioctl(8) from OpenBSD, a driver control block device controllers, and more specifically raid controllers. Add a new sensor type, ENVSYS_DRIVE, to report drive status. From OpenBSD. Add bio and sysmon support to mfi(4). This allow userland to query status for drives and logical volumes attached to a mfi(4) controller. While there fix some debug printfs in mfi so they compile. Add bio(4) to amd64 and i386 GENERIC. --- distrib/sets/lists/base/mi | 3 +- distrib/sets/lists/comp/mi | 3 +- distrib/sets/lists/man/mi | 6 +- sbin/Makefile | 6 +- sbin/bioctl/Makefile | 10 + sbin/bioctl/bioctl.8 | 164 +++++++++ sbin/bioctl/bioctl.c | 661 +++++++++++++++++++++++++++++++++++ sbin/bioctl/strtonum.c | 72 ++++ sbin/bioctl/strtonum.h | 4 + share/man/man4/Makefile | 4 +- share/man/man4/bio.4 | 124 +++++++ sys/arch/amd64/conf/GENERIC | 5 +- sys/arch/i386/conf/GENERIC | 5 +- sys/arch/i386/conf/XEN2_DOM0 | 3 +- sys/conf/files | 4 +- sys/conf/majors | 3 +- sys/dev/Makefile | 4 +- sys/dev/bio.c | 234 +++++++++++++ sys/dev/biovar.h | 191 ++++++++++ sys/dev/ic/mfi.c | 262 +++++++------- sys/dev/ic/mfivar.h | 13 +- sys/sys/envsys.h | 22 +- usr.sbin/envstat/envstat.c | 11 +- 23 files changed, 1667 insertions(+), 147 deletions(-) create mode 100644 sbin/bioctl/Makefile create mode 100644 sbin/bioctl/bioctl.8 create mode 100644 sbin/bioctl/bioctl.c create mode 100644 sbin/bioctl/strtonum.c create mode 100644 sbin/bioctl/strtonum.h create mode 100644 share/man/man4/bio.4 create mode 100644 sys/dev/bio.c create mode 100644 sys/dev/biovar.h diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index a54e19a40dee..cd62c5b40faf 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.703 2007/04/26 21:22:04 agc Exp $ +# $NetBSD: mi,v 1.704 2007/05/01 17:18:52 bouyer Exp $ . base-sys-root ./altroot base-sys-root ./bin base-sys-root @@ -123,6 +123,7 @@ ./sbin/amrctl base-sysutil-root ./sbin/apmlabel base-sysutil-root ./sbin/atactl base-sysutil-root +./sbin/bioctl base-sysutil-root ./sbin/badsect base-sysutil-root ./sbin/brconfig base-netutil-root ./sbin/ccdconfig base-sysutil-root diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index e031bcc81989..f666125eaa8e 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1021 2007/04/30 14:44:28 rmind Exp $ +# $NetBSD: mi,v 1.1022 2007/05/01 17:18:52 bouyer Exp $ ./etc/mtree/set.comp comp-sys-root ./usr/bin/addr2line comp-debug-bin bfd ./usr/bin/ar comp-util-bin bfd @@ -156,6 +156,7 @@ ./usr/include/dev/auconv.h comp-obsolete obsolete ./usr/include/dev/audio_if.h comp-obsolete obsolete ./usr/include/dev/audiovar.h comp-obsolete obsolete +./usr/include/dev/biovar.h comp-c-include ./usr/include/dev/bluetooth comp-c-include ./usr/include/dev/bluetooth/btdev.h comp-c-include ./usr/include/dev/bluetooth/bthidev.h comp-c-include diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index 86a2788329eb..26d1591361c7 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.996 2007/04/26 21:22:04 agc Exp $ +# $NetBSD: mi,v 1.997 2007/05/01 17:18:53 bouyer Exp $ ./etc/mtree/set.man man-sys-root ./usr/share/info/am-utils.info man-amd-info info ./usr/share/info/as.info man-computil-info bfd,info @@ -721,6 +721,7 @@ ./usr/share/man/cat4/bge.0 man-sys-catman .cat ./usr/share/man/cat4/bha.0 man-sys-catman .cat ./usr/share/man/cat4/bicc.0 man-sys-catman .cat +./usr/share/man/cat4/bio.0 man-sys-catman .cat ./usr/share/man/cat4/bktr.0 man-sys-catman .cat ./usr/share/man/cat4/bluetooth.0 man-sys-catman .cat ./usr/share/man/cat4/bmtphy.0 man-sys-catman .cat @@ -1814,6 +1815,7 @@ ./usr/share/man/cat8/badsect.0 man-sysutil-catman .cat ./usr/share/man/cat8/bebox/MAKEDEV.0 man-obsolete obsolete ./usr/share/man/cat8/bebox/makedev.0 man-obsolete obsolete +./usr/share/man/cat8/bioctl.0 man-sysutil-catman .cat ./usr/share/man/cat8/boot.0 man-sysutil-catman .cat ./usr/share/man/cat8/bootparamd.0 man-bootserver-catman .cat ./usr/share/man/cat8/bootpd.0 man-bootserver-catman .cat @@ -3172,6 +3174,7 @@ ./usr/share/man/man4/bge.4 man-sys-man .man ./usr/share/man/man4/bha.4 man-sys-man .man ./usr/share/man/man4/bicc.4 man-sys-man .man +./usr/share/man/man4/bio.4 man-sys-man .man ./usr/share/man/man4/bktr.4 man-sys-man .man ./usr/share/man/man4/bluetooth.4 man-sys-man .man ./usr/share/man/man4/bmtphy.4 man-sys-man .man @@ -4264,6 +4267,7 @@ ./usr/share/man/man8/badsect.8 man-sysutil-man .man ./usr/share/man/man8/bebox/MAKEDEV.8 man-obsolete obsolete ./usr/share/man/man8/bebox/makedev.8 man-obsolete obsolete +./usr/share/man/man8/bioctl.8 man-sysutil-man .man ./usr/share/man/man8/boot.8 man-sysutil-man .man ./usr/share/man/man8/bootparamd.8 man-bootserver-man .man ./usr/share/man/man8/bootpd.8 man-bootserver-man .man diff --git a/sbin/Makefile b/sbin/Makefile index f349abe85102..69f6cc30889c 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.104 2007/03/06 11:28:45 dillo Exp $ +# $NetBSD: Makefile,v 1.105 2007/05/01 17:18:53 bouyer Exp $ # @(#)Makefile 8.5 (Berkeley) 3/31/94 # Not ported: XNSrouted enpload scsiformat startslip @@ -6,8 +6,8 @@ .include -SUBDIR= amrctl apmlabel atactl badsect bim brconfig ccdconfig disklabel \ - dkctl dkscan_bsdlabel dmesg \ +SUBDIR= amrctl apmlabel atactl badsect bim bioctl brconfig ccdconfig \ + disklabel dkctl dkscan_bsdlabel dmesg \ drvctl edlabel fastboot fdisk fsck fsirand gpt ifconfig init ldconfig \ mbrlabel mknod modload modunload mount newbtconf nologin \ pdisk ping pppoectl raidctl reboot rcorder rndctl route routed \ diff --git a/sbin/bioctl/Makefile b/sbin/bioctl/Makefile new file mode 100644 index 000000000000..5c48c7d0dd1c --- /dev/null +++ b/sbin/bioctl/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.8 2006/11/26 11:31:08 deraadt Exp $ + +PROG= bioctl +SRCS= bioctl.c strtonum.c +MAN= bioctl.8 + +DPADD= ${LIBUTIL} +LDADD= -lutil + +.include diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8 new file mode 100644 index 000000000000..5f53f75c1267 --- /dev/null +++ b/sbin/bioctl/bioctl.8 @@ -0,0 +1,164 @@ +.\" $NetBSD: bioctl.8,v 1.1 2007/05/01 17:18:53 bouyer Exp $ +.\" $OpenBSD: bioctl.8,v 1.43 2007/03/20 06:12:11 jmc Exp $ +.\" +.\" Copyright (c) 2004, 2005 Marco Peereboom +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 8, 2007 +.Dt BIOCTL 8 +.Os +.Sh NAME +.Nm bioctl +.Nd RAID management interface +.Sh SYNOPSIS +.Nm bioctl +.Bk -words +.Op Fl Dhiv +.Op Fl a Ar alarm-function +.Op Fl b Ar channel:target[.lun] +.Op Fl c Ar raidlevel +.Op Fl H Ar channel:target[.lun] +.Op Fl l Ar special[,special[,...]] +.Op Fl u Ar channel:target[.lun] +.Ar device +.Ek +.Sh DESCRIPTION +RAID device drivers which support management functionality can +register their services with the +.Xr bio 4 +driver. +.Nm bioctl +then can be used to maintain RAID volumes. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a Ar alarm-function +Control the RAID card's alarm functionality, if supported. +.Ar alarm-function +may be one of: +.Pp +.Bl -tag -width disable -compact +.It Ar disable +Disable the alarm on the RAID controller. +.It Ar enable +Enable the alarm on the RAID controller. +.It Ar get +Retrieve the current alarm state (enabled or disabled). +.It Ar silence | Ar quiet +Silence the alarm if it is currently beeping. +.El +.Pp +The +.Ar alarm-function +may be specified as given above, +or by the first letter only +(e.g. -a e). +.It Fl b Ar channel:target[.lun] +Instruct the device at +.Ar channel:target[.lun] +to start blinking, if there is +.Xr ses 4 +or +.Xr safte 4 +support in the enclosure. +.It Fl c Ar raidlevel +Create a +.Xr softraid 4 +device of level +.Ar raidlevel . +The device must begin with +.Dq softraid +followed by a number. +.It Fl D +Enable debug output. +.It Fl H Ar channel:target[.lun] +If the device at +.Ar channel:target[.lun] +is currently marked +.Dq Unused , +promote it to being a +.Dq Hot Spare . +.It Fl h +Where necessary, produce "human-readable" output. +Use unit suffixes: Byte, Kilobyte, Megabyte, +Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of +digits to four or less. +.It Fl i +Enumerate the selected RAID devices. +.It Fl l Ar special[,special[,...]] +Use +.Ar special +device list to create within the +.Xr softraid 4 +framework. +Requires +.Fl c . +.It Fl u Ar channel:target[.lun] +Instruct the device at +.Ar channel:target[.lun] +to cease blinking, if there is +.Xr ses 4 +or +.Xr safte 4 +support in the enclosure. +.It Fl v +Be more verbose in output. +.It Ar device +Select a drive by name (e.g. sd0) or a RAID controller by name (e.g. ami0). +For operations which will be performed against +.Xr ses 4 +or +.Xr safte 4 +enclosures, it is also possible to directly specify the enclosure name +(e.g. safte0). +.El +.Sh EXAMPLES +The following command, executed from the command line, shows the status of +the logical drives on the RAID controller: +.Bd -literal +# bioctl -h mfi0 +Volume Status Size Device + mfi0 0 Online 74G mfi0 RAID1 + 0 Online 75G 1:0.0 noencl + 1 Online 75G 1:1.0 noencl + mfi0 1 Online 697G mfi0 RAID5 + 0 Online 233G 1:3.0 noencl + 1 Online 233G 1:2.0 noencl + 2 Online 233G 1:4.0 noencl + 3 Online 233G 1:5.0 noencl +.Ed +.Sh SEE ALSO +.Xr bio 4 , +.Xr mfi 4 , +.Sh BUGS +the softraid stuff available at this time. +.Sh HISTORY +The +.Nm +command first appeared in +.Ox 3.8 . +.Sh AUTHORS +The +.Nm +interface was written by +.An Marco Peereboom Aq marco@openbsd.org . diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c new file mode 100644 index 000000000000..bb1b07015c0b --- /dev/null +++ b/sbin/bioctl/bioctl.c @@ -0,0 +1,661 @@ +/* $NetBSD: bioctl.c,v 1.1 2007/05/01 17:18:53 bouyer Exp $ */ +/* $OpenBSD: bioctl.c,v 1.52 2007/03/20 15:26:06 jmc Exp $ */ + +/* + * Copyright (c) 2004, 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include + +#ifndef lint +__RCSID("$NetBSD: bioctl.c,v 1.1 2007/05/01 17:18:53 bouyer Exp $"); +#endif + +#include +#include +#include +// #include +// #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "strtonum.h" + +struct locator { + int channel; + int target; + int lun; +}; + +void usage(void); +const char *str2locator(const char *, struct locator *); +void cleanup(void); + +void bio_inq(char *); +void bio_alarm(char *); +void bio_setstate(char *); +void bio_setblink(char *, char *, int); +void bio_blink(char *, int, int); +void bio_createraid(u_int16_t, char *); + +int devh = -1; +int debug; +int human; +int verbose; + +struct bio_locate bl; + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + u_int64_t func = 0; + /* u_int64_t subfunc = 0; XXX */ + char *bioc_dev = NULL, *sd_dev = NULL; + char /* *realname = NULL, XXX */ *al_arg = NULL; + char *bl_arg = NULL, *dev_list = NULL; + int ch, rv, blink = 0; /* XXX GCC */ + u_int16_t cr_level = 0; /* XXX GCC */ + + if (argc < 2) + usage(); + + while ((ch = getopt(argc, argv, "b:c:l:u:H:ha:Div")) != -1) { + switch (ch) { + case 'a': /* alarm */ + func |= BIOC_ALARM; + al_arg = optarg; + break; + case 'b': /* blink */ + func |= BIOC_BLINK; + blink = BIOC_SBBLINK; + bl_arg = optarg; + break; + case 'c': /* create */ + func |= BIOC_CREATERAID; + cr_level = atoi(optarg); + break; + case 'u': /* unblink */ + func |= BIOC_BLINK; + blink = BIOC_SBUNBLINK; + bl_arg = optarg; + break; + case 'D': /* debug */ + debug = 1; + break; + case 'H': /* set hotspare */ + func |= BIOC_SETSTATE; + al_arg = optarg; + break; + case 'h': + human = 1; + break; + case 'i': /* inquiry */ + func |= BIOC_INQ; + break; + case 'l': /* device list */ + func |= BIOC_DEVLIST; + dev_list = optarg; + break; + case 'v': + verbose = 1; + break; + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + if (func == 0) + func |= BIOC_INQ; +#if 0 + /* if at least glob sd[0-9]*, it is a drive identifier */ + if (strncmp(argv[0], "sd", 2) == 0 && strlen(argv[0]) > 2 && + isdigit((int)argv[0][2])) + sd_dev = argv[0]; + else +#endif + bioc_dev = argv[0]; + + if (bioc_dev) { + devh = open("/dev/bio", O_RDWR); + if (devh == -1) + err(1, "Can't open %s", "/dev/bio"); + + bl.bl_name = bioc_dev; + rv = ioctl(devh, BIOCLOCATE, &bl); + if (rv == -1) + errx(1, "Can't locate %s device via %s", + bl.bl_name, "/dev/bio"); + } +#if 0 + else if (sd_dev) { + devh = opendev(sd_dev, O_RDWR, OPENDEV_PART, &realname); + if (devh == -1) + err(1, "Can't open %s", sd_dev); + } +#endif + else + errx(1, "need -d or -f parameter"); + + if (debug) + warnx("cookie = %p", bl.bl_cookie); + + if (func & BIOC_INQ) { + bio_inq(sd_dev); + } else if (func == BIOC_ALARM) { + bio_alarm(al_arg); + } else if (func == BIOC_BLINK) { + bio_setblink(sd_dev, bl_arg, blink); + } else if (func == BIOC_SETSTATE) { + bio_setstate(al_arg); + } else if (func & BIOC_CREATERAID || func & BIOC_DEVLIST) { + if (!(func & BIOC_CREATERAID)) + errx(1, "need -c parameter"); + if (!(func & BIOC_DEVLIST)) + errx(1, "need -l parameter"); + if (sd_dev) + errx(1, "can't use sd device"); + bio_createraid(cr_level, dev_list); + } + + return (0); +} + +void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, + "usage: %s [-Dhiv] [-a alarm-function] " + "[-b channel:target[.lun]]\n" + "\t[-c raidlevel] [-H channel:target[.lun]]\n" + "\t[-l special[,special[,...]]] " + "[-u channel:target[.lun]] device\n", __progname); + + exit(1); +} + +const char * +str2locator(const char *string, struct locator *location) +{ + const char *errstr; + char parse[80], *targ, *lun; + + strlcpy(parse, string, sizeof parse); + targ = strchr(parse, ':'); + if (targ == NULL) + return ("target not specified"); + *targ++ = '\0'; + + lun = strchr(targ, '.'); + if (lun != NULL) { + *lun++ = '\0'; + location->lun = strtonum(lun, 0, 256, &errstr); + if (errstr) + return (errstr); + } else + location->lun = 0; + + location->target = strtonum(targ, 0, 256, &errstr); + if (errstr) + return (errstr); + location->channel = strtonum(parse, 0, 256, &errstr); + if (errstr) + return (errstr); + return (NULL); +} + +void +bio_inq(char *name) +{ + const char *status; + char size[64], scsiname[16], volname[32]; + char percent[10], seconds[20]; + int rv, i, d, volheader, hotspare, unused; + char encname[16], serial[32]; + struct bioc_disk bd; + struct bioc_inq bi; + struct bioc_vol bv; + + memset(&bi, 0, sizeof(bi)); + + if (debug) + printf("bio_inq\n"); + + bi.bi_cookie = bl.bl_cookie; + + rv = ioctl(devh, BIOCINQ, &bi); + if (rv == -1) { + warn("BIOCINQ"); + return; + } + + if (debug) + printf("bio_inq { %p, %s, %d, %d }\n", + bi.bi_cookie, + bi.bi_dev, + bi.bi_novol, + bi.bi_nodisk); + + volheader = 0; + for (i = 0; i < bi.bi_novol; i++) { + memset(&bv, 0, sizeof(bv)); + bv.bv_cookie = bl.bl_cookie; + bv.bv_volid = i; + bv.bv_percent = -1; + bv.bv_seconds = 0; + + rv = ioctl(devh, BIOCVOL, &bv); + if (rv == -1) { + warn("BIOCVOL"); + return; + } + + if (name && strcmp(name, bv.bv_dev) != 0) + continue; + + if (!volheader) { + volheader = 1; + printf("%-7s %-10s %14s %-8s\n", + "Volume", "Status", "Size", "Device"); + } + + percent[0] = '\0'; + seconds[0] = '\0'; + if (bv.bv_percent != -1) + snprintf(percent, sizeof percent, + " %d%% done", bv.bv_percent); + if (bv.bv_seconds) + snprintf(seconds, sizeof seconds, + " %u seconds", bv.bv_seconds); + switch (bv.bv_status) { + case BIOC_SVONLINE: + status = BIOC_SVONLINE_S; + break; + case BIOC_SVOFFLINE: + status = BIOC_SVOFFLINE_S; + break; + case BIOC_SVDEGRADED: + status = BIOC_SVDEGRADED_S; + break; + case BIOC_SVBUILDING: + status = BIOC_SVBUILDING_S; + break; + case BIOC_SVREBUILD: + status = BIOC_SVREBUILD_S; + break; + case BIOC_SVSCRUB: + status = BIOC_SVSCRUB_S; + break; + case BIOC_SVINVALID: + default: + status = BIOC_SVINVALID_S; + } + + snprintf(volname, sizeof volname, "%s %u", + bi.bi_dev, bv.bv_volid); + + if (bv.bv_level == -1 && bv.bv_nodisk == 1) { + hotspare = 1; + unused = 0; + } else if (bv.bv_level == -2 && bv.bv_nodisk == 1) { + unused = 1; + hotspare = 0; + } else { + unused = 0; + hotspare = 0; + + if (human) + humanize_number(size, 5, + (int64_t)bv.bv_size, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE | HN_DECIMAL); + else + snprintf(size, sizeof size, "%14llu", + (long long unsigned int)bv.bv_size); + printf("%7s %-10s %14s %-7s RAID%u%s%s\n", + volname, status, size, bv.bv_dev, + bv.bv_level, percent, seconds); + } + + for (d = 0; d < bv.bv_nodisk; d++) { + memset(&bd, 0, sizeof(bd)); + bd.bd_cookie = bl.bl_cookie; + bd.bd_diskid = d; + bd.bd_volid = i; + + rv = ioctl(devh, BIOCDISK, &bd); + if (rv == -1) { + warn("BIOCDISK"); + return; + } + + switch (bd.bd_status) { + case BIOC_SDONLINE: + status = BIOC_SDONLINE_S; + break; + case BIOC_SDOFFLINE: + status = BIOC_SDOFFLINE_S; + break; + case BIOC_SDFAILED: + status = BIOC_SDFAILED_S; + break; + case BIOC_SDREBUILD: + status = BIOC_SDREBUILD_S; + break; + case BIOC_SDHOTSPARE: + status = BIOC_SDHOTSPARE_S; + break; + case BIOC_SDUNUSED: + status = BIOC_SDUNUSED_S; + break; + case BIOC_SDSCRUB: + status = BIOC_SDSCRUB_S; + break; + case BIOC_SDINVALID: + default: + status = BIOC_SDINVALID_S; + } + + if (hotspare || unused) + ; /* use volname from parent volume */ + else + snprintf(volname, sizeof volname, " %3u", + bd.bd_diskid); + + if (human) + humanize_number(size, 5, + bd.bd_size, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE | HN_DECIMAL); + else + snprintf(size, sizeof size, "%14llu", + (long long unsigned int)bd.bd_size); + snprintf(scsiname, sizeof scsiname, + "%u:%u.%u", + bd.bd_channel, bd.bd_target, bd.bd_lun); + if (bd.bd_procdev[0]) + strlcpy(encname, bd.bd_procdev, sizeof encname); + else + strlcpy(encname, "noencl", sizeof encname); + if (bd.bd_serial[0]) + strlcpy(serial, bd.bd_serial, sizeof serial); + else + strlcpy(serial, "unknown serial", sizeof serial); + + printf("%7s %-10s %14s %-7s %-6s <%s>\n", + volname, status, size, scsiname, encname, + bd.bd_vendor); + if (verbose) + printf("%7s %-10s %14s %-7s %-6s '%s'\n", + "", "", "", "", "", serial); + } + } +} + +void +bio_alarm(char *arg) +{ + int rv; + struct bioc_alarm ba; + + ba.ba_cookie = bl.bl_cookie; + + switch (arg[0]) { + case 'q': /* silence alarm */ + /* FALLTHROUGH */ + case 's': + ba.ba_opcode = BIOC_SASILENCE; + break; + + case 'e': /* enable alarm */ + ba.ba_opcode = BIOC_SAENABLE; + break; + + case 'd': /* disable alarm */ + ba.ba_opcode = BIOC_SADISABLE; + break; + + case 't': /* test alarm */ + ba.ba_opcode = BIOC_SATEST; + break; + + case 'g': /* get alarm state */ + ba.ba_opcode = BIOC_GASTATUS; + break; + + default: + warnx("invalid alarm function: %s", arg); + return; + } + + rv = ioctl(devh, BIOCALARM, &ba); + if (rv == -1) { + warn("BIOCALARM"); + return; + } + + if (arg[0] == 'g') { + printf("alarm is currently %s\n", + ba.ba_status ? "enabled" : "disabled"); + + } +} + +void +bio_setstate(char *arg) +{ + struct bioc_setstate bs; + struct locator location; + const char *errstr; + int rv; + + errstr = str2locator(arg, &location); + if (errstr) + errx(1, "Target %s: %s", arg, errstr); + + bs.bs_cookie = bl.bl_cookie; + bs.bs_status = BIOC_SSHOTSPARE; + bs.bs_channel = location.channel; + bs.bs_target = location.target; + bs.bs_lun = location.lun; + + rv = ioctl(devh, BIOCSETSTATE, &bs); + if (rv == -1) { + warn("BIOCSETSTATE"); + return; + } +} + +void +bio_setblink(char *name, char *arg, int blink) +{ + struct locator location; + struct bioc_inq bi; + struct bioc_vol bv; + struct bioc_disk bd; + struct bioc_blink bb; + const char *errstr; + int v, d, rv; + + errstr = str2locator(arg, &location); + if (errstr) + errx(1, "Target %s: %s", arg, errstr); + + /* try setting blink on the device directly */ + memset(&bb, 0, sizeof(bb)); + bb.bb_cookie = bl.bl_cookie; + bb.bb_status = blink; + bb.bb_target = location.target; + bb.bb_channel = location.channel; + rv = ioctl(devh, BIOCBLINK, &bb); + if (rv == 0) + return; + + /* if the blink didnt work, try to find something that will */ + + memset(&bi, 0, sizeof(bi)); + bi.bi_cookie = bl.bl_cookie; + rv = ioctl(devh, BIOCINQ, &bi); + if (rv == -1) { + warn("BIOCINQ"); + return; + } + + for (v = 0; v < bi.bi_novol; v++) { + memset(&bv, 0, sizeof(bv)); + bv.bv_cookie = bl.bl_cookie; + bv.bv_volid = v; + rv = ioctl(devh, BIOCVOL, &bv); + if (rv == -1) { + warn("BIOCVOL"); + return; + } + + if (name && strcmp(name, bv.bv_dev) != 0) + continue; + + for (d = 0; d < bv.bv_nodisk; d++) { + memset(&bd, 0, sizeof(bd)); + bd.bd_cookie = bl.bl_cookie; + bd.bd_volid = v; + bd.bd_diskid = d; + + rv = ioctl(devh, BIOCDISK, &bd); + if (rv == -1) { + warn("BIOCDISK"); + return; + } + + if (bd.bd_channel == location.channel && + bd.bd_target == location.target && + bd.bd_lun == location.lun) { + if (bd.bd_procdev[0] != '\0') { + bio_blink(bd.bd_procdev, + location.target, blink); + } else + warnx("Disk %s is not in an enclosure", arg); + return; + } + } + } + + warnx("Disk %s does not exist", arg); + return; +} + +void +bio_blink(char *enclosure, int target, int blinktype) +{ + int bioh; + struct bio_locate bio; + struct bioc_blink blink; + int rv; + + bioh = open("/dev/bio", O_RDWR); + if (bioh == -1) + err(1, "Can't open %s", "/dev/bio"); + + bio.bl_name = enclosure; + rv = ioctl(bioh, BIOCLOCATE, &bio); + if (rv == -1) + errx(1, "Can't locate %s device via %s", enclosure, "/dev/bio"); + + memset(&blink, 0, sizeof(blink)); + blink.bb_cookie = bio.bl_cookie; + blink.bb_status = blinktype; + blink.bb_target = target; + + rv = ioctl(bioh, BIOCBLINK, &blink); + if (rv == -1) + warn("BIOCBLINK"); + + close(bioh); +} + +void +bio_createraid(u_int16_t level, char *dev_list) +{ + struct bioc_createraid create; + int rv; + u_int16_t min_disks = 0; + + if (debug) + printf("bio_createraid\n"); + + if (!dev_list) + errx(1, "no devices specified"); + + switch (level) { + case 0: + min_disks = 1; + break; + case 1: + min_disks = 2; + break; + default: + errx(1, "unsuported raid level"); + } + + /* XXX validate device list for real */ +#if 0 + if (strncmp(dev_list, "sd", 2) == 0 && strlen(dev_list) > 2 && + isdigit(dev_list[2])) { + if (strlen(dev_list) != 3) + errx(1, "only one device supported"); + + if (debug) + printf("bio_createraid: dev_list: %s\n", dev_list); + } + else + errx(1, "no sd device specified"); +#endif + + memset(&create, 0, sizeof(create)); + create.bc_cookie = bl.bl_cookie; + create.bc_level = level; + create.bc_dev_list_len = strlen(dev_list); + create.bc_dev_list = dev_list; + + rv = ioctl(devh, BIOCCREATERAID, &create); + if (rv == -1) { + warn("BIOCCREATERAID"); + return; + } +} diff --git a/sbin/bioctl/strtonum.c b/sbin/bioctl/strtonum.c new file mode 100644 index 000000000000..c4f23108b6e0 --- /dev/null +++ b/sbin/bioctl/strtonum.c @@ -0,0 +1,72 @@ +/* $NetBSD: strtonum.c,v 1.1 2007/05/01 17:18:54 bouyer Exp $ */ +/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ + +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include + +#ifndef lint +__RCSID("$NetBSD: strtonum.c,v 1.1 2007/05/01 17:18:54 bouyer Exp $"); +#endif + +#include +#include +#include +#include "strtonum.h" + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + char *ep; + int error = 0; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) + error = INVALID; + else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} diff --git a/sbin/bioctl/strtonum.h b/sbin/bioctl/strtonum.h new file mode 100644 index 000000000000..a9c02e95178e --- /dev/null +++ b/sbin/bioctl/strtonum.h @@ -0,0 +1,4 @@ +/* $NetBSD: strtonum.h,v 1.1 2007/05/01 17:18:54 bouyer Exp $ */ + +long long strtonum(const char *, long long, long long, const char **); + diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 51119b44de89..26d0092c7fc0 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.425 2007/04/21 06:11:58 plunky Exp $ +# $NetBSD: Makefile,v 1.426 2007/05/01 17:18:54 bouyer Exp $ # @(#)Makefile 8.1 (Berkeley) 6/18/93 MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \ @@ -8,7 +8,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \ ath.4 atppc.4 attimer.4 atw.4 \ auacer.4 audio.4 audiocs.4 auich.4 \ auixp.4 autri.4 auvia.4 awi.4 azalia.4 \ - bba.4 bce.4 be.4 bge.4 bnx.4 bha.4 bktr.4 bluetooth.4 bmtphy.4 \ + bba.4 bce.4 be.4 bge.4 bnx.4 bha.4 bio.4 bktr.4 bluetooth.4 bmtphy.4 \ bpf.4 brgphy.4 bridge.4 bthidev.4 bthub.4 btkbd.4 btms.4 btsco.4 \ btuart.4 cac.4 cardbus.4 carp.4 ccd.4 cd.4 \ cec.4 cgd.4 cfb.4 ch.4 chipsfb.4 ciphy.4 ciss.4 clcs.4 clct.4 clnp.4 \ diff --git a/share/man/man4/bio.4 b/share/man/man4/bio.4 new file mode 100644 index 000000000000..469795915e67 --- /dev/null +++ b/share/man/man4/bio.4 @@ -0,0 +1,124 @@ +.\" $NetBSD: bio.4,v 1.1 2007/05/01 17:20:10 bouyer Exp $ +.\" $OpenBSD: bio.4,v 1.19 2006/09/20 22:22:37 jmc Exp $ +.\" +.\" Copyright (c) 2002 Niklas Hallqvist +.\" Copyright (c) 2006 Marco Peereboom +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +.\" DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd April 8, 2007 +.Dt BIO 4 +.Os +.Sh NAME +.Nm bio +.Nd Block IO ioctl tunnel pseudo-device +.Sh SYNOPSIS +.Cd "pseudo-device bio" +.Sh DESCRIPTION +The +.Nm +driver provides userland applications +.Xr ioctl 2 +access to devices otherwise not found as +.Pa /dev +nodes. +The +.Pa /dev/bio +device node operates by delegating ioctl +calls to a requested device driver. +Only drivers which have registered with the +.Nm +device can be accessed via this interface. +.Pp +The following device drivers register with +.Nm +for volume management: +.Pp +.Bl -tag -width ciss(4)XX -offset indent -compact +.\" .It Xr ami 4 +.\" American Megatrends Inc. MegaRAID PATA/SATA/SCSI RAID controller +.\" .It Xr arc 4 +.\" Areca Technology Corporation SATA RAID controller +.\" .It Xr ciss 4 +.\" Compaq Smart ARRAY 5/6 SAS/SATA/SCSI RAID controller +.It Xr mfi 4 +LSI Logic & Dell MegaRAID SAS RAID controller +.El +.Pp +The following ioctl calls apply to the +.Nm bio +device: +.Bl -tag -width BIOCCAPABILITIES +.It Dv BIOCLOCATE +Locate a named device and give back a cookie to the application +for subsequent ioctl calls. +The cookie is used to tunnel further ioctls to the right device. +.It Dv BIOCINQ +Retrieve number of volumes and physical disks for a specific device. +.It Dv BIOCDISK +Retrieve detailed information for the specified physical disk. +Information returned can include status, size, channel, target, lun, +vendor name, serial number and processor device (ses or safte). +.It Dv BIOCVOL +Retrieve detailed information for the specified volume. +Information returned can include status, size, RAID level, number of disks, +device name association (sd?) and vendor name. +.It Dv BIOCALARM +Control the alarm beeper on the device. +Supported states are: disable alarm, enable alarm, silence alarm, status and +test alarm. +.Pp +Note: These options might not be supported on all hardware. +.It Dv BIOCBLINK +Blink an LED of the specified physical disk. +Supported blink states are: blink LED, unblink LED and blink alarm LED. +.Pp +Note: This option is only supported if the disk is governed by ses(4) or +safte(4) and the hardware supports hardware blinking. +.It Dv BIOCSETSTATE +Alter the state of specified physical disk. +Supported states are: create hot-spare, online disk and offline disk. +.El +.Sh FILES +.Bl -tag -width /dev/bio -compact +.It Pa /dev/bio +ioctl tunnel device +.El +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr bioctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Ox 3.2 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Niklas Hallqvist Aq niklas@openbsd.org . +The API was written by +.An Marco Peereboom Aq marco@openbsd.org . diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index 71f263cae45c..21e5992a9dfc 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.138 2007/04/23 04:55:07 dyoung Exp $ +# $NetBSD: GENERIC,v 1.139 2007/05/01 17:18:54 bouyer Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.138 $" +#ident "GENERIC-$Revision: 1.139 $" maxusers 32 # estimated number of users @@ -882,6 +882,7 @@ pseudo-device crypto # /dev/crypto device pseudo-device swcrypto # software crypto implementation # disk/mass storage pseudo-devices +pseudo-device bio # RAID control device driver pseudo-device ccd 4 # concatenated/striped disk devices #pseudo-device cgd 4 # cryptographic disk devices pseudo-device raid 8 # RAIDframe disk driver diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index b8e5466d82db..f3ab6774ff3d 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.824 2007/04/26 17:11:36 dyoung Exp $ +# $NetBSD: GENERIC,v 1.825 2007/05/01 17:18:54 bouyer Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.824 $" +#ident "GENERIC-$Revision: 1.825 $" maxusers 32 # estimated number of users @@ -1361,6 +1361,7 @@ pseudo-device crypto # /dev/crypto device pseudo-device swcrypto # software crypto implementation # disk/mass storage pseudo-devices +pseudo-device bio # RAID control device driver pseudo-device ccd 4 # concatenated/striped disk devices #pseudo-device cgd 4 # cryptographic disk devices pseudo-device raid 8 # RAIDframe disk driver diff --git a/sys/arch/i386/conf/XEN2_DOM0 b/sys/arch/i386/conf/XEN2_DOM0 index ec66c1394114..e3053b88a801 100644 --- a/sys/arch/i386/conf/XEN2_DOM0 +++ b/sys/arch/i386/conf/XEN2_DOM0 @@ -1,4 +1,4 @@ -# $NetBSD: XEN2_DOM0,v 1.24 2007/03/14 12:27:24 drochner Exp $ +# $NetBSD: XEN2_DOM0,v 1.25 2007/05/01 17:18:55 bouyer Exp $ include "arch/xen/conf/std.xen" @@ -683,6 +683,7 @@ pseudo-device crypto # /dev/crypto device pseudo-device swcrypto # software crypto implementation # disk/mass storage pseudo-devices +pseudo-device bio # RAID control device driver pseudo-device ccd 4 # concatenated/striped disk devices #pseudo-device cgd 4 # cryptographic disk devices pseudo-device raid 8 # RAIDframe disk driver diff --git a/sys/conf/files b/sys/conf/files index d4c850783775..b0192f8eb792 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.838 2007/04/30 14:44:29 rmind Exp $ +# $NetBSD: files,v 1.839 2007/05/01 17:18:55 bouyer Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -1144,6 +1144,7 @@ defpseudo rnd defpseudo ksyms defpseudo nullcons defpseudo lockstat +defpseudo bio: sysmon_envsys defpseudo loop: ifnet defpseudo sl: ifnet @@ -1242,6 +1243,7 @@ file dev/auconv.c auconv | mulaw file dev/audio.c audio | midi | midibus needs-flag file dev/audiobell.c audiobell file dev/aurateconv.c aurateconv needs-flag +file dev/bio.c bio needs-flag file dev/ccd.c ccd needs-flag file dev/cgd.c cgd needs-flag file dev/cgd_crypto.c cgd diff --git a/sys/conf/majors b/sys/conf/majors index 1687537fdb62..278733404e95 100644 --- a/sys/conf/majors +++ b/sys/conf/majors @@ -1,4 +1,4 @@ -# $NetBSD: majors,v 1.33 2007/03/20 16:37:12 drochner Exp $ +# $NetBSD: majors,v 1.34 2007/05/01 17:18:55 bouyer Exp $ # # Device majors for Machine-Independent drivers. # @@ -30,4 +30,5 @@ device-major lockstat char 177 lockstat device-major puffs char 178 puffs device-major srt char 179 srt device-major drm char 180 drmbase +device-major bio char 181 bio device-major twa char 187 twa diff --git a/sys/dev/Makefile b/sys/dev/Makefile index 9cb26d7159d6..1975a6d6da77 100644 --- a/sys/dev/Makefile +++ b/sys/dev/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.24 2006/09/07 00:20:28 ad Exp $ +# $NetBSD: Makefile,v 1.25 2007/05/01 17:18:55 bouyer Exp $ SUBDIR= apm ata bluetooth dec dmover hpc i2o ic ieee1394 ir isa microcode ofw \ pci pckbport pcmcia raidframe sbus scsipi sun tc usb vme wscons @@ -6,6 +6,6 @@ SUBDIR= apm ata bluetooth dec dmover hpc i2o ic ieee1394 ir isa microcode ofw \ INCSDIR= /usr/include/dev # Only install includes which are used by userland -INCS= ccdvar.h cgdvar.h fssvar.h kttcpio.h lockstat.h md.h vndvar.h +INCS= biovar.h ccdvar.h cgdvar.h fssvar.h kttcpio.h lockstat.h md.h vndvar.h .include diff --git a/sys/dev/bio.c b/sys/dev/bio.c new file mode 100644 index 000000000000..b5d4815edc14 --- /dev/null +++ b/sys/dev/bio.c @@ -0,0 +1,234 @@ +/* $NetBSD: bio.c,v 1.1 2007/05/01 17:20:11 bouyer Exp $ */ +/* $OpenBSD: bio.c,v 1.9 2007/03/20 02:35:55 marco Exp $ */ + +/* + * Copyright (c) 2002 Niklas Hallqvist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* A device controller ioctl tunnelling device. */ + +#include +__KERNEL_RCSID(0, "$NetBSD: bio.c,v 1.1 2007/05/01 17:20:11 bouyer Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct bio_mapping { + LIST_ENTRY(bio_mapping) bm_link; + struct device *bm_dev; + int (*bm_ioctl)(struct device *, u_long, void *); +}; + +LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios); +static kmutex_t bio_lock; + +void bioattach(int); +int bioclose(dev_t, int, int, struct lwp *); +int bioioctl(dev_t, u_long, void *, int, struct lwp *); +int bioopen(dev_t, int, int, struct lwp *); + +int bio_delegate_ioctl(struct bio_mapping *, u_long, void *); +struct bio_mapping *bio_lookup(char *); +int bio_validate(void *); + +const struct cdevsw bio_cdevsw = { + bioopen, bioclose, noread, nowrite, bioioctl, + nostop, notty, nopoll, nommap, nokqfilter, 0 +}; + + +void +bioattach(int nunits) +{ + mutex_init(&bio_lock, MUTEX_DRIVER, IPL_BIO); +} + +int +bioopen(dev_t dev, int flags, int mode, struct lwp *l) +{ + return (0); +} + +int +bioclose(dev_t dev, int flags, int mode, struct lwp *l) +{ + return (0); +} + +int +bioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) +{ + struct bio_locate *locate; + struct bio_common *common; + char name[16]; + int error; + + switch(cmd) { + case BIOCLOCATE: + case BIOCINQ: + case BIOCDISK: + case BIOCVOL: + error = kauth_authorize_device_passthru(l->l_cred, dev, + KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF, addr); + if (error) + return (error); + break; + case BIOCBLINK: + case BIOCSETSTATE: + error = kauth_authorize_device_passthru(l->l_cred, dev, + KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITECONF, addr); + if (error) + return (error); + break; + case BIOCALARM: { + struct bioc_alarm *alarm = (struct bioc_alarm *)addr; + switch (alarm->ba_opcode) { + case BIOC_SADISABLE: + case BIOC_SAENABLE: + case BIOC_SASILENCE: + case BIOC_SATEST: + error = kauth_authorize_device_passthru(l->l_cred, dev, + KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITECONF, addr); + if (error) + return (error); + break; + case BIOC_GASTATUS: + error = kauth_authorize_device_passthru(l->l_cred, dev, + KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF, addr); + if (error) + return (error); + break; + default: + return EINVAL; + } + break; + } + default: + return ENOTTY; + } + + switch (cmd) { + case BIOCLOCATE: + locate = (struct bio_locate *)addr; + error = copyinstr(locate->bl_name, name, 16, NULL); + if (error != 0) + return (error); + locate->bl_cookie = bio_lookup(name); + if (locate->bl_cookie == NULL) + return (ENOENT); + break; + + default: + common = (struct bio_common *)addr; + mutex_enter(&bio_lock); + if (!bio_validate(common->bc_cookie)) { + mutex_exit(&bio_lock); + return (ENOENT); + } + mutex_exit(&bio_lock); + error = bio_delegate_ioctl( + (struct bio_mapping *)common->bc_cookie, cmd, addr); + return (error); + } + return (0); +} + +int +bio_register(struct device *dev, int (*ioctl)(struct device *, u_long, void *)) +{ + struct bio_mapping *bm; + + MALLOC(bm, struct bio_mapping *, sizeof *bm, M_DEVBUF, M_NOWAIT); + if (bm == NULL) + return (ENOMEM); + bm->bm_dev = dev; + bm->bm_ioctl = ioctl; + mutex_enter(&bio_lock); + LIST_INSERT_HEAD(&bios, bm, bm_link); + mutex_exit(&bio_lock); + return (0); +} + +void +bio_unregister(struct device *dev) +{ + struct bio_mapping *bm, *next; + + mutex_enter(&bio_lock); + for (bm = LIST_FIRST(&bios); bm != NULL; bm = next) { + next = LIST_NEXT(bm, bm_link); + + if (dev == bm->bm_dev) { + LIST_REMOVE(bm, bm_link); + free(bm, M_DEVBUF); + } + } + mutex_exit(&bio_lock); +} + +struct bio_mapping * +bio_lookup(char *name) +{ + struct bio_mapping *bm; + + mutex_enter(&bio_lock); + LIST_FOREACH(bm, &bios, bm_link) { + if (strcmp(name, bm->bm_dev->dv_xname) == 0) { + mutex_exit(&bio_lock); + return (bm); + } + } + mutex_exit(&bio_lock); + return (NULL); +} + +int +bio_validate(void *cookie) +{ + struct bio_mapping *bm; + + LIST_FOREACH(bm, &bios, bm_link) { + if (bm == cookie) { + return (1); + } + } + return (0); +} + +int +bio_delegate_ioctl(struct bio_mapping *bm, u_long cmd, void *addr) +{ + + return (bm->bm_ioctl(bm->bm_dev, cmd, addr)); +} diff --git a/sys/dev/biovar.h b/sys/dev/biovar.h new file mode 100644 index 000000000000..3af968fdb673 --- /dev/null +++ b/sys/dev/biovar.h @@ -0,0 +1,191 @@ +/* $NetBSD: biovar.h,v 1.1 2007/05/01 17:20:11 bouyer Exp $ */ +/* $OpenBSD: biovar.h,v 1.26 2007/03/19 03:02:08 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Devices getting ioctls through this interface should use ioctl class 'B' + * and command numbers starting from 32, lower ones are reserved for generic + * ioctls. All ioctl data must be structures which start with a void * + * cookie. + */ + +#include + +struct bio_common { + void *bc_cookie; +}; + +/* convert name to a cookie */ +#define BIOCLOCATE _IOWR('B', 0, struct bio_locate) +struct bio_locate { + void *bl_cookie; + char *bl_name; +}; + +#ifdef _KERNEL +int bio_register(struct device *, int (*)(struct device *, u_long, + void *)); +void bio_unregister(struct device *); +#endif + +#define BIOCINQ _IOWR('B', 32, struct bioc_inq) +struct bioc_inq { + void *bi_cookie; + + char bi_dev[16]; /* controller device */ + int bi_novol; /* nr of volumes */ + int bi_nodisk; /* nr of total disks */ +}; + +#define BIOCDISK _IOWR('B', 33, struct bioc_disk) +/* structure that represents a disk in a RAID volume */ +struct bioc_disk { + void *bd_cookie; + + u_int16_t bd_channel; + u_int16_t bd_target; + u_int16_t bd_lun; + u_int16_t bd_other_id; /* unused for now */ + + int bd_volid; /* associate with volume */ + int bd_diskid; /* virtual disk */ + int bd_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_SDSCRUB 0x06 +#define BIOC_SDSCRUB_S "Scrubbing" +#define BIOC_SDINVALID 0xff +#define BIOC_SDINVALID_S "Invalid" + size_t bd_size; /* size of the disk */ + + char bd_vendor[32]; /* scsi string */ + char bd_serial[32]; /* serial number */ + char bd_procdev[16]; /* processor device */ +}; + +#define BIOCVOL _IOWR('B', 34, struct bioc_vol) +/* structure that represents a RAID volume */ +struct bioc_vol { + void *bv_cookie; + int bv_volid; /* volume id */ + + int16_t bv_percent; /* percent done operation */ + u_int16_t bv_seconds; /* seconds of progress so far */ + + int bv_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_SVBUILDING 0x03 +#define BIOC_SVBUILDING_S "Building" +#define BIOC_SVSCRUB 0x04 +#define BIOC_SVSCRUB_S "Scrubbing" +#define BIOC_SVREBUILD 0x05 +#define BIOC_SVREBUILD_S "Rebuild" +#define BIOC_SVINVALID 0xff +#define BIOC_SVINVALID_S "Invalid" + size_t bv_size; /* size of the disk */ + int bv_level; /* raid level */ + int bv_nodisk; /* nr of drives */ + + char bv_dev[16]; /* device */ + char bv_vendor[32]; /* scsi string */ +}; + +#define BIOCALARM _IOWR('B', 35, struct bioc_alarm) +struct bioc_alarm { + void *ba_cookie; + int ba_opcode; + + int ba_status; /* only used with get state */ +#define BIOC_SADISABLE 0x00 /* disable alarm */ +#define BIOC_SAENABLE 0x01 /* enable alarm */ +#define BIOC_SASILENCE 0x02 /* silence alarm */ +#define BIOC_GASTATUS 0x03 /* get status */ +#define BIOC_SATEST 0x04 /* test alarm */ +}; + +#define BIOCBLINK _IOWR('B', 36, struct bioc_blink) +struct bioc_blink { + void *bb_cookie; + u_int16_t bb_channel; + u_int16_t bb_target; + + int bb_status; /* current status */ +#define BIOC_SBUNBLINK 0x00 /* disable blinking */ +#define BIOC_SBBLINK 0x01 /* enable blink */ +#define BIOC_SBALARM 0x02 /* enable alarm blink */ +}; + +#define BIOCSETSTATE _IOWR('B', 37, struct bioc_setstate) +struct bioc_setstate { + void *bs_cookie; + u_int16_t bs_channel; + u_int16_t bs_target; + u_int16_t bs_lun; + u_int16_t bs_other_id; /* unused for now */ + + int bs_status; /* change to this status */ +#define BIOC_SSONLINE 0x00 /* online disk */ +#define BIOC_SSOFFLINE 0x01 /* offline disk */ +#define BIOC_SSHOTSPARE 0x02 /* mark as hotspare */ +#define BIOC_SSREBUILD 0x03 /* rebuild on this disk */ + int bs_volid; /* volume id for rebuild */ +}; + +#define BIOCCREATERAID _IOWR('B', 38, struct bioc_createraid) +struct bioc_createraid { + void *bc_cookie; + char *bc_dev_list; + u_int16_t bc_dev_list_len; + u_int16_t bc_level; +}; + +/* kernel and userspace defines */ +#define BIOC_INQ 0x0001 +#define BIOC_DISK 0x0002 +#define BIOC_VOL 0x0004 +#define BIOC_ALARM 0x0008 +#define BIOC_BLINK 0x0010 +#define BIOC_SETSTATE 0x0020 +#define BIOC_CREATERAID 0x0040 + +/* user space defines */ +#define BIOC_DEVLIST 0x10000 diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c index 647f73505a53..7d6875c83a78 100644 --- a/sys/dev/ic/mfi.c +++ b/sys/dev/ic/mfi.c @@ -1,4 +1,4 @@ -/* $NetBSD: mfi.c,v 1.3 2007/03/04 06:01:58 christos Exp $ */ +/* $NetBSD: mfi.c,v 1.4 2007/05/01 17:18:55 bouyer Exp $ */ /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */ /* * Copyright (c) 2006 Marco Peereboom @@ -17,9 +17,9 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.3 2007/03/04 06:01:58 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.4 2007/05/01 17:18:55 bouyer Exp $"); -/* #include "bio.h" XXX */ +#include "bio.h" #include #include @@ -46,7 +46,6 @@ __KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.3 2007/03/04 06:01:58 christos Exp $"); #if NBIO > 0 #include -#include #endif /* NBIO > 0 */ #ifdef MFI_DEBUG @@ -103,7 +102,10 @@ int mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *); int mfi_ioctl_setstate(struct mfi_softc *, struct bioc_setstate *); int mfi_bio_hs(struct mfi_softc *, int, int, void *); int mfi_create_sensors(struct mfi_softc *); -void mfi_refresh_sensors(void *); +int mfi_sensor_gtredata(struct sysmon_envsys *, + struct envsys_tre_data *); +int mfi_sensor_streinfo(struct sysmon_envsys *, + struct envsys_basic_info *); #endif /* NBIO > 0 */ struct mfi_ccb * @@ -190,11 +192,11 @@ mfi_init_ccb(struct mfi_softc *sc) } DNPRINTF(MFI_D_CCB, - "ccb(%d): %p frame: %#x (%#x) sense: %#x (%#x) map: %#x\n", + "ccb(%d): %p frame: %#lx (%#lx) sense: %#lx (%#lx) map: %#lx\n", ccb->ccb_frame->mfr_header.mfh_context, ccb, - ccb->ccb_frame, ccb->ccb_pframe, - ccb->ccb_sense, ccb->ccb_psense, - ccb->ccb_dmamap); + (u_long)ccb->ccb_frame, (u_long)ccb->ccb_pframe, + (u_long)ccb->ccb_sense, (u_long)ccb->ccb_psense, + (u_long)ccb->ccb_dmamap); /* add ccb to queue */ mfi_put_ccb(ccb); @@ -223,14 +225,14 @@ mfi_read(struct mfi_softc *sc, bus_size_t r) BUS_SPACE_BARRIER_READ); rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); - DNPRINTF(MFI_D_RW, "%s: mr 0x%x 0x08%x ", DEVNAME(sc), r, rv); + DNPRINTF(MFI_D_RW, "%s: mr 0x%lx 0x08%x ", DEVNAME(sc), (u_long)r, rv); return (rv); } void mfi_write(struct mfi_softc *sc, bus_size_t r, uint32_t v) { - DNPRINTF(MFI_D_RW, "%s: mw 0x%x 0x%08x", DEVNAME(sc), r, v); + DNPRINTF(MFI_D_RW, "%s: mw 0x%lx 0x%08x", DEVNAME(sc), (u_long)r, v); bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, @@ -243,8 +245,8 @@ mfi_allocmem(struct mfi_softc *sc, size_t size) struct mfi_mem *mm; int nsegs; - DNPRINTF(MFI_D_MEM, "%s: mfi_allocmem: %d\n", DEVNAME(sc), - size); + DNPRINTF(MFI_D_MEM, "%s: mfi_allocmem: %ld\n", DEVNAME(sc), + (long)size); mm = malloc(sizeof(struct mfi_mem), M_DEVBUF, M_NOWAIT); if (mm == NULL) @@ -270,7 +272,7 @@ mfi_allocmem(struct mfi_softc *sc, size_t size) goto unmap; DNPRINTF(MFI_D_MEM, " kva: %p dva: %p map: %p\n", - mm->am_kva, mm->am_map->dm_segs[0].ds_addr, mm->am_map); + mm->am_kva, (void *)mm->am_map->dm_segs[0].ds_addr, mm->am_map); memset(mm->am_kva, 0, size); return (mm); @@ -544,7 +546,7 @@ mfi_get_info(struct mfi_softc *sc) sc->sc_info.mci_host.mih_port_count); for (i = 0; i < 8; i++) - printf("%.0llx ", sc->sc_info.mci_host.mih_port_addr[i]); + printf("%.0lx ", sc->sc_info.mci_host.mih_port_addr[i]); printf("\n"); printf("%s: type %.x port_count %d port_addr ", @@ -553,7 +555,7 @@ mfi_get_info(struct mfi_softc *sc) sc->sc_info.mci_device.mid_port_count); for (i = 0; i < 8; i++) - printf("%.0llx ", sc->sc_info.mci_device.mid_port_addr[i]); + printf("%.0lx ", sc->sc_info.mci_device.mid_port_addr[i]); printf("\n"); #endif /* MFI_DEBUG */ @@ -586,8 +588,6 @@ mfi_attach(struct mfi_softc *sc) TAILQ_INIT(&sc->sc_ccb_freeq); - /* rw_init(&sc->sc_lock, "mfi_lock"); XXX */ - status = mfi_read(sc, MFI_OMSG0); sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK; sc->sc_max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; @@ -693,7 +693,6 @@ mfi_attach(struct mfi_softc *sc) panic("%s: controller registration failed", DEVNAME(sc)); else sc->sc_ioctl = mfi_ioctl; - if (mfi_create_sensors(sc) != 0) aprint_error("%s: unable to create sensors\n", DEVNAME(sc)); #endif /* NBIO > 0 */ @@ -794,9 +793,11 @@ mfi_intr(void *arg) /* write status back to acknowledge interrupt */ mfi_write(sc, MFI_OSTS, status); - DNPRINTF(MFI_D_INTR, "%s: mfi_intr %#x %#x\n", DEVNAME(sc), sc, pcq); - pcq = MFIMEM_KVA(sc->sc_pcq); + + DNPRINTF(MFI_D_INTR, "%s: mfi_intr %#lx %#lx\n", DEVNAME(sc), + (u_long)sc, (u_long)pcq); + bus_dmamap_sync(sc->sc_dmat, MFIMEM_MAP(sc->sc_pcq), 0, sizeof(uint32_t) * sc->sc_max_cmds + sizeof(struct mfi_prod_cons), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -892,8 +893,8 @@ mfi_scsi_xs_done(struct mfi_ccb *ccb) struct mfi_softc *sc = ccb->ccb_sc; struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; - DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done %#x %#x\n", - DEVNAME(sc), ccb, ccb->ccb_frame); + DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done %#lx %#lx\n", + DEVNAME(sc), (u_long)ccb, (u_long)ccb->ccb_frame); if (xs->data != NULL) { DNPRINTF(MFI_D_INTR, "%s: mfi_scsi_xs_done sync\n", @@ -916,9 +917,9 @@ mfi_scsi_xs_done(struct mfi_ccb *ccb) ccb->ccb_psense - MFIMEM_DVA(sc->sc_sense), MFI_SENSE_SIZE, BUS_DMASYNC_POSTREAD); DNPRINTF(MFI_D_INTR, - "%s: mfi_scsi_xs_done sense %#x %x %x\n", + "%s: mfi_scsi_xs_done sense %#x %lx %lx\n", DEVNAME(sc), hdr->mfh_scsi_status, - &xs->sense, ccb->ccb_sense); + (u_long)&xs->sense, (u_long)ccb->ccb_sense); memset(&xs->sense, 0, sizeof(xs->sense)); memcpy(&xs->sense, ccb->ccb_sense, sizeof(struct scsi_sense_data)); @@ -998,9 +999,6 @@ mfi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, uint8_t mbox[MFI_MBOX_SIZE]; int s; - DNPRINTF(MFI_D_CMD, "%s: mfi_scsipi_request req %d opcode: %#x\n", - DEVNAME(sc), req, xs->cmd->opcode); - switch (req) { case ADAPTER_REQ_GROW_RESOURCES: /* Not supported. */ @@ -1013,6 +1011,10 @@ mfi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, } xs = arg; + + DNPRINTF(MFI_D_CMD, "%s: mfi_scsipi_request req %d opcode: %#x\n", + DEVNAME(sc), req, xs->cmd->opcode); + periph = xs->xs_periph; target = periph->periph_target; @@ -1142,8 +1144,8 @@ mfi_create_sgl(struct mfi_ccb *ccb, int flags) union mfi_sgl *sgl; int error, i; - DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %#x\n", DEVNAME(sc), - ccb->ccb_data); + DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %#lx\n", DEVNAME(sc), + (u_long)ccb->ccb_data); if (!ccb->ccb_data) return (1); @@ -1263,8 +1265,8 @@ mfi_mgmt_done(struct mfi_ccb *ccb) struct mfi_softc *sc = ccb->ccb_sc; struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; - DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done %#x %#x\n", - DEVNAME(sc), ccb, ccb->ccb_frame); + DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done %#lx %#lx\n", + DEVNAME(sc), (u_long)ccb, (u_long)ccb->ccb_frame); if (ccb->ccb_data != NULL) { DNPRINTF(MFI_D_INTR, "%s: mfi_mgmt_done sync\n", @@ -1300,10 +1302,9 @@ mfi_ioctl(struct device *dev, u_long cmd, void *addr) struct mfi_softc *sc = (struct mfi_softc *)dev; int error = 0; + int s = splbio(); DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl ", DEVNAME(sc)); - rw_enter_write(&sc->sc_lock); - switch (cmd) { case BIOCINQ: DNPRINTF(MFI_D_IOCTL, "inq\n"); @@ -1339,9 +1340,8 @@ mfi_ioctl(struct device *dev, u_long cmd, void *addr) DNPRINTF(MFI_D_IOCTL, " invalid ioctl\n"); error = EINVAL; } - - rw_exit_write(&sc->sc_lock); - + splx(s); + DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl return %x\n", DEVNAME(sc), error); return (error); } @@ -1458,6 +1458,8 @@ mfi_ioctl_vol(struct mfi_softc *sc, struct bioc_vol *bv) rv = 0; done: + DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_vol done %x\n", + DEVNAME(sc), rv); return (rv); } @@ -1468,7 +1470,7 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) struct mfi_array *ar; struct mfi_ld_cfg *ld; struct mfi_pd_details *pd; - struct scsi_inquiry_data *inqbuf; + struct scsipi_inquiry_data *inqbuf; char vend[8+16+4+1]; int i, rv = EINVAL; int arr, vol, disk; @@ -1478,7 +1480,7 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_disk %#x\n", DEVNAME(sc), bd->bd_diskid); - pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); + pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK | M_ZERO); /* send single element command to retrieve size for full structure */ cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); @@ -1554,6 +1556,7 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) /* get the remaining fields */ *((uint16_t *)&mbox) = ar[arr].pd[disk].mar_pd.mfp_id; + memset(pd, 0, sizeof(*pd)); if (mfi_mgmt(sc, MR_DCMD_PD_GET_INFO, MFI_DATA_IN, sizeof *pd, pd, mbox)) goto freeme; @@ -1563,7 +1566,7 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) /* if pd->mpd_enc_idx is 0 then it is not in an enclosure */ bd->bd_channel = pd->mpd_enc_idx; - inqbuf = (struct scsi_inquiry_data *)&pd->mpd_inq_data; + inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; memcpy(vend, inqbuf->vendor, sizeof vend - 1); vend[sizeof vend - 1] = '\0'; strlcpy(bd->bd_vendor, vend, sizeof(bd->bd_vendor)); @@ -1761,7 +1764,7 @@ mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) struct mfi_pd_details *pd; struct bioc_disk *sdhs; struct bioc_vol *vdhs; - struct scsi_inquiry_data *inqbuf; + struct scsipi_inquiry_data *inqbuf; char vend[8+16+4+1]; int i, rv = EINVAL; uint32_t size; @@ -1772,7 +1775,7 @@ mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) if (!bio_hs) return (EINVAL); - pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK); + pd = malloc(sizeof *pd, M_DEVBUF, M_WAITOK | M_ZERO); /* send single element command to retrieve size for full structure */ cfg = malloc(sizeof *cfg, M_DEVBUF, M_WAITOK); @@ -1832,8 +1835,8 @@ mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) sdhs->bd_size = pd->mpd_size / 2; /* XXX why? / 2 */ sdhs->bd_channel = pd->mpd_enc_idx; sdhs->bd_target = pd->mpd_enc_slot; - inqbuf = (struct scsi_inquiry_data *)&pd->mpd_inq_data; - memcpy(vend, inqbuf->vendor, sizeof vend - 1); + inqbuf = (struct scsipi_inquiry_data *)&pd->mpd_inq_data; + memcpy(vend, inqbuf->vendor, sizeof(vend) - 1); vend[sizeof vend - 1] = '\0'; strlcpy(sdhs->bd_vendor, vend, sizeof(sdhs->bd_vendor)); break; @@ -1854,97 +1857,110 @@ freeme: int mfi_create_sensors(struct mfi_softc *sc) { - struct device *dev; - struct scsibus_softc *ssc; int i; + struct envsys_range env_ranges[2]; + int nsensors = sc->sc_ld_cnt; - TAILQ_FOREACH(dev, &alldevs, dv_list) { - if (dev->dv_parent != &sc->sc_dev) - continue; + env_ranges[0].low = 0; + env_ranges[0].high = nsensors; + env_ranges[0].units = ENVSYS_DRIVE; + env_ranges[1].low = 1; + env_ranges[1].high = 0; + env_ranges[1].units = 0; - /* check if this is the scsibus for the logical disks */ - ssc = (struct scsibus_softc *)dev; - if (ssc->adapter_link == &sc->sc_link) - break; + sc->sc_sensor_data = + malloc(sizeof(struct envsys_tre_data) * nsensors, + M_DEVBUF, M_NOWAIT | M_ZERO); + if (sc->sc_sensor_data == NULL) { + aprint_error("%s: can't allocate envsys_tre_data\n", + DEVNAME(sc)); + return(ENOMEM); } - - if (ssc == NULL) - return (1); - - sc->sc_sensors = malloc(sizeof(struct sensor) * sc->sc_ld_cnt, - M_DEVBUF, M_WAITOK); - if (sc->sc_sensors == NULL) - return (1); - bzero(sc->sc_sensors, sizeof(struct sensor) * sc->sc_ld_cnt); - - for (i = 0; i < sc->sc_ld_cnt; i++) { - if (ssc->sc_link[i][0] == NULL) - goto bad; - - dev = ssc->sc_link[i][0]->device_softc; - - sc->sc_sensors[i].type = SENSOR_DRIVE; - sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; - - strlcpy(sc->sc_sensors[i].device, DEVNAME(sc), - sizeof(sc->sc_sensors[i].device)); - strlcpy(sc->sc_sensors[i].desc, dev->dv_xname, - sizeof(sc->sc_sensors[i].desc)); - - sensor_add(&sc->sc_sensors[i]); + sc->sc_sensor_info = + malloc(sizeof(struct envsys_basic_info) * nsensors, + M_DEVBUF, M_NOWAIT | M_ZERO); + if (sc->sc_sensor_info == NULL) { + aprint_error("%s: can't allocate envsys_basic_info\n", + DEVNAME(sc)); + return(ENOMEM); + } + for (i = 0; i < nsensors; i++) { + sc->sc_sensor_data[i].sensor = i; + sc->sc_sensor_data[i].units = ENVSYS_DRIVE; + sc->sc_sensor_data[i].validflags = ENVSYS_FVALID; + sc->sc_sensor_data[i].warnflags = ENVSYS_WARN_OK; + sc->sc_sensor_info[i].sensor = i; + sc->sc_sensor_info[i].units = ENVSYS_DRIVE; + sc->sc_sensor_info[i].validflags = ENVSYS_FVALID; + /* logical drives */ + snprintf(sc->sc_sensor_info[i].desc, + sizeof(sc->sc_sensor_info[i].desc), "%s:%d", + DEVNAME(sc), i); + } + sc->sc_ranges = env_ranges; + sc->sc_envsys.sme_cookie = sc; + sc->sc_envsys.sme_gtredata = mfi_sensor_gtredata; + sc->sc_envsys.sme_streinfo = mfi_sensor_streinfo; + sc->sc_envsys.sme_nsensors = sc->sc_ld_cnt; + sc->sc_envsys.sme_envsys_version = 1000; + if (sysmon_envsys_register(&sc->sc_envsys)) { + printf("%s: unable to register with sysmon\n", DEVNAME(sc)); + return(1); } - - if (sensor_task_register(sc, mfi_refresh_sensors, 10) != 0) - goto bad; - return (0); - -bad: - while (--i >= 0) - sensor_del(&sc->sc_sensors[i]); - free(sc->sc_sensors, M_DEVBUF); - - return (1); } -void -mfi_refresh_sensors(void *arg) +int +mfi_sensor_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred) { - struct mfi_softc *sc = arg; - int i; + struct mfi_softc *sc = sme->sme_cookie; struct bioc_vol bv; + int s; + if (tred->sensor >= sc->sc_ld_cnt || tred->sensor < 0) + return EINVAL; - for (i = 0; i < sc->sc_ld_cnt; i++) { - bzero(&bv, sizeof(bv)); - bv.bv_volid = i; - if (mfi_ioctl_vol(sc, &bv)) - return; - - switch(bv.bv_status) { - case BIOC_SVOFFLINE: - sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL; - sc->sc_sensors[i].status = SENSOR_S_CRIT; - break; - - case BIOC_SVDEGRADED: - sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL; - sc->sc_sensors[i].status = SENSOR_S_WARN; - break; - - case BIOC_SVSCRUB: - case BIOC_SVONLINE: - sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE; - sc->sc_sensors[i].status = SENSOR_S_OK; - break; - - case BIOC_SVINVALID: - /* FALLTRHOUGH */ - default: - sc->sc_sensors[i].value = 0; /* unknown */ - sc->sc_sensors[i].status = SENSOR_S_UNKNOWN; - } - + bzero(&bv, sizeof(bv)); + bv.bv_volid = tred->sensor; + s = splbio(); + if (mfi_ioctl_vol(sc, &bv)) { + splx(s); + return EIO; } + splx(s); + + switch(bv.bv_status) { + case BIOC_SVOFFLINE: + tred->cur.data_us = ENVSYS_DRIVE_FAIL; + tred->warnflags = ENVSYS_WARN_CRITOVER; + break; + + case BIOC_SVDEGRADED: + tred->cur.data_us = ENVSYS_DRIVE_PFAIL; + tred->warnflags = ENVSYS_WARN_OVER; + break; + + case BIOC_SVSCRUB: + case BIOC_SVONLINE: + tred->cur.data_us = ENVSYS_DRIVE_ONLINE; + tred->warnflags = ENVSYS_WARN_OK; + break; + + case BIOC_SVINVALID: + /* FALLTRHOUGH */ + default: + tred->cur.data_us = 0; /* unknown */ + tred->warnflags = ENVSYS_WARN_CRITOVER; + } + tred->validflags = ENVSYS_FVALID | ENVSYS_FCURVALID; + tred->units = ENVSYS_DRIVE; + return 0; +} + +int +mfi_sensor_streinfo(struct sysmon_envsys *sme, struct envsys_basic_info *binfo) +{ + binfo->validflags = 0; + return 0; } #endif /* NBIO > 0 */ diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h index c1506969bcba..d245e781ea2d 100644 --- a/sys/dev/ic/mfivar.h +++ b/sys/dev/ic/mfivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: mfivar.h,v 1.3 2007/03/04 06:01:58 christos Exp $ */ +/* $NetBSD: mfivar.h,v 1.4 2007/05/01 17:18:55 bouyer Exp $ */ /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom @@ -16,9 +16,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include + #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) -/* #define MFI_DEBUG */ +// #define MFI_DEBUG #ifdef MFI_DEBUG extern uint32_t mfi_debug; #define DPRINTF(x...) do { if (mfi_debug) printf(x); } while(0) @@ -142,7 +145,11 @@ struct mfi_softc { struct mfi_ccb_list sc_ccb_freeq; - struct sensor *sc_sensors; + struct sysmon_envsys sc_envsys; +#define sc_ranges sc_envsys.sme_ranges +#define sc_sensor_info sc_envsys.sme_sensor_info +#define sc_sensor_data sc_envsys.sme_sensor_data + }; int mfi_attach(struct mfi_softc *sc); diff --git a/sys/sys/envsys.h b/sys/sys/envsys.h index 3791a10266c9..b3d627b507a9 100644 --- a/sys/sys/envsys.h +++ b/sys/sys/envsys.h @@ -1,4 +1,4 @@ -/* $NetBSD: envsys.h,v 1.10 2006/03/15 11:22:23 lukem Exp $ */ +/* $NetBSD: envsys.h,v 1.11 2007/05/01 17:18:56 bouyer Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -95,16 +95,34 @@ enum envsys_units { ENVSYS_SAMPHOUR, ENVSYS_INDICATOR, /* boolean indicator */ ENVSYS_INTEGER, /* generic integer return */ + ENVSYS_DRIVE, /* disk status */ ENVSYS_NSENSORS }; +/* drive status */ +#define ENVSYS_DRIVE_EMPTY 1 +#define ENVSYS_DRIVE_READY 2 +#define ENVSYS_DRIVE_POWERUP 3 +#define ENVSYS_DRIVE_ONLINE 4 +#define ENVSYS_DRIVE_IDLE 5 +#define ENVSYS_DRIVE_ACTIVE 6 +#define ENVSYS_DRIVE_REBUILD 7 +#define ENVSYS_DRIVE_POWERDOWN 8 +#define ENVSYS_DRIVE_FAIL 9 +#define ENVSYS_DRIVE_PFAIL 10 + #ifdef ENVSYSUNITNAMES static const char * const envsysunitnames[] = { "degC", "RPM", "VAC", "V", "Ohms", "W", - "A", "Wh", "Ah", "bool", "integer", "Unk" + "A", "Wh", "Ah", "bool", "integer", "drive", "Unk" +}; +static const char * const envsysdrivestatus[] = { + "unknown", "empty", "ready", "powering up", "online", "idle", "active", + "rebuilding", "powering down", "failed", "degraded" }; #endif + /* flags for validflags */ #define ENVSYS_FVALID 0x00000001 /* sensor is valid */ #define ENVSYS_FCURVALID 0x00000002 /* cur for this sens is valid */ diff --git a/usr.sbin/envstat/envstat.c b/usr.sbin/envstat/envstat.c index 02f266c555b8..b2c5b684ca8c 100644 --- a/usr.sbin/envstat/envstat.c +++ b/usr.sbin/envstat/envstat.c @@ -1,4 +1,4 @@ -/* $NetBSD: envstat.c,v 1.23 2006/08/31 10:25:04 gson Exp $ */ +/* $NetBSD: envstat.c,v 1.24 2007/05/01 17:18:56 bouyer Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include #ifndef lint -__RCSID("$NetBSD: envstat.c,v 1.23 2006/08/31 10:25:04 gson Exp $"); +__RCSID("$NetBSD: envstat.c,v 1.24 2007/05/01 17:18:56 bouyer Exp $"); #endif #include @@ -231,6 +231,9 @@ printrow(int *cetds, envsys_tre_data_t *etds, envsys_basic_info_t *ebis, /* different units need some magic */ switch (ebis[i].units) { + case ENVSYS_DRIVE: + printf(": drive %s", + envsysdrivestatus[etds[i].cur.data_us]); case ENVSYS_INDICATOR: break; case ENVSYS_INTEGER: @@ -319,6 +322,10 @@ values(size_t width, int celsius, envsys_tre_data_t *etds, } switch(etds[i].units) { + case ENVSYS_DRIVE: + printf(" %*.*s", (int)width, (int)width, + envsysdrivestatus[etds[i].cur.data_us]); + break; case ENVSYS_INDICATOR: printf(" %*.*s", (int)width, (int)width, etds[i].cur.data_us ? "ON" : "OFF");