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