Home | History | Annotate | Line # | Download | only in dev
ipmi.c revision 1.2
      1 /*	$NetBSD: ipmi.c,v 1.2 2018/12/26 06:45:58 mlelstv Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2006 Manuel Bouyer.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  *
     26  */
     27 
     28 /*
     29  * Copyright (c) 2005 Jordan Hargrave
     30  * All rights reserved.
     31  *
     32  * Redistribution and use in source and binary forms, with or without
     33  * modification, are permitted provided that the following conditions
     34  * are met:
     35  * 1. Redistributions of source code must retain the above copyright
     36  *    notice, this list of conditions and the following disclaimer.
     37  * 2. Redistributions in binary form must reproduce the above copyright
     38  *    notice, this list of conditions and the following disclaimer in the
     39  *    documentation and/or other materials provided with the distribution.
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
     45  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  */
     53 
     54 #include <sys/cdefs.h>
     55 __KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.2 2018/12/26 06:45:58 mlelstv Exp $");
     56 
     57 #include <sys/types.h>
     58 #include <sys/param.h>
     59 #include <sys/systm.h>
     60 #include <sys/kernel.h>
     61 #include <sys/device.h>
     62 #include <sys/extent.h>
     63 #include <sys/callout.h>
     64 #include <sys/envsys.h>
     65 #include <sys/malloc.h>
     66 #include <sys/kthread.h>
     67 #include <sys/bus.h>
     68 #include <sys/intr.h>
     69 
     70 #include <dev/isa/isareg.h>
     71 #include <dev/isa/isavar.h>
     72 
     73 #include <dev/ipmivar.h>
     74 
     75 #include <uvm/uvm_extern.h>
     76 
     77 struct ipmi_sensor {
     78 	uint8_t	*i_sdr;
     79 	int		i_num;
     80 	int		i_stype;
     81 	int		i_etype;
     82 	char		i_envdesc[64];
     83 	int 		i_envtype; /* envsys compatible type */
     84 	int		i_envnum; /* envsys index */
     85 	sysmon_envsys_lim_t i_limits, i_deflims;
     86 	uint32_t	i_props, i_defprops;
     87 	SLIST_ENTRY(ipmi_sensor) i_list;
     88 	int32_t		i_prevval;	/* feed rnd source on change */
     89 };
     90 
     91 #if 0
     92 static	int ipmi_nintr;
     93 #endif
     94 static	int ipmi_dbg = 0;
     95 static	int ipmi_enabled = 0;
     96 
     97 #define SENSOR_REFRESH_RATE (hz / 2)
     98 
     99 #define IPMI_BTMSG_LEN			0
    100 #define IPMI_BTMSG_NFLN			1
    101 #define IPMI_BTMSG_SEQ			2
    102 #define IPMI_BTMSG_CMD			3
    103 #define IPMI_BTMSG_CCODE		4
    104 #define IPMI_BTMSG_DATASND		4
    105 #define IPMI_BTMSG_DATARCV		5
    106 
    107 #define IPMI_MSG_NFLN			0
    108 #define IPMI_MSG_CMD			1
    109 #define IPMI_MSG_CCODE			2
    110 #define IPMI_MSG_DATASND		2
    111 #define IPMI_MSG_DATARCV		3
    112 
    113 #define IPMI_SENSOR_TYPE_TEMP		0x0101
    114 #define IPMI_SENSOR_TYPE_VOLT		0x0102
    115 #define IPMI_SENSOR_TYPE_FAN		0x0104
    116 #define IPMI_SENSOR_TYPE_INTRUSION	0x6F05
    117 #define IPMI_SENSOR_TYPE_PWRSUPPLY	0x6F08
    118 
    119 #define IPMI_NAME_UNICODE		0x00
    120 #define IPMI_NAME_BCDPLUS		0x01
    121 #define IPMI_NAME_ASCII6BIT		0x02
    122 #define IPMI_NAME_ASCII8BIT		0x03
    123 
    124 #define IPMI_ENTITY_PWRSUPPLY		0x0A
    125 
    126 #define IPMI_SENSOR_SCANNING_ENABLED	(1L << 6)
    127 #define IPMI_SENSOR_UNAVAILABLE		(1L << 5)
    128 #define IPMI_INVALID_SENSOR_P(x) \
    129 	(((x) & (IPMI_SENSOR_SCANNING_ENABLED|IPMI_SENSOR_UNAVAILABLE)) \
    130 	!= IPMI_SENSOR_SCANNING_ENABLED)
    131 
    132 #define IPMI_SDR_TYPEFULL		1
    133 #define IPMI_SDR_TYPECOMPACT		2
    134 
    135 #define byteof(x) ((x) >> 3)
    136 #define bitof(x)  (1L << ((x) & 0x7))
    137 #define TB(b,m)	  (data[2+byteof(b)] & bitof(b))
    138 
    139 #define dbg_printf(lvl, fmt...) \
    140 	if (ipmi_dbg >= lvl) \
    141 		printf(fmt);
    142 #define dbg_dump(lvl, msg, len, buf) \
    143 	if (len && ipmi_dbg >= lvl) \
    144 		dumpb(msg, len, (const uint8_t *)(buf));
    145 
    146 static	long signextend(unsigned long, int);
    147 
    148 SLIST_HEAD(ipmi_sensors_head, ipmi_sensor);
    149 static struct ipmi_sensors_head ipmi_sensor_list =
    150     SLIST_HEAD_INITIALIZER(&ipmi_sensor_list);
    151 
    152 static	void dumpb(const char *, int, const uint8_t *);
    153 
    154 static	int read_sensor(struct ipmi_softc *, struct ipmi_sensor *);
    155 static	int add_sdr_sensor(struct ipmi_softc *, uint8_t *);
    156 static	int get_sdr_partial(struct ipmi_softc *, uint16_t, uint16_t,
    157 	    uint8_t, uint8_t, void *, uint16_t *);
    158 static	int get_sdr(struct ipmi_softc *, uint16_t, uint16_t *);
    159 
    160 static	char *ipmi_buf_acquire(struct ipmi_softc *, size_t);
    161 static	void ipmi_buf_release(struct ipmi_softc *, char *);
    162 static	int ipmi_sendcmd(struct ipmi_softc *, int, int, int, int, int, const void*);
    163 static	int ipmi_recvcmd(struct ipmi_softc *, int, int *, void *);
    164 static	void ipmi_delay(struct ipmi_softc *, int);
    165 
    166 static	int ipmi_watchdog_setmode(struct sysmon_wdog *);
    167 static	int ipmi_watchdog_tickle(struct sysmon_wdog *);
    168 static	void ipmi_dotickle(struct ipmi_softc *);
    169 
    170 #if 0
    171 static	int ipmi_intr(void *);
    172 #endif
    173 
    174 static	int ipmi_match(device_t, cfdata_t, void *);
    175 static	void ipmi_attach(device_t, device_t, void *);
    176 static	int ipmi_detach(device_t, int);
    177 
    178 static	long	ipmi_convert(uint8_t, struct sdrtype1 *, long);
    179 static	void	ipmi_sensor_name(char *, int, uint8_t, uint8_t *);
    180 
    181 /* BMC Helper Functions */
    182 static	uint8_t bmc_read(struct ipmi_softc *, int);
    183 static	void bmc_write(struct ipmi_softc *, int, uint8_t);
    184 static	int bmc_io_wait(struct ipmi_softc *, int, uint8_t, uint8_t, const char *);
    185 static	int bmc_io_wait_spin(struct ipmi_softc *, int, uint8_t, uint8_t);
    186 static	int bmc_io_wait_sleep(struct ipmi_softc *, int, uint8_t, uint8_t);
    187 
    188 static	void *bt_buildmsg(struct ipmi_softc *, int, int, int, const void *, int *);
    189 static	void *cmn_buildmsg(struct ipmi_softc *, int, int, int, const void *, int *);
    190 
    191 static	int getbits(uint8_t *, int, int);
    192 static	int ipmi_sensor_type(int, int, int);
    193 
    194 static	void ipmi_refresh_sensors(struct ipmi_softc *);
    195 static	int ipmi_map_regs(struct ipmi_softc *, struct ipmi_attach_args *);
    196 static	void ipmi_unmap_regs(struct ipmi_softc *);
    197 
    198 static	int32_t ipmi_convert_sensor(uint8_t *, struct ipmi_sensor *);
    199 static	void ipmi_set_limits(struct sysmon_envsys *, envsys_data_t *,
    200 		sysmon_envsys_lim_t *, uint32_t *);
    201 static	void ipmi_get_limits(struct sysmon_envsys *, envsys_data_t *,
    202 		sysmon_envsys_lim_t *, uint32_t *);
    203 static	void ipmi_get_sensor_limits(struct ipmi_softc *, struct ipmi_sensor *,
    204 		sysmon_envsys_lim_t *, uint32_t *);
    205 static	int ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *,
    206 		envsys_data_t *, uint8_t *);
    207 
    208 static	int add_child_sensors(struct ipmi_softc *, uint8_t *, int, int, int,
    209 		int, int, int, const char *);
    210 
    211 static	bool ipmi_suspend(device_t, const pmf_qual_t *);
    212 
    213 static	int kcs_probe(struct ipmi_softc *);
    214 static	int kcs_reset(struct ipmi_softc *);
    215 static	int kcs_sendmsg(struct ipmi_softc *, int, const uint8_t *);
    216 static	int kcs_recvmsg(struct ipmi_softc *, int, int *len, uint8_t *);
    217 
    218 static	int bt_probe(struct ipmi_softc *);
    219 static	int bt_reset(struct ipmi_softc *);
    220 static	int bt_sendmsg(struct ipmi_softc *, int, const uint8_t *);
    221 static	int bt_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);
    222 
    223 static	int smic_probe(struct ipmi_softc *);
    224 static	int smic_reset(struct ipmi_softc *);
    225 static	int smic_sendmsg(struct ipmi_softc *, int, const uint8_t *);
    226 static	int smic_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);
    227 
    228 static struct ipmi_if kcs_if = {
    229 	"KCS",
    230 	IPMI_IF_KCS_NREGS,
    231 	cmn_buildmsg,
    232 	kcs_sendmsg,
    233 	kcs_recvmsg,
    234 	kcs_reset,
    235 	kcs_probe,
    236 };
    237 
    238 static struct ipmi_if smic_if = {
    239 	"SMIC",
    240 	IPMI_IF_SMIC_NREGS,
    241 	cmn_buildmsg,
    242 	smic_sendmsg,
    243 	smic_recvmsg,
    244 	smic_reset,
    245 	smic_probe,
    246 };
    247 
    248 static struct ipmi_if bt_if = {
    249 	"BT",
    250 	IPMI_IF_BT_NREGS,
    251 	bt_buildmsg,
    252 	bt_sendmsg,
    253 	bt_recvmsg,
    254 	bt_reset,
    255 	bt_probe,
    256 };
    257 
    258 static	struct ipmi_if *ipmi_get_if(int);
    259 
    260 static struct ipmi_if *
    261 ipmi_get_if(int iftype)
    262 {
    263 	switch (iftype) {
    264 	case IPMI_IF_KCS:
    265 		return &kcs_if;
    266 	case IPMI_IF_SMIC:
    267 		return &smic_if;
    268 	case IPMI_IF_BT:
    269 		return &bt_if;
    270 	default:
    271 		return NULL;
    272 	}
    273 }
    274 
    275 /*
    276  * BMC Helper Functions
    277  */
    278 static uint8_t
    279 bmc_read(struct ipmi_softc *sc, int offset)
    280 {
    281 	return bus_space_read_1(sc->sc_iot, sc->sc_ioh,
    282 	    offset * sc->sc_if_iospacing);
    283 }
    284 
    285 static void
    286 bmc_write(struct ipmi_softc *sc, int offset, uint8_t val)
    287 {
    288 	bus_space_write_1(sc->sc_iot, sc->sc_ioh,
    289 	    offset * sc->sc_if_iospacing, val);
    290 }
    291 
    292 static int
    293 bmc_io_wait_sleep(struct ipmi_softc *sc, int offset, uint8_t mask,
    294     uint8_t value)
    295 {
    296 	int retries;
    297 	uint8_t v;
    298 
    299 	KASSERT(mutex_owned(&sc->sc_cmd_mtx));
    300 
    301 	for (retries = 0; retries < sc->sc_max_retries; retries++) {
    302 		v = bmc_read(sc, offset);
    303 		if ((v & mask) == value)
    304 			return v;
    305 		mutex_enter(&sc->sc_sleep_mtx);
    306 		cv_timedwait(&sc->sc_cmd_sleep, &sc->sc_sleep_mtx, 1);
    307 		mutex_exit(&sc->sc_sleep_mtx);
    308 	}
    309 	return -1;
    310 }
    311 
    312 static int
    313 bmc_io_wait(struct ipmi_softc *sc, int offset, uint8_t mask, uint8_t value,
    314     const char *lbl)
    315 {
    316 	int v;
    317 
    318 	v = bmc_io_wait_spin(sc, offset, mask, value);
    319 	if (cold || v != -1)
    320 		return v;
    321 
    322 	return bmc_io_wait_sleep(sc, offset, mask, value);
    323 }
    324 
    325 static int
    326 bmc_io_wait_spin(struct ipmi_softc *sc, int offset, uint8_t mask,
    327     uint8_t value)
    328 {
    329 	uint8_t	v;
    330 	int			count = cold ? 15000 : 500;
    331 	/* ~us */
    332 
    333 	while (count--) {
    334 		v = bmc_read(sc, offset);
    335 		if ((v & mask) == value)
    336 			return v;
    337 
    338 		delay(1);
    339 	}
    340 
    341 	return -1;
    342 
    343 }
    344 
    345 #define NETFN_LUN(nf,ln) (((nf) << 2) | ((ln) & 0x3))
    346 
    347 /*
    348  * BT interface
    349  */
    350 #define _BT_CTRL_REG			0
    351 #define	  BT_CLR_WR_PTR			(1L << 0)
    352 #define	  BT_CLR_RD_PTR			(1L << 1)
    353 #define	  BT_HOST2BMC_ATN		(1L << 2)
    354 #define	  BT_BMC2HOST_ATN		(1L << 3)
    355 #define	  BT_EVT_ATN			(1L << 4)
    356 #define	  BT_HOST_BUSY			(1L << 6)
    357 #define	  BT_BMC_BUSY			(1L << 7)
    358 
    359 #define	  BT_READY	(BT_HOST_BUSY|BT_HOST2BMC_ATN|BT_BMC2HOST_ATN)
    360 
    361 #define _BT_DATAIN_REG			1
    362 #define _BT_DATAOUT_REG			1
    363 
    364 #define _BT_INTMASK_REG			2
    365 #define	 BT_IM_HIRQ_PEND		(1L << 1)
    366 #define	 BT_IM_SCI_EN			(1L << 2)
    367 #define	 BT_IM_SMI_EN			(1L << 3)
    368 #define	 BT_IM_NMI2SMI			(1L << 4)
    369 
    370 static int bt_read(struct ipmi_softc *, int);
    371 static int bt_write(struct ipmi_softc *, int, uint8_t);
    372 
    373 static int
    374 bt_read(struct ipmi_softc *sc, int reg)
    375 {
    376 	return bmc_read(sc, reg);
    377 }
    378 
    379 static int
    380 bt_write(struct ipmi_softc *sc, int reg, uint8_t data)
    381 {
    382 	if (bmc_io_wait(sc, _BT_CTRL_REG, BT_BMC_BUSY, 0, __func__) < 0)
    383 		return -1;
    384 
    385 	bmc_write(sc, reg, data);
    386 	return 0;
    387 }
    388 
    389 static int
    390 bt_sendmsg(struct ipmi_softc *sc, int len, const uint8_t *data)
    391 {
    392 	int i;
    393 
    394 	bt_write(sc, _BT_CTRL_REG, BT_CLR_WR_PTR);
    395 	for (i = 0; i < len; i++)
    396 		bt_write(sc, _BT_DATAOUT_REG, data[i]);
    397 
    398 	bt_write(sc, _BT_CTRL_REG, BT_HOST2BMC_ATN);
    399 	if (bmc_io_wait(sc, _BT_CTRL_REG, BT_HOST2BMC_ATN | BT_BMC_BUSY, 0,
    400 	    __func__) < 0)
    401 		return -1;
    402 
    403 	return 0;
    404 }
    405 
    406 static int
    407 bt_recvmsg(struct ipmi_softc *sc, int maxlen, int *rxlen, uint8_t *data)
    408 {
    409 	uint8_t len, v, i;
    410 
    411 	if (bmc_io_wait(sc, _BT_CTRL_REG, BT_BMC2HOST_ATN, BT_BMC2HOST_ATN,
    412 	    __func__) < 0)
    413 		return -1;
    414 
    415 	bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
    416 	bt_write(sc, _BT_CTRL_REG, BT_BMC2HOST_ATN);
    417 	bt_write(sc, _BT_CTRL_REG, BT_CLR_RD_PTR);
    418 	len = bt_read(sc, _BT_DATAIN_REG);
    419 	for (i = IPMI_BTMSG_NFLN; i <= len; i++) {
    420 		v = bt_read(sc, _BT_DATAIN_REG);
    421 		if (i != IPMI_BTMSG_SEQ)
    422 			*(data++) = v;
    423 	}
    424 	bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
    425 	*rxlen = len - 1;
    426 
    427 	return 0;
    428 }
    429 
    430 static int
    431 bt_reset(struct ipmi_softc *sc)
    432 {
    433 	return -1;
    434 }
    435 
    436 static int
    437 bt_probe(struct ipmi_softc *sc)
    438 {
    439 	uint8_t rv;
    440 
    441 	rv = bmc_read(sc, _BT_CTRL_REG);
    442 	rv &= BT_HOST_BUSY;
    443 	rv |= BT_CLR_WR_PTR|BT_CLR_RD_PTR|BT_BMC2HOST_ATN|BT_HOST2BMC_ATN;
    444 	bmc_write(sc, _BT_CTRL_REG, rv);
    445 
    446 	rv = bmc_read(sc, _BT_INTMASK_REG);
    447 	rv &= BT_IM_SCI_EN|BT_IM_SMI_EN|BT_IM_NMI2SMI;
    448 	rv |= BT_IM_HIRQ_PEND;
    449 	bmc_write(sc, _BT_INTMASK_REG, rv);
    450 
    451 #if 0
    452 	printf("%s: %2x\n", __func__, v);
    453 	printf(" WR    : %2x\n", v & BT_CLR_WR_PTR);
    454 	printf(" RD    : %2x\n", v & BT_CLR_RD_PTR);
    455 	printf(" H2B   : %2x\n", v & BT_HOST2BMC_ATN);
    456 	printf(" B2H   : %2x\n", v & BT_BMC2HOST_ATN);
    457 	printf(" EVT   : %2x\n", v & BT_EVT_ATN);
    458 	printf(" HBSY  : %2x\n", v & BT_HOST_BUSY);
    459 	printf(" BBSY  : %2x\n", v & BT_BMC_BUSY);
    460 #endif
    461 	return 0;
    462 }
    463 
    464 /*
    465  * SMIC interface
    466  */
    467 #define _SMIC_DATAIN_REG		0
    468 #define _SMIC_DATAOUT_REG		0
    469 
    470 #define _SMIC_CTRL_REG			1
    471 #define	  SMS_CC_GET_STATUS		 0x40
    472 #define	  SMS_CC_START_TRANSFER		 0x41
    473 #define	  SMS_CC_NEXT_TRANSFER		 0x42
    474 #define	  SMS_CC_END_TRANSFER		 0x43
    475 #define	  SMS_CC_START_RECEIVE		 0x44
    476 #define	  SMS_CC_NEXT_RECEIVE		 0x45
    477 #define	  SMS_CC_END_RECEIVE		 0x46
    478 #define	  SMS_CC_TRANSFER_ABORT		 0x47
    479 
    480 #define	  SMS_SC_READY			 0xc0
    481 #define	  SMS_SC_WRITE_START		 0xc1
    482 #define	  SMS_SC_WRITE_NEXT		 0xc2
    483 #define	  SMS_SC_WRITE_END		 0xc3
    484 #define	  SMS_SC_READ_START		 0xc4
    485 #define	  SMS_SC_READ_NEXT		 0xc5
    486 #define	  SMS_SC_READ_END		 0xc6
    487 
    488 #define _SMIC_FLAG_REG			2
    489 #define	  SMIC_BUSY			(1L << 0)
    490 #define	  SMIC_SMS_ATN			(1L << 2)
    491 #define	  SMIC_EVT_ATN			(1L << 3)
    492 #define	  SMIC_SMI			(1L << 4)
    493 #define	  SMIC_TX_DATA_RDY		(1L << 6)
    494 #define	  SMIC_RX_DATA_RDY		(1L << 7)
    495 
    496 static int smic_wait(struct ipmi_softc *, uint8_t, uint8_t, const char *);
    497 static int smic_write_cmd_data(struct ipmi_softc *, uint8_t, const uint8_t *);
    498 static int smic_read_data(struct ipmi_softc *, uint8_t *);
    499 
    500 static int
    501 smic_wait(struct ipmi_softc *sc, uint8_t mask, uint8_t val, const char *lbl)
    502 {
    503 	int v;
    504 
    505 	/* Wait for expected flag bits */
    506 	v = bmc_io_wait(sc, _SMIC_FLAG_REG, mask, val, __func__);
    507 	if (v < 0)
    508 		return -1;
    509 
    510 	/* Return current status */
    511 	v = bmc_read(sc, _SMIC_CTRL_REG);
    512 	dbg_printf(99, "%s(%s) = %#.2x\n", __func__, lbl, v);
    513 	return v;
    514 }
    515 
    516 static int
    517 smic_write_cmd_data(struct ipmi_softc *sc, uint8_t cmd, const uint8_t *data)
    518 {
    519 	int	sts, v;
    520 
    521 	dbg_printf(50, "%s: %#.2x %#.2x\n", __func__, cmd, data ? *data : -1);
    522 	sts = smic_wait(sc, SMIC_TX_DATA_RDY | SMIC_BUSY, SMIC_TX_DATA_RDY,
    523 	    "smic_write_cmd_data ready");
    524 	if (sts < 0)
    525 		return sts;
    526 
    527 	bmc_write(sc, _SMIC_CTRL_REG, cmd);
    528 	if (data)
    529 		bmc_write(sc, _SMIC_DATAOUT_REG, *data);
    530 
    531 	/* Toggle BUSY bit, then wait for busy bit to clear */
    532 	v = bmc_read(sc, _SMIC_FLAG_REG);
    533 	bmc_write(sc, _SMIC_FLAG_REG, v | SMIC_BUSY);
    534 
    535 	return smic_wait(sc, SMIC_BUSY, 0, __func__);
    536 }
    537 
    538 static int
    539 smic_read_data(struct ipmi_softc *sc, uint8_t *data)
    540 {
    541 	int sts;
    542 
    543 	sts = smic_wait(sc, SMIC_RX_DATA_RDY | SMIC_BUSY, SMIC_RX_DATA_RDY,
    544 	    __func__);
    545 	if (sts >= 0) {
    546 		*data = bmc_read(sc, _SMIC_DATAIN_REG);
    547 		dbg_printf(50, "%s: %#.2x\n", __func__, *data);
    548 	}
    549 	return sts;
    550 }
    551 
    552 #define ErrStat(a, ...) if (a) printf(__VA_ARGS__);
    553 
    554 static int
    555 smic_sendmsg(struct ipmi_softc *sc, int len, const uint8_t *data)
    556 {
    557 	int sts, idx;
    558 
    559 	sts = smic_write_cmd_data(sc, SMS_CC_START_TRANSFER, &data[0]);
    560 	ErrStat(sts != SMS_SC_WRITE_START, "%s: wstart", __func__);
    561 	for (idx = 1; idx < len - 1; idx++) {
    562 		sts = smic_write_cmd_data(sc, SMS_CC_NEXT_TRANSFER,
    563 		    &data[idx]);
    564 		ErrStat(sts != SMS_SC_WRITE_NEXT, "%s: write", __func__);
    565 	}
    566 	sts = smic_write_cmd_data(sc, SMS_CC_END_TRANSFER, &data[idx]);
    567 	if (sts != SMS_SC_WRITE_END) {
    568 		dbg_printf(50, "%s: %d/%d = %#.2x\n", __func__, idx, len, sts);
    569 		return -1;
    570 	}
    571 
    572 	return 0;
    573 }
    574 
    575 static int
    576 smic_recvmsg(struct ipmi_softc *sc, int maxlen, int *len, uint8_t *data)
    577 {
    578 	int sts, idx;
    579 
    580 	*len = 0;
    581 	sts = smic_wait(sc, SMIC_RX_DATA_RDY, SMIC_RX_DATA_RDY, __func__);
    582 	if (sts < 0)
    583 		return -1;
    584 
    585 	sts = smic_write_cmd_data(sc, SMS_CC_START_RECEIVE, NULL);
    586 	ErrStat(sts != SMS_SC_READ_START, "%s: rstart", __func__);
    587 	for (idx = 0;; ) {
    588 		sts = smic_read_data(sc, &data[idx++]);
    589 		if (sts != SMS_SC_READ_START && sts != SMS_SC_READ_NEXT)
    590 			break;
    591 		smic_write_cmd_data(sc, SMS_CC_NEXT_RECEIVE, NULL);
    592 	}
    593 	ErrStat(sts != SMS_SC_READ_END, "%s: rend", __func__);
    594 
    595 	*len = idx;
    596 
    597 	sts = smic_write_cmd_data(sc, SMS_CC_END_RECEIVE, NULL);
    598 	if (sts != SMS_SC_READY) {
    599 		dbg_printf(50, "%s: %d/%d = %#.2x\n",
    600 		    __func__, idx, maxlen, sts);
    601 		return -1;
    602 	}
    603 
    604 	return 0;
    605 }
    606 
    607 static int
    608 smic_reset(struct ipmi_softc *sc)
    609 {
    610 	return -1;
    611 }
    612 
    613 static int
    614 smic_probe(struct ipmi_softc *sc)
    615 {
    616 	/* Flag register should not be 0xFF on a good system */
    617 	if (bmc_read(sc, _SMIC_FLAG_REG) == 0xFF)
    618 		return -1;
    619 
    620 	return 0;
    621 }
    622 
    623 /*
    624  * KCS interface
    625  */
    626 #define _KCS_DATAIN_REGISTER		0
    627 #define _KCS_DATAOUT_REGISTER		0
    628 #define	  KCS_READ_NEXT			0x68
    629 
    630 #define _KCS_COMMAND_REGISTER		1
    631 #define	  KCS_GET_STATUS		0x60
    632 #define	  KCS_WRITE_START		0x61
    633 #define	  KCS_WRITE_END			0x62
    634 
    635 #define _KCS_STATUS_REGISTER		1
    636 #define	  KCS_OBF			(1L << 0)
    637 #define	  KCS_IBF			(1L << 1)
    638 #define	  KCS_SMS_ATN			(1L << 2)
    639 #define	  KCS_CD			(1L << 3)
    640 #define	  KCS_OEM1			(1L << 4)
    641 #define	  KCS_OEM2			(1L << 5)
    642 #define	  KCS_STATE_MASK		0xc0
    643 #define	    KCS_IDLE_STATE		0x00
    644 #define	    KCS_READ_STATE		0x40
    645 #define	    KCS_WRITE_STATE		0x80
    646 #define	    KCS_ERROR_STATE		0xC0
    647 
    648 static int kcs_wait(struct ipmi_softc *, uint8_t, uint8_t, const char *);
    649 static int kcs_write_cmd(struct ipmi_softc *, uint8_t);
    650 static int kcs_write_data(struct ipmi_softc *, uint8_t);
    651 static int kcs_read_data(struct ipmi_softc *, uint8_t *);
    652 
    653 static int
    654 kcs_wait(struct ipmi_softc *sc, uint8_t mask, uint8_t value, const char *lbl)
    655 {
    656 	int v;
    657 
    658 	v = bmc_io_wait(sc, _KCS_STATUS_REGISTER, mask, value, lbl);
    659 	if (v < 0)
    660 		return v;
    661 
    662 	/* Check if output buffer full, read dummy byte	 */
    663 	if ((v & (KCS_OBF | KCS_STATE_MASK)) == (KCS_OBF | KCS_WRITE_STATE))
    664 		bmc_read(sc, _KCS_DATAIN_REGISTER);
    665 
    666 	/* Check for error state */
    667 	if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE) {
    668 		bmc_write(sc, _KCS_COMMAND_REGISTER, KCS_GET_STATUS);
    669 		while (bmc_read(sc, _KCS_STATUS_REGISTER) & KCS_IBF)
    670 			;
    671 		aprint_error_dev(sc->sc_dev, "error code: %#x\n",
    672 		    bmc_read(sc, _KCS_DATAIN_REGISTER));
    673 	}
    674 
    675 	return v & KCS_STATE_MASK;
    676 }
    677 
    678 static int
    679 kcs_write_cmd(struct ipmi_softc *sc, uint8_t cmd)
    680 {
    681 	/* ASSERT: IBF and OBF are clear */
    682 	dbg_printf(50, "%s: %#.2x\n", __func__, cmd);
    683 	bmc_write(sc, _KCS_COMMAND_REGISTER, cmd);
    684 
    685 	return kcs_wait(sc, KCS_IBF, 0, "write_cmd");
    686 }
    687 
    688 static int
    689 kcs_write_data(struct ipmi_softc *sc, uint8_t data)
    690 {
    691 	/* ASSERT: IBF and OBF are clear */
    692 	dbg_printf(50, "%s: %#.2x\n", __func__, data);
    693 	bmc_write(sc, _KCS_DATAOUT_REGISTER, data);
    694 
    695 	return kcs_wait(sc, KCS_IBF, 0, "write_data");
    696 }
    697 
    698 static int
    699 kcs_read_data(struct ipmi_softc *sc, uint8_t * data)
    700 {
    701 	int sts;
    702 
    703 	sts = kcs_wait(sc, KCS_IBF | KCS_OBF, KCS_OBF, __func__);
    704 	if (sts != KCS_READ_STATE)
    705 		return sts;
    706 
    707 	/* ASSERT: OBF is set read data, request next byte */
    708 	*data = bmc_read(sc, _KCS_DATAIN_REGISTER);
    709 	bmc_write(sc, _KCS_DATAOUT_REGISTER, KCS_READ_NEXT);
    710 
    711 	dbg_printf(50, "%s: %#.2x\n", __func__, *data);
    712 
    713 	return sts;
    714 }
    715 
    716 /* Exported KCS functions */
    717 static int
    718 kcs_sendmsg(struct ipmi_softc *sc, int len, const uint8_t * data)
    719 {
    720 	int idx, sts;
    721 
    722 	/* ASSERT: IBF is clear */
    723 	dbg_dump(50, __func__, len, data);
    724 	sts = kcs_write_cmd(sc, KCS_WRITE_START);
    725 	for (idx = 0; idx < len; idx++) {
    726 		if (idx == len - 1)
    727 			sts = kcs_write_cmd(sc, KCS_WRITE_END);
    728 
    729 		if (sts != KCS_WRITE_STATE)
    730 			break;
    731 
    732 		sts = kcs_write_data(sc, data[idx]);
    733 	}
    734 	if (sts != KCS_READ_STATE) {
    735 		dbg_printf(1, "%s: %d/%d <%#.2x>\n", __func__, idx, len, sts);
    736 		dbg_dump(1, __func__, len, data);
    737 		return -1;
    738 	}
    739 
    740 	return 0;
    741 }
    742 
    743 static int
    744 kcs_recvmsg(struct ipmi_softc *sc, int maxlen, int *rxlen, uint8_t * data)
    745 {
    746 	int idx, sts;
    747 
    748 	for (idx = 0; idx < maxlen; idx++) {
    749 		sts = kcs_read_data(sc, &data[idx]);
    750 		if (sts != KCS_READ_STATE)
    751 			break;
    752 	}
    753 	sts = kcs_wait(sc, KCS_IBF, 0, __func__);
    754 	*rxlen = idx;
    755 	if (sts != KCS_IDLE_STATE) {
    756 		dbg_printf(1, "%s: %d/%d <%#.2x>\n",
    757 		    __func__, idx, maxlen, sts);
    758 		return -1;
    759 	}
    760 
    761 	dbg_dump(50, __func__, idx, data);
    762 
    763 	return 0;
    764 }
    765 
    766 static int
    767 kcs_reset(struct ipmi_softc *sc)
    768 {
    769 	return -1;
    770 }
    771 
    772 static int
    773 kcs_probe(struct ipmi_softc *sc)
    774 {
    775 	uint8_t v;
    776 
    777 	v = bmc_read(sc, _KCS_STATUS_REGISTER);
    778 #if 0
    779 	printf("%s: %2x\n", __func__, v);
    780 	printf(" STS: %2x\n", v & KCS_STATE_MASK);
    781 	printf(" ATN: %2x\n", v & KCS_SMS_ATN);
    782 	printf(" C/D: %2x\n", v & KCS_CD);
    783 	printf(" IBF: %2x\n", v & KCS_IBF);
    784 	printf(" OBF: %2x\n", v & KCS_OBF);
    785 #else
    786 	__USE(v);
    787 #endif
    788 	return 0;
    789 }
    790 
    791 /*
    792  * IPMI code
    793  */
    794 #define READ_SMS_BUFFER		0x37
    795 #define WRITE_I2C		0x50
    796 
    797 #define GET_MESSAGE_CMD		0x33
    798 #define SEND_MESSAGE_CMD	0x34
    799 
    800 #define IPMB_CHANNEL_NUMBER	0
    801 
    802 #define PUBLIC_BUS		0
    803 
    804 #define MIN_I2C_PACKET_SIZE	3
    805 #define MIN_IMB_PACKET_SIZE	7	/* one byte for cksum */
    806 
    807 #define MIN_BTBMC_REQ_SIZE	4
    808 #define MIN_BTBMC_RSP_SIZE	5
    809 #define MIN_BMC_REQ_SIZE	2
    810 #define MIN_BMC_RSP_SIZE	3
    811 
    812 #define BMC_SA			0x20	/* BMC/ESM3 */
    813 #define FPC_SA			0x22	/* front panel */
    814 #define BP_SA			0xC0	/* Primary Backplane */
    815 #define BP2_SA			0xC2	/* Secondary Backplane */
    816 #define PBP_SA			0xC4	/* Peripheral Backplane */
    817 #define DRAC_SA			0x28	/* DRAC-III */
    818 #define DRAC3_SA		0x30	/* DRAC-III */
    819 #define BMC_LUN			0
    820 #define SMS_LUN			2
    821 
    822 struct ipmi_request {
    823 	uint8_t	rsSa;
    824 	uint8_t	rsLun;
    825 	uint8_t	netFn;
    826 	uint8_t	cmd;
    827 	uint8_t	data_len;
    828 	uint8_t	*data;
    829 };
    830 
    831 struct ipmi_response {
    832 	uint8_t	cCode;
    833 	uint8_t	data_len;
    834 	uint8_t	*data;
    835 };
    836 
    837 struct ipmi_bmc_request {
    838 	uint8_t	bmc_nfLn;
    839 	uint8_t	bmc_cmd;
    840 	uint8_t	bmc_data_len;
    841 	uint8_t	bmc_data[1];
    842 };
    843 
    844 struct ipmi_bmc_response {
    845 	uint8_t	bmc_nfLn;
    846 	uint8_t	bmc_cmd;
    847 	uint8_t	bmc_cCode;
    848 	uint8_t	bmc_data_len;
    849 	uint8_t	bmc_data[1];
    850 };
    851 
    852 
    853 CFATTACH_DECL2_NEW(ipmi, sizeof(struct ipmi_softc),
    854     ipmi_match, ipmi_attach, ipmi_detach, NULL, NULL, NULL);
    855 
    856 static void
    857 dumpb(const char *lbl, int len, const uint8_t *data)
    858 {
    859 	int idx;
    860 
    861 	printf("%s: ", lbl);
    862 	for (idx = 0; idx < len; idx++)
    863 		printf("%.2x ", data[idx]);
    864 
    865 	printf("\n");
    866 }
    867 
    868 /*
    869  * bt_buildmsg builds an IPMI message from a nfLun, cmd, and data
    870  * This is used by BT protocol
    871  *
    872  * Returns a buffer to an allocated message, txlen contains length
    873  *   of allocated message
    874  */
    875 static void *
    876 bt_buildmsg(struct ipmi_softc *sc, int nfLun, int cmd, int len,
    877     const void *data, int *txlen)
    878 {
    879 	uint8_t *buf;
    880 
    881 	/* Block transfer needs 4 extra bytes: length/netfn/seq/cmd + data */
    882 	*txlen = len + 4;
    883 	buf = ipmi_buf_acquire(sc, *txlen);
    884 	if (buf == NULL)
    885 		return NULL;
    886 
    887 	buf[IPMI_BTMSG_LEN] = len + 3;
    888 	buf[IPMI_BTMSG_NFLN] = nfLun;
    889 	buf[IPMI_BTMSG_SEQ] = sc->sc_btseq++;
    890 	buf[IPMI_BTMSG_CMD] = cmd;
    891 	if (len && data)
    892 		memcpy(buf + IPMI_BTMSG_DATASND, data, len);
    893 
    894 	return buf;
    895 }
    896 
    897 /*
    898  * cmn_buildmsg builds an IPMI message from a nfLun, cmd, and data
    899  * This is used by both SMIC and KCS protocols
    900  *
    901  * Returns a buffer to an allocated message, txlen contains length
    902  *   of allocated message
    903  */
    904 static void *
    905 cmn_buildmsg(struct ipmi_softc *sc, int nfLun, int cmd, int len,
    906     const void *data, int *txlen)
    907 {
    908 	uint8_t *buf;
    909 
    910 	/* Common needs two extra bytes: nfLun/cmd + data */
    911 	*txlen = len + 2;
    912 	buf = ipmi_buf_acquire(sc, *txlen);
    913 	if (buf == NULL)
    914 		return NULL;
    915 
    916 	buf[IPMI_MSG_NFLN] = nfLun;
    917 	buf[IPMI_MSG_CMD] = cmd;
    918 	if (len && data)
    919 		memcpy(buf + IPMI_MSG_DATASND, data, len);
    920 
    921 	return buf;
    922 }
    923 
    924 /*
    925  * ipmi_sendcmd: caller must hold sc_cmd_mtx.
    926  *
    927  * Send an IPMI command
    928  */
    929 static int
    930 ipmi_sendcmd(struct ipmi_softc *sc, int rssa, int rslun, int netfn, int cmd,
    931     int txlen, const void *data)
    932 {
    933 	uint8_t	*buf;
    934 	int		rc = -1;
    935 
    936 	dbg_printf(50, "%s: rssa=%#.2x nfln=%#.2x cmd=%#.2x len=%#.2x\n",
    937 	    __func__, rssa, NETFN_LUN(netfn, rslun), cmd, txlen);
    938 	dbg_dump(10, __func__, txlen, data);
    939 	if (rssa != BMC_SA) {
    940 #if 0
    941 		buf = sc->sc_if->buildmsg(sc, NETFN_LUN(APP_NETFN, BMC_LUN),
    942 		    APP_SEND_MESSAGE, 7 + txlen, NULL, &txlen);
    943 		pI2C->bus = (sc->if_ver == 0x09) ?
    944 		    PUBLIC_BUS :
    945 		    IPMB_CHANNEL_NUMBER;
    946 
    947 		imbreq->rsSa = rssa;
    948 		imbreq->nfLn = NETFN_LUN(netfn, rslun);
    949 		imbreq->cSum1 = -(imbreq->rsSa + imbreq->nfLn);
    950 		imbreq->rqSa = BMC_SA;
    951 		imbreq->seqLn = NETFN_LUN(sc->imb_seq++, SMS_LUN);
    952 		imbreq->cmd = cmd;
    953 		if (txlen)
    954 			memcpy(imbreq->data, data, txlen);
    955 		/* Set message checksum */
    956 		imbreq->data[txlen] = cksum8(&imbreq->rqSa, txlen + 3);
    957 #endif
    958 		goto done;
    959 	} else
    960 		buf = sc->sc_if->buildmsg(sc, NETFN_LUN(netfn, rslun), cmd,
    961 		    txlen, data, &txlen);
    962 
    963 	if (buf == NULL) {
    964 		aprint_error_dev(sc->sc_dev, "sendcmd buffer busy\n");
    965 		goto done;
    966 	}
    967 	rc = sc->sc_if->sendmsg(sc, txlen, buf);
    968 	ipmi_buf_release(sc, buf);
    969 
    970 	ipmi_delay(sc, 50); /* give bmc chance to digest command */
    971 
    972 done:
    973 	return rc;
    974 }
    975 
    976 static void
    977 ipmi_buf_release(struct ipmi_softc *sc, char *buf)
    978 {
    979 	KASSERT(sc->sc_buf_rsvd);
    980 	KASSERT(sc->sc_buf == buf);
    981 	sc->sc_buf_rsvd = false;
    982 }
    983 
    984 static char *
    985 ipmi_buf_acquire(struct ipmi_softc *sc, size_t len)
    986 {
    987 	KASSERT(len <= sizeof(sc->sc_buf));
    988 
    989 	if (sc->sc_buf_rsvd || len > sizeof(sc->sc_buf))
    990 		return NULL;
    991 	sc->sc_buf_rsvd = true;
    992 	return sc->sc_buf;
    993 }
    994 
    995 /*
    996  * ipmi_recvcmd: caller must hold sc_cmd_mtx.
    997  */
    998 static int
    999 ipmi_recvcmd(struct ipmi_softc *sc, int maxlen, int *rxlen, void *data)
   1000 {
   1001 	uint8_t	*buf, rc = 0;
   1002 	int		rawlen;
   1003 
   1004 	/* Need three extra bytes: netfn/cmd/ccode + data */
   1005 	buf = ipmi_buf_acquire(sc, maxlen + 3);
   1006 	if (buf == NULL) {
   1007 		aprint_error_dev(sc->sc_dev, "%s: malloc fails\n", __func__);
   1008 		return -1;
   1009 	}
   1010 	/* Receive message from interface, copy out result data */
   1011 	if (sc->sc_if->recvmsg(sc, maxlen + 3, &rawlen, buf)) {
   1012 		ipmi_buf_release(sc, buf);
   1013 		return -1;
   1014 	}
   1015 
   1016 	*rxlen = rawlen - IPMI_MSG_DATARCV;
   1017 	if (*rxlen > 0 && data)
   1018 		memcpy(data, buf + IPMI_MSG_DATARCV, *rxlen);
   1019 
   1020 	if ((rc = buf[IPMI_MSG_CCODE]) != 0)
   1021 		dbg_printf(1, "%s: nfln=%#.2x cmd=%#.2x err=%#.2x\n", __func__,
   1022 		    buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE]);
   1023 
   1024 	dbg_printf(50, "%s: nfln=%#.2x cmd=%#.2x err=%#.2x len=%#.2x\n",
   1025 	    __func__, buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD],
   1026 	    buf[IPMI_MSG_CCODE], *rxlen);
   1027 	dbg_dump(10, __func__, *rxlen, data);
   1028 
   1029 	ipmi_buf_release(sc, buf);
   1030 
   1031 	return rc;
   1032 }
   1033 
   1034 /*
   1035  * ipmi_delay: caller must hold sc_cmd_mtx.
   1036  */
   1037 static void
   1038 ipmi_delay(struct ipmi_softc *sc, int ms)
   1039 {
   1040 	if (cold) {
   1041 		delay(ms * 1000);
   1042 		return;
   1043 	}
   1044 	mutex_enter(&sc->sc_sleep_mtx);
   1045 	cv_timedwait(&sc->sc_cmd_sleep, &sc->sc_sleep_mtx, mstohz(ms));
   1046 	mutex_exit(&sc->sc_sleep_mtx);
   1047 }
   1048 
   1049 /* Read a partial SDR entry */
   1050 static int
   1051 get_sdr_partial(struct ipmi_softc *sc, uint16_t recordId, uint16_t reserveId,
   1052     uint8_t offset, uint8_t length, void *buffer, uint16_t *nxtRecordId)
   1053 {
   1054 	uint8_t	cmd[256 + 8];
   1055 	int		len;
   1056 
   1057 	((uint16_t *) cmd)[0] = reserveId;
   1058 	((uint16_t *) cmd)[1] = recordId;
   1059 	cmd[4] = offset;
   1060 	cmd[5] = length;
   1061 	mutex_enter(&sc->sc_cmd_mtx);
   1062 	if (ipmi_sendcmd(sc, BMC_SA, 0, STORAGE_NETFN, STORAGE_GET_SDR, 6,
   1063 	    cmd)) {
   1064 		mutex_exit(&sc->sc_cmd_mtx);
   1065 		aprint_error_dev(sc->sc_dev, "%s: sendcmd fails\n", __func__);
   1066 		return -1;
   1067 	}
   1068 	if (ipmi_recvcmd(sc, 8 + length, &len, cmd)) {
   1069 		mutex_exit(&sc->sc_cmd_mtx);
   1070 		aprint_error_dev(sc->sc_dev, "%s: recvcmd fails\n", __func__);
   1071 		return -1;
   1072 	}
   1073 	mutex_exit(&sc->sc_cmd_mtx);
   1074 	if (nxtRecordId)
   1075 		*nxtRecordId = *(uint16_t *) cmd;
   1076 	memcpy(buffer, cmd + 2, len - 2);
   1077 
   1078 	return 0;
   1079 }
   1080 
   1081 static int maxsdrlen = 0x10;
   1082 
   1083 /* Read an entire SDR; pass to add sensor */
   1084 static int
   1085 get_sdr(struct ipmi_softc *sc, uint16_t recid, uint16_t *nxtrec)
   1086 {
   1087 	uint16_t	resid = 0;
   1088 	int		len, sdrlen, offset;
   1089 	uint8_t	*psdr;
   1090 	struct sdrhdr	shdr;
   1091 
   1092 	mutex_enter(&sc->sc_cmd_mtx);
   1093 	/* Reserve SDR */
   1094 	if (ipmi_sendcmd(sc, BMC_SA, 0, STORAGE_NETFN, STORAGE_RESERVE_SDR,
   1095 	    0, NULL)) {
   1096 		mutex_exit(&sc->sc_cmd_mtx);
   1097 		aprint_error_dev(sc->sc_dev, "reserve send fails\n");
   1098 		return -1;
   1099 	}
   1100 	if (ipmi_recvcmd(sc, sizeof(resid), &len, &resid)) {
   1101 		mutex_exit(&sc->sc_cmd_mtx);
   1102 		aprint_error_dev(sc->sc_dev, "reserve recv fails\n");
   1103 		return -1;
   1104 	}
   1105 	mutex_exit(&sc->sc_cmd_mtx);
   1106 	/* Get SDR Header */
   1107 	if (get_sdr_partial(sc, recid, resid, 0, sizeof shdr, &shdr, nxtrec)) {
   1108 		aprint_error_dev(sc->sc_dev, "get header fails\n");
   1109 		return -1;
   1110 	}
   1111 	/* Allocate space for entire SDR Length of SDR in header does not
   1112 	 * include header length */
   1113 	sdrlen = sizeof(shdr) + shdr.record_length;
   1114 	psdr = malloc(sdrlen, M_DEVBUF, M_WAITOK);
   1115 	if (psdr == NULL)
   1116 		return -1;
   1117 
   1118 	memcpy(psdr, &shdr, sizeof(shdr));
   1119 
   1120 	/* Read SDR Data maxsdrlen bytes at a time */
   1121 	for (offset = sizeof(shdr); offset < sdrlen; offset += maxsdrlen) {
   1122 		len = sdrlen - offset;
   1123 		if (len > maxsdrlen)
   1124 			len = maxsdrlen;
   1125 
   1126 		if (get_sdr_partial(sc, recid, resid, offset, len,
   1127 		    psdr + offset, NULL)) {
   1128 			aprint_error_dev(sc->sc_dev,
   1129 			    "get chunk : %d,%d fails\n", offset, len);
   1130 			free(psdr, M_DEVBUF);
   1131 			return -1;
   1132 		}
   1133 	}
   1134 
   1135 	/* Add SDR to sensor list, if not wanted, free buffer */
   1136 	if (add_sdr_sensor(sc, psdr) == 0)
   1137 		free(psdr, M_DEVBUF);
   1138 
   1139 	return 0;
   1140 }
   1141 
   1142 static int
   1143 getbits(uint8_t *bytes, int bitpos, int bitlen)
   1144 {
   1145 	int	v;
   1146 	int	mask;
   1147 
   1148 	bitpos += bitlen - 1;
   1149 	for (v = 0; bitlen--;) {
   1150 		v <<= 1;
   1151 		mask = 1L << (bitpos & 7);
   1152 		if (bytes[bitpos >> 3] & mask)
   1153 			v |= 1;
   1154 		bitpos--;
   1155 	}
   1156 
   1157 	return v;
   1158 }
   1159 
   1160 /* Decode IPMI sensor name */
   1161 static void
   1162 ipmi_sensor_name(char *name, int len, uint8_t typelen, uint8_t *bits)
   1163 {
   1164 	int	i, slen;
   1165 	char	bcdplus[] = "0123456789 -.:,_";
   1166 
   1167 	slen = typelen & 0x1F;
   1168 	switch (typelen >> 6) {
   1169 	case IPMI_NAME_UNICODE:
   1170 		//unicode
   1171 		break;
   1172 
   1173 	case IPMI_NAME_BCDPLUS:
   1174 		/* Characters are encoded in 4-bit BCDPLUS */
   1175 		if (len < slen * 2 + 1)
   1176 			slen = (len >> 1) - 1;
   1177 		for (i = 0; i < slen; i++) {
   1178 			*(name++) = bcdplus[bits[i] >> 4];
   1179 			*(name++) = bcdplus[bits[i] & 0xF];
   1180 		}
   1181 		break;
   1182 
   1183 	case IPMI_NAME_ASCII6BIT:
   1184 		/* Characters are encoded in 6-bit ASCII
   1185 		 *   0x00 - 0x3F maps to 0x20 - 0x5F */
   1186 		/* XXX: need to calculate max len: slen = 3/4 * len */
   1187 		if (len < slen + 1)
   1188 			slen = len - 1;
   1189 		for (i = 0; i < slen * 8; i += 6)
   1190 			*(name++) = getbits(bits, i, 6) + ' ';
   1191 		break;
   1192 
   1193 	case IPMI_NAME_ASCII8BIT:
   1194 		/* Characters are 8-bit ascii */
   1195 		if (len < slen + 1)
   1196 			slen = len - 1;
   1197 		while (slen--)
   1198 			*(name++) = *(bits++);
   1199 		break;
   1200 	}
   1201 	*name = 0;
   1202 }
   1203 
   1204 /* Sign extend a n-bit value */
   1205 static long
   1206 signextend(unsigned long val, int bits)
   1207 {
   1208 	long msk = (1L << (bits-1))-1;
   1209 
   1210 	return -(val & ~msk) | val;
   1211 }
   1212 
   1213 
   1214 /* fixpoint arithmetic */
   1215 #define FIX2INT(x)   ((int64_t)((x) >> 32))
   1216 #define INT2FIX(x)   ((int64_t)((uint64_t)(x) << 32))
   1217 
   1218 #define FIX2            0x0000000200000000ll /* 2.0 */
   1219 #define FIX3            0x0000000300000000ll /* 3.0 */
   1220 #define FIXE            0x00000002b7e15163ll /* 2.71828182845904523536 */
   1221 #define FIX10           0x0000000a00000000ll /* 10.0 */
   1222 #define FIXMONE         0xffffffff00000000ll /* -1.0 */
   1223 #define FIXHALF         0x0000000080000000ll /* 0.5 */
   1224 #define FIXTHIRD        0x0000000055555555ll /* 0.33333333333333333333 */
   1225 
   1226 #define FIX1LOG2        0x0000000171547653ll /* 1.0/log(2) */
   1227 #define FIX1LOGE        0x0000000100000000ll /* 1.0/log(2.71828182845904523536) */
   1228 #define FIX1LOG10       0x000000006F2DEC55ll /* 1.0/log(10) */
   1229 
   1230 #define FIX1E           0x000000005E2D58D9ll /* 1.0/2.71828182845904523536 */
   1231 
   1232 static int64_t fixlog_a[] = {
   1233 	0x0000000100000000ll /* 1.0/1.0 */,
   1234 	0xffffffff80000000ll /* -1.0/2.0 */,
   1235 	0x0000000055555555ll /* 1.0/3.0 */,
   1236 	0xffffffffc0000000ll /* -1.0/4.0 */,
   1237 	0x0000000033333333ll /* 1.0/5.0 */,
   1238 	0x000000002aaaaaabll /* -1.0/6.0 */,
   1239 	0x0000000024924925ll /* 1.0/7.0 */,
   1240 	0x0000000020000000ll /* -1.0/8.0 */,
   1241 	0x000000001c71c71cll /* 1.0/9.0 */
   1242 };
   1243 
   1244 static int64_t fixexp_a[] = {
   1245 	0x0000000100000000ll /* 1.0/1.0 */,
   1246 	0x0000000100000000ll /* 1.0/1.0 */,
   1247 	0x0000000080000000ll /* 1.0/2.0 */,
   1248 	0x000000002aaaaaabll /* 1.0/6.0 */,
   1249 	0x000000000aaaaaabll /* 1.0/24.0 */,
   1250 	0x0000000002222222ll /* 1.0/120.0 */,
   1251 	0x00000000005b05b0ll /* 1.0/720.0 */,
   1252 	0x00000000000d00d0ll /* 1.0/5040.0 */,
   1253 	0x000000000001a01all /* 1.0/40320.0 */
   1254 };
   1255 
   1256 static int64_t
   1257 fixmul(int64_t x, int64_t y)
   1258 {
   1259 	int64_t z;
   1260 	int64_t a,b,c,d;
   1261 	int neg;
   1262 
   1263 	neg = 0;
   1264 	if (x < 0) {
   1265 		x = -x;
   1266 		neg = !neg;
   1267 	}
   1268 	if (y < 0) {
   1269 		y = -y;
   1270 		neg = !neg;
   1271 	}
   1272 
   1273 	a = FIX2INT(x);
   1274 	b = x - INT2FIX(a);
   1275 	c = FIX2INT(y);
   1276 	d = y - INT2FIX(c);
   1277 
   1278 	z = INT2FIX(a*c) + a * d + b * c + (b/2 * d/2 >> 30);
   1279 
   1280 	return neg ? -z : z;
   1281 }
   1282 
   1283 static int64_t
   1284 poly(int64_t x0, int64_t x, int64_t a[], int n)
   1285 {
   1286 	int64_t z;
   1287 	int i;
   1288 
   1289 	z  = fixmul(x0, a[0]);
   1290 	for (i=1; i<n; ++i) {
   1291 		x0 = fixmul(x0, x);
   1292 		z  = fixmul(x0, a[i]) + z;
   1293 	}
   1294 	return z;
   1295 }
   1296 
   1297 static int64_t
   1298 logx(int64_t x, int64_t y)
   1299 {
   1300 	int64_t z;
   1301 
   1302 	if (x <= INT2FIX(0)) {
   1303 		z = INT2FIX(-99999);
   1304 		goto done;
   1305 	}
   1306 
   1307 	z = INT2FIX(0);
   1308 	while (x >= FIXE) {
   1309 		x = fixmul(x, FIX1E);
   1310 		z += INT2FIX(1);
   1311 	}
   1312 	while (x < INT2FIX(1)) {
   1313 		x = fixmul(x, FIXE);
   1314 		z -= INT2FIX(1);
   1315 	}
   1316 
   1317 	x -= INT2FIX(1);
   1318 	z += poly(x, x, fixlog_a, sizeof(fixlog_a)/sizeof(fixlog_a[0]));
   1319 	z  = fixmul(z, y);
   1320 
   1321 done:
   1322 	return z;
   1323 }
   1324 
   1325 static int64_t
   1326 powx(int64_t x, int64_t y)
   1327 {
   1328 	int64_t k;
   1329 
   1330 	if (x == INT2FIX(0))
   1331 		goto done;
   1332 
   1333 	x = logx(x,y);
   1334 
   1335 	if (x < INT2FIX(0)) {
   1336 		x = INT2FIX(0) - x;
   1337 		k = -FIX2INT(x);
   1338 		x = INT2FIX(-k) - x;
   1339 	} else {
   1340 		k = FIX2INT(x);
   1341 		x = x - INT2FIX(k);
   1342 	}
   1343 
   1344 	x = poly(INT2FIX(1), x, fixexp_a, sizeof(fixexp_a)/sizeof(fixexp_a[0]));
   1345 
   1346 	while (k < 0) {
   1347 		x = fixmul(x, FIX1E);
   1348 		++k;
   1349 	}
   1350 	while (k > 0) {
   1351 		x = fixmul(x, FIXE);
   1352 		--k;
   1353 	}
   1354 
   1355 done:
   1356 	return x;
   1357 }
   1358 
   1359 /* Convert IPMI reading from sensor factors */
   1360 static long
   1361 ipmi_convert(uint8_t v, struct sdrtype1 *s1, long adj)
   1362 {
   1363 	int64_t	M, B;
   1364 	char	K1, K2;
   1365 	int64_t	val, v1, v2, vs;
   1366 	int sign = (s1->units1 >> 6) & 0x3;
   1367 
   1368 	vs = (sign == 0x1 || sign == 0x2) ? (int8_t)v : v;
   1369 	if ((vs < 0) && (sign == 0x1))
   1370 		vs++;
   1371 
   1372 	/* Calculate linear reading variables */
   1373 	M  = signextend((((short)(s1->m_tolerance & 0xC0)) << 2) + s1->m, 10);
   1374 	B  = signextend((((short)(s1->b_accuracy & 0xC0)) << 2) + s1->b, 10);
   1375 	K1 = signextend(s1->rbexp & 0xF, 4);
   1376 	K2 = signextend(s1->rbexp >> 4, 4);
   1377 
   1378 	/* Calculate sensor reading:
   1379 	 *  y = L((M * v + (B * 10^K1)) * 10^(K2+adj)
   1380 	 *
   1381 	 * This commutes out to:
   1382 	 *  y = L(M*v * 10^(K2+adj) + B * 10^(K1+K2+adj)); */
   1383 	v1 = powx(FIX10, INT2FIX(K2 + adj));
   1384 	v2 = powx(FIX10, INT2FIX(K1 + K2 + adj));
   1385 	val = M * vs * v1 + B * v2;
   1386 
   1387 	/* Linearization function: y = f(x) 0 : y = x 1 : y = ln(x) 2 : y =
   1388 	 * log10(x) 3 : y = log2(x) 4 : y = e^x 5 : y = 10^x 6 : y = 2^x 7 : y
   1389 	 * = 1/x 8 : y = x^2 9 : y = x^3 10 : y = square root(x) 11 : y = cube
   1390 	 * root(x) */
   1391 	switch (s1->linear & 0x7f) {
   1392 	case 0: break;
   1393 	case 1: val = logx(val,FIX1LOGE); break;
   1394 	case 2: val = logx(val,FIX1LOG10); break;
   1395 	case 3: val = logx(val,FIX1LOG2); break;
   1396 	case 4: val = powx(FIXE,val); break;
   1397 	case 5: val = powx(FIX10,val); break;
   1398 	case 6: val = powx(FIX2,val); break;
   1399 	case 7: val = powx(val,FIXMONE); break;
   1400 	case 8: val = powx(val,FIX2); break;
   1401 	case 9: val = powx(val,FIX3); break;
   1402 	case 10: val = powx(val,FIXHALF); break;
   1403 	case 11: val = powx(val,FIXTHIRD); break;
   1404 	}
   1405 
   1406 	return FIX2INT(val);
   1407 }
   1408 
   1409 static int32_t
   1410 ipmi_convert_sensor(uint8_t *reading, struct ipmi_sensor *psensor)
   1411 {
   1412 	struct sdrtype1	*s1 = (struct sdrtype1 *)psensor->i_sdr;
   1413 	int32_t val;
   1414 
   1415 	switch (psensor->i_envtype) {
   1416 	case ENVSYS_STEMP:
   1417 		val = ipmi_convert(reading[0], s1, 6) + 273150000;
   1418 		break;
   1419 
   1420 	case ENVSYS_SVOLTS_DC:
   1421 		val = ipmi_convert(reading[0], s1, 6);
   1422 		break;
   1423 
   1424 	case ENVSYS_SFANRPM:
   1425 		val = ipmi_convert(reading[0], s1, 0);
   1426 		if (((s1->units1>>3)&0x7) == 0x3)
   1427 			val *= 60; /* RPS -> RPM */
   1428 		break;
   1429 	default:
   1430 		val = 0;
   1431 		break;
   1432 	}
   1433 	return val;
   1434 }
   1435 
   1436 static void
   1437 ipmi_set_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
   1438 		sysmon_envsys_lim_t *limits, uint32_t *props)
   1439 {
   1440 	struct ipmi_sensor *ipmi_s;
   1441 
   1442 	/* Find the ipmi_sensor corresponding to this edata */
   1443 	SLIST_FOREACH(ipmi_s, &ipmi_sensor_list, i_list) {
   1444 		if (ipmi_s->i_envnum == edata->sensor) {
   1445 			if (limits == NULL) {
   1446 				limits = &ipmi_s->i_deflims;
   1447 				props  = &ipmi_s->i_defprops;
   1448 			}
   1449 			*props |= PROP_DRIVER_LIMITS;
   1450 			ipmi_s->i_limits = *limits;
   1451 			ipmi_s->i_props  = *props;
   1452 			return;
   1453 		}
   1454 	}
   1455 	return;
   1456 }
   1457 
   1458 static void
   1459 ipmi_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
   1460 		sysmon_envsys_lim_t *limits, uint32_t *props)
   1461 {
   1462 	struct ipmi_sensor *ipmi_s;
   1463 	struct ipmi_softc *sc = sme->sme_cookie;
   1464 
   1465 	/* Find the ipmi_sensor corresponding to this edata */
   1466 	SLIST_FOREACH(ipmi_s, &ipmi_sensor_list, i_list) {
   1467 		if (ipmi_s->i_envnum == edata->sensor) {
   1468 			ipmi_get_sensor_limits(sc, ipmi_s, limits, props);
   1469 			ipmi_s->i_limits = *limits;
   1470 			ipmi_s->i_props  = *props;
   1471 			if (ipmi_s->i_defprops == 0) {
   1472 				ipmi_s->i_defprops = *props;
   1473 				ipmi_s->i_deflims  = *limits;
   1474 			}
   1475 			return;
   1476 		}
   1477 	}
   1478 	return;
   1479 }
   1480 
   1481 static void
   1482 ipmi_get_sensor_limits(struct ipmi_softc *sc, struct ipmi_sensor *psensor,
   1483 		       sysmon_envsys_lim_t *limits, uint32_t *props)
   1484 {
   1485 	struct sdrtype1	*s1 = (struct sdrtype1 *)psensor->i_sdr;
   1486 	bool failure;
   1487 	int	rxlen;
   1488 	uint8_t	data[32];
   1489 	uint32_t prop_critmax, prop_warnmax, prop_critmin, prop_warnmin;
   1490 	int32_t *pcritmax, *pwarnmax, *pcritmin, *pwarnmin;
   1491 
   1492 	*props &= ~(PROP_CRITMIN | PROP_CRITMAX | PROP_WARNMIN | PROP_WARNMAX);
   1493 	data[0] = psensor->i_num;
   1494 	mutex_enter(&sc->sc_cmd_mtx);
   1495 	failure =
   1496 	    ipmi_sendcmd(sc, s1->owner_id, s1->owner_lun,
   1497 			 SE_NETFN, SE_GET_SENSOR_THRESHOLD, 1, data) ||
   1498 	    ipmi_recvcmd(sc, sizeof(data), &rxlen, data);
   1499 	mutex_exit(&sc->sc_cmd_mtx);
   1500 	if (failure)
   1501 		return;
   1502 
   1503 	dbg_printf(25, "%s: %#.2x %#.2x %#.2x %#.2x %#.2x %#.2x %#.2x\n",
   1504 	    __func__, data[0], data[1], data[2], data[3], data[4], data[5],
   1505 	    data[6]);
   1506 
   1507 	switch (s1->linear & 0x7f) {
   1508 	case 7: /* 1/x sensor, exchange upper and lower limits */
   1509 		prop_critmax = PROP_CRITMIN;
   1510 		prop_warnmax = PROP_WARNMIN;
   1511 		prop_critmin = PROP_CRITMAX;
   1512 		prop_warnmin = PROP_WARNMAX;
   1513 		pcritmax = &limits->sel_critmin;
   1514 		pwarnmax = &limits->sel_warnmin;
   1515 		pcritmin = &limits->sel_critmax;
   1516 		pwarnmin = &limits->sel_warnmax;
   1517 		break;
   1518 	default:
   1519 		prop_critmax = PROP_CRITMAX;
   1520 		prop_warnmax = PROP_WARNMAX;
   1521 		prop_critmin = PROP_CRITMIN;
   1522 		prop_warnmin = PROP_WARNMIN;
   1523 		pcritmax = &limits->sel_critmax;
   1524 		pwarnmax = &limits->sel_warnmax;
   1525 		pcritmin = &limits->sel_critmin;
   1526 		pwarnmin = &limits->sel_warnmin;
   1527 		break;
   1528 	}
   1529 
   1530 	if (data[0] & 0x20 && data[6] != 0xff) {
   1531 		*pcritmax = ipmi_convert_sensor(&data[6], psensor);
   1532 		*props |= prop_critmax;
   1533 	}
   1534 	if (data[0] & 0x10 && data[5] != 0xff) {
   1535 		*pcritmax = ipmi_convert_sensor(&data[5], psensor);
   1536 		*props |= prop_critmax;
   1537 	}
   1538 	if (data[0] & 0x08 && data[4] != 0xff) {
   1539 		*pwarnmax = ipmi_convert_sensor(&data[4], psensor);
   1540 		*props |= prop_warnmax;
   1541 	}
   1542 	if (data[0] & 0x04 && data[3] != 0x00) {
   1543 		*pcritmin = ipmi_convert_sensor(&data[3], psensor);
   1544 		*props |= prop_critmin;
   1545 	}
   1546 	if (data[0] & 0x02 && data[2] != 0x00) {
   1547 		*pcritmin = ipmi_convert_sensor(&data[2], psensor);
   1548 		*props |= prop_critmin;
   1549 	}
   1550 	if (data[0] & 0x01 && data[1] != 0x00) {
   1551 		*pwarnmin = ipmi_convert_sensor(&data[1], psensor);
   1552 		*props |= prop_warnmin;
   1553 	}
   1554 	return;
   1555 }
   1556 
   1557 static int
   1558 ipmi_sensor_status(struct ipmi_softc *sc, struct ipmi_sensor *psensor,
   1559     envsys_data_t *edata, uint8_t *reading)
   1560 {
   1561 	int	etype;
   1562 
   1563 	/* Get reading of sensor */
   1564 	edata->value_cur = ipmi_convert_sensor(reading, psensor);
   1565 
   1566 	/* Return Sensor Status */
   1567 	etype = (psensor->i_etype << 8) + psensor->i_stype;
   1568 	switch (etype) {
   1569 	case IPMI_SENSOR_TYPE_TEMP:
   1570 	case IPMI_SENSOR_TYPE_VOLT:
   1571 	case IPMI_SENSOR_TYPE_FAN:
   1572 		if (psensor->i_props & PROP_CRITMAX &&
   1573 		    edata->value_cur > psensor->i_limits.sel_critmax)
   1574 			return ENVSYS_SCRITOVER;
   1575 
   1576 		if (psensor->i_props & PROP_WARNMAX &&
   1577 		    edata->value_cur > psensor->i_limits.sel_warnmax)
   1578 			return ENVSYS_SWARNOVER;
   1579 
   1580 		if (psensor->i_props & PROP_WARNMIN &&
   1581 		    edata->value_cur < psensor->i_limits.sel_warnmin)
   1582 			return ENVSYS_SWARNUNDER;
   1583 
   1584 		if (psensor->i_props & PROP_CRITMIN &&
   1585 		    edata->value_cur < psensor->i_limits.sel_critmin)
   1586 			return ENVSYS_SCRITUNDER;
   1587 
   1588 		break;
   1589 
   1590 	case IPMI_SENSOR_TYPE_INTRUSION:
   1591 		edata->value_cur = (reading[2] & 1) ? 0 : 1;
   1592 		if (reading[2] & 0x1)
   1593 			return ENVSYS_SCRITICAL;
   1594 		break;
   1595 
   1596 	case IPMI_SENSOR_TYPE_PWRSUPPLY:
   1597 		/* Reading: 1 = present+powered, 0 = otherwise */
   1598 		edata->value_cur = (reading[2] & 1) ? 0 : 1;
   1599 		if (reading[2] & 0x10) {
   1600 			/* XXX: Need envsys type for Power Supply types
   1601 			 *   ok: power supply installed && powered
   1602 			 * warn: power supply installed && !powered
   1603 			 * crit: power supply !installed
   1604 			 */
   1605 			return ENVSYS_SCRITICAL;
   1606 		}
   1607 		if (reading[2] & 0x08) {
   1608 			/* Power supply AC lost */
   1609 			return ENVSYS_SWARNOVER;
   1610 		}
   1611 		break;
   1612 	}
   1613 
   1614 	return ENVSYS_SVALID;
   1615 }
   1616 
   1617 static int
   1618 read_sensor(struct ipmi_softc *sc, struct ipmi_sensor *psensor)
   1619 {
   1620 	struct sdrtype1	*s1 = (struct sdrtype1 *) psensor->i_sdr;
   1621 	uint8_t	data[8];
   1622 	int		rxlen;
   1623 	envsys_data_t *edata = &sc->sc_sensor[psensor->i_envnum];
   1624 
   1625 	memset(data, 0, sizeof(data));
   1626 	data[0] = psensor->i_num;
   1627 
   1628 	mutex_enter(&sc->sc_cmd_mtx);
   1629 	if (ipmi_sendcmd(sc, s1->owner_id, s1->owner_lun, SE_NETFN,
   1630 	    SE_GET_SENSOR_READING, 1, data))
   1631 		goto err;
   1632 
   1633 	if (ipmi_recvcmd(sc, sizeof(data), &rxlen, data))
   1634 		goto err;
   1635 	mutex_exit(&sc->sc_cmd_mtx);
   1636 
   1637 	dbg_printf(10, "m=%u, m_tolerance=%u, b=%u, b_accuracy=%u, "
   1638 	    "rbexp=%u, linear=%d\n", s1->m, s1->m_tolerance, s1->b,
   1639 	    s1->b_accuracy, s1->rbexp, s1->linear);
   1640 	dbg_printf(10, "values=%#.2x %#.2x %#.2x %#.2x %s\n",
   1641 	    data[0],data[1],data[2],data[3], edata->desc);
   1642 	if (IPMI_INVALID_SENSOR_P(data[1])) {
   1643 		/* Check if sensor is valid */
   1644 		edata->state = ENVSYS_SINVALID;
   1645 	} else {
   1646 		edata->state = ipmi_sensor_status(sc, psensor, edata, data);
   1647 	}
   1648 	return 0;
   1649 err:
   1650 	mutex_exit(&sc->sc_cmd_mtx);
   1651 	return -1;
   1652 }
   1653 
   1654 static int
   1655 ipmi_sensor_type(int type, int ext_type, int entity)
   1656 {
   1657 	switch (ext_type << 8L | type) {
   1658 	case IPMI_SENSOR_TYPE_TEMP:
   1659 		return ENVSYS_STEMP;
   1660 
   1661 	case IPMI_SENSOR_TYPE_VOLT:
   1662 		return ENVSYS_SVOLTS_DC;
   1663 
   1664 	case IPMI_SENSOR_TYPE_FAN:
   1665 		return ENVSYS_SFANRPM;
   1666 
   1667 	case IPMI_SENSOR_TYPE_PWRSUPPLY:
   1668 		if (entity == IPMI_ENTITY_PWRSUPPLY)
   1669 			return ENVSYS_INDICATOR;
   1670 		break;
   1671 
   1672 	case IPMI_SENSOR_TYPE_INTRUSION:
   1673 		return ENVSYS_INDICATOR;
   1674 	}
   1675 
   1676 	return -1;
   1677 }
   1678 
   1679 /* Add Sensor to BSD Sysctl interface */
   1680 static int
   1681 add_sdr_sensor(struct ipmi_softc *sc, uint8_t *psdr)
   1682 {
   1683 	int			rc;
   1684 	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
   1685 	struct sdrtype2		*s2 = (struct sdrtype2 *)psdr;
   1686 	char			name[64];
   1687 
   1688 	switch (s1->sdrhdr.record_type) {
   1689 	case IPMI_SDR_TYPEFULL:
   1690 		ipmi_sensor_name(name, sizeof(name), s1->typelen, s1->name);
   1691 		rc = add_child_sensors(sc, psdr, 1, s1->sensor_num,
   1692 		    s1->sensor_type, s1->event_code, 0, s1->entity_id, name);
   1693 		break;
   1694 
   1695 	case IPMI_SDR_TYPECOMPACT:
   1696 		ipmi_sensor_name(name, sizeof(name), s2->typelen, s2->name);
   1697 		rc = add_child_sensors(sc, psdr, s2->share1 & 0xF,
   1698 		    s2->sensor_num, s2->sensor_type, s2->event_code,
   1699 		    s2->share2 & 0x7F, s2->entity_id, name);
   1700 		break;
   1701 
   1702 	default:
   1703 		return 0;
   1704 	}
   1705 
   1706 	return rc;
   1707 }
   1708 
   1709 static int
   1710 ipmi_is_dupname(char *name)
   1711 {
   1712 	struct ipmi_sensor *ipmi_s;
   1713 
   1714 	SLIST_FOREACH(ipmi_s, &ipmi_sensor_list, i_list) {
   1715 		if (strcmp(ipmi_s->i_envdesc, name) == 0) {
   1716 			return 1;
   1717 		}
   1718 	}
   1719 	return 0;
   1720 }
   1721 
   1722 static int
   1723 add_child_sensors(struct ipmi_softc *sc, uint8_t *psdr, int count,
   1724     int sensor_num, int sensor_type, int ext_type, int sensor_base,
   1725     int entity, const char *name)
   1726 {
   1727 	int			typ, idx, dupcnt, c;
   1728 	char			*e;
   1729 	struct ipmi_sensor	*psensor;
   1730 	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
   1731 
   1732 	typ = ipmi_sensor_type(sensor_type, ext_type, entity);
   1733 	if (typ == -1) {
   1734 		dbg_printf(5, "Unknown sensor type:%#.2x et:%#.2x sn:%#.2x "
   1735 		    "name:%s\n", sensor_type, ext_type, sensor_num, name);
   1736 		return 0;
   1737 	}
   1738 	dupcnt = 0;
   1739 	sc->sc_nsensors += count;
   1740 	for (idx = 0; idx < count; idx++) {
   1741 		psensor = malloc(sizeof(struct ipmi_sensor), M_DEVBUF,
   1742 		    M_WAITOK);
   1743 		if (psensor == NULL)
   1744 			break;
   1745 
   1746 		memset(psensor, 0, sizeof(struct ipmi_sensor));
   1747 
   1748 		/* Initialize BSD Sensor info */
   1749 		psensor->i_sdr = psdr;
   1750 		psensor->i_num = sensor_num + idx;
   1751 		psensor->i_stype = sensor_type;
   1752 		psensor->i_etype = ext_type;
   1753 		psensor->i_envtype = typ;
   1754 		if (count > 1)
   1755 			snprintf(psensor->i_envdesc,
   1756 			    sizeof(psensor->i_envdesc),
   1757 			    "%s - %d", name, sensor_base + idx);
   1758 		else
   1759 			strlcpy(psensor->i_envdesc, name,
   1760 			    sizeof(psensor->i_envdesc));
   1761 
   1762 		/*
   1763 		 * Check for duplicates.  If there are duplicates,
   1764 		 * make sure there is space in the name (if not,
   1765 		 * truncate to make space) for a count (1-99) to
   1766 		 * add to make the name unique.  If we run the
   1767 		 * counter out, just accept the duplicate (@name99)
   1768 		 * for now.
   1769 		 */
   1770 		if (ipmi_is_dupname(psensor->i_envdesc)) {
   1771 			if (strlen(psensor->i_envdesc) >=
   1772 			    sizeof(psensor->i_envdesc) - 3) {
   1773 				e = psensor->i_envdesc +
   1774 				    sizeof(psensor->i_envdesc) - 3;
   1775 			} else {
   1776 				e = psensor->i_envdesc +
   1777 				    strlen(psensor->i_envdesc);
   1778 			}
   1779 			c = psensor->i_envdesc +
   1780 			    sizeof(psensor->i_envdesc) - e;
   1781 			do {
   1782 				dupcnt++;
   1783 				snprintf(e, c, "%d", dupcnt);
   1784 			} while (dupcnt < 100 &&
   1785 			         ipmi_is_dupname(psensor->i_envdesc));
   1786 		}
   1787 
   1788 		dbg_printf(5, "%s: %#.4x %#.2x:%d ent:%#.2x:%#.2x %s\n",
   1789 		    __func__,
   1790 		    s1->sdrhdr.record_id, s1->sensor_type,
   1791 		    typ, s1->entity_id, s1->entity_instance,
   1792 		    psensor->i_envdesc);
   1793 		SLIST_INSERT_HEAD(&ipmi_sensor_list, psensor, i_list);
   1794 	}
   1795 
   1796 	return 1;
   1797 }
   1798 
   1799 #if 0
   1800 /* Interrupt handler */
   1801 static int
   1802 ipmi_intr(void *arg)
   1803 {
   1804 	struct ipmi_softc	*sc = (struct ipmi_softc *)arg;
   1805 	int			v;
   1806 
   1807 	v = bmc_read(sc, _KCS_STATUS_REGISTER);
   1808 	if (v & KCS_OBF)
   1809 		++ipmi_nintr;
   1810 
   1811 	return 0;
   1812 }
   1813 #endif
   1814 
   1815 /* Handle IPMI Timer - reread sensor values */
   1816 static void
   1817 ipmi_refresh_sensors(struct ipmi_softc *sc)
   1818 {
   1819 
   1820 	if (SLIST_EMPTY(&ipmi_sensor_list))
   1821 		return;
   1822 
   1823 	sc->current_sensor = SLIST_NEXT(sc->current_sensor, i_list);
   1824 	if (sc->current_sensor == NULL)
   1825 		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
   1826 
   1827 	if (read_sensor(sc, sc->current_sensor)) {
   1828 		dbg_printf(1, "%s: error reading\n", __func__);
   1829 	}
   1830 }
   1831 
   1832 static int
   1833 ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
   1834 {
   1835 	int error;
   1836 
   1837 	sc->sc_if = ipmi_get_if(ia->iaa_if_type);
   1838 	if (sc->sc_if == NULL)
   1839 		return -1;
   1840 
   1841 	if (ia->iaa_if_iotype == 'i')
   1842 		sc->sc_iot = ia->iaa_iot;
   1843 	else
   1844 		sc->sc_iot = ia->iaa_memt;
   1845 
   1846 	sc->sc_if_rev = ia->iaa_if_rev;
   1847 	sc->sc_if_iospacing = ia->iaa_if_iospacing;
   1848 	if ((error = bus_space_map(sc->sc_iot, ia->iaa_if_iobase,
   1849 	    sc->sc_if->nregs * sc->sc_if_iospacing, 0, &sc->sc_ioh)) != 0) {
   1850 		const char *xname = sc->sc_dev ? device_xname(sc->sc_dev) :
   1851 		    "ipmi0";
   1852 		aprint_error("%s: %s:bus_space_map(..., %" PRIx64 ", %x"
   1853 		    ", 0, %p) type %c failed %d\n",
   1854 		    xname, __func__, (uint64_t)ia->iaa_if_iobase,
   1855 		    sc->sc_if->nregs * sc->sc_if_iospacing, &sc->sc_ioh,
   1856 		    ia->iaa_if_iotype, error);
   1857 		return -1;
   1858 	}
   1859 #if 0
   1860 	if (iaa->if_if_irq != -1)
   1861 		sc->ih = isa_intr_establish(-1, iaa->if_if_irq,
   1862 		    iaa->if_irqlvl, IPL_BIO, ipmi_intr, sc,
   1863 		    device_xname(sc->sc_dev);
   1864 #endif
   1865 	return 0;
   1866 }
   1867 
   1868 static void
   1869 ipmi_unmap_regs(struct ipmi_softc *sc)
   1870 {
   1871 	bus_space_unmap(sc->sc_iot, sc->sc_ioh,
   1872 	    sc->sc_if->nregs * sc->sc_if_iospacing);
   1873 }
   1874 
   1875 static int
   1876 ipmi_match(device_t parent, cfdata_t cf, void *aux)
   1877 {
   1878 	struct ipmi_softc sc;
   1879 	struct ipmi_attach_args *ia = aux;
   1880 	uint8_t		cmd[32];
   1881 	int			len;
   1882 	int			rv = 0;
   1883 
   1884 	memset(&sc, 0, sizeof(sc));
   1885 
   1886 	/* Map registers */
   1887 	if (ipmi_map_regs(&sc, ia) != 0)
   1888 		return 0;
   1889 
   1890 	sc.sc_if->probe(&sc);
   1891 
   1892 	mutex_init(&sc.sc_cmd_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
   1893 	cv_init(&sc.sc_cmd_sleep, "ipmimtch");
   1894 	mutex_enter(&sc.sc_cmd_mtx);
   1895 	/* Identify BMC device early to detect lying bios */
   1896 	if (ipmi_sendcmd(&sc, BMC_SA, 0, APP_NETFN, APP_GET_DEVICE_ID,
   1897 	    0, NULL)) {
   1898 		mutex_exit(&sc.sc_cmd_mtx);
   1899 		dbg_printf(1, ": unable to send get device id "
   1900 		    "command\n");
   1901 		goto unmap;
   1902 	}
   1903 	if (ipmi_recvcmd(&sc, sizeof(cmd), &len, cmd)) {
   1904 		mutex_exit(&sc.sc_cmd_mtx);
   1905 		dbg_printf(1, ": unable to retrieve device id\n");
   1906 		goto unmap;
   1907 	}
   1908 	mutex_exit(&sc.sc_cmd_mtx);
   1909 
   1910 	dbg_dump(1, __func__, len, cmd);
   1911 	rv = 1; /* GETID worked, we got IPMI */
   1912 unmap:
   1913 	cv_destroy(&sc.sc_cmd_sleep);
   1914 	mutex_destroy(&sc.sc_cmd_mtx);
   1915 	ipmi_unmap_regs(&sc);
   1916 
   1917 	return rv;
   1918 }
   1919 
   1920 static void
   1921 ipmi_thread(void *cookie)
   1922 {
   1923 	device_t		self = cookie;
   1924 	struct ipmi_softc	*sc = device_private(self);
   1925 	struct ipmi_attach_args *ia = &sc->sc_ia;
   1926 	uint16_t		rec;
   1927 	struct ipmi_sensor *ipmi_s;
   1928 	int i;
   1929 
   1930 	sc->sc_thread_running = true;
   1931 
   1932 	/* setup ticker */
   1933 	sc->sc_max_retries = hz * 90; /* 90 seconds max */
   1934 
   1935 	/* Map registers */
   1936 	ipmi_map_regs(sc, ia);
   1937 
   1938 	/* Scan SDRs, add sensors to list */
   1939 	for (rec = 0; rec != 0xFFFF;)
   1940 		if (get_sdr(sc, rec, &rec))
   1941 			break;
   1942 
   1943 	/* allocate and fill sensor arrays */
   1944 	sc->sc_sensor =
   1945 	    malloc(sizeof(envsys_data_t) * sc->sc_nsensors,
   1946 	        M_DEVBUF, M_WAITOK | M_ZERO);
   1947 	if (sc->sc_sensor == NULL) {
   1948 		aprint_error_dev(self, "can't allocate envsys_data_t\n");
   1949 		kthread_exit(0);
   1950 	}
   1951 
   1952 	sc->sc_envsys = sysmon_envsys_create();
   1953 	sc->sc_envsys->sme_cookie = sc;
   1954 	sc->sc_envsys->sme_get_limits = ipmi_get_limits;
   1955 	sc->sc_envsys->sme_set_limits = ipmi_set_limits;
   1956 
   1957 	i = 0;
   1958 	SLIST_FOREACH(ipmi_s, &ipmi_sensor_list, i_list) {
   1959 		ipmi_s->i_props = 0;
   1960 		ipmi_s->i_envnum = -1;
   1961 		sc->sc_sensor[i].units = ipmi_s->i_envtype;
   1962 		sc->sc_sensor[i].state = ENVSYS_SINVALID;
   1963 		sc->sc_sensor[i].flags |= ENVSYS_FHAS_ENTROPY;
   1964 		/*
   1965 		 * Monitor threshold limits in the sensors.
   1966 		 */
   1967 		switch (sc->sc_sensor[i].units) {
   1968 		case ENVSYS_STEMP:
   1969 		case ENVSYS_SVOLTS_DC:
   1970 		case ENVSYS_SFANRPM:
   1971 			sc->sc_sensor[i].flags |= ENVSYS_FMONLIMITS;
   1972 			break;
   1973 		default:
   1974 			sc->sc_sensor[i].flags |= ENVSYS_FMONCRITICAL;
   1975 		}
   1976 		(void)strlcpy(sc->sc_sensor[i].desc, ipmi_s->i_envdesc,
   1977 		    sizeof(sc->sc_sensor[i].desc));
   1978 		++i;
   1979 
   1980 		if (sysmon_envsys_sensor_attach(sc->sc_envsys,
   1981 						&sc->sc_sensor[i-1]))
   1982 			continue;
   1983 
   1984 		/* get reference number from envsys */
   1985 		ipmi_s->i_envnum = sc->sc_sensor[i-1].sensor;
   1986 	}
   1987 
   1988 	sc->sc_envsys->sme_name = device_xname(sc->sc_dev);
   1989 	sc->sc_envsys->sme_flags = SME_DISABLE_REFRESH;
   1990 
   1991 	if (sysmon_envsys_register(sc->sc_envsys)) {
   1992 		aprint_error_dev(self, "unable to register with sysmon\n");
   1993 		sysmon_envsys_destroy(sc->sc_envsys);
   1994 	}
   1995 
   1996 	/* initialize sensor list for thread */
   1997 	if (!SLIST_EMPTY(&ipmi_sensor_list))
   1998 		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
   1999 
   2000 	aprint_verbose_dev(self, "version %d.%d interface %s %sbase "
   2001 	    "0x%" PRIx64 "/%#x spacing %d\n",
   2002 	    ia->iaa_if_rev >> 4, ia->iaa_if_rev & 0xF, sc->sc_if->name,
   2003 	    ia->iaa_if_iotype == 'i' ? "io" : "mem",
   2004 	    (uint64_t)ia->iaa_if_iobase,
   2005 	    ia->iaa_if_iospacing * sc->sc_if->nregs, ia->iaa_if_iospacing);
   2006 	if (ia->iaa_if_irq != -1)
   2007 		aprint_verbose_dev(self, " irq %d\n", ia->iaa_if_irq);
   2008 
   2009 	/* setup flag to exclude iic */
   2010 	ipmi_enabled = 1;
   2011 
   2012 	/* Setup Watchdog timer */
   2013 	sc->sc_wdog.smw_name = device_xname(sc->sc_dev);
   2014 	sc->sc_wdog.smw_cookie = sc;
   2015 	sc->sc_wdog.smw_setmode = ipmi_watchdog_setmode;
   2016 	sc->sc_wdog.smw_tickle = ipmi_watchdog_tickle;
   2017 	sysmon_wdog_register(&sc->sc_wdog);
   2018 
   2019 	/* Set up a power handler so we can possibly sleep */
   2020 	if (!pmf_device_register(self, ipmi_suspend, NULL))
   2021                 aprint_error_dev(self, "couldn't establish a power handler\n");
   2022 
   2023 	mutex_enter(&sc->sc_poll_mtx);
   2024 	while (sc->sc_thread_running) {
   2025 		ipmi_refresh_sensors(sc);
   2026 		cv_timedwait(&sc->sc_poll_cv, &sc->sc_poll_mtx,
   2027 		    SENSOR_REFRESH_RATE);
   2028 		if (sc->sc_tickle_due) {
   2029 			ipmi_dotickle(sc);
   2030 			sc->sc_tickle_due = false;
   2031 		}
   2032 	}
   2033 	mutex_exit(&sc->sc_poll_mtx);
   2034 	self->dv_flags &= ~DVF_ATTACH_INPROGRESS;
   2035 	kthread_exit(0);
   2036 }
   2037 
   2038 static void
   2039 ipmi_attach(device_t parent, device_t self, void *aux)
   2040 {
   2041 	struct ipmi_softc	*sc = device_private(self);
   2042 
   2043 	sc->sc_ia = *(struct ipmi_attach_args *)aux;
   2044 	sc->sc_dev = self;
   2045 	aprint_naive("\n");
   2046 	aprint_normal("\n");
   2047 
   2048 	/* lock around read_sensor so that no one messes with the bmc regs */
   2049 	mutex_init(&sc->sc_cmd_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
   2050 	mutex_init(&sc->sc_sleep_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
   2051 	cv_init(&sc->sc_cmd_sleep, "ipmicmd");
   2052 
   2053 	mutex_init(&sc->sc_poll_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
   2054 	cv_init(&sc->sc_poll_cv, "ipmipoll");
   2055 
   2056 	if (kthread_create(PRI_NONE, 0, NULL, ipmi_thread, self,
   2057 	    &sc->sc_kthread, "%s", device_xname(self)) != 0) {
   2058 		aprint_error_dev(self, "unable to create thread, disabled\n");
   2059 	} else
   2060 		self->dv_flags |= DVF_ATTACH_INPROGRESS;
   2061 }
   2062 
   2063 static int
   2064 ipmi_detach(device_t self, int flags)
   2065 {
   2066 	struct ipmi_sensor *i;
   2067 	int rc;
   2068 	struct ipmi_softc *sc = device_private(self);
   2069 
   2070 	mutex_enter(&sc->sc_poll_mtx);
   2071 	sc->sc_thread_running = false;
   2072 	cv_signal(&sc->sc_poll_cv);
   2073 	mutex_exit(&sc->sc_poll_mtx);
   2074 
   2075 	if ((rc = sysmon_wdog_unregister(&sc->sc_wdog)) != 0) {
   2076 		if (rc == ERESTART)
   2077 			rc = EINTR;
   2078 		return rc;
   2079 	}
   2080 
   2081 	/* cancel any pending countdown */
   2082 	sc->sc_wdog.smw_mode &= ~WDOG_MODE_MASK;
   2083 	sc->sc_wdog.smw_mode |= WDOG_MODE_DISARMED;
   2084 	sc->sc_wdog.smw_period = WDOG_PERIOD_DEFAULT;
   2085 
   2086 	if ((rc = ipmi_watchdog_setmode(&sc->sc_wdog)) != 0)
   2087 		return rc;
   2088 
   2089 	ipmi_enabled = 0;
   2090 
   2091 	if (sc->sc_envsys != NULL) {
   2092 		/* _unregister also destroys */
   2093 		sysmon_envsys_unregister(sc->sc_envsys);
   2094 		sc->sc_envsys = NULL;
   2095 	}
   2096 
   2097 	while ((i = SLIST_FIRST(&ipmi_sensor_list)) != NULL) {
   2098 		SLIST_REMOVE_HEAD(&ipmi_sensor_list, i_list);
   2099 		free(i, M_DEVBUF);
   2100 	}
   2101 
   2102 	if (sc->sc_sensor != NULL) {
   2103 		free(sc->sc_sensor, M_DEVBUF);
   2104 		sc->sc_sensor = NULL;
   2105 	}
   2106 
   2107 	ipmi_unmap_regs(sc);
   2108 
   2109 	cv_destroy(&sc->sc_poll_cv);
   2110 	mutex_destroy(&sc->sc_poll_mtx);
   2111 	cv_destroy(&sc->sc_cmd_sleep);
   2112 	mutex_destroy(&sc->sc_sleep_mtx);
   2113 	mutex_destroy(&sc->sc_cmd_mtx);
   2114 
   2115 	return 0;
   2116 }
   2117 
   2118 static int
   2119 ipmi_watchdog_setmode(struct sysmon_wdog *smwdog)
   2120 {
   2121 	struct ipmi_softc	*sc = smwdog->smw_cookie;
   2122 	struct ipmi_get_watchdog gwdog;
   2123 	struct ipmi_set_watchdog swdog;
   2124 	int			rc, len;
   2125 
   2126 	if (smwdog->smw_period < 10)
   2127 		return EINVAL;
   2128 	if (smwdog->smw_period == WDOG_PERIOD_DEFAULT)
   2129 		sc->sc_wdog.smw_period = 10;
   2130 	else
   2131 		sc->sc_wdog.smw_period = smwdog->smw_period;
   2132 
   2133 	mutex_enter(&sc->sc_cmd_mtx);
   2134 	/* see if we can properly task to the watchdog */
   2135 	rc = ipmi_sendcmd(sc, BMC_SA, BMC_LUN, APP_NETFN,
   2136 	    APP_GET_WATCHDOG_TIMER, 0, NULL);
   2137 	rc = ipmi_recvcmd(sc, sizeof(gwdog), &len, &gwdog);
   2138 	mutex_exit(&sc->sc_cmd_mtx);
   2139 	if (rc) {
   2140 		aprint_error_dev(sc->sc_dev,
   2141 		    "APP_GET_WATCHDOG_TIMER returned %#x\n", rc);
   2142 		return EIO;
   2143 	}
   2144 
   2145 	memset(&swdog, 0, sizeof(swdog));
   2146 	/* Period is 10ths/sec */
   2147 	swdog.wdog_timeout = htole16(sc->sc_wdog.smw_period * 10);
   2148 	if ((smwdog->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED)
   2149 		swdog.wdog_action = IPMI_WDOG_ACT_DISABLED;
   2150 	else
   2151 		swdog.wdog_action = IPMI_WDOG_ACT_RESET;
   2152 	swdog.wdog_use = IPMI_WDOG_USE_USE_OS;
   2153 
   2154 	mutex_enter(&sc->sc_cmd_mtx);
   2155 	if ((rc = ipmi_sendcmd(sc, BMC_SA, BMC_LUN, APP_NETFN,
   2156 	    APP_SET_WATCHDOG_TIMER, sizeof(swdog), &swdog)) == 0)
   2157 		rc = ipmi_recvcmd(sc, 0, &len, NULL);
   2158 	mutex_exit(&sc->sc_cmd_mtx);
   2159 	if (rc) {
   2160 		aprint_error_dev(sc->sc_dev,
   2161 		    "APP_SET_WATCHDOG_TIMER returned %#x\n", rc);
   2162 		return EIO;
   2163 	}
   2164 
   2165 	return 0;
   2166 }
   2167 
   2168 static int
   2169 ipmi_watchdog_tickle(struct sysmon_wdog *smwdog)
   2170 {
   2171 	struct ipmi_softc	*sc = smwdog->smw_cookie;
   2172 
   2173 	mutex_enter(&sc->sc_poll_mtx);
   2174 	sc->sc_tickle_due = true;
   2175 	cv_signal(&sc->sc_poll_cv);
   2176 	mutex_exit(&sc->sc_poll_mtx);
   2177 	return 0;
   2178 }
   2179 
   2180 static void
   2181 ipmi_dotickle(struct ipmi_softc *sc)
   2182 {
   2183 	int			rc, len;
   2184 
   2185 	mutex_enter(&sc->sc_cmd_mtx);
   2186 	/* tickle the watchdog */
   2187 	if ((rc = ipmi_sendcmd(sc, BMC_SA, BMC_LUN, APP_NETFN,
   2188 	    APP_RESET_WATCHDOG, 0, NULL)) == 0)
   2189 		rc = ipmi_recvcmd(sc, 0, &len, NULL);
   2190 	mutex_exit(&sc->sc_cmd_mtx);
   2191 	if (rc != 0) {
   2192 		aprint_error_dev(sc->sc_dev, "watchdog tickle returned %#x\n",
   2193 		    rc);
   2194 	}
   2195 }
   2196 
   2197 static bool
   2198 ipmi_suspend(device_t dev, const pmf_qual_t *qual)
   2199 {
   2200 	struct ipmi_softc *sc = device_private(dev);
   2201 
   2202 	/* Don't allow suspend if watchdog is armed */
   2203 	if ((sc->sc_wdog.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED)
   2204 		return false;
   2205 	return true;
   2206 }
   2207