1/*	$OpenBSD: ipmi.c,v 1.119 2024/04/03 18:32:47 gkoehler 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
47struct 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
56int	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/* IPMI 2.0, Table 42-3: Sensor Type Codes */
71#define IPMI_SENSOR_TYPE_TEMP		0x0101
72#define IPMI_SENSOR_TYPE_VOLT		0x0102
73#define IPMI_SENSOR_TYPE_CURRENT	0x0103
74#define IPMI_SENSOR_TYPE_FAN		0x0104
75#define IPMI_SENSOR_TYPE_INTRUSION	0x6F05
76#define IPMI_SENSOR_TYPE_PWRSUPPLY	0x6F08
77
78/* IPMI 2.0, Table 43-15: Sensor Unit Type Codes */
79#define IPMI_UNIT_TYPE_DEGREE_C		1
80#define IPMI_UNIT_TYPE_DEGREE_F		2
81#define IPMI_UNIT_TYPE_DEGREE_K		3
82#define IPMI_UNIT_TYPE_VOLTS		4
83#define IPMI_UNIT_TYPE_AMPS		5
84#define IPMI_UNIT_TYPE_WATTS		6
85#define IPMI_UNIT_TYPE_RPM		18
86
87#define IPMI_NAME_UNICODE		0x00
88#define IPMI_NAME_BCDPLUS		0x01
89#define IPMI_NAME_ASCII6BIT		0x02
90#define IPMI_NAME_ASCII8BIT		0x03
91
92#define IPMI_ENTITY_PWRSUPPLY		0x0A
93
94#define IPMI_INVALID_SENSOR		(1L << 5)
95#define IPMI_DISABLED_SENSOR		(1L << 6)
96
97#define IPMI_SDR_TYPEFULL		1
98#define IPMI_SDR_TYPECOMPACT		2
99
100#define byteof(x) ((x) >> 3)
101#define bitof(x)  (1L << ((x) & 0x7))
102#define TB(b,m)	  (data[2+byteof(b)] & bitof(b))
103
104#ifdef IPMI_DEBUG
105int	ipmi_dbg = 0;
106#define dbg_printf(lvl, fmt...) \
107	if (ipmi_dbg >= lvl) \
108		printf(fmt);
109#define dbg_dump(lvl, msg, len, buf) \
110	if (len && ipmi_dbg >= lvl) \
111		dumpb(msg, len, (const u_int8_t *)(buf));
112#else
113#define dbg_printf(lvl, fmt...)
114#define dbg_dump(lvl, msg, len, buf)
115#endif
116
117long signextend(unsigned long, int);
118
119SLIST_HEAD(ipmi_sensors_head, ipmi_sensor);
120struct ipmi_sensors_head ipmi_sensor_list =
121    SLIST_HEAD_INITIALIZER(ipmi_sensor_list);
122
123void	dumpb(const char *, int, const u_int8_t *);
124
125int	read_sensor(struct ipmi_softc *, struct ipmi_sensor *);
126int	add_sdr_sensor(struct ipmi_softc *, u_int8_t *, int);
127int	get_sdr_partial(struct ipmi_softc *, u_int16_t, u_int16_t,
128	    u_int8_t, u_int8_t, void *, u_int16_t *);
129int	get_sdr(struct ipmi_softc *, u_int16_t, u_int16_t *);
130
131int	ipmi_sendcmd(struct ipmi_cmd *);
132int	ipmi_recvcmd(struct ipmi_cmd *);
133void	ipmi_cmd(struct ipmi_cmd *);
134void	ipmi_cmd_poll(struct ipmi_cmd *);
135void	ipmi_cmd_wait(struct ipmi_cmd *);
136void	ipmi_cmd_wait_cb(void *);
137
138int	ipmi_watchdog(void *, int);
139void	ipmi_watchdog_tickle(void *);
140void	ipmi_watchdog_set(void *);
141
142struct ipmi_softc *ipmilookup(dev_t dev);
143
144int	ipmiopen(dev_t, int, int, struct proc *);
145int	ipmiclose(dev_t, int, int, struct proc *);
146int	ipmiioctl(dev_t, u_long, caddr_t, int, struct proc *);
147
148long	ipow(long, int);
149long	ipmi_convert(u_int8_t, struct sdrtype1 *, long);
150int	ipmi_sensor_name(char *, int, u_int8_t, u_int8_t *, int);
151
152/* BMC Helper Functions */
153u_int8_t bmc_read(struct ipmi_softc *, int);
154void	bmc_write(struct ipmi_softc *, int, u_int8_t);
155int	bmc_io_wait(struct ipmi_softc *, struct ipmi_iowait *);
156
157void	bt_buildmsg(struct ipmi_cmd *);
158void	cmn_buildmsg(struct ipmi_cmd *);
159
160int	getbits(u_int8_t *, int, int);
161int	ipmi_sensor_type(int, int, int, int);
162
163void	ipmi_refresh_sensors(struct ipmi_softc *sc);
164int	ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia);
165void	ipmi_unmap_regs(struct ipmi_softc *);
166
167int	ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *,
168    u_int8_t *);
169
170int	 add_child_sensors(struct ipmi_softc *, u_int8_t *, int, int, int,
171    int, int, int, const char *);
172
173void	ipmi_create_thread(void *);
174void	ipmi_poll_thread(void *);
175
176int	kcs_probe(struct ipmi_softc *);
177int	kcs_reset(struct ipmi_softc *);
178int	kcs_sendmsg(struct ipmi_cmd *);
179int	kcs_recvmsg(struct ipmi_cmd *);
180
181int	bt_probe(struct ipmi_softc *);
182int	bt_reset(struct ipmi_softc *);
183int	bt_sendmsg(struct ipmi_cmd *);
184int	bt_recvmsg(struct ipmi_cmd *);
185
186int	smic_probe(struct ipmi_softc *);
187int	smic_reset(struct ipmi_softc *);
188int	smic_sendmsg(struct ipmi_cmd *);
189int	smic_recvmsg(struct ipmi_cmd *);
190
191struct ipmi_if kcs_if = {
192	"KCS",
193	IPMI_IF_KCS_NREGS,
194	cmn_buildmsg,
195	kcs_sendmsg,
196	kcs_recvmsg,
197	kcs_reset,
198	kcs_probe,
199	IPMI_MSG_DATASND,
200	IPMI_MSG_DATARCV,
201};
202
203struct ipmi_if smic_if = {
204	"SMIC",
205	IPMI_IF_SMIC_NREGS,
206	cmn_buildmsg,
207	smic_sendmsg,
208	smic_recvmsg,
209	smic_reset,
210	smic_probe,
211	IPMI_MSG_DATASND,
212	IPMI_MSG_DATARCV,
213};
214
215struct ipmi_if bt_if = {
216	"BT",
217	IPMI_IF_BT_NREGS,
218	bt_buildmsg,
219	bt_sendmsg,
220	bt_recvmsg,
221	bt_reset,
222	bt_probe,
223	IPMI_BTMSG_DATASND,
224	IPMI_BTMSG_DATARCV,
225};
226
227struct ipmi_if *ipmi_get_if(int);
228
229struct ipmi_if *
230ipmi_get_if(int iftype)
231{
232	switch (iftype) {
233	case IPMI_IF_KCS:
234		return (&kcs_if);
235	case IPMI_IF_SMIC:
236		return (&smic_if);
237	case IPMI_IF_BT:
238		return (&bt_if);
239	}
240
241	return (NULL);
242}
243
244/*
245 * BMC Helper Functions
246 */
247u_int8_t
248bmc_read(struct ipmi_softc *sc, int offset)
249{
250	if (sc->sc_if_iosize == 4)
251		return (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
252		    offset * sc->sc_if_iospacing));
253	else
254		return (bus_space_read_1(sc->sc_iot, sc->sc_ioh,
255		    offset * sc->sc_if_iospacing));
256}
257
258void
259bmc_write(struct ipmi_softc *sc, int offset, u_int8_t val)
260{
261	if (sc->sc_if_iosize == 4)
262		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
263		    offset * sc->sc_if_iospacing, val);
264	else
265		bus_space_write_1(sc->sc_iot, sc->sc_ioh,
266		    offset * sc->sc_if_iospacing, val);
267}
268
269int
270bmc_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
316int bt_read(struct ipmi_softc *, int);
317int bt_write(struct ipmi_softc *, int, uint8_t);
318
319int
320bt_read(struct ipmi_softc *sc, int reg)
321{
322	return bmc_read(sc, reg);
323}
324
325int
326bt_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
341int
342bt_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
363int
364bt_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
392int
393bt_reset(struct ipmi_softc *sc)
394{
395	return (-1);
396}
397
398int
399bt_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
458int	smic_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
459int	smic_write_cmd_data(struct ipmi_softc *, u_int8_t, const u_int8_t *);
460int	smic_read_data(struct ipmi_softc *, u_int8_t *);
461
462int
463smic_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
483int
484smic_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
505int
506smic_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
521int
522smic_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
543int
544smic_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
575int
576smic_reset(struct ipmi_softc *sc)
577{
578	return (-1);
579}
580
581int
582smic_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
616int	kcs_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *);
617int	kcs_write_cmd(struct ipmi_softc *, u_int8_t);
618int	kcs_write_data(struct ipmi_softc *, u_int8_t);
619int	kcs_read_data(struct ipmi_softc *, u_int8_t *);
620
621int
622kcs_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
651int
652kcs_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
661int
662kcs_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
671int
672kcs_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 */
690int
691kcs_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
717int
718kcs_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
740int
741kcs_reset(struct ipmi_softc *sc)
742{
743	return (-1);
744}
745
746int
747kcs_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
796struct 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
805struct ipmi_response {
806	u_int8_t	cCode;
807	u_int8_t	data_len;
808	u_int8_t	*data;
809};
810
811struct 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
818struct 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
826struct cfdriver ipmi_cd = {
827	NULL, "ipmi", DV_DULL
828};
829
830void
831dumpb(const char *lbl, int len, const u_int8_t *data)
832{
833	int idx;
834
835	printf("%s: ", lbl);
836	for (idx = 0; idx < len; idx++)
837		printf("%.2x ", data[idx]);
838
839	printf("\n");
840}
841
842/*
843 * bt_buildmsg builds an IPMI message from a nfLun, cmd, and data
844 * This is used by BT protocol
845 */
846void
847bt_buildmsg(struct ipmi_cmd *c)
848{
849	struct ipmi_softc *sc = c->c_sc;
850	u_int8_t *buf = sc->sc_buf;
851
852	buf[IPMI_BTMSG_LEN] = c->c_txlen + (IPMI_BTMSG_DATASND - 1);
853	buf[IPMI_BTMSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
854	buf[IPMI_BTMSG_SEQ] = sc->sc_btseq++;
855	buf[IPMI_BTMSG_CMD] = c->c_cmd;
856	if (c->c_txlen && c->c_data)
857		memcpy(buf + IPMI_BTMSG_DATASND, c->c_data, c->c_txlen);
858}
859
860/*
861 * cmn_buildmsg builds an IPMI message from a nfLun, cmd, and data
862 * This is used by both SMIC and KCS protocols
863 */
864void
865cmn_buildmsg(struct ipmi_cmd *c)
866{
867	struct ipmi_softc *sc = c->c_sc;
868	u_int8_t *buf = sc->sc_buf;
869
870	buf[IPMI_MSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun);
871	buf[IPMI_MSG_CMD] = c->c_cmd;
872	if (c->c_txlen && c->c_data)
873		memcpy(buf + IPMI_MSG_DATASND, c->c_data, c->c_txlen);
874}
875
876/* Send an IPMI command */
877int
878ipmi_sendcmd(struct ipmi_cmd *c)
879{
880	struct ipmi_softc	*sc = c->c_sc;
881	int		rc = -1;
882
883	dbg_printf(50, "ipmi_sendcmd: rssa=%.2x nfln=%.2x cmd=%.2x len=%.2x\n",
884	    c->c_rssa, NETFN_LUN(c->c_netfn, c->c_rslun), c->c_cmd, c->c_txlen);
885	dbg_dump(10, " send", c->c_txlen, c->c_data);
886	if (c->c_rssa != BMC_SA) {
887#if 0
888		sc->sc_if->buildmsg(c);
889		pI2C->bus = (sc->if_ver == 0x09) ?
890		    PUBLIC_BUS :
891		    IPMB_CHANNEL_NUMBER;
892
893		imbreq->rsSa = rssa;
894		imbreq->nfLn = NETFN_LUN(netfn, rslun);
895		imbreq->cSum1 = -(imbreq->rsSa + imbreq->nfLn);
896		imbreq->rqSa = BMC_SA;
897		imbreq->seqLn = NETFN_LUN(sc->imb_seq++, SMS_LUN);
898		imbreq->cmd = cmd;
899		if (txlen)
900			memcpy(imbreq->data, data, txlen);
901		/* Set message checksum */
902		imbreq->data[txlen] = cksum8(&imbreq->rqSa, txlen + 3);
903#endif
904		goto done;
905	} else
906		sc->sc_if->buildmsg(c);
907
908	c->c_txlen += sc->sc_if->datasnd;
909	rc = sc->sc_if->sendmsg(c);
910
911done:
912	return (rc);
913}
914
915/* Receive an IPMI command */
916int
917ipmi_recvcmd(struct ipmi_cmd *c)
918{
919	struct ipmi_softc *sc = c->c_sc;
920	u_int8_t	*buf = sc->sc_buf, rc = 0;
921
922	/* Receive message from interface, copy out result data */
923	c->c_maxrxlen += sc->sc_if->datarcv;
924	if (sc->sc_if->recvmsg(c) ||
925	    c->c_rxlen < sc->sc_if->datarcv) {
926		return (-1);
927	}
928
929	c->c_rxlen -= sc->sc_if->datarcv;
930	if (c->c_rxlen > 0 && c->c_data)
931		memcpy(c->c_data, buf + sc->sc_if->datarcv, c->c_rxlen);
932
933	rc = buf[IPMI_MSG_CCODE];
934#ifdef IPMI_DEBUG
935	if (rc != 0)
936		dbg_printf(1, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x\n",
937		    buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE]);
938#endif
939
940	dbg_printf(50, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x len=%.2x\n",
941	    buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE],
942	    c->c_rxlen);
943	dbg_dump(10, " recv", c->c_rxlen, c->c_data);
944
945	return (rc);
946}
947
948void
949ipmi_cmd(struct ipmi_cmd *c)
950{
951	if (cold || panicstr != NULL)
952		ipmi_cmd_poll(c);
953	else
954		ipmi_cmd_wait(c);
955}
956
957void
958ipmi_cmd_poll(struct ipmi_cmd *c)
959{
960	if ((c->c_ccode = ipmi_sendcmd(c)))
961		printf("%s: sendcmd fails\n", DEVNAME(c->c_sc));
962	else
963		c->c_ccode = ipmi_recvcmd(c);
964}
965
966void
967ipmi_cmd_wait(struct ipmi_cmd *c)
968{
969	struct task t;
970	int res;
971
972	task_set(&t, ipmi_cmd_wait_cb, c);
973	res = task_add(c->c_sc->sc_cmd_taskq, &t);
974	KASSERT(res == 1);
975
976	tsleep_nsec(c, PWAIT, "ipmicmd", INFSLP);
977
978	res = task_del(c->c_sc->sc_cmd_taskq, &t);
979	KASSERT(res == 0);
980}
981
982void
983ipmi_cmd_wait_cb(void *arg)
984{
985	struct ipmi_cmd *c = arg;
986
987	ipmi_cmd_poll(c);
988	wakeup(c);
989}
990
991/* Read a partial SDR entry */
992int
993get_sdr_partial(struct ipmi_softc *sc, u_int16_t recordId, u_int16_t reserveId,
994    u_int8_t offset, u_int8_t length, void *buffer, u_int16_t *nxtRecordId)
995{
996	u_int8_t	cmd[IPMI_GET_WDOG_MAX + 255];	/* 8 + max of length */
997	int		len;
998
999	((u_int16_t *) cmd)[0] = reserveId;
1000	((u_int16_t *) cmd)[1] = recordId;
1001	cmd[4] = offset;
1002	cmd[5] = length;
1003
1004	struct ipmi_cmd	c;
1005	c.c_sc = sc;
1006	c.c_rssa = BMC_SA;
1007	c.c_rslun = BMC_LUN;
1008	c.c_netfn = STORAGE_NETFN;
1009	c.c_cmd = STORAGE_GET_SDR;
1010	c.c_txlen = IPMI_SET_WDOG_MAX;
1011	c.c_rxlen = 0;
1012	c.c_maxrxlen = 8 + length;
1013	c.c_data = cmd;
1014	ipmi_cmd(&c);
1015	len = c.c_rxlen;
1016
1017	if (nxtRecordId)
1018		*nxtRecordId = *(uint16_t *) cmd;
1019	if (len > 2)
1020		memcpy(buffer, cmd + 2, len - 2);
1021	else
1022		return (1);
1023
1024	return (0);
1025}
1026
1027int maxsdrlen = 0x10;
1028
1029/* Read an entire SDR; pass to add sensor */
1030int
1031get_sdr(struct ipmi_softc *sc, u_int16_t recid, u_int16_t *nxtrec)
1032{
1033	u_int16_t	resid = 0;
1034	int		len, sdrlen, offset;
1035	u_int8_t	*psdr;
1036	struct sdrhdr	shdr;
1037
1038	/* Reserve SDR */
1039	struct ipmi_cmd	c;
1040	c.c_sc = sc;
1041	c.c_rssa = BMC_SA;
1042	c.c_rslun = BMC_LUN;
1043	c.c_netfn = STORAGE_NETFN;
1044	c.c_cmd = STORAGE_RESERVE_SDR;
1045	c.c_txlen = 0;
1046	c.c_maxrxlen = sizeof(resid);
1047	c.c_rxlen = 0;
1048	c.c_data = &resid;
1049	ipmi_cmd(&c);
1050
1051	/* Get SDR Header */
1052	if (get_sdr_partial(sc, recid, resid, 0, sizeof shdr, &shdr, nxtrec)) {
1053		printf("%s: get header fails\n", DEVNAME(sc));
1054		return (1);
1055	}
1056	/* Allocate space for entire SDR Length of SDR in header does not
1057	 * include header length */
1058	sdrlen = sizeof(shdr) + shdr.record_length;
1059	psdr = malloc(sdrlen, M_DEVBUF, M_NOWAIT);
1060	if (psdr == NULL)
1061		return (1);
1062
1063	memcpy(psdr, &shdr, sizeof(shdr));
1064
1065	/* Read SDR Data maxsdrlen bytes at a time */
1066	for (offset = sizeof(shdr); offset < sdrlen; offset += maxsdrlen) {
1067		len = sdrlen - offset;
1068		if (len > maxsdrlen)
1069			len = maxsdrlen;
1070
1071		if (get_sdr_partial(sc, recid, resid, offset, len,
1072		    psdr + offset, NULL)) {
1073			printf("%s: get chunk: %d,%d fails\n", DEVNAME(sc),
1074			    offset, len);
1075			free(psdr, M_DEVBUF, sdrlen);
1076			return (1);
1077		}
1078	}
1079
1080	/* Add SDR to sensor list, if not wanted, free buffer */
1081	if (add_sdr_sensor(sc, psdr, sdrlen) == 0)
1082		free(psdr, M_DEVBUF, sdrlen);
1083
1084	return (0);
1085}
1086
1087int
1088getbits(u_int8_t *bytes, int bitpos, int bitlen)
1089{
1090	int	v;
1091	int	mask;
1092
1093	bitpos += bitlen - 1;
1094	for (v = 0; bitlen--;) {
1095		v <<= 1;
1096		mask = 1L << (bitpos & 7);
1097		if (bytes[bitpos >> 3] & mask)
1098			v |= 1;
1099		bitpos--;
1100	}
1101
1102	return (v);
1103}
1104
1105/* Decode IPMI sensor name */
1106int
1107ipmi_sensor_name(char *name, int len, u_int8_t typelen, u_int8_t *bits,
1108    int bitslen)
1109{
1110	int	i, slen;
1111	char	bcdplus[] = "0123456789 -.:,_";
1112
1113	slen = typelen & 0x1F;
1114	switch (typelen >> 6) {
1115	case IPMI_NAME_UNICODE:
1116		//unicode
1117		break;
1118
1119	case IPMI_NAME_BCDPLUS:
1120		/* Characters are encoded in 4-bit BCDPLUS */
1121		if (len < slen * 2 + 1)
1122			slen = (len >> 1) - 1;
1123		if (slen > bitslen)
1124			return (0);
1125		for (i = 0; i < slen; i++) {
1126			*(name++) = bcdplus[bits[i] >> 4];
1127			*(name++) = bcdplus[bits[i] & 0xF];
1128		}
1129		break;
1130
1131	case IPMI_NAME_ASCII6BIT:
1132		/* Characters are encoded in 6-bit ASCII
1133		 *   0x00 - 0x3F maps to 0x20 - 0x5F */
1134		/* XXX: need to calculate max len: slen = 3/4 * len */
1135		if (len < slen + 1)
1136			slen = len - 1;
1137		if (slen * 6 / 8 > bitslen)
1138			return (0);
1139		for (i = 0; i < slen * 8; i += 6) {
1140			*(name++) = getbits(bits, i, 6) + ' ';
1141		}
1142		break;
1143
1144	case IPMI_NAME_ASCII8BIT:
1145		/* Characters are 8-bit ascii */
1146		if (len < slen + 1)
1147			slen = len - 1;
1148		if (slen > bitslen)
1149			return (0);
1150		while (slen--)
1151			*(name++) = *(bits++);
1152		break;
1153	}
1154	*name = 0;
1155
1156	return (1);
1157}
1158
1159/* Calculate val * 10^exp */
1160long
1161ipow(long val, int exp)
1162{
1163	while (exp > 0) {
1164		val *= 10;
1165		exp--;
1166	}
1167
1168	while (exp < 0) {
1169		val /= 10;
1170		exp++;
1171	}
1172
1173	return (val);
1174}
1175
1176/* Sign extend a n-bit value */
1177long
1178signextend(unsigned long val, int bits)
1179{
1180	long msk = (1L << (bits-1))-1;
1181
1182	return (-(val & ~msk) | val);
1183}
1184
1185/* Convert IPMI reading from sensor factors */
1186long
1187ipmi_convert(u_int8_t v, struct sdrtype1 *s1, long adj)
1188{
1189	int16_t	M, B;
1190	int8_t	K1, K2;
1191	long	val;
1192
1193	/* Calculate linear reading variables */
1194	M  = signextend((((short)(s1->m_tolerance & 0xC0)) << 2) + s1->m, 10);
1195	B  = signextend((((short)(s1->b_accuracy & 0xC0)) << 2) + s1->b, 10);
1196	K1 = signextend(s1->rbexp & 0xF, 4);
1197	K2 = signextend(s1->rbexp >> 4, 4);
1198
1199	/* Calculate sensor reading:
1200	 *  y = L((M * v + (B * 10^K1)) * 10^(K2+adj)
1201	 *
1202	 * This commutes out to:
1203	 *  y = L(M*v * 10^(K2+adj) + B * 10^(K1+K2+adj)); */
1204	val = ipow(M * v, K2 + adj) + ipow(B, K1 + K2 + adj);
1205
1206	/* Linearization function: y = f(x) 0 : y = x 1 : y = ln(x) 2 : y =
1207	 * log10(x) 3 : y = log2(x) 4 : y = e^x 5 : y = 10^x 6 : y = 2^x 7 : y
1208	 * = 1/x 8 : y = x^2 9 : y = x^3 10 : y = square root(x) 11 : y = cube
1209	 * root(x) */
1210	return (val);
1211}
1212
1213int
1214ipmi_sensor_status(struct ipmi_softc *sc, struct ipmi_sensor *psensor,
1215    u_int8_t *reading)
1216{
1217	struct sdrtype1	*s1 = (struct sdrtype1 *)psensor->i_sdr;
1218	int		etype;
1219
1220	/* Get reading of sensor */
1221	switch (psensor->i_sensor.type) {
1222	case SENSOR_TEMP:
1223		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
1224		psensor->i_sensor.value += 273150000;
1225		break;
1226
1227	case SENSOR_VOLTS_DC:
1228	case SENSOR_VOLTS_AC:
1229	case SENSOR_AMPS:
1230	case SENSOR_WATTS:
1231		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6);
1232		break;
1233
1234	case SENSOR_FANRPM:
1235		psensor->i_sensor.value = ipmi_convert(reading[0], s1, 0);
1236		if (((s1->units1>>3)&0x7) == 0x3)
1237			psensor->i_sensor.value *= 60; // RPS -> RPM
1238		break;
1239	default:
1240		break;
1241	}
1242
1243	/* Return Sensor Status */
1244	etype = (psensor->etype << 8) + psensor->stype;
1245	switch (etype) {
1246	case IPMI_SENSOR_TYPE_TEMP:
1247	case IPMI_SENSOR_TYPE_VOLT:
1248	case IPMI_SENSOR_TYPE_CURRENT:
1249	case IPMI_SENSOR_TYPE_FAN:
1250		/* non-recoverable threshold */
1251		if (reading[2] & ((1 << 5) | (1 << 2)))
1252			return (SENSOR_S_CRIT);
1253		/* critical threshold */
1254		else if (reading[2] & ((1 << 4) | (1 << 1)))
1255			return (SENSOR_S_CRIT);
1256		/* non-critical threshold */
1257		else if (reading[2] & ((1 << 3) | (1 << 0)))
1258			return (SENSOR_S_WARN);
1259		break;
1260
1261	case IPMI_SENSOR_TYPE_INTRUSION:
1262		psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
1263		if (reading[2] & 0x1)
1264			return (SENSOR_S_CRIT);
1265		break;
1266
1267	case IPMI_SENSOR_TYPE_PWRSUPPLY:
1268		/* Reading: 1 = present+powered, 0 = otherwise */
1269		psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0;
1270		if (reading[2] & 0x10) {
1271			/* XXX: Need sysctl type for Power Supply types
1272			 *   ok: power supply installed && powered
1273			 * warn: power supply installed && !powered
1274			 * crit: power supply !installed
1275			 */
1276			return (SENSOR_S_CRIT);
1277		}
1278		if (reading[2] & 0x08) {
1279			/* Power supply AC lost */
1280			return (SENSOR_S_WARN);
1281		}
1282		break;
1283	}
1284
1285	return (SENSOR_S_OK);
1286}
1287
1288int
1289read_sensor(struct ipmi_softc *sc, struct ipmi_sensor *psensor)
1290{
1291	struct sdrtype1	*s1 = (struct sdrtype1 *) psensor->i_sdr;
1292	u_int8_t	data[8];
1293	int		rv = -1;
1294
1295	memset(data, 0, sizeof(data));
1296	data[0] = psensor->i_num;
1297
1298	struct ipmi_cmd	c;
1299	c.c_sc = sc;
1300	c.c_rssa = s1->owner_id;
1301	c.c_rslun = s1->owner_lun;
1302	c.c_netfn = SE_NETFN;
1303	c.c_cmd = SE_GET_SENSOR_READING;
1304	c.c_txlen = 1;
1305	c.c_maxrxlen = sizeof(data);
1306	c.c_rxlen = 0;
1307	c.c_data = data;
1308	ipmi_cmd(&c);
1309
1310	if (c.c_ccode != 0) {
1311		dbg_printf(1, "sensor reading command for %s failed: %.2x\n",
1312			psensor->i_sensor.desc, c.c_ccode);
1313		return (rv);
1314	}
1315	dbg_printf(10, "values=%.2x %.2x %.2x %.2x %s\n",
1316	    data[0],data[1],data[2],data[3], psensor->i_sensor.desc);
1317	psensor->i_sensor.flags &= ~SENSOR_FINVALID;
1318	if ((data[1] & IPMI_INVALID_SENSOR) ||
1319	    ((data[1] & IPMI_DISABLED_SENSOR) == 0 && data[0] == 0))
1320		psensor->i_sensor.flags |= SENSOR_FINVALID;
1321	psensor->i_sensor.status = ipmi_sensor_status(sc, psensor, data);
1322	rv = 0;
1323	return (rv);
1324}
1325
1326int
1327ipmi_sensor_type(int type, int ext_type, int units2, int entity)
1328{
1329	switch (units2) {
1330	case IPMI_UNIT_TYPE_AMPS:
1331		return (SENSOR_AMPS);
1332
1333	case IPMI_UNIT_TYPE_RPM:
1334		return (SENSOR_FANRPM);
1335
1336	/* XXX sensors framework distinguishes AC/DC but ipmi does not */
1337	case IPMI_UNIT_TYPE_VOLTS:
1338		return (SENSOR_VOLTS_DC);
1339
1340	case IPMI_UNIT_TYPE_WATTS:
1341		return (SENSOR_WATTS);
1342	}
1343
1344	switch (ext_type << 8L | type) {
1345	case IPMI_SENSOR_TYPE_TEMP:
1346		return (SENSOR_TEMP);
1347
1348	case IPMI_SENSOR_TYPE_PWRSUPPLY:
1349		if (entity == IPMI_ENTITY_PWRSUPPLY)
1350			return (SENSOR_INDICATOR);
1351		break;
1352
1353	case IPMI_SENSOR_TYPE_INTRUSION:
1354		return (SENSOR_INDICATOR);
1355	}
1356
1357	return (-1);
1358}
1359
1360/* Add Sensor to BSD Sysctl interface */
1361int
1362add_sdr_sensor(struct ipmi_softc *sc, u_int8_t *psdr, int sdrlen)
1363{
1364	int			rc;
1365	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
1366	struct sdrtype2		*s2 = (struct sdrtype2 *)psdr;
1367	char			name[64];
1368
1369	switch (s1->sdrhdr.record_type) {
1370	case IPMI_SDR_TYPEFULL:
1371		rc = ipmi_sensor_name(name, sizeof(name), s1->typelen,
1372		    s1->name, sdrlen - (int)offsetof(struct sdrtype1, name));
1373		if (rc == 0)
1374			return (0);
1375		rc = add_child_sensors(sc, psdr, 1, s1->sensor_num,
1376		    s1->sensor_type, s1->event_code, 0, s1->entity_id, name);
1377		break;
1378
1379	case IPMI_SDR_TYPECOMPACT:
1380		rc = ipmi_sensor_name(name, sizeof(name), s2->typelen,
1381		    s2->name, sdrlen - (int)offsetof(struct sdrtype2, name));
1382		if (rc == 0)
1383			return (0);
1384		rc = add_child_sensors(sc, psdr, s2->share1 & 0xF,
1385		    s2->sensor_num, s2->sensor_type, s2->event_code,
1386		    s2->share2 & 0x7F, s2->entity_id, name);
1387		break;
1388
1389	default:
1390		return (0);
1391	}
1392
1393	return rc;
1394}
1395
1396int
1397add_child_sensors(struct ipmi_softc *sc, u_int8_t *psdr, int count,
1398    int sensor_num, int sensor_type, int ext_type, int sensor_base,
1399    int entity, const char *name)
1400{
1401	int			typ, idx, rc = 0;
1402	struct ipmi_sensor	*psensor;
1403	struct sdrtype1		*s1 = (struct sdrtype1 *)psdr;
1404
1405	typ = ipmi_sensor_type(sensor_type, ext_type, s1->units2, entity);
1406	if (typ == -1) {
1407		dbg_printf(5, "Unknown sensor type:%.2x et:%.2x sn:%.2x "
1408		    "units2:%u name:%s\n", sensor_type, ext_type, sensor_num,
1409		    s1->units2, name);
1410		return 0;
1411	}
1412	for (idx = 0; idx < count; idx++) {
1413		psensor = malloc(sizeof(*psensor), M_DEVBUF, M_NOWAIT | M_ZERO);
1414		if (psensor == NULL)
1415			break;
1416
1417		/* Initialize BSD Sensor info */
1418		psensor->i_sdr = psdr;
1419		psensor->i_num = sensor_num + idx;
1420		psensor->stype = sensor_type;
1421		psensor->etype = ext_type;
1422		psensor->i_sensor.type = typ;
1423		if (count > 1)
1424			snprintf(psensor->i_sensor.desc,
1425			    sizeof(psensor->i_sensor.desc),
1426			    "%s - %d", name, sensor_base + idx);
1427		else
1428			strlcpy(psensor->i_sensor.desc, name,
1429			    sizeof(psensor->i_sensor.desc));
1430
1431		dbg_printf(5, "add sensor:%.4x %.2x:%d ent:%.2x:%.2x %s\n",
1432		    s1->sdrhdr.record_id, s1->sensor_type,
1433		    typ, s1->entity_id, s1->entity_instance,
1434		    psensor->i_sensor.desc);
1435		if (read_sensor(sc, psensor) == 0) {
1436			SLIST_INSERT_HEAD(&ipmi_sensor_list, psensor, list);
1437			sensor_attach(&sc->sc_sensordev, &psensor->i_sensor);
1438			dbg_printf(5, "	 reading: %lld [%s]\n",
1439			    psensor->i_sensor.value,
1440			    psensor->i_sensor.desc);
1441			rc = 1;
1442		} else
1443			free(psensor, M_DEVBUF, sizeof(*psensor));
1444	}
1445
1446	return (rc);
1447}
1448
1449/* Handle IPMI Timer - reread sensor values */
1450void
1451ipmi_refresh_sensors(struct ipmi_softc *sc)
1452{
1453	if (SLIST_EMPTY(&ipmi_sensor_list))
1454		return;
1455
1456	sc->current_sensor = SLIST_NEXT(sc->current_sensor, list);
1457	if (sc->current_sensor == NULL)
1458		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
1459
1460	if (read_sensor(sc, sc->current_sensor)) {
1461		dbg_printf(1, "%s: error reading: %s\n", DEVNAME(sc),
1462		    sc->current_sensor->i_sensor.desc);
1463		return;
1464	}
1465}
1466
1467int
1468ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
1469{
1470	if (sc->sc_if && sc->sc_if->nregs == 0)
1471		return (0);
1472
1473	sc->sc_if = ipmi_get_if(ia->iaa_if_type);
1474	if (sc->sc_if == NULL)
1475		return (-1);
1476
1477	if (ia->iaa_if_iotype == 'i')
1478		sc->sc_iot = ia->iaa_iot;
1479	else
1480		sc->sc_iot = ia->iaa_memt;
1481
1482	sc->sc_if_rev = ia->iaa_if_rev;
1483	sc->sc_if_iosize = ia->iaa_if_iosize;
1484	sc->sc_if_iospacing = ia->iaa_if_iospacing;
1485	if (bus_space_map(sc->sc_iot, ia->iaa_if_iobase,
1486	    sc->sc_if->nregs * sc->sc_if_iospacing,
1487	    0, &sc->sc_ioh)) {
1488		printf("%s: bus_space_map(%lx %lx %x 0 %p) failed\n",
1489		    DEVNAME(sc),
1490		    (unsigned long)sc->sc_iot, ia->iaa_if_iobase,
1491		    sc->sc_if->nregs * sc->sc_if_iospacing, &sc->sc_ioh);
1492		return (-1);
1493	}
1494	return (0);
1495}
1496
1497void
1498ipmi_unmap_regs(struct ipmi_softc *sc)
1499{
1500	if (sc->sc_if->nregs > 0) {
1501		bus_space_unmap(sc->sc_iot, sc->sc_ioh,
1502		    sc->sc_if->nregs * sc->sc_if_iospacing);
1503	}
1504}
1505
1506void
1507ipmi_poll_thread(void *arg)
1508{
1509	struct ipmi_thread	*thread = arg;
1510	struct ipmi_softc	*sc = thread->sc;
1511	u_int16_t		rec;
1512
1513	/* Scan SDRs, add sensors */
1514	for (rec = 0; rec != 0xFFFF;) {
1515		if (get_sdr(sc, rec, &rec)) {
1516			ipmi_unmap_regs(sc);
1517			printf("%s: no SDRs IPMI disabled\n", DEVNAME(sc));
1518			goto done;
1519		}
1520		tsleep_nsec(sc, PWAIT, "ipmirun", MSEC_TO_NSEC(1));
1521	}
1522
1523	/* initialize sensor list for thread */
1524	if (SLIST_EMPTY(&ipmi_sensor_list))
1525		goto done;
1526	else
1527		sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list);
1528
1529	strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
1530	    sizeof(sc->sc_sensordev.xname));
1531	sensordev_install(&sc->sc_sensordev);
1532
1533	while (thread->running) {
1534		ipmi_refresh_sensors(sc);
1535		tsleep_nsec(thread, PWAIT, "ipmi_poll",
1536		    SEC_TO_NSEC(SENSOR_REFRESH_RATE));
1537	}
1538
1539done:
1540	kthread_exit(0);
1541}
1542
1543void
1544ipmi_create_thread(void *arg)
1545{
1546	struct ipmi_softc	*sc = arg;
1547
1548	if (kthread_create(ipmi_poll_thread, sc->sc_thread, NULL,
1549	    DEVNAME(sc)) != 0) {
1550		printf("%s: unable to create run thread, ipmi disabled\n",
1551		    DEVNAME(sc));
1552		return;
1553	}
1554}
1555
1556void
1557ipmi_attach_common(struct ipmi_softc *sc, struct ipmi_attach_args *ia)
1558{
1559	struct ipmi_cmd		*c = &sc->sc_ioctl.cmd;
1560
1561	/* Map registers */
1562	ipmi_map_regs(sc, ia);
1563
1564	sc->sc_thread = malloc(sizeof(struct ipmi_thread), M_DEVBUF, M_NOWAIT);
1565	if (sc->sc_thread == NULL) {
1566		printf(": unable to allocate thread\n");
1567		return;
1568	}
1569	sc->sc_thread->sc = sc;
1570	sc->sc_thread->running = 1;
1571
1572	/* Setup threads */
1573	kthread_create_deferred(ipmi_create_thread, sc);
1574
1575	printf(": version %d.%d interface %s",
1576	    ia->iaa_if_rev >> 4, ia->iaa_if_rev & 0xF, sc->sc_if->name);
1577	if (sc->sc_if->nregs > 0)
1578		printf(" %sbase 0x%lx/%x spacing %d",
1579		    ia->iaa_if_iotype == 'i' ? "io" : "mem", ia->iaa_if_iobase,
1580		    ia->iaa_if_iospacing * sc->sc_if->nregs,
1581		    ia->iaa_if_iospacing);
1582	if (ia->iaa_if_irq != -1)
1583		printf(" irq %d", ia->iaa_if_irq);
1584	printf("\n");
1585
1586	/* setup flag to exclude iic */
1587	ipmi_enabled = 1;
1588
1589	/* Setup Watchdog timer */
1590	sc->sc_wdog_period = 0;
1591	task_set(&sc->sc_wdog_tickle_task, ipmi_watchdog_tickle, sc);
1592	wdog_register(ipmi_watchdog, sc);
1593
1594	rw_init(&sc->sc_ioctl.lock, DEVNAME(sc));
1595	sc->sc_ioctl.req.msgid = -1;
1596	c->c_sc = sc;
1597	c->c_ccode = -1;
1598
1599	sc->sc_cmd_taskq = taskq_create("ipmicmd", 1, IPL_MPFLOOR,
1600	    TASKQ_MPSAFE);
1601}
1602
1603int
1604ipmi_activate(struct device *self, int act)
1605{
1606	switch (act) {
1607	case DVACT_POWERDOWN:
1608		wdog_shutdown(self);
1609		break;
1610	}
1611
1612	return (0);
1613}
1614
1615struct ipmi_softc *
1616ipmilookup(dev_t dev)
1617{
1618	return (struct ipmi_softc *)device_lookup(&ipmi_cd, minor(dev));
1619}
1620
1621int
1622ipmiopen(dev_t dev, int flags, int mode, struct proc *p)
1623{
1624	struct ipmi_softc	*sc = ipmilookup(dev);
1625
1626	if (sc == NULL)
1627		return (ENXIO);
1628	return (0);
1629}
1630
1631int
1632ipmiclose(dev_t dev, int flags, int mode, struct proc *p)
1633{
1634	struct ipmi_softc	*sc = ipmilookup(dev);
1635
1636	if (sc == NULL)
1637		return (ENXIO);
1638	return (0);
1639}
1640
1641int
1642ipmiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc)
1643{
1644	struct ipmi_softc	*sc = ipmilookup(dev);
1645	struct ipmi_req		*req = (struct ipmi_req *)data;
1646	struct ipmi_recv	*recv = (struct ipmi_recv *)data;
1647	struct ipmi_cmd		*c = &sc->sc_ioctl.cmd;
1648	int			iv;
1649	int			len;
1650	u_char			ccode;
1651	int			rc = 0;
1652
1653	if (sc == NULL)
1654		return (ENXIO);
1655
1656	rw_enter_write(&sc->sc_ioctl.lock);
1657
1658	c->c_maxrxlen = sizeof(sc->sc_ioctl.buf);
1659	c->c_data = sc->sc_ioctl.buf;
1660
1661	switch (cmd) {
1662	case IPMICTL_SEND_COMMAND:
1663		if (req->msgid == -1) {
1664			rc = EINVAL;
1665			goto reset;
1666		}
1667		if (sc->sc_ioctl.req.msgid != -1) {
1668			rc = EBUSY;
1669			goto reset;
1670		}
1671		len = req->msg.data_len;
1672		if (len < 0) {
1673			rc = EINVAL;
1674			goto reset;
1675		}
1676		if (len > c->c_maxrxlen) {
1677			rc = E2BIG;
1678			goto reset;
1679		}
1680		sc->sc_ioctl.req = *req;
1681		c->c_ccode = -1;
1682		rc = copyin(req->msg.data, c->c_data, len);
1683		if (rc != 0)
1684			goto reset;
1685		KASSERT(c->c_ccode == -1);
1686
1687		/* Execute a command synchronously. */
1688		c->c_netfn = req->msg.netfn;
1689		c->c_cmd = req->msg.cmd;
1690		c->c_txlen = req->msg.data_len;
1691		c->c_rxlen = 0;
1692		ipmi_cmd(c);
1693		break;
1694	case IPMICTL_RECEIVE_MSG_TRUNC:
1695	case IPMICTL_RECEIVE_MSG:
1696		if (sc->sc_ioctl.req.msgid == -1) {
1697			rc = EINVAL;
1698			goto reset;
1699		}
1700		if (c->c_ccode == -1) {
1701			rc = EAGAIN;
1702			goto reset;
1703		}
1704		ccode = c->c_ccode & 0xff;
1705		rc = copyout(&ccode, recv->msg.data, 1);
1706		if (rc != 0)
1707			goto reset;
1708
1709		/* Return a command result. */
1710		recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
1711		recv->msgid = sc->sc_ioctl.req.msgid;
1712		recv->msg.netfn = sc->sc_ioctl.req.msg.netfn;
1713		recv->msg.cmd = sc->sc_ioctl.req.msg.cmd;
1714		recv->msg.data_len = c->c_rxlen + 1;
1715
1716		rc = copyout(c->c_data, recv->msg.data + 1, c->c_rxlen);
1717		/* Always reset state after command completion. */
1718		goto reset;
1719	case IPMICTL_SET_MY_ADDRESS_CMD:
1720		iv = *(int *)data;
1721		if (iv < 0 || iv > RSSA_MASK) {
1722			rc = EINVAL;
1723			goto reset;
1724		}
1725		c->c_rssa = iv;
1726		break;
1727	case IPMICTL_GET_MY_ADDRESS_CMD:
1728		*(int *)data = c->c_rssa;
1729		break;
1730	case IPMICTL_SET_MY_LUN_CMD:
1731		iv = *(int *)data;
1732		if (iv < 0 || iv > LUN_MASK) {
1733			rc = EINVAL;
1734			goto reset;
1735		}
1736		c->c_rslun = iv;
1737		break;
1738	case IPMICTL_GET_MY_LUN_CMD:
1739		*(int *)data = c->c_rslun;
1740		break;
1741	case IPMICTL_SET_GETS_EVENTS_CMD:
1742		break;
1743	case IPMICTL_REGISTER_FOR_CMD:
1744	case IPMICTL_UNREGISTER_FOR_CMD:
1745	default:
1746		break;
1747	}
1748done:
1749	rw_exit_write(&sc->sc_ioctl.lock);
1750	return (rc);
1751reset:
1752	sc->sc_ioctl.req.msgid = -1;
1753	c->c_ccode = -1;
1754	goto done;
1755}
1756
1757#define		MIN_PERIOD	10
1758
1759int
1760ipmi_watchdog(void *arg, int period)
1761{
1762	struct ipmi_softc	*sc = arg;
1763
1764	if (sc->sc_wdog_period == period) {
1765		if (period != 0) {
1766			struct task *t;
1767			int res;
1768
1769			t = &sc->sc_wdog_tickle_task;
1770			(void)task_del(systq, t);
1771			res = task_add(systq, t);
1772			KASSERT(res == 1);
1773		}
1774		return (period);
1775	}
1776
1777	if (period < MIN_PERIOD && period > 0)
1778		period = MIN_PERIOD;
1779	sc->sc_wdog_period = period;
1780	ipmi_watchdog_set(sc);
1781	printf("%s: watchdog %sabled\n", DEVNAME(sc),
1782	    (period == 0) ? "dis" : "en");
1783	return (period);
1784}
1785
1786void
1787ipmi_watchdog_tickle(void *arg)
1788{
1789	struct ipmi_softc	*sc = arg;
1790	struct ipmi_cmd		c;
1791
1792	c.c_sc = sc;
1793	c.c_rssa = BMC_SA;
1794	c.c_rslun = BMC_LUN;
1795	c.c_netfn = APP_NETFN;
1796	c.c_cmd = APP_RESET_WATCHDOG;
1797	c.c_txlen = 0;
1798	c.c_maxrxlen = 0;
1799	c.c_rxlen = 0;
1800	c.c_data = NULL;
1801	ipmi_cmd(&c);
1802}
1803
1804void
1805ipmi_watchdog_set(void *arg)
1806{
1807	struct ipmi_softc	*sc = arg;
1808	uint8_t			wdog[IPMI_GET_WDOG_MAX];
1809	struct ipmi_cmd		c;
1810
1811	c.c_sc = sc;
1812	c.c_rssa = BMC_SA;
1813	c.c_rslun = BMC_LUN;
1814	c.c_netfn = APP_NETFN;
1815	c.c_cmd = APP_GET_WATCHDOG_TIMER;
1816	c.c_txlen = 0;
1817	c.c_maxrxlen = IPMI_GET_WDOG_MAX;
1818	c.c_rxlen = 0;
1819	c.c_data = wdog;
1820	ipmi_cmd(&c);
1821
1822	/* Period is 10ths/sec */
1823	uint16_t timo = htole16(sc->sc_wdog_period * 10);
1824
1825	memcpy(&wdog[IPMI_SET_WDOG_TIMOL], &timo, 2);
1826	wdog[IPMI_SET_WDOG_TIMER] &= ~IPMI_WDOG_DONTSTOP;
1827	wdog[IPMI_SET_WDOG_TIMER] |= (sc->sc_wdog_period == 0) ?
1828	    0 : IPMI_WDOG_DONTSTOP;
1829	wdog[IPMI_SET_WDOG_ACTION] &= ~IPMI_WDOG_MASK;
1830	wdog[IPMI_SET_WDOG_ACTION] |= (sc->sc_wdog_period == 0) ?
1831	    IPMI_WDOG_DISABLED : IPMI_WDOG_REBOOT;
1832
1833	c.c_cmd = APP_SET_WATCHDOG_TIMER;
1834	c.c_txlen = IPMI_SET_WDOG_MAX;
1835	c.c_maxrxlen = 0;
1836	c.c_rxlen = 0;
1837	c.c_data = wdog;
1838	ipmi_cmd(&c);
1839}
1840
1841#if defined(__amd64__) || defined(__i386__)
1842
1843#include <dev/isa/isareg.h>
1844#include <dev/isa/isavar.h>
1845
1846/*
1847 * Format of SMBIOS IPMI Flags
1848 *
1849 * bit0: interrupt trigger mode (1=level, 0=edge)
1850 * bit1: interrupt polarity (1=active high, 0=active low)
1851 * bit2: reserved
1852 * bit3: address LSB (1=odd,0=even)
1853 * bit4: interrupt (1=specified, 0=not specified)
1854 * bit5: reserved
1855 * bit6/7: register spacing (1,4,2,err)
1856 */
1857#define SMIPMI_FLAG_IRQLVL		(1L << 0)
1858#define SMIPMI_FLAG_IRQEN		(1L << 3)
1859#define SMIPMI_FLAG_ODDOFFSET		(1L << 4)
1860#define SMIPMI_FLAG_IFSPACING(x)	(((x)>>6)&0x3)
1861#define	 IPMI_IOSPACING_BYTE		 0
1862#define	 IPMI_IOSPACING_WORD		 2
1863#define	 IPMI_IOSPACING_DWORD		 1
1864
1865struct dmd_ipmi {
1866	u_int8_t	dmd_sig[4];		/* Signature 'IPMI' */
1867	u_int8_t	dmd_i2c_address;	/* Address of BMC */
1868	u_int8_t	dmd_nvram_address;	/* Address of NVRAM */
1869	u_int8_t	dmd_if_type;		/* IPMI Interface Type */
1870	u_int8_t	dmd_if_rev;		/* IPMI Interface Revision */
1871} __packed;
1872
1873void	*scan_sig(long, long, int, int, const void *);
1874
1875void	ipmi_smbios_probe(struct smbios_ipmi *, struct ipmi_attach_args *);
1876int	ipmi_match(struct device *, void *, void *);
1877void	ipmi_attach(struct device *, struct device *, void *);
1878
1879const struct cfattach ipmi_ca = {
1880	sizeof(struct ipmi_softc), ipmi_match, ipmi_attach,
1881	NULL, ipmi_activate
1882};
1883
1884int
1885ipmi_match(struct device *parent, void *match, void *aux)
1886{
1887	struct ipmi_softc	*sc;
1888	struct ipmi_attach_args *ia = aux;
1889	struct cfdata		*cf = match;
1890	u_int8_t		cmd[32];
1891	int			rv = 0;
1892
1893	if (strcmp(ia->iaa_name, cf->cf_driver->cd_name))
1894		return (0);
1895
1896	/* XXX local softc is wrong wrong wrong */
1897	sc = malloc(sizeof(*sc), M_TEMP, M_WAITOK | M_ZERO);
1898	strlcpy(sc->sc_dev.dv_xname, "ipmi0", sizeof(sc->sc_dev.dv_xname));
1899
1900	/* Map registers */
1901	if (ipmi_map_regs(sc, ia) == 0) {
1902		sc->sc_if->probe(sc);
1903
1904		/* Identify BMC device early to detect lying bios */
1905		struct ipmi_cmd c;
1906		c.c_sc = sc;
1907		c.c_rssa = BMC_SA;
1908		c.c_rslun = BMC_LUN;
1909		c.c_netfn = APP_NETFN;
1910		c.c_cmd = APP_GET_DEVICE_ID;
1911		c.c_txlen = 0;
1912		c.c_maxrxlen = sizeof(cmd);
1913		c.c_rxlen = 0;
1914		c.c_data = cmd;
1915		ipmi_cmd(&c);
1916
1917		dbg_dump(1, "bmc data", c.c_rxlen, cmd);
1918		rv = 1; /* GETID worked, we got IPMI */
1919		ipmi_unmap_regs(sc);
1920	}
1921
1922	free(sc, M_TEMP, sizeof(*sc));
1923
1924	return (rv);
1925}
1926
1927void
1928ipmi_attach(struct device *parent, struct device *self, void *aux)
1929{
1930	ipmi_attach_common((struct ipmi_softc *)self, aux);
1931}
1932
1933/* Scan memory for signature */
1934void *
1935scan_sig(long start, long end, int skip, int len, const void *data)
1936{
1937	void *va;
1938
1939	while (start < end) {
1940		va = ISA_HOLE_VADDR(start);
1941		if (memcmp(va, data, len) == 0)
1942			return (va);
1943
1944		start += skip;
1945	}
1946
1947	return (NULL);
1948}
1949
1950void
1951ipmi_smbios_probe(struct smbios_ipmi *pipmi, struct ipmi_attach_args *ia)
1952{
1953
1954	dbg_printf(1, "ipmi_smbios_probe: %02x %02x %02x %02x %08llx %02x "
1955	    "%02x\n",
1956	    pipmi->smipmi_if_type,
1957	    pipmi->smipmi_if_rev,
1958	    pipmi->smipmi_i2c_address,
1959	    pipmi->smipmi_nvram_address,
1960	    pipmi->smipmi_base_address,
1961	    pipmi->smipmi_base_flags,
1962	    pipmi->smipmi_irq);
1963
1964	ia->iaa_if_type = pipmi->smipmi_if_type;
1965	ia->iaa_if_rev = pipmi->smipmi_if_rev;
1966	ia->iaa_if_irq = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQEN) ?
1967	    pipmi->smipmi_irq : -1;
1968	ia->iaa_if_irqlvl = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQLVL) ?
1969	    IST_LEVEL : IST_EDGE;
1970	ia->iaa_if_iosize = 1;
1971
1972	switch (SMIPMI_FLAG_IFSPACING(pipmi->smipmi_base_flags)) {
1973	case IPMI_IOSPACING_BYTE:
1974		ia->iaa_if_iospacing = 1;
1975		break;
1976
1977	case IPMI_IOSPACING_DWORD:
1978		ia->iaa_if_iospacing = 4;
1979		break;
1980
1981	case IPMI_IOSPACING_WORD:
1982		ia->iaa_if_iospacing = 2;
1983		break;
1984
1985	default:
1986		ia->iaa_if_iospacing = 1;
1987		printf("ipmi: unknown register spacing\n");
1988	}
1989
1990	/* Calculate base address (PCI BAR format) */
1991	if (pipmi->smipmi_base_address & 0x1) {
1992		ia->iaa_if_iotype = 'i';
1993		ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0x1;
1994	} else {
1995		ia->iaa_if_iotype = 'm';
1996		ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0xF;
1997	}
1998	if (pipmi->smipmi_base_flags & SMIPMI_FLAG_ODDOFFSET)
1999		ia->iaa_if_iobase++;
2000
2001	if (pipmi->smipmi_base_flags == 0x7f) {
2002		/* IBM 325 eServer workaround */
2003		ia->iaa_if_iospacing = 1;
2004		ia->iaa_if_iobase = pipmi->smipmi_base_address;
2005		ia->iaa_if_iotype = 'i';
2006		return;
2007	}
2008}
2009
2010int
2011ipmi_probe(void *aux)
2012{
2013	struct ipmi_attach_args *ia = aux;
2014	struct dmd_ipmi *pipmi;
2015	struct smbtable tbl;
2016
2017	tbl.cookie = 0;
2018	if (smbios_find_table(SMBIOS_TYPE_IPMIDEV, &tbl))
2019		ipmi_smbios_probe(tbl.tblhdr, ia);
2020	else {
2021		pipmi = (struct dmd_ipmi *)scan_sig(0xC0000L, 0xFFFFFL, 16, 4,
2022		    "IPMI");
2023		/* XXX hack to find Dell PowerEdge 8450 */
2024		if (pipmi == NULL) {
2025			/* no IPMI found */
2026			return (0);
2027		}
2028
2029		/* we have an IPMI signature, fill in attach arg structure */
2030		ia->iaa_if_type = pipmi->dmd_if_type;
2031		ia->iaa_if_rev = pipmi->dmd_if_rev;
2032	}
2033
2034	return (1);
2035}
2036
2037#endif
2038