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