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/cdefs.h> 28 #include <sys/param.h> 29 #include <sys/systm.h> 30 #include <sys/bus.h> 31 #include <sys/kernel.h> 32 #include <sys/lock.h> 33 #include <sys/module.h> 34 #include <sys/mutex.h> 35 #include <sys/rman.h> 36 #include <machine/bus.h> 37 #include <dev/smbus/smbconf.h> 38 39 #include "smbus_if.h" 40 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcivar.h> 43 #include <dev/intpm/intpmreg.h> 44 #include <dev/amdsbwd/amd_chipset.h> 45 46 #include "opt_intpm.h" 47 48 struct intsmb_softc { 49 device_t dev; 50 struct resource *io_res; 51 struct resource *irq_res; 52 void *irq_hand; 53 device_t smbus; 54 int io_rid; 55 int isbusy; 56 int cfg_irq9; 57 int sb8xx; 58 int poll; 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 uint16_t addr; 140 int rid; 141 int rc; 142 bool enabled; 143 144 sc = device_get_softc(dev); 145 rid = 0; 146 rc = bus_set_resource(dev, SYS_RES_IOPORT, rid, AMDSB_PMIO_INDEX, 147 AMDSB_PMIO_WIDTH); 148 if (rc != 0) { 149 device_printf(dev, "bus_set_resource for PM IO failed\n"); 150 return (ENXIO); 151 } 152 res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 153 RF_ACTIVE); 154 if (res == NULL) { 155 device_printf(dev, "bus_alloc_resource for PM IO failed\n"); 156 return (ENXIO); 157 } 158 159 devid = pci_get_devid(dev); 160 revid = pci_get_revid(dev); 161 if (devid == AMDSB_SMBUS_DEVID || 162 (devid == AMDFCH_SMBUS_DEVID && revid < AMDFCH41_SMBUS_REVID) || 163 (devid == AMDCZ_SMBUS_DEVID && revid < AMDCZ49_SMBUS_REVID)) { 164 addr = amd_pmio_read(res, AMDSB8_PM_SMBUS_EN + 1); 165 addr <<= 8; 166 addr |= amd_pmio_read(res, AMDSB8_PM_SMBUS_EN); 167 enabled = (addr & AMDSB8_SMBUS_EN) != 0; 168 addr &= AMDSB8_SMBUS_ADDR_MASK; 169 } else { 170 addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN0); 171 enabled = (addr & AMDFCH41_SMBUS_EN) != 0; 172 addr = amd_pmio_read(res, AMDFCH41_PM_DECODE_EN1); 173 addr <<= 8; 174 } 175 176 bus_release_resource(dev, SYS_RES_IOPORT, rid, res); 177 bus_delete_resource(dev, SYS_RES_IOPORT, rid); 178 179 if (!enabled) { 180 device_printf(dev, "SB8xx/SB9xx/FCH SMBus not enabled\n"); 181 return (ENXIO); 182 } 183 184 sc->io_rid = 0; 185 rc = bus_set_resource(dev, SYS_RES_IOPORT, sc->io_rid, addr, 186 AMDSB_SMBIO_WIDTH); 187 if (rc != 0) { 188 device_printf(dev, "bus_set_resource for SMBus IO failed\n"); 189 return (ENXIO); 190 } 191 sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid, 192 RF_ACTIVE); 193 if (sc->io_res == NULL) { 194 device_printf(dev, "Could not allocate I/O space\n"); 195 return (ENXIO); 196 } 197 sc->poll = 1; 198 return (0); 199 } 200 201 static void 202 intsmb_release_resources(device_t dev) 203 { 204 struct intsmb_softc *sc = device_get_softc(dev); 205 206 if (sc->smbus) 207 device_delete_child(dev, sc->smbus); 208 if (sc->irq_hand) 209 bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); 210 if (sc->irq_res) 211 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 212 if (sc->io_res) 213 bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, 214 sc->io_res); 215 mtx_destroy(&sc->lock); 216 } 217 218 static int 219 intsmb_attach(device_t dev) 220 { 221 struct intsmb_softc *sc = device_get_softc(dev); 222 int error, rid, value; 223 int intr; 224 char *str; 225 226 sc->dev = dev; 227 228 mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF); 229 230 sc->cfg_irq9 = 0; 231 switch (pci_get_devid(dev)) { 232 #ifndef NO_CHANGE_PCICONF 233 case 0x71138086: /* Intel 82371AB */ 234 case 0x719b8086: /* Intel 82443MX */ 235 /* Changing configuration is allowed. */ 236 sc->cfg_irq9 = 1; 237 break; 238 #endif 239 case AMDSB_SMBUS_DEVID: 240 if (pci_get_revid(dev) >= AMDSB8_SMBUS_REVID) 241 sc->sb8xx = 1; 242 break; 243 case AMDFCH_SMBUS_DEVID: 244 case AMDCZ_SMBUS_DEVID: 245 case HYGONCZ_SMBUS_DEVID: 246 sc->sb8xx = 1; 247 break; 248 } 249 250 if (sc->sb8xx) { 251 error = sb8xx_attach(dev); 252 if (error != 0) 253 goto fail; 254 else 255 goto no_intr; 256 } 257 258 sc->io_rid = PCI_BASE_ADDR_SMB; 259 sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid, 260 RF_ACTIVE); 261 if (sc->io_res == NULL) { 262 device_printf(dev, "Could not allocate I/O space\n"); 263 error = ENXIO; 264 goto fail; 265 } 266 267 if (sc->cfg_irq9) { 268 pci_write_config(dev, PCIR_INTLINE, 0x9, 1); 269 pci_write_config(dev, PCI_HST_CFG_SMB, 270 PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1); 271 } 272 value = pci_read_config(dev, PCI_HST_CFG_SMB, 1); 273 sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0; 274 intr = value & PCI_INTR_SMB_MASK; 275 switch (intr) { 276 case PCI_INTR_SMB_SMI: 277 str = "SMI"; 278 break; 279 case PCI_INTR_SMB_IRQ9: 280 str = "IRQ 9"; 281 break; 282 case PCI_INTR_SMB_IRQ_PCI: 283 str = "PCI IRQ"; 284 break; 285 default: 286 str = "BOGUS"; 287 } 288 289 device_printf(dev, "intr %s %s ", str, 290 sc->poll == 0 ? "enabled" : "disabled"); 291 printf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1)); 292 293 if (!sc->poll && intr == PCI_INTR_SMB_SMI) { 294 device_printf(dev, 295 "using polling mode when configured interrupt is SMI\n"); 296 sc->poll = 1; 297 } 298 299 if (sc->poll) 300 goto no_intr; 301 302 if (intr != PCI_INTR_SMB_IRQ9 && intr != PCI_INTR_SMB_IRQ_PCI) { 303 device_printf(dev, "Unsupported interrupt mode\n"); 304 error = ENXIO; 305 goto fail; 306 } 307 308 /* Force IRQ 9. */ 309 rid = 0; 310 if (sc->cfg_irq9) 311 bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1); 312 313 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 314 RF_SHAREABLE | RF_ACTIVE); 315 if (sc->irq_res == NULL) { 316 device_printf(dev, "Could not allocate irq\n"); 317 error = ENXIO; 318 goto fail; 319 } 320 321 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 322 NULL, intsmb_rawintr, sc, &sc->irq_hand); 323 if (error) { 324 device_printf(dev, "Failed to map intr\n"); 325 goto fail; 326 } 327 328 no_intr: 329 sc->isbusy = 0; 330 sc->smbus = device_add_child(dev, "smbus", -1); 331 if (sc->smbus == NULL) { 332 device_printf(dev, "failed to add smbus child\n"); 333 error = ENXIO; 334 goto fail; 335 } 336 error = device_probe_and_attach(sc->smbus); 337 if (error) { 338 device_printf(dev, "failed to probe+attach smbus child\n"); 339 goto fail; 340 } 341 342 #ifdef ENABLE_ALART 343 /* Enable Arart */ 344 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); 345 #endif 346 return (0); 347 348 fail: 349 intsmb_release_resources(dev); 350 return (error); 351 } 352 353 static int 354 intsmb_detach(device_t dev) 355 { 356 int error; 357 358 error = bus_generic_detach(dev); 359 if (error) { 360 device_printf(dev, "bus detach failed\n"); 361 return (error); 362 } 363 364 intsmb_release_resources(dev); 365 return (0); 366 } 367 368 static void 369 intsmb_rawintr(void *arg) 370 { 371 struct intsmb_softc *sc = arg; 372 373 INTSMB_LOCK(sc); 374 intsmb_intr(sc); 375 intsmb_slvintr(sc); 376 INTSMB_UNLOCK(sc); 377 } 378 379 static int 380 intsmb_callback(device_t dev, int index, void *data) 381 { 382 int error = 0; 383 384 switch (index) { 385 case SMB_REQUEST_BUS: 386 break; 387 case SMB_RELEASE_BUS: 388 break; 389 default: 390 error = SMB_EINVAL; 391 } 392 393 return (error); 394 } 395 396 /* Counterpart of smbtx_smb_free(). */ 397 static int 398 intsmb_free(struct intsmb_softc *sc) 399 { 400 401 INTSMB_LOCK_ASSERT(sc); 402 if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) || 403 #ifdef ENABLE_ALART 404 (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) || 405 #endif 406 sc->isbusy) 407 return (SMB_EBUSY); 408 409 sc->isbusy = 1; 410 /* Disable Interrupt in slave part. */ 411 #ifndef ENABLE_ALART 412 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0); 413 #endif 414 /* Reset INTR Flag to prepare INTR. */ 415 bus_write_1(sc->io_res, PIIX4_SMBHSTSTS, 416 PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | 417 PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL); 418 return (0); 419 } 420 421 static int 422 intsmb_intr(struct intsmb_softc *sc) 423 { 424 int status, tmp; 425 426 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 427 if (status & PIIX4_SMBHSTSTAT_BUSY) 428 return (1); 429 430 if (status & (PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR | 431 PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL)) { 432 433 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 434 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, 435 tmp & ~PIIX4_SMBHSTCNT_INTREN); 436 if (sc->isbusy) { 437 sc->isbusy = 0; 438 wakeup(sc); 439 } 440 return (0); 441 } 442 return (1); /* Not Completed */ 443 } 444 445 static int 446 intsmb_slvintr(struct intsmb_softc *sc) 447 { 448 int status; 449 450 status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS); 451 if (status & PIIX4_SMBSLVSTS_BUSY) 452 return (1); 453 if (status & PIIX4_SMBSLVSTS_ALART) 454 intsmb_alrintr(sc); 455 else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 456 | PIIX4_SMBSLVSTS_SDW1)) { 457 } 458 459 /* Reset Status Register */ 460 bus_write_1(sc->io_res, PIIX4_SMBSLVSTS, 461 PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 | 462 PIIX4_SMBSLVSTS_SDW1 | PIIX4_SMBSLVSTS_SLV); 463 return (0); 464 } 465 466 static void 467 intsmb_alrintr(struct intsmb_softc *sc) 468 { 469 int slvcnt __unused; 470 #ifdef ENABLE_ALART 471 int error; 472 uint8_t addr; 473 #endif 474 475 /* Stop generating INTR from ALART. */ 476 slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT); 477 #ifdef ENABLE_ALART 478 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 479 slvcnt & ~PIIX4_SMBSLVCNT_ALTEN); 480 #endif 481 DELAY(5); 482 483 /* Ask bus who asserted it and then ask it what's the matter. */ 484 #ifdef ENABLE_ALART 485 error = intsmb_free(sc); 486 if (error) 487 return; 488 489 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, SMBALTRESP | LSB); 490 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 1); 491 error = intsmb_stop_poll(sc); 492 if (error) 493 device_printf(sc->dev, "ALART: ERROR\n"); 494 else { 495 addr = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 496 device_printf(sc->dev, "ALART_RESPONSE: 0x%x\n", addr); 497 } 498 499 /* Re-enable INTR from ALART. */ 500 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 501 slvcnt | PIIX4_SMBSLVCNT_ALTEN); 502 DELAY(5); 503 #endif 504 } 505 506 static void 507 intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr) 508 { 509 unsigned char tmp; 510 511 INTSMB_LOCK_ASSERT(sc); 512 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 513 tmp &= 0xe0; 514 tmp |= cmd; 515 tmp |= PIIX4_SMBHSTCNT_START; 516 517 /* While not in autoconfiguration enable interrupts. */ 518 if (!sc->poll && !cold && !nointr) 519 tmp |= PIIX4_SMBHSTCNT_INTREN; 520 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp); 521 } 522 523 static int 524 intsmb_error(device_t dev, int status) 525 { 526 int error = 0; 527 528 /* 529 * PIIX4_SMBHSTSTAT_ERR can mean either of 530 * - SMB_ENOACK ("Unclaimed cycle"), 531 * - SMB_ETIMEOUT ("Host device time-out"), 532 * - SMB_EINVAL ("Illegal command field"). 533 * SMB_ENOACK seems to be most typical. 534 */ 535 if (status & PIIX4_SMBHSTSTAT_ERR) 536 error |= SMB_ENOACK; 537 if (status & PIIX4_SMBHSTSTAT_BUSC) 538 error |= SMB_ECOLLI; 539 if (status & PIIX4_SMBHSTSTAT_FAIL) 540 error |= SMB_EABORT; 541 542 if (error != 0 && bootverbose) 543 device_printf(dev, "error = %d, status = %#x\n", error, status); 544 545 return (error); 546 } 547 548 /* 549 * Polling Code. 550 * 551 * Polling is not encouraged because it requires waiting for the 552 * device if it is busy. 553 * (29063505.pdf from Intel) But during boot, interrupt cannot be used, so use 554 * polling code then. 555 */ 556 static int 557 intsmb_stop_poll(struct intsmb_softc *sc) 558 { 559 int error, i, status, tmp; 560 561 INTSMB_LOCK_ASSERT(sc); 562 563 /* First, wait for busy to be set. */ 564 for (i = 0; i < 0x7fff; i++) 565 if (bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & 566 PIIX4_SMBHSTSTAT_BUSY) 567 break; 568 569 /* Wait for busy to clear. */ 570 for (i = 0; i < 0x7fff; i++) { 571 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 572 if (!(status & PIIX4_SMBHSTSTAT_BUSY)) { 573 sc->isbusy = 0; 574 error = intsmb_error(sc->dev, status); 575 return (error); 576 } 577 } 578 579 /* Timed out waiting for busy to clear. */ 580 sc->isbusy = 0; 581 tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 582 bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN); 583 return (SMB_ETIMEOUT); 584 } 585 586 /* 587 * Wait for completion and return result. 588 */ 589 static int 590 intsmb_stop(struct intsmb_softc *sc) 591 { 592 int error, status; 593 594 INTSMB_LOCK_ASSERT(sc); 595 596 if (sc->poll || cold) 597 /* So that it can use device during device probe on SMBus. */ 598 return (intsmb_stop_poll(sc)); 599 600 error = msleep(sc, &sc->lock, PWAIT | PCATCH, "SMBWAI", hz / 8); 601 if (error == 0) { 602 status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS); 603 if (!(status & PIIX4_SMBHSTSTAT_BUSY)) { 604 error = intsmb_error(sc->dev, status); 605 if (error == 0 && !(status & PIIX4_SMBHSTSTAT_INTR)) 606 device_printf(sc->dev, "unknown cause why?\n"); 607 #ifdef ENABLE_ALART 608 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 609 PIIX4_SMBSLVCNT_ALTEN); 610 #endif 611 return (error); 612 } 613 } 614 615 /* Timeout Procedure. */ 616 sc->isbusy = 0; 617 618 /* Re-enable suppressed interrupt from slave part. */ 619 bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN); 620 if (error == EWOULDBLOCK) 621 return (SMB_ETIMEOUT); 622 else 623 return (SMB_EABORT); 624 } 625 626 static int 627 intsmb_quick(device_t dev, u_char slave, int how) 628 { 629 struct intsmb_softc *sc = device_get_softc(dev); 630 int error; 631 u_char data; 632 633 data = slave; 634 635 /* Quick command is part of Address, I think. */ 636 switch(how) { 637 case SMB_QWRITE: 638 data &= ~LSB; 639 break; 640 case SMB_QREAD: 641 data |= LSB; 642 break; 643 default: 644 return (SMB_EINVAL); 645 } 646 647 INTSMB_LOCK(sc); 648 error = intsmb_free(sc); 649 if (error) { 650 INTSMB_UNLOCK(sc); 651 return (error); 652 } 653 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, data); 654 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_QUICK, 0); 655 error = intsmb_stop(sc); 656 INTSMB_UNLOCK(sc); 657 return (error); 658 } 659 660 static int 661 intsmb_sendb(device_t dev, u_char slave, char byte) 662 { 663 struct intsmb_softc *sc = device_get_softc(dev); 664 int error; 665 666 INTSMB_LOCK(sc); 667 error = intsmb_free(sc); 668 if (error) { 669 INTSMB_UNLOCK(sc); 670 return (error); 671 } 672 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 673 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, byte); 674 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); 675 error = intsmb_stop(sc); 676 INTSMB_UNLOCK(sc); 677 return (error); 678 } 679 680 static int 681 intsmb_recvb(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 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); 694 error = intsmb_stop(sc); 695 if (error == 0) { 696 #ifdef RECV_IS_IN_CMD 697 /* 698 * Linux SMBus stuff also troubles 699 * Because Intel's datasheet does not make clear. 700 */ 701 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD); 702 #else 703 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 704 #endif 705 } 706 INTSMB_UNLOCK(sc); 707 return (error); 708 } 709 710 static int 711 intsmb_writeb(device_t dev, u_char slave, char cmd, char byte) 712 { 713 struct intsmb_softc *sc = device_get_softc(dev); 714 int error; 715 716 INTSMB_LOCK(sc); 717 error = intsmb_free(sc); 718 if (error) { 719 INTSMB_UNLOCK(sc); 720 return (error); 721 } 722 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 723 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 724 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, byte); 725 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0); 726 error = intsmb_stop(sc); 727 INTSMB_UNLOCK(sc); 728 return (error); 729 } 730 731 static int 732 intsmb_writew(device_t dev, u_char slave, char cmd, short word) 733 { 734 struct intsmb_softc *sc = device_get_softc(dev); 735 int error; 736 737 INTSMB_LOCK(sc); 738 error = intsmb_free(sc); 739 if (error) { 740 INTSMB_UNLOCK(sc); 741 return (error); 742 } 743 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 744 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 745 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, word & 0xff); 746 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (word >> 8) & 0xff); 747 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); 748 error = intsmb_stop(sc); 749 INTSMB_UNLOCK(sc); 750 return (error); 751 } 752 753 static int 754 intsmb_readb(device_t dev, u_char slave, char cmd, char *byte) 755 { 756 struct intsmb_softc *sc = device_get_softc(dev); 757 int error; 758 759 INTSMB_LOCK(sc); 760 error = intsmb_free(sc); 761 if (error) { 762 INTSMB_UNLOCK(sc); 763 return (error); 764 } 765 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 766 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 767 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0); 768 error = intsmb_stop(sc); 769 if (error == 0) 770 *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 771 INTSMB_UNLOCK(sc); 772 return (error); 773 } 774 775 static int 776 intsmb_readw(device_t dev, u_char slave, char cmd, short *word) 777 { 778 struct intsmb_softc *sc = device_get_softc(dev); 779 int error; 780 781 INTSMB_LOCK(sc); 782 error = intsmb_free(sc); 783 if (error) { 784 INTSMB_UNLOCK(sc); 785 return (error); 786 } 787 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 788 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 789 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); 790 error = intsmb_stop(sc); 791 if (error == 0) { 792 *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 793 *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; 794 } 795 INTSMB_UNLOCK(sc); 796 return (error); 797 } 798 799 static int 800 intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) 801 { 802 803 return (SMB_ENOTSUPP); 804 } 805 806 static int 807 intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) 808 { 809 struct intsmb_softc *sc = device_get_softc(dev); 810 int error, i; 811 812 if (count > SMBBLOCKTRANS_MAX || count == 0) 813 return (SMB_EINVAL); 814 815 INTSMB_LOCK(sc); 816 error = intsmb_free(sc); 817 if (error) { 818 INTSMB_UNLOCK(sc); 819 return (error); 820 } 821 822 /* Reset internal array index. */ 823 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 824 825 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); 826 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 827 for (i = 0; i < count; i++) 828 bus_write_1(sc->io_res, PIIX4_SMBBLKDAT, buf[i]); 829 bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, count); 830 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); 831 error = intsmb_stop(sc); 832 INTSMB_UNLOCK(sc); 833 return (error); 834 } 835 836 static int 837 intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) 838 { 839 struct intsmb_softc *sc = device_get_softc(dev); 840 int error, i; 841 u_char nread; 842 843 INTSMB_LOCK(sc); 844 error = intsmb_free(sc); 845 if (error) { 846 INTSMB_UNLOCK(sc); 847 return (error); 848 } 849 850 /* Reset internal array index. */ 851 bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); 852 853 bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); 854 bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); 855 intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); 856 error = intsmb_stop(sc); 857 if (error == 0) { 858 nread = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); 859 if (nread != 0 && nread <= SMBBLOCKTRANS_MAX) { 860 *count = nread; 861 for (i = 0; i < nread; i++) 862 bus_read_1(sc->io_res, PIIX4_SMBBLKDAT); 863 } else 864 error = SMB_EBUSERR; 865 } 866 INTSMB_UNLOCK(sc); 867 return (error); 868 } 869 870 static device_method_t intsmb_methods[] = { 871 /* Device interface */ 872 DEVMETHOD(device_probe, intsmb_probe), 873 DEVMETHOD(device_attach, intsmb_attach), 874 DEVMETHOD(device_detach, intsmb_detach), 875 876 /* SMBus interface */ 877 DEVMETHOD(smbus_callback, intsmb_callback), 878 DEVMETHOD(smbus_quick, intsmb_quick), 879 DEVMETHOD(smbus_sendb, intsmb_sendb), 880 DEVMETHOD(smbus_recvb, intsmb_recvb), 881 DEVMETHOD(smbus_writeb, intsmb_writeb), 882 DEVMETHOD(smbus_writew, intsmb_writew), 883 DEVMETHOD(smbus_readb, intsmb_readb), 884 DEVMETHOD(smbus_readw, intsmb_readw), 885 DEVMETHOD(smbus_pcall, intsmb_pcall), 886 DEVMETHOD(smbus_bwrite, intsmb_bwrite), 887 DEVMETHOD(smbus_bread, intsmb_bread), 888 889 DEVMETHOD_END 890 }; 891 892 static driver_t intsmb_driver = { 893 "intsmb", 894 intsmb_methods, 895 sizeof(struct intsmb_softc), 896 }; 897 898 DRIVER_MODULE_ORDERED(intsmb, pci, intsmb_driver, 0, 0, SI_ORDER_ANY); 899 DRIVER_MODULE(smbus, intsmb, smbus_driver, 0, 0); 900 MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 901 MODULE_VERSION(intsmb, 1); 902 MODULE_PNP_INFO("W32:vendor/device;D:#", pci, intpm, intsmb_products, 903 nitems(intsmb_products)); 904