summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2013-05-01 03:44:21 +0000
committerdlg <dlg@openbsd.org>2013-05-01 03:44:21 +0000
commit2ee2f0489493905bae963025f966e8fe33fb0ad6 (patch)
treed81c6505ddb8046f00efd7604084d7cd770b6a7c /sys
parentthere's some extra bits for the bbu status that freebsd dont have. provide (diff)
downloadwireguard-openbsd-2ee2f0489493905bae963025f966e8fe33fb0ad6.tar.xz
wireguard-openbsd-2ee2f0489493905bae963025f966e8fe33fb0ad6.zip
provide a sensor for the battery backup unit (bbu) on mfi boards that
support it. now i can tell (a bit better) why io might be slow on some of my boxes.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/mfi.c64
-rw-r--r--sys/dev/ic/mfireg.h14
-rw-r--r--sys/dev/ic/mfivar.h5
3 files changed, 75 insertions, 8 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 15744960a5e..1b876682293 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.141 2013/05/01 00:47:31 dlg Exp $ */
+/* $OpenBSD: mfi.c,v 1.142 2013/05/01 03:44:21 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -120,6 +120,7 @@ int mfi_bio_hs(struct mfi_softc *, int, int, void *);
#ifndef SMALL_KERNEL
int mfi_create_sensors(struct mfi_softc *);
void mfi_refresh_sensors(void *);
+int mfi_bbu(struct mfi_softc *);
#endif /* SMALL_KERNEL */
#endif /* NBIO > 0 */
@@ -2020,6 +2021,44 @@ freeme:
}
#ifndef SMALL_KERNEL
+
+int
+mfi_bbu(struct mfi_softc *sc)
+{
+ struct mfi_bbu_status bbu;
+ u_int32_t status;
+ u_int32_t mask;
+
+ if (mfi_mgmt(sc, MR_DCMD_BBU_GET_STATUS, MFI_DATA_IN,
+ sizeof(bbu), &bbu, NULL) != 0) {
+ sc->sc_bbu->value = 0;
+ sc->sc_bbu->status = SENSOR_S_UNKNOWN;
+ return (-1);
+ }
+
+ switch (bbu.battery_type) {
+ case MFI_BBU_TYPE_IBBU:
+ mask = MFI_BBU_STATE_BAD_IBBU;
+ break;
+ case MFI_BBU_TYPE_BBU:
+ mask = MFI_BBU_STATE_BAD_BBU;
+ break;
+
+ case MFI_BBU_TYPE_NONE:
+ default:
+ sc->sc_bbu->value = 0;
+ sc->sc_bbu->status = SENSOR_S_CRIT;
+ return (0);
+ }
+
+ status = letoh32(bbu.fw_status);
+
+ sc->sc_bbu->value = (status & MFI_BBU_STATE_PACK_MISSING) ? 0 : 1;
+ sc->sc_bbu->status = (status & mask) ? SENSOR_S_CRIT : SENSOR_S_OK;
+
+ return (0);
+}
+
int
mfi_create_sensors(struct mfi_softc *sc)
{
@@ -2027,14 +2066,27 @@ mfi_create_sensors(struct mfi_softc *sc)
struct scsi_link *link;
int i;
+ strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
+ sizeof(sc->sc_sensordev.xname));
+
+ if (ISSET(letoh32(sc->sc_info.mci_hw_present), MFI_INFO_HW_BBU) &&
+ ISSET(letoh32(sc->sc_info.mci_adapter_ops ), MFI_INFO_AOPS_BBU)) {
+ sc->sc_bbu = malloc(sizeof(*sc->sc_bbu), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+
+ sc->sc_bbu->type = SENSOR_INDICATOR;
+ sc->sc_bbu->status = SENSOR_S_UNKNOWN;
+ strlcpy(sc->sc_bbu->desc, "Battery Presence",
+ sizeof(sc->sc_bbu->desc));
+
+ sensor_attach(&sc->sc_sensordev, sc->sc_bbu);
+ }
+
sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_ld_cnt,
M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->sc_sensors == NULL)
return (1);
- strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
- sizeof(sc->sc_sensordev.xname));
-
for (i = 0; i < sc->sc_ld_cnt; i++) {
link = scsi_get_link(sc->sc_scsibus, i, 0);
if (link == NULL)
@@ -2071,6 +2123,8 @@ mfi_refresh_sensors(void *arg)
int i;
struct bioc_vol bv;
+ if (sc->sc_bbu != NULL && mfi_bbu(sc) != 0)
+ return;
for (i = 0; i < sc->sc_ld_cnt; i++) {
bzero(&bv, sizeof(bv));
@@ -2100,8 +2154,8 @@ mfi_refresh_sensors(void *arg)
default:
sc->sc_sensors[i].value = 0; /* unknown */
sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
+ break;
}
-
}
}
#endif /* SMALL_KERNEL */
diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h
index 865ddb63379..0a7aeffba7b 100644
--- a/sys/dev/ic/mfireg.h
+++ b/sys/dev/ic/mfireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfireg.h,v 1.38 2013/05/01 01:56:29 dlg Exp $ */
+/* $OpenBSD: mfireg.h,v 1.39 2013/05/01 03:44:22 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -1091,6 +1091,18 @@ struct mfi_bbu_status {
"\013REPLACE_PACK" \
"\014CAPACITY_LOW" \
"\015LEARN_REQUIRED"
+#define MFI_BBU_STATE_BAD_IBBU ( \
+ MFI_BBU_STATE_PACK_MISSING | \
+ MFI_BBU_STATE_VOLTAGE_LOW | \
+ MFI_BBU_STATE_DISCHARGE_ACTIVE | \
+ MFI_BBU_STATE_LEARN_CYC_REQ | \
+ MFI_BBU_STATE_LEARN_CYC_ACTIVE | \
+ MFI_BBU_STATE_REPLACE_PACK | \
+ MFI_BBU_STATE_CAPACITY_LOW)
+#define MFI_BBU_STATE_BAD_BBU ( \
+ MFI_BBU_STATE_PACK_MISSING | \
+ MFI_BBU_STATE_REPLACE_PACK | \
+ MFI_BBU_STATE_CAPACITY_LOW)
uint8_t pad[20];
union mfi_bbu_status_detail detail;
diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h
index 53cfe33f3c1..3263fb0d396 100644
--- a/sys/dev/ic/mfivar.h
+++ b/sys/dev/ic/mfivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfivar.h,v 1.51 2013/04/30 07:19:23 dlg Exp $ */
+/* $OpenBSD: mfivar.h,v 1.52 2013/05/01 03:44:22 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -186,8 +186,9 @@ struct mfi_softc {
struct rwlock sc_lock;
/* sensors */
- struct ksensor *sc_sensors;
struct ksensordev sc_sensordev;
+ struct ksensor *sc_bbu;
+ struct ksensor *sc_sensors;
};
int mfi_attach(struct mfi_softc *sc, enum mfi_iop);