xref: /openbsd/sys/dev/ipmi.c (revision 76d0caae)
1 /*	$OpenBSD: ipmi.c,v 1.115 2021/01/23 12:10:08 kettenis Exp $ */
2 
3 /*
4  * Copyright (c) 2015 Masao Uebayashi
5  * Copyright (c) 2005 Jordan Hargrave
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/device.h>
34 #include <sys/ioctl.h>
35 #include <sys/extent.h>
36 #include <sys/sensors.h>
37 #include <sys/malloc.h>
38 #include <sys/kthread.h>
39 #include <sys/task.h>
40 
41 #include <machine/bus.h>
42 #include <machine/smbiosvar.h>
43 
44 #include <dev/ipmivar.h>
45 #include <dev/ipmi.h>
46 
47 struct ipmi_sensor {
48 	u_int8_t	*i_sdr;
49 	int		i_num;
50 	int		stype;
51 	int		etype;
52 	struct		ksensor i_sensor;
53 	SLIST_ENTRY(ipmi_sensor) list;
54 };
55 
56 int	ipmi_enabled = 0;
57 
58 #define SENSOR_REFRESH_RATE 5	/* seconds */
59 
60 #define DEVNAME(s)  ((s)->sc_dev.dv_xname)
61 
62 #define IPMI_BTMSG_LEN			0
63 #define IPMI_BTMSG_NFLN			1
64 #define IPMI_BTMSG_SEQ			2
65 #define IPMI_BTMSG_CMD			3
66 #define IPMI_BTMSG_CCODE		4
67 #define IPMI_BTMSG_DATASND		4
68 #define IPMI_BTMSG_DATARCV		5
69 
70 #define IPMI_SENSOR_TYPE_TEMP		0x0101
71 #define IPMI_SENSOR_TYPE_VOLT		0x0102
72 #define IPMI_SENSOR_TYPE_FAN		0x0104
73 #define IPMI_SENSOR_TYPE_INTRUSION	0x6F05
74 #define IPMI_SENSOR_TYPE_PWRSUPPLY	0x6F08
75 
76 #define IPMI_NAME_UNICODE		0x00
77 #define IPMI_NAME_BCDPLUS		0x01
78 #define IPMI_NAME_ASCII6BIT		0x02
79 #define IPMI_NAME_ASCII8BIT		0x03
80 
81 #define IPMI_ENTITY_PWRSUPPLY		0x0A
82 
83 #define IPMI_INVALID_SENSOR		(1L << 5)
84 #define IPMI_DISABLED_SENSOR		(1L << 6)
85 
86 #define IPMI_SDR_TYPEFULL		1
87 #define IPMI_SDR_TYPECOMPACT		2
88 
89 #define byteof(x) ((x) >> 3)
90 #define bitof(x)  (1L << ((x) & 0x7))
91 #define TB(b,m)	  (data[2+byteof(b)] & bitof(b))
92 
93 #ifdef IPMI_DEBUG
94 int	ipmi_dbg = 0;
95 #define dbg_printf(lvl, fmt...) \
96 	if (ipmi_dbg >= lvl) \
97 		printf(fmt);
98 #define dbg_dump(lvl, msg, len, buf) \
99 	if (len && ipmi_dbg >= lvl) \
100 		dumpb(msg, len, (const u_int8_t *)(buf));
101 #else
102 #define dbg_printf(lvl, fmt...)
103 #define dbg_dump(lvl, msg, len, buf)
104 #endif
105 
106 long signextend(unsigned long, int);
107 
108 SLIST_HEAD(ipmi_sensors_head, ipmi_sensor);
109 struct ipmi_sensors_head ipmi_sensor_list =
110     SLIST_HEAD_INITIALIZER(ipmi_sensor_list);
111 
112 void	dumpb(const char *, int, const u_int8_t *);
113 
114 int	read_sensor(struct ipmi_softc *, struct ipmi_sensor *);
115 int	add_sdr_sensor(struct ipmi_softc *, u_int8_t *, int);
116 int	get_sdr_partial(struct ipmi_softc *, u_int16_t, u_int16_t,
117 	    u_int8_t, u_int8_t, void *, u_int16_t *);
118 int	get_sdr(struct ipmi_softc *, u_int16_t, u_int16_t *);
119 
120 int	ipmi_sendcmd(struct ipmi_cmd *);
121 int	ipmi_recvcmd(struct ipmi_cmd *);
122 void	ipmi_cmd(struct ipmi_cmd *);
123 void	ipmi_cmd_poll(struct ipmi_cmd *);
124 void	ipmi_cmd_wait(struct ipmi_cmd *);
125 void	ipmi_cmd_wait_cb(void *);
126 
127 int	ipmi_watchdog(void *, int);
128 void	ipmi_watchdog_tickle(void *);
129 void	ipmi_watchdog_set(void *);
130 
131 struct ipmi_softc *ipmilookup(dev_t dev);
132 
133 int	ipmiopen(dev_t, int, int, struct proc *);
134 int	ipmiclose(dev_t, int, int, struct proc *);
135 int	ipmiioctl(dev_t, u_long, caddr_t, int, struct proc *);
136 
137 long	ipow(long, int);
138 long	ipmi_convert(u_int8_t, struct sdrtype1 *, long);
139 int	ipmi_sensor_name(char *, int, u_int8_t, u_int8_t *, int);
140 
141 /* BMC Helper Functions */
142 u_int8_t bmc_read(struct ipmi_softc *, int);
143 void	bmc_write(struct ipmi_softc *, int, u_int8_t);
144 int	bmc_io_wait(struct ipmi_softc *, struct ipmi_iowait *);
145 
146 void	bt_buildmsg(struct ipmi_cmd *);
147 void	cmn_buildmsg(struct ipmi_cmd *);
148 
149 int	getbits(u_int8_t *, int, int);
150 int	ipmi_sensor_type(int, int, int);
151 
152 void	ipmi_refresh_sensors(struct ipmi_softc *sc);
153 int	ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia);
154 void	ipmi_unmap_regs(struct ipmi_softc *);
155 
156 int	ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *,
157     u_int8_t *);
158 
159 int	 add_child_sensors(struct ipmi_softc *, u_int8_t *, int, int, int,
160     int, int, int, const char *);
161 
162 void	ipmi_create_thread(void *);
163 void	ipmi_poll_thread(void *);
164 
165 int	kcs_probe(struct ipmi_softc *);
166 int	kcs_reset(struct ipmi_softc *);
167 int	kcs_sendmsg(struct ipmi_cmd *);
168 int	kcs_recvmsg(struct ipmi_cmd *);
169 
170 int	bt_probe(struct ipmi_softc *);
171 int	bt_reset(struct ipmi_softc *);
172 int	bt_sendmsg(struct ipmi_cmd *);
173 int	bt_recvmsg(struct ipmi_cmd *);
174 
175 int	smic_probe(struct ipmi_softc *);
176 int	smic_reset(struct ipmi_softc *);
177 int	smic_sendmsg(struct ipmi_cmd *);
178 int	smic_recvmsg(struct ipmi_cmd *);
179 
180 struct ipmi_if kcs_if = {
181 	"KCS",
182 	IPMI_IF_KCS_NREGS,
183 	cmn_buildmsg,
184 	kcs_sendmsg,
185 	kcs_recvmsg,
186 	kcs_reset,
187 	kcs_probe,
188 	IPMI_MSG_DATASND,
189 	IPMI_MSG_DATARCV,
190 };
191 
192 struct ipmi_if smic_if = {
193 	"SMIC",
194 	IPMI_IF_SMIC_NREGS,
195 	cmn_buildmsg,
196 	smic_sendmsg,
197 	smic_recvmsg,
198 	smic_reset,
199 	smic_probe,
200 	IPMI_MSG_DATASND,
201 	IPMI_MSG_DATARCV,
202 };
203 
204 struct ipmi_if bt_if = {
205 	"BT",
206 	IPMI_IF_BT_NREGS,
207 	bt_buildmsg,
208 	bt_sendmsg,
209 	bt_recvmsg,
210 	bt_reset,
211 	bt_probe,
212 	IPMI_BTMSG_DATASND,
213 	IPMI_BTMSG_DATARCV,
214 };
215 
216 struct ipmi_if *ipmi_get_if(int);
217 
218 struct ipmi_if *
219 ipmi_get_if(int iftype)
220 {
221 	switch (iftype) {
222 	case IPMI_IF_KCS:
223 		return (&kcs_if);
224 	case IPMI_IF_SMIC:
225 		return (&smic_if);
226 	case IPMI_IF_BT:
227 		return (&bt_if);
228 	}
229 
230 	return (NULL);
231 }
232 
233 /*
234  * BMC Helper Functions
235  */
236 u_int8_t
237 bmc_read(struct ipmi_softc *sc, int offset)
238 {
239 	if (sc->sc_if_iosize == 4)
240 		return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
241 		    offset * sc->sc_if_iospacing));
242 	else
243 		return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
244 		    offset * sc->sc_if_iospacing));
245 }
246 
247 void
248 bmc_write(struct ipmi_softc *sc, int offset, u_int8_t val)
249 {
250 	if (sc->sc_if_iosize == 4)
251 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
252 		    offset * sc->sc_if_iospacing, val);
253 	else
254 		bus_space_write_1(sc->sc_iot, sc->sc_ioh,
255 		    offset * sc->sc_if_iospacing, val);
256 }
257 
258 int
259 bmc_io_wait(struct ipmi_softc *sc, struct ipmi_iowait *a)
260 {
261 	volatile u_int8_t	v;
262 	int			count = 5000000; /* == 5s XXX can be shorter */
263 
264 	while (count--) {
265 		v = bmc_read(sc, a->offset);
266 		if ((v & a->mask) == a->value)
267 			return v;
268 
269 		delay(1);
270 	}
271 
272 	dbg_printf(1, "%s: bmc_io_wait fails : *v=%.2x m=%.2x b=%.2x %s\n",
273 	    DEVNAME(sc), v, a->mask, a->value, a->lbl);
274 	return (-1);
275 
276 }
277 
278 #define RSSA_MASK 0xff
279 #define LUN_MASK 0x3
280 #define NETFN_LUN(nf,ln) (((nf) << 2) | ((ln) & LUN_MASK))
281 
282 /*
283  * BT interface
284  */
285 #define _BT_CTRL_REG			0
286 #define	  BT_CLR_WR_PTR			(1L << 0)
287 #define	  BT_CLR_RD_PTR			(1L << 1)
288 #define	  BT_HOST2BMC_ATN		(1L << 2)
289 #define	  BT_BMC2HOST_ATN		(1L << 3)
290 #define	  BT_EVT_ATN			(1L << 4)
291 #define	  BT_HOST_BUSY			(1L << 6)
292 #define	  BT_BMC_BUSY			(1L << 7)
293 
294 #define	  BT_READY	(BT_HOST_BUSY|BT_HOST2BMC_ATN|BT_BMC2HOST_ATN)
295 
296 #define _BT_DATAIN_REG			1
297 #define _BT_DATAOUT_REG			1
298 
299 #define _BT_INTMASK_REG			2
300 #define	 BT_IM_HIRQ_PEND		(1L << 1)
301 #define	 BT_IM_SCI_EN			(1L << 2)
302 #define	 BT_IM_SMI_EN			(1L << 3)
303 #define	 BT_IM_NMI2SMI			(1L << 4)
304 
305 int bt_read(struct ipmi_softc *, int);
306 int bt_write(struct ipmi_softc *, int, uint8_t);
307 
308 int
309 bt_read(struct ipmi_softc *sc, int reg)
310 {
311 	return bmc_read(sc, reg);
312 }
313 
314 int
315 bt_write(struct ipmi_softc *sc, int reg, uint8_t data)
316 {
317 	struct ipmi_iowait a;
318 
319 	a.offset = _BT_CTRL_REG;
320 	a.mask = BT_BMC_BUSY;
321 	a.value = 0;
322 	a.lbl = "bt_write";
323 	if (bmc_io_wait(sc, &a) < 0)
324 		return (-1);
325 
326 	bmc_write(sc, reg, data);
327 	return (0);
328 }
329 
330 int
331 bt_sendmsg(struct ipmi_cmd *c)
332 {
333 	struct ipmi_softc *sc = c->c_sc;
334 	struct ipmi_iowait a;
335 	int i;
336 
337 	bt_write(sc, _BT_CTRL_REG, BT_CLR_WR_PTR);
338 	for (i = 0; i < c->c_txlen; i++)
339 		bt_write(sc, _BT_DATAOUT_REG, sc->sc_buf[i]);
340 
341 	bt_write(sc, _BT_CTRL_REG, BT_HOST2BMC_ATN);
342 	a.offset = _BT_CTRL_REG;
343 	a.mask = BT_HOST2BMC_ATN | BT_BMC_BUSY;
344 	a.value = 0;
345 	a.lbl = "bt_sendwait";
346 	if (bmc_io_wait(sc, &a) < 0)
347 		return (-1);
348 
349 	return (0);
350 }
351 
352 int
353 bt_recvmsg(struct ipmi_cmd *c)
354 {
355 	struct ipmi_softc *sc = c->c_sc;
356 	struct ipmi_iowait a;
357 	u_int8_t len, v, i, j;
358 
359 	a.offset = _BT_CTRL_REG;
360 	a.mask = BT_BMC2HOST_ATN;
361 	a.value = BT_BMC2HOST_ATN;
362 	a.lbl = "bt_recvwait";
363 	if (bmc_io_wait(sc, &a) < 0)
364 		return (-1);
365 
366 	bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
367 	bt_write(sc, _BT_CTRL_REG, BT_BMC2HOST_ATN);
368 	bt_write(sc, _BT_CTRL_REG, BT_CLR_RD_PTR);
369 	len = bt_read(sc, _BT_DATAIN_REG);
370 	for (i = IPMI_BTMSG_NFLN, j = 0; i <= len; i++) {
371 		v = bt_read(sc, _BT_DATAIN_REG);
372 		if (i != IPMI_BTMSG_SEQ)
373 			*(sc->sc_buf + j++) = v;
374 	}
375 	bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY);
376 	c->c_rxlen = len - 1;
377 
378 	return (0);
379 }
380 
381 int
382 bt_reset(struct ipmi_softc *sc)
383 {
384 	return (-1);
385 }
386 
387 int
388 bt_probe(struct ipmi_softc *sc)
389 {
390 	u_int8_t rv;
391 
392 	rv = bmc_read(sc, _BT_CTRL_REG);
393 	rv &= BT_HOST_BUSY;
394 	rv |= BT_CLR_WR_PTR|BT_CLR_RD_PTR|BT_BMC2HOST_ATN|BT_HOST2BMC_ATN;
395 	bmc_write(sc, _BT_CTRL_REG, rv);
396 
397 	rv = bmc_read(sc, _BT_INTMASK_REG);
398 	rv &= BT_IM_SCI_EN|BT_IM_SMI_EN|BT_IM_NMI2SMI;
399 	rv |= BT_IM_HIRQ_PEND;
400 	bmc_write(sc, _BT_INTMASK_REG, rv);
401 
402 #if 0
403 	printf("bt_probe: %2x\n", v);
404 	printf(" WR    : %2x\n", v & BT_CLR_WR_PTR);
405 	printf(" RD    : %2x\n", v & BT_CLR_RD_PTR);
406 	printf(" H2B   : %2x\n", v & BT_HOST2BMC_ATN);
407 	printf(" B2H   : %2x\n", v & BT_BMC2HOST_ATN);
408 	printf(" EVT   : %2x\n", v & BT_EVT_ATN);
409 	printf(" HBSY  : %2x\n", v & BT_HOST_BUSY);
410 	printf(" BBSY  : %2x\n", v & BT_BMC_BUSY);
411 #endif
412 	return (0);
413 }
414 
415 /*
416  * SMIC interface
417  */
418 #define _SMIC_DATAIN_REG		0
419 #define _SMIC_DATAOUT_REG		0
420 
421 #define _SMIC_CTRL_REG			1
422 #define	  SMS_CC_GET_STATUS		 0x40
423 #define	  SMS_CC_START_TRANSFER		 0x41
424 #define	  SMS_CC_NEXT_TRANSFER		 0x42
425 #define	  SMS_CC_END_TRANSFER		 0x43
426 #define	  SMS_CC_START_RECEIVE		 0x44
427 #define	  SMS_CC_NEXT_RECEIVE		 0x45
428 #define	  SMS_CC_END_RECEIVE		 0x46
429 #define	  SMS_CC_TRANSFER_ABORT		 0x47
430 
431 #define	  SMS_SC_READY			 0xc0
432 #define	  SMS_SC_WRITE_START		 0xc1
433 #define	  SMS_SC_WRITE_NEXT		 0xc2
434 #define	  SMS_SC_WRITE_END		 0xc3
435 #define	  SMS_SC_READ_START		 0xc4
436 #define	  SMS_SC_READ_NEXT		 0xc5
437 #define	  SMS_SC_READ_END		 0xc6
438 
439 #define _SMIC_FLAG_REG			2
440 #define	  SMIC_BUSY			(1L << 0)
441 #define	  SMIC_SMS_ATN			(1L << 2)
442 #define	  SMIC_EVT_ATN			(1L << 3)
443 #define	  SMIC_SMI			(1L << 4)
444 #define	  SMIC_TX_DATA_RDY		(1L << 6)
445 #define	  SMIC_RX_DATA_RDY		(1L << 7)
446 
447 int	smic_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
448 int	smic_write_cmd_data(struct ipmi_softc *, u_int8_t, const u_int8_t *);
449 int	smic_read_data(struct ipmi_softc *, u_int8_t *);
450 
451 int
452 smic_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t val, const char *lbl)
453 {
454 	struct ipmi_iowait a;
455 	int v;
456 
457 	/* Wait for expected flag bits */
458 	a.offset = _SMIC_FLAG_REG;
459 	a.mask = mask;
460 	a.value = val;
461 	a.lbl = "smicwait";
462 	v = bmc_io_wait(sc, &a);
463 	if (v < 0)
464 		return (-1);
465 
466 	/* Return current status */
467 	v = bmc_read(sc, _SMIC_CTRL_REG);
468 	dbg_printf(99, "smic_wait = %.2x\n", v);
469 	return (v);
470 }
471 
472 int
473 smic_write_cmd_data(struct ipmi_softc *sc, u_int8_t cmd, const u_int8_t *data)
474 {
475 	int	sts, v;
476 
477 	dbg_printf(50, "smic_wcd: %.2x %.2x\n", cmd, data ? *data : -1);
478 	sts = smic_wait(sc, SMIC_TX_DATA_RDY | SMIC_BUSY, SMIC_TX_DATA_RDY,
479 	    "smic_write_cmd_data ready");
480 	if (sts < 0)
481 		return (sts);
482 
483 	bmc_write(sc, _SMIC_CTRL_REG, cmd);
484 	if (data)
485 		bmc_write(sc, _SMIC_DATAOUT_REG, *data);
486 
487 	/* Toggle BUSY bit, then wait for busy bit to clear */
488 	v = bmc_read(sc, _SMIC_FLAG_REG);
489 	bmc_write(sc, _SMIC_FLAG_REG, v | SMIC_BUSY);
490 
491 	return (smic_wait(sc, SMIC_BUSY, 0, "smic_write_cmd_data busy"));
492 }
493 
494 int
495 smic_read_data(struct ipmi_softc *sc, u_int8_t *data)
496 {
497 	int sts;
498 
499 	sts = smic_wait(sc, SMIC_RX_DATA_RDY | SMIC_BUSY, SMIC_RX_DATA_RDY,
500 	    "smic_read_data");
501 	if (sts >= 0) {
502 		*data = bmc_read(sc, _SMIC_DATAIN_REG);
503 		dbg_printf(50, "smic_readdata: %.2x\n", *data);
504 	}
505 	return (sts);
506 }
507 
508 #define ErrStat(a,b) if (a) printf(b);
509 
510 int
511 smic_sendmsg(struct ipmi_cmd *c)
512 {
513 	struct ipmi_softc *sc = c->c_sc;
514 	int sts, idx;
515 
516 	sts = smic_write_cmd_data(sc, SMS_CC_START_TRANSFER, &sc->sc_buf[0]);
517 	ErrStat(sts != SMS_SC_WRITE_START, "wstart");
518 	for (idx = 1; idx < c->c_txlen - 1; idx++) {
519 		sts = smic_write_cmd_data(sc, SMS_CC_NEXT_TRANSFER,
520 		    &sc->sc_buf[idx]);
521 		ErrStat(sts != SMS_SC_WRITE_NEXT, "write");
522 	}
523 	sts = smic_write_cmd_data(sc, SMS_CC_END_TRANSFER, &sc->sc_buf[idx]);
524 	if (sts != SMS_SC_WRITE_END) {
525 		dbg_printf(50, "smic_sendmsg %d/%d = %.2x\n", idx, c->c_txlen, sts);
526 		return (-1);
527 	}
528 
529 	return (0);
530 }
531 
532 int
533 smic_recvmsg(struct ipmi_cmd *c)
534 {
535 	struct ipmi_softc *sc = c->c_sc;
536 	int sts, idx;
537 
538 	c->c_rxlen = 0;
539 	sts = smic_wait(sc, SMIC_RX_DATA_RDY, SMIC_RX_DATA_RDY, "smic_recvmsg");
540 	if (sts < 0)
541 		return (-1);
542 
543 	sts = smic_write_cmd_data(sc, SMS_CC_START_RECEIVE, NULL);
544 	ErrStat(sts != SMS_SC_READ_START, "rstart");
545 	for (idx = 0;; ) {
546 		sts = smic_read_data(sc, &sc->sc_buf[idx++]);
547 		if (sts != SMS_SC_READ_START && sts != SMS_SC_READ_NEXT)
548 			break;
549 		smic_write_cmd_data(sc, SMS_CC_NEXT_RECEIVE, NULL);
550 	}
551 	ErrStat(sts != SMS_SC_READ_END, "rend");
552 
553 	c->c_rxlen = idx;
554 
555 	sts = smic_write_cmd_data(sc, SMS_CC_END_RECEIVE, NULL);
556 	if (sts != SMS_SC_READY) {
557 		dbg_printf(50, "smic_recvmsg %d/%d = %.2x\n", idx, c->c_maxrxlen, sts);
558 		return (-1);
559 	}
560 
561 	return (0);
562 }
563 
564 int
565 smic_reset(struct ipmi_softc *sc)
566 {
567 	return (-1);
568 }
569 
570 int
571 smic_probe(struct ipmi_softc *sc)
572 {
573 	/* Flag register should not be 0xFF on a good system */
574 	if (bmc_read(sc, _SMIC_FLAG_REG) == 0xFF)
575 		return (-1);
576 
577 	return (0);
578 }
579 
580 /*
581  * KCS interface
582  */
583 #define _KCS_DATAIN_REGISTER		0
584 #define _KCS_DATAOUT_REGISTER		0
585 #define	  KCS_READ_NEXT			0x68
586 
587 #define _KCS_COMMAND_REGISTER		1
588 #define	  KCS_GET_STATUS		0x60
589 #define	  KCS_WRITE_START		0x61
590 #define	  KCS_WRITE_END			0x62
591 
592 #define _KCS_STATUS_REGISTER		1
593 #define	  KCS_OBF			(1L << 0)
594 #define	  KCS_IBF			(1L << 1)
595 #define	  KCS_SMS_ATN			(1L << 2)
596 #define	  KCS_CD			(1L << 3)
597 #define	  KCS_OEM1			(1L << 4)
598 #define	  KCS_OEM2			(1L << 5)
599 #define	  KCS_STATE_MASK		0xc0
600 #define	    KCS_IDLE_STATE		0x00
601 #define	    KCS_READ_STATE		0x40
602 #define	    KCS_WRITE_STATE		0x80
603 #define	    KCS_ERROR_STATE		0xC0
604 
605 int	kcs_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
606 int	kcs_write_cmd(struct ipmi_softc *, u_int8_t);
607 int	kcs_write_data(struct ipmi_softc *, u_int8_t);
608 int	kcs_read_data(struct ipmi_softc *, u_int8_t *);
609 
610 int
611 kcs_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t value, const char *lbl)
612 {
613 	struct ipmi_iowait a;
614 	int v;
615 
616 	a.offset = _KCS_STATUS_REGISTER;
617 	a.mask = mask;
618 	a.value = value;
619 	a.lbl = lbl;
620 	v = bmc_io_wait(sc, &a);
621 	if (v < 0)
622 		return (v);
623 
624 	/* Check if output buffer full, read dummy byte	 */
625 	if ((v & (KCS_OBF | KCS_STATE_MASK)) == (KCS_OBF | KCS_WRITE_STATE))
626 		bmc_read(sc, _KCS_DATAIN_REGISTER);
627 
628 	/* Check for error state */
629 	if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE) {
630 		bmc_write(sc, _KCS_COMMAND_REGISTER, KCS_GET_STATUS);
631 		while (bmc_read(sc, _KCS_STATUS_REGISTER) & KCS_IBF)
632 			continue;
633 		printf("%s: error code: %x\n", DEVNAME(sc),
634 		    bmc_read(sc, _KCS_DATAIN_REGISTER));
635 	}
636 
637 	return (v & KCS_STATE_MASK);
638 }
639 
640 int
641 kcs_write_cmd(struct ipmi_softc *sc, u_int8_t cmd)
642 {
643 	/* ASSERT: IBF and OBF are clear */
644 	dbg_printf(50, "kcswritecmd: %.2x\n", cmd);
645 	bmc_write(sc, _KCS_COMMAND_REGISTER, cmd);
646 
647 	return (kcs_wait(sc, KCS_IBF, 0, "write_cmd"));
648 }
649 
650 int
651 kcs_write_data(struct ipmi_softc *sc, u_int8_t data)
652 {
653 	/* ASSERT: IBF and OBF are clear */
654 	dbg_printf(50, "kcswritedata: %.2x\n", data);
655 	bmc_write(sc, _KCS_DATAOUT_REGISTER, data);
656 
657 	return (kcs_wait(sc, KCS_IBF, 0, "write_data"));
658 }
659 
660 int
661 kcs_read_data(struct ipmi_softc *sc, u_int8_t * data)
662 {
663 	int sts;
664 
665 	sts = kcs_wait(sc, KCS_IBF | KCS_OBF, KCS_OBF, "read_data");
666 	if (sts != KCS_READ_STATE)
667 		return (sts);
668 
669 	/* ASSERT: OBF is set read data, request next byte */
670 	*data = bmc_read(sc, _KCS_DATAIN_REGISTER);
671 	bmc_write(sc, _KCS_DATAOUT_REGISTER, KCS_READ_NEXT);
672 
673 	dbg_printf(50, "kcsreaddata: %.2x\n", *data);
674 
675 	return (sts);
676 }
677 
678 /* Exported KCS functions */
679 int
680 kcs_sendmsg(struct ipmi_cmd *c)
681 {
682 	struct ipmi_softc *sc = c->c_sc;
683 	int idx, sts;
684 
685 	/* ASSERT: IBF is clear */
686 	dbg_dump(50, "kcs sendmsg", c->c_txlen, sc->sc_buf);
687 	sts = kcs_write_cmd(sc, KCS_WRITE_START);
688 	for (idx = 0; idx < c->c_txlen; idx++) {
689 		if (idx == c->c_txlen - 1)
690 			sts = kcs_write_cmd(sc, KCS_WRITE_END);
691 
692 		if (sts != KCS_WRITE_STATE)
693 			break;
694 
695 		sts = kcs_write_data(sc, sc->sc_buf[idx]);
696 	}
697 	if (sts != KCS_READ_STATE) {
698 		dbg_printf(1, "kcs sendmsg = %d/%d <%.2x>\n", idx, c->c_txlen, sts);
699 		dbg_dump(1, "kcs_sendmsg", c->c_txlen, sc->sc_buf);
700 		return (-1);
701 	}
702 
703 	return (0);
704 }
705 
706 int
707 kcs_recvmsg(struct ipmi_cmd *c)
708 {
709 	struct ipmi_softc *sc = c->c_sc;
710 	int idx, sts;
711 
712 	for (idx = 0; idx < c->c_maxrxlen; idx++) {
713 		sts = kcs_read_data(sc, &sc->sc_buf[idx]);
714 		if (sts != KCS_READ_STATE)
715 			break;
716 	}
717 	sts = kcs_wait(sc, KCS_IBF, 0, "recv");
718 	c->c_rxlen = idx;
719 	if (sts != KCS_IDLE_STATE) {
720 		dbg_printf(1, "kcs recvmsg = %d/%d <%.2x>\n", idx, c->c_maxrxlen, sts);
721 		return (-1);
722 	}
723 
724 	dbg_dump(50, "kcs recvmsg", idx, sc->sc_buf);
725 
726 	return (0);
727 }
728 
729 int
730 kcs_reset(struct ipmi_softc *sc)
731 {
732 	return (-1);
733 }
734 
735 int
736 kcs_probe(struct ipmi_softc *sc)
737 {
738 	u_int8_t v;
739 
740 	v = bmc_read(sc, _KCS_STATUS_REGISTER);
741 	if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE)
742 		return (1);
743 #if 0
744 	printf("kcs_probe: %2x\n", v);
745 	printf(" STS: %2x\n", v & KCS_STATE_MASK);
746 	printf(" ATN: %2x\n", v & KCS_SMS_ATN);
747 	printf(" C/D: %2x\n", v & KCS_CD);
748 	printf(" IBF: %2x\n", v & KCS_IBF);
749 	printf(" OBF: %2x\n", v & KCS_OBF);
750 #endif
751 	return (0);
752 }
753 
754 /*
755  * IPMI code
756  */
757 #define READ_SMS_BUFFER		0x37
758 #define WRITE_I2C		0x50
759 
760 #define GET_MESSAGE_CMD		0x33
761 #define SEND_MESSAGE_CMD	0x34
762 
763 #define IPMB_CHANNEL_NUMBER	0
764 
765 #define PUBLIC_BUS		0
766 
767 #define MIN_I2C_PACKET_SIZE	3
768 #define MIN_IMB_PACKET_SIZE	7	/* one byte for cksum */
769 
770 #define MIN_BTBMC_REQ_SIZE	4
771 #define MIN_BTBMC_RSP_SIZE	5
772 #define MIN_BMC_REQ_SIZE	2
773 #define MIN_BMC_RSP_SIZE	3
774 
775 #define BMC_SA			0x20	/* BMC/ESM3 */
776 #define FPC_SA			0x22	/* front panel */
777 #define BP_SA			0xC0	/* Primary Backplane */
778 #define BP2_SA			0xC2	/* Secondary Backplane */
779 #define PBP_SA			0xC4	/* Peripheral Backplane */
780 #define DRAC_SA			0x28	/* DRAC-III */
781 #define DRAC3_SA		0x30	/* DRAC-III */
782 #define BMC_LUN			0
783 #define SMS_LUN			2
784 
785 struct ipmi_request {
786 	u_int8_t	rsSa;
787 	u_int8_t	rsLun;
788 	u_int8_t	netFn;
789 	u_int8_t	cmd;
790 	u_int8_t	data_len;
791 	u_int8_t	*data;
792 };
793 
794 struct ipmi_response {
795 	u_int8_t	cCode;
796 	u_int8_t	data_len;
797 	u_int8_t	*data;
798 };
799 
800 struct ipmi_bmc_request {
801 	u_int8_t	bmc_nfLn;
802 	u_int8_t	bmc_cmd;
803 	u_int8_t	bmc_data_len;
804 	u_int8_t	bmc_data[1];
805 };
806 
807 struct ipmi_bmc_response {
808 	u_int8_t	bmc_nfLn;
809 	u_int8_t	bmc_cmd;
810 	u_int8_t	bmc_cCode;
811 	u_int8_t	bmc_data_len;
812 	u_int8_t	bmc_data[1];
813 };
814 
815 struct cfdriver ipmi_cd = {
816 	NULL, "ipmi", DV_DULL
817 };
818 
819 void
820 dumpb(const char *lbl, int len, const u_int8_t *data)
821 {
822 	int idx;
823 
824 	printf("%s: ", lbl);
825 	for (idx = 0; idx < len; idx++)
826 		printf("%.2x ", data[idx]);
827 
828 	printf("\n");
829 }
830 
831 /*
832  * bt_buildmsg builds an IPMI message from a nfLun, cmd, and data
833  * This is used by BT protocol
834  */
835 void
836 bt_buildmsg(struct ipmi_cmd *c)
837 {
838 	struct ipmi_softc *sc = c->c_sc;
839 	u_int8_t *buf = sc->sc_buf;
840 
841 	buf[IPMI_BTMSG_LEN] = c->c_txlen + (IPMI_BTMSG_DATASND - 1);
842 	buf[IPMI_BTMSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
843 	buf[IPMI_BTMSG_SEQ] = sc->sc_btseq++;
844 	buf[IPMI_BTMSG_CMD] = c->c_cmd;
845 	if (c->c_txlen && c->c_data)
846 		memcpy(buf + IPMI_BTMSG_DATASND, c->c_data, c->c_txlen);
847 }
848 
849 /*
850  * cmn_buildmsg builds an IPMI message from a nfLun, cmd, and data
851  * This is used by both SMIC and KCS protocols
852  */
853 void
854 cmn_buildmsg(struct ipmi_cmd *c)
855 {
856 	struct ipmi_softc *sc = c->c_sc;
857 	u_int8_t *buf = sc->sc_buf;
858 
859 	buf[IPMI_MSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
860 	buf[IPMI_MSG_CMD] = c->c_cmd;
861 	if (c->c_txlen && c->c_data)
862 		memcpy(buf + IPMI_MSG_DATASND, c->c_data, c->c_txlen);
863 }
864 
865 /* Send an IPMI command */
866 int
867 ipmi_sendcmd(struct ipmi_cmd *c)
868 {
869 	struct ipmi_softc	*sc = c->c_sc;
870 	int		rc = -1;
871 
872 	dbg_printf(50, "ipmi_sendcmd: rssa=%.2x nfln=%.2x cmd=%.2x len=%.2x\n",
873 	    c->c_rssa, NETFN_LUN(c->c_netfn, c->c_rslun), c->c_cmd, c->c_txlen);
874 	dbg_dump(10, " send", c->c_txlen, c->c_data);
875 	if (c->c_rssa != BMC_SA) {
876 #if 0
877 		sc->sc_if->buildmsg(c);
878 		pI2C->bus = (sc->if_ver == 0x09) ?
879 		    PUBLIC_BUS :
880 		    IPMB_CHANNEL_NUMBER;
881 
882 		imbreq->rsSa = rssa;
883 		imbreq->nfLn = NETFN_LUN(netfn, rslun);
884 		imbreq->cSum1 = -(imbreq->rsSa + imbreq->nfLn);
885 		imbreq->rqSa = BMC_SA;
886 		imbreq->seqLn = NETFN_LUN(sc->imb_seq++, SMS_LUN);
887 		imbreq->cmd = cmd;
888 		if (txlen)
889 			memcpy(imbreq->data, data, txlen);
890 		/* Set message checksum */
891 		imbreq->data[txlen] = cksum8(&imbreq->rqSa, txlen + 3);
892 #endif
893 		goto done;
894 	} else
895 		sc->sc_if->buildmsg(c);
896 
897 	c->c_txlen += sc->sc_if->datasnd;
898 	rc = sc->sc_if->sendmsg(c);
899 
900 done:
901 	return (rc);
902 }
903 
904 /* Receive an IPMI command */
905 int
906 ipmi_recvcmd(struct ipmi_cmd *c)
907 {
908 	struct ipmi_softc *sc = c->c_sc;
909 	u_int8_t	*buf = sc->sc_buf, rc = 0;
910 
911 	/* Receive message from interface, copy out result data */
912 	c->c_maxrxlen += sc->sc_if->datarcv;
913 	if (sc->sc_if->recvmsg(c) ||
914 	    c->c_rxlen < sc->sc_if->datarcv) {
915 		return (-1);
916 	}
917 
918 	c->c_rxlen -= sc->sc_if->datarcv;
919 	if (c->c_rxlen > 0 && c->c_data)
920 		memcpy(c->c_data, buf + sc->sc_if->datarcv, c->c_rxlen);
921 
922 	rc = buf[IPMI_MSG_CCODE];
923 #ifdef IPMI_DEBUG
924 	if (rc != 0)
925 		dbg_printf(1, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x\n",
926 		    buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE]);
927 #endif
928 
929 	dbg_printf(50, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x len=%.2x\n",
930 	    buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE],
931 	    c->c_rxlen);
932 	dbg_dump(10, " recv", c->c_rxlen, c->c_data);
933 
934 	return (rc);
935 }
936 
937 void
938 ipmi_cmd(struct ipmi_cmd *c)
939 {
940 	if (cold || panicstr != NULL)
941 		ipmi_cmd_poll(c);
942 	else
943 		ipmi_cmd_wait(c);
944 }
945 
946 void
947 ipmi_cmd_poll(struct ipmi_cmd *c)
948 {
949 	if ((c->c_ccode = ipmi_sendcmd(c)))
950 		printf("%s: sendcmd fails\n", DEVNAME(c->c_sc));
951 	else
952 		c->c_ccode = ipmi_recvcmd(c);
953 }
954 
955 void
956 ipmi_cmd_wait(struct ipmi_cmd *c)
957 {
958 	struct task t;
959 	int res;
960 
961 	task_set(&t, ipmi_cmd_wait_cb, c);
962 	res = task_add(c->c_sc->sc_cmd_taskq, &t);
963 	KASSERT(res == 1);
964 
965 	tsleep_nsec(c, PWAIT, "ipmicmd", INFSLP);
966 
967 	res = task_del(c->c_sc->sc_cmd_taskq, &t);
968 	KASSERT(res == 0);
969 }
970 
971 void
972 ipmi_cmd_wait_cb(void *arg)
973 {
974 	struct ipmi_cmd *c = arg;
975 
976 	ipmi_cmd_poll(c);
977 	wakeup(c);
978 }
979 
980 /* Read a partial SDR entry */
981 int
982 get_sdr_partial(struct ipmi_softc *sc, u_int16_t recordId, u_int16_t reserveId,
983     u_int8_t offset, u_int8_t length, void *buffer, u_int16_t *nxtRecordId)
984 {
985 	u_int8_t	cmd[IPMI_GET_WDOG_MAX + 255];	/* 8 + max of length */
986 	int		len;
987 
988 	((u_int16_t *) cmd)[0] = reserveId;
989 	((u_int16_t *) cmd)[1] = recordId;
990 	cmd[4] = offset;
991 	cmd[5] = length;
992 
993 	struct ipmi_cmd	c;
994 	c.c_sc = sc;
995 	c.c_rssa = BMC_SA;
996 	c.c_rslun = BMC_LUN;
997 	c.c_netfn = STORAGE_NETFN;
998 	c.c_cmd = STORAGE_GET_SDR;
999 	c.c_txlen = IPMI_SET_WDOG_MAX;
1000 	c.c_rxlen = 0;
1001 	c.c_maxrxlen = 8 + length;
1002 	c.c_data = cmd;
1003 	ipmi_cmd(&c);
1004 	len = c.c_rxlen;
1005 
1006 	if (nxtRecordId)
1007 		*nxtRecordId = *(uint16_t *) cmd;
1008 	if (len > 2)
1009 		memcpy(buffer, cmd + 2, len - 2);
1010 	else
1011 		return (1);
1012 
1013 	return (0);
1014 }
1015 
1016 int maxsdrlen = 0x10;
1017 
1018 /* Read an entire SDR; pass to add sensor */
1019 int
1020 get_sdr(struct ipmi_softc *sc, u_int16_t recid, u_int16_t *nxtrec)
1021 {
1022 	u_int16_t	resid = 0;
1023 	int		len, sdrlen, offset;
1024 	u_int8_t	*psdr;
1025 	struct sdrhdr	shdr;
1026 
1027 	/* Reserve SDR */
1028 	struct ipmi_cmd	c;
1029 	c.c_sc = sc;
1030 	c.c_rssa = BMC_SA;
1031 	c.c_rslun = BMC_LUN;
1032 	c.c_netfn = STORAGE_NETFN;
1033 	c.c_cmd = STORAGE_RESERVE_SDR;
1034 	c.c_txlen = 0;
1035 	c.c_maxrxlen = sizeof(resid);
1036 	c.c_rxlen = 0;
1037 	c.c_data = &resid;
1038 	ipmi_cmd(&c);
1039 
1040 	/* Get SDR Header */
1041 	if (get_sdr_partial(sc, recid, resid, 0, sizeof shdr, &shdr, nxtrec)) {
1042 		printf("%s: get header fails\n", DEVNAME(sc));
1043 		return (1);
1044 	}
1045 	/* Allocate space for entire SDR Length of SDR in header does not
1046 	 * include header length */
1047 	sdrlen = sizeof(shdr) + shdr.record_length;
1048 	psdr = malloc(sdrlen, M_DEVBUF, M_NOWAIT);
1049 	if (psdr == NULL)
1050 		return (1);
1051 
1052 	memcpy(psdr, &shdr, sizeof(shdr));
1053 
1054 	/* Read SDR Data maxsdrlen bytes at a time */
1055 	for (offset = sizeof(shdr); offset < sdrlen; offset += maxsdrlen) {
1056 		len = sdrlen - offset;
1057 		if (len > maxsdrlen)
1058 			len = maxsdrlen;
1059 
1060 		if (get_sdr_partial(sc, recid, resid, offset, len,
1061 		    psdr + offset, NULL)) {
1062 			printf("%s: get chunk: %d,%d fails\n", DEVNAME(sc),
1063 			    offset, len);
1064 			free(psdr, M_DEVBUF, sdrlen);
1065 			return (1);
1066 		}
1067 	}
1068 
1069 	/* Add SDR to sensor list, if not wanted, free buffer */
1070 	if (add_sdr_sensor(sc, psdr, sdrlen) == 0)
1071 		free(psdr, M_DEVBUF, sdrlen);
1072 
1073 	return (0);
1074 }
1075 
1076 int
1077 getbits(u_int8_t *bytes, int bitpos, int bitlen)
1078 {
1079 	int	v;
1080 	int	mask;
1081 
1082 	bitpos += bitlen - 1;
1083 	for (v = 0; bitlen--;) {
1084 		v <<= 1;
1085 		mask = 1L << (bitpos & 7);
1086 		if (bytes[bitpos >> 3] & mask)
1087 			v |= 1;
1088 		bitpos--;
1089 	}
1090 
1091 	return (v);
1092 }
1093 
1094 /* Decode IPMI sensor name */
1095 int
1096 ipmi_sensor_name(char *name, int len, u_int8_t typelen, u_int8_t *bits,
1097     int bitslen)
1098 {
1099 	int	i, slen;
1100 	char	bcdplus[] = "0123456789 -.:,_";
1101 
1102 	slen = typelen & 0x1F;
1103 	switch (typelen >> 6) {
1104 	case IPMI_NAME_UNICODE:
1105 		//unicode
1106 		break;
1107 
1108 	case IPMI_NAME_BCDPLUS:
1109 		/* Characters are encoded in 4-bit BCDPLUS */
1110 		if (len < slen * 2 + 1)
1111 			slen = (len >> 1) - 1;
1112 		if (slen > bitslen)
1113 			return (0);
1114 		for (i = 0; i < slen; i++) {
1115 			*(name++) = bcdplus[bits[i] >> 4];
1116 			*(name++) = bcdplus[bits[i] & 0xF];
1117 		}
1118 		break;
1119 
1120 	case IPMI_NAME_ASCII6BIT:
1121 		/* Characters are encoded in 6-bit ASCII
1122 		 *   0x00 - 0x3F maps to 0x20 - 0x5F */
1123 		/* XXX: need to calculate max len: slen = 3/4 * len */
1124 		if (len < slen + 1)
1125 			slen = len - 1;
1126 		if (slen * 6 / 8 > bitslen)
1127 			return (0);
1128 		for (i = 0; i < slen * 8; i += 6) {
1129 			*(name++) = getbits(bits, i, 6) + ' ';
1130 		}
1131 		break;
1132 
1133 	case IPMI_NAME_ASCII8BIT:
1134 		/* Characters are 8-bit ascii */
1135 		if (len < slen + 1)
1136 			slen = len - 1;
1137 		if (slen > bitslen)
1138 			return (0);
1139 		while (slen--)
1140 			*(name++) = *(bits++);
1141 		break;
1142 	}
1143 	*name = 0;
1144 
1145 	return (1);
1146 }
1147 
1148 /* Calculate val * 10^exp */
1149 long
1150 ipow(long val, int exp)
1151 {
1152 	while (exp > 0) {
1153 		val *= 10;
1154 		exp--;
1155 	}
1156 
1157 	while (exp < 0) {
1158 		val /= 10;
1159 		exp++;
1160 	}
1161 
1162 	return (val);
1163 }
1164 
1165 /* Sign extend a n-bit value */
1166 long
1167 signextend(unsigned long val, int bits)
1168 {
1169 	long msk = (1L << (bits-1))-1;
1170 
1171 	return (-(val & ~msk) | val);
1172 }
1173 
1174 /* Convert IPMI reading from sensor factors */
1175 long
1176 ipmi_convert(u_int8_t v, struct sdrtype1 *s1, long adj)
1177 {
1178 	int16_t	M, B;
1179 	int8_t	K1, K2;
1180 	long	val;
1181 
1182 	/* Calculate linear reading variables */
1183 	M  = signextend((((short)(s1->m_tolerance & 0xC0)) << 2) + s1->m, 10);
1184 	B  = signextend((((short)(s1->b_accuracy & 0xC0)) << 2) + s1->b, 10);
1185 	K1 = signextend(s1->rbexp & 0xF, 4);
1186 	K2 = signextend(s1->rbexp >> 4, 4);
1187 
1188 	/* Calculate sensor reading:
1189 	 *  y = L((M * v + (B * 10^K1)) * 10^(K2+adj)
1190 	 *
1191 	 * This commutes out to:
1192 	 *  y = L(M*v * 10^(K2+adj) + B * 10^(K1+K2+adj)); */
1193 	val = ipow(M * v, K2 + adj) + ipow(B, K1 + K2 + adj);
1194 
1195 	/* Linearization function: y = f(x) 0 : y = x 1 : y = ln(x) 2 : y =
1196 	 * log10(x) 3 : y = log2(x) 4 : y = e^x 5 : y = 10^x 6 : y = 2^x 7 : y
1197 	 * = 1/x 8 : y = x^2 9 : y = x^3 10 : y = square root(x) 11 : y = cube
1198 	 * root(x) */
1199 	return (val);
1200 }
1201 
1202 int
1203 ipmi_sensor_status(struct ipmi_softc *sc, struct ipmi_sensor *psensor,
1204     u_int8_t *reading)
1205 {
1206 	struct sdrtype1	*s1 = (struct sdrtype1 *)psensor->i_sdr;
1207 	int		etype;
1208 
1209 	/* Get reading of sensor */
1210 	switch (psensor->i_sensor.type) {
1211 	case SENSOR_TEMP:
1212 		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
1213 		psensor->i_sensor.value += 273150000;
1214 		break;
1215 
1216 	case SENSOR_VOLTS_DC:
1217 		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
1218 		break;
1219 
1220 	case SENSOR_FANRPM:
1221 		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 0);
1222 		if (((s1->units1>>3)&0x7) == 0x3)
1223 			psensor->i_sensor.value *= 60; // RPS -> RPM
1224 		break;
1225 	default:
1226 		break;
1227 	}
1228 
1229 	/* Return Sensor Status */
1230 	etype = (psensor->etype << 8) + psensor->stype;
1231 	switch (etype) {
1232 	case IPMI_SENSOR_TYPE_TEMP:
1233 	case IPMI_SENSOR_TYPE_VOLT:
1234 	case IPMI_SENSOR_TYPE_FAN:
1235 		/* non-recoverable threshold */
1236 		if (reading[2] & ((1 << 5) | (1 << 2)))
1237 			return (SENSOR_S_CRIT);
1238 		/* critical threshold */
1239 		else if (reading[2] & ((1 << 4) | (1 << 1)))
1240 			return (SENSOR_S_CRIT);
1241 		/* non-critical threshold */
1242 		else if (reading[2] & ((1 << 3) | (1 << 0)))
1243 			return (SENSOR_S_WARN);
1244 		break;
1245 
1246 	case IPMI_SENSOR_TYPE_INTRUSION:
1247 		psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
1248 		if (reading[2] & 0x1)
1249 			return (SENSOR_S_CRIT);
1250 		break;
1251 
1252 	case IPMI_SENSOR_TYPE_PWRSUPPLY:
1253 		/* Reading: 1 = present+powered, 0 = otherwise */
1254 		psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
1255 		if (reading[2] & 0x10) {
1256 			/* XXX: Need sysctl type for Power Supply types
1257 			 *   ok: power supply installed && powered
1258 			 * warn: power supply installed && !powered
1259 			 * crit: power supply !installed
1260 			 */
1261 			return (SENSOR_S_CRIT);
1262 		}
1263 		if (reading[2] & 0x08) {
1264 			/* Power supply AC lost */
1265 			return (SENSOR_S_WARN);
1266 		}
1267 		break;
1268 	}
1269 
1270 	return (SENSOR_S_OK);
1271 }
1272 
1273 int
1274 read_sensor(struct ipmi_softc *sc, struct ipmi_sensor *psensor)
1275 {
1276 	struct sdrtype1	*s1 = (struct sdrtype1 *) psensor->i_sdr;
1277 	u_int8_t	data[8];
1278 	int		rv = -1;
1279 
1280 	memset(data, 0, sizeof(data));
1281 	data[0] = psensor->i_num;
1282 
1283 	struct ipmi_cmd	c;
1284 	c.c_sc = sc;
1285 	c.c_rssa = s1->owner_id;
1286 	c.c_rslun = s1->owner_lun;
1287 	c.c_netfn = SE_NETFN;
1288 	c.c_cmd = SE_GET_SENSOR_READING;
1289 	c.c_txlen = 1;
1290 	c.c_maxrxlen = sizeof(data);
1291 	c.c_rxlen = 0;
1292 	c.c_data = data;
1293 	ipmi_cmd(&c);
1294 
1295 	if (c.c_ccode != 0) {
1296 		dbg_printf(1, "sensor reading command for %s failed: %.2x\n",
1297 			psensor->i_sensor.desc, c.c_ccode);
1298 		return (rv);
1299 	}
1300 	dbg_printf(10, "values=%.2x %.2x %.2x %.2x %s\n",
1301 	    data[0],data[1],data[2],data[3], psensor->i_sensor.desc);
1302 	psensor->i_sensor.flags &= ~SENSOR_FINVALID;
1303 	if ((data[1] & IPMI_INVALID_SENSOR) ||
1304 	    ((data[1] & IPMI_DISABLED_SENSOR) == 0 && data[0] == 0))
1305 		psensor->i_sensor.flags |= SENSOR_FINVALID;
1306 	psensor->i_sensor.status = ipmi_sensor_status(sc, psensor, data);
1307 	rv = 0;
1308 	return (rv);
1309 }
1310 
1311 int
1312 ipmi_sensor_type(int type, int ext_type, int entity)
1313 {
1314 	switch (ext_type << 8L | type) {
1315 	case IPMI_SENSOR_TYPE_TEMP:
1316 		return (SENSOR_TEMP);
1317 
1318 	case IPMI_SENSOR_TYPE_VOLT:
1319 		return (SENSOR_VOLTS_DC);
1320 
1321 	case IPMI_SENSOR_TYPE_FAN:
1322 		return (SENSOR_FANRPM);
1323 
1324 	case IPMI_SENSOR_TYPE_PWRSUPPLY:
1325 		if (entity == IPMI_ENTITY_PWRSUPPLY)
1326 			return (SENSOR_INDICATOR);
1327 		break;
1328 
1329 	case IPMI_SENSOR_TYPE_INTRUSION:
1330 		return (SENSOR_INDICATOR);
1331 	}
1332 
1333 	return (-1);
1334 }
1335 
1336 /* Add Sensor to BSD Sysctl interface */
1337 int
1338 add_sdr_sensor(struct ipmi_softc *sc, u_int8_t *psdr, int sdrlen)
1339 {
1340 	int			rc;
1341 	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
1342 	struct sdrtype2		*s2 = (struct sdrtype2 *)psdr;
1343 	char			name[64];
1344 
1345 	switch (s1->sdrhdr.record_type) {
1346 	case IPMI_SDR_TYPEFULL:
1347 		rc = ipmi_sensor_name(name, sizeof(name), s1->typelen,
1348 		    s1->name, sdrlen - (int)offsetof(struct sdrtype1, name));
1349 		if (rc == 0)
1350 			return (0);
1351 		rc = add_child_sensors(sc, psdr, 1, s1->sensor_num,
1352 		    s1->sensor_type, s1->event_code, 0, s1->entity_id, name);
1353 		break;
1354 
1355 	case IPMI_SDR_TYPECOMPACT:
1356 		rc = ipmi_sensor_name(name, sizeof(name), s2->typelen,
1357 		    s2->name, sdrlen - (int)offsetof(struct sdrtype2, name));
1358 		if (rc == 0)
1359 			return (0);
1360 		rc = add_child_sensors(sc, psdr, s2->share1 & 0xF,
1361 		    s2->sensor_num, s2->sensor_type, s2->event_code,
1362 		    s2->share2 & 0x7F, s2->entity_id, name);
1363 		break;
1364 
1365 	default:
1366 		return (0);
1367 	}
1368 
1369 	return rc;
1370 }
1371 
1372 int
1373 add_child_sensors(struct ipmi_softc *sc, u_int8_t *psdr, int count,
1374     int sensor_num, int sensor_type, int ext_type, int sensor_base,
1375     int entity, const char *name)
1376 {
1377 	int			typ, idx;
1378 	struct ipmi_sensor	*psensor;
1379 #ifdef IPMI_DEBUG
1380 	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
1381 #endif
1382 
1383 	typ = ipmi_sensor_type(sensor_type, ext_type, entity);
1384 	if (typ == -1) {
1385 		dbg_printf(5, "Unknown sensor type:%.2x et:%.2x sn:%.2x "
1386 		    "name:%s\n", sensor_type, ext_type, sensor_num, name);
1387 		return 0;
1388 	}
1389 	for (idx = 0; idx < count; idx++) {
1390 		psensor = malloc(sizeof(*psensor), M_DEVBUF, M_NOWAIT | M_ZERO);
1391 		if (psensor == NULL)
1392 			break;
1393 
1394 		/* Initialize BSD Sensor info */
1395 		psensor->i_sdr = psdr;
1396 		psensor->i_num = sensor_num + idx;
1397 		psensor->stype = sensor_type;
1398 		psensor->etype = ext_type;
1399 		psensor->i_sensor.type = typ;
1400 		if (count > 1)
1401 			snprintf(psensor->i_sensor.desc,
1402 			    sizeof(psensor->i_sensor.desc),
1403 			    "%s - %d", name, sensor_base + idx);
1404 		else
1405 			strlcpy(psensor->i_sensor.desc, name,
1406 			    sizeof(psensor->i_sensor.desc));
1407 
1408 		dbg_printf(5, "add sensor:%.4x %.2x:%d ent:%.2x:%.2x %s\n",
1409 		    s1->sdrhdr.record_id, s1->sensor_type,
1410 		    typ, s1->entity_id, s1->entity_instance,
1411 		    psensor->i_sensor.desc);
1412 		if (read_sensor(sc, psensor) == 0) {
1413 			SLIST_INSERT_HEAD(&ipmi_sensor_list, psensor, list);
1414 			sensor_attach(&sc->sc_sensordev, &psensor->i_sensor);
1415 			dbg_printf(5, "	 reading: %lld [%s]\n",
1416 			    psensor->i_sensor.value,
1417 			    psensor->i_sensor.desc);
1418 		} else
1419 			free(psensor, M_DEVBUF, sizeof(*psensor));
1420 	}
1421 
1422 	return (1);
1423 }
1424 
1425 /* Handle IPMI Timer - reread sensor values */
1426 void
1427 ipmi_refresh_sensors(struct ipmi_softc *sc)
1428 {
1429 	if (SLIST_EMPTY(&ipmi_sensor_list))
1430 		return;
1431 
1432 	sc->current_sensor = SLIST_NEXT(sc->current_sensor, list);
1433 	if (sc->current_sensor == NULL)
1434 		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
1435 
1436 	if (read_sensor(sc, sc->current_sensor)) {
1437 		dbg_printf(1, "%s: error reading: %s\n", DEVNAME(sc),
1438 		    sc->current_sensor->i_sensor.desc);
1439 		return;
1440 	}
1441 }
1442 
1443 int
1444 ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
1445 {
1446 	if (sc->sc_if && sc->sc_if->nregs == 0)
1447 		return (0);
1448 
1449 	sc->sc_if = ipmi_get_if(ia->iaa_if_type);
1450 	if (sc->sc_if == NULL)
1451 		return (-1);
1452 
1453 	if (ia->iaa_if_iotype == 'i')
1454 		sc->sc_iot = ia->iaa_iot;
1455 	else
1456 		sc->sc_iot = ia->iaa_memt;
1457 
1458 	sc->sc_if_rev = ia->iaa_if_rev;
1459 	sc->sc_if_iosize = ia->iaa_if_iosize;
1460 	sc->sc_if_iospacing = ia->iaa_if_iospacing;
1461 	if (bus_space_map(sc->sc_iot, ia->iaa_if_iobase,
1462 	    sc->sc_if->nregs * sc->sc_if_iospacing,
1463 	    0, &sc->sc_ioh)) {
1464 		printf("%s: bus_space_map(%lx %lx %x 0 %p) failed\n",
1465 		    DEVNAME(sc),
1466 		    (unsigned long)sc->sc_iot, ia->iaa_if_iobase,
1467 		    sc->sc_if->nregs * sc->sc_if_iospacing, &sc->sc_ioh);
1468 		return (-1);
1469 	}
1470 	return (0);
1471 }
1472 
1473 void
1474 ipmi_unmap_regs(struct ipmi_softc *sc)
1475 {
1476 	if (sc->sc_if->nregs > 0) {
1477 		bus_space_unmap(sc->sc_iot, sc->sc_ioh,
1478 		    sc->sc_if->nregs * sc->sc_if_iospacing);
1479 	}
1480 }
1481 
1482 void
1483 ipmi_poll_thread(void *arg)
1484 {
1485 	struct ipmi_thread	*thread = arg;
1486 	struct ipmi_softc	*sc = thread->sc;
1487 	u_int16_t		rec;
1488 
1489 	/* Scan SDRs, add sensors */
1490 	for (rec = 0; rec != 0xFFFF;) {
1491 		if (get_sdr(sc, rec, &rec)) {
1492 			ipmi_unmap_regs(sc);
1493 			printf("%s: no SDRs IPMI disabled\n", DEVNAME(sc));
1494 			goto done;
1495 		}
1496 		tsleep_nsec(sc, PWAIT, "ipmirun", MSEC_TO_NSEC(1));
1497 	}
1498 
1499 	/* initialize sensor list for thread */
1500 	if (SLIST_EMPTY(&ipmi_sensor_list))
1501 		goto done;
1502 	else
1503 		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
1504 
1505 	strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
1506 	    sizeof(sc->sc_sensordev.xname));
1507 	sensordev_install(&sc->sc_sensordev);
1508 
1509 	while (thread->running) {
1510 		ipmi_refresh_sensors(sc);
1511 		tsleep_nsec(thread, PWAIT, "ipmi_poll",
1512 		    SEC_TO_NSEC(SENSOR_REFRESH_RATE));
1513 	}
1514 
1515 done:
1516 	kthread_exit(0);
1517 }
1518 
1519 void
1520 ipmi_create_thread(void *arg)
1521 {
1522 	struct ipmi_softc	*sc = arg;
1523 
1524 	if (kthread_create(ipmi_poll_thread, sc->sc_thread, NULL,
1525 	    DEVNAME(sc)) != 0) {
1526 		printf("%s: unable to create run thread, ipmi disabled\n",
1527 		    DEVNAME(sc));
1528 		return;
1529 	}
1530 }
1531 
1532 void
1533 ipmi_attach_common(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
1534 {
1535 	struct ipmi_cmd		*c = &sc->sc_ioctl.cmd;
1536 
1537 	/* Map registers */
1538 	ipmi_map_regs(sc, ia);
1539 
1540 	sc->sc_thread = malloc(sizeof(struct ipmi_thread), M_DEVBUF, M_NOWAIT);
1541 	if (sc->sc_thread == NULL) {
1542 		printf(": unable to allocate thread\n");
1543 		return;
1544 	}
1545 	sc->sc_thread->sc = sc;
1546 	sc->sc_thread->running = 1;
1547 
1548 	/* Setup threads */
1549 	kthread_create_deferred(ipmi_create_thread, sc);
1550 
1551 	printf(": version %d.%d interface %s",
1552 	    ia->iaa_if_rev >> 4, ia->iaa_if_rev & 0xF, sc->sc_if->name);
1553 	if (sc->sc_if->nregs > 0)
1554 		printf(" %sbase 0x%lx/%x spacing %d",
1555 		    ia->iaa_if_iotype == 'i' ? "io" : "mem", ia->iaa_if_iobase,
1556 		    ia->iaa_if_iospacing * sc->sc_if->nregs,
1557 		    ia->iaa_if_iospacing);
1558 	if (ia->iaa_if_irq != -1)
1559 		printf(" irq %d", ia->iaa_if_irq);
1560 	printf("\n");
1561 
1562 	/* setup flag to exclude iic */
1563 	ipmi_enabled = 1;
1564 
1565 	/* Setup Watchdog timer */
1566 	sc->sc_wdog_period = 0;
1567 	task_set(&sc->sc_wdog_tickle_task, ipmi_watchdog_tickle, sc);
1568 	wdog_register(ipmi_watchdog, sc);
1569 
1570 	rw_init(&sc->sc_ioctl.lock, DEVNAME(sc));
1571 	sc->sc_ioctl.req.msgid = -1;
1572 	c->c_sc = sc;
1573 	c->c_ccode = -1;
1574 
1575 	sc->sc_cmd_taskq = taskq_create("ipmicmd", 1, IPL_NONE, TASKQ_MPSAFE);
1576 }
1577 
1578 int
1579 ipmi_activate(struct device *self, int act)
1580 {
1581 	switch (act) {
1582 	case DVACT_POWERDOWN:
1583 		wdog_shutdown(self);
1584 		break;
1585 	}
1586 
1587 	return (0);
1588 }
1589 
1590 struct ipmi_softc *
1591 ipmilookup(dev_t dev)
1592 {
1593 	return (struct ipmi_softc *)device_lookup(&ipmi_cd, minor(dev));
1594 }
1595 
1596 int
1597 ipmiopen(dev_t dev, int flags, int mode, struct proc *p)
1598 {
1599 	struct ipmi_softc	*sc = ipmilookup(dev);
1600 
1601 	if (sc == NULL)
1602 		return (ENXIO);
1603 	return (0);
1604 }
1605 
1606 int
1607 ipmiclose(dev_t dev, int flags, int mode, struct proc *p)
1608 {
1609 	struct ipmi_softc	*sc = ipmilookup(dev);
1610 
1611 	if (sc == NULL)
1612 		return (ENXIO);
1613 	return (0);
1614 }
1615 
1616 int
1617 ipmiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc)
1618 {
1619 	struct ipmi_softc	*sc = ipmilookup(dev);
1620 	struct ipmi_req		*req = (struct ipmi_req *)data;
1621 	struct ipmi_recv	*recv = (struct ipmi_recv *)data;
1622 	struct ipmi_cmd		*c = &sc->sc_ioctl.cmd;
1623 	int			iv;
1624 	int			len;
1625 	u_char			ccode;
1626 	int			rc = 0;
1627 
1628 	if (sc == NULL)
1629 		return (ENXIO);
1630 
1631 	rw_enter_write(&sc->sc_ioctl.lock);
1632 
1633 	c->c_maxrxlen = sizeof(sc->sc_ioctl.buf);
1634 	c->c_data = sc->sc_ioctl.buf;
1635 
1636 	switch (cmd) {
1637 	case IPMICTL_SEND_COMMAND:
1638 		if (req->msgid == -1) {
1639 			rc = EINVAL;
1640 			goto reset;
1641 		}
1642 		if (sc->sc_ioctl.req.msgid != -1) {
1643 			rc = EBUSY;
1644 			goto reset;
1645 		}
1646 		len = req->msg.data_len;
1647 		if (len < 0) {
1648 			rc = EINVAL;
1649 			goto reset;
1650 		}
1651 		if (len > c->c_maxrxlen) {
1652 			rc = E2BIG;
1653 			goto reset;
1654 		}
1655 		sc->sc_ioctl.req = *req;
1656 		c->c_ccode = -1;
1657 		rc = copyin(req->msg.data, c->c_data, len);
1658 		if (rc != 0)
1659 			goto reset;
1660 		KASSERT(c->c_ccode == -1);
1661 
1662 		/* Execute a command synchronously. */
1663 		c->c_netfn = req->msg.netfn;
1664 		c->c_cmd = req->msg.cmd;
1665 		c->c_txlen = req->msg.data_len;
1666 		c->c_rxlen = 0;
1667 		ipmi_cmd(c);
1668 		break;
1669 	case IPMICTL_RECEIVE_MSG_TRUNC:
1670 	case IPMICTL_RECEIVE_MSG:
1671 		if (sc->sc_ioctl.req.msgid == -1) {
1672 			rc = EINVAL;
1673 			goto reset;
1674 		}
1675 		if (c->c_ccode == -1) {
1676 			rc = EAGAIN;
1677 			goto reset;
1678 		}
1679 		ccode = c->c_ccode & 0xff;
1680 		rc = copyout(&ccode, recv->msg.data, 1);
1681 		if (rc != 0)
1682 			goto reset;
1683 
1684 		/* Return a command result. */
1685 		recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
1686 		recv->msgid = sc->sc_ioctl.req.msgid;
1687 		recv->msg.netfn = sc->sc_ioctl.req.msg.netfn;
1688 		recv->msg.cmd = sc->sc_ioctl.req.msg.cmd;
1689 		recv->msg.data_len = c->c_rxlen + 1;
1690 
1691 		rc = copyout(c->c_data, recv->msg.data + 1, c->c_rxlen);
1692 		/* Always reset state after command completion. */
1693 		goto reset;
1694 	case IPMICTL_SET_MY_ADDRESS_CMD:
1695 		iv = *(int *)data;
1696 		if (iv < 0 || iv > RSSA_MASK) {
1697 			rc = EINVAL;
1698 			goto reset;
1699 		}
1700 		c->c_rssa = iv;
1701 		break;
1702 	case IPMICTL_GET_MY_ADDRESS_CMD:
1703 		*(int *)data = c->c_rssa;
1704 		break;
1705 	case IPMICTL_SET_MY_LUN_CMD:
1706 		iv = *(int *)data;
1707 		if (iv < 0 || iv > LUN_MASK) {
1708 			rc = EINVAL;
1709 			goto reset;
1710 		}
1711 		c->c_rslun = iv;
1712 		break;
1713 	case IPMICTL_GET_MY_LUN_CMD:
1714 		*(int *)data = c->c_rslun;
1715 		break;
1716 	case IPMICTL_SET_GETS_EVENTS_CMD:
1717 		break;
1718 	case IPMICTL_REGISTER_FOR_CMD:
1719 	case IPMICTL_UNREGISTER_FOR_CMD:
1720 	default:
1721 		break;
1722 	}
1723 done:
1724 	rw_exit_write(&sc->sc_ioctl.lock);
1725 	return (rc);
1726 reset:
1727 	sc->sc_ioctl.req.msgid = -1;
1728 	c->c_ccode = -1;
1729 	goto done;
1730 }
1731 
1732 #define		MIN_PERIOD	10
1733 
1734 int
1735 ipmi_watchdog(void *arg, int period)
1736 {
1737 	struct ipmi_softc	*sc = arg;
1738 
1739 	if (sc->sc_wdog_period == period) {
1740 		if (period != 0) {
1741 			struct task *t;
1742 			int res;
1743 
1744 			t = &sc->sc_wdog_tickle_task;
1745 			(void)task_del(systq, t);
1746 			res = task_add(systq, t);
1747 			KASSERT(res == 1);
1748 		}
1749 		return (period);
1750 	}
1751 
1752 	if (period < MIN_PERIOD && period > 0)
1753 		period = MIN_PERIOD;
1754 	sc->sc_wdog_period = period;
1755 	ipmi_watchdog_set(sc);
1756 	printf("%s: watchdog %sabled\n", DEVNAME(sc),
1757 	    (period == 0) ? "dis" : "en");
1758 	return (period);
1759 }
1760 
1761 void
1762 ipmi_watchdog_tickle(void *arg)
1763 {
1764 	struct ipmi_softc	*sc = arg;
1765 	struct ipmi_cmd		c;
1766 
1767 	c.c_sc = sc;
1768 	c.c_rssa = BMC_SA;
1769 	c.c_rslun = BMC_LUN;
1770 	c.c_netfn = APP_NETFN;
1771 	c.c_cmd = APP_RESET_WATCHDOG;
1772 	c.c_txlen = 0;
1773 	c.c_maxrxlen = 0;
1774 	c.c_rxlen = 0;
1775 	c.c_data = NULL;
1776 	ipmi_cmd(&c);
1777 }
1778 
1779 void
1780 ipmi_watchdog_set(void *arg)
1781 {
1782 	struct ipmi_softc	*sc = arg;
1783 	uint8_t			wdog[IPMI_GET_WDOG_MAX];
1784 	struct ipmi_cmd		c;
1785 
1786 	c.c_sc = sc;
1787 	c.c_rssa = BMC_SA;
1788 	c.c_rslun = BMC_LUN;
1789 	c.c_netfn = APP_NETFN;
1790 	c.c_cmd = APP_GET_WATCHDOG_TIMER;
1791 	c.c_txlen = 0;
1792 	c.c_maxrxlen = IPMI_GET_WDOG_MAX;
1793 	c.c_rxlen = 0;
1794 	c.c_data = wdog;
1795 	ipmi_cmd(&c);
1796 
1797 	/* Period is 10ths/sec */
1798 	uint16_t timo = htole16(sc->sc_wdog_period * 10);
1799 
1800 	memcpy(&wdog[IPMI_SET_WDOG_TIMOL], &timo, 2);
1801 	wdog[IPMI_SET_WDOG_TIMER] &= ~IPMI_WDOG_DONTSTOP;
1802 	wdog[IPMI_SET_WDOG_TIMER] |= (sc->sc_wdog_period == 0) ?
1803 	    0 : IPMI_WDOG_DONTSTOP;
1804 	wdog[IPMI_SET_WDOG_ACTION] &= ~IPMI_WDOG_MASK;
1805 	wdog[IPMI_SET_WDOG_ACTION] |= (sc->sc_wdog_period == 0) ?
1806 	    IPMI_WDOG_DISABLED : IPMI_WDOG_REBOOT;
1807 
1808 	c.c_cmd = APP_SET_WATCHDOG_TIMER;
1809 	c.c_txlen = IPMI_SET_WDOG_MAX;
1810 	c.c_maxrxlen = 0;
1811 	c.c_rxlen = 0;
1812 	c.c_data = wdog;
1813 	ipmi_cmd(&c);
1814 }
1815 
1816 #if defined(__amd64__) || defined(__i386__)
1817 
1818 #include <dev/isa/isareg.h>
1819 #include <dev/isa/isavar.h>
1820 
1821 /*
1822  * Format of SMBIOS IPMI Flags
1823  *
1824  * bit0: interrupt trigger mode (1=level, 0=edge)
1825  * bit1: interrupt polarity (1=active high, 0=active low)
1826  * bit2: reserved
1827  * bit3: address LSB (1=odd,0=even)
1828  * bit4: interrupt (1=specified, 0=not specified)
1829  * bit5: reserved
1830  * bit6/7: register spacing (1,4,2,err)
1831  */
1832 #define SMIPMI_FLAG_IRQLVL		(1L << 0)
1833 #define SMIPMI_FLAG_IRQEN		(1L << 3)
1834 #define SMIPMI_FLAG_ODDOFFSET		(1L << 4)
1835 #define SMIPMI_FLAG_IFSPACING(x)	(((x)>>6)&0x3)
1836 #define	 IPMI_IOSPACING_BYTE		 0
1837 #define	 IPMI_IOSPACING_WORD		 2
1838 #define	 IPMI_IOSPACING_DWORD		 1
1839 
1840 struct dmd_ipmi {
1841 	u_int8_t	dmd_sig[4];		/* Signature 'IPMI' */
1842 	u_int8_t	dmd_i2c_address;	/* Address of BMC */
1843 	u_int8_t	dmd_nvram_address;	/* Address of NVRAM */
1844 	u_int8_t	dmd_if_type;		/* IPMI Interface Type */
1845 	u_int8_t	dmd_if_rev;		/* IPMI Interface Revision */
1846 } __packed;
1847 
1848 void	*scan_sig(long, long, int, int, const void *);
1849 
1850 void	ipmi_smbios_probe(struct smbios_ipmi *, struct ipmi_attach_args *);
1851 int	ipmi_match(struct device *, void *, void *);
1852 void	ipmi_attach(struct device *, struct device *, void *);
1853 
1854 struct cfattach ipmi_ca = {
1855 	sizeof(struct ipmi_softc), ipmi_match, ipmi_attach,
1856 	NULL, ipmi_activate
1857 };
1858 
1859 int
1860 ipmi_match(struct device *parent, void *match, void *aux)
1861 {
1862 	struct ipmi_softc	*sc;
1863 	struct ipmi_attach_args *ia = aux;
1864 	struct cfdata		*cf = match;
1865 	u_int8_t		cmd[32];
1866 	int			rv = 0;
1867 
1868 	if (strcmp(ia->iaa_name, cf->cf_driver->cd_name))
1869 		return (0);
1870 
1871 	/* XXX local softc is wrong wrong wrong */
1872 	sc = malloc(sizeof(*sc), M_TEMP, M_WAITOK | M_ZERO);
1873 	strlcpy(sc->sc_dev.dv_xname, "ipmi0", sizeof(sc->sc_dev.dv_xname));
1874 
1875 	/* Map registers */
1876 	if (ipmi_map_regs(sc, ia) == 0) {
1877 		sc->sc_if->probe(sc);
1878 
1879 		/* Identify BMC device early to detect lying bios */
1880 		struct ipmi_cmd c;
1881 		c.c_sc = sc;
1882 		c.c_rssa = BMC_SA;
1883 		c.c_rslun = BMC_LUN;
1884 		c.c_netfn = APP_NETFN;
1885 		c.c_cmd = APP_GET_DEVICE_ID;
1886 		c.c_txlen = 0;
1887 		c.c_maxrxlen = sizeof(cmd);
1888 		c.c_rxlen = 0;
1889 		c.c_data = cmd;
1890 		ipmi_cmd(&c);
1891 
1892 		dbg_dump(1, "bmc data", c.c_rxlen, cmd);
1893 		rv = 1; /* GETID worked, we got IPMI */
1894 		ipmi_unmap_regs(sc);
1895 	}
1896 
1897 	free(sc, M_TEMP, sizeof(*sc));
1898 
1899 	return (rv);
1900 }
1901 
1902 void
1903 ipmi_attach(struct device *parent, struct device *self, void *aux)
1904 {
1905 	ipmi_attach_common((struct ipmi_softc *)self, aux);
1906 }
1907 
1908 /* Scan memory for signature */
1909 void *
1910 scan_sig(long start, long end, int skip, int len, const void *data)
1911 {
1912 	void *va;
1913 
1914 	while (start < end) {
1915 		va = ISA_HOLE_VADDR(start);
1916 		if (memcmp(va, data, len) == 0)
1917 			return (va);
1918 
1919 		start += skip;
1920 	}
1921 
1922 	return (NULL);
1923 }
1924 
1925 void
1926 ipmi_smbios_probe(struct smbios_ipmi *pipmi, struct ipmi_attach_args *ia)
1927 {
1928 
1929 	dbg_printf(1, "ipmi_smbios_probe: %02x %02x %02x %02x %08llx %02x "
1930 	    "%02x\n",
1931 	    pipmi->smipmi_if_type,
1932 	    pipmi->smipmi_if_rev,
1933 	    pipmi->smipmi_i2c_address,
1934 	    pipmi->smipmi_nvram_address,
1935 	    pipmi->smipmi_base_address,
1936 	    pipmi->smipmi_base_flags,
1937 	    pipmi->smipmi_irq);
1938 
1939 	ia->iaa_if_type = pipmi->smipmi_if_type;
1940 	ia->iaa_if_rev = pipmi->smipmi_if_rev;
1941 	ia->iaa_if_irq = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQEN) ?
1942 	    pipmi->smipmi_irq : -1;
1943 	ia->iaa_if_irqlvl = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQLVL) ?
1944 	    IST_LEVEL : IST_EDGE;
1945 	ia->iaa_if_iosize = 1;
1946 
1947 	switch (SMIPMI_FLAG_IFSPACING(pipmi->smipmi_base_flags)) {
1948 	case IPMI_IOSPACING_BYTE:
1949 		ia->iaa_if_iospacing = 1;
1950 		break;
1951 
1952 	case IPMI_IOSPACING_DWORD:
1953 		ia->iaa_if_iospacing = 4;
1954 		break;
1955 
1956 	case IPMI_IOSPACING_WORD:
1957 		ia->iaa_if_iospacing = 2;
1958 		break;
1959 
1960 	default:
1961 		ia->iaa_if_iospacing = 1;
1962 		printf("ipmi: unknown register spacing\n");
1963 	}
1964 
1965 	/* Calculate base address (PCI BAR format) */
1966 	if (pipmi->smipmi_base_address & 0x1) {
1967 		ia->iaa_if_iotype = 'i';
1968 		ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0x1;
1969 	} else {
1970 		ia->iaa_if_iotype = 'm';
1971 		ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0xF;
1972 	}
1973 	if (pipmi->smipmi_base_flags & SMIPMI_FLAG_ODDOFFSET)
1974 		ia->iaa_if_iobase++;
1975 
1976 	if (pipmi->smipmi_base_flags == 0x7f) {
1977 		/* IBM 325 eServer workaround */
1978 		ia->iaa_if_iospacing = 1;
1979 		ia->iaa_if_iobase = pipmi->smipmi_base_address;
1980 		ia->iaa_if_iotype = 'i';
1981 		return;
1982 	}
1983 }
1984 
1985 int
1986 ipmi_probe(void *aux)
1987 {
1988 	struct ipmi_attach_args *ia = aux;
1989 	struct dmd_ipmi *pipmi;
1990 	struct smbtable tbl;
1991 
1992 	tbl.cookie = 0;
1993 	if (smbios_find_table(SMBIOS_TYPE_IPMIDEV, &tbl))
1994 		ipmi_smbios_probe(tbl.tblhdr, ia);
1995 	else {
1996 		pipmi = (struct dmd_ipmi *)scan_sig(0xC0000L, 0xFFFFFL, 16, 4,
1997 		    "IPMI");
1998 		/* XXX hack to find Dell PowerEdge 8450 */
1999 		if (pipmi == NULL) {
2000 			/* no IPMI found */
2001 			return (0);
2002 		}
2003 
2004 		/* we have an IPMI signature, fill in attach arg structure */
2005 		ia->iaa_if_type = pipmi->dmd_if_type;
2006 		ia->iaa_if_rev = pipmi->dmd_if_rev;
2007 	}
2008 
2009 	return (1);
2010 }
2011 
2012 #endif
2013