Deleted Added
full compact
28c28
< __FBSDID("$FreeBSD: head/sys/pci/intpm.c 162289 2006-09-13 18:56:39Z jhb $");
---
> __FBSDID("$FreeBSD: head/sys/pci/intpm.c 165951 2007-01-11 19:56:24Z jhb $");
31a32
> #include <sys/bus.h>
33,35c34
< #include <machine/bus.h>
<
< #include <sys/uio.h>
---
> #include <sys/lock.h>
37c36
< #include <sys/bus.h>
---
> #include <sys/mutex.h>
39c38
< #include <machine/resource.h>
---
> #include <machine/bus.h>
44,46d42
< /*This should be removed if force_pci_map_int supported*/
< #include <sys/interrupt.h>
<
53,65c49,56
< static struct _pcsid
< {
< u_int32_t type;
< char *desc;
< } pci_ids[] = {
< { 0x71138086, "Intel 82371AB Power management controller" },
< { 0x719b8086, "Intel 82443MX Power management controller" },
< #if 0
< /* Not a good idea yet, this stops isab0 functioning */
< { 0x02001166, "ServerWorks OSB4 PCI to ISA Bridge" },
< #endif
<
< { 0x00000000, NULL }
---
> struct intsmb_softc {
> device_t dev;
> struct resource *io_res;
> struct resource *irq_res;
> void *irq_hand;
> device_t smbus;
> int isbusy;
> struct mtx lock;
67a59,62
> #define INTSMB_LOCK(sc) mtx_lock(&(sc)->lock)
> #define INTSMB_UNLOCK(sc) mtx_unlock(&(sc)->lock)
> #define INTSMB_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED)
>
70,72c65,68
< static int intsmb_intr(device_t dev);
< static int intsmb_slvintr(device_t dev);
< static void intsmb_alrintr(device_t dev);
---
> static int intsmb_detach(device_t);
> static int intsmb_intr(struct intsmb_softc *sc);
> static int intsmb_slvintr(struct intsmb_softc *sc);
> static void intsmb_alrintr(struct intsmb_softc *sc);
84,90c80,84
< static void intsmb_start(device_t dev, u_char cmd, int nointr);
< static int intsmb_stop(device_t dev);
< static int intsmb_stop_poll(device_t dev);
< static int intsmb_free(device_t dev);
< static int intpm_probe (device_t dev);
< static int intpm_attach (device_t dev);
< static void intpm_intr(void *arg);
---
> static void intsmb_start(struct intsmb_softc *sc, u_char cmd, int nointr);
> static int intsmb_stop(struct intsmb_softc *sc);
> static int intsmb_stop_poll(struct intsmb_softc *sc);
> static int intsmb_free(struct intsmb_softc *sc);
> static void intsmb_rawintr(void *arg);
92c86,88
< static devclass_t intsmb_devclass;
---
> static int
> intsmb_probe(device_t dev)
> {
94,97c90,101
< static device_method_t intpm_methods[] = {
< /* Device interface */
< DEVMETHOD(device_probe, intsmb_probe),
< DEVMETHOD(device_attach, intsmb_attach),
---
> switch (pci_get_devid(dev)) {
> case 0x71138086: /* Intel 82371AB */
> case 0x719b8086: /* Intel 82443MX */
> #if 0
> /* Not a good idea yet, this stops isab0 functioning */
> case 0x02001166: /* ServerWorks OSB4 */
> #endif
> device_set_desc(dev, "Intel PIIX4 SMBUS Interface");
> break;
> default:
> return (ENXIO);
> }
99,100c103,104
< /* Bus interface */
< DEVMETHOD(bus_print_child, bus_generic_print_child),
---
> return (BUS_PROBE_DEFAULT);
> }
102,113c106,111
< /* SMBus interface */
< DEVMETHOD(smbus_callback, intsmb_callback),
< DEVMETHOD(smbus_quick, intsmb_quick),
< DEVMETHOD(smbus_sendb, intsmb_sendb),
< DEVMETHOD(smbus_recvb, intsmb_recvb),
< DEVMETHOD(smbus_writeb, intsmb_writeb),
< DEVMETHOD(smbus_writew, intsmb_writew),
< DEVMETHOD(smbus_readb, intsmb_readb),
< DEVMETHOD(smbus_readw, intsmb_readw),
< DEVMETHOD(smbus_pcall, intsmb_pcall),
< DEVMETHOD(smbus_bwrite, intsmb_bwrite),
< DEVMETHOD(smbus_bread, intsmb_bread),
---
> static int
> intsmb_attach(device_t dev)
> {
> struct intsmb_softc *sc = device_get_softc(dev);
> int error, rid, value;
> char *str;
115,116c113,114
< { 0, 0 }
< };
---
> sc = device_get_softc(dev);
> mtx_init(&sc->lock, device_get_nameunit(dev), "intsmb", MTX_DEF);
118,124c116,123
< struct intpm_pci_softc {
< bus_space_tag_t smbst;
< bus_space_handle_t smbsh;
< bus_space_tag_t pmst;
< bus_space_handle_t pmsh;
< device_t smbus;
< };
---
> rid = PCI_BASE_ADDR_SMB;
> sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
> RF_ACTIVE);
> if (sc->io_res == NULL) {
> device_printf(dev, "Could not allocate I/O space\n");
> error = ENXIO;
> goto fail;
> }
125a125,144
> #ifndef NO_CHANGE_PCICONF
> pci_write_config(dev, PCIR_INTLINE, 0x9, 1);
> pci_write_config(dev, PCI_HST_CFG_SMB,
> PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1);
> #endif
> value = pci_read_config(dev, PCI_HST_CFG_SMB, 1);
> switch (value & 0xe) {
> case PCI_INTR_SMB_SMI:
> str = "SMI";
> break;
> case PCI_INTR_SMB_IRQ9:
> str = "IRQ 9";
> break;
> default:
> str = "BOGUS";
> }
> device_printf(dev, "intr %s %s ", str,
> (value & 1) ? "enabled" : "disabled");
> value = pci_read_config(dev, PCI_REVID_SMB, 1);
> printf("revision %d\n", value);
127,133c146,150
< struct intsmb_softc {
< struct intpm_pci_softc *pci_sc;
< bus_space_tag_t st;
< bus_space_handle_t sh;
< device_t smbus;
< int isbusy;
< };
---
> if ((value & 0xe) != PCI_INTR_SMB_IRQ9) {
> device_printf(dev, "Unsupported interrupt mode\n");
> error = ENXIO;
> goto fail;
> }
135,139c152,161
< static driver_t intpm_driver = {
< "intsmb",
< intpm_methods,
< sizeof(struct intsmb_softc),
< };
---
> /* Force IRQ 9. */
> rid = 0;
> bus_set_resource(dev, SYS_RES_IRQ, rid, 9, 1);
> sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
> RF_SHAREABLE | RF_ACTIVE);
> if (sc->irq_res == NULL) {
> device_printf(dev, "Could not allocate irq\n");
> error = ENXIO;
> goto fail;
> }
141c163,168
< static devclass_t intpm_devclass;
---
> error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, intsmb_rawintr,
> sc, &sc->irq_hand);
> if (error) {
> device_printf(dev, "Failed to map intr\n");
> goto fail;
> }
143,145c170,172
< static device_method_t intpm_pci_methods[] = {
< DEVMETHOD(device_probe, intpm_probe),
< DEVMETHOD(device_attach, intpm_attach),
---
> value = pci_read_config(dev, PCI_BASE_ADDR_PM, 4);
> device_printf(dev, "PM %s %x\n", (value & 1) ? "I/O mapped" : "Memory",
> value & 0xfffe);
147,148c174,182
< { 0, 0 }
< };
---
> sc->isbusy = 0;
> sc->smbus = device_add_child(dev, "smbus", -1);
> if (sc->smbus == NULL) {
> error = ENXIO;
> goto fail;
> }
> error = device_probe_and_attach(sc->smbus);
> if (error)
> goto fail;
150,154c184,188
< static driver_t intpm_pci_driver = {
< "intpm",
< intpm_pci_methods,
< sizeof(struct intpm_pci_softc)
< };
---
> #ifdef ENABLE_ALART
> /* Enable Arart */
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN);
> #endif
> return (0);
155a190,194
> fail:
> intsmb_detach(dev);
> return (error);
> }
>
157c196
< intsmb_probe(device_t dev)
---
> intsmb_detach(device_t dev)
159a199
> int error;
161,164c201,203
< sc->smbus = device_add_child(dev, "smbus", -1);
< if (!sc->smbus)
< return (EINVAL); /* XXX don't know what to return else */
< device_set_desc(dev, "Intel PIIX4 SMBUS Interface");
---
> error = bus_generic_detach(dev);
> if (error)
> return (error);
166c205,215
< return (BUS_PROBE_DEFAULT); /* XXX don't know what to return else */
---
> if (sc->smbus)
> device_delete_child(dev, sc->smbus);
> if (sc->irq_hand)
> bus_teardown_intr(dev, sc->irq_res, sc->irq_hand);
> if (sc->irq_res)
> bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
> if (sc->io_res)
> bus_release_resource(dev, SYS_RES_IOPORT, PCI_BASE_ADDR_SMB,
> sc->io_res);
> mtx_destroy(&sc->lock);
> return (0);
168,169c217,219
< static int
< intsmb_attach(device_t dev)
---
>
> static void
> intsmb_rawintr(void *arg)
171c221
< struct intsmb_softc *sc = device_get_softc(dev);
---
> struct intsmb_softc *sc = arg;
173,184c223,226
< sc->pci_sc = device_get_softc(device_get_parent(dev));
< sc->isbusy = 0;
< sc->sh = sc->pci_sc->smbsh;
< sc->st = sc->pci_sc->smbst;
< sc->pci_sc->smbus = dev;
< device_probe_and_attach(sc->smbus);
< #ifdef ENABLE_ALART
< /*Enable Arart*/
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT,
< PIIX4_SMBSLVCNT_ALTEN);
< #endif
< return (0);
---
> INTSMB_LOCK(sc);
> intsmb_intr(sc);
> intsmb_slvintr(sc);
> INTSMB_UNLOCK(sc);
191d232
< intrmask_t s;
193d233
< s = splnet();
202d241
< splx(s);
209c248
< intsmb_free(device_t dev)
---
> intsmb_free(struct intsmb_softc *sc)
211,212d249
< struct intsmb_softc *sc = device_get_softc(dev);
< intrmask_t s;
214,215c251,252
< if ((bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTSTS) &
< PIIX4_SMBHSTSTAT_BUSY) ||
---
> INTSMB_LOCK_ASSERT(sc);
> if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) ||
217,218c254
< (bus_space_read_1(sc->st, sc->sh, PIIX4_SMBSLVSTS) &
< PIIX4_SMBSLVSTS_BUSY) ||
---
> (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) ||
221,222c257,258
< return (EBUSY);
< s = splhigh();
---
> return (SMB_EBUSY);
>
226c262
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT, 0);
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0);
229,232c265,267
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTSTS,
< (PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR |
< PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL));
< splx(s);
---
> bus_write_1(sc->io_res, PIIX4_SMBHSTSTS,
> PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR |
> PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL);
237c272
< intsmb_intr(device_t dev)
---
> intsmb_intr(struct intsmb_softc *sc)
239,240c274
< struct intsmb_softc *sc = device_get_softc(dev);
< int status;
---
> int status, tmp;
242c276
< status = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTSTS);
---
> status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
248d281
< int tmp;
250,251c283,284
< tmp = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTCNT);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCNT,
---
> tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCNT,
263c296
< intsmb_slvintr(device_t dev)
---
> intsmb_slvintr(struct intsmb_softc *sc)
265,266c298
< struct intsmb_softc *sc = device_get_softc(dev);
< int status, retval;
---
> int status;
268,269c300
< retval = 1;
< status = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBSLVSTS);
---
> status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS);
271,275c302,305
< return (retval);
< if (status & PIIX4_SMBSLVSTS_ALART) {
< intsmb_alrintr(dev);
< retval = 0;
< } else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2
---
> return (1);
> if (status & PIIX4_SMBSLVSTS_ALART)
> intsmb_alrintr(sc);
> else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2
277d306
< retval = 0;
281c310
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVSTS,
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVSTS,
284c313
< return (retval);
---
> return (0);
288c317
< intsmb_alrintr(device_t dev)
---
> intsmb_alrintr(struct intsmb_softc *sc)
290d318
< struct intsmb_softc *sc = device_get_softc(dev);
293a322
> uint8_t addr;
297c326
< slvcnt = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBSLVCNT);
---
> slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT);
299c328
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT,
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
306,312c335,337
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< SMBALTRESP | LSB);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BYTE, 1);
< if (!(error = intsmb_stop_poll(dev))) {
< u_int8_t addr;
---
> error = intsmb_free(sc);
> if (error)
> return;
314,319c339,347
< addr = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT0);
< printf("ALART_RESPONSE: 0x%x\n", addr);
< }
< } else
< printf("ERROR\n");
---
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, SMBALTRESP | LSB);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 1);
> error = intsmb_stop_poll(sc);
> if (error)
> device_printf(sc->dev, "ALART: ERROR\n");
> else {
> addr = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
> device_printf(sc->dev, "ALART_RESPONSE: 0x%x\n", addr);
> }
322c350
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT,
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
329c357
< intsmb_start(device_t dev, unsigned char cmd, int nointr)
---
> intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr)
331d358
< struct intsmb_softc *sc = device_get_softc(dev);
334c361,362
< tmp = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTCNT);
---
> INTSMB_LOCK_ASSERT(sc);
> tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
342c370
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCNT, tmp);
---
> bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp);
344a373,386
> static int
> intsmb_error(int status)
> {
> int error = 0;
>
> if (status & PIIX4_SMBHSTSTAT_ERR)
> error |= SMB_EBUSERR;
> if (status & PIIX4_SMBHSTSTAT_BUSC)
> error |= SMB_ECOLLI;
> if (status & PIIX4_SMBHSTSTAT_FAIL)
> error |= SMB_ENOACK;
> return (error);
> }
>
354c396
< intsmb_stop_poll(device_t dev)
---
> intsmb_stop_poll(struct intsmb_softc *sc)
356,358c398
< struct intsmb_softc *sc = device_get_softc(dev);
< int error, i;
< int tmp;
---
> int error, i, status, tmp;
360,363c400,402
< /*
< * In smbtx driver, Simply waiting.
< * This loops 100-200 times.
< */
---
> INTSMB_LOCK_ASSERT(sc);
>
> /* First, wait for busy to be set. */
365c404
< if (bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTSTS) &
---
> if (bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) &
368a408
> /* Wait for busy to clear. */
370,372c410
< int status;
<
< status = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTSTS);
---
> status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
375,377c413
< error = (status & PIIX4_SMBHSTSTAT_ERR) ? EIO :
< (status & PIIX4_SMBHSTSTAT_BUSC) ? EBUSY :
< (status & PIIX4_SMBHSTSTAT_FAIL) ? EIO : 0;
---
> error = intsmb_error(status);
379c415
< printf("unknown cause why?");
---
> device_printf(sc->dev, "unknown cause why?");
383a420
> /* Timed out waiting for busy to clear. */
385,388c422,424
< tmp = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTCNT);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCNT,
< tmp & ~PIIX4_SMBHSTCNT_INTREN);
< return (EIO);
---
> tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN);
> return (SMB_ETIMEOUT);
395c431
< intsmb_stop(device_t dev)
---
> intsmb_stop(struct intsmb_softc *sc)
397,399c433
< struct intsmb_softc *sc = device_get_softc(dev);
< int error;
< intrmask_t s;
---
> int error, status;
401c435,437
< if (cold) {
---
> INTSMB_LOCK_ASSERT(sc);
>
> if (cold)
403,405c439
< error = intsmb_stop_poll(dev);
< return (error);
< }
---
> return (intsmb_stop_poll(sc));
407,410c441,443
< if (!tsleep(sc, (PWAIT) | PCATCH, "SMBWAI", hz/8)) {
< int status;
<
< status = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTSTS);
---
> error = tsleep(sc, PWAIT | PCATCH, "SMBWAI", hz / 8);
> if (error == 0) {
> status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
412,414c445
< error = (status & PIIX4_SMBHSTSTAT_ERR) ? EIO :
< (status & PIIX4_SMBHSTSTAT_BUSC) ? EBUSY :
< (status & PIIX4_SMBHSTSTAT_FAIL) ? EIO : 0;
---
> error = intsmb_error(status);
416,417c447
< printf("intsmb%d: unknown cause why?\n",
< device_get_unit(dev));
---
> device_printf(sc->dev, "unknown cause why?\n");
419c449
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT,
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
427d456
< s = splhigh();
431,434c460,464
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBSLVCNT,
< PIIX4_SMBSLVCNT_ALTEN);
< splx(s);
< return (EIO);
---
> bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN);
> if (error == EWOULDBLOCK)
> return (SMB_ETIMEOUT);
> else
> return (SMB_EABORT);
441c471
< int error = 0;
---
> int error;
455c485
< error = EINVAL;
---
> return (EINVAL);
457,465d486
< if (!error) {
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< data);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_QUICK, 0);
< error = intsmb_stop(dev);
< }
< }
466a488,497
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
> }
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, data);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_QUICK, 0);
> error = intsmb_stop(sc);
> INTSMB_UNLOCK(sc);
476,482c507,511
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< slave & ~LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, byte);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BYTE, 0);
< error = intsmb_stop(dev);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
483a513,517
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, byte);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0);
> error = intsmb_stop(sc);
> INTSMB_UNLOCK(sc);
493,497c527,536
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD, slave | LSB);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BYTE, 0);
< if (!(error = intsmb_stop(dev))) {
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
> }
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0);
> error = intsmb_stop(sc);
> if (error == 0) {
499,504c538,542
< /*
< * Linux SMBus stuff also troubles
< * Because Intel's datasheet does not make clear.
< */
< *byte = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTCMD);
---
> /*
> * Linux SMBus stuff also troubles
> * Because Intel's datasheet does not make clear.
> */
> *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD);
506,507c544
< *byte = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT0);
---
> *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
509d545
< }
510a547
> INTSMB_UNLOCK(sc);
520,527c557,561
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< slave & ~LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0, byte);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BDATA, 0);
< error = intsmb_stop(dev);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
528a563,568
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, byte);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0);
> error = intsmb_stop(sc);
> INTSMB_UNLOCK(sc);
538,548c578,582
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< slave & ~LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0,
< word & 0xff);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT1,
< (word >> 8) & 0xff);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
< error = intsmb_stop(dev);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
549a584,590
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, word & 0xff);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (word >> 8) & 0xff);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
> error = intsmb_stop(sc);
> INTSMB_UNLOCK(sc);
559,566c600,604
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD, slave | LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BDATA, 0);
< if (!(error = intsmb_stop(dev)))
< *byte = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT0);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
567a606,612
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0);
> error = intsmb_stop(sc);
> if (error == 0)
> *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
> INTSMB_UNLOCK(sc);
569a615
>
576,586c622,626
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD, slave | LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
< if (!(error = intsmb_stop(dev))) {
< *word = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT0);
< *word |= bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT1) << 8;
< }
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
587a628,636
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
> error = intsmb_stop(sc);
> if (error == 0) {
> *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
> *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8;
> }
> INTSMB_UNLOCK(sc);
603,612c652,656
< error = intsmb_free(dev);
< if (!error) {
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< slave & ~LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0,
< sdata & 0xff);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT1,
< (sdata & 0xff) >> 8);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
614,617c658,666
< if (!(error = intsmb_stop(dev))) {
< *rdata = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0);
< *rdata |= bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTDAT1) <<
< 8;
---
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, sdata & 0xff);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (sdata & 0xff) >> 8);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0);
> error = intsmb_stop(sc);
> if (error == 0) {
> *rdata = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
> *rdata |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8;
618a668
> INTSMB_UNLOCK(sc);
621c671
< return (0);
---
> return (SMB_ENOTSUPP);
631d680
< error = intsmb_free(dev);
633,636c682
< error = SMB_EINVAL;
< if (!error) {
< /* Reset internal array index. */
< bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTCNT);
---
> return (SMB_EINVAL);
638,646c684,688
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD,
< slave & ~LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< for (i = 0; i < count; i++)
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBBLKDAT,
< buf[i]);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0, count);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BLOCK, 0);
< error = intsmb_stop(dev);
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
647a690,701
>
> /* Reset internal array index. */
> bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
>
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> for (i = 0; i < count; i++)
> bus_write_1(sc->io_res, PIIX4_SMBBLKDAT, buf[i]);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, count);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0);
> error = intsmb_stop(sc);
> INTSMB_UNLOCK(sc);
658d711
< error = intsmb_free(dev);
660,663c713
< error = SMB_EINVAL;
< if (!error) {
< /* Reset internal array index. */
< bus_space_read_1(sc->st, sc->sh, PIIX4_SMBHSTCNT);
---
> return (SMB_EINVAL);
665,682c715,736
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTADD, slave | LSB);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTCMD, cmd);
< bus_space_write_1(sc->st, sc->sh, PIIX4_SMBHSTDAT0, *count);
< intsmb_start(dev, PIIX4_SMBHSTCNT_PROT_BLOCK, 0);
< error = intsmb_stop(dev);
< if (!error) {
< nread= bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBHSTDAT0);
< if (nread != 0 && nread <= SMBBLOCKTRANS_MAX) {
< for (i = 0; i < nread; i++) {
< data = bus_space_read_1(sc->st, sc->sh,
< PIIX4_SMBBLKDAT);
< if (i < *count)
< buf[i] = data;
< }
< *count = nread;
< } else {
< error = EIO;
---
> INTSMB_LOCK(sc);
> error = intsmb_free(sc);
> if (error) {
> INTSMB_UNLOCK(sc);
> return (error);
> }
>
> /* Reset internal array index. */
> bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
>
> bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB);
> bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd);
> bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, *count);
> intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0);
> error = intsmb_stop(sc);
> if (error == 0) {
> nread = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
> if (nread != 0 && nread <= SMBBLOCKTRANS_MAX) {
> for (i = 0; i < nread; i++) {
> data = bus_read_1(sc->io_res, PIIX4_SMBBLKDAT);
> if (i < *count)
> buf[i] = data;
684c738,740
< }
---
> *count = nread;
> } else
> error = EIO;
685a742
> INTSMB_UNLOCK(sc);
689c746
< DRIVER_MODULE(intsmb, intpm, intpm_driver, intsmb_devclass, 0, 0);
---
> static devclass_t intsmb_devclass;
691,700c748,752
< static int
< intpm_attach(device_t dev)
< {
< struct intpm_pci_softc *sc;
< struct resource *res;
< device_t smbinterface;
< void *ih;
< char *str;
< int error, rid, value;
< int unit = device_get_unit(dev);
---
> static device_method_t intsmb_methods[] = {
> /* Device interface */
> DEVMETHOD(device_probe, intsmb_probe),
> DEVMETHOD(device_attach, intsmb_attach),
> DEVMETHOD(device_detach, intsmb_detach),
702,704c754,755
< sc = device_get_softc(dev);
< if (sc == NULL)
< return (ENOMEM);
---
> /* Bus interface */
> DEVMETHOD(bus_print_child, bus_generic_print_child),
706,713c757,768
< rid = PCI_BASE_ADDR_SMB;
< res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
< if (res == NULL) {
< device_printf(dev, "Could not allocate Bus space\n");
< return (ENXIO);
< }
< sc->smbst = rman_get_bustag(res);
< sc->smbsh = rman_get_bushandle(res);
---
> /* SMBus interface */
> DEVMETHOD(smbus_callback, intsmb_callback),
> DEVMETHOD(smbus_quick, intsmb_quick),
> DEVMETHOD(smbus_sendb, intsmb_sendb),
> DEVMETHOD(smbus_recvb, intsmb_recvb),
> DEVMETHOD(smbus_writeb, intsmb_writeb),
> DEVMETHOD(smbus_writew, intsmb_writew),
> DEVMETHOD(smbus_readb, intsmb_readb),
> DEVMETHOD(smbus_readw, intsmb_readw),
> DEVMETHOD(smbus_pcall, intsmb_pcall),
> DEVMETHOD(smbus_bwrite, intsmb_bwrite),
> DEVMETHOD(smbus_bread, intsmb_bread),
715,718c770,771
< #ifdef __i386__
< device_printf(dev, "%s %lx\n", (sc->smbst == I386_BUS_SPACE_IO) ?
< "I/O mapped" : "Memory", rman_get_start(res));
< #endif
---
> { 0, 0 }
> };
720,739c773,777
< #ifndef NO_CHANGE_PCICONF
< pci_write_config(dev, PCIR_INTLINE, 0x9, 1);
< pci_write_config(dev, PCI_HST_CFG_SMB,
< PCI_INTR_SMB_IRQ9 | PCI_INTR_SMB_ENABLE, 1);
< #endif
< value = pci_read_config(dev, PCI_HST_CFG_SMB, 1);
< switch (value & 0xe) {
< case PCI_INTR_SMB_SMI:
< str = "SMI";
< break;
< case PCI_INTR_SMB_IRQ9:
< str = "IRQ 9";
< break;
< default:
< str = "BOGUS";
< }
< device_printf(dev, "intr %s %s ", str,
< (value & 1) ? "enabled" : "disabled");
< value = pci_read_config(dev, PCI_REVID_SMB, 1);
< printf("revision %d\n", value);
---
> static driver_t intsmb_driver = {
> "intsmb",
> intsmb_methods,
> sizeof(struct intsmb_softc),
> };
741,791c779
< /* Install interrupt handler. */
< rid = 0;
< res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 9, 9, 1,
< RF_SHAREABLE | RF_ACTIVE);
< if (res == NULL) {
< device_printf(dev, "could not allocate irq");
< return (ENOMEM);
< }
< error = bus_setup_intr(dev, res, INTR_TYPE_MISC, intpm_intr, sc, &ih);
< if (error) {
< device_printf(dev, "Failed to map intr\n");
< return (error);
< }
< smbinterface = device_add_child(dev, "intsmb", unit);
< if (!smbinterface)
< printf("intsmb%d: could not add SMBus device\n", unit);
< device_probe_and_attach(smbinterface);
<
< value = pci_read_config(dev, PCI_BASE_ADDR_PM, 4);
< printf("intpm%d: PM %s %x \n", unit,
< (value & 1) ? "I/O mapped" : "Memory", value & 0xfffe);
< return (0);
< }
<
< static int
< intpm_probe(device_t dev)
< {
< struct _pcsid *ep = pci_ids;
< uint32_t device_id = pci_get_devid(dev);
<
< while (ep->type && ep->type != device_id)
< ++ep;
< if (ep->desc != NULL) {
< device_set_desc(dev, ep->desc);
< bus_set_resource(dev, SYS_RES_IRQ, 0, 9, 1); /* XXX setup intr resource */
< return (BUS_PROBE_DEFAULT);
< } else {
< return (ENXIO);
< }
< }
<
< static void
< intpm_intr(void *arg)
< {
< struct intpm_pci_softc *sc = arg;
<
< intsmb_intr(sc->smbus);
< intsmb_slvintr(sc->smbus);
< }
<
< DRIVER_MODULE(intpm, pci , intpm_pci_driver, intpm_devclass, 0, 0);
---
> DRIVER_MODULE(intsmb, pci, intsmb_driver, intsmb_devclass, 0, 0);
793,794c781,782
< MODULE_DEPEND(intpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
< MODULE_VERSION(intpm, 1);
---
> MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
> MODULE_VERSION(intsmb, 1);