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