1 /*- 2 * Copyright (c) 1998, 1999 Takanori Watanabe 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/bus.h> 30 #include <sys/kernel.h> 31 #include <sys/lock.h> 32 #include <sys/module.h> 33 #include <sys/mutex.h> 34 #include <sys/rman.h> 35 #include <machine/bus.h> 36 #include <dev/smbus/smbconf.h> 37 38 #include "smbus_if.h" 39 40 #include <dev/pci/pcireg.h> 41 #include <dev/pci/pcivar.h> 42 #include <dev/intpm/intpmreg.h> 43 #include <dev/amdsbwd/amd_chipset.h> 44 45 #include "opt_intpm.h" 46 47 struct intsmb_softc { 48 device_t dev; 49 struct resource *io_res; 50 struct resource *irq_res; 51 void *irq_hand; 52 device_t smbus; 53 int io_rid; 54 int isbusy; 55 int cfg_irq9; 56 int sb8xx; 57 int poll; 58 int type; 59 struct mtx lock; 60 }; 61 62 #define INTSMB_LOCK(sc) mtx_lock(&(sc)->lock) 63 #define INTSMB_UNLOCK(sc) mtx_unlock(&(sc)->lock) 64 #define INTSMB_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED) 65 66 static int intsmb_probe(device_t); 67 static int intsmb_attach(device_t); 68 static int intsmb_detach(device_t); 69 static int intsmb_intr(struct intsmb_softc *sc); 70 static int intsmb_slvintr(struct intsmb_softc *sc); 71 static void intsmb_alrintr(struct intsmb_softc *sc); 72 static int intsmb_callback(device_t dev, int index, void *data); 73 static int intsmb_quick(device_t dev, u_char slave, int how); 74 static int intsmb_sendb(device_t dev, u_char slave, char byte); 75 static int intsmb_recvb(device_t dev, u_char slave, char *byte); 76 static int intsmb_writeb(device_t dev, u_char slave, char cmd, char byte); 77 static int intsmb_writew(device_t dev, u_char slave, char cmd, short word); 78 static int intsmb_readb(device_t dev, u_char slave, char cmd, char *byte); 79 static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word); 80 static int intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata); 81 static int intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf); 82 static int intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf); 83 static void intsmb_start(struct intsmb_softc *sc, u_char cmd, int nointr); 84 static int intsmb_stop(struct intsmb_softc *sc); 85 static int intsmb_stop_poll(struct intsmb_softc *sc); 86 static int intsmb_free(struct intsmb_softc *sc); 87 static void intsmb_rawintr(void *arg); 88 89 const struct intsmb_device { 90 uint32_t devid; 91 const char *description; 92 } intsmb_products[] = { 93 { 0x71138086, "Intel PIIX4 SMBUS Interface" }, 94 { 0x719b8086, "Intel PIIX4 SMBUS Interface" }, 95 #if 0 96 /* Not a good idea yet, this stops isab0 functioning */ 97 { 0x02001166, "ServerWorks OSB4" }, 98 #endif 99 { 0x43721002, "ATI IXP400 SMBus Controller" }, 100 { AMDSB_SMBUS_DEVID, "AMD SB600/7xx/8xx/9xx SMBus Controller" }, 101 { AMDFCH_SMBUS_DEVID, "AMD FCH SMBus Controller" }, 102 { AMDCZ_SMBUS_DEVID, "AMD FCH SMBus Controller" }, 103 { HYGONCZ_SMBUS_DEVID, "Hygon FCH SMBus Controller" }, 104 }; 105 106 static int 107 intsmb_probe(device_t dev) 108 { 109 const struct intsmb_device *isd; 110 uint32_t devid; 111 size_t i; 112 113 devid = pci_get_devid(dev); 114 for (i = 0; i < nitems(intsmb_products); i++) { 115 isd = &intsmb_products[i]; 116 if (isd->devid == devid) { 117 device_set_desc(dev, isd->description); 118 return (BUS_PROBE_DEFAULT); 119 } 120 } 121 return (ENXIO); 122 } 123 124 static uint8_t 125 amd_pmio_read(struct resource *res, uint8_t reg) 126 { 127 bus_write_1(res, 0, reg); /* Index */ 128 return (bus_read_1(res, 1)); /* Data */ 129 } 130 131 static int 132 sb8xx_attach(device_t dev) 133 { 134 static const int AMDSB_SMBIO_WIDTH = 0x10; 135 struct intsmb_softc *sc; 136 struct resource *res; 137 uint32_t devid; 138 uint8_t revid; 139 uint32_t addr; 140 int rid; 141 int rc; 142 bool enabled; 143 144 sc = device_get_softc(dev); 145 devid = pci_get_devid(dev); 146 revid = pci_get_revid(dev); 147 148 /* 149 * Comment from Linux i2c-piix4.c: 150 * 151 * cd6h/cd7h port I/O accesses can be disabled on AMD processors 152 * w/ SMBus PCI revision ID 0x51 or greater. MMIO is supported on 153 * the same processors and is the recommended access method. 154 */ 155 if (devid == AMDCZ_SMBUS_DEVID && revid >= AMDCZ51_SMBUS_REVID) { 156 sc->type = SYS_RES_MEMORY; 157 addr = AMDFCH41_MMIO_ADDR + AMDFCH41_MMIO_PM_OFF; 158 } else { 159 sc->type = SYS_RES_IOPORT; 160 addr = AMDSB_PMIO_INDEX; 161 } 162 163 rid = 0; 164 rc = bus_set_resource(dev, sc->type, rid, addr, 165 AMDSB_PMIO_WIDTH); 166 if (rc != 0) { 167 device_printf(dev, "bus_set_resource for PM IO failed\n"); 168 return (ENXIO); 169 } 170 res = bus_alloc_resource_any(dev, sc->type, &rid, 171 RF_ACTIVE); 172 if (res == NULL) { 173 device_printf(dev, "bus_alloc_resource for PM IO failed\n"); 174 return (ENXIO); 175 } 176 177 if (devid == AMDSB_SMBUS_DEVID || 178 (devid == AMDFCH_SMBUS_DEVID && revid < AMDFCH41_SMBUS_REVID) || 179 (devid == AMDCZ_SMBUS_DEVID && revid < AMDCZ49_SMBUS_REVID)) { 180 addr = amd_pmio_read(res, AMDSB8_PM_SMBUS_EN + 1); 181 addr <<= 8; 182 addr |= amd_pmio_read(res, AMDSB8_PM_SMBUS_EN); 183 enabled = (addr & AMDSB8_SMBUS_EN) != 0; 184 addr &= AMDSB8_SMBUS_ADDR_MASK; 185 } else if (devid == AMDCZ_SMBUS_DEVID && revid >= AMDCZ51_SMBUS_REVID) { 186 addr = bus_read_1(res, AMDFCH41_PM_DECODE_EN0); 187 enabled = (addr & AMDFCH41_SMBUS_EN) != 0; 188 addr = AMDFCH41_MMIO_ADDR + AMDFCH41_MMIO_SMBUS_OFF; 189 } else { 190 addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN0); 191 enabled = (addr & AMDFCH41_SMBUS_EN) != 0; 192 addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN1); 193 addr <<= 8; 194 } 195 196 bus_release_resource(dev, sc->type, rid, res); 197 bus_delete_resource(dev, sc->type, rid); 198 199 if (!enabled) { 200 device_printf(dev, "SB8xx/SB9xx/FCH SMBus not enabled\n"); 201 return (ENXIO); 202 } 203 204 sc->io_rid = 0; 205 rc = bus_set_resource(dev, sc->type, sc->io_rid, addr, 206 AMDSB_SMBIO_WIDTH); 207 if (rc != 0) { 208 device_printf(dev, "bus_set_resource for SMBus IO failed\n"); 209 return (ENXIO); 210 } 211 sc->io_res = bus_alloc_resource_any(dev, sc->type, &sc->io_rid, 212 RF_ACTIVE); 213 if (sc->io_res == NULL) { 214 device_printf(dev, "Could not allocate I/O space\n"); 215 return (ENXIO); 216 } 217 sc->poll = 1; 218 return (0); 219 } 220 221 static void 222 intsmb_release_resources(device_t dev) 223 { 224 struct intsmb_softc *sc = device_get_softc(dev); 225 226 device_delete_children(dev); 227 if (sc->irq_hand) 228 bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); 229 if (sc->irq_res) 230 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 231 if (sc->io_res) 232 bus_release_resource(dev, sc->type, sc->io_rid, 233 sc->io_res); 234 mtx_destroy(&sc->lock); 235 } 236 237 static int 238 intsmb_attach(device_t dev) 239 { 240 struct intsmb_softc *sc = device_get_softc(dev); 241 int error, rid, value; 242 int intr; 243 char *str; 244 245 sc->dev = dev; 246 247 mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF); 248 249 sc->cfg_irq9 = 0; 250 sc->type = SYS_RES_IOPORT; 251 switch (pci_get_devid(dev)) { 252 #ifndef NO_CHANGE_PCICONF 253 case 0x71138086: /* Intel 82371AB */ 254 case 0x719b8086: /* Intel 82443MX */ 255 /* Changing configuration is allowed. */ 256 sc->cfg_irq9 = 1; 257 break; 258 #endif 259 case AMDSB_SMBUS_DEVID: 260 if (pci_get_revid(dev) >= AMDSB8_SMBUS_REVID) 261 sc->sb8xx = 1; 262 break; 263 case AMDFCH_SMBUS_DEVID: 264 case AMDCZ_SMBUS_DEVID: 265 case HYGONCZ_SMBUS_DEVID: 266 sc->sb8xx = 1; 267 break; 268 } 269 270 if (sc->sb8xx) { 271 error = sb8xx_attach(dev); 272 if (error != 0) 273 goto fail; 274 else 275 goto no_intr; 276 } 277 278 sc->io_rid = PCI_BASE_ADDR_SMB; 279 sc->io_res = bus_alloc_resource_any(dev, sc->type, &sc->io_rid, 280 RF_ACTIVE); 281 if (sc->io_res == NULL) { 282 device_printf(dev, "Could not allocate I/O space\n"); 283 error = ENXIO; 284 goto fail; 285 } 286 287 if (sc->cfg_irq9) { 288 pci_write_config(dev, PCIR_INTLINE, 0x9, 1); 289 pci_write_config(dev, PCI_HST_CFG_SMB, 290 PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1); 291 } 292 value = pci_read_config(dev, PCI_HST_CFG_SMB, 1); 293 sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0; 294 intr = value & PCI_INTR_SMB_MASK; 295 switch (intr) { 296 case PCI_INTR_SMB_SMI: 297 str = "SMI"; 298 break; 299 case PCI_INTR_SMB_IRQ9: 300 str = "IRQ 9"; 301 break; 302 case PCI_INTR_SMB_IRQ_PCI: 303 str = "PCI IRQ"; 304 break; 305 default: 306 str = "BOGUS"; 307 } 308 309 device_printf(dev, "intr %s %s ", str, 310 sc->poll == 0 ? "enabled" : "disabled"); 311 printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1)); 312 313 if (!sc->poll && intr == PCI_INTR_SMB_SMI) { 314 device_printf(dev, 315 "using polling mode when configured interrupt is SMI\n"); 316 sc->poll = 1; 317 } 318 319 if (sc->poll) 320 goto no_intr; 321 322 if (intr != PCI_INTR_SMB_IRQ9 && intr != PCI_INTR_SMB_IRQ_PCI) { 323 device_printf(dev, "Unsupported interrupt mode\n"); 324 error = ENXIO; 325 goto fail; 326 } 327 328 /* Force IRQ 9. */ 329 rid = 0; 330 if (sc->cfg_irq9) 331 bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1); 332 333 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 334 RF_SHAREABLE | RF_ACTIVE); 335 if (sc->irq_res == NULL) { 336 device_printf(dev, "Could not allocate irq\n"); 337 error = ENXIO; 338 goto fail; 339 } 340 341 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 342 NULL, intsmb_rawintr, sc, &sc->irq_hand); 343 if (error) { 344 device_printf(dev, "Failed to map intr\n"); 345 goto fail; 346 } 347 348 no_intr: 349 sc->isbusy = 0; 350 sc->smbus = device_add_child(dev, "smbus", DEVICE_UNIT_ANY); 351 if (sc->smbus == NULL) { 352 device_printf(dev, "failed to add smbus child\n"); 353 error = ENXIO; 354 goto fail; 355 } 356 error = device_probe_and_attach(sc->smbus); 357 if (error) { 358 device_printf(dev, "failed to probe+attach smbus child\n"); 359 goto fail; 360 } 361 362 #ifdef ENABLE_ALART 363 /* Enable Arart */ 364 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); 365 #endif 366 return (0); 367 368 fail: 369 intsmb_release_resources(dev); 370 return (error); 371 } 372 373 static int 374 intsmb_detach(device_t dev) 375 { 376 int error; 377 378 error = bus_generic_detach(dev); 379 if (error) { 380 device_printf(dev, "bus detach failed\n"); 381 return (error); 382 } 383 384 intsmb_release_resources(dev); 385 return (0); 386 } 387 388 static void 389 intsmb_rawintr(void *arg) 390 { 391 struct intsmb_softc *sc = arg; 392 393 INTSMB_LOCK(sc); 394 intsmb_intr(sc); 395 intsmb_slvintr(sc); 396 INTSMB_UNLOCK(sc); 397 } 398 399 static int 400 intsmb_callback(device_t dev, int index, void *data) 401 { 402 int error = 0; 403 404 switch (index) { 405 case SMB_REQUEST_BUS: 406 break; 407 case SMB_RELEASE_BUS: 408 break; 409 default: 410 error = SMB_EINVAL; 411 } 412 413 return (error); 414 } 415 416 /* Counterpart of smbtx_smb_free(). */ 417 static int 418 intsmb_free(struct intsmb_softc *sc) 419 { 420 421 INTSMB_LOCK_ASSERT(sc); 422 if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) || 423 #ifdef ENABLE_ALART 424 (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) || 425 #endif 426 sc->isbusy) 427 return (SMB_EBUSY); 428 429 sc->isbusy = 1; 430 /* Disable Interrupt in slave part. */ 431 #ifndef ENABLE_ALART 432 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0); 433 #endif 434 /* Reset INTR Flag to prepare INTR. */ 435 bus_write_1(sc->io_res, PIIX4_SMBHSTSTS, 436 PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | 437 PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL); 438 return (0); 439 } 440 441 static int 442 intsmb_intr(struct intsmb_softc *sc) 443 { 444 int status, tmp; 445 446 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 447 if (status & PIIX4_SMBHSTSTAT_BUSY) 448 return (1); 449 450 if (status & (PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | 451 PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL)) { 452 453 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 454 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, 455 tmp & ~PIIX4_SMBHSTCNT_INTREN); 456 if (sc->isbusy) { 457 sc->isbusy = 0; 458 wakeup(sc); 459 } 460 return (0); 461 } 462 return (1); /* Not Completed */ 463 } 464 465 static int 466 intsmb_slvintr(struct intsmb_softc *sc) 467 { 468 int status; 469 470 status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS); 471 if (status & PIIX4_SMBSLVSTS_BUSY) 472 return (1); 473 if (status & PIIX4_SMBSLVSTS_ALART) 474 intsmb_alrintr(sc); 475 else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 476 | PIIX4_SMBSLVSTS_SDW1)) { 477 } 478 479 /* Reset Status Register */ 480 bus_write_1(sc->io_res, PIIX4_SMBSLVSTS, 481 PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 | 482 PIIX4_SMBSLVSTS_SDW1 | PIIX4_SMBSLVSTS_SLV); 483 return (0); 484 } 485 486 static void 487 intsmb_alrintr(struct intsmb_softc *sc) 488 { 489 int slvcnt __unused; 490 #ifdef ENABLE_ALART 491 int error; 492 uint8_t addr; 493 #endif 494 495 /* Stop generating INTR from ALART. */ 496 slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT); 497 #ifdef ENABLE_ALART 498 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 499 slvcnt & ~PIIX4_SMBSLVCNT_ALTEN); 500 #endif 501 DELAY(5); 502 503 /* Ask bus who asserted it and then ask it what's the matter. */ 504 #ifdef ENABLE_ALART 505 error = intsmb_free(sc); 506 if (error) 507 return; 508 509 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, SMBALTRESP | LSB); 510 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 1); 511 error = intsmb_stop_poll(sc); 512 if (error) 513 device_printf(sc->dev, "ALART: ERROR\n"); 514 else { 515 addr = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 516 device_printf(sc->dev, "ALART_RESPONSE: 0x%x\n", addr); 517 } 518 519 /* Re-enable INTR from ALART. */ 520 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 521 slvcnt | PIIX4_SMBSLVCNT_ALTEN); 522 DELAY(5); 523 #endif 524 } 525 526 static void 527 intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr) 528 { 529 unsigned char tmp; 530 531 INTSMB_LOCK_ASSERT(sc); 532 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 533 tmp &= 0xe0; 534 tmp |= cmd; 535 tmp |= PIIX4_SMBHSTCNT_START; 536 537 /* While not in autoconfiguration enable interrupts. */ 538 if (!sc->poll && !cold && !nointr) 539 tmp |= PIIX4_SMBHSTCNT_INTREN; 540 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp); 541 } 542 543 static int 544 intsmb_error(device_t dev, int status) 545 { 546 int error = 0; 547 548 /* 549 * PIIX4_SMBHSTSTAT_ERR can mean either of 550 * - SMB_ENOACK ("Unclaimed cycle"), 551 * - SMB_ETIMEOUT ("Host device time-out"), 552 * - SMB_EINVAL ("Illegal command field"). 553 * SMB_ENOACK seems to be most typical. 554 */ 555 if (status & PIIX4_SMBHSTSTAT_ERR) 556 error |= SMB_ENOACK; 557 if (status & PIIX4_SMBHSTSTAT_BUSC) 558 error |= SMB_ECOLLI; 559 if (status & PIIX4_SMBHSTSTAT_FAIL) 560 error |= SMB_EABORT; 561 562 if (error != 0 && bootverbose) 563 device_printf(dev, "error = %d, status = %#x\n", error, status); 564 565 return (error); 566 } 567 568 /* 569 * Polling Code. 570 * 571 * Polling is not encouraged because it requires waiting for the 572 * device if it is busy. 573 * (29063505.pdf from Intel) But during boot, interrupt cannot be used, so use 574 * polling code then. 575 */ 576 static int 577 intsmb_stop_poll(struct intsmb_softc *sc) 578 { 579 int error, i, status, tmp; 580 581 INTSMB_LOCK_ASSERT(sc); 582 583 /* First, wait for busy to be set. */ 584 for (i = 0; i < 0x7fff; i++) 585 if (bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & 586 PIIX4_SMBHSTSTAT_BUSY) 587 break; 588 589 /* Wait for busy to clear. */ 590 for (i = 0; i < 0x7fff; i++) { 591 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 592 if (!(status & PIIX4_SMBHSTSTAT_BUSY)) { 593 sc->isbusy = 0; 594 error = intsmb_error(sc->dev, status); 595 return (error); 596 } 597 } 598 599 /* Timed out waiting for busy to clear. */ 600 sc->isbusy = 0; 601 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 602 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN); 603 return (SMB_ETIMEOUT); 604 } 605 606 /* 607 * Wait for completion and return result. 608 */ 609 static int 610 intsmb_stop(struct intsmb_softc *sc) 611 { 612 int error, status; 613 614 INTSMB_LOCK_ASSERT(sc); 615 616 if (sc->poll || cold) 617 /* So that it can use device during device probe on SMBus. */ 618 return (intsmb_stop_poll(sc)); 619 620 error = msleep(sc, &sc->lock, PWAIT | PCATCH, "SMBWAI", hz / 8); 621 if (error == 0) { 622 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 623 if (!(status & PIIX4_SMBHSTSTAT_BUSY)) { 624 error = intsmb_error(sc->dev, status); 625 if (error == 0 && !(status & PIIX4_SMBHSTSTAT_INTR)) 626 device_printf(sc->dev, "unknown cause why?\n"); 627 #ifdef ENABLE_ALART 628 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 629 PIIX4_SMBSLVCNT_ALTEN); 630 #endif 631 return (error); 632 } 633 } 634 635 /* Timeout Procedure. */ 636 sc->isbusy = 0; 637 638 /* Re-enable suppressed interrupt from slave part. */ 639 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); 640 if (error == EWOULDBLOCK) 641 return (SMB_ETIMEOUT); 642 else 643 return (SMB_EABORT); 644 } 645 646 static int 647 intsmb_quick(device_t dev, u_char slave, int how) 648 { 649 struct intsmb_softc *sc = device_get_softc(dev); 650 int error; 651 u_char data; 652 653 data = slave; 654 655 /* Quick command is part of Address, I think. */ 656 switch(how) { 657 case SMB_QWRITE: 658 data &= ~LSB; 659 break; 660 case SMB_QREAD: 661 data |= LSB; 662 break; 663 default: 664 return (SMB_EINVAL); 665 } 666 667 INTSMB_LOCK(sc); 668 error = intsmb_free(sc); 669 if (error) { 670 INTSMB_UNLOCK(sc); 671 return (error); 672 } 673 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, data); 674 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_QUICK, 0); 675 error = intsmb_stop(sc); 676 INTSMB_UNLOCK(sc); 677 return (error); 678 } 679 680 static int 681 intsmb_sendb(device_t dev, u_char slave, char byte) 682 { 683 struct intsmb_softc *sc = device_get_softc(dev); 684 int error; 685 686 INTSMB_LOCK(sc); 687 error = intsmb_free(sc); 688 if (error) { 689 INTSMB_UNLOCK(sc); 690 return (error); 691 } 692 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 693 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, byte); 694 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); 695 error = intsmb_stop(sc); 696 INTSMB_UNLOCK(sc); 697 return (error); 698 } 699 700 static int 701 intsmb_recvb(device_t dev, u_char slave, char *byte) 702 { 703 struct intsmb_softc *sc = device_get_softc(dev); 704 int error; 705 706 INTSMB_LOCK(sc); 707 error = intsmb_free(sc); 708 if (error) { 709 INTSMB_UNLOCK(sc); 710 return (error); 711 } 712 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 713 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); 714 error = intsmb_stop(sc); 715 if (error == 0) { 716 #ifdef RECV_IS_IN_CMD 717 /* 718 * Linux SMBus stuff also troubles 719 * Because Intel's datasheet does not make clear. 720 */ 721 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD); 722 #else 723 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 724 #endif 725 } 726 INTSMB_UNLOCK(sc); 727 return (error); 728 } 729 730 static int 731 intsmb_writeb(device_t dev, u_char slave, char cmd, char byte) 732 { 733 struct intsmb_softc *sc = device_get_softc(dev); 734 int error; 735 736 INTSMB_LOCK(sc); 737 error = intsmb_free(sc); 738 if (error) { 739 INTSMB_UNLOCK(sc); 740 return (error); 741 } 742 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 743 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 744 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, byte); 745 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0); 746 error = intsmb_stop(sc); 747 INTSMB_UNLOCK(sc); 748 return (error); 749 } 750 751 static int 752 intsmb_writew(device_t dev, u_char slave, char cmd, short word) 753 { 754 struct intsmb_softc *sc = device_get_softc(dev); 755 int error; 756 757 INTSMB_LOCK(sc); 758 error = intsmb_free(sc); 759 if (error) { 760 INTSMB_UNLOCK(sc); 761 return (error); 762 } 763 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 764 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 765 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, word & 0xff); 766 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (word >> 8) & 0xff); 767 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); 768 error = intsmb_stop(sc); 769 INTSMB_UNLOCK(sc); 770 return (error); 771 } 772 773 static int 774 intsmb_readb(device_t dev, u_char slave, char cmd, char *byte) 775 { 776 struct intsmb_softc *sc = device_get_softc(dev); 777 int error; 778 779 INTSMB_LOCK(sc); 780 error = intsmb_free(sc); 781 if (error) { 782 INTSMB_UNLOCK(sc); 783 return (error); 784 } 785 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 786 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 787 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0); 788 error = intsmb_stop(sc); 789 if (error == 0) 790 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 791 INTSMB_UNLOCK(sc); 792 return (error); 793 } 794 795 static int 796 intsmb_readw(device_t dev, u_char slave, char cmd, short *word) 797 { 798 struct intsmb_softc *sc = device_get_softc(dev); 799 int error; 800 801 INTSMB_LOCK(sc); 802 error = intsmb_free(sc); 803 if (error) { 804 INTSMB_UNLOCK(sc); 805 return (error); 806 } 807 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 808 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 809 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); 810 error = intsmb_stop(sc); 811 if (error == 0) { 812 *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 813 *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; 814 } 815 INTSMB_UNLOCK(sc); 816 return (error); 817 } 818 819 static int 820 intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) 821 { 822 823 return (SMB_ENOTSUPP); 824 } 825 826 static int 827 intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) 828 { 829 struct intsmb_softc *sc = device_get_softc(dev); 830 int error, i; 831 832 if (count > SMBBLOCKTRANS_MAX || count == 0) 833 return (SMB_EINVAL); 834 835 INTSMB_LOCK(sc); 836 error = intsmb_free(sc); 837 if (error) { 838 INTSMB_UNLOCK(sc); 839 return (error); 840 } 841 842 /* Reset internal array index. */ 843 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 844 845 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 846 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 847 for (i = 0; i < count; i++) 848 bus_write_1(sc->io_res, PIIX4_SMBBLKDAT, buf[i]); 849 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, count); 850 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); 851 error = intsmb_stop(sc); 852 INTSMB_UNLOCK(sc); 853 return (error); 854 } 855 856 static int 857 intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) 858 { 859 struct intsmb_softc *sc = device_get_softc(dev); 860 int error, i; 861 u_char nread; 862 863 INTSMB_LOCK(sc); 864 error = intsmb_free(sc); 865 if (error) { 866 INTSMB_UNLOCK(sc); 867 return (error); 868 } 869 870 /* Reset internal array index. */ 871 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 872 873 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 874 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 875 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); 876 error = intsmb_stop(sc); 877 if (error == 0) { 878 nread = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 879 if (nread != 0 && nread <= SMBBLOCKTRANS_MAX) { 880 *count = nread; 881 for (i = 0; i < nread; i++) 882 buf[i] = bus_read_1(sc->io_res, PIIX4_SMBBLKDAT); 883 } else 884 error = SMB_EBUSERR; 885 } 886 INTSMB_UNLOCK(sc); 887 return (error); 888 } 889 890 static device_method_t intsmb_methods[] = { 891 /* Device interface */ 892 DEVMETHOD(device_probe, intsmb_probe), 893 DEVMETHOD(device_attach, intsmb_attach), 894 DEVMETHOD(device_detach, intsmb_detach), 895 896 /* SMBus interface */ 897 DEVMETHOD(smbus_callback, intsmb_callback), 898 DEVMETHOD(smbus_quick, intsmb_quick), 899 DEVMETHOD(smbus_sendb, intsmb_sendb), 900 DEVMETHOD(smbus_recvb, intsmb_recvb), 901 DEVMETHOD(smbus_writeb, intsmb_writeb), 902 DEVMETHOD(smbus_writew, intsmb_writew), 903 DEVMETHOD(smbus_readb, intsmb_readb), 904 DEVMETHOD(smbus_readw, intsmb_readw), 905 DEVMETHOD(smbus_pcall, intsmb_pcall), 906 DEVMETHOD(smbus_bwrite, intsmb_bwrite), 907 DEVMETHOD(smbus_bread, intsmb_bread), 908 909 DEVMETHOD_END 910 }; 911 912 static driver_t intsmb_driver = { 913 "intsmb", 914 intsmb_methods, 915 sizeof(struct intsmb_softc), 916 }; 917 918 DRIVER_MODULE_ORDERED(intsmb, pci, intsmb_driver, 0, 0, SI_ORDER_ANY); 919 DRIVER_MODULE(smbus, intsmb, smbus_driver, 0, 0); 920 MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 921 MODULE_VERSION(intsmb, 1); 922 MODULE_PNP_INFO("W32:vendor/device;D:#", pci, intpm, intsmb_products, 923 nitems(intsmb_products)); 924