diff options
| author | bouyer <bouyer@NetBSD.org> | 2007-05-01 17:18:52 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2007-05-01 17:18:52 +0000 |
| commit | 982bad256fc21a5e71968cc2f7d7eee826501621 (patch) | |
| tree | 8bb2ba0b15e367fd0b6480ea40e69e5a0aeee2b4 /sys/dev | |
| parent | f5ef068cda333e75f9c667bb95f027003562e929 (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/Makefile | 4 | ||||
| -rw-r--r-- | sys/dev/bio.c | 234 | ||||
| -rw-r--r-- | sys/dev/biovar.h | 191 | ||||
| -rw-r--r-- | sys/dev/ic/mfi.c | 258 | ||||
| -rw-r--r-- | sys/dev/ic/mfivar.h | 13 |
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); |
