1 /* $OpenBSD: ipmi.c,v 1.97 2016/06/07 01:31:54 tedu Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Masao Uebayashi 5 * Copyright (c) 2005 Jordan Hargrave 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/device.h> 35 #include <sys/ioctl.h> 36 #include <sys/extent.h> 37 #include <sys/sensors.h> 38 #include <sys/malloc.h> 39 #include <sys/kthread.h> 40 #include <sys/task.h> 41 42 #include <machine/bus.h> 43 #include <machine/smbiosvar.h> 44 45 #include <dev/isa/isareg.h> 46 #include <dev/isa/isavar.h> 47 48 #include <dev/ipmivar.h> 49 #include <dev/ipmi.h> 50 51 struct ipmi_sensor { 52 u_int8_t *i_sdr; 53 int i_num; 54 int stype; 55 int etype; 56 struct ksensor i_sensor; 57 SLIST_ENTRY(ipmi_sensor) list; 58 }; 59 60 int ipmi_enabled = 0; 61 62 #define SENSOR_REFRESH_RATE (5 * hz) 63 64 #define SMBIOS_TYPE_IPMI 0x26 65 66 #define DEVNAME(s) ((s)->sc_dev.dv_xname) 67 68 /* 69 * Format of SMBIOS IPMI Flags 70 * 71 * bit0: interrupt trigger mode (1=level, 0=edge) 72 * bit1: interrupt polarity (1=active high, 0=active low) 73 * bit2: reserved 74 * bit3: address LSB (1=odd,0=even) 75 * bit4: interrupt (1=specified, 0=not specified) 76 * bit5: reserved 77 * bit6/7: register spacing (1,4,2,err) 78 */ 79 #define SMIPMI_FLAG_IRQLVL (1L << 0) 80 #define SMIPMI_FLAG_IRQEN (1L << 3) 81 #define SMIPMI_FLAG_ODDOFFSET (1L << 4) 82 #define SMIPMI_FLAG_IFSPACING(x) (((x)>>6)&0x3) 83 #define IPMI_IOSPACING_BYTE 0 84 #define IPMI_IOSPACING_WORD 2 85 #define IPMI_IOSPACING_DWORD 1 86 87 #define IPMI_BTMSG_LEN 0 88 #define IPMI_BTMSG_NFLN 1 89 #define IPMI_BTMSG_SEQ 2 90 #define IPMI_BTMSG_CMD 3 91 #define IPMI_BTMSG_CCODE 4 92 #define IPMI_BTMSG_DATASND 4 93 #define IPMI_BTMSG_DATARCV 5 94 95 #define IPMI_MSG_NFLN 0 96 #define IPMI_MSG_CMD 1 97 #define IPMI_MSG_CCODE 2 98 #define IPMI_MSG_DATASND 2 99 #define IPMI_MSG_DATARCV 3 100 101 #define IPMI_SENSOR_TYPE_TEMP 0x0101 102 #define IPMI_SENSOR_TYPE_VOLT 0x0102 103 #define IPMI_SENSOR_TYPE_FAN 0x0104 104 #define IPMI_SENSOR_TYPE_INTRUSION 0x6F05 105 #define IPMI_SENSOR_TYPE_PWRSUPPLY 0x6F08 106 107 #define IPMI_NAME_UNICODE 0x00 108 #define IPMI_NAME_BCDPLUS 0x01 109 #define IPMI_NAME_ASCII6BIT 0x02 110 #define IPMI_NAME_ASCII8BIT 0x03 111 112 #define IPMI_ENTITY_PWRSUPPLY 0x0A 113 114 #define IPMI_INVALID_SENSOR (1L << 5) 115 #define IPMI_DISABLED_SENSOR (1L << 6) 116 117 #define IPMI_SDR_TYPEFULL 1 118 #define IPMI_SDR_TYPECOMPACT 2 119 120 #define byteof(x) ((x) >> 3) 121 #define bitof(x) (1L << ((x) & 0x7)) 122 #define TB(b,m) (data[2+byteof(b)] & bitof(b)) 123 124 #ifdef IPMI_DEBUG 125 int ipmi_dbg = 0; 126 #define dbg_printf(lvl, fmt...) \ 127 if (ipmi_dbg >= lvl) \ 128 printf(fmt); 129 #define dbg_dump(lvl, msg, len, buf) \ 130 if (len && ipmi_dbg >= lvl) \ 131 dumpb(msg, len, (const u_int8_t *)(buf)); 132 #else 133 #define dbg_printf(lvl, fmt...) 134 #define dbg_dump(lvl, msg, len, buf) 135 #endif 136 137 long signextend(unsigned long, int); 138 139 SLIST_HEAD(ipmi_sensors_head, ipmi_sensor); 140 struct ipmi_sensors_head ipmi_sensor_list = 141 SLIST_HEAD_INITIALIZER(ipmi_sensor_list); 142 143 void dumpb(const char *, int, const u_int8_t *); 144 145 int read_sensor(struct ipmi_softc *, struct ipmi_sensor *); 146 int add_sdr_sensor(struct ipmi_softc *, u_int8_t *, int); 147 int get_sdr_partial(struct ipmi_softc *, u_int16_t, u_int16_t, 148 u_int8_t, u_int8_t, void *, u_int16_t *); 149 int get_sdr(struct ipmi_softc *, u_int16_t, u_int16_t *); 150 151 int ipmi_sendcmd(struct ipmi_cmd *); 152 int ipmi_recvcmd(struct ipmi_cmd *); 153 void ipmi_cmd(struct ipmi_cmd *); 154 void ipmi_cmd_poll(struct ipmi_cmd *); 155 void ipmi_cmd_wait(struct ipmi_cmd *); 156 void ipmi_cmd_wait_cb(void *); 157 158 int ipmi_watchdog(void *, int); 159 void ipmi_watchdog_tickle(void *); 160 void ipmi_watchdog_set(void *); 161 162 int ipmi_match(struct device *, void *, void *); 163 void ipmi_attach(struct device *, struct device *, void *); 164 int ipmi_activate(struct device *, int); 165 struct ipmi_softc *ipmilookup(dev_t dev); 166 167 int ipmiopen(dev_t, int, int, struct proc *); 168 int ipmiclose(dev_t, int, int, struct proc *); 169 int ipmiioctl(dev_t, u_long, caddr_t, int, struct proc *); 170 171 long ipow(long, int); 172 long ipmi_convert(u_int8_t, struct sdrtype1 *, long); 173 int ipmi_sensor_name(char *, int, u_int8_t, u_int8_t *, int); 174 175 /* BMC Helper Functions */ 176 u_int8_t bmc_read(struct ipmi_softc *, int); 177 void bmc_write(struct ipmi_softc *, int, u_int8_t); 178 int bmc_io_wait(struct ipmi_softc *, struct ipmi_iowait *); 179 180 void bt_buildmsg(struct ipmi_cmd *); 181 void cmn_buildmsg(struct ipmi_cmd *); 182 183 int getbits(u_int8_t *, int, int); 184 int ipmi_sensor_type(int, int, int); 185 186 void ipmi_smbios_probe(struct smbios_ipmi *, struct ipmi_attach_args *); 187 void ipmi_refresh_sensors(struct ipmi_softc *sc); 188 int ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia); 189 void ipmi_unmap_regs(struct ipmi_softc *); 190 191 void *scan_sig(long, long, int, int, const void *); 192 193 int ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *, 194 u_int8_t *); 195 196 int add_child_sensors(struct ipmi_softc *, u_int8_t *, int, int, int, 197 int, int, int, const char *); 198 199 struct ipmi_if kcs_if = { 200 "KCS", 201 IPMI_IF_KCS_NREGS, 202 cmn_buildmsg, 203 kcs_sendmsg, 204 kcs_recvmsg, 205 kcs_reset, 206 kcs_probe, 207 IPMI_MSG_DATASND, 208 IPMI_MSG_DATARCV, 209 }; 210 211 struct ipmi_if smic_if = { 212 "SMIC", 213 IPMI_IF_SMIC_NREGS, 214 cmn_buildmsg, 215 smic_sendmsg, 216 smic_recvmsg, 217 smic_reset, 218 smic_probe, 219 IPMI_MSG_DATASND, 220 IPMI_MSG_DATARCV, 221 }; 222 223 struct ipmi_if bt_if = { 224 "BT", 225 IPMI_IF_BT_NREGS, 226 bt_buildmsg, 227 bt_sendmsg, 228 bt_recvmsg, 229 bt_reset, 230 bt_probe, 231 IPMI_BTMSG_DATASND, 232 IPMI_BTMSG_DATARCV, 233 }; 234 235 struct ipmi_if *ipmi_get_if(int); 236 237 struct ipmi_if * 238 ipmi_get_if(int iftype) 239 { 240 switch (iftype) { 241 case IPMI_IF_KCS: 242 return (&kcs_if); 243 case IPMI_IF_SMIC: 244 return (&smic_if); 245 case IPMI_IF_BT: 246 return (&bt_if); 247 } 248 249 return (NULL); 250 } 251 252 /* 253 * BMC Helper Functions 254 */ 255 u_int8_t 256 bmc_read(struct ipmi_softc *sc, int offset) 257 { 258 return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, 259 offset * sc->sc_if_iospacing)); 260 } 261 262 void 263 bmc_write(struct ipmi_softc *sc, int offset, u_int8_t val) 264 { 265 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 266 offset * sc->sc_if_iospacing, val); 267 } 268 269 int 270 bmc_io_wait(struct ipmi_softc *sc, struct ipmi_iowait *a) 271 { 272 volatile u_int8_t v; 273 int count = 5000000; /* == 5s XXX can be shorter */ 274 275 while (count--) { 276 v = bmc_read(sc, a->offset); 277 if ((v & a->mask) == a->value) 278 return v; 279 280 delay(1); 281 } 282 283 dbg_printf(1, "%s: bmc_io_wait fails : *v=%.2x m=%.2x b=%.2x %s\n", 284 DEVNAME(sc), v, a->mask, a->value, a->lbl); 285 return (-1); 286 287 } 288 289 #define RSSA_MASK 0xff 290 #define LUN_MASK 0x3 291 #define NETFN_LUN(nf,ln) (((nf) << 2) | ((ln) & LUN_MASK)) 292 293 /* 294 * BT interface 295 */ 296 #define _BT_CTRL_REG 0 297 #define BT_CLR_WR_PTR (1L << 0) 298 #define BT_CLR_RD_PTR (1L << 1) 299 #define BT_HOST2BMC_ATN (1L << 2) 300 #define BT_BMC2HOST_ATN (1L << 3) 301 #define BT_EVT_ATN (1L << 4) 302 #define BT_HOST_BUSY (1L << 6) 303 #define BT_BMC_BUSY (1L << 7) 304 305 #define BT_READY (BT_HOST_BUSY|BT_HOST2BMC_ATN|BT_BMC2HOST_ATN) 306 307 #define _BT_DATAIN_REG 1 308 #define _BT_DATAOUT_REG 1 309 310 #define _BT_INTMASK_REG 2 311 #define BT_IM_HIRQ_PEND (1L << 1) 312 #define BT_IM_SCI_EN (1L << 2) 313 #define BT_IM_SMI_EN (1L << 3) 314 #define BT_IM_NMI2SMI (1L << 4) 315 316 int bt_read(struct ipmi_softc *, int); 317 int bt_write(struct ipmi_softc *, int, uint8_t); 318 319 int 320 bt_read(struct ipmi_softc *sc, int reg) 321 { 322 return bmc_read(sc, reg); 323 } 324 325 int 326 bt_write(struct ipmi_softc *sc, int reg, uint8_t data) 327 { 328 struct ipmi_iowait a; 329 330 a.offset = _BT_CTRL_REG; 331 a.mask = BT_BMC_BUSY; 332 a.value = 0; 333 a.lbl = "bt_write"; 334 if (bmc_io_wait(sc, &a) < 0) 335 return (-1); 336 337 bmc_write(sc, reg, data); 338 return (0); 339 } 340 341 int 342 bt_sendmsg(struct ipmi_cmd *c) 343 { 344 struct ipmi_softc *sc = c->c_sc; 345 struct ipmi_iowait a; 346 int i; 347 348 bt_write(sc, _BT_CTRL_REG, BT_CLR_WR_PTR); 349 for (i = 0; i < c->c_txlen; i++) 350 bt_write(sc, _BT_DATAOUT_REG, sc->sc_buf[i]); 351 352 bt_write(sc, _BT_CTRL_REG, BT_HOST2BMC_ATN); 353 a.offset = _BT_CTRL_REG; 354 a.mask = BT_HOST2BMC_ATN | BT_BMC_BUSY; 355 a.value = 0; 356 a.lbl = "bt_sendwait"; 357 if (bmc_io_wait(sc, &a) < 0) 358 return (-1); 359 360 return (0); 361 } 362 363 int 364 bt_recvmsg(struct ipmi_cmd *c) 365 { 366 struct ipmi_softc *sc = c->c_sc; 367 struct ipmi_iowait a; 368 u_int8_t len, v, i, j; 369 370 a.offset = _BT_CTRL_REG; 371 a.mask = BT_BMC2HOST_ATN; 372 a.value = BT_BMC2HOST_ATN; 373 a.lbl = "bt_recvwait"; 374 if (bmc_io_wait(sc, &a) < 0) 375 return (-1); 376 377 bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY); 378 bt_write(sc, _BT_CTRL_REG, BT_BMC2HOST_ATN); 379 bt_write(sc, _BT_CTRL_REG, BT_CLR_RD_PTR); 380 len = bt_read(sc, _BT_DATAIN_REG); 381 for (i = IPMI_BTMSG_NFLN, j = 0; i <= len; i++) { 382 v = bt_read(sc, _BT_DATAIN_REG); 383 if (i != IPMI_BTMSG_SEQ) 384 *(sc->sc_buf + j++) = v; 385 } 386 bt_write(sc, _BT_CTRL_REG, BT_HOST_BUSY); 387 c->c_rxlen = len - 1; 388 389 return (0); 390 } 391 392 int 393 bt_reset(struct ipmi_softc *sc) 394 { 395 return (-1); 396 } 397 398 int 399 bt_probe(struct ipmi_softc *sc) 400 { 401 u_int8_t rv; 402 403 rv = bmc_read(sc, _BT_CTRL_REG); 404 rv &= BT_HOST_BUSY; 405 rv |= BT_CLR_WR_PTR|BT_CLR_RD_PTR|BT_BMC2HOST_ATN|BT_HOST2BMC_ATN; 406 bmc_write(sc, _BT_CTRL_REG, rv); 407 408 rv = bmc_read(sc, _BT_INTMASK_REG); 409 rv &= BT_IM_SCI_EN|BT_IM_SMI_EN|BT_IM_NMI2SMI; 410 rv |= BT_IM_HIRQ_PEND; 411 bmc_write(sc, _BT_INTMASK_REG, rv); 412 413 #if 0 414 printf("bt_probe: %2x\n", v); 415 printf(" WR : %2x\n", v & BT_CLR_WR_PTR); 416 printf(" RD : %2x\n", v & BT_CLR_RD_PTR); 417 printf(" H2B : %2x\n", v & BT_HOST2BMC_ATN); 418 printf(" B2H : %2x\n", v & BT_BMC2HOST_ATN); 419 printf(" EVT : %2x\n", v & BT_EVT_ATN); 420 printf(" HBSY : %2x\n", v & BT_HOST_BUSY); 421 printf(" BBSY : %2x\n", v & BT_BMC_BUSY); 422 #endif 423 return (0); 424 } 425 426 /* 427 * SMIC interface 428 */ 429 #define _SMIC_DATAIN_REG 0 430 #define _SMIC_DATAOUT_REG 0 431 432 #define _SMIC_CTRL_REG 1 433 #define SMS_CC_GET_STATUS 0x40 434 #define SMS_CC_START_TRANSFER 0x41 435 #define SMS_CC_NEXT_TRANSFER 0x42 436 #define SMS_CC_END_TRANSFER 0x43 437 #define SMS_CC_START_RECEIVE 0x44 438 #define SMS_CC_NEXT_RECEIVE 0x45 439 #define SMS_CC_END_RECEIVE 0x46 440 #define SMS_CC_TRANSFER_ABORT 0x47 441 442 #define SMS_SC_READY 0xc0 443 #define SMS_SC_WRITE_START 0xc1 444 #define SMS_SC_WRITE_NEXT 0xc2 445 #define SMS_SC_WRITE_END 0xc3 446 #define SMS_SC_READ_START 0xc4 447 #define SMS_SC_READ_NEXT 0xc5 448 #define SMS_SC_READ_END 0xc6 449 450 #define _SMIC_FLAG_REG 2 451 #define SMIC_BUSY (1L << 0) 452 #define SMIC_SMS_ATN (1L << 2) 453 #define SMIC_EVT_ATN (1L << 3) 454 #define SMIC_SMI (1L << 4) 455 #define SMIC_TX_DATA_RDY (1L << 6) 456 #define SMIC_RX_DATA_RDY (1L << 7) 457 458 int smic_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *); 459 int smic_write_cmd_data(struct ipmi_softc *, u_int8_t, const u_int8_t *); 460 int smic_read_data(struct ipmi_softc *, u_int8_t *); 461 462 int 463 smic_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t val, const char *lbl) 464 { 465 struct ipmi_iowait a; 466 int v; 467 468 /* Wait for expected flag bits */ 469 a.offset = _SMIC_FLAG_REG; 470 a.mask = mask; 471 a.value = val; 472 a.lbl = "smicwait"; 473 v = bmc_io_wait(sc, &a); 474 if (v < 0) 475 return (-1); 476 477 /* Return current status */ 478 v = bmc_read(sc, _SMIC_CTRL_REG); 479 dbg_printf(99, "smic_wait = %.2x\n", v); 480 return (v); 481 } 482 483 int 484 smic_write_cmd_data(struct ipmi_softc *sc, u_int8_t cmd, const u_int8_t *data) 485 { 486 int sts, v; 487 488 dbg_printf(50, "smic_wcd: %.2x %.2x\n", cmd, data ? *data : -1); 489 sts = smic_wait(sc, SMIC_TX_DATA_RDY | SMIC_BUSY, SMIC_TX_DATA_RDY, 490 "smic_write_cmd_data ready"); 491 if (sts < 0) 492 return (sts); 493 494 bmc_write(sc, _SMIC_CTRL_REG, cmd); 495 if (data) 496 bmc_write(sc, _SMIC_DATAOUT_REG, *data); 497 498 /* Toggle BUSY bit, then wait for busy bit to clear */ 499 v = bmc_read(sc, _SMIC_FLAG_REG); 500 bmc_write(sc, _SMIC_FLAG_REG, v | SMIC_BUSY); 501 502 return (smic_wait(sc, SMIC_BUSY, 0, "smic_write_cmd_data busy")); 503 } 504 505 int 506 smic_read_data(struct ipmi_softc *sc, u_int8_t *data) 507 { 508 int sts; 509 510 sts = smic_wait(sc, SMIC_RX_DATA_RDY | SMIC_BUSY, SMIC_RX_DATA_RDY, 511 "smic_read_data"); 512 if (sts >= 0) { 513 *data = bmc_read(sc, _SMIC_DATAIN_REG); 514 dbg_printf(50, "smic_readdata: %.2x\n", *data); 515 } 516 return (sts); 517 } 518 519 #define ErrStat(a,b) if (a) printf(b); 520 521 int 522 smic_sendmsg(struct ipmi_cmd *c) 523 { 524 struct ipmi_softc *sc = c->c_sc; 525 int sts, idx; 526 527 sts = smic_write_cmd_data(sc, SMS_CC_START_TRANSFER, &sc->sc_buf[0]); 528 ErrStat(sts != SMS_SC_WRITE_START, "wstart"); 529 for (idx = 1; idx < c->c_txlen - 1; idx++) { 530 sts = smic_write_cmd_data(sc, SMS_CC_NEXT_TRANSFER, 531 &sc->sc_buf[idx]); 532 ErrStat(sts != SMS_SC_WRITE_NEXT, "write"); 533 } 534 sts = smic_write_cmd_data(sc, SMS_CC_END_TRANSFER, &sc->sc_buf[idx]); 535 if (sts != SMS_SC_WRITE_END) { 536 dbg_printf(50, "smic_sendmsg %d/%d = %.2x\n", idx, c->c_txlen, sts); 537 return (-1); 538 } 539 540 return (0); 541 } 542 543 int 544 smic_recvmsg(struct ipmi_cmd *c) 545 { 546 struct ipmi_softc *sc = c->c_sc; 547 int sts, idx; 548 549 c->c_rxlen = 0; 550 sts = smic_wait(sc, SMIC_RX_DATA_RDY, SMIC_RX_DATA_RDY, "smic_recvmsg"); 551 if (sts < 0) 552 return (-1); 553 554 sts = smic_write_cmd_data(sc, SMS_CC_START_RECEIVE, NULL); 555 ErrStat(sts != SMS_SC_READ_START, "rstart"); 556 for (idx = 0;; ) { 557 sts = smic_read_data(sc, &sc->sc_buf[idx++]); 558 if (sts != SMS_SC_READ_START && sts != SMS_SC_READ_NEXT) 559 break; 560 smic_write_cmd_data(sc, SMS_CC_NEXT_RECEIVE, NULL); 561 } 562 ErrStat(sts != SMS_SC_READ_END, "rend"); 563 564 c->c_rxlen = idx; 565 566 sts = smic_write_cmd_data(sc, SMS_CC_END_RECEIVE, NULL); 567 if (sts != SMS_SC_READY) { 568 dbg_printf(50, "smic_recvmsg %d/%d = %.2x\n", idx, c->c_maxrxlen, sts); 569 return (-1); 570 } 571 572 return (0); 573 } 574 575 int 576 smic_reset(struct ipmi_softc *sc) 577 { 578 return (-1); 579 } 580 581 int 582 smic_probe(struct ipmi_softc *sc) 583 { 584 /* Flag register should not be 0xFF on a good system */ 585 if (bmc_read(sc, _SMIC_FLAG_REG) == 0xFF) 586 return (-1); 587 588 return (0); 589 } 590 591 /* 592 * KCS interface 593 */ 594 #define _KCS_DATAIN_REGISTER 0 595 #define _KCS_DATAOUT_REGISTER 0 596 #define KCS_READ_NEXT 0x68 597 598 #define _KCS_COMMAND_REGISTER 1 599 #define KCS_GET_STATUS 0x60 600 #define KCS_WRITE_START 0x61 601 #define KCS_WRITE_END 0x62 602 603 #define _KCS_STATUS_REGISTER 1 604 #define KCS_OBF (1L << 0) 605 #define KCS_IBF (1L << 1) 606 #define KCS_SMS_ATN (1L << 2) 607 #define KCS_CD (1L << 3) 608 #define KCS_OEM1 (1L << 4) 609 #define KCS_OEM2 (1L << 5) 610 #define KCS_STATE_MASK 0xc0 611 #define KCS_IDLE_STATE 0x00 612 #define KCS_READ_STATE 0x40 613 #define KCS_WRITE_STATE 0x80 614 #define KCS_ERROR_STATE 0xC0 615 616 int kcs_wait(struct ipmi_softc *, u_int8_t, u_int8_t, const char *); 617 int kcs_write_cmd(struct ipmi_softc *, u_int8_t); 618 int kcs_write_data(struct ipmi_softc *, u_int8_t); 619 int kcs_read_data(struct ipmi_softc *, u_int8_t *); 620 621 int 622 kcs_wait(struct ipmi_softc *sc, u_int8_t mask, u_int8_t value, const char *lbl) 623 { 624 struct ipmi_iowait a; 625 int v; 626 627 a.offset = _KCS_STATUS_REGISTER; 628 a.mask = mask; 629 a.value = value; 630 a.lbl = lbl; 631 v = bmc_io_wait(sc, &a); 632 if (v < 0) 633 return (v); 634 635 /* Check if output buffer full, read dummy byte */ 636 if ((v & (KCS_OBF | KCS_STATE_MASK)) == (KCS_OBF | KCS_WRITE_STATE)) 637 bmc_read(sc, _KCS_DATAIN_REGISTER); 638 639 /* Check for error state */ 640 if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE) { 641 bmc_write(sc, _KCS_COMMAND_REGISTER, KCS_GET_STATUS); 642 while (bmc_read(sc, _KCS_STATUS_REGISTER) & KCS_IBF) 643 continue; 644 printf("%s: error code: %x\n", DEVNAME(sc), 645 bmc_read(sc, _KCS_DATAIN_REGISTER)); 646 } 647 648 return (v & KCS_STATE_MASK); 649 } 650 651 int 652 kcs_write_cmd(struct ipmi_softc *sc, u_int8_t cmd) 653 { 654 /* ASSERT: IBF and OBF are clear */ 655 dbg_printf(50, "kcswritecmd: %.2x\n", cmd); 656 bmc_write(sc, _KCS_COMMAND_REGISTER, cmd); 657 658 return (kcs_wait(sc, KCS_IBF, 0, "write_cmd")); 659 } 660 661 int 662 kcs_write_data(struct ipmi_softc *sc, u_int8_t data) 663 { 664 /* ASSERT: IBF and OBF are clear */ 665 dbg_printf(50, "kcswritedata: %.2x\n", data); 666 bmc_write(sc, _KCS_DATAOUT_REGISTER, data); 667 668 return (kcs_wait(sc, KCS_IBF, 0, "write_data")); 669 } 670 671 int 672 kcs_read_data(struct ipmi_softc *sc, u_int8_t * data) 673 { 674 int sts; 675 676 sts = kcs_wait(sc, KCS_IBF | KCS_OBF, KCS_OBF, "read_data"); 677 if (sts != KCS_READ_STATE) 678 return (sts); 679 680 /* ASSERT: OBF is set read data, request next byte */ 681 *data = bmc_read(sc, _KCS_DATAIN_REGISTER); 682 bmc_write(sc, _KCS_DATAOUT_REGISTER, KCS_READ_NEXT); 683 684 dbg_printf(50, "kcsreaddata: %.2x\n", *data); 685 686 return (sts); 687 } 688 689 /* Exported KCS functions */ 690 int 691 kcs_sendmsg(struct ipmi_cmd *c) 692 { 693 struct ipmi_softc *sc = c->c_sc; 694 int idx, sts; 695 696 /* ASSERT: IBF is clear */ 697 dbg_dump(50, "kcs sendmsg", c->c_txlen, sc->sc_buf); 698 sts = kcs_write_cmd(sc, KCS_WRITE_START); 699 for (idx = 0; idx < c->c_txlen; idx++) { 700 if (idx == c->c_txlen - 1) 701 sts = kcs_write_cmd(sc, KCS_WRITE_END); 702 703 if (sts != KCS_WRITE_STATE) 704 break; 705 706 sts = kcs_write_data(sc, sc->sc_buf[idx]); 707 } 708 if (sts != KCS_READ_STATE) { 709 dbg_printf(1, "kcs sendmsg = %d/%d <%.2x>\n", idx, c->c_txlen, sts); 710 dbg_dump(1, "kcs_sendmsg", c->c_txlen, sc->sc_buf); 711 return (-1); 712 } 713 714 return (0); 715 } 716 717 int 718 kcs_recvmsg(struct ipmi_cmd *c) 719 { 720 struct ipmi_softc *sc = c->c_sc; 721 int idx, sts; 722 723 for (idx = 0; idx < c->c_maxrxlen; idx++) { 724 sts = kcs_read_data(sc, &sc->sc_buf[idx]); 725 if (sts != KCS_READ_STATE) 726 break; 727 } 728 sts = kcs_wait(sc, KCS_IBF, 0, "recv"); 729 c->c_rxlen = idx; 730 if (sts != KCS_IDLE_STATE) { 731 dbg_printf(1, "kcs recvmsg = %d/%d <%.2x>\n", idx, c->c_maxrxlen, sts); 732 return (-1); 733 } 734 735 dbg_dump(50, "kcs recvmsg", idx, sc->sc_buf); 736 737 return (0); 738 } 739 740 int 741 kcs_reset(struct ipmi_softc *sc) 742 { 743 return (-1); 744 } 745 746 int 747 kcs_probe(struct ipmi_softc *sc) 748 { 749 u_int8_t v; 750 751 v = bmc_read(sc, _KCS_STATUS_REGISTER); 752 if ((v & KCS_STATE_MASK) == KCS_ERROR_STATE) 753 return (1); 754 #if 0 755 printf("kcs_probe: %2x\n", v); 756 printf(" STS: %2x\n", v & KCS_STATE_MASK); 757 printf(" ATN: %2x\n", v & KCS_SMS_ATN); 758 printf(" C/D: %2x\n", v & KCS_CD); 759 printf(" IBF: %2x\n", v & KCS_IBF); 760 printf(" OBF: %2x\n", v & KCS_OBF); 761 #endif 762 return (0); 763 } 764 765 /* 766 * IPMI code 767 */ 768 #define READ_SMS_BUFFER 0x37 769 #define WRITE_I2C 0x50 770 771 #define GET_MESSAGE_CMD 0x33 772 #define SEND_MESSAGE_CMD 0x34 773 774 #define IPMB_CHANNEL_NUMBER 0 775 776 #define PUBLIC_BUS 0 777 778 #define MIN_I2C_PACKET_SIZE 3 779 #define MIN_IMB_PACKET_SIZE 7 /* one byte for cksum */ 780 781 #define MIN_BTBMC_REQ_SIZE 4 782 #define MIN_BTBMC_RSP_SIZE 5 783 #define MIN_BMC_REQ_SIZE 2 784 #define MIN_BMC_RSP_SIZE 3 785 786 #define BMC_SA 0x20 /* BMC/ESM3 */ 787 #define FPC_SA 0x22 /* front panel */ 788 #define BP_SA 0xC0 /* Primary Backplane */ 789 #define BP2_SA 0xC2 /* Secondary Backplane */ 790 #define PBP_SA 0xC4 /* Peripheral Backplane */ 791 #define DRAC_SA 0x28 /* DRAC-III */ 792 #define DRAC3_SA 0x30 /* DRAC-III */ 793 #define BMC_LUN 0 794 #define SMS_LUN 2 795 796 struct ipmi_request { 797 u_int8_t rsSa; 798 u_int8_t rsLun; 799 u_int8_t netFn; 800 u_int8_t cmd; 801 u_int8_t data_len; 802 u_int8_t *data; 803 }; 804 805 struct ipmi_response { 806 u_int8_t cCode; 807 u_int8_t data_len; 808 u_int8_t *data; 809 }; 810 811 struct ipmi_bmc_request { 812 u_int8_t bmc_nfLn; 813 u_int8_t bmc_cmd; 814 u_int8_t bmc_data_len; 815 u_int8_t bmc_data[1]; 816 }; 817 818 struct ipmi_bmc_response { 819 u_int8_t bmc_nfLn; 820 u_int8_t bmc_cmd; 821 u_int8_t bmc_cCode; 822 u_int8_t bmc_data_len; 823 u_int8_t bmc_data[1]; 824 }; 825 826 struct cfattach ipmi_ca = { 827 sizeof(struct ipmi_softc), ipmi_match, ipmi_attach, 828 NULL, ipmi_activate 829 }; 830 831 struct cfdriver ipmi_cd = { 832 NULL, "ipmi", DV_DULL 833 }; 834 835 /* Scan memory for signature */ 836 void * 837 scan_sig(long start, long end, int skip, int len, const void *data) 838 { 839 void *va; 840 841 while (start < end) { 842 va = ISA_HOLE_VADDR(start); 843 if (memcmp(va, data, len) == 0) 844 return (va); 845 846 start += skip; 847 } 848 849 return (NULL); 850 } 851 852 void 853 dumpb(const char *lbl, int len, const u_int8_t *data) 854 { 855 int idx; 856 857 printf("%s: ", lbl); 858 for (idx = 0; idx < len; idx++) 859 printf("%.2x ", data[idx]); 860 861 printf("\n"); 862 } 863 864 void 865 ipmi_smbios_probe(struct smbios_ipmi *pipmi, struct ipmi_attach_args *ia) 866 { 867 868 dbg_printf(1, "ipmi_smbios_probe: %02x %02x %02x %02x %08llx %02x " 869 "%02x\n", 870 pipmi->smipmi_if_type, 871 pipmi->smipmi_if_rev, 872 pipmi->smipmi_i2c_address, 873 pipmi->smipmi_nvram_address, 874 pipmi->smipmi_base_address, 875 pipmi->smipmi_base_flags, 876 pipmi->smipmi_irq); 877 878 ia->iaa_if_type = pipmi->smipmi_if_type; 879 ia->iaa_if_rev = pipmi->smipmi_if_rev; 880 ia->iaa_if_irq = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQEN) ? 881 pipmi->smipmi_irq : -1; 882 ia->iaa_if_irqlvl = (pipmi->smipmi_base_flags & SMIPMI_FLAG_IRQLVL) ? 883 IST_LEVEL : IST_EDGE; 884 885 switch (SMIPMI_FLAG_IFSPACING(pipmi->smipmi_base_flags)) { 886 case IPMI_IOSPACING_BYTE: 887 ia->iaa_if_iospacing = 1; 888 break; 889 890 case IPMI_IOSPACING_DWORD: 891 ia->iaa_if_iospacing = 4; 892 break; 893 894 case IPMI_IOSPACING_WORD: 895 ia->iaa_if_iospacing = 2; 896 break; 897 898 default: 899 ia->iaa_if_iospacing = 1; 900 printf("ipmi: unknown register spacing\n"); 901 } 902 903 /* Calculate base address (PCI BAR format) */ 904 if (pipmi->smipmi_base_address & 0x1) { 905 ia->iaa_if_iotype = 'i'; 906 ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0x1; 907 } else { 908 ia->iaa_if_iotype = 'm'; 909 ia->iaa_if_iobase = pipmi->smipmi_base_address & ~0xF; 910 } 911 if (pipmi->smipmi_base_flags & SMIPMI_FLAG_ODDOFFSET) 912 ia->iaa_if_iobase++; 913 914 if (pipmi->smipmi_base_flags == 0x7f) { 915 /* IBM 325 eServer workaround */ 916 ia->iaa_if_iospacing = 1; 917 ia->iaa_if_iobase = pipmi->smipmi_base_address; 918 ia->iaa_if_iotype = 'i'; 919 return; 920 } 921 } 922 923 /* 924 * bt_buildmsg builds an IPMI message from a nfLun, cmd, and data 925 * This is used by BT protocol 926 */ 927 void 928 bt_buildmsg(struct ipmi_cmd *c) 929 { 930 struct ipmi_softc *sc = c->c_sc; 931 u_int8_t *buf = sc->sc_buf; 932 933 buf[IPMI_BTMSG_LEN] = c->c_txlen + (IPMI_BTMSG_DATASND - 1); 934 buf[IPMI_BTMSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun); 935 buf[IPMI_BTMSG_SEQ] = sc->sc_btseq++; 936 buf[IPMI_BTMSG_CMD] = c->c_cmd; 937 if (c->c_txlen && c->c_data) 938 memcpy(buf + IPMI_BTMSG_DATASND, c->c_data, c->c_txlen); 939 } 940 941 /* 942 * cmn_buildmsg builds an IPMI message from a nfLun, cmd, and data 943 * This is used by both SMIC and KCS protocols 944 */ 945 void 946 cmn_buildmsg(struct ipmi_cmd *c) 947 { 948 struct ipmi_softc *sc = c->c_sc; 949 u_int8_t *buf = sc->sc_buf; 950 951 buf[IPMI_MSG_NFLN] = NETFN_LUN(c->c_netfn, c->c_rslun); 952 buf[IPMI_MSG_CMD] = c->c_cmd; 953 if (c->c_txlen && c->c_data) 954 memcpy(buf + IPMI_MSG_DATASND, c->c_data, c->c_txlen); 955 } 956 957 /* Send an IPMI command */ 958 int 959 ipmi_sendcmd(struct ipmi_cmd *c) 960 { 961 struct ipmi_softc *sc = c->c_sc; 962 int rc = -1; 963 964 dbg_printf(50, "ipmi_sendcmd: rssa=%.2x nfln=%.2x cmd=%.2x len=%.2x\n", 965 c->c_rssa, NETFN_LUN(c->c_netfn, c->c_rslun), c->c_cmd, c->c_txlen); 966 dbg_dump(10, " send", c->c_txlen, c->c_data); 967 if (c->c_rssa != BMC_SA) { 968 #if 0 969 sc->sc_if->buildmsg(c); 970 pI2C->bus = (sc->if_ver == 0x09) ? 971 PUBLIC_BUS : 972 IPMB_CHANNEL_NUMBER; 973 974 imbreq->rsSa = rssa; 975 imbreq->nfLn = NETFN_LUN(netfn, rslun); 976 imbreq->cSum1 = -(imbreq->rsSa + imbreq->nfLn); 977 imbreq->rqSa = BMC_SA; 978 imbreq->seqLn = NETFN_LUN(sc->imb_seq++, SMS_LUN); 979 imbreq->cmd = cmd; 980 if (txlen) 981 memcpy(imbreq->data, data, txlen); 982 /* Set message checksum */ 983 imbreq->data[txlen] = cksum8(&imbreq->rqSa, txlen + 3); 984 #endif 985 goto done; 986 } else 987 sc->sc_if->buildmsg(c); 988 989 c->c_txlen += sc->sc_if->datasnd; 990 rc = sc->sc_if->sendmsg(c); 991 992 done: 993 return (rc); 994 } 995 996 /* Receive an IPMI command */ 997 int 998 ipmi_recvcmd(struct ipmi_cmd *c) 999 { 1000 struct ipmi_softc *sc = c->c_sc; 1001 u_int8_t *buf = sc->sc_buf, rc = 0; 1002 1003 /* Receive message from interface, copy out result data */ 1004 c->c_maxrxlen += sc->sc_if->datarcv; 1005 if (sc->sc_if->recvmsg(c) || 1006 c->c_rxlen < sc->sc_if->datarcv) { 1007 return (-1); 1008 } 1009 1010 c->c_rxlen -= sc->sc_if->datarcv; 1011 if (c->c_rxlen > 0 && c->c_data) 1012 memcpy(c->c_data, buf + sc->sc_if->datarcv, c->c_rxlen); 1013 1014 rc = buf[IPMI_MSG_CCODE]; 1015 #ifdef IPMI_DEBUG 1016 if (rc != 0) 1017 dbg_printf(1, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x\n", 1018 buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE]); 1019 #endif 1020 1021 dbg_printf(50, "ipmi_recvcmd: nfln=%.2x cmd=%.2x err=%.2x len=%.2x\n", 1022 buf[IPMI_MSG_NFLN], buf[IPMI_MSG_CMD], buf[IPMI_MSG_CCODE], 1023 c->c_rxlen); 1024 dbg_dump(10, " recv", c->c_rxlen, c->c_data); 1025 1026 return (rc); 1027 } 1028 1029 void 1030 ipmi_cmd(struct ipmi_cmd *c) 1031 { 1032 if (cold || panicstr != NULL) 1033 ipmi_cmd_poll(c); 1034 else 1035 ipmi_cmd_wait(c); 1036 } 1037 1038 void 1039 ipmi_cmd_poll(struct ipmi_cmd *c) 1040 { 1041 mtx_enter(&c->c_sc->sc_cmd_mtx); 1042 1043 if (ipmi_sendcmd(c)) { 1044 panic("%s: sendcmd fails", DEVNAME(c->c_sc)); 1045 } 1046 c->c_ccode = ipmi_recvcmd(c); 1047 1048 mtx_leave(&c->c_sc->sc_cmd_mtx); 1049 } 1050 1051 void 1052 ipmi_cmd_wait(struct ipmi_cmd *c) 1053 { 1054 struct task t; 1055 int res; 1056 1057 task_set(&t, ipmi_cmd_wait_cb, c); 1058 res = task_add(c->c_sc->sc_cmd_taskq, &t); 1059 KASSERT(res == 1); 1060 1061 tsleep(c, PWAIT, "ipmicmd", 0); 1062 1063 res = task_del(c->c_sc->sc_cmd_taskq, &t); 1064 KASSERT(res == 0); 1065 } 1066 1067 void 1068 ipmi_cmd_wait_cb(void *arg) 1069 { 1070 struct ipmi_cmd *c = arg; 1071 1072 ipmi_cmd_poll(c); 1073 wakeup(c); 1074 } 1075 1076 /* Read a partial SDR entry */ 1077 int 1078 get_sdr_partial(struct ipmi_softc *sc, u_int16_t recordId, u_int16_t reserveId, 1079 u_int8_t offset, u_int8_t length, void *buffer, u_int16_t *nxtRecordId) 1080 { 1081 u_int8_t cmd[IPMI_GET_WDOG_MAX + 255]; /* 8 + max of length */ 1082 int len; 1083 1084 ((u_int16_t *) cmd)[0] = reserveId; 1085 ((u_int16_t *) cmd)[1] = recordId; 1086 cmd[4] = offset; 1087 cmd[5] = length; 1088 1089 struct ipmi_cmd c; 1090 c.c_sc = sc; 1091 c.c_rssa = BMC_SA; 1092 c.c_rslun = BMC_LUN; 1093 c.c_netfn = STORAGE_NETFN; 1094 c.c_cmd = STORAGE_GET_SDR; 1095 c.c_txlen = IPMI_SET_WDOG_MAX; 1096 c.c_rxlen = 0; 1097 c.c_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_NOWAIT | 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