1 /* $OpenBSD: ipmi.c,v 1.98 2017/06/29 03:48:44 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_maxrxlen = 8 + length; 1098 c.c_data = cmd; 1099 ipmi_cmd(&c); 1100 len = c.c_rxlen; 1101 1102 if (nxtRecordId) 1103 *nxtRecordId = *(uint16_t *) cmd; 1104 if (len > 2) 1105 memcpy(buffer, cmd + 2, len - 2); 1106 else 1107 return (1); 1108 1109 return (0); 1110 } 1111 1112 int maxsdrlen = 0x10; 1113 1114 /* Read an entire SDR; pass to add sensor */ 1115 int 1116 get_sdr(struct ipmi_softc *sc, u_int16_t recid, u_int16_t *nxtrec) 1117 { 1118 u_int16_t resid = 0; 1119 int len, sdrlen, offset; 1120 u_int8_t *psdr; 1121 struct sdrhdr shdr; 1122 1123 /* Reserve SDR */ 1124 struct ipmi_cmd c; 1125 c.c_sc = sc; 1126 c.c_rssa = BMC_SA; 1127 c.c_rslun = BMC_LUN; 1128 c.c_netfn = STORAGE_NETFN; 1129 c.c_cmd = STORAGE_RESERVE_SDR; 1130 c.c_txlen = 0; 1131 c.c_maxrxlen = sizeof(resid); 1132 c.c_rxlen = 0; 1133 c.c_data = &resid; 1134 ipmi_cmd(&c); 1135 1136 /* Get SDR Header */ 1137 if (get_sdr_partial(sc, recid, resid, 0, sizeof shdr, &shdr, nxtrec)) { 1138 printf("%s: get header fails\n", DEVNAME(sc)); 1139 return (1); 1140 } 1141 /* Allocate space for entire SDR Length of SDR in header does not 1142 * include header length */ 1143 sdrlen = sizeof(shdr) + shdr.record_length; 1144 psdr = malloc(sdrlen, M_DEVBUF, M_NOWAIT); 1145 if (psdr == NULL) 1146 return (1); 1147 1148 memcpy(psdr, &shdr, sizeof(shdr)); 1149 1150 /* Read SDR Data maxsdrlen bytes at a time */ 1151 for (offset = sizeof(shdr); offset < sdrlen; offset += maxsdrlen) { 1152 len = sdrlen - offset; 1153 if (len > maxsdrlen) 1154 len = maxsdrlen; 1155 1156 if (get_sdr_partial(sc, recid, resid, offset, len, 1157 psdr + offset, NULL)) { 1158 printf("%s: get chunk: %d,%d fails\n", DEVNAME(sc), 1159 offset, len); 1160 free(psdr, M_DEVBUF, sdrlen); 1161 return (1); 1162 } 1163 } 1164 1165 /* Add SDR to sensor list, if not wanted, free buffer */ 1166 if (add_sdr_sensor(sc, psdr, sdrlen) == 0) 1167 free(psdr, M_DEVBUF, sdrlen); 1168 1169 return (0); 1170 } 1171 1172 int 1173 getbits(u_int8_t *bytes, int bitpos, int bitlen) 1174 { 1175 int v; 1176 int mask; 1177 1178 bitpos += bitlen - 1; 1179 for (v = 0; bitlen--;) { 1180 v <<= 1; 1181 mask = 1L << (bitpos & 7); 1182 if (bytes[bitpos >> 3] & mask) 1183 v |= 1; 1184 bitpos--; 1185 } 1186 1187 return (v); 1188 } 1189 1190 /* Decode IPMI sensor name */ 1191 int 1192 ipmi_sensor_name(char *name, int len, u_int8_t typelen, u_int8_t *bits, 1193 int bitslen) 1194 { 1195 int i, slen; 1196 char bcdplus[] = "0123456789 -.:,_"; 1197 1198 slen = typelen & 0x1F; 1199 switch (typelen >> 6) { 1200 case IPMI_NAME_UNICODE: 1201 //unicode 1202 break; 1203 1204 case IPMI_NAME_BCDPLUS: 1205 /* Characters are encoded in 4-bit BCDPLUS */ 1206 if (len < slen * 2 + 1) 1207 slen = (len >> 1) - 1; 1208 if (slen > bitslen) 1209 return (0); 1210 for (i = 0; i < slen; i++) { 1211 *(name++) = bcdplus[bits[i] >> 4]; 1212 *(name++) = bcdplus[bits[i] & 0xF]; 1213 } 1214 break; 1215 1216 case IPMI_NAME_ASCII6BIT: 1217 /* Characters are encoded in 6-bit ASCII 1218 * 0x00 - 0x3F maps to 0x20 - 0x5F */ 1219 /* XXX: need to calculate max len: slen = 3/4 * len */ 1220 if (len < slen + 1) 1221 slen = len - 1; 1222 if (slen * 6 / 8 > bitslen) 1223 return (0); 1224 for (i = 0; i < slen * 8; i += 6) { 1225 *(name++) = getbits(bits, i, 6) + ' '; 1226 } 1227 break; 1228 1229 case IPMI_NAME_ASCII8BIT: 1230 /* Characters are 8-bit ascii */ 1231 if (len < slen + 1) 1232 slen = len - 1; 1233 if (slen > bitslen) 1234 return (0); 1235 while (slen--) 1236 *(name++) = *(bits++); 1237 break; 1238 } 1239 *name = 0; 1240 1241 return (1); 1242 } 1243 1244 /* Calculate val * 10^exp */ 1245 long 1246 ipow(long val, int exp) 1247 { 1248 while (exp > 0) { 1249 val *= 10; 1250 exp--; 1251 } 1252 1253 while (exp < 0) { 1254 val /= 10; 1255 exp++; 1256 } 1257 1258 return (val); 1259 } 1260 1261 /* Sign extend a n-bit value */ 1262 long 1263 signextend(unsigned long val, int bits) 1264 { 1265 long msk = (1L << (bits-1))-1; 1266 1267 return (-(val & ~msk) | val); 1268 } 1269 1270 /* Convert IPMI reading from sensor factors */ 1271 long 1272 ipmi_convert(u_int8_t v, struct sdrtype1 *s1, long adj) 1273 { 1274 short M, B; 1275 char K1, K2; 1276 long val; 1277 1278 /* Calculate linear reading variables */ 1279 M = signextend((((short)(s1->m_tolerance & 0xC0)) << 2) + s1->m, 10); 1280 B = signextend((((short)(s1->b_accuracy & 0xC0)) << 2) + s1->b, 10); 1281 K1 = signextend(s1->rbexp & 0xF, 4); 1282 K2 = signextend(s1->rbexp >> 4, 4); 1283 1284 /* Calculate sensor reading: 1285 * y = L((M * v + (B * 10^K1)) * 10^(K2+adj) 1286 * 1287 * This commutes out to: 1288 * y = L(M*v * 10^(K2+adj) + B * 10^(K1+K2+adj)); */ 1289 val = ipow(M * v, K2 + adj) + ipow(B, K1 + K2 + adj); 1290 1291 /* Linearization function: y = f(x) 0 : y = x 1 : y = ln(x) 2 : y = 1292 * log10(x) 3 : y = log2(x) 4 : y = e^x 5 : y = 10^x 6 : y = 2^x 7 : y 1293 * = 1/x 8 : y = x^2 9 : y = x^3 10 : y = square root(x) 11 : y = cube 1294 * root(x) */ 1295 return (val); 1296 } 1297 1298 int 1299 ipmi_sensor_status(struct ipmi_softc *sc, struct ipmi_sensor *psensor, 1300 u_int8_t *reading) 1301 { 1302 struct sdrtype1 *s1 = (struct sdrtype1 *)psensor->i_sdr; 1303 int etype; 1304 1305 /* Get reading of sensor */ 1306 switch (psensor->i_sensor.type) { 1307 case SENSOR_TEMP: 1308 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6); 1309 psensor->i_sensor.value += 273150000; 1310 break; 1311 1312 case SENSOR_VOLTS_DC: 1313 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 6); 1314 break; 1315 1316 case SENSOR_FANRPM: 1317 psensor->i_sensor.value = ipmi_convert(reading[0], s1, 0); 1318 if (((s1->units1>>3)&0x7) == 0x3) 1319 psensor->i_sensor.value *= 60; // RPS -> RPM 1320 break; 1321 default: 1322 break; 1323 } 1324 1325 /* Return Sensor Status */ 1326 etype = (psensor->etype << 8) + psensor->stype; 1327 switch (etype) { 1328 case IPMI_SENSOR_TYPE_TEMP: 1329 case IPMI_SENSOR_TYPE_VOLT: 1330 case IPMI_SENSOR_TYPE_FAN: 1331 /* non-recoverable threshold */ 1332 if (reading[2] & ((1 << 5) | (1 << 2))) 1333 return (SENSOR_S_CRIT); 1334 /* critical threshold */ 1335 else if (reading[2] & ((1 << 4) | (1 << 1))) 1336 return (SENSOR_S_CRIT); 1337 /* non-critical threshold */ 1338 else if (reading[2] & ((1 << 3) | (1 << 0))) 1339 return (SENSOR_S_WARN); 1340 break; 1341 1342 case IPMI_SENSOR_TYPE_INTRUSION: 1343 psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0; 1344 if (reading[2] & 0x1) 1345 return (SENSOR_S_CRIT); 1346 break; 1347 1348 case IPMI_SENSOR_TYPE_PWRSUPPLY: 1349 /* Reading: 1 = present+powered, 0 = otherwise */ 1350 psensor->i_sensor.value = (reading[2] & 1) ? 1 : 0; 1351 if (reading[2] & 0x10) { 1352 /* XXX: Need sysctl type for Power Supply types 1353 * ok: power supply installed && powered 1354 * warn: power supply installed && !powered 1355 * crit: power supply !installed 1356 */ 1357 return (SENSOR_S_CRIT); 1358 } 1359 if (reading[2] & 0x08) { 1360 /* Power supply AC lost */ 1361 return (SENSOR_S_WARN); 1362 } 1363 break; 1364 } 1365 1366 return (SENSOR_S_OK); 1367 } 1368 1369 int 1370 read_sensor(struct ipmi_softc *sc, struct ipmi_sensor *psensor) 1371 { 1372 struct sdrtype1 *s1 = (struct sdrtype1 *) psensor->i_sdr; 1373 u_int8_t data[8]; 1374 int rv = -1; 1375 1376 memset(data, 0, sizeof(data)); 1377 data[0] = psensor->i_num; 1378 1379 struct ipmi_cmd c; 1380 c.c_sc = sc; 1381 c.c_rssa = s1->owner_id; 1382 c.c_rslun = s1->owner_lun; 1383 c.c_netfn = SE_NETFN; 1384 c.c_cmd = SE_GET_SENSOR_READING; 1385 c.c_txlen = 1; 1386 c.c_maxrxlen = sizeof(data); 1387 c.c_rxlen = 0; 1388 c.c_data = data; 1389 ipmi_cmd(&c); 1390 1391 dbg_printf(10, "values=%.2x %.2x %.2x %.2x %s\n", 1392 data[0],data[1],data[2],data[3], psensor->i_sensor.desc); 1393 psensor->i_sensor.flags &= ~SENSOR_FINVALID; 1394 if ((data[1] & IPMI_INVALID_SENSOR) || 1395 ((data[1] & IPMI_DISABLED_SENSOR) == 0 && data[0] == 0)) 1396 psensor->i_sensor.flags |= SENSOR_FINVALID; 1397 psensor->i_sensor.status = ipmi_sensor_status(sc, psensor, data); 1398 rv = 0; 1399 return (rv); 1400 } 1401 1402 int 1403 ipmi_sensor_type(int type, int ext_type, int entity) 1404 { 1405 switch (ext_type << 8L | type) { 1406 case IPMI_SENSOR_TYPE_TEMP: 1407 return (SENSOR_TEMP); 1408 1409 case IPMI_SENSOR_TYPE_VOLT: 1410 return (SENSOR_VOLTS_DC); 1411 1412 case IPMI_SENSOR_TYPE_FAN: 1413 return (SENSOR_FANRPM); 1414 1415 case IPMI_SENSOR_TYPE_PWRSUPPLY: 1416 if (entity == IPMI_ENTITY_PWRSUPPLY) 1417 return (SENSOR_INDICATOR); 1418 break; 1419 1420 case IPMI_SENSOR_TYPE_INTRUSION: 1421 return (SENSOR_INDICATOR); 1422 } 1423 1424 return (-1); 1425 } 1426 1427 /* Add Sensor to BSD Sysctl interface */ 1428 int 1429 add_sdr_sensor(struct ipmi_softc *sc, u_int8_t *psdr, int sdrlen) 1430 { 1431 int rc; 1432 struct sdrtype1 *s1 = (struct sdrtype1 *)psdr; 1433 struct sdrtype2 *s2 = (struct sdrtype2 *)psdr; 1434 char name[64]; 1435 1436 switch (s1->sdrhdr.record_type) { 1437 case IPMI_SDR_TYPEFULL: 1438 rc = ipmi_sensor_name(name, sizeof(name), s1->typelen, 1439 s1->name, sdrlen - (int)offsetof(struct sdrtype1, name)); 1440 if (rc == 0) 1441 return (0); 1442 rc = add_child_sensors(sc, psdr, 1, s1->sensor_num, 1443 s1->sensor_type, s1->event_code, 0, s1->entity_id, name); 1444 break; 1445 1446 case IPMI_SDR_TYPECOMPACT: 1447 rc = ipmi_sensor_name(name, sizeof(name), s2->typelen, 1448 s2->name, sdrlen - (int)offsetof(struct sdrtype2, name)); 1449 if (rc == 0) 1450 return (0); 1451 rc = add_child_sensors(sc, psdr, s2->share1 & 0xF, 1452 s2->sensor_num, s2->sensor_type, s2->event_code, 1453 s2->share2 & 0x7F, s2->entity_id, name); 1454 break; 1455 1456 default: 1457 return (0); 1458 } 1459 1460 return rc; 1461 } 1462 1463 int 1464 add_child_sensors(struct ipmi_softc *sc, u_int8_t *psdr, int count, 1465 int sensor_num, int sensor_type, int ext_type, int sensor_base, 1466 int entity, const char *name) 1467 { 1468 int typ, idx; 1469 struct ipmi_sensor *psensor; 1470 #ifdef IPMI_DEBUG 1471 struct sdrtype1 *s1 = (struct sdrtype1 *)psdr; 1472 #endif 1473 1474 typ = ipmi_sensor_type(sensor_type, ext_type, entity); 1475 if (typ == -1) { 1476 dbg_printf(5, "Unknown sensor type:%.2x et:%.2x sn:%.2x " 1477 "name:%s\n", sensor_type, ext_type, sensor_num, name); 1478 return 0; 1479 } 1480 for (idx = 0; idx < count; idx++) { 1481 psensor = malloc(sizeof(*psensor), M_DEVBUF, M_NOWAIT | M_ZERO); 1482 if (psensor == NULL) 1483 break; 1484 1485 /* Initialize BSD Sensor info */ 1486 psensor->i_sdr = psdr; 1487 psensor->i_num = sensor_num + idx; 1488 psensor->stype = sensor_type; 1489 psensor->etype = ext_type; 1490 psensor->i_sensor.type = typ; 1491 if (count > 1) 1492 snprintf(psensor->i_sensor.desc, 1493 sizeof(psensor->i_sensor.desc), 1494 "%s - %d", name, sensor_base + idx); 1495 else 1496 strlcpy(psensor->i_sensor.desc, name, 1497 sizeof(psensor->i_sensor.desc)); 1498 1499 dbg_printf(5, "add sensor:%.4x %.2x:%d ent:%.2x:%.2x %s\n", 1500 s1->sdrhdr.record_id, s1->sensor_type, 1501 typ, s1->entity_id, s1->entity_instance, 1502 psensor->i_sensor.desc); 1503 if (read_sensor(sc, psensor) == 0) { 1504 SLIST_INSERT_HEAD(&ipmi_sensor_list, psensor, list); 1505 sensor_attach(&sc->sc_sensordev, &psensor->i_sensor); 1506 dbg_printf(5, " reading: %lld [%s]\n", 1507 psensor->i_sensor.value, 1508 psensor->i_sensor.desc); 1509 } 1510 } 1511 1512 return (1); 1513 } 1514 1515 /* Handle IPMI Timer - reread sensor values */ 1516 void 1517 ipmi_refresh_sensors(struct ipmi_softc *sc) 1518 { 1519 if (SLIST_EMPTY(&ipmi_sensor_list)) 1520 return; 1521 1522 sc->current_sensor = SLIST_NEXT(sc->current_sensor, list); 1523 if (sc->current_sensor == NULL) 1524 sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list); 1525 1526 if (read_sensor(sc, sc->current_sensor)) { 1527 dbg_printf(1, "%s: error reading: %s\n", DEVNAME(sc), 1528 sc->current_sensor->i_sensor.desc); 1529 return; 1530 } 1531 } 1532 1533 int 1534 ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia) 1535 { 1536 sc->sc_if = ipmi_get_if(ia->iaa_if_type); 1537 if (sc->sc_if == NULL) 1538 return (-1); 1539 1540 if (ia->iaa_if_iotype == 'i') 1541 sc->sc_iot = ia->iaa_iot; 1542 else 1543 sc->sc_iot = ia->iaa_memt; 1544 1545 sc->sc_if_rev = ia->iaa_if_rev; 1546 sc->sc_if_iospacing = ia->iaa_if_iospacing; 1547 if (bus_space_map(sc->sc_iot, ia->iaa_if_iobase, 1548 sc->sc_if->nregs * sc->sc_if_iospacing, 1549 0, &sc->sc_ioh)) { 1550 printf("%s: bus_space_map(%lx %x %x 0 %p) failed\n", 1551 DEVNAME(sc), 1552 (unsigned long)sc->sc_iot, ia->iaa_if_iobase, 1553 sc->sc_if->nregs * sc->sc_if_iospacing, &sc->sc_ioh); 1554 return (-1); 1555 } 1556 return (0); 1557 } 1558 1559 void 1560 ipmi_unmap_regs(struct ipmi_softc *sc) 1561 { 1562 bus_space_unmap(sc->sc_iot, sc->sc_ioh, 1563 sc->sc_if->nregs * sc->sc_if_iospacing); 1564 } 1565 1566 void 1567 ipmi_poll_thread(void *arg) 1568 { 1569 struct ipmi_thread *thread = arg; 1570 struct ipmi_softc *sc = thread->sc; 1571 u_int16_t rec; 1572 1573 /* Scan SDRs, add sensors */ 1574 for (rec = 0; rec != 0xFFFF;) { 1575 if (get_sdr(sc, rec, &rec)) { 1576 ipmi_unmap_regs(sc); 1577 printf("%s: no SDRs IPMI disabled\n", DEVNAME(sc)); 1578 goto done; 1579 } 1580 while (tsleep(sc, PWAIT, "ipmirun", 1) != EWOULDBLOCK) 1581 continue; 1582 } 1583 1584 /* initialize sensor list for thread */ 1585 if (SLIST_EMPTY(&ipmi_sensor_list)) 1586 goto done; 1587 else 1588 sc->current_sensor = SLIST_FIRST(&ipmi_sensor_list); 1589 1590 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 1591 sizeof(sc->sc_sensordev.xname)); 1592 sensordev_install(&sc->sc_sensordev); 1593 1594 while (thread->running) { 1595 ipmi_refresh_sensors(sc); 1596 tsleep(thread, PWAIT, "ipmi_poll", SENSOR_REFRESH_RATE); 1597 } 1598 1599 done: 1600 kthread_exit(0); 1601 } 1602 1603 void 1604 ipmi_create_thread(void *arg) 1605 { 1606 struct ipmi_softc *sc = arg; 1607 1608 if (kthread_create(ipmi_poll_thread, sc->sc_thread, NULL, 1609 DEVNAME(sc)) != 0) { 1610 printf("%s: unable to create run thread, ipmi disabled\n", 1611 DEVNAME(sc)); 1612 return; 1613 } 1614 } 1615 1616 int 1617 ipmi_probe(void *aux) 1618 { 1619 struct ipmi_attach_args *ia = aux; 1620 struct dmd_ipmi *pipmi; 1621 struct smbtable tbl; 1622 1623 tbl.cookie = 0; 1624 if (smbios_find_table(SMBIOS_TYPE_IPMIDEV, &tbl)) 1625 ipmi_smbios_probe(tbl.tblhdr, ia); 1626 else { 1627 pipmi = (struct dmd_ipmi *)scan_sig(0xC0000L, 0xFFFFFL, 16, 4, 1628 "IPMI"); 1629 /* XXX hack to find Dell PowerEdge 8450 */ 1630 if (pipmi == NULL) { 1631 /* no IPMI found */ 1632 return (0); 1633 } 1634 1635 /* we have an IPMI signature, fill in attach arg structure */ 1636 ia->iaa_if_type = pipmi->dmd_if_type; 1637 ia->iaa_if_rev = pipmi->dmd_if_rev; 1638 } 1639 1640 return (1); 1641 } 1642 1643 int 1644 ipmi_match(struct device *parent, void *match, void *aux) 1645 { 1646 struct ipmi_softc *sc; 1647 struct ipmi_attach_args *ia = aux; 1648 struct cfdata *cf = match; 1649 u_int8_t cmd[32]; 1650 int rv = 0; 1651 1652 if (strcmp(ia->iaa_name, cf->cf_driver->cd_name)) 1653 return (0); 1654 1655 /* XXX local softc is wrong wrong wrong */ 1656 sc = malloc(sizeof(*sc), M_TEMP, M_NOWAIT | M_ZERO); 1657 mtx_init(&sc->sc_cmd_mtx, IPL_NONE); 1658 strlcpy(sc->sc_dev.dv_xname, "ipmi0", sizeof(sc->sc_dev.dv_xname)); 1659 1660 /* Map registers */ 1661 if (ipmi_map_regs(sc, ia) == 0) { 1662 sc->sc_if->probe(sc); 1663 1664 /* Identify BMC device early to detect lying bios */ 1665 struct ipmi_cmd c; 1666 c.c_sc = sc; 1667 c.c_rssa = BMC_SA; 1668 c.c_rslun = BMC_LUN; 1669 c.c_netfn = APP_NETFN; 1670 c.c_cmd = APP_GET_DEVICE_ID; 1671 c.c_txlen = 0; 1672 c.c_maxrxlen = sizeof(cmd); 1673 c.c_rxlen = 0; 1674 c.c_data = cmd; 1675 ipmi_cmd(&c); 1676 1677 dbg_dump(1, "bmc data", c.c_rxlen, cmd); 1678 rv = 1; /* GETID worked, we got IPMI */ 1679 ipmi_unmap_regs(sc); 1680 } 1681 1682 free(sc, M_TEMP, sizeof(*sc)); 1683 1684 return (rv); 1685 } 1686 1687 void 1688 ipmi_attach(struct device *parent, struct device *self, void *aux) 1689 { 1690 struct ipmi_softc *sc = (void *) self; 1691 struct ipmi_attach_args *ia = aux; 1692 struct ipmi_cmd *c = &sc->sc_ioctl.cmd; 1693 1694 /* Map registers */ 1695 ipmi_map_regs(sc, ia); 1696 1697 sc->sc_thread = malloc(sizeof(struct ipmi_thread), M_DEVBUF, M_NOWAIT); 1698 if (sc->sc_thread == NULL) { 1699 printf(": unable to allocate thread\n"); 1700 return; 1701 } 1702 sc->sc_thread->sc = sc; 1703 sc->sc_thread->running = 1; 1704 1705 /* Setup threads */ 1706 kthread_create_deferred(ipmi_create_thread, sc); 1707 1708 printf(": version %d.%d interface %s %sbase 0x%x/%x spacing %d", 1709 ia->iaa_if_rev >> 4, ia->iaa_if_rev & 0xF, sc->sc_if->name, 1710 ia->iaa_if_iotype == 'i' ? "io" : "mem", ia->iaa_if_iobase, 1711 ia->iaa_if_iospacing * sc->sc_if->nregs, ia->iaa_if_iospacing); 1712 if (ia->iaa_if_irq != -1) 1713 printf(" irq %d", ia->iaa_if_irq); 1714 printf("\n"); 1715 1716 /* setup flag to exclude iic */ 1717 ipmi_enabled = 1; 1718 1719 /* Setup Watchdog timer */ 1720 sc->sc_wdog_period = 0; 1721 task_set(&sc->sc_wdog_tickle_task, ipmi_watchdog_tickle, sc); 1722 wdog_register(ipmi_watchdog, sc); 1723 1724 rw_init(&sc->sc_ioctl.lock, DEVNAME(sc)); 1725 sc->sc_ioctl.req.msgid = -1; 1726 c->c_sc = sc; 1727 c->c_ccode = -1; 1728 1729 sc->sc_cmd_taskq = taskq_create("ipmicmd", 1, IPL_NONE, TASKQ_MPSAFE); 1730 mtx_init(&sc->sc_cmd_mtx, IPL_NONE); 1731 } 1732 1733 int 1734 ipmi_activate(struct device *self, int act) 1735 { 1736 switch (act) { 1737 case DVACT_POWERDOWN: 1738 wdog_shutdown(self); 1739 break; 1740 } 1741 1742 return (0); 1743 } 1744 1745 struct ipmi_softc * 1746 ipmilookup(dev_t dev) 1747 { 1748 return (struct ipmi_softc *)device_lookup(&ipmi_cd, minor(dev)); 1749 } 1750 1751 int 1752 ipmiopen(dev_t dev, int flags, int mode, struct proc *p) 1753 { 1754 struct ipmi_softc *sc = ipmilookup(dev); 1755 1756 if (sc == NULL) 1757 return (ENXIO); 1758 return (0); 1759 } 1760 1761 int 1762 ipmiclose(dev_t dev, int flags, int mode, struct proc *p) 1763 { 1764 struct ipmi_softc *sc = ipmilookup(dev); 1765 1766 if (sc == NULL) 1767 return (ENXIO); 1768 return (0); 1769 } 1770 1771 int 1772 ipmiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc) 1773 { 1774 struct ipmi_softc *sc = ipmilookup(dev); 1775 struct ipmi_req *req = (struct ipmi_req *)data; 1776 struct ipmi_recv *recv = (struct ipmi_recv *)data; 1777 struct ipmi_cmd *c = &sc->sc_ioctl.cmd; 1778 int iv; 1779 int len; 1780 u_char ccode; 1781 int rc = 0; 1782 1783 if (sc == NULL) 1784 return (ENXIO); 1785 1786 rw_enter_write(&sc->sc_ioctl.lock); 1787 1788 c->c_maxrxlen = sizeof(sc->sc_ioctl.buf); 1789 c->c_data = sc->sc_ioctl.buf; 1790 1791 switch (cmd) { 1792 case IPMICTL_SEND_COMMAND: 1793 if (req->msgid == -1) { 1794 rc = EINVAL; 1795 goto reset; 1796 } 1797 if (sc->sc_ioctl.req.msgid != -1) { 1798 rc = EBUSY; 1799 goto reset; 1800 } 1801 len = req->msg.data_len; 1802 if (len < 0) { 1803 rc = EINVAL; 1804 goto reset; 1805 } 1806 if (len > c->c_maxrxlen) { 1807 rc = E2BIG; 1808 goto reset; 1809 } 1810 sc->sc_ioctl.req = *req; 1811 c->c_ccode = -1; 1812 rc = copyin(req->msg.data, c->c_data, len); 1813 if (rc != 0) 1814 goto reset; 1815 KASSERT(c->c_ccode == -1); 1816 1817 /* Execute a command synchronously. */ 1818 c->c_netfn = req->msg.netfn; 1819 c->c_cmd = req->msg.cmd; 1820 c->c_txlen = req->msg.data_len; 1821 c->c_rxlen = 0; 1822 ipmi_cmd(c); 1823 1824 KASSERT(c->c_ccode != -1); 1825 break; 1826 case IPMICTL_RECEIVE_MSG_TRUNC: 1827 case IPMICTL_RECEIVE_MSG: 1828 if (sc->sc_ioctl.req.msgid == -1) { 1829 rc = EINVAL; 1830 goto reset; 1831 } 1832 if (c->c_ccode == -1) { 1833 rc = EAGAIN; 1834 goto reset; 1835 } 1836 ccode = c->c_ccode & 0xff; 1837 rc = copyout(&ccode, recv->msg.data, 1); 1838 if (rc != 0) 1839 goto reset; 1840 1841 /* Return a command result. */ 1842 recv->recv_type = IPMI_RESPONSE_RECV_TYPE; 1843 recv->msgid = sc->sc_ioctl.req.msgid; 1844 recv->msg.netfn = sc->sc_ioctl.req.msg.netfn; 1845 recv->msg.cmd = sc->sc_ioctl.req.msg.cmd; 1846 recv->msg.data_len = c->c_rxlen + 1; 1847 1848 rc = copyout(c->c_data, recv->msg.data + 1, c->c_rxlen); 1849 /* Always reset state after command completion. */ 1850 goto reset; 1851 case IPMICTL_SET_MY_ADDRESS_CMD: 1852 iv = *(int *)data; 1853 if (iv < 0 || iv > RSSA_MASK) { 1854 rc = EINVAL; 1855 goto reset; 1856 } 1857 c->c_rssa = iv; 1858 break; 1859 case IPMICTL_GET_MY_ADDRESS_CMD: 1860 *(int *)data = c->c_rssa; 1861 break; 1862 case IPMICTL_SET_MY_LUN_CMD: 1863 iv = *(int *)data; 1864 if (iv < 0 || iv > LUN_MASK) { 1865 rc = EINVAL; 1866 goto reset; 1867 } 1868 c->c_rslun = iv; 1869 break; 1870 case IPMICTL_GET_MY_LUN_CMD: 1871 *(int *)data = c->c_rslun; 1872 break; 1873 case IPMICTL_SET_GETS_EVENTS_CMD: 1874 break; 1875 case IPMICTL_REGISTER_FOR_CMD: 1876 case IPMICTL_UNREGISTER_FOR_CMD: 1877 default: 1878 break; 1879 } 1880 done: 1881 rw_exit_write(&sc->sc_ioctl.lock); 1882 return (rc); 1883 reset: 1884 sc->sc_ioctl.req.msgid = -1; 1885 c->c_ccode = -1; 1886 goto done; 1887 } 1888 1889 #define MIN_PERIOD 10 1890 1891 int 1892 ipmi_watchdog(void *arg, int period) 1893 { 1894 struct ipmi_softc *sc = arg; 1895 1896 if (sc->sc_wdog_period == period) { 1897 if (period != 0) { 1898 struct task *t; 1899 int res; 1900 1901 t = &sc->sc_wdog_tickle_task; 1902 (void)task_del(systq, t); 1903 res = task_add(systq, t); 1904 KASSERT(res == 1); 1905 } 1906 return (period); 1907 } 1908 1909 if (period < MIN_PERIOD && period > 0) 1910 period = MIN_PERIOD; 1911 sc->sc_wdog_period = period; 1912 ipmi_watchdog_set(sc); 1913 printf("%s: watchdog %sabled\n", DEVNAME(sc), 1914 (period == 0) ? "dis" : "en"); 1915 return (period); 1916 } 1917 1918 void 1919 ipmi_watchdog_tickle(void *arg) 1920 { 1921 struct ipmi_softc *sc = arg; 1922 struct ipmi_cmd c; 1923 1924 c.c_sc = sc; 1925 c.c_rssa = BMC_SA; 1926 c.c_rslun = BMC_LUN; 1927 c.c_netfn = APP_NETFN; 1928 c.c_cmd = APP_RESET_WATCHDOG; 1929 c.c_txlen = 0; 1930 c.c_maxrxlen = 0; 1931 c.c_rxlen = 0; 1932 c.c_data = NULL; 1933 ipmi_cmd(&c); 1934 } 1935 1936 void 1937 ipmi_watchdog_set(void *arg) 1938 { 1939 struct ipmi_softc *sc = arg; 1940 uint8_t wdog[IPMI_GET_WDOG_MAX]; 1941 struct ipmi_cmd c; 1942 1943 c.c_sc = sc; 1944 c.c_rssa = BMC_SA; 1945 c.c_rslun = BMC_LUN; 1946 c.c_netfn = APP_NETFN; 1947 c.c_cmd = APP_GET_WATCHDOG_TIMER; 1948 c.c_txlen = 0; 1949 c.c_maxrxlen = IPMI_GET_WDOG_MAX; 1950 c.c_rxlen = 0; 1951 c.c_data = wdog; 1952 ipmi_cmd(&c); 1953 1954 /* Period is 10ths/sec */ 1955 uint16_t timo = htole16(sc->sc_wdog_period * 10); 1956 1957 memcpy(&wdog[IPMI_SET_WDOG_TIMOL], &timo, 2); 1958 wdog[IPMI_SET_WDOG_TIMER] &= ~IPMI_WDOG_DONTSTOP; 1959 wdog[IPMI_SET_WDOG_TIMER] |= (sc->sc_wdog_period == 0) ? 1960 0 : IPMI_WDOG_DONTSTOP; 1961 wdog[IPMI_SET_WDOG_ACTION] &= ~IPMI_WDOG_MASK; 1962 wdog[IPMI_SET_WDOG_ACTION] |= (sc->sc_wdog_period == 0) ? 1963 IPMI_WDOG_DISABLED : IPMI_WDOG_REBOOT; 1964 1965 c.c_cmd = APP_SET_WATCHDOG_TIMER; 1966 c.c_txlen = IPMI_SET_WDOG_MAX; 1967 c.c_maxrxlen = 0; 1968 c.c_rxlen = 0; 1969 c.c_data = wdog; 1970 ipmi_cmd(&c); 1971 } 1972