summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJolan Luff <jolan@cvs.openbsd.org>2006-10-31 15:23:22 +0000
committerJolan Luff <jolan@cvs.openbsd.org>2006-10-31 15:23:22 +0000
commit3448b5f8fe160f08b3a81478b57cc347464d6745 (patch)
tree3a22aef5c5f9afe3274094a9dc3b0932127a720f /sys
parenta38c805a613a20acc4b80430c9220ca678ef759f (diff)
first cut at sensors
help from & ok dlg@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/arc.c118
1 files changed, 116 insertions, 2 deletions
diff --git a/sys/dev/pci/arc.c b/sys/dev/pci/arc.c
index a30ba78c2d0..fd7a763b1f4 100644
--- a/sys/dev/pci/arc.c
+++ b/sys/dev/pci/arc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: arc.c,v 1.50 2006/09/25 22:49:28 dlg Exp $ */
+/* $OpenBSD: arc.c,v 1.51 2006/10/31 15:23:21 jolan Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -38,6 +38,7 @@
#if NBIO > 0
#include <sys/ioctl.h>
+#include <sys/sensors.h>
#include <dev/biovar.h>
#endif
@@ -372,6 +373,7 @@ struct arc_softc {
void *sc_shutdownhook;
+ int sc_disk_count;
int sc_req_count;
struct arc_dmamem *sc_requests;
@@ -382,6 +384,8 @@ struct arc_softc {
struct rwlock sc_lock;
volatile int sc_talking;
+
+ struct sensor *sc_sensors;
};
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
@@ -486,6 +490,10 @@ int arc_bio_alarm_state(struct arc_softc *,
int arc_bio_getvol(struct arc_softc *, int,
struct arc_fw_volinfo *);
+
+/* sensors */
+int arc_create_sensors(struct arc_softc *);
+void arc_refresh_sensors(void *);
#endif
int
@@ -541,6 +549,9 @@ arc_attach(struct device *parent, struct device *self, void *aux)
#if NBIO > 0
if (bio_register(self, arc_bioctl) != 0)
panic("%s: bioctl registration failed\n", DEVNAME(sc));
+
+ if (arc_create_sensors(sc) != 0)
+ printf("%s: unable to create sensors\n", DEVNAME(sc));
#endif
return;
@@ -884,6 +895,7 @@ arc_query_firmware(struct arc_softc *sc)
{
struct arc_msg_firmware_info fwinfo;
char string[81]; /* sizeof(vendor)*2+1 */
+ int i, j;
if (arc_wait_eq(sc, ARC_REG_OUTB_ADDR1, ARC_REG_OUTB_ADDR1_FIRMWARE_OK,
ARC_REG_OUTB_ADDR1_FIRMWARE_OK) != 0) {
@@ -925,7 +937,11 @@ arc_query_firmware(struct arc_softc *sc)
scsi_strvis(string, fwinfo.fw_version, sizeof(fwinfo.fw_version));
DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
- /* device map? */
+ /* iterate through the device map and get a physical disk count */
+ for (i = 0; i < 16; i++)
+ for (j = 0; j < 8; j++)
+ if (fwinfo.device_map[i] & (1 << j))
+ sc->sc_disk_count++;
if (letoh32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) {
printf("%s: unexpected request frame size (%d != %d)\n",
@@ -1525,6 +1541,104 @@ arc_wait(struct arc_softc *sc)
arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE);
splx(s);
}
+
+int
+arc_create_sensors(struct arc_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;
+ }
+
+ if (ssc == NULL)
+ return (1);
+
+ sc->sc_sensors = malloc(sizeof(struct sensor) * sc->sc_disk_count,
+ M_DEVBUF, M_WAITOK);
+ if (sc->sc_sensors == NULL)
+ return (1);
+ bzero(sc->sc_sensors, sizeof(struct sensor) * sc->sc_disk_count);
+
+ for (i = 0; i < sc->sc_disk_count; 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]);
+ }
+
+ if (sensor_task_register(sc, arc_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
+arc_refresh_sensors(void *arg)
+{
+ struct arc_softc *sc = arg;
+ struct bioc_vol bv;
+ int i;
+
+ for (i = 0; i < sc->sc_disk_count; i++) {
+ bzero(&bv, sizeof(bv));
+ bv.bv_volid = i;
+ if (arc_bio_vol(sc, &bv)) {
+ sc->sc_sensors[i].flags = SENSOR_FINVALID;
+ 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;
+ }
+
+ }
+}
#endif /* NBIO > 0 */
u_int32_t