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