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