1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2011 Sandvine Incorporated ULC. 5 * Copyright (c) 2012 iXsystems, Inc. 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR 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 * Support for Winbond watchdog. 31 * 32 * With minor abstractions it might be possible to add support for other 33 * different Winbond Super I/O chips as well. Winbond seems to have four 34 * different types of chips, four different ways to get into extended config 35 * mode. 36 * 37 * Note: there is no serialization between the debugging sysctl handlers and 38 * the watchdog functions and possibly others poking the registers at the same 39 * time. For that at least possibly interfering sysctls are hidden by default. 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD$"); 44 45 #include <sys/param.h> 46 #include <sys/kernel.h> 47 #include <sys/systm.h> 48 #include <sys/bus.h> 49 #include <sys/eventhandler.h> 50 #include <sys/lock.h> 51 #include <sys/module.h> 52 #include <sys/rman.h> 53 #include <sys/sbuf.h> 54 #include <sys/sysctl.h> 55 #include <sys/watchdog.h> 56 57 #include <isa/isavar.h> 58 59 #include <machine/bus.h> 60 #include <machine/resource.h> 61 62 /* 63 * Global registers. 64 */ 65 #define WB_DEVICE_ID_REG 0x20 /* Device ID */ 66 #define WB_DEVICE_REV_REG 0x21 /* Device revision */ 67 #define WB_CR26 0x26 /* Bit6: HEFRAS (base port selector) */ 68 69 /* LDN selection. */ 70 #define WB_LDN_REG 0x07 71 #define WB_LDN_REG_LDN8 0x08 /* GPIO 2, Watchdog */ 72 73 /* 74 * LDN8 (GPIO 2, Watchdog) specific registers and options. 75 */ 76 /* CR30: LDN8 activation control. */ 77 #define WB_LDN8_CR30 0x30 78 #define WB_LDN8_CR30_ACTIVE 0x01 /* 1: LD active */ 79 80 /* CRF5: Watchdog scale, P20. Mapped to reg_1. */ 81 #define WB_LDN8_CRF5 0xF5 82 #define WB_LDN8_CRF5_SCALE 0x08 /* 0: 1s, 1: 60s */ 83 #define WB_LDN8_CRF5_KEYB_P20 0x04 /* 1: keyb P20 forces timeout */ 84 #define WB_LDN8_CRF5_KBRST 0x02 /* 1: timeout causes pin60 kbd reset */ 85 86 /* CRF6: Watchdog Timeout (0 == off). Mapped to reg_timeout. */ 87 #define WB_LDN8_CRF6 0xF6 88 89 /* CRF7: Watchdog mouse, keyb, force, .. Mapped to reg_2. */ 90 #define WB_LDN8_CRF7 0xF7 91 #define WB_LDN8_CRF7_MOUSE 0x80 /* 1: mouse irq resets wd timer */ 92 #define WB_LDN8_CRF7_KEYB 0x40 /* 1: keyb irq resets wd timer */ 93 #define WB_LDN8_CRF7_FORCE 0x20 /* 1: force timeout (self-clear) */ 94 #define WB_LDN8_CRF7_TS 0x10 /* 0: counting, 1: fired */ 95 #define WB_LDN8_CRF7_IRQS 0x0f /* irq source for watchdog, 2 == SMI */ 96 97 enum chips { w83627hf, w83627s, w83697hf, w83697ug, w83637hf, w83627thf, 98 w83687thf, w83627ehf, w83627dhg, w83627uhg, w83667hg, 99 w83627dhg_p, w83667hg_b, nct6775, nct6776, nct6779, nct6791, 100 nct6792, nct6102 }; 101 102 struct wb_softc { 103 device_t dev; 104 struct resource *portres; 105 bus_space_tag_t bst; 106 bus_space_handle_t bsh; 107 int rid; 108 eventhandler_tag ev_tag; 109 int (*ext_cfg_enter_f)(struct wb_softc *, u_short); 110 void (*ext_cfg_exit_f)(struct wb_softc *, u_short); 111 enum chips chip; 112 uint8_t ctl_reg; 113 uint8_t time_reg; 114 uint8_t csr_reg; 115 int debug_verbose; 116 117 /* 118 * Special feature to let the watchdog fire at a different 119 * timeout as set by watchdog(4) but still use that API to 120 * re-load it periodically. 121 */ 122 unsigned int timeout_override; 123 124 /* 125 * Space to save current state temporary and for sysctls. 126 * We want to know the timeout value and usually need two 127 * additional registers for options. Do not name them by 128 * register as these might be different by chip. 129 */ 130 uint8_t reg_timeout; 131 uint8_t reg_1; 132 uint8_t reg_2; 133 }; 134 135 static int ext_cfg_enter_0x87_0x87(struct wb_softc *, u_short); 136 static void ext_cfg_exit_0xaa(struct wb_softc *, u_short); 137 138 struct winbond_superio_cfg { 139 uint8_t efer; /* and efir */ 140 int (*ext_cfg_enter_f)(struct wb_softc *, u_short); 141 void (*ext_cfg_exit_f)(struct wb_softc *, u_short); 142 } probe_addrs[] = { 143 { 144 .efer = 0x2e, 145 .ext_cfg_enter_f = ext_cfg_enter_0x87_0x87, 146 .ext_cfg_exit_f = ext_cfg_exit_0xaa, 147 }, 148 { 149 .efer = 0x4e, 150 .ext_cfg_enter_f = ext_cfg_enter_0x87_0x87, 151 .ext_cfg_exit_f = ext_cfg_exit_0xaa, 152 }, 153 }; 154 155 struct winbond_vendor_device_id { 156 uint8_t device_id; 157 enum chips chip; 158 const char * descr; 159 } wb_devs[] = { 160 { 161 .device_id = 0x52, 162 .chip = w83627hf, 163 .descr = "Winbond 83627HF/F/HG/G", 164 }, 165 { 166 .device_id = 0x59, 167 .chip = w83627s, 168 .descr = "Winbond 83627S", 169 }, 170 { 171 .device_id = 0x60, 172 .chip = w83697hf, 173 .descr = "Winbond 83697HF", 174 }, 175 { 176 .device_id = 0x68, 177 .chip = w83697ug, 178 .descr = "Winbond 83697UG", 179 }, 180 { 181 .device_id = 0x70, 182 .chip = w83637hf, 183 .descr = "Winbond 83637HF", 184 }, 185 { 186 .device_id = 0x82, 187 .chip = w83627thf, 188 .descr = "Winbond 83627THF", 189 }, 190 { 191 .device_id = 0x85, 192 .chip = w83687thf, 193 .descr = "Winbond 83687THF", 194 }, 195 { 196 .device_id = 0x88, 197 .chip = w83627ehf, 198 .descr = "Winbond 83627EHF", 199 }, 200 { 201 .device_id = 0xa0, 202 .chip = w83627dhg, 203 .descr = "Winbond 83627DHG", 204 }, 205 { 206 .device_id = 0xa2, 207 .chip = w83627uhg, 208 .descr = "Winbond 83627UHG", 209 }, 210 { 211 .device_id = 0xa5, 212 .chip = w83667hg, 213 .descr = "Winbond 83667HG", 214 }, 215 { 216 .device_id = 0xb0, 217 .chip = w83627dhg_p, 218 .descr = "Winbond 83627DHG-P", 219 }, 220 { 221 .device_id = 0xb3, 222 .chip = w83667hg_b, 223 .descr = "Winbond 83667HG-B", 224 }, 225 { 226 .device_id = 0xb4, 227 .chip = nct6775, 228 .descr = "Nuvoton NCT6775", 229 }, 230 { 231 .device_id = 0xc3, 232 .chip = nct6776, 233 .descr = "Nuvoton NCT6776", 234 }, 235 { 236 .device_id = 0xc4, 237 .chip = nct6102, 238 .descr = "Nuvoton NCT6102", 239 }, 240 { 241 .device_id = 0xc5, 242 .chip = nct6779, 243 .descr = "Nuvoton NCT6779", 244 }, 245 { 246 .device_id = 0xc8, 247 .chip = nct6791, 248 .descr = "Nuvoton NCT6791", 249 }, 250 { 251 .device_id = 0xc9, 252 .chip = nct6792, 253 .descr = "Nuvoton NCT6792", 254 }, 255 }; 256 257 static void 258 write_efir_1(struct wb_softc *sc, u_short baseport, uint8_t value) 259 { 260 261 MPASS(sc != NULL || baseport != 0); 262 if (sc != NULL) 263 bus_space_write_1((sc)->bst, (sc)->bsh, 0, (value)); 264 else 265 outb(baseport, value); 266 } 267 268 static uint8_t __unused 269 read_efir_1(struct wb_softc *sc, u_short baseport) 270 { 271 272 MPASS(sc != NULL || baseport != 0); 273 if (sc != NULL) 274 return (bus_space_read_1((sc)->bst, (sc)->bsh, 0)); 275 else 276 return (inb(baseport)); 277 } 278 279 static void 280 write_efdr_1(struct wb_softc *sc, u_short baseport, uint8_t value) 281 { 282 283 MPASS(sc != NULL || baseport != 0); 284 if (sc != NULL) 285 bus_space_write_1((sc)->bst, (sc)->bsh, 1, (value)); 286 else 287 outb(baseport + 1, value); 288 } 289 290 static uint8_t 291 read_efdr_1(struct wb_softc *sc, u_short baseport) 292 { 293 294 MPASS(sc != NULL || baseport != 0); 295 if (sc != NULL) 296 return (bus_space_read_1((sc)->bst, (sc)->bsh, 1)); 297 else 298 return (inb(baseport + 1)); 299 } 300 301 static void 302 write_reg(struct wb_softc *sc, uint8_t reg, uint8_t value) 303 { 304 305 write_efir_1(sc, 0, reg); 306 write_efdr_1(sc, 0, value); 307 } 308 309 static uint8_t 310 read_reg(struct wb_softc *sc, uint8_t reg) 311 { 312 313 write_efir_1(sc, 0, reg); 314 return (read_efdr_1(sc, 0)); 315 } 316 317 /* 318 * Return the watchdog related registers as we last read them. This will 319 * usually not give the current timeout or state on whether the watchdog 320 * fired. 321 */ 322 static int 323 sysctl_wb_debug(SYSCTL_HANDLER_ARGS) 324 { 325 struct wb_softc *sc; 326 struct sbuf sb; 327 int error; 328 329 sc = arg1; 330 331 sbuf_new_for_sysctl(&sb, NULL, 64, req); 332 333 sbuf_printf(&sb, "LDN8 (GPIO2, Watchdog): "); 334 sbuf_printf(&sb, "CR%02X 0x%02x ", sc->ctl_reg, sc->reg_1); 335 sbuf_printf(&sb, "CR%02X 0x%02x ", sc->time_reg, sc->reg_timeout); 336 sbuf_printf(&sb, "CR%02X 0x%02x", sc->csr_reg, sc->reg_2); 337 338 error = sbuf_finish(&sb); 339 sbuf_delete(&sb); 340 return (error); 341 } 342 343 /* 344 * Read the current values before returning them. Given this might poke 345 * the registers the same time as the watchdog, this sysctl handler should 346 * be marked CTLFLAG_SKIP to not show up by default. 347 */ 348 static int 349 sysctl_wb_debug_current(SYSCTL_HANDLER_ARGS) 350 { 351 struct wb_softc *sc; 352 353 sc = arg1; 354 355 if ((*sc->ext_cfg_enter_f)(sc, 0) != 0) 356 return (ENXIO); 357 358 /* Watchdog is configured as part of LDN 8 (GPIO Port2, Watchdog). */ 359 write_reg(sc, WB_LDN_REG, WB_LDN_REG_LDN8); 360 361 sc->reg_1 = read_reg(sc, sc->ctl_reg); 362 sc->reg_timeout = read_reg(sc, sc->time_reg); 363 sc->reg_2 = read_reg(sc, sc->csr_reg); 364 365 (*sc->ext_cfg_exit_f)(sc, 0); 366 367 return (sysctl_wb_debug(oidp, arg1, arg2, req)); 368 } 369 370 /* 371 * Sysctl handlers to force a watchdog timeout or to test the NMI functionality 372 * works as expetced. 373 * For testing we could set a test_nmi flag in the softc that, in case of NMI, a 374 * callback function from trap.c could check whether we fired and not report the 375 * timeout but clear the flag for the sysctl again. This is interesting given a 376 * lot of boards have jumpers to change the action on watchdog timeout or 377 * disable the watchdog completely. 378 * XXX-BZ notyet: currently no general infrastructure exists to do this. 379 */ 380 static int 381 sysctl_wb_force_test_nmi(SYSCTL_HANDLER_ARGS) 382 { 383 struct wb_softc *sc; 384 int error, test, val; 385 386 sc = arg1; 387 test = arg2; 388 389 #ifdef notyet 390 val = sc->test_nmi; 391 #else 392 val = 0; 393 #endif 394 error = sysctl_handle_int(oidp, &val, 0, req); 395 if (error || !req->newptr) 396 return (error); 397 398 #ifdef notyet 399 /* Manually clear the test for a value of 0 and do nothing else. */ 400 if (test && val == 0) { 401 sc->test_nmi = 0; 402 return (0); 403 } 404 #endif 405 406 if ((*sc->ext_cfg_enter_f)(sc, 0) != 0) 407 return (ENXIO); 408 409 #ifdef notyet 410 /* 411 * If we are testing the NMI functionality, set the flag before 412 * forcing the timeout. 413 */ 414 if (test) 415 sc->test_nmi = 1; 416 #endif 417 418 /* Watchdog is configured as part of LDN 8 (GPIO Port2, Watchdog). */ 419 write_reg(sc, WB_LDN_REG, WB_LDN_REG_LDN8); 420 421 /* Force watchdog to fire. */ 422 sc->reg_2 = read_reg(sc, sc->csr_reg); 423 sc->reg_2 |= WB_LDN8_CRF7_FORCE; 424 write_reg(sc, sc->csr_reg, sc->reg_2); 425 426 (*sc->ext_cfg_exit_f)(sc, 0); 427 428 return (0); 429 } 430 431 /* 432 * Print current watchdog state. 433 * 434 * Note: it is the responsibility of the caller to update the registers 435 * upfront. 436 */ 437 static void 438 wb_print_state(struct wb_softc *sc, const char *msg) 439 { 440 441 device_printf(sc->dev, "%s%sWatchdog %sabled. %s" 442 "Scaling by %ds, timer at %d (%s=%ds%s). " 443 "CRF5 0x%02x CRF7 0x%02x\n", 444 (msg != NULL) ? msg : "", (msg != NULL) ? ": " : "", 445 (sc->reg_timeout > 0x00) ? "en" : "dis", 446 (sc->reg_2 & WB_LDN8_CRF7_TS) ? "Watchdog fired. " : "", 447 (sc->reg_1 & WB_LDN8_CRF5_SCALE) ? 60 : 1, 448 sc->reg_timeout, 449 (sc->reg_timeout > 0x00) ? "<" : "", 450 sc->reg_timeout * ((sc->reg_1 & WB_LDN8_CRF5_SCALE) ? 60 : 1), 451 (sc->reg_timeout > 0x00) ? " left" : "", 452 sc->reg_1, sc->reg_2); 453 } 454 455 /* 456 * Functions to enter and exit extended function mode. Possibly shared 457 * between different chips. 458 */ 459 static int 460 ext_cfg_enter_0x87_0x87(struct wb_softc *sc, u_short baseport) 461 { 462 463 /* 464 * Enable extended function mode. 465 * Winbond does not allow us to validate so always return success. 466 */ 467 write_efir_1(sc, baseport, 0x87); 468 write_efir_1(sc, baseport, 0x87); 469 470 return (0); 471 } 472 473 static void 474 ext_cfg_exit_0xaa(struct wb_softc *sc, u_short baseport) 475 { 476 477 write_efir_1(sc, baseport, 0xaa); 478 } 479 480 /* 481 * (Re)load the watchdog counter depending on timeout. A timeout of 0 will 482 * disable the watchdog. 483 */ 484 static int 485 wb_set_watchdog(struct wb_softc *sc, unsigned int timeout) 486 { 487 488 if (timeout != 0) { 489 /* 490 * In case an override is set, let it override. It may lead 491 * to strange results as we do not check the input of the sysctl. 492 */ 493 if (sc->timeout_override > 0) 494 timeout = sc->timeout_override; 495 496 /* Make sure we support the requested timeout. */ 497 if (timeout > 255 * 60) 498 return (EINVAL); 499 } 500 501 if (sc->debug_verbose) 502 wb_print_state(sc, "Before watchdog counter (re)load"); 503 504 if ((*sc->ext_cfg_enter_f)(sc, 0) != 0) 505 return (ENXIO); 506 507 /* Watchdog is configured as part of LDN 8 (GPIO Port2, Watchdog) */ 508 write_reg(sc, WB_LDN_REG, WB_LDN_REG_LDN8); 509 510 if (timeout == 0) { 511 /* Disable watchdog. */ 512 sc->reg_timeout = 0; 513 write_reg(sc, sc->time_reg, sc->reg_timeout); 514 515 } else { 516 /* Read current scaling factor. */ 517 sc->reg_1 = read_reg(sc, sc->ctl_reg); 518 519 if (timeout > 255) { 520 /* Set scaling factor to 60s. */ 521 sc->reg_1 |= WB_LDN8_CRF5_SCALE; 522 sc->reg_timeout = (timeout / 60); 523 if (timeout % 60) 524 sc->reg_timeout++; 525 } else { 526 /* Set scaling factor to 1s. */ 527 sc->reg_1 &= ~WB_LDN8_CRF5_SCALE; 528 sc->reg_timeout = timeout; 529 } 530 531 /* In case we fired before we need to clear to fire again. */ 532 sc->reg_2 = read_reg(sc, sc->csr_reg); 533 if (sc->reg_2 & WB_LDN8_CRF7_TS) { 534 sc->reg_2 &= ~WB_LDN8_CRF7_TS; 535 write_reg(sc, sc->csr_reg, sc->reg_2); 536 } 537 538 /* Write back scaling factor. */ 539 write_reg(sc, sc->ctl_reg, sc->reg_1); 540 541 /* Set timer and arm/reset the watchdog. */ 542 write_reg(sc, sc->time_reg, sc->reg_timeout); 543 } 544 545 (*sc->ext_cfg_exit_f)(sc, 0); 546 547 if (sc->debug_verbose) 548 wb_print_state(sc, "After watchdog counter (re)load"); 549 return (0); 550 } 551 552 /* 553 * watchdog(9) EVENTHANDLER function implementation to (re)load the counter 554 * with the given timeout or disable the watchdog. 555 */ 556 static void 557 wb_watchdog_fn(void *private, u_int cmd, int *error) 558 { 559 struct wb_softc *sc; 560 unsigned int timeout; 561 int e; 562 563 sc = private; 564 KASSERT(sc != NULL, ("%s: watchdog handler function called without " 565 "softc.", __func__)); 566 567 cmd &= WD_INTERVAL; 568 if (cmd > 0 && cmd <= 63) { 569 /* Reset (and arm) watchdog. */ 570 timeout = ((uint64_t)1 << cmd) / 1000000000; 571 if (timeout == 0) 572 timeout = 1; 573 e = wb_set_watchdog(sc, timeout); 574 if (e == 0) { 575 if (error != NULL) 576 *error = 0; 577 } else { 578 /* On error, try to make sure the WD is disabled. */ 579 wb_set_watchdog(sc, 0); 580 } 581 582 } else { 583 /* Disable watchdog. */ 584 e = wb_set_watchdog(sc, 0); 585 if (e != 0 && cmd == 0 && error != NULL) { 586 /* Failed to disable watchdog. */ 587 *error = EOPNOTSUPP; 588 } 589 } 590 } 591 592 /* 593 * Probe/attach the Winbond Super I/O chip. 594 * 595 * Initial abstraction to possibly support more chips: 596 * - Iterate over the well known base ports, try to enable extended function 597 * mode and read and match the device ID and device revision. Unfortunately 598 * the Vendor ID is in the hardware monitoring section accessible by different 599 * base ports only. 600 * - Also HEFRAS, which would tell use the base port, is only accessible after 601 * entering extended function mode, for which the base port is needed. 602 * At least check HEFRAS to match the current base port we are probing. 603 * - On match set the description, remember functions to enter/exit extended 604 * function mode as well as the base port. 605 */ 606 static int 607 wb_probe_enable(device_t dev, int probe) 608 { 609 struct wb_softc *sc; 610 int error, found, i, j; 611 uint8_t dev_id, dev_rev, cr26; 612 char buf[128]; 613 614 if (dev == NULL) 615 sc = NULL; 616 else { 617 sc = device_get_softc(dev); 618 bzero(sc, sizeof(*sc)); 619 sc->dev = dev; 620 } 621 622 error = ENXIO; 623 found = 0; 624 for (i = 0; i < nitems(probe_addrs); i++) { 625 626 if (sc != NULL) { 627 /* Allocate bus resources for IO index/data register access. */ 628 sc->portres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->rid, 629 probe_addrs[i].efer, probe_addrs[i].efer + 1, 2, RF_ACTIVE); 630 if (sc->portres == NULL) 631 continue; 632 sc->bst = rman_get_bustag(sc->portres); 633 sc->bsh = rman_get_bushandle(sc->portres); 634 } 635 636 error = (*probe_addrs[i].ext_cfg_enter_f)(sc, probe_addrs[i].efer); 637 if (error != 0) 638 goto cleanup; 639 640 /* Identify the SuperIO chip. */ 641 write_efir_1(sc, probe_addrs[i].efer, WB_DEVICE_ID_REG); 642 dev_id = read_efdr_1(sc, probe_addrs[i].efer); 643 write_efir_1(sc, probe_addrs[i].efer, WB_DEVICE_REV_REG); 644 dev_rev = read_efdr_1(sc, probe_addrs[i].efer); 645 write_efir_1(sc, probe_addrs[i].efer, WB_CR26); 646 cr26 = read_efdr_1(sc, probe_addrs[i].efer); 647 648 if (dev_id == 0xff && dev_rev == 0xff) 649 goto cleanup; 650 651 /* HEFRAS of 0 means EFER at 0x2e, 1 means EFER at 0x4e. */ 652 if (((cr26 & 0x40) == 0x00 && probe_addrs[i].efer != 0x2e) || 653 ((cr26 & 0x40) == 0x40 && probe_addrs[i].efer != 0x4e)) { 654 if (dev != NULL) 655 device_printf(dev, "HEFRAS and EFER do not " 656 "align: EFER 0x%02x DevID 0x%02x DevRev " 657 "0x%02x CR26 0x%02x\n", 658 probe_addrs[i].efer, dev_id, dev_rev, cr26); 659 goto cleanup; 660 } 661 662 for (j = 0; j < nitems(wb_devs); j++) { 663 if (wb_devs[j].device_id == dev_id) { 664 found = 1; 665 break; 666 } 667 } 668 669 if (probe && dev != NULL) { 670 snprintf(buf, sizeof(buf), 671 "%s (0x%02x/0x%02x) Watchdog Timer", 672 found ? wb_devs[j].descr : 673 "Unknown Winbond/Nuvoton", dev_id, dev_rev); 674 device_set_desc_copy(dev, buf); 675 } 676 677 /* If this is hinted attach, try to guess the model. */ 678 if (dev != NULL && !found) { 679 found = 1; 680 j = 0; 681 } 682 683 cleanup: 684 if (probe || !found) { 685 (*probe_addrs[i].ext_cfg_exit_f)(sc, probe_addrs[i].efer); 686 if (sc != NULL) 687 (void) bus_release_resource(dev, SYS_RES_IOPORT, 688 sc->rid, sc->portres); 689 } 690 691 /* 692 * Stop probing if have successfully identified the SuperIO. 693 * Remember the extended function mode enter/exit functions 694 * for operations. 695 */ 696 if (found) { 697 if (sc != NULL) { 698 sc->ext_cfg_enter_f = probe_addrs[i].ext_cfg_enter_f; 699 sc->ext_cfg_exit_f = probe_addrs[i].ext_cfg_exit_f; 700 sc->chip = wb_devs[j].chip; 701 sc->ctl_reg = 0xf5; 702 sc->time_reg = 0xf6; 703 sc->csr_reg = 0xf7; 704 if (sc->chip == w83697hf || 705 sc->chip == w83697ug) { 706 sc->ctl_reg = 0xf3; 707 sc->time_reg = 0xf4; 708 } else if (sc->chip == nct6102) { 709 sc->ctl_reg = 0xf0; 710 sc->time_reg = 0xf1; 711 sc->csr_reg = 0xf2; 712 } 713 } 714 return (BUS_PROBE_SPECIFIC); 715 } else 716 error = ENXIO; 717 } 718 719 return (error); 720 } 721 722 static void 723 wb_identify(driver_t *driver, device_t parent) 724 { 725 726 if (device_find_child(parent, driver->name, 0) == NULL) { 727 if (wb_probe_enable(NULL, 1) <= 0) 728 BUS_ADD_CHILD(parent, 0, driver->name, 0); 729 } 730 } 731 732 static int 733 wb_probe(device_t dev) 734 { 735 736 /* Make sure we do not claim some ISA PNP device. */ 737 if (isa_get_logicalid(dev) != 0) 738 return (ENXIO); 739 740 return (wb_probe_enable(dev, 1)); 741 } 742 743 static int 744 wb_attach(device_t dev) 745 { 746 struct wb_softc *sc; 747 struct sysctl_ctx_list *sctx; 748 struct sysctl_oid *soid; 749 unsigned long timeout; 750 int error; 751 uint8_t t; 752 753 error = wb_probe_enable(dev, 0); 754 if (error > 0) 755 return (ENXIO); 756 757 sc = device_get_softc(dev); 758 KASSERT(sc->ext_cfg_enter_f != NULL && sc->ext_cfg_exit_f != NULL, 759 ("%s: successful probe result but not setup correctly", __func__)); 760 761 /* Watchdog is configured as part of LDN 8 (GPIO Port2, Watchdog). */ 762 write_reg(sc, WB_LDN_REG, WB_LDN_REG_LDN8); 763 764 /* Make sure WDT is enabled. */ 765 write_reg(sc, WB_LDN8_CR30, 766 read_reg(sc, WB_LDN8_CR30) | WB_LDN8_CR30_ACTIVE); 767 768 switch (sc->chip) { 769 case w83627hf: 770 case w83627s: 771 t = read_reg(sc, 0x2B) & ~0x10; 772 write_reg(sc, 0x2B, t); /* set GPIO24 to WDT0 */ 773 break; 774 case w83697hf: 775 /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ 776 t = read_reg(sc, 0x29) & ~0x60; 777 t |= 0x20; 778 write_reg(sc, 0x29, t); 779 break; 780 case w83697ug: 781 /* Set pin 118 to WDTO# mode */ 782 t = read_reg(sc, 0x2b) & ~0x04; 783 write_reg(sc, 0x2b, t); 784 break; 785 case w83627thf: 786 t = (read_reg(sc, 0x2B) & ~0x08) | 0x04; 787 write_reg(sc, 0x2B, t); /* set GPIO3 to WDT0 */ 788 break; 789 case w83627dhg: 790 case w83627dhg_p: 791 t = read_reg(sc, 0x2D) & ~0x01; /* PIN77 -> WDT0# */ 792 write_reg(sc, 0x2D, t); /* set GPIO5 to WDT0 */ 793 t = read_reg(sc, sc->ctl_reg); 794 t |= 0x02; /* enable the WDTO# output low pulse 795 * to the KBRST# pin */ 796 write_reg(sc, sc->ctl_reg, t); 797 break; 798 case w83637hf: 799 break; 800 case w83687thf: 801 t = read_reg(sc, 0x2C) & ~0x80; /* PIN47 -> WDT0# */ 802 write_reg(sc, 0x2C, t); 803 break; 804 case w83627ehf: 805 case w83627uhg: 806 case w83667hg: 807 case w83667hg_b: 808 case nct6775: 809 case nct6776: 810 case nct6779: 811 case nct6791: 812 case nct6792: 813 case nct6102: 814 /* 815 * These chips have a fixed WDTO# output pin (W83627UHG), 816 * or support more than one WDTO# output pin. 817 * Don't touch its configuration, and hope the BIOS 818 * does the right thing. 819 */ 820 t = read_reg(sc, sc->ctl_reg); 821 t |= 0x02; /* enable the WDTO# output low pulse 822 * to the KBRST# pin */ 823 write_reg(sc, sc->ctl_reg, t); 824 break; 825 default: 826 break; 827 } 828 829 /* Read the current watchdog configuration. */ 830 sc->reg_1 = read_reg(sc, sc->ctl_reg); 831 sc->reg_timeout = read_reg(sc, sc->time_reg); 832 sc->reg_2 = read_reg(sc, sc->csr_reg); 833 834 /* Print current state if bootverbose or watchdog already enabled. */ 835 if (bootverbose || (sc->reg_timeout > 0x00)) 836 wb_print_state(sc, "Before watchdog attach"); 837 838 sc->reg_1 &= ~WB_LDN8_CRF5_KEYB_P20; 839 sc->reg_1 |= WB_LDN8_CRF5_KBRST; 840 write_reg(sc, sc->ctl_reg, sc->reg_1); 841 842 /* 843 * Clear a previous watchdog timeout event (if still set). 844 * Disable timer reset on mouse interrupts. Leave reset on keyboard, 845 * since one of my boards is getting stuck in reboot without it. 846 */ 847 sc->reg_2 &= ~(WB_LDN8_CRF7_MOUSE|WB_LDN8_CRF7_TS); 848 write_reg(sc, sc->csr_reg, sc->reg_2); 849 850 (*sc->ext_cfg_exit_f)(sc, 0); 851 852 /* Read global timeout override tunable, Add per device sysctls. */ 853 if (TUNABLE_ULONG_FETCH("hw.wbwd.timeout_override", &timeout)) { 854 if (timeout > 0) 855 sc->timeout_override = timeout; 856 } 857 sctx = device_get_sysctl_ctx(dev); 858 soid = device_get_sysctl_tree(dev); 859 SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, 860 "timeout_override", CTLFLAG_RW, &sc->timeout_override, 0, 861 "Timeout in seconds overriding default watchdog timeout"); 862 SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, 863 "debug_verbose", CTLFLAG_RW, &sc->debug_verbose, 0, 864 "Enables extra debugging information"); 865 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug", 866 CTLTYPE_STRING|CTLFLAG_RD, sc, 0, sysctl_wb_debug, "A", 867 "Selected register information from last change by driver"); 868 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug_current", 869 CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_SKIP, sc, 0, 870 sysctl_wb_debug_current, "A", 871 "Selected register information (may interfere)"); 872 SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "force_timeout", 873 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_SKIP, sc, 0, 874 sysctl_wb_force_test_nmi, "I", "Enable to force watchdog to fire."); 875 876 /* Register watchdog. */ 877 sc->ev_tag = EVENTHANDLER_REGISTER(watchdog_list, wb_watchdog_fn, sc, 878 0); 879 880 if (bootverbose) 881 wb_print_state(sc, "After watchdog attach"); 882 883 return (0); 884 } 885 886 static int 887 wb_detach(device_t dev) 888 { 889 struct wb_softc *sc; 890 891 sc = device_get_softc(dev); 892 893 /* Unregister and stop the watchdog if running. */ 894 if (sc->ev_tag) 895 EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); 896 wb_set_watchdog(sc, 0); 897 898 /* Disable extended function mode. */ 899 (*sc->ext_cfg_exit_f)(sc, 0); 900 901 /* Cleanup resources. */ 902 (void) bus_release_resource(dev, SYS_RES_IOPORT, sc->rid, sc->portres); 903 904 /* Bus subroutines take care of sysctls already. */ 905 906 return (0); 907 } 908 909 static device_method_t wb_methods[] = { 910 /* Device interface */ 911 DEVMETHOD(device_identify, wb_identify), 912 DEVMETHOD(device_probe, wb_probe), 913 DEVMETHOD(device_attach, wb_attach), 914 DEVMETHOD(device_detach, wb_detach), 915 916 DEVMETHOD_END 917 }; 918 919 static driver_t wb_isa_driver = { 920 "wbwd", 921 wb_methods, 922 sizeof(struct wb_softc) 923 }; 924 925 static devclass_t wb_devclass; 926 927 DRIVER_MODULE(wb, isa, wb_isa_driver, wb_devclass, NULL, NULL); 928