summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2007-05-01 17:18:52 +0000
committerbouyer <bouyer@NetBSD.org>2007-05-01 17:18:52 +0000
commit982bad256fc21a5e71968cc2f7d7eee826501621 (patch)
tree8bb2ba0b15e367fd0b6480ea40e69e5a0aeee2b4 /sys/dev
parentf5ef068cda333e75f9c667bb95f027003562e929 (diff)
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.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/Makefile4
-rw-r--r--sys/dev/bio.c234
-rw-r--r--sys/dev/biovar.h191
-rw-r--r--sys/dev/ic/mfi.c258
-rw-r--r--sys/dev/ic/mfivar.h13
5 files changed, 574 insertions, 126 deletions
diff --git a/sys/dev/Makefile b/sys/dev/Makefile
index 9cb26d7159d..1975a6d6da7 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 <bsd.kinc.mk>
diff --git a/sys/dev/bio.c b/sys/dev/bio.c
new file mode 100644
index 00000000000..b5d4815edc1
--- /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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: bio.c,v 1.1 2007/05/01 17:20:11 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/event.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/kauth.h>
+
+#include <dev/biovar.h>
+
+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 00000000000..3af968fdb67
--- /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 <sys/types.h>
+
+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 647f73505a5..7d6875c83a7 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 <marco@peereboom.us>
@@ -17,9 +17,9 @@
*/
#include <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/systm.h>
@@ -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 <dev/biovar.h>
-#include <sys/sensors.h>
#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;
-
- TAILQ_FOREACH(dev, &alldevs, dv_list) {
- if (dev->dv_parent != &sc->sc_dev)
- continue;
-
- /* check if this is the scsibus for the logical disks */
- ssc = (struct scsibus_softc *)dev;
- if (ssc->adapter_link == &sc->sc_link)
- break;
+ struct envsys_range env_ranges[2];
+ int nsensors = sc->sc_ld_cnt;
+
+ 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;
+
+ 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;
+ bzero(&bv, sizeof(bv));
+ bv.bv_volid = tred->sensor;
+ s = splbio();
+ if (mfi_ioctl_vol(sc, &bv)) {
+ splx(s);
+ return EIO;
+ }
+ splx(s);
- case BIOC_SVDEGRADED:
- sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL;
- sc->sc_sensors[i].status = SENSOR_S_WARN;
- break;
+ switch(bv.bv_status) {
+ case BIOC_SVOFFLINE:
+ tred->cur.data_us = ENVSYS_DRIVE_FAIL;
+ tred->warnflags = ENVSYS_WARN_CRITOVER;
+ 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_SVDEGRADED:
+ tred->cur.data_us = ENVSYS_DRIVE_PFAIL;
+ tred->warnflags = ENVSYS_WARN_OVER;
+ break;
- case BIOC_SVINVALID:
- /* FALLTRHOUGH */
- default:
- sc->sc_sensors[i].value = 0; /* unknown */
- sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
- }
+ 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 c1506969bcb..d245e781ea2 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 <marco@peereboom.us>
@@ -16,9 +16,12 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <dev/sysmon/sysmonvar.h>
+#include <sys/envsys.h>
+
#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);