iicbus: Bring us closer to FreeBSD.
authorSascha Wildner <saw@online.de>
Mon, 16 Aug 2010 17:39:23 +0000 (19:39 +0200)
committerSascha Wildner <saw@online.de>
Mon, 16 Aug 2010 17:41:13 +0000 (19:41 +0200)
This is work in progress and I commit it so Dave Shao's Summer of Code
project can proceed.

Further commits will follow.

Taken-from: FreeBSD

60 files changed:
share/man/man4/intpm.4
sys/bus/Makefile
sys/bus/iicbus/Makefile [new file with mode: 0644]
sys/bus/iicbus/iic.c
sys/bus/iicbus/iic.h [moved from sys/platform/pc32/include/iic.h with 76% similarity]
sys/bus/iicbus/iic/Makefile [new file with mode: 0644]
sys/bus/iicbus/iicbb.c
sys/bus/iicbus/iicbb/Makefile [new file with mode: 0644]
sys/bus/iicbus/iicbb_if.m
sys/bus/iicbus/iicbus.c
sys/bus/iicbus/iicbus.h
sys/bus/iicbus/iicbus/Makefile [new file with mode: 0644]
sys/bus/iicbus/iicbus_if.m
sys/bus/iicbus/iiconf.c
sys/bus/iicbus/iiconf.h
sys/bus/iicbus/iicsmb.c
sys/bus/iicbus/iicsmb/Makefile [new file with mode: 0644]
sys/bus/iicbus/pcf/Makefile [new file with mode: 0644]
sys/bus/iicbus/pcf/pcf.c [moved from sys/bus/iicbus/i386/pcf.c with 95% similarity]
sys/bus/ppbus/Makefile [new file with mode: 0644]
sys/bus/smbus/Makefile [new file with mode: 0644]
sys/bus/smbus/smb.c
sys/bus/smbus/smb.h [moved from sys/platform/pc32/include/smb.h with 85% similarity]
sys/bus/smbus/smb/Makefile [new file with mode: 0644]
sys/bus/smbus/smbconf.c
sys/bus/smbus/smbconf.h
sys/bus/smbus/smbus.c
sys/bus/smbus/smbus.h
sys/bus/smbus/smbus/Makefile [new file with mode: 0644]
sys/bus/smbus/smbus_if.m
sys/conf/files
sys/dev/misc/Makefile
sys/dev/misc/lpbb/Makefile [new file with mode: 0644]
sys/dev/misc/lpbb/lpbb.c
sys/dev/netif/Makefile
sys/dev/netif/ic/Makefile [new file with mode: 0644]
sys/dev/netif/ic/if_ic.c
sys/dev/powermng/Makefile
sys/dev/powermng/alpm/Makefile [new file with mode: 0644]
sys/dev/powermng/alpm/alpm.c [moved from sys/dev/powermng/i386/alpm/alpm.c with 62% similarity]
sys/dev/powermng/amdpm/Makefile [new file with mode: 0644]
sys/dev/powermng/amdpm/amdpm.c [moved from sys/dev/powermng/i386/amdpm/amdpm.c with 63% similarity]
sys/dev/powermng/i386/intpm/intpm.c [deleted file]
sys/dev/powermng/i386/intpm/intpmreg.h [deleted file]
sys/dev/powermng/ichsmb/Makefile [new file with mode: 0644]
sys/dev/powermng/ichsmb/ichsmb.c
sys/dev/powermng/ichsmb/ichsmb_pci.c
sys/dev/powermng/ichsmb/ichsmb_reg.h
sys/dev/powermng/ichsmb/ichsmb_var.h
sys/dev/powermng/intpm/Makefile [new file with mode: 0644]
sys/dev/powermng/intpm/intpm.c [new file with mode: 0644]
sys/dev/powermng/intpm/intpmreg.h [new file with mode: 0644]
sys/dev/powermng/viapm/Makefile [new file with mode: 0644]
sys/dev/powermng/viapm/viapm.c [moved from sys/dev/powermng/i386/viapm/viapm.c with 86% similarity]
sys/dev/video/Makefile
sys/dev/video/cxm/Makefile [new file with mode: 0644]
sys/dev/video/cxm/cxm/Makefile [new file with mode: 0644]
sys/dev/video/cxm/cxm_i2c.c
sys/dev/video/cxm/cxm_iic/Makefile [new file with mode: 0644]
sys/platform/pc32/conf/files

index e11680d..cd5f918 100644 (file)
@@ -22,8 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man4/intpm.4,v 1.8.2.4 2001/08/17 13:08:38 ru Exp $
-.\" $DragonFly: src/share/man/man4/intpm.4,v 1.2 2003/06/17 04:36:59 dillon Exp $
+.\" $FreeBSD: src/share/man/man4/intpm.4,v 1.15 2005/02/13 22:25:17 ru Exp $
 .\"
 .Dd January 8, 1999
 .Dt INTPM 4
@@ -33,6 +32,7 @@
 .Nd Intel PIIX4 Power Management controller driver
 .Sh SYNOPSIS
 .Cd device smbus
+.Cd device smb
 .Cd device intpm
 .Sh DESCRIPTION
 This driver provides access to
@@ -60,4 +60,4 @@ This device requires IRQ 9 exclusively.
 To use this, you should enable
 ACPI function in BIOS configuration, or PnP mechanism assigns conflicted
 IRQ for PnP ISA card.
-And don't use IRQ 9 for Non-PnP ISA cards.
+And do not use IRQ 9 for Non-PnP ISA cards.
index 124f34c..deb666b 100644 (file)
@@ -1,3 +1,3 @@
-SUBDIR=cam firewire mmc pccard usb
+SUBDIR=cam firewire iicbus mmc pccard ppbus smbus usb
 
 .include <bsd.subdir.mk>
diff --git a/sys/bus/iicbus/Makefile b/sys/bus/iicbus/Makefile
new file mode 100644 (file)
index 0000000..13f81e3
--- /dev/null
@@ -0,0 +1,5 @@
+# $FreeBSD: src/sys/modules/i2c/Makefile,v 1.1 2002/03/23 15:48:36 nsouch Exp $
+
+SUBDIR = iicbus iicbb iicsmb iic pcf
+
+.include <bsd.subdir.mk>
index d611739..1b0b2d2 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iic.c,v 1.18 1999/11/18 05:43:32 peter Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iic.c,v 1.43 2009/01/26 13:53:39 raj Exp $
  * $DragonFly: src/sys/bus/iicbus/iic.c,v 1.10 2006/09/10 01:26:32 dillon Exp $
  *
  */
 #include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/module.h>
+#include <sys/buf.h>
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/uio.h>
-#include <sys/malloc.h>
 #include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
 
-#include <machine/clock.h>
-
-#include "iiconf.h"
-#include "iicbus.h"
-
-#include <machine/iic.h>
+#include <bus/iicbus/iiconf.h>
+#include <bus/iicbus/iicbus.h>
+#include <bus/iicbus/iic.h>
 
 #include "iicbus_if.h"
 
 
 struct iic_softc {
 
-       u_char sc_addr;                 /* address on iicbus */
+       device_t sc_dev;
+       u_char sc_addr;                 /* 7 bit address on iicbus */
        int sc_count;                   /* >0 if device opened */
 
        char sc_buffer[BUFSIZE];        /* output buffer */
        char sc_inbuf[BUFSIZE];         /* input buffer */
-};
 
-#define IIC_SOFTC(unit) \
-       ((struct iic_softc *)devclass_get_softc(iic_devclass, (unit)))
+       cdev_t sc_devnode;
+};
 
-#define IIC_DEVICE(unit) \
-       (devclass_get_device(iic_devclass, (unit)))
+#define        IIC_LOCK(sc)
+#define        IIC_UNLOCK(sc)
 
 static int iic_probe(device_t);
 static int iic_attach(device_t);
+static int iic_detach(device_t);
+static void iic_identify(driver_t *driver, device_t parent);
 
 static devclass_t iic_devclass;
 
 static device_method_t iic_methods[] = {
        /* device interface */
+       DEVMETHOD(device_identify,      iic_identify),
        DEVMETHOD(device_probe,         iic_probe),
        DEVMETHOD(device_attach,        iic_attach),
+       DEVMETHOD(device_detach,        iic_detach),
 
        /* iicbus interface */
        DEVMETHOD(iicbus_intr,          iicbus_generic_intr),
@@ -92,9 +93,8 @@ static        d_write_t       iicwrite;
 static d_read_t        iicread;
 static d_ioctl_t       iicioctl;
 
-#define CDEV_MAJOR 105
 static struct dev_ops iic_ops = {
-       { "iic", CDEV_MAJOR, 0 },
+       { "iic", 0, 0 },
        .d_open =       iicopen,
        .d_close =      iicclose,
        .d_read =       iicread,
@@ -102,46 +102,67 @@ static struct dev_ops iic_ops = {
        .d_ioctl =      iicioctl,
 };
 
-/*
- * iicprobe()
- */
+static void
+iic_identify(driver_t *driver, device_t parent)
+{
+
+       if (device_find_child(parent, "iic", -1) == NULL)
+               BUS_ADD_CHILD(parent, parent, 0, "iic", -1);
+}
+
 static int
 iic_probe(device_t dev)
 {
-       struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
-
-       sc->sc_addr = iicbus_get_addr(dev);
+       if (iicbus_get_addr(dev) > 0)
+               return (ENXIO);
 
-       /* XXX detect chip with start/stop conditions */
+       device_set_desc(dev, "I2C generic I/O");
 
        return (0);
 }
        
-/*
- * iicattach()
- */
 static int
 iic_attach(device_t dev)
 {
-       make_dev(&iic_ops, device_get_unit(dev),        /* XXX cleanup */
+       struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
+
+       sc->sc_devnode = make_dev(&iic_ops, device_get_unit(dev),
                        UID_ROOT, GID_WHEEL,
                        0600, "iic%d", device_get_unit(dev));
+       if (sc->sc_devnode == NULL) {
+               device_printf(dev, "failed to create character device\n");
+               return (ENXIO);
+       }
+       sc->sc_devnode->si_drv1 = sc;
+
        return (0);
 }
 
 static int
-iicopen (struct dev_open_args *ap)
+iic_detach(device_t dev)
 {
-       cdev_t dev = ap->a_head.a_dev;
-       struct iic_softc *sc = IIC_SOFTC(minor(dev));
+       struct iic_softc *sc = (struct iic_softc *)device_get_softc(dev);
 
-       if (!sc)
-               return (EINVAL);
+       if (sc->sc_devnode)
+               dev_ops_remove_minor(&iic_ops, device_get_unit(dev));
+
+       return (0);
+}
+
+static int
+iicopen(struct dev_open_args *ap)
+{
+       cdev_t dev = ap->a_head.a_dev;
+       struct iic_softc *sc = dev->si_drv1;
 
-       if (sc->sc_count > 0)
+       IIC_LOCK(sc);
+       if (sc->sc_count > 0) {
+               IIC_UNLOCK(sc);
                return (EBUSY);
+       }
 
        sc->sc_count++;
+       IIC_UNLOCK(sc);
 
        return (0);
 }
@@ -150,18 +171,20 @@ static int
 iicclose(struct dev_close_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
-       struct iic_softc *sc = IIC_SOFTC(minor(dev));
-
-       if (!sc)
-               return (EINVAL);
+       struct iic_softc *sc = dev->si_drv1;
 
-       if (!sc->sc_count)
+       IIC_LOCK(sc);
+       if (!sc->sc_count) {
+               /* XXX: I don't think this can happen. */
+               IIC_UNLOCK(sc);
                return (EINVAL);
+       }
 
        sc->sc_count--;
 
        if (sc->sc_count < 0)
                panic("%s: iic_count < 0!", __func__);
+       IIC_UNLOCK(sc);
 
        return (0);
 }
@@ -171,18 +194,28 @@ iicwrite(struct dev_write_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
        struct uio *uio = ap->a_uio;
-       device_t iicdev = IIC_DEVICE(minor(dev));
-       struct iic_softc *sc = IIC_SOFTC(minor(dev));
+       struct iic_softc *sc = dev->si_drv1;
+       device_t iicdev = sc->sc_dev;
        int sent, error, count;
 
-       if (!sc || !iicdev)
+       IIC_LOCK(sc);
+       if (!sc->sc_addr) {
+               IIC_UNLOCK(sc);
                return (EINVAL);
+       }
 
-       if (sc->sc_count == 0)
+       if (sc->sc_count == 0) {
+               /* XXX: I don't think this can happen. */
+               IIC_UNLOCK(sc);
                return (EINVAL);
+       }
 
-       if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
+       error = iicbus_request_bus(device_get_parent(iicdev), iicdev,
+           IIC_DONTWAIT);
+       if (error) {
+               IIC_UNLOCK(sc);
                return (error);
+       }
 
        count = (int)szmin(uio->uio_resid, BUFSIZE);
        uiomove(sc->sc_buffer, (size_t)count, uio);
@@ -191,8 +224,9 @@ iicwrite(struct dev_write_args *ap)
                                        sc->sc_buffer, count, &sent);
 
        iicbus_release_bus(device_get_parent(iicdev), iicdev);
+       IIC_UNLOCK(sc);
 
-       return(error);
+       return (error);
 }
 
 static int
@@ -200,56 +234,86 @@ iicread(struct dev_read_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
        struct uio *uio = ap->a_uio;
-       device_t iicdev = IIC_DEVICE(minor(dev));
-       struct iic_softc *sc = IIC_SOFTC(minor(dev));
+       struct iic_softc *sc = dev->si_drv1;
+       device_t iicdev = sc->sc_dev;
        int len, error = 0;
        int bufsize;
 
-       if (!sc || !iicdev)
+       IIC_LOCK(sc);
+       if (!sc->sc_addr) {
+               IIC_UNLOCK(sc);
                return (EINVAL);
+       }
 
-       if (sc->sc_count == 0)
+       if (sc->sc_count == 0) {
+               /* XXX: I don't think this can happen. */
+               IIC_UNLOCK(sc);
                return (EINVAL);
+       }
 
-       if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
+       error = iicbus_request_bus(device_get_parent(iicdev), iicdev,
+           IIC_DONTWAIT);
+       if (error) {
+               IIC_UNLOCK(sc);
                return (error);
+       }
 
        /* max amount of data to read */
        len = (int)szmin(uio->uio_resid, BUFSIZE);
 
-       if ((error = iicbus_block_read(device_get_parent(iicdev), sc->sc_addr,
-                                       sc->sc_inbuf, len, &bufsize)))
+       error = iicbus_block_read(device_get_parent(iicdev), sc->sc_addr,
+           sc->sc_inbuf, len, &bufsize);
+       if (error) {
+               IIC_UNLOCK(sc);
                return (error);
+       }
 
        if (bufsize > uio->uio_resid)
                panic("%s: too much data read!", __func__);
 
        iicbus_release_bus(device_get_parent(iicdev), iicdev);
 
-       return (uiomove(sc->sc_inbuf, (size_t)bufsize, uio));
+       error = uiomove(sc->sc_inbuf, (size_t)bufsize, uio);
+       IIC_UNLOCK(sc);
+       return (error);
 }
 
 static int
 iicioctl(struct dev_ioctl_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
-       device_t iicdev = IIC_DEVICE(minor(dev));
-       struct iic_softc *sc = IIC_SOFTC(minor(dev));
+       u_long cmd = ap->a_cmd;
+       caddr_t data = ap->a_data;
+       int flags = ap->a_fflag;
+       struct iic_softc *sc = dev->si_drv1;
+       device_t iicdev = sc->sc_dev;
        device_t parent = device_get_parent(iicdev);
-       struct iiccmd *s = (struct iiccmd *)ap->a_data;
-       int error, count;
-
-       if (!sc)
-               return (EINVAL);
+       struct iiccmd *s = (struct iiccmd *)data;
+       struct iic_rdwr_data *d = (struct iic_rdwr_data *)data;
+       struct iic_msg *m;
+       int error, count, i;
+       char *buf = NULL;
+       void **usrbufs = NULL;
 
        if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev,
-                       (ap->a_fflag & O_NONBLOCK) ? IIC_DONTWAIT :
+                       (flags & O_NONBLOCK) ? IIC_DONTWAIT :
                                                (IIC_WAIT | IIC_INTR))))
                return (error);
 
-       switch (ap->a_cmd) {
+       switch (cmd) {
        case I2CSTART:
+               IIC_LOCK(sc);
                error = iicbus_start(parent, s->slave, 0);
+
+               /*
+                * Implicitly set the chip addr to the slave addr passed as
+                * parameter. Consequently, start/stop shall be called before
+                * the read or the write of a block.
+                */
+               if (!error)
+                       sc->sc_addr = s->slave;
+               IIC_UNLOCK(sc);
+
                break;
 
        case I2CSTOP:
@@ -257,24 +321,73 @@ iicioctl(struct dev_ioctl_args *ap)
                break;
 
        case I2CRSTCARD:
-               error = iicbus_reset(parent, 0, 0, NULL);
+               error = iicbus_reset(parent, IIC_UNKNOWN, 0, NULL);
                break;
 
        case I2CWRITE:
-               error = iicbus_write(parent, s->buf, s->count, &count, 0);
+               if (s->count <= 0) {
+                       error = EINVAL;
+                       break;
+               }
+               buf = kmalloc((unsigned long)s->count, M_TEMP, M_WAITOK);
+               error = copyin(s->buf, buf, s->count);
+               if (error)
+                       break;
+               error = iicbus_write(parent, buf, s->count, &count, 10);
                break;
 
        case I2CREAD:
-               error = iicbus_read(parent, s->buf, s->count, &count, s->last, 0);
+               if (s->count <= 0) {
+                       error = EINVAL;
+                       break;
+               }
+               buf = kmalloc((unsigned long)s->count, M_TEMP, M_WAITOK);
+               error = iicbus_read(parent, buf, s->count, &count, s->last, 10);
+               if (error)
+                       break;
+               error = copyout(buf, s->buf, s->count);
+               break;
+
+       case I2CRDWR:
+               buf = kmalloc(sizeof(*d->msgs) * d->nmsgs, M_TEMP, M_WAITOK);
+               usrbufs = kmalloc(sizeof(void *) * d->nmsgs, M_TEMP, M_ZERO | M_WAITOK);
+               error = copyin(d->msgs, buf, sizeof(*d->msgs) * d->nmsgs);
+               if (error)
+                       break;
+               /* Alloc kernel buffers for userland data, copyin write data */
+               for (i = 0; i < d->nmsgs; i++) {
+                       m = &((struct iic_msg *)buf)[i];
+                       usrbufs[i] = m->buf;
+                       m->buf = kmalloc(m->len, M_TEMP, M_WAITOK);
+                       if (!(m->flags & IIC_M_RD))
+                               copyin(usrbufs[i], m->buf, m->len);
+               }
+               error = iicbus_transfer(parent, (struct iic_msg *)buf, d->nmsgs);
+               /* Copyout all read segments, free up kernel buffers */
+               for (i = 0; i < d->nmsgs; i++) {
+                       m = &((struct iic_msg *)buf)[i];
+                       if (m->flags & IIC_M_RD)
+                               copyout(m->buf, usrbufs[i], m->len);
+                       kfree(m->buf, M_TEMP);
+               }
+               kfree(usrbufs, M_TEMP);
+               break;
+
+       case I2CRPTSTART:
+               error = iicbus_repeated_start(parent, s->slave, 0);
                break;
 
        default:
-               error = ENODEV;
+               error = ENOTTY;
        }
 
        iicbus_release_bus(device_get_parent(iicdev), iicdev);
 
+       if (buf != NULL)
+               kfree(buf, M_TEMP);
        return (error);
 }
 
 DRIVER_MODULE(iic, iicbus, iic_driver, iic_devclass, 0, 0);
+MODULE_DEPEND(iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
+MODULE_VERSION(iic, 1);
similarity index 76%
rename from sys/platform/pc32/include/iic.h
rename to sys/bus/iicbus/iic.h
index 06f2209..fa62e85 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/i386/include/iic.h,v 1.3 1999/08/28 00:44:16 peter Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iic.h,v 1.6 2009/01/26 13:53:39 raj Exp $
  * $DragonFly: src/sys/platform/pc32/include/iic.h,v 1.4 2006/05/20 02:42:06 dillon Exp $
  *
  */
-#ifndef _MACHINE_IIC_H_
-#define _MACHINE_IIC_H_
+#ifndef __IIC_H
+#define __IIC_H
 
-#ifndef _SYS_TYPES_H_
-#include <sys/types.h>
-#endif
-#ifndef _SYS_IOCCOM_H_
 #include <sys/ioccom.h>
-#endif
+
+/* Designed to be compatible with linux's struct i2c_msg */
+struct iic_msg
+{
+       uint16_t        slave;
+       uint16_t        flags;
+#define        IIC_M_WR        0       /* Fake flag for write */
+#define        IIC_M_RD        0x0001  /* read vs write */
+       uint16_t        len;    /* msg legnth */
+       uint8_t *       buf;
+};
 
 struct iiccmd {
        u_char slave;
@@ -44,10 +50,17 @@ struct iiccmd {
        char *buf;
 };
 
+struct iic_rdwr_data {
+       struct iic_msg *msgs;
+       uint32_t nmsgs;
+};
+
 #define I2CSTART       _IOW('i', 1, struct iiccmd)     /* start condition */
 #define I2CSTOP                _IO('i', 2)                     /* stop condition */
 #define I2CRSTCARD     _IOW('i', 3, struct iiccmd)     /* reset the card */
 #define I2CWRITE       _IOW('i', 4, struct iiccmd)     /* send data */
 #define I2CREAD                _IOW('i', 5, struct iiccmd)     /* receive data */
+#define I2CRDWR                _IOW('i', 6, struct iic_rdwr_data)      /* General read/write interface */
+#define I2CRPTSTART    _IOW('i', 7, struct iiccmd)     /* repeated start */
 
 #endif
diff --git a/sys/bus/iicbus/iic/Makefile b/sys/bus/iicbus/iic/Makefile
new file mode 100644 (file)
index 0000000..d3ebbfc
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/iic/Makefile,v 1.1 2002/03/23 15:48:51 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = iic
+SRCS           = device_if.h bus_if.h iicbus_if.h \
+                 iic.c
+
+.include <bsd.kmod.mk>
index 3fbb1e1..f2822a9 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iicbb.c,v 1.6.2.2 2002/04/19 05:52:12 nsouch Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iicbb.c,v 1.21 2009/02/10 22:50:23 imp Exp $
  * $DragonFly: src/sys/bus/iicbus/iicbb.c,v 1.5 2006/12/22 23:12:16 swildner Exp $
  *
  */
@@ -34,7 +34,7 @@
  * Example:
  *
  *     iicbus
- *      /  \ 
+ *      /  \
  *    iicbb pcf
  *     |  \
  *   bti2c lpbb
@@ -42,7 +42,6 @@
  * From Linux I2C generic interface
  * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
  *
- * TODO: port Peter's generic bit-banging code <dufault@hda.com>
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/module.h>
 #include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
 #include <sys/uio.h>
-#include <sys/malloc.h>
 
-#include <machine/clock.h>
-
-#include "iiconf.h"
-#include "iicbus.h"
+#include <bus/iicbus/iiconf.h>
+#include <bus/iicbus/iicbus.h>
 
 #include <bus/smbus/smbconf.h>
 
@@ -100,17 +94,18 @@ static device_method_t iicbb_methods[] = {
        DEVMETHOD(iicbus_write,         iicbb_write),
        DEVMETHOD(iicbus_read,          iicbb_read),
        DEVMETHOD(iicbus_reset,         iicbb_reset),
+       DEVMETHOD(iicbus_transfer,      iicbus_transfer_gen),
 
        { 0, 0 }
 };
 
-static driver_t iicbb_driver = {
+driver_t iicbb_driver = {
        "iicbb",
        iicbb_methods,
        sizeof(struct iicbb_softc),
 };
 
-static devclass_t iicbb_devclass;
+devclass_t iicbb_devclass;
 
 static int
 iicbb_probe(device_t dev)
@@ -157,7 +152,7 @@ iicbb_detach(device_t dev)
 }
 
 static void
-iicbb_child_detached(device_t dev, device_t child)
+iicbb_child_detached( device_t dev, device_t child )
 {
        struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
 
@@ -189,16 +184,53 @@ iicbb_print_child(device_t bus, device_t dev)
        return (retval);
 }
 
-#define I2C_SET(dev,ctrl,data) \
-       IICBB_SETLINES(device_get_parent(dev), ctrl, data)
+#define IIC_DELAY      10
+
+#define I2C_SETSDA(dev,val) do {                       \
+       IICBB_SETSDA(device_get_parent(dev), val);      \
+       DELAY(IIC_DELAY);                               \
+       } while (0)
+
+#define I2C_SETSCL(dev,val) do {                       \
+       iicbb_setscl(dev, val, 100);                    \
+       } while (0)
+
+#define I2C_SET(dev,ctrl,data) do {                    \
+       I2C_SETSCL(dev, ctrl);                          \
+       I2C_SETSDA(dev, data);                          \
+       } while (0)
 
-#define I2C_GET(dev) (IICBB_GETDATALINE(device_get_parent(dev)))
+#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
+
+#define I2C_GETSCL(dev) (IICBB_GETSCL(device_get_parent(dev)))
 
 static int i2c_debug = 0;
-#define I2C_DEBUG(x) if (i2c_debug) (x)
+#define I2C_DEBUG(x)   do {                                    \
+                               if (i2c_debug) (x);             \
+                       } while (0)
+
+#define I2C_LOG(format,args...)        do {                            \
+                                       kprintf(format, args);  \
+                               } while (0)
+
+static void
+iicbb_setscl(device_t dev, int val, int timeout)
+{
+       int k = 0;
+
+       IICBB_SETSCL(device_get_parent(dev), val);
+       DELAY(IIC_DELAY);
+
+       while (val && !I2C_GETSCL(dev) && k++ < timeout) {
+               IICBB_SETSCL(device_get_parent(dev), val);
+               DELAY(IIC_DELAY);
+       }
+
+       return;
+}
 
 static void
-iicbb_one(device_t dev)
+iicbb_one(device_t dev, int timeout)
 {
        I2C_SET(dev,0,1);
        I2C_SET(dev,1,1);
@@ -207,7 +239,7 @@ iicbb_one(device_t dev)
 }
 
 static void
-iicbb_zero(device_t dev)
+iicbb_zero(device_t dev, int timeout)
 {
        I2C_SET(dev,0,0);
        I2C_SET(dev,1,0);
@@ -233,17 +265,17 @@ static int
 iicbb_ack(device_t dev, int timeout)
 {
        int noack;
-       int k = timeout/10;
-    
+       int k = 0;
+
        I2C_SET(dev,0,1);
        I2C_SET(dev,1,1);
-
        do {
-               noack = I2C_GET(dev);
+               noack = I2C_GETSDA(dev);
                if (!noack)
                        break;
-               DELAY(10);              /* XXX wait 10us */
-       } while (k--);
+               DELAY(10);
+               k += 10;
+       } while (k < timeout);
 
        I2C_SET(dev,0,1);
        I2C_DEBUG(kprintf("%c ",noack?'-':'+'));
@@ -252,32 +284,40 @@ iicbb_ack(device_t dev, int timeout)
 }
 
 static void
-iicbb_sendbyte(device_t dev, u_char data)
+iicbb_sendbyte(device_t dev, u_char data, int timeout)
 {
        int i;
-    
-       I2C_SET(dev,0,0);
-       for (i=7; i>=0; i--)
-               (data&(1<<i)) ? iicbb_one(dev) : iicbb_zero(dev);
+
+       for (i=7; i>=0; i--) {
+               if (data&(1<<i)) {
+                       iicbb_one(dev, timeout);
+               } else {
+                       iicbb_zero(dev, timeout);
+               }
+       }
        I2C_DEBUG(kprintf("w%02x",(int)data));
        return;
 }
 
 static u_char
-iicbb_readbyte(device_t dev, int last)
+iicbb_readbyte(device_t dev, int last, int timeout)
 {
        int i;
        unsigned char data=0;
-    
+
        I2C_SET(dev,0,1);
-       for (i=7; i>=0; i--) 
+       for (i=7; i>=0; i--)
        {
                I2C_SET(dev,1,1);
-               if (I2C_GET(dev))
+               if (I2C_GETSDA(dev))
                        data |= (1<<i);
                I2C_SET(dev,0,1);
        }
-       last ? iicbb_one(dev) : iicbb_zero(dev);
+       if (last) {
+               iicbb_one(dev, timeout);
+       } else {
+               iicbb_zero(dev, timeout);
+       }
        I2C_DEBUG(kprintf("r%02x%c ",(int)data,last?'-':'+'));
        return data;
 }
@@ -301,13 +341,12 @@ iicbb_start(device_t dev, u_char slave, int timeout)
 
        I2C_DEBUG(kprintf("<"));
 
-       I2C_SET(dev,0,1);
        I2C_SET(dev,1,1);
        I2C_SET(dev,1,0);
        I2C_SET(dev,0,0);
 
        /* send address */
-       iicbb_sendbyte(dev, slave);
+       iicbb_sendbyte(dev, slave, timeout);
 
        /* check for ack */
        if (iicbb_ack(dev, timeout)) {
@@ -340,7 +379,7 @@ iicbb_write(device_t dev, const char *buf, int len, int *sent, int timeout)
        bytes = 0;
        while (len) {
                /* send byte */
-               iicbb_sendbyte(dev,(u_char)*buf++);
+               iicbb_sendbyte(dev,(u_char)*buf++, timeout);
 
                /* check for ack */
                if (iicbb_ack(dev, timeout)) {
@@ -364,7 +403,7 @@ iicbb_read(device_t dev, char * buf, int len, int *read, int last, int delay)
        bytes = 0;
        while (len) {
                /* XXX should insert delay here */
-               *buf++ = (char)iicbb_readbyte(dev, (len == 1) ? last : 0);
+               *buf++ = (char)iicbb_readbyte(dev, (len == 1) ? last : 0, delay);
 
                bytes ++;
                len --;
@@ -378,3 +417,6 @@ DRIVER_MODULE(iicbb, bti2c, iicbb_driver, iicbb_devclass, 0, 0);
 DRIVER_MODULE(iicbb, cxm_iic, iicbb_driver, iicbb_devclass, 0, 0);
 DRIVER_MODULE(iicbb, lpbb, iicbb_driver, iicbb_devclass, 0, 0);
 DRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0);
+
+MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
+MODULE_VERSION(iicbb, IICBB_MODVER);
diff --git a/sys/bus/iicbus/iicbb/Makefile b/sys/bus/iicbus/iicbb/Makefile
new file mode 100644 (file)
index 0000000..12e14a4
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/iicbb/Makefile,v 1.1 2002/03/23 15:48:53 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = iicbb
+SRCS           = device_if.h bus_if.h iicbus_if.h \
+                 iicbb_if.h iicbb_if.c iicbb.c
+
+.include <bsd.kmod.mk>
index 9d88298..202c20c 100644 (file)
@@ -1,4 +1,4 @@
-#
+#-
 # Copyright (c) 1998 Nicolas Souchu
 # All rights reserved.
 #
@@ -23,7 +23,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/sys/dev/iicbus/iicbb_if.m,v 1.3 1999/08/28 00:41:58 peter Exp $
+# $FreeBSD: src/sys/dev/iicbus/iicbb_if.m,v 1.6 2005/01/06 01:42:47 imp Exp $
 # $DragonFly: src/sys/bus/iicbus/iicbb_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
@@ -41,19 +41,34 @@ METHOD int callback {
 };
 
 #
-# Set I2C bus lines
+# Set I2C bus data line
+#
+METHOD void setsda {
+       device_t dev;
+       int val;
+};
+
+#
+# Set I2C bus clock line
+#
+METHOD void setscl {
+       device_t dev;
+       int val;
+};
+
+#
+# Get I2C bus data line
+#
 #
-METHOD void setlines {
+METHOD int getsda {
        device_t dev;
-       int ctrl;
-       int data;
 };
 
 #
-# Get I2C bus lines
+# Get I2C bus clock line
 #
 #
-METHOD int getdataline {
+METHOD int getscl {
        device_t dev;
 };
 
index b95178a..75dff2e 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iicbus.c,v 1.13 1999/12/03 08:41:02 mdodd Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iicbus.c,v 1.29 2009/02/10 22:50:23 imp Exp $
  * $DragonFly: src/sys/bus/iicbus/iicbus.c,v 1.5 2006/12/22 23:12:16 swildner Exp $
  *
  */
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
-#include <sys/bus.h> 
+#include <sys/bus.h>
 
-#include <machine/clock.h>
-
-#include "iiconf.h"
-#include "iicbus.h"
+#include <bus/iicbus/iiconf.h>
+#include <bus/iicbus/iicbus.h>
 
 #include "iicbus_if.h"
 
 #define DEVTOIICBUS(dev) ((struct iicbus_device*)device_get_ivars(dev))
 
-/*
- * structure used to attach devices to the I2C bus
- */
-struct iicbus_device {
-       const char *iicd_name;          /* device name */
-       int iicd_class;                 /* driver or slave device class */
-       const char *iicd_desc;          /* device descriptor */
-       u_char iicd_addr;               /* address of the device */
-       int iicd_waitack;               /* wait for ack timeout or delay */
-       int iicd_alive;                 /* 1 if device found */
-};
-
-/*
- * Common I2C addresses
- */
-#define I2C_GENERAL_CALL       0x0
-#define PCF_MASTER_ADDRESS     0xaa
-#define FIRST_SLAVE_ADDR       0x2
-
-#define LAST_SLAVE_ADDR                255
-
-#define IICBUS_UNKNOWN_CLASS   0
-#define IICBUS_DEVICE_CLASS    1
-#define IICBUS_DRIVER_CLASS    2
-
-/*
- * list of known devices
- *
- * XXX only one smb driver should exist for each I2C interface
- */
-static struct iicbus_device iicbus_children[] = {
-       { "iicsmb", IICBUS_DRIVER_CLASS, "I2C to SMB bridge" },
-       { "iic", IICBUS_DRIVER_CLASS, "I2C general purpose I/O" },
-#if 0
-       { "ic", IICBUS_DEVICE_CLASS, "network interface", PCF_MASTER_ADDRESS },
-#endif
-       { NULL, 0 }
-};
+devclass_t iicbus_devclass;
 
-static devclass_t iicbus_devclass;
+/* See comments below for why auto-scanning is a bad idea. */
+#define SCAN_IICBUS 0
 
 /*
  * Device methods
  */
 static int iicbus_probe(device_t);
 static int iicbus_attach(device_t);
-static int iicbus_print_child(device_t, device_t);
-static int iicbus_read_ivar(device_t , device_t, int, u_long *);
-static int iicbus_write_ivar(device_t , device_t, int, u_long);
+static int iicbus_detach(device_t);
+static int iicbus_add_child(device_t dev, int order, const char *name, int unit);
 
 static device_method_t iicbus_methods[] = {
         /* device interface */
         DEVMETHOD(device_probe,         iicbus_probe),
         DEVMETHOD(device_attach,        iicbus_attach),
-        DEVMETHOD(device_detach,        bus_generic_detach),
-        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
+        DEVMETHOD(device_detach,        iicbus_detach),
 
         /* bus interface */
-        DEVMETHOD(bus_print_child,      iicbus_print_child),
-        DEVMETHOD(bus_read_ivar,        iicbus_read_ivar),
-        DEVMETHOD(bus_write_ivar,       iicbus_write_ivar),
+        DEVMETHOD(bus_add_child,       iicbus_add_child),
+       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
+        DEVMETHOD(bus_print_child,      bus_generic_print_child),
+
+       DEVMETHOD(iicbus_transfer,      iicbus_transfer_gen),
 
         { 0, 0 }
 };
 
-static driver_t iicbus_driver = {
+driver_t iicbus_driver = {
         "iicbus",
         iicbus_methods,
         sizeof(struct iicbus_softc),
@@ -121,13 +83,15 @@ static driver_t iicbus_driver = {
 static int
 iicbus_probe(device_t dev)
 {
+
        device_set_desc(dev, "Philips I2C bus");
 
-       return (0);
+       /* Allow other subclasses to override this driver. */
+       return (BUS_PROBE_GENERIC);
 }
 
-#if 0
-static int 
+#if SCAN_IICBUS
+static int
 iic_probe_device(device_t dev, u_char addr)
 {
        int count;
@@ -156,8 +120,9 @@ iic_probe_device(device_t dev, u_char addr)
 static int
 iicbus_attach(device_t dev)
 {
-       struct iicbus_device *iicdev;
-       device_t child;
+#if SCAN_IICBUS
+       unsigned char addr;
+#endif
 
        iicbus_reset(dev, IIC_FASTEST, 0, NULL);
 
@@ -166,11 +131,11 @@ iicbus_attach(device_t dev)
         * accesses like stop after start to fast, reads for less than
         * x bytes...
         */
-#if 0
+#if SCAN_IICBUS
        kprintf("Probing for devices on iicbus%d:", device_get_unit(dev));
 
        /* probe any devices */
-       for (addr = FIRST_SLAVE_ADDR; addr <= LAST_SLAVE_ADDR; addr++) {
+       for (addr = 16; addr < 240; addr++) {
                if (iic_probe_device(dev, (u_char)addr)) {
                        kprintf(" <%x>", addr);
                }
@@ -178,113 +143,55 @@ iicbus_attach(device_t dev)
        kprintf("\n");
 #endif
 
-       /* attach known devices */
-       for (iicdev = iicbus_children; iicdev->iicd_name; iicdev++) {
-               switch (iicdev->iicd_class) {
-               case IICBUS_DEVICE_CLASS:
-                       /* check if the devclass exists */
-                       if (devclass_find(iicdev->iicd_name))
-                               iicdev->iicd_alive = 1;
-                       else if (bootverbose)
-                               kprintf("iicbus: %s devclass not found\n",
-                                       iicdev->iicd_name);
-                       break;
-
-               case IICBUS_DRIVER_CLASS:
-                       /* check if the devclass exists */
-                       if (devclass_find(iicdev->iicd_name))
-                               iicdev->iicd_alive = 1;
-                       else if (bootverbose)
-                               kprintf("iicbus: %s devclass not found\n",
-                                       iicdev->iicd_name);
-                       break;
-
-               default:
-                       panic("%s: unknown class!", __func__);
-               }
-
-               if (iicdev->iicd_alive) {
-                       child = device_add_child(dev, iicdev->iicd_name, -1);
-                       device_set_ivars(child, iicdev);
-                       device_set_desc(child, iicdev->iicd_desc);
-               }
-       }
+       device_add_child(dev, "ic", -1);
+       device_add_child(dev, "iic", -1);
+       device_add_child(dev, "iicsmb", -1);
+#if 0
+       /* attach any known device */
+       device_add_child(dev, "iic", -1);
+#endif
        bus_generic_attach(dev);
          
         return (0);
 }
 
-int
-iicbus_generic_intr(device_t dev, int event, char *buf)
+static int
+iicbus_detach(device_t dev)
 {
+       iicbus_reset(dev, IIC_FASTEST, 0, NULL);
+       bus_generic_detach(dev);
        return (0);
 }
 
-int
-iicbus_null_callback(device_t dev, int index, caddr_t data)
+static int
+iicbus_add_child(device_t dev, int order, const char *name, int unit)
 {
+
+       device_add_child_ordered(dev, order, name, unit);
+       bus_generic_attach(dev);
        return (0);
 }
 
 int
-iicbus_null_repeated_start(device_t dev, u_char addr)
-{
-       return (IIC_ENOTSUPP);
-}
-
-static int
-iicbus_print_child(device_t bus, device_t dev)
+iicbus_generic_intr(device_t dev, int event, char *buf)
 {
-       struct iicbus_device* iicdev = DEVTOIICBUS(dev);
-       int retval = 0;
-
-       retval += bus_print_child_header(bus, dev);
-
-       switch (iicdev->iicd_class) {   
-       case IICBUS_DEVICE_CLASS:
-               retval += kprintf(" on %s addr 0x%x\n",
-                                device_get_nameunit(bus), iicdev->iicd_addr);
-               break;
-
-       case IICBUS_DRIVER_CLASS:
-               retval += bus_print_child_footer(bus, dev);
-               break;
 
-       default:
-               panic("%s: unknown class!", __func__);
-       }
-
-       return (retval);
+       return (0);
 }
 
-static int
-iicbus_read_ivar(device_t bus, device_t dev, int index, u_long* result)
+int
+iicbus_null_callback(device_t dev, int index, caddr_t data)
 {
-       struct iicbus_device* iicdev = DEVTOIICBUS(dev);
-
-       switch (index) {
-       case IICBUS_IVAR_ADDR:
-               *result = (u_long)iicdev->iicd_addr;
-               break;
-
-       default:
-               return (ENOENT);
-       }
 
        return (0);
 }
 
-static int
-iicbus_write_ivar(device_t bus, device_t dev, int index, u_long val)
+int
+iicbus_null_repeated_start(device_t dev, u_char addr)
 {
-       switch (index) {
-       default:
-               return (ENOENT);
-       }
 
-       return (0);
+       return (IIC_ENOTSUPP);
 }
 
-DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
 DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
-DRIVER_MODULE(iicbus, bti2c, iicbus_driver, iicbus_devclass, 0, 0);
+MODULE_VERSION(iicbus, IICBUS_MODVER);
index 5fb7587..a886779 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iicbus.h,v 1.4 1999/08/28 00:41:58 peter Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iicbus.h,v 1.8 2008/08/04 21:03:06 jhb Exp $
  * $DragonFly: src/sys/bus/iicbus/iicbus.h,v 1.3 2006/09/30 20:03:44 swildner Exp $
  *
  */
 #ifndef __IICBUS_H
 #define __IICBUS_H
 
-struct iicbus_softc {
+#define IICBUS_IVAR(d) (struct iicbus_ivar *) device_get_ivars(d)
+#define IICBUS_SOFTC(d) (struct iicbus_softc *) device_get_softc(d)
 
+struct iicbus_softc
+{
+       device_t dev;           /* Myself */
        device_t owner;         /* iicbus owner device structure */
        u_char started;         /* address of the 'started' slave
                                 * 0 if no start condition succeeded */
 };
 
+struct iicbus_ivar
+{
+       uint32_t        addr;
+};
+
+enum {
+       IICBUS_IVAR_ADDR                /* Address or base address */
+};
+
+#define IICBUS_ACCESSOR(A, B, T)                                       \
+       __BUS_ACCESSOR(iicbus, A, IICBUS, B, T)
+
+IICBUS_ACCESSOR(addr,          ADDR,           uint32_t)
+
+#define        IICBUS_LOCK(sc)
+#define        IICBUS_UNLOCK(sc)
+#define        IICBUS_ASSERT_LOCKED(sc)
+
 extern int iicbus_generic_intr(device_t dev, int event, char *buf);
 
+extern driver_t iicbus_driver;
+extern devclass_t iicbus_devclass;
+
 #endif
diff --git a/sys/bus/iicbus/iicbus/Makefile b/sys/bus/iicbus/iicbus/Makefile
new file mode 100644 (file)
index 0000000..2d7f8b1
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/iicbus/Makefile,v 1.1 2002/03/23 15:48:55 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = iicbus
+SRCS           = device_if.h bus_if.h iicbus_if.h iicbus_if.c \
+                 iiconf.h iiconf.c iicbus.h iicbus.c
+
+.include <bsd.kmod.mk>
index 3b08488..b62b310 100644 (file)
@@ -1,4 +1,4 @@
-#
+#-
 # Copyright (c) 1998 Nicolas Souchu
 # All rights reserved.
 #
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/sys/dev/iicbus/iicbus_if.m,v 1.4 1999/08/28 00:41:59 peter Exp $
+# $FreeBSD: src/sys/dev/iicbus/iicbus_if.m,v 1.8 2006/12/05 06:19:36 imp Exp $
 # $DragonFly: src/sys/bus/iicbus/iicbus_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
 #include <sys/bus.h>
+#include <bus/iicbus/iic.h>
 
 INTERFACE iicbus;
 
@@ -106,3 +107,12 @@ METHOD int reset {
        u_char addr;
        u_char *oldaddr;
 };
+
+#
+# Generalized Read/Write interface
+#
+METHOD int transfer {
+       device_t dev;
+       struct iic_msg *msgs;
+       uint32_t nmsgs;
+};
index 534e2b5..12275ba 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iiconf.c,v 1.10 1999/12/03 08:41:02 mdodd Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iiconf.c,v 1.19 2008/08/23 07:38:00 imp Exp $
  * $DragonFly: src/sys/bus/iicbus/iiconf.c,v 1.5 2005/06/02 20:40:36 dillon Exp $
  *
  */
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/thread2.h>
 
-#include "iiconf.h"
-#include "iicbus.h"
+#include <bus/iicbus/iiconf.h>
+#include <bus/iicbus/iicbus.h>
 #include "iicbus_if.h"
 
 /*
@@ -54,33 +53,17 @@ iicbus_intr(device_t bus, int event, char *buf)
        return;
 }
 
-/*
- * iicbus_alloc_bus()
- *
- * Allocate a new bus connected to the given parent device
- */
-device_t
-iicbus_alloc_bus(device_t parent)
-{
-       device_t child;
-
-       /* add the bus to the parent */
-       child = device_add_child(parent, "iicbus", -1);
-
-       return (child);
-}
-
 static int
 iicbus_poll(struct iicbus_softc *sc, int how)
 {
        int error;
 
        switch (how) {
-       case (IIC_WAIT | IIC_INTR):
+       case IIC_WAIT | IIC_INTR:
                error = tsleep(sc, PCATCH, "iicreq", 0);
                break;
 
-       case (IIC_WAIT | IIC_NOINTR):
+       case IIC_WAIT | IIC_NOINTR:
                error = tsleep(sc, 0, "iicreq", 0);
                break;
 
@@ -155,7 +138,7 @@ iicbus_release_bus(device_t bus, device_t dev)
                crit_exit();
                return (EACCES);
        }
-       sc->owner = 0;
+       sc->owner = NULL;
        crit_exit();
 
        /* wakeup waiting processes */
@@ -349,18 +332,49 @@ iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
 }
 
 /*
- * iicbus_get_addr()
+ * iicbus_transfer()
  *
- * Get the I2C 7 bits address of the device
+ * Do an aribtrary number of transfers on the iicbus.  We pass these
+ * raw requests to the bridge driver.  If the bridge driver supports
+ * them directly, then it manages all the details.  If not, it can use
+ * the helper function iicbus_transfer_gen() which will do the
+ * transfers at a low level.
+ *
+ * Pointers passed in as part of iic_msg must be kernel pointers.
+ * Callers that have user addresses to manage must do so on their own.
  */
-u_char
-iicbus_get_addr(device_t dev)
+int
+iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
 {
-       uintptr_t addr;
-       device_t parent = device_get_parent(dev);
+       return (IICBUS_TRANSFER(device_get_parent(bus), msgs, nmsgs));
+}
 
-       BUS_READ_IVAR(parent, dev, IICBUS_IVAR_ADDR, &addr);
+/*
+ * Generic version of iicbus_transfer that calls the appropriate
+ * routines to accomplish this.  See note above about acceptable
+ * buffer addresses.
+ */
+int
+iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+       int i, error, lenread, lenwrote, nkid;
+       device_t *children, bus;
 
-       return ((u_char)addr);
+       if ((error = device_get_children(dev, &children, &nkid)) != 0)
+               return (error);
+       if (nkid != 1) {
+               kfree(children, M_TEMP);
+               return (EIO);
+       }
+       bus = children[0];
+       kfree(children, M_TEMP);
+       for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
+               if (msgs[i].flags & IIC_M_RD)
+                       error = iicbus_block_read(bus, msgs[i].slave,
+                           msgs[i].buf, msgs[i].len, &lenread);
+               else
+                       error = iicbus_block_write(bus, msgs[i].slave,
+                           msgs[i].buf, msgs[i].len, &lenwrote);
+       }
+       return (error);
 }
-
index 5d00e90..7816b6d 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iiconf.h,v 1.7 2002/03/23 15:47:17 nsouch Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iiconf.h,v 1.11 2006/12/05 06:19:36 imp Exp $
  * $DragonFly: src/sys/bus/iicbus/iiconf.h,v 1.4 2003/11/14 21:46:17 daver Exp $
  */
 #ifndef __IICONF_H
 #define __IICONF_H
 
 #include <sys/queue.h>
+#include <bus/iicbus/iic.h>
 
-#define n(flags) (~(flags) & (flags))
+
+#define IICPRI (PZERO+8)               /* XXX sleep/wakeup queue priority */
 
 #define LSB 0x1
 
 #define IIC_ENOTSUPP   0x8     /* request not supported */
 #define IIC_ENOADDR    0x9     /* no address assigned to the interface */
 
-/*
- * ivars codes
- */
-#define IICBUS_IVAR_ADDR       0x1     /* I2C address of the device */
-
 extern int iicbus_request_bus(device_t, device_t, int);
 extern int iicbus_release_bus(device_t, device_t);
-extern device_t iicbus_alloc_bus(device_t);
 
 extern void iicbus_intr(device_t, int, char *);
 
@@ -124,16 +120,21 @@ extern int iicbus_read_byte(device_t, char *, int);
 extern int iicbus_block_write(device_t, u_char, char *, int, int *);
 extern int iicbus_block_read(device_t, u_char, char *, int, int *);
 
-extern u_char iicbus_get_addr(device_t);
+/* vectors of iic operations to pass to bridge */
+int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs);
+int iicbus_transfer_gen(device_t bus, struct iic_msg *msgs, uint32_t nmsgs);
+
+#define IICBUS_MODVER  1
+#define IICBUS_MINVER  1
+#define IICBUS_MAXVER  1
+#define IICBUS_PREFVER IICBUS_MODVER
 
-#define IICBUS_MODVER  1
-#define IICBUS_MINVER  1
-#define IICBUS_MAXVER  1
-#define IICBUS_PREFVER IICBUS_MODVER
+extern driver_t iicbb_driver;
+extern devclass_t iicbb_devclass;
 
-#define IICBB_MODVER   1
-#define IICBB_MINVER   1
-#define IICBB_MAXVER   1
-#define IICBB_PREFVER  IICBB_MODVER
+#define IICBB_MODVER   1
+#define IICBB_MINVER   1
+#define IICBB_MAXVER   1
+#define IICBB_PREFVER  IICBB_MODVER
 
 #endif
index 8cc9e6a..c2ec179 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/iicbus/iicsmb.c,v 1.5.2.2 2000/08/09 00:59:27 peter Exp $
+ * $FreeBSD: src/sys/dev/iicbus/iicsmb.c,v 1.18 2009/02/10 22:50:23 imp Exp $
  * $DragonFly: src/sys/bus/iicbus/iicsmb.c,v 1.5 2006/12/22 23:12:16 swildner Exp $
  *
  */
  */
 
 #include <sys/param.h>
+#include <sys/bus.h>
 #include <sys/kernel.h>
-#include <sys/systm.h>
 #include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
+#include <sys/systm.h>
 #include <sys/uio.h>
-#include <sys/malloc.h>
 
-#include <machine/clock.h>
-
-#include "iiconf.h"
-#include "iicbus.h"
+#include <bus/iicbus/iiconf.h>
+#include <bus/iicbus/iicbus.h>
 
 #include <bus/smbus/smbconf.h>
 
@@ -84,9 +79,11 @@ struct iicsmb_softc {
 
 static int iicsmb_probe(device_t);
 static int iicsmb_attach(device_t);
+static int iicsmb_detach(device_t);
+static void iicsmb_identify(driver_t *driver, device_t parent);
 
-static void iicsmb_intr(device_t dev, int event, char *buf);
-static int iicsmb_callback(device_t dev, int index, caddr_t data);
+static int iicsmb_intr(device_t dev, int event, char *buf);
+static int iicsmb_callback(device_t dev, int index, void *data);
 static int iicsmb_quick(device_t dev, u_char slave, int how);
 static int iicsmb_sendb(device_t dev, u_char slave, char byte);
 static int iicsmb_recvb(device_t dev, u_char slave, char *byte);
@@ -96,17 +93,19 @@ static int iicsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
 static int iicsmb_readw(device_t dev, u_char slave, char cmd, short *word);
 static int iicsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata);
 static int iicsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
-static int iicsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf);
+static int iicsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf);
 
 static devclass_t iicsmb_devclass;
 
 static device_method_t iicsmb_methods[] = {
        /* device interface */
+       DEVMETHOD(device_identify,      iicsmb_identify),
        DEVMETHOD(device_probe,         iicsmb_probe),
        DEVMETHOD(device_attach,        iicsmb_attach),
-       DEVMETHOD(device_detach,        bus_generic_detach),
+       DEVMETHOD(device_detach,        iicsmb_detach),
 
        /* bus interface */
+       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
        DEVMETHOD(bus_print_child,      bus_generic_print_child),
 
        /* iicbus interface */
@@ -124,7 +123,7 @@ static device_method_t iicsmb_methods[] = {
        DEVMETHOD(smbus_pcall,          iicsmb_pcall),
        DEVMETHOD(smbus_bwrite,         iicsmb_bwrite),
        DEVMETHOD(smbus_bread,          iicsmb_bread),
-       
+
        { 0, 0 }
 };
 
@@ -134,26 +133,45 @@ static driver_t iicsmb_driver = {
        sizeof(struct iicsmb_softc),
 };
 
+#define IICBUS_TIMEOUT 100     /* us */
+
+static void
+iicsmb_identify(driver_t *driver, device_t parent)
+{
+
+       if (device_find_child(parent, "iicsmb", -1) == NULL)
+               BUS_ADD_CHILD(parent, parent, 0, "iicsmb", -1);
+}
+
 static int
 iicsmb_probe(device_t dev)
 {
+       device_set_desc(dev, "SMBus over I2C bridge");
+       return (0);
+}
+
+static int
+iicsmb_attach(device_t dev)
+{
        struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
 
-       sc->smbus = smbus_alloc_bus(dev);
+       sc->smbus = device_add_child(dev, "smbus", -1);
+
+       /* probe and attach the smbus */
+       bus_generic_attach(dev);
 
-       if (!sc->smbus)
-               return (EINVAL);        /* XXX don't know what to return else */
-               
        return (0);
 }
 
 static int
-iicsmb_attach(device_t dev)
+iicsmb_detach(device_t dev)
 {
        struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
 
-       /* probe and attach the smbus */
-       device_probe_and_attach(sc->smbus);
+       bus_generic_detach(dev);
+       if (sc->smbus) {
+               device_delete_child(dev, sc->smbus);
+       }
 
        return (0);
 }
@@ -163,7 +181,7 @@ iicsmb_attach(device_t dev)
  *
  * iicbus interrupt handler
  */
-static void
+static int
 iicsmb_intr(device_t dev, int event, char *buf)
 {
        struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
@@ -227,11 +245,11 @@ end:
                panic("%s: unknown event (%d)!", __func__, event);
        }
 
-       return;
+       return (0);
 }
 
 static int
-iicsmb_callback(device_t dev, int index, caddr_t data)
+iicsmb_callback(device_t dev, int index, void *data)
 {
        device_t parent = device_get_parent(dev);
        int error = 0;
@@ -264,11 +282,11 @@ iicsmb_quick(device_t dev, u_char slave, int how)
 
        switch (how) {
        case SMB_QWRITE:
-               error = iicbus_start(parent, slave & ~LSB, 0);
+               error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
                break;
 
        case SMB_QREAD:
-               error = iicbus_start(parent, slave | LSB, 0);
+               error = iicbus_start(parent, slave | LSB, IICBUS_TIMEOUT);
                break;
 
        default:
@@ -288,10 +306,10 @@ iicsmb_sendb(device_t dev, u_char slave, char byte)
        device_t parent = device_get_parent(dev);
        int error, sent;
 
-       error = iicbus_start(parent, slave & ~LSB, 0);
+       error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
 
        if (!error) {
-               error = iicbus_write(parent, &byte, 1, &sent, 0);
+               error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
 
                iicbus_stop(parent);
        }
@@ -308,7 +326,7 @@ iicsmb_recvb(device_t dev, u_char slave, char *byte)
        error = iicbus_start(parent, slave | LSB, 0);
 
        if (!error) {
-               error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, 0);
+               error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT);
 
                iicbus_stop(parent);
        }
@@ -325,8 +343,8 @@ iicsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
        error = iicbus_start(parent, slave & ~LSB, 0);
 
        if (!error) {
-               if (!(error = iicbus_write(parent, &cmd, 1, &sent, 0)))
-                       error = iicbus_write(parent, &byte, 1, &sent, 0);
+               if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
+                       error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
 
                iicbus_stop(parent);
        }
@@ -346,9 +364,9 @@ iicsmb_writew(device_t dev, u_char slave, char cmd, short word)
        error = iicbus_start(parent, slave & ~LSB, 0);
 
        if (!error) {
-               if (!(error = iicbus_write(parent, &cmd, 1, &sent, 0)))
-                 if (!(error = iicbus_write(parent, &low, 1, &sent, 0)))
-                   error = iicbus_write(parent, &high, 1, &sent, 0);
+               if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
+                 if (!(error = iicbus_write(parent, &low, 1, &sent, IICBUS_TIMEOUT)))
+                   error = iicbus_write(parent, &high, 1, &sent, IICBUS_TIMEOUT);
 
                iicbus_stop(parent);
        }
@@ -362,16 +380,16 @@ iicsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
        device_t parent = device_get_parent(dev);
        int error, sent, read;
 
-       if ((error = iicbus_start(parent, slave & ~LSB, 0)))
+       if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
                return (error);
 
-       if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
+       if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
+       if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, 0)))
+       if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
                goto error;
 
 error:
@@ -389,16 +407,16 @@ iicsmb_readw(device_t dev, u_char slave, char cmd, short *word)
        int error, sent, read;
        char buf[2];
 
-       if ((error = iicbus_start(parent, slave & ~LSB, 0)))
+       if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
                return (error);
 
-       if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
+       if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
+       if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, 0)))
+       if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
                goto error;
 
        /* first, receive low, then high byte */
@@ -416,23 +434,23 @@ iicsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
        int error, sent, read;
        char buf[2];
 
-       if ((error = iicbus_start(parent, slave & ~LSB, 0)))
+       if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
                return (error);
 
-       if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
+       if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
                goto error;
 
        /* first, send low, then high byte */
        buf[0] = (char)(sdata & 0xff);
        buf[1] = (char)((sdata & 0xff00) >> 8);
 
-       if ((error = iicbus_write(parent, buf, 2, &sent, 0)))
+       if ((error = iicbus_write(parent, buf, 2, &sent, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
+       if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, 0)))
+       if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
                goto error;
 
        /* first, receive low, then high byte */
@@ -449,13 +467,13 @@ iicsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
        device_t parent = device_get_parent(dev);
        int error, sent;
 
-       if ((error = iicbus_start(parent, slave & ~LSB, 0)))
+       if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
+       if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_write(parent, buf, (int)count, &sent, 0)))
+       if ((error = iicbus_write(parent, buf, (int)count, &sent, IICBUS_TIMEOUT)))
                goto error;
 
        if ((error = iicbus_stop(parent)))
@@ -466,23 +484,24 @@ error:
 }
 
 static int
-iicsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+iicsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
 {
        device_t parent = device_get_parent(dev);
        int error, sent, read;
 
-       if ((error = iicbus_start(parent, slave & ~LSB, 0)))
+       if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
                return (error);
 
-       if ((error = iicbus_write(parent, &cmd, 1, &sent, 0)))
+       if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_repeated_start(parent, slave | LSB, 0)))
+       if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
                goto error;
 
-       if ((error = iicbus_read(parent, buf, (int)count, &read,
-                                                       IIC_LAST_READ, 0)))
+       if ((error = iicbus_read(parent, buf, (int)*count, &read,
+                                               IIC_LAST_READ, IICBUS_TIMEOUT)))
                goto error;
+       *count = read;
 
 error:
        iicbus_stop(parent);
@@ -490,3 +509,7 @@ error:
 }
 
 DRIVER_MODULE(iicsmb, iicbus, iicsmb_driver, iicsmb_devclass, 0, 0);
+DRIVER_MODULE(smbus, iicsmb, smbus_driver, smbus_devclass, 0, 0);
+MODULE_DEPEND(iicsmb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
+MODULE_DEPEND(iicsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(iicsmb, 1);
diff --git a/sys/bus/iicbus/iicsmb/Makefile b/sys/bus/iicbus/iicsmb/Makefile
new file mode 100644 (file)
index 0000000..14bcebb
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/iicsmb/Makefile,v 1.1 2002/03/23 15:48:56 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = iicsmb
+SRCS           = device_if.h bus_if.h iicbus_if.h \
+                 smbus_if.h iicsmb.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/bus/iicbus/pcf/Makefile b/sys/bus/iicbus/pcf/Makefile
new file mode 100644 (file)
index 0000000..cf394c4
--- /dev/null
@@ -0,0 +1,20 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/pcf/Makefile,v 1.4 2005/11/22 17:32:51 marius Exp $
+
+.PATH: ${.CURDIR}/..
+
+KMOD=  pcf
+SRCS=  ${envctrl} pcf.c ${pcf_ebus} ${pcf_isa}
+SRCS+= bus_if.h device_if.h iicbus_if.h ${isa_if} ${ofw_bus_if}
+
+.if ${MACHINE_ARCH} == "i386"
+isa_if=                isa_if.h
+pcf_isa=       pcf.c
+.endif
+
+.if ${MACHINE_ARCH} == "sparc64"
+envctrl=       envctrl.c
+ofw_bus_if=    ofw_bus_if.h
+pcf_ebus=      pcf_ebus.c
+.endif
+
+.include <bsd.kmod.mk>
similarity index 95%
rename from sys/bus/iicbus/i386/pcf.c
rename to sys/bus/iicbus/pcf/pcf.c
index bb75dd5..ca09aad 100644 (file)
@@ -23,8 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/i386/isa/pcf.c,v 1.14 2000/01/14 00:18:05 nsouch Exp $
- * $DragonFly: src/sys/bus/iicbus/i386/pcf.c,v 1.11 2008/08/02 01:14:38 dillon Exp $
+ * $FreeBSD: src/sys/dev/pcf/pcf.c,v 1.21 2003/06/20 07:22:54 jmg Exp $
  *
  */
 #include <sys/param.h>
@@ -32,9 +31,7 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
-#include <sys/malloc.h>
 
-#include <machine/clock.h>
 #include <sys/rman.h>
 
 #include <bus/isa/isareg.h>
@@ -86,7 +83,7 @@ struct pcf_softc {
 
        device_t iicbus;                /* the corresponding iicbus */
 
-       int rid_irq, rid_ioport;
+       int rid_irq, rid_ioport;
        struct resource *res_irq, *res_ioport;
        void *intr_cookie;
 };
@@ -139,6 +136,7 @@ pcf_probe(device_t pcfdev)
 {
        struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
        device_t parent = device_get_parent(pcfdev);
+       uintptr_t base;
 
        device_set_desc(pcfdev, "PCF8584 I2C bus controller");
 
@@ -149,13 +147,14 @@ pcf_probe(device_t pcfdev)
 
        /* IO port is mandatory */
        pcf->res_ioport = bus_alloc_resource(pcfdev, SYS_RES_IOPORT,
-                                            &pcf->rid_ioport, 0ul, ~0ul, 
+                                            &pcf->rid_ioport, 0ul, ~0ul,
                                             IO_PCFSIZE, RF_ACTIVE);
        if (pcf->res_ioport == 0) {
                device_printf(pcfdev, "cannot reserve I/O port range\n");
                goto error;
        }
-       BUS_READ_IVAR(parent, pcfdev, ISA_IVAR_PORT, &pcf->pcf_base);
+       BUS_READ_IVAR(parent, pcfdev, ISA_IVAR_PORT, &base);
+       pcf->pcf_base = base;
 
        pcf->pcf_flags = device_get_flags(pcfdev);
 
@@ -191,17 +190,17 @@ pcf_attach(device_t pcfdev)
 
        if (pcf->res_irq) {
                /* default to the tty mask for registration */  /* XXX */
-               error = BUS_SETUP_INTR(parent, pcfdev, pcf->res_irq, 
+               error = BUS_SETUP_INTR(parent, pcfdev, pcf->res_irq,
                                        0, pcfintr, pcfdev,
                                        &pcf->intr_cookie, NULL);
                if (error)
                        return (error);
        }
 
-       pcf->iicbus = iicbus_alloc_bus(pcfdev);
+       pcf->iicbus = device_add_child(pcfdev, "iicbus", -1);
 
        /* probe and attach the iicbus */
-       device_probe_and_attach(pcf->iicbus);
+       bus_generic_attach(pcfdev);
 
        return (0);
 }
@@ -292,7 +291,7 @@ pcf_stop(device_t pcfdev)
 
        /*
         * Send STOP condition iff the START condition was previously sent.
-        * STOP is sent only once even if a iicbus_stop() is called after
+        * STOP is sent only once even if an iicbus_stop() is called after
         * an iicbus_read()... see pcf_read(): the pcf needs to send the stop
         * before the last char is read.
         */
@@ -403,7 +402,7 @@ pcfintr(void *arg)
                device_printf(pcfdev, "spurious interrupt, status=0x%x\n", status & 0xff);
 
                goto error;
-       }       
+       }
 
        if (status & LAB)
                device_printf(pcfdev, "bus arbitration lost!\n");
@@ -435,9 +434,9 @@ pcfintr(void *arg)
                        /* get data from upper code */
                        iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
 
-                       PCF_SET_S0(pcf, data);  
-                       break;  
-               
+                       PCF_SET_S0(pcf, data);
+                       break;
+
                case SLAVE_RECEIVER:
                        if (status & AAS) {
                                addr = PCF_GET_S0(pcf);
@@ -508,7 +507,7 @@ pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr)
                pcf->pcf_addr = PCF_DEFAULT_ADDR;
        else
                pcf->pcf_addr = addr;
-       
+
        PCF_SET_S1(pcf, PIN);                           /* initialize S1 */
 
        /* own address S'O<>0 */
diff --git a/sys/bus/ppbus/Makefile b/sys/bus/ppbus/Makefile
new file mode 100644 (file)
index 0000000..b1ba345
--- /dev/null
@@ -0,0 +1,21 @@
+# $FreeBSD: src/sys/modules/ppbus/Makefile,v 1.5 2003/11/19 05:08:26 imp Exp $
+
+.PATH: ${.CURDIR}/..
+KMOD=  ppbus
+SRCS=  bus_if.h device_if.h ppbus_if.h ppbus_if.c \
+       opt_ppb_1284.h \
+       ppb_1284.c ppb_base.c ppb_msq.c ppbconf.c
+
+EXPORT_SYMS=   ppb_attach_device       \
+               ppb_request_bus         \
+               ppb_release_bus         \
+               ppb_get_status          \
+               ppb_poll_bus            \
+               ppb_reset_epp_timeout   \
+               ppb_ecp_sync            \
+               ppb_get_epp_protocol    \
+               ppb_set_mode            \
+               ppb_get_mode            \
+               ppb_write
+
+.include <bsd.kmod.mk>
diff --git a/sys/bus/smbus/Makefile b/sys/bus/smbus/Makefile
new file mode 100644 (file)
index 0000000..d46c7ac
--- /dev/null
@@ -0,0 +1,6 @@
+# $FreeBSD: src/sys/modules/i2c/Makefile,v 1.1 2002/03/23 15:48:36 nsouch Exp $
+
+SUBDIR =
+SUBDIR += smbus smb
+
+.include <bsd.subdir.mk>
index fb25491..97e0edc 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/smbus/smb.c,v 1.20 1999/11/18 05:44:56 peter Exp $
+ * $FreeBSD: src/sys/dev/smbus/smb.c,v 1.34.8.2 2006/09/22 19:19:16 jhb Exp $
  * $DragonFly: src/sys/bus/smbus/smb.c,v 1.9 2006/09/10 01:26:33 dillon Exp $
  *
  */
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
+#include <sys/device.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/buf.h>
 #include <sys/uio.h>
-#include <sys/malloc.h>
 #include <sys/fcntl.h>
 
-#include <machine/clock.h>
-
 #include "smbconf.h"
 #include "smbus.h"
-#include <machine/smb.h>
+#include "smb.h"
 
 #include "smbus_if.h"
 
 
 struct smb_softc {
 
-       int sc_addr;                    /* address on smbus */
        int sc_count;                   /* >0 if device opened */
-
-       char *sc_cp;                    /* output buffer pointer */
-
-       char sc_buffer[BUFSIZE];        /* output buffer */
-       char sc_inbuf[BUFSIZE];         /* input buffer */
+       cdev_t sc_devnode;
 };
 
 #define IIC_SOFTC(unit) \
@@ -65,15 +58,19 @@ struct smb_softc {
 #define IIC_DEVICE(unit) \
        (devclass_get_device(smb_devclass, (unit)))
 
+static void smb_identify(driver_t *driver, device_t parent);
 static int smb_probe(device_t);
 static int smb_attach(device_t);
+static int smb_detach(device_t);
 
 static devclass_t smb_devclass;
 
 static device_method_t smb_methods[] = {
        /* device interface */
+       DEVMETHOD(device_identify,      smb_identify),
        DEVMETHOD(device_probe,         smb_probe),
        DEVMETHOD(device_attach,        smb_attach),
+       DEVMETHOD(device_detach,        smb_detach),
 
        /* smbus interface */
        DEVMETHOD(smbus_intr,           smbus_generic_intr),
@@ -89,8 +86,6 @@ static driver_t smb_driver = {
 
 static d_open_t        smbopen;
 static d_close_t       smbclose;
-static d_write_t       smbwrite;
-static d_read_t        smbread;
 static d_ioctl_t       smbioctl;
 
 #define CDEV_MAJOR 106
@@ -98,35 +93,49 @@ static struct dev_ops smb_ops = {
        { "smb", CDEV_MAJOR, 0 },
        .d_open =       smbopen,
        .d_close =      smbclose,
-       .d_read =       smbread,
-       .d_write =      smbwrite,
        .d_ioctl =      smbioctl,
 };
 
-/*
- * smbprobe()
- */
+static void
+smb_identify(driver_t *driver, device_t parent)
+{
+       if (device_find_child(parent, "smb", -1) == NULL)
+               BUS_ADD_CHILD(parent, parent, 0, "smb", -1);
+}
+
 static int
 smb_probe(device_t dev)
 {
+       device_set_desc(dev, "SMBus generic I/O");
+
+       return (0);
+}
+
+static int
+smb_attach(device_t dev)
+{
        struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev);
 
-       sc->sc_addr = smbus_get_addr(dev);
+       if (!sc)
+               return (ENOMEM);
+
+       bzero(sc, sizeof(struct smb_softc *));
 
-       /* XXX detect chip with start/stop conditions */
+       sc->sc_devnode = make_dev(&smb_ops, device_get_unit(dev),
+                       UID_ROOT, GID_WHEEL,
+                       0600, "smb%d", device_get_unit(dev));
 
        return (0);
 }
-       
-/*
- * smbattach()
- */
+
 static int
-smb_attach(device_t dev)
+smb_detach(device_t dev)
 {
-       make_dev(&smb_ops, device_get_unit(dev),
-                UID_ROOT, GID_WHEEL,
-                0600, "smb%d", device_get_unit(dev));
+       struct smb_softc *sc = (struct smb_softc *)device_get_softc(dev);
+
+       if (sc->sc_devnode)
+               dev_ops_remove_minor(&smb_ops, device_get_unit(dev));
+
        return (0);
 }
 
@@ -136,10 +145,10 @@ smbopen (struct dev_open_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        struct smb_softc *sc = IIC_SOFTC(minor(dev));
 
-       if (!sc)
-               return (EINVAL);
+       if (sc == NULL)
+               return (ENXIO);
 
-       if (sc->sc_count)
+       if (sc->sc_count != 0)
                return (EBUSY);
 
        sc->sc_count++;
@@ -153,17 +162,19 @@ smbclose(struct dev_close_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        struct smb_softc *sc = IIC_SOFTC(minor(dev));
 
-       if (!sc)
-               return (EINVAL);
+       if (sc == NULL)
+               return (ENXIO);
 
-       if (!sc->sc_count)
-               return (EINVAL);
+       if (sc->sc_count == 0)
+               /* This is not supposed to happen. */
+               return (0);
 
        sc->sc_count--;
 
        return (0);
 }
 
+#if 0
 static int
 smbwrite(struct dev_write_args *ap)
 {
@@ -175,22 +186,30 @@ smbread(struct dev_read_args *ap)
 {
        return (EINVAL);
 }
+#endif
 
 static int
 smbioctl(struct dev_ioctl_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
-       device_t smbdev = IIC_DEVICE(minor(dev));
-       struct smb_softc *sc = IIC_SOFTC(minor(dev));
-       device_t parent = device_get_parent(smbdev);
-
-       int error = 0;
+       char buf[SMB_MAXBLOCKSIZE];
+       device_t parent;
        struct smbcmd *s = (struct smbcmd *)ap->a_data;
-
-       if (!sc || !s)
+       struct smb_softc *sc = IIC_SOFTC(minor(dev));
+       device_t smbdev = IIC_DEVICE(minor(dev));
+       int error;
+       short w;
+       u_char count;
+       char c;
+
+       if (sc == NULL)
+               return (ENXIO);
+       if (s == NULL)
                return (EINVAL);
 
-       /* allocate the bus */
+       parent = device_get_parent(smbdev);
+
+       /* Allocate the bus. */
        if ((error = smbus_request_bus(parent, smbdev,
                        (ap->a_fflag & O_NONBLOCK) ? SMB_DONTWAIT : (SMB_WAIT | SMB_INTR))))
                return (error);
@@ -223,43 +242,74 @@ smbioctl(struct dev_ioctl_args *ap)
                break;
 
        case SMB_READB:
-               if (s->data.byte_ptr)
+               if (s->data.byte_ptr) {
                        error = smbus_error(smbus_readb(parent, s->slave,
-                                               s->cmd, s->data.byte_ptr));
+                                               s->cmd, &c));
+                       if (error)
+                               break;
+                       error = copyout(&c, s->data.byte_ptr,
+                                       sizeof(*(s->data.byte_ptr)));
+               }
                break;
 
        case SMB_READW:
-               if (s->data.word_ptr)
+               if (s->data.word_ptr) {
                        error = smbus_error(smbus_readw(parent, s->slave,
-                                               s->cmd, s->data.word_ptr));
+                                               s->cmd, &w));
+                       if (error == 0) {
+                               error = copyout(&w, s->data.word_ptr,
+                                               sizeof(*(s->data.word_ptr)));
+                       }
+               }
                break;
 
        case SMB_PCALL:
-               if (s->data.process.rdata)
+               if (s->data.process.rdata) {
                        error = smbus_error(smbus_pcall(parent, s->slave, s->cmd,
-                               s->data.process.sdata, s->data.process.rdata));
+                               s->data.process.sdata, &w));
+                       if (error)
+                               break;
+                       error = copyout(&w, s->data.process.rdata,
+                                       sizeof(*(s->data.process.rdata)));
+               }
+
                break;
 
        case SMB_BWRITE:
-               if (s->count && s->data.byte_ptr)
+               if (s->count && s->data.byte_ptr) {
+                       if (s->count > SMB_MAXBLOCKSIZE)
+                               s->count = SMB_MAXBLOCKSIZE;
+                       error = copyin(s->data.byte_ptr, buf, s->count);
+                       if (error)
+                               break;
                        error = smbus_error(smbus_bwrite(parent, s->slave,
-                                               s->cmd, s->count, s->data.byte_ptr));
+                                               s->cmd, s->count, buf));
+               }
                break;
 
+       case SMB_OLD_BREAD:
        case SMB_BREAD:
-               if (s->count && s->data.byte_ptr)
+               if (s->count && s->data.byte_ptr) {
+                       count = min(s->count, SMB_MAXBLOCKSIZE);
                        error = smbus_error(smbus_bread(parent, s->slave,
-                                               s->cmd, s->count, s->data.byte_ptr));
+                                               s->cmd, &count, buf));
+                       if (error)
+                               break;
+                       error = copyout(buf, s->data.byte_ptr,
+                           min(count, s->count));
+                       s->count = count;
+               }
                break;
-               
+
        default:
-               error = ENODEV;
+               error = ENOTTY;
        }
 
-       /* release the bus */
        smbus_release_bus(parent, smbdev);
 
        return (error);
 }
 
 DRIVER_MODULE(smb, smbus, smb_driver, smb_devclass, 0, 0);
+MODULE_DEPEND(smb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(smb, 1);
similarity index 85%
rename from sys/platform/pc32/include/smb.h
rename to sys/bus/smbus/smb.h
index 5542c17..ef2cd68 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/i386/include/smb.h,v 1.3 1999/08/28 00:44:24 peter Exp $
+ * $FreeBSD: src/sys/dev/smbus/smb.h,v 1.4.8.1 2006/09/22 19:19:16 jhb Exp $
  * $DragonFly: src/sys/platform/pc32/include/smb.h,v 1.4 2006/05/20 02:42:06 dillon Exp $
  *
  */
-#ifndef _MACHINE_SMB_H_
-#define _MACHINE_SMB_H_
+#ifndef __SMB_H
+#define __SMB_H
 
-#ifndef _SYS_TYPES_H_
-#include <sys/types.h>
-#endif
-#ifndef _SYS_IOCCOM_H_
 #include <sys/ioccom.h>
-#endif
 
 struct smbcmd {
        char cmd;
@@ -55,16 +50,22 @@ struct smbcmd {
        } data;
 };
 
+/*
+ * SMBus spec 2.0 says block transfers may be at most 32 bytes.
+ */
+#define SMB_MAXBLOCKSIZE       32
+
 #define SMB_QUICK_WRITE        _IOW('i', 1, struct smbcmd)
 #define SMB_QUICK_READ _IOW('i', 2, struct smbcmd)
 #define SMB_SENDB      _IOW('i', 3, struct smbcmd)
-#define SMB_RECVB      _IOW('i', 4, struct smbcmd)
+#define SMB_RECVB      _IOWR('i', 4, struct smbcmd)
 #define SMB_WRITEB     _IOW('i', 5, struct smbcmd)
 #define SMB_WRITEW     _IOW('i', 6, struct smbcmd)
 #define SMB_READB      _IOW('i', 7, struct smbcmd)
 #define SMB_READW      _IOW('i', 8, struct smbcmd)
 #define SMB_PCALL      _IOW('i', 9, struct smbcmd)
 #define SMB_BWRITE     _IOW('i', 10, struct smbcmd)
-#define SMB_BREAD      _IOW('i', 11, struct smbcmd)
+#define SMB_OLD_BREAD  _IOW('i', 11, struct smbcmd)
+#define SMB_BREAD      _IOWR('i', 11, struct smbcmd)
 
 #endif
diff --git a/sys/bus/smbus/smb/Makefile b/sys/bus/smbus/smb/Makefile
new file mode 100644 (file)
index 0000000..cafa6e2
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/smb/Makefile,v 1.1 2002/03/23 15:48:58 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = smb
+SRCS           = device_if.h bus_if.h smbus_if.h \
+                 smb.c
+
+.include <bsd.kmod.mk>
index 9b9c548..44d7d75 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/smbus/smbconf.c,v 1.9 1999/12/03 08:41:08 mdodd Exp $
+ * $FreeBSD: src/sys/dev/smbus/smbconf.c,v 1.13.10.1 2006/09/22 19:19:16 jhb Exp $
  * $DragonFly: src/sys/bus/smbus/smbconf.c,v 1.5 2005/06/02 20:40:38 dillon Exp $
  *
  */
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/bus.h>
 #include <sys/thread2.h>
@@ -50,8 +48,6 @@ smbus_intr(device_t bus, u_char devaddr, char low, char high, int error)
        /* call owner's intr routine */
        if (sc->owner)
                SMBUS_INTR(sc->owner, devaddr, low, high, error);
-
-       return;
 }
 
 /*
@@ -67,37 +63,22 @@ smbus_error(int smb_error)
        if (smb_error == SMB_ENOERR)
                return (0);
        
-       if (smb_error & (SMB_ENOTSUPP)) {
+       if (smb_error & (SMB_ENOTSUPP))
                error = ENODEV;
-       } else if (smb_error & (SMB_ENOACK)) {
+       else if (smb_error & (SMB_ENOACK))
                error = ENXIO;
-       } else if (smb_error & (SMB_ETIMEOUT)) {
+       else if (smb_error & (SMB_ETIMEOUT))
                error = EWOULDBLOCK;
-       } else if (smb_error & (SMB_EBUSY)) {
+       else if (smb_error & (SMB_EBUSY))
                error = EBUSY;
-       } else {
+       else if (smb_error & (SMB_EABORT | SMB_EBUSERR | SMB_ECOLLI))
+               error = EIO;
+       else
                error = EINVAL;
-       }
 
        return (error);
 }
 
-/*
- * smbus_alloc_bus()
- *
- * Allocate a new bus connected to the given parent device
- */
-device_t
-smbus_alloc_bus(device_t parent)
-{
-       device_t child;
-
-       /* add the bus to the parent */
-       child = device_add_child(parent, "smbus", -1);
-
-       return (child);
-}
-
 static int
 smbus_poll(struct smbus_softc *sc, int how)
 {
@@ -113,7 +94,7 @@ smbus_poll(struct smbus_softc *sc, int how)
                break;
 
        default:
-               return (EWOULDBLOCK);
+               error = EWOULDBLOCK;
                break;
        }
 
@@ -130,18 +111,19 @@ smbus_poll(struct smbus_softc *sc, int how)
 int
 smbus_request_bus(device_t bus, device_t dev, int how)
 {
-       struct smbus_softc *sc = (struct smbus_softc *)device_get_softc(bus);
-       int error = 0;
+       struct smbus_softc *sc = device_get_softc(bus);
+       device_t parent;
+       int error;
 
        /* first, ask the underlying layers if the request is ok */
+       parent = device_get_parent(bus);
        do {
-               error = SMBUS_CALLBACK(device_get_parent(bus),
-                                               SMB_REQUEST_BUS, (caddr_t)&how);
+               error = SMBUS_CALLBACK(parent, SMB_REQUEST_BUS, &how);
                if (error)
                        error = smbus_poll(sc, how);
        } while (error == EWOULDBLOCK);
 
-       while (!error) {
+       while (error == 0) {
                crit_enter();
                if (sc->owner && sc->owner != dev) {
                        crit_exit();
@@ -149,13 +131,11 @@ smbus_request_bus(device_t bus, device_t dev, int how)
                } else {
                        sc->owner = dev;
                        crit_exit();
-                       return (0);
                }
 
                /* free any allocated resource */
                if (error)
-                       SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS,
-                                       (caddr_t)&how);
+                       SMBUS_CALLBACK(parent, SMB_RELEASE_BUS, &how);
        }
 
        return (error);
@@ -179,31 +159,18 @@ smbus_release_bus(device_t bus, device_t dev)
                return (error);
 
        crit_enter();
-       if (sc->owner != dev) {
-               crit_exit();
-               return (EACCES);
+       if (sc->owner == dev) {
+               sc->owner = NULL;
+
+               /* wakeup waiting processes */
+               wakeup(sc);
+       } else {
+               error = EACCES;
        }
-       sc->owner = 0;
        crit_exit();
 
        /* wakeup waiting processes */
        wakeup(sc);
 
-       return (0);
-}
-
-/*
- * smbus_get_addr()
- *
- * Get the I2C 7 bits address of the device
- */
-u_char
-smbus_get_addr(device_t dev)
-{
-       uintptr_t addr;
-       device_t parent = device_get_parent(dev);
-
-       BUS_READ_IVAR(parent, dev, SMBUS_IVAR_ADDR, &addr);
-
-       return ((u_char)addr);
+       return (error);
 }
index 7518065..4786d22 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/smbus/smbconf.h,v 1.7 2002/03/23 15:47:28 nsouch Exp $
+ * $FreeBSD: src/sys/dev/smbus/smbconf.h,v 1.7.14.1 2006/09/22 19:19:16 jhb Exp $
  * $DragonFly: src/sys/bus/smbus/smbconf.h,v 1.4 2003/11/14 21:46:18 daver Exp $
  */
 #ifndef __SMBONF_H
@@ -31,6 +31,8 @@
 
 #include <sys/queue.h>
 
+#define SMBPRI (PZERO+8)               /* XXX sleep/wakeup queue priority */
+
 #define n(flags) (~(flags) & (flags))
 
 /*
@@ -58,6 +60,7 @@
 #define SMB_EABORT     0x10
 #define SMB_ETIMEOUT   0x20
 #define SMB_EBUSY      0x40
+#define        SMB_EINVAL      0x100
 
 /*
  * How Quick command is executed
 /*
  * ivars codes
  */
-#define SMBUS_IVAR_ADDR        0x1     /* I2C address of the device */
+#define SMBUS_IVAR_ADDR        0x1     /* slave address of the device */
+
+int    smbus_request_bus(device_t, device_t, int);
+int    smbus_release_bus(device_t, device_t);
+int    smbus_error(int error);
 
-extern int smbus_request_bus(device_t, device_t, int);
-extern int smbus_release_bus(device_t, device_t);
-extern device_t smbus_alloc_bus(device_t);
-extern int smbus_error(int error);
+void   smbus_intr(device_t, u_char, char low, char high, int error);
 
-extern void smbus_intr(device_t, u_char, char low, char high, int error);
+u_char smbus_get_addr(device_t);
 
-extern u_char smbus_get_addr(device_t);
+extern driver_t smbus_driver;
+extern devclass_t smbus_devclass;
 
 #define smbus_quick(bus,slave,how) \
        (SMBUS_QUICK(device_get_parent(bus), slave, how))
@@ -100,9 +105,9 @@ extern u_char smbus_get_addr(device_t);
 #define smbus_bread(bus,slave,cmd,count,buf) \
        (SMBUS_BREAD(device_get_parent(bus), slave, cmd, count, buf))
 
-#define SMBUS_MODVER   1
-#define SMBUS_MINVER   1
-#define SMBUS_MAXVER   1
-#define SMBUS_PREFVER  SMBUS_MODVER
+#define SMBUS_MODVER   1
+#define SMBUS_MINVER   1
+#define SMBUS_MAXVER   1
+#define SMBUS_PREFVER  SMBUS_MODVER
 
 #endif
index 65c9fae..1e2d6fa 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu
+ * Copyright (c) 1998, 2001 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/smbus/smbus.c,v 1.12.2.3 2002/04/19 05:52:12 nsouch Exp $
+ * $FreeBSD: src/sys/dev/smbus/smbus.c,v 1.18.10.4 2006/09/26 18:44:56 jhb Exp $
  * $DragonFly: src/sys/bus/smbus/smbus.c,v 1.4 2006/12/22 23:12:17 swildner Exp $
  *
  */
 #include "smbus.h"
 
 /*
- * Autoconfiguration and support routines for the Philips serial I2C bus
+ * Autoconfiguration and support routines for System Management bus
  */
 
-#define DEVTOSMBUS(dev) ((struct smbus_device*)device_get_ivars(dev))
-
-/*
- * structure used to attach devices to the I2C bus
- */
-struct smbus_device {
-       const char *smbd_name;          /* device name */
-       const char *smbd_desc;          /* device descriptor */
-};
-
-/*
- * list of known devices
- */
-struct smbus_device smbus_children[] = {
-       { "smb", "SMBus general purpose I/O" },
-       { NULL, 0 }
-};
-
-static devclass_t smbus_devclass;
-
 /*
  * Device methods
  */
 static int smbus_probe(device_t);
 static int smbus_attach(device_t);
-
-#if 0
-static int smbus_read_ivar(device_t , device_t, int, u_long *);
-#endif
+static int smbus_detach(device_t);
 
 static device_method_t smbus_methods[] = {
         /* device interface */
         DEVMETHOD(device_probe,         smbus_probe),
         DEVMETHOD(device_attach,        smbus_attach),
-        DEVMETHOD(device_detach,        bus_generic_detach),
-        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
+        DEVMETHOD(device_detach,        smbus_detach),
 
         /* bus interface */
+       DEVMETHOD(bus_add_child,        bus_generic_add_child),
         DEVMETHOD(bus_print_child,     bus_generic_print_child),
-        DEVMETHOD(bus_read_ivar,        bus_generic_read_ivar),
-        DEVMETHOD(bus_write_ivar,       bus_generic_write_ivar),
 
         { 0, 0 }
 };
 
-static driver_t smbus_driver = {
+driver_t smbus_driver = {
         "smbus",
         smbus_methods,
         sizeof(struct smbus_softc),
 };
 
+devclass_t smbus_devclass;
+
 /*
  * At 'probe' time, we add all the devices which we know about to the
  * bus.  The generic attach routine will probe and attach them if they
@@ -107,49 +84,27 @@ smbus_probe(device_t dev)
 static int
 smbus_attach(device_t dev)
 {
-       struct smbus_device *smbdev;
-
-       /* add known devices */
-       for (smbdev = smbus_children; smbdev->smbd_name; smbdev++) {
-               device_t child;
-
-               if (devclass_find(smbdev->smbd_name)) {
-                       child = device_add_child(dev, smbdev->smbd_name, -1);
-                       device_set_ivars(child, smbdev);
-                       device_set_desc(child, smbdev->smbd_desc);
-               } else if (bootverbose)
-                       kprintf("smbus: %s devclass not found\n",
-                               smbdev->smbd_name);
-       }
+       bus_generic_probe(dev);
        bus_generic_attach(dev);
-         
-        return (0);
-}
 
-void
-smbus_generic_intr(device_t dev, u_char devaddr, char low, char high)
-{
-       return;
+       return (0);
 }
 
-#if 0
 static int
-smbus_read_ivar(device_t bus, device_t dev, int index, u_long* result)
+smbus_detach(device_t dev)
 {
-       struct smbus_device* smbdev = DEVTOSMBUS(dev);
+       int error;
+
+       error = bus_generic_detach(dev);
+       if (error)
+               return (error);
+
+       return (0);
+}
 
-       switch (index) {
-       default:
-               break;
-       }
-       return (ENOENT);
+void
+smbus_generic_intr(device_t dev, u_char devaddr, char low, char high)
+{
 }
-#endif
-
-DRIVER_MODULE(smbus, iicsmb, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, bti2c, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, alsmb, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, ichsmb, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, amdsmb, smbus_driver, smbus_devclass, 0, 0);
-DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
+
+MODULE_VERSION(smbus, SMBUS_MODVER);
index ab59078..858082d 100644 (file)
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/smbus/smbus.h,v 1.2 1999/08/28 00:42:30 peter Exp $
+ * $FreeBSD: src/sys/dev/smbus/smbus.h,v 1.2.34.2 2006/09/22 19:19:16 jhb Exp $
  * $DragonFly: src/sys/bus/smbus/smbus.h,v 1.3 2006/09/30 20:03:44 swildner Exp $
  *
  */
 #define __SMBUS_H
 
 struct smbus_softc {
-
        device_t owner;         /* smbus owner device structure */
 };
 
-extern void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high);
+void   smbus_generic_intr(device_t dev, u_char devaddr, char low, char high);
 
 #endif
diff --git a/sys/bus/smbus/smbus/Makefile b/sys/bus/smbus/smbus/Makefile
new file mode 100644 (file)
index 0000000..b0c831b
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/smbus/Makefile,v 1.1 2002/03/23 15:48:59 nsouch Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = smbus
+SRCS           = device_if.h bus_if.h smbus_if.h smbus_if.c \
+                 smbconf.h smbconf.c smbus.h smbus.c
+
+.include <bsd.kmod.mk>
index f1bece3..0595359 100644 (file)
@@ -1,4 +1,4 @@
-#
+#-
 # Copyright (c) 1998 Nicolas Souchu
 # All rights reserved.
 #
@@ -23,7 +23,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: src/sys/dev/smbus/smbus_if.m,v 1.5 1999/08/28 00:42:30 peter Exp $
+# $FreeBSD: src/sys/dev/smbus/smbus_if.m,v 1.7.2.1 2006/09/22 19:19:16 jhb Exp $
 # $DragonFly: src/sys/bus/smbus/smbus_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
@@ -48,7 +48,7 @@ METHOD void intr {
 METHOD int callback {
        device_t dev;
        int index;
-       caddr_t data;
+       void *data;
 };
 
 #
@@ -147,6 +147,6 @@ METHOD int bread {
        device_t dev;
        u_char slave;
        char cmd;
-       u_char count;
+       u_char *count;
        char *buf;
 };
index eaeaf25..5aba466 100644 (file)
@@ -672,6 +672,7 @@ dev/misc/lpt/lpt.c          optional lpt
 dev/misc/pcfclock/pcfclock.c   optional pcfclock
 dev/misc/cmx/cmx.c             optional cmx
 dev/misc/cmx/cmx_pccard.c      optional cmx pccard
+bus/iicbus/pcf/pcf.c   optional pcf
 bus/ppbus/ppb_base.c   optional ppbus
 bus/ppbus/ppb_1284.c   optional ppbus
 bus/ppbus/ppb_msq.c    optional ppbus
@@ -1599,9 +1600,10 @@ dev/netif/vge/if_vge.c           optional vge
 dev/netif/vr/if_vr.c           optional vr
 dev/netif/wb/if_wb.c           optional wb
 dev/netif/xl/if_xl.c           optional xl
-dev/powermng/i386/intpm/intpm.c        optional intpm
-dev/powermng/i386/amdpm/amdpm.c        optional amdpm
-dev/powermng/i386/viapm/viapm.c        optional viapm
+dev/powermng/alpm/alpm.c       optional alpm
+dev/powermng/amdpm/amdpm.c     optional amdpm
+dev/powermng/intpm/intpm.c     optional intpm
+dev/powermng/viapm/viapm.c     optional viapm
 dev/video/meteor/meteor.c      optional meteor pci
 dev/disk/ncr/ncr.c             optional ncr
 dev/disk/sym/sym_hipd.c                optional sym                            \
@@ -1618,7 +1620,6 @@ bus/pci/pci_user.c                optional pci
 bus/pci/pcib_if.m              optional pci
 bus/pci/vga_pci.c              optional pci
 bus/pci/pci_compat.c           optional pci compat_oldpci
-dev/powermng/i386/alpm/alpm.c  optional alpm
 kern/kern_posix4_mib.c         standard
 kern/kern_p1003_1b.c           standard
 kern/kern_sched.c              optional _kposix_priority_scheduling
index 8bc099a..b4cf95a 100644 (file)
@@ -1,6 +1,6 @@
 # $DragonFly: src/sys/dev/misc/Makefile,v 1.5 2008/04/23 08:57:10 hasso Exp $
 #
 
-SUBDIR=cmx dcons joy kbdmux pcfclock nmdm syscons snp hotplug
+SUBDIR=cmx dcons joy kbdmux lpbb pcfclock nmdm syscons snp hotplug
 
 .include <bsd.subdir.mk>
diff --git a/sys/dev/misc/lpbb/Makefile b/sys/dev/misc/lpbb/Makefile
new file mode 100644 (file)
index 0000000..0a7bccb
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/lpbb/Makefile,v 1.2 2003/06/14 20:43:33 jmg Exp $
+
+.PATH:         ${.CURDIR}/../../../bus/ppbus
+KMOD           = lpbb
+SRCS           = device_if.h bus_if.h iicbb_if.h ppbus_if.h \
+                 lpbb.c
+
+.include <bsd.kmod.mk>
index f311f08..a49a107 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
+ * Copyright (c) 1998, 2001 Nicolas Souchu, Marc Bouget
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/ppbus/lpbb.c,v 1.11.2.1 2000/05/24 00:20:57 n_hibma Exp $
+ * $FreeBSD: src/sys/dev/ppbus/lpbb.c,v 1.18.8.1 2006/07/19 16:31:12 kib Exp $
  * $DragonFly: src/sys/dev/misc/lpbb/lpbb.c,v 1.4 2005/10/28 03:25:45 dillon Exp $
  *
  */
@@ -41,8 +41,6 @@
 #include <sys/bus.h>
 #include <sys/uio.h>
 
-#include <machine/clock.h>
-
 #include <bus/ppbus/ppbconf.h>
 #include "ppbus_if.h"
 #include <bus/ppbus/ppbio.h>
 
 static int lpbb_detect(device_t dev);
 
+static void
+lpbb_identify(driver_t *driver, device_t parent)
+{
+
+       device_t dev;
+
+       dev = device_find_child(parent, "lpbb", 0);
+       if (!dev)
+               BUS_ADD_CHILD(parent, parent, 0, "lpbb", -1);
+}
+
 static int
 lpbb_probe(device_t dev)
 {
@@ -70,19 +79,12 @@ lpbb_probe(device_t dev)
 static int
 lpbb_attach(device_t dev)
 {
-       device_t bitbang, iicbus;
+       device_t bitbang;
        
        /* add generic bit-banging code */
        bitbang = device_add_child(dev, "iicbb", -1);
-
-       /* add the iicbus to the tree */
-       iicbus = iicbus_alloc_bus(bitbang);
-
        device_probe_and_attach(bitbang);
 
-       /* XXX should be in iicbb_attach! */
-       device_probe_and_attach(iicbus);
-
        return (0);
 }
 
@@ -119,24 +121,34 @@ lpbb_callback(device_t dev, int index, caddr_t *data)
 #define ALIM    0x20
 #define I2CKEY  0x50
 
-static int getSDA(device_t ppbus)
+static int
+lpbb_getscl(device_t dev)
 {
-       if((ppb_rstr(ppbus)&SDA_in)==SDA_in)
-               return 1;                   
-       else                                
-               return 0;                   
+       return ((ppb_rstr(device_get_parent(dev)) & SCL_in) == SCL_in);
 }
 
-static void setSDA(device_t ppbus, char val)
+static int
+lpbb_getsda(device_t dev)
+{
+       return ((ppb_rstr(device_get_parent(dev)) & SDA_in) == SDA_in);
+}
+
+static void
+lpbb_setsda(device_t dev, char val)
 {
+       device_t ppbus = device_get_parent(dev);
+
        if(val==0)
                ppb_wdtr(ppbus, (u_char)SDA_out);
        else                            
                ppb_wdtr(ppbus, (u_char)~SDA_out);
 }
 
-static void setSCL(device_t ppbus, unsigned char val)
+static void
+lpbb_setscl(device_t dev, unsigned char val)
 {
+       device_t ppbus = device_get_parent(dev);
+
        if(val==0)
                ppb_wctr(ppbus, (u_char)(ppb_rctr(ppbus)&~SCL_out));
        else                                               
@@ -153,8 +165,8 @@ static int lpbb_detect(device_t dev)
        }
 
        /* reset bus */
-       setSDA(ppbus, 1);
-       setSCL(ppbus, 1);
+       lpbb_setsda(dev, 1);
+       lpbb_setscl(dev, 1);
 
        if ((ppb_rstr(ppbus) & I2CKEY) ||
                ((ppb_rstr(ppbus) & ALIM) != ALIM)) {
@@ -173,40 +185,25 @@ lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
 {
        device_t ppbus = device_get_parent(dev);
 
-       /* reset bus */
-       setSDA(ppbus, 1);
-       setSCL(ppbus, 1);
-
-       return (IIC_ENOADDR);
-}
-
-static void
-lpbb_setlines(device_t dev, int ctrl, int data)
-{
-       device_t ppbus = device_get_parent(dev);
+       if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
+               device_printf(dev, "can't allocate ppbus\n");
+               return (0);
+       }
 
-       setSCL(ppbus, ctrl);
-       setSDA(ppbus, data);
-}
+       /* reset bus */
+       lpbb_setsda(dev, 1);
+       lpbb_setscl(dev, 1);
 
-static int
-lpbb_getdataline(device_t dev)
-{
-       device_t ppbus = device_get_parent(dev);
+       ppb_release_bus(ppbus, dev);
 
-       return (getSDA(ppbus));
+       return (IIC_ENOADDR);
 }
 
-/*
- * Because lpbb is a static device that always exists under any attached
- * ppbus device, and not scanned by the ppbus device, we need an identify
- * function to install the device.
- */
 static devclass_t lpbb_devclass;
 
 static device_method_t lpbb_methods[] = {
        /* device interface */
-       DEVMETHOD(device_identify,      bus_generic_identify),
+       DEVMETHOD(device_identify,      lpbb_identify),
        DEVMETHOD(device_probe,         lpbb_probe),
        DEVMETHOD(device_attach,        lpbb_attach),
 
@@ -215,8 +212,10 @@ static device_method_t lpbb_methods[] = {
 
        /* iicbb interface */
        DEVMETHOD(iicbb_callback,       lpbb_callback),
-       DEVMETHOD(iicbb_setlines,       lpbb_setlines),
-       DEVMETHOD(iicbb_getdataline,    lpbb_getdataline),
+       DEVMETHOD(iicbb_setsda,         lpbb_setsda),
+       DEVMETHOD(iicbb_setscl,         lpbb_setscl),
+       DEVMETHOD(iicbb_getsda,         lpbb_getsda),
+       DEVMETHOD(iicbb_getscl,         lpbb_getscl),
        DEVMETHOD(iicbb_reset,          lpbb_reset),
 
        { 0, 0 }
@@ -229,3 +228,6 @@ static driver_t lpbb_driver = {
 };
 
 DRIVER_MODULE(lpbb, ppbus, lpbb_driver, lpbb_devclass, 0, 0);
+MODULE_DEPEND(lpbb, ppbus, 1, 1, 1);
+MODULE_DEPEND(lpbb, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
+MODULE_VERSION(lpbb, 1);
index 373b4a9..cebe2f8 100644 (file)
@@ -3,8 +3,8 @@
 
 SUBDIR= an age alc ale ar ath aue axe bce bfe bge \
        cue dc ed em ep et fwe \
-       fxp iwi iwn jme kue lge lnc mii_layer my msk mxge nfe nge pcn ral re \
-       rl rue sbni sbsh sf sis sk sln sr ste stge ti tl tx txp \
+       fxp ic iwi iwn jme kue lge lnc mii_layer my msk mxge nfe nge pcn \
+       ral re rl rue sbni sbsh sf sis sk sln sr ste stge ti tl tx txp \
        vge vr vx wb wi wpi xe xl ig_hal emx ae
 
 # XXX need to be updated to the new net80211 stack
diff --git a/sys/dev/netif/ic/Makefile b/sys/dev/netif/ic/Makefile
new file mode 100644 (file)
index 0000000..6d34153
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/if_ic/Makefile,v 1.1 2002/03/23 15:48:48 nsouch Exp $
+
+.PATH:         ${.CURDIR}/../../../bus/iicbus
+KMOD           = if_ic
+SRCS           = device_if.h bus_if.h iicbus_if.h \
+                 if_ic.c
+
+.include <bsd.kmod.mk>
index 6c76866..1be8d0f 100644 (file)
@@ -69,6 +69,8 @@
 
 #include "iicbus_if.h"
 
+#define PCF_MASTER_ADDRESS 0xaa
+
 #define ICHDRLEN       sizeof(uint32_t)
 #define ICMTU          1500            /* default mtu */
 
@@ -134,7 +136,7 @@ icattach(device_t dev)
        struct ic_softc *sc = (struct ic_softc *)device_get_softc(dev);
        struct ifnet *ifp = &sc->ic_if;
 
-       sc->ic_addr = iicbus_get_addr(dev);
+       sc->ic_addr = PCF_MASTER_ADDRESS;       /* XXX only PCF masters */
 
        ifp->if_softc = sc;
        if_initname(ifp, "ic", device_get_unit(dev));
@@ -407,6 +409,6 @@ error:
        return(0);
 }
 
-DECLARE_DUMMY_MODULE(if_ic);
 DRIVER_MODULE(if_ic, iicbus, ic_driver, ic_devclass, 0, 0);
-
+MODULE_DEPEND(if_ic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
+MODULE_VERSION(if_ic, 1);
index f95e6f4..0f5fcca 100644 (file)
@@ -1,4 +1,5 @@
-SUBDIR=        aps coretemp kate km lm wbsio
+SUBDIR=        alpm amdpm aps coretemp ichsmb intpm kate km lm viapm wbsio
+
 .if ${MACHINE_ARCH} == "i386"
 SUBDIR+= powernow
 .endif
diff --git a/sys/dev/powermng/alpm/Makefile b/sys/dev/powermng/alpm/Makefile
new file mode 100644 (file)
index 0000000..5a249f2
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/alpm/Makefile,v 1.2 2007/06/24 20:35:58 njl Exp $
+
+.PATH:         ${.CURDIR}/../../../../bus/pci
+KMOD           = alpm
+SRCS           = device_if.h bus_if.h iicbus_if.h smbus_if.h pci_if.h \
+                 alpm.c
+
+.include <bsd.kmod.mk>
similarity index 62%
rename from sys/dev/powermng/i386/alpm/alpm.c
rename to sys/dev/powermng/alpm/alpm.c
index ff0aff8..d363ec4 100644 (file)
@@ -23,8 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/pci/alpm.c,v 1.15 2001/01/17 00:38:06 peter Exp $
- * $DragonFly: src/sys/dev/powermng/i386/alpm/alpm.c,v 1.8 2006/12/22 23:26:23 swildner Exp $
+ * $FreeBSD: src/sys/pci/alpm.c,v 1.24 2005/05/29 04:42:29 nyan Exp $
  *
  */
 
@@ -117,108 +116,64 @@ static int alpm_debug = 0;
 #define SMBCLOCK_111K  0xa0
 #define SMBCLOCK_55K   0xc0
 
-struct alpm_data {
+struct alpm_softc {
        int base;
+       struct resource *res;
         bus_space_tag_t smbst;
         bus_space_handle_t smbsh;
-};
-
-struct alsmb_softc {
-       int base;
        device_t smbus;
-       struct alpm_data *alpm;
 };
 
-#define ALPM_SMBINB(alsmb,register) \
-       (bus_space_read_1(alsmb->alpm->smbst, alsmb->alpm->smbsh, register))
-#define ALPM_SMBOUTB(alsmb,register,value) \
-       (bus_space_write_1(alsmb->alpm->smbst, alsmb->alpm->smbsh, register, value))
-
-static int alsmb_probe(device_t);
-static int alsmb_attach(device_t);
-static int alsmb_smb_callback(device_t, int, caddr_t *);
-static int alsmb_smb_quick(device_t dev, u_char slave, int how);
-static int alsmb_smb_sendb(device_t dev, u_char slave, char byte);
-static int alsmb_smb_recvb(device_t dev, u_char slave, char *byte);
-static int alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte);
-static int alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte);
-static int alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word);
-static int alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word);
-static int alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
-static int alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *byte);
-
-static devclass_t alsmb_devclass;
-
-static device_method_t alsmb_methods[] = {
-       /* device interface */
-       DEVMETHOD(device_probe,         alsmb_probe),
-       DEVMETHOD(device_attach,        alsmb_attach),
+#define ALPM_SMBINB(alpm,register) \
+       (bus_space_read_1(alpm->smbst, alpm->smbsh, register))
+#define ALPM_SMBOUTB(alpm,register,value) \
+       (bus_space_write_1(alpm->smbst, alpm->smbsh, register, value))
 
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       
-       /* smbus interface */
-       DEVMETHOD(smbus_callback,       alsmb_smb_callback),
-       DEVMETHOD(smbus_quick,          alsmb_smb_quick),
-       DEVMETHOD(smbus_sendb,          alsmb_smb_sendb),
-       DEVMETHOD(smbus_recvb,          alsmb_smb_recvb),
-       DEVMETHOD(smbus_writeb,         alsmb_smb_writeb),
-       DEVMETHOD(smbus_readb,          alsmb_smb_readb),
-       DEVMETHOD(smbus_writew,         alsmb_smb_writew),
-       DEVMETHOD(smbus_readw,          alsmb_smb_readw),
-       DEVMETHOD(smbus_bwrite,         alsmb_smb_bwrite),
-       DEVMETHOD(smbus_bread,          alsmb_smb_bread),
-       
-       { 0, 0 }
-};
+static int
+alpm_probe(device_t dev)
+{
+#ifdef ALPM_SMBIO_BASE_ADDR
+       u_int32_t l;
+#endif
 
-static driver_t alsmb_driver = {
-       "alsmb",
-       alsmb_methods,
-       sizeof(struct alsmb_softc),
-};
+       if(pci_get_devid(dev) == ACER_M1543_PMU_ID) {
+               device_set_desc(dev, "AcerLabs M15x3 Power Management Unit");
 
-static int alpm_pci_probe(device_t dev);
-static int alpm_pci_attach(device_t dev);
+#ifdef ALPM_SMBIO_BASE_ADDR
+               if (bootverbose || alpm_debug)
+                       device_printf(dev, "forcing base I/O at 0x%x\n",
+                                       ALPM_SMBIO_BASE_ADDR);
 
-static devclass_t alpm_devclass;
+               /* disable I/O */
+               l = pci_read_config(dev, COM, 2);
+               pci_write_config(dev, COM, l & ~COM_ENABLE_IO, 2);
 
-static device_method_t alpm_pci_methods[] = {
-       /* device interface */
-       DEVMETHOD(device_probe,         alpm_pci_probe),
-       DEVMETHOD(device_attach,        alpm_pci_attach),
-       
-       { 0, 0 }
-};
+               /* set the I/O base address */
+               pci_write_config(dev, SMBBA, ALPM_SMBIO_BASE_ADDR | 0x1, 4);
 
-static driver_t alpm_pci_driver = {
-       "alpm",
-       alpm_pci_methods,
-       sizeof(struct alpm_data)
-};
+               /* enable I/O */
+               pci_write_config(dev, COM, l | COM_ENABLE_IO, 2);
 
-static int
-alpm_pci_probe(device_t dev)
-{
-       if(pci_get_devid(dev) == ACER_M1543_PMU_ID) {
-               device_set_desc(dev, "AcerLabs M15x3 Power Management Unit");
-               return 0;
-       } else {
-               return ENXIO;
+               if (bus_set_resource(dev, SYS_RES_IOPORT, SMBBA,
+                                       ALPM_SMBIO_BASE_ADDR, 256)) {
+                       device_printf(dev, "could not set bus resource\n");
+                       return (ENXIO);
+               }
+#endif
+               return (BUS_PROBE_DEFAULT);
        }
+
+       return (ENXIO);
 }
 
 static int
-alpm_pci_attach(device_t dev)
+alpm_attach(device_t dev)
 {
-       int rid, unit;
+       int rid;
        u_int32_t l;
-       struct alpm_data *alpm;
-       struct resource *res;
-       device_t smbinterface;
+       struct alpm_softc *alpm;
 
        alpm = device_get_softc(dev);
-       unit = device_get_unit(dev);
 
        /* Unlock SMBIO base register access */
        l = pci_read_config(dev, ATPC, 1);
@@ -232,9 +187,9 @@ alpm_pci_attach(device_t dev)
        pci_write_config(dev, SMBHCBC, l, 1)
         */
 
-       if (bootverbose) {
+       if (bootverbose || alpm_debug) {
                l = pci_read_config(dev, SMBHSI, 1);
-               kprintf("alsmb%d: %s/%s", unit,
+               device_printf(dev, "%s/%s",
                        (l & SMBHSI_HOST) ? "host":"nohost",
                        (l & SMBHSI_SLAVE) ? "slave":"noslave");
 
@@ -258,76 +213,49 @@ alpm_pci_attach(device_t dev)
                case SMBCLOCK_55K:
                        kprintf(" 55K");
                        break;
+               default:
+                       kprintf("unkown");
+                       break;
                }
+               kprintf("\n");
        }
 
-#ifdef ALPM_SMBIO_BASE_ADDR
-       /* XX will this even work anymore? */
-       /* disable I/O */
-       l = pci_read_config(dev, COM, 2);
-       pci_write_config(dev, COM, l & ~COM_ENABLE_IO, 2);
-
-       /* set the I/O base address */
-       pci_write_config(dev, SMBBA, ALPM_SMBIO_BASE_ADDR | 0x1, 4);
-
-       /* enable I/O */
-       pci_write_config(dev, COM, l | COM_ENABLE_IO, 2);
-
-#endif
        rid = SMBBA;
-       res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
-           0, ~0, 1, RF_ACTIVE);
-       if (res == NULL) {
+       alpm->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
+           RF_ACTIVE);
+
+       if (alpm->res == NULL) {
                device_printf(dev, "Could not allocate Bus space\n");
-               return ENXIO;
+               return (ENXIO);
        }
-       alpm->smbst = rman_get_bustag(res);
-       alpm->smbsh = rman_get_bushandle(res);
-
-       if (bootverbose)
-               kprintf(" at 0x%x\n", alpm->smbsh);
-
-       smbinterface = device_add_child(dev, "alsmb", unit);
-       if (!smbinterface)
-               device_printf(dev, "could not add SMBus device\n");
-       else
-               device_probe_and_attach(smbinterface);
-       return 0;
-}
+       alpm->smbst = rman_get_bustag(alpm->res);
+       alpm->smbsh = rman_get_bushandle(alpm->res);
 
-/*
- * Not a real probe, we know the device exists since the device has
- * been added after the successfull pci probe.
- */
-static int
-alsmb_probe(device_t dev)
-{
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
-
-       /* allocate a new smbus device */
-       sc->smbus = smbus_alloc_bus(dev);
-       if (!sc->smbus)
-               return (EINVAL);
-       device_set_desc(dev, "Aladdin IV/V/Pro2 SMBus controller");
+       /* attach the smbus */
+       alpm->smbus = device_add_child(dev, "smbus", -1);
+       bus_generic_attach(dev);
 
        return (0);
 }
 
 static int
-alsmb_attach(device_t dev)
+alpm_detach(device_t dev)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *alpm = device_get_softc(dev);
 
-       sc->alpm = device_get_softc(device_get_parent(dev));
+       if (alpm->smbus) {
+               device_delete_child(dev, alpm->smbus);
+               alpm->smbus = NULL;
+       }
 
-       /* probe and attach the smbus */
-       device_probe_and_attach(sc->smbus);
+       if (alpm->res)
+               bus_release_resource(dev, SYS_RES_IOPORT, SMBBA, alpm->res);
 
        return (0);
 }
 
 static int
-alsmb_smb_callback(device_t dev, int index, caddr_t *data)
+alpm_callback(device_t dev, int index, caddr_t *data)
 {
        int error = 0;
 
@@ -344,7 +272,7 @@ alsmb_smb_callback(device_t dev, int index, caddr_t *data)
 }
 
 static int
-alsmb_clear(struct alsmb_softc *sc)
+alpm_clear(struct alpm_softc *sc)
 {
        ALPM_SMBOUTB(sc, SMBSTS, 0xff);
        DELAY(10);
@@ -354,7 +282,7 @@ alsmb_clear(struct alsmb_softc *sc)
 
 #if 0
 static int
-alsmb_abort(struct alsmb_softc *sc)
+alpm_abort(struct alpm_softc *sc)
 {
        ALPM_SMBOUTB(sc, SMBCMD, T_OUT_CMD | ABORT_HOST);
 
@@ -363,7 +291,7 @@ alsmb_abort(struct alsmb_softc *sc)
 #endif
 
 static int
-alsmb_idle(struct alsmb_softc *sc)
+alpm_idle(struct alpm_softc *sc)
 {
        u_char sts;
 
@@ -378,7 +306,7 @@ alsmb_idle(struct alsmb_softc *sc)
  * Poll the SMBus controller
  */
 static int
-alsmb_wait(struct alsmb_softc *sc)
+alpm_wait(struct alpm_softc *sc)
 {
        int count = 10000;
        u_char sts = 0;
@@ -409,19 +337,19 @@ alsmb_wait(struct alsmb_softc *sc)
                error |= SMB_EBUSERR;
 
        if (error != SMB_ENOERR)
-               alsmb_clear(sc);
+               alpm_clear(sc);
 
        return (error);
 }
 
 static int
-alsmb_smb_quick(device_t dev, u_char slave, int how)
+alpm_quick(device_t dev, u_char slave, int how)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (EBUSY);
 
        switch (how) {
@@ -439,7 +367,7 @@ alsmb_smb_quick(device_t dev, u_char slave, int how)
        ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       error = alsmb_wait(sc);
+       error = alpm_wait(sc);
 
        ALPM_DEBUG(kprintf(", error=0x%x\n", error));
 
@@ -447,13 +375,13 @@ alsmb_smb_quick(device_t dev, u_char slave, int how)
 }
 
 static int
-alsmb_smb_sendb(device_t dev, u_char slave, char byte)
+alpm_sendb(device_t dev, u_char slave, char byte)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
@@ -461,7 +389,7 @@ alsmb_smb_sendb(device_t dev, u_char slave, char byte)
        ALPM_SMBOUTB(sc, SMBHDATA, byte);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       error = alsmb_wait(sc);
+       error = alpm_wait(sc);
 
        ALPM_DEBUG(kprintf("alpm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
 
@@ -469,20 +397,20 @@ alsmb_smb_sendb(device_t dev, u_char slave, char byte)
 }
 
 static int
-alsmb_smb_recvb(device_t dev, u_char slave, char *byte)
+alpm_recvb(device_t dev, u_char slave, char *byte)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
        ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       if ((error = alsmb_wait(sc)) == SMB_ENOERR)
+       if ((error = alpm_wait(sc)) == SMB_ENOERR)
                *byte = ALPM_SMBINB(sc, SMBHDATA);
 
        ALPM_DEBUG(kprintf("alpm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
@@ -491,13 +419,13 @@ alsmb_smb_recvb(device_t dev, u_char slave, char *byte)
 }
 
 static int
-alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
+alpm_writeb(device_t dev, u_char slave, char cmd, char byte)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
@@ -506,7 +434,7 @@ alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
        ALPM_SMBOUTB(sc, SMBHCMD, cmd);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       error = alsmb_wait(sc);
+       error = alpm_wait(sc);
 
        ALPM_DEBUG(kprintf("alpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
 
@@ -514,13 +442,13 @@ alsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
 }
 
 static int
-alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
+alpm_readb(device_t dev, u_char slave, char cmd, char *byte)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
@@ -528,7 +456,7 @@ alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
        ALPM_SMBOUTB(sc, SMBHCMD, cmd);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       if ((error = alsmb_wait(sc)) == SMB_ENOERR)
+       if ((error = alpm_wait(sc)) == SMB_ENOERR)
                *byte = ALPM_SMBINB(sc, SMBHDATA);
 
        ALPM_DEBUG(kprintf("alpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
@@ -537,13 +465,13 @@ alsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
 }
 
 static int
-alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
+alpm_writew(device_t dev, u_char slave, char cmd, short word)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
@@ -553,7 +481,7 @@ alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
        ALPM_SMBOUTB(sc, SMBHCMD, cmd);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       error = alsmb_wait(sc);
+       error = alpm_wait(sc);
 
        ALPM_DEBUG(kprintf("alpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
 
@@ -561,14 +489,14 @@ alsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
 }
 
 static int
-alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
+alpm_readw(device_t dev, u_char slave, char cmd, short *word)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        int error;
        u_char high, low;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
@@ -576,7 +504,7 @@ alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
        ALPM_SMBOUTB(sc, SMBHCMD, cmd);
        ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-       if ((error = alsmb_wait(sc)) == SMB_ENOERR) {
+       if ((error = alpm_wait(sc)) == SMB_ENOERR) {
                low = ALPM_SMBINB(sc, SMBHDATA);
                high = ALPM_SMBINB(sc, SMBHDATB);
 
@@ -589,14 +517,14 @@ alsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
 }
 
 static int
-alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        u_char remain, len, i;
        int error = SMB_ENOERR;
 
-       alsmb_clear(sc);
-       if(!alsmb_idle(sc))
+       alpm_clear(sc);
+       if(!alpm_idle(sc))
                return (SMB_EBUSY);
 
        remain = count;
@@ -604,7 +532,7 @@ alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                len = min(remain, 32);
 
                ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
-       
+
                /* set the cmd and reset the
                 * 32-byte long internal buffer */
                ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
@@ -619,7 +547,7 @@ alsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                ALPM_SMBOUTB(sc, SMBHCMD, cmd);
                ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-               if ((error = alsmb_wait(sc)) != SMB_ENOERR)
+               if ((error = alpm_wait(sc)) != SMB_ENOERR)
                        goto error;
 
                remain -= len;
@@ -632,20 +560,20 @@ error:
 }
 
 static int
-alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+alpm_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
 {
-       struct alsmb_softc *sc = (struct alsmb_softc *)device_get_softc(dev);
+       struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
        u_char remain, len, i;
        int error = SMB_ENOERR;
 
-       alsmb_clear(sc);
-       if (!alsmb_idle(sc))
+       alpm_clear(sc);
+       if (!alpm_idle(sc))
                return (SMB_EBUSY);
 
        remain = count;
        while (remain) {
                ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
-       
+
                /* set the cmd and reset the
                 * 32-byte long internal buffer */
                ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
@@ -653,7 +581,7 @@ alsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                ALPM_SMBOUTB(sc, SMBHCMD, cmd);
                ALPM_SMBOUTB(sc, SMBSTART, 0xff);
 
-               if ((error = alsmb_wait(sc)) != SMB_ENOERR)
+               if ((error = alpm_wait(sc)) != SMB_ENOERR)
                        goto error;
 
                len = ALPM_SMBINB(sc, SMBHDATA);
@@ -672,5 +600,36 @@ error:
        return (error);
 }
 
-DRIVER_MODULE(alpm, pci, alpm_pci_driver, alpm_devclass, 0, 0);
-DRIVER_MODULE(alsmb, alpm, alsmb_driver, alsmb_devclass, 0, 0);
+static devclass_t alpm_devclass;
+
+static device_method_t alpm_methods[] = {
+       /* device interface */
+       DEVMETHOD(device_probe,         alpm_probe),
+       DEVMETHOD(device_attach,        alpm_attach),
+       DEVMETHOD(device_detach,        alpm_detach),
+
+       /* smbus interface */
+       DEVMETHOD(smbus_callback,       alpm_callback),
+       DEVMETHOD(smbus_quick,          alpm_quick),
+       DEVMETHOD(smbus_sendb,          alpm_sendb),
+       DEVMETHOD(smbus_recvb,          alpm_recvb),
+       DEVMETHOD(smbus_writeb,         alpm_writeb),
+       DEVMETHOD(smbus_readb,          alpm_readb),
+       DEVMETHOD(smbus_writew,         alpm_writew),
+       DEVMETHOD(smbus_readw,          alpm_readw),
+       DEVMETHOD(smbus_bwrite,         alpm_bwrite),
+       DEVMETHOD(smbus_bread,          alpm_bread),
+
+       { 0, 0 }
+};
+
+static driver_t alpm_driver = {
+       "alpm",
+       alpm_methods,
+       sizeof(struct alpm_softc)
+};
+
+DRIVER_MODULE(alpm, pci, alpm_driver, alpm_devclass, 0, 0);
+MODULE_DEPEND(alpm, pci, 1, 1, 1);
+MODULE_DEPEND(alpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(alpm, 1);
diff --git a/sys/dev/powermng/amdpm/Makefile b/sys/dev/powermng/amdpm/Makefile
new file mode 100644 (file)
index 0000000..8fa6d69
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/amdpm/Makefile,v 1.1 2002/03/23 15:48:41 nsouch Exp $
+
+.PATH:         ${.CURDIR}/../../../../bus/pci
+KMOD           = amdpm
+SRCS           = device_if.h bus_if.h pci_if.h smbus_if.h \
+                 amdpm.c
+
+.include <bsd.kmod.mk>
similarity index 63%
rename from sys/dev/powermng/i386/amdpm/amdpm.c
rename to sys/dev/powermng/amdpm/amdpm.c
index df95023..6062835 100644 (file)
@@ -27,8 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/pci/amdpm.c,v 1.1.2.1 2001/10/10 12:10:26 murray Exp $
- * $DragonFly: src/sys/dev/powermng/i386/amdpm/amdpm.c,v 1.7 2006/12/22 23:26:23 swildner Exp $
+ * $FreeBSD: src/sys/pci/amdpm.c,v 1.10 2003/09/06 13:56:56 dfr Exp $
  *
  */
 
@@ -63,9 +62,17 @@ static int amdpm_debug = 0;
 
 #define AMDPM_VENDORID_AMD 0x1022
 #define AMDPM_DEVICEID_AMD756PM 0x740b
+#define AMDPM_DEVICEID_AMD766PM 0x7413
+#define AMDPM_DEVICEID_AMD768PM 0x7443
+
+/* nVidia nForce chipset */
+#define AMDPM_VENDORID_NVIDIA 0x10de
+#define AMDPM_DEVICEID_NF_SMB 0x01b4
+
 
 /* PCI Configuration space registers */
 #define AMDPCI_PMBASE 0x58
+#define NFPCI_PMBASE  0x14
 
 #define AMDPCI_GEN_CONFIG_PM 0x41
 #define AMDPCI_PMIOEN (1<<7)
@@ -79,7 +86,8 @@ static int amdpm_debug = 0;
  * I/O registers.
  * Base address programmed via AMDPCI_PMBASE.
  */
-#define AMDSMB_GLOBAL_STATUS 0xE0
+
+#define AMDSMB_GLOBAL_STATUS (0x00)
 #define AMDSMB_GS_TO_STS (1<<5)
 #define AMDSMB_GS_HCYC_STS (1<<4)
 #define AMDSMB_GS_HST_STS (1<<3)
@@ -88,7 +96,7 @@ static int amdpm_debug = 0;
 #define AMDSMB_GS_ABRT_STS (1<<0)
 #define AMDSMB_GS_CLEAR_STS (AMDSMB_GS_TO_STS|AMDSMB_GS_HCYC_STS|AMDSMB_GS_PRERR_STS|AMDSMB_GS_COL_STS|AMDSMB_GS_ABRT_STS)
 
-#define AMDSMB_GLOBAL_ENABLE 0xE2
+#define AMDSMB_GLOBAL_ENABLE (0x02)
 #define AMDSMB_GE_ABORT (1<<5)
 #define AMDSMB_GE_HCYC_EN (1<<4)
 #define AMDSMB_GE_HOST_STC (1<<3)
@@ -99,73 +107,76 @@ static int amdpm_debug = 0;
 #define AMDSMB_GE_CYC_PROCCALL 4
 #define AMDSMB_GE_CYC_BLOCK 5
 
-#define AMDSMB_HSTADDR 0xE4
-#define AMDSMB_HSTDATA 0xE6
-#define AMDSMB_HSTCMD 0xE8
-#define AMDSMB_HSTDFIFO 0xE9
-#define AMDSMB_HSLVDATA 0xEA
-#define AMDSMB_HSLVDA 0xEC
-#define AMDSMB_HSLVDDR 0xEE
-#define AMDSMB_SNPADDR 0xEF
+#define AMDSMB_HSTADDR  (0x04)
+#define AMDSMB_HSTDATA  (0x06)
+#define AMDSMB_HSTCMD   (0x08)
+#define AMDSMB_HSTDFIFO (0x09)
+#define AMDSMB_HSLVDATA (0x0A)
+#define AMDSMB_HSLVDA   (0x0C)
+#define AMDSMB_HSLVDDR  (0x0E)
+#define AMDSMB_SNPADDR  (0x0F)
 
 struct amdpm_softc {
        int base;
        int rid;
        struct resource *res;
-        bus_space_tag_t smbst;
-        bus_space_handle_t smbsh;
-};
+       bus_space_tag_t smbst;
+       bus_space_handle_t smbsh;
 
-struct amdsmb_softc {
-       int base;
        device_t smbus;
-       struct amdpm_softc *amdpm;
 };
 
-#define AMDPM_SMBINB(amdsmb,register) \
-       (bus_space_read_1(amdsmb->amdpm->smbst, amdsmb->amdpm->smbsh, register))
-#define AMDPM_SMBOUTB(amdsmb,register,value) \
-       (bus_space_write_1(amdsmb->amdpm->smbst, amdsmb->amdpm->smbsh, register, value))
-#define AMDPM_SMBINW(amdsmb,register) \
-       (bus_space_read_2(amdsmb->amdpm->smbst, amdsmb->amdpm->smbsh, register))
-#define AMDPM_SMBOUTW(amdsmb,register,value) \
-       (bus_space_write_2(amdsmb->amdpm->smbst, amdsmb->amdpm->smbsh, register, value))
-
-static int amdsmb_probe(device_t);
-static int amdsmb_attach(device_t);
-static int amdsmb_smb_callback(device_t, int, caddr_t *);
-static int amdsmb_smb_quick(device_t dev, u_char slave, int how);
-static int amdsmb_smb_sendb(device_t dev, u_char slave, char byte);
-static int amdsmb_smb_recvb(device_t dev, u_char slave, char *byte);
-static int amdsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte);
-static int amdsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte);
-static int amdsmb_smb_writew(device_t dev, u_char slave, char cmd, short word);
-static int amdsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word);
-static int amdsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
-static int amdsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *byte);
-
-static int amdpm_probe(device_t);
-static int amdpm_attach(device_t);
-
+#define AMDPM_SMBINB(amdpm,register) \
+       (bus_space_read_1(amdpm->smbst, amdpm->smbsh, register))
+#define AMDPM_SMBOUTB(amdpm,register,value) \
+       (bus_space_write_1(amdpm->smbst, amdpm->smbsh, register, value))
+#define AMDPM_SMBINW(amdpm,register) \
+       (bus_space_read_2(amdpm->smbst, amdpm->smbsh, register))
+#define AMDPM_SMBOUTW(amdpm,register,value) \
+       (bus_space_write_2(amdpm->smbst, amdpm->smbsh, register, value))
 
 static int
 amdpm_probe(device_t dev)
 {
        u_long base;
-       
-       if ((pci_get_vendor(dev) == AMDPM_VENDORID_AMD) &&
-           (pci_get_device(dev) == AMDPM_DEVICEID_AMD756PM)) {
-             device_set_desc(dev, "AMD 756 Power Management Controller");
-             
-             /* 
+       u_int16_t vid;
+       u_int16_t did;
+
+       vid = pci_get_vendor(dev);
+       did = pci_get_device(dev);
+       if ((vid == AMDPM_VENDORID_AMD) &&
+           ((did == AMDPM_DEVICEID_AMD756PM) ||
+            (did == AMDPM_DEVICEID_AMD766PM) ||
+            (did == AMDPM_DEVICEID_AMD768PM))) {
+             device_set_desc(dev, "AMD 756/766/768 Power Management Controller");
+
+             /*
               * We have to do this, since the BIOS won't give us the
               * resource info (not mine, anyway).
               */
              base = pci_read_config(dev, AMDPCI_PMBASE, 4);
              base &= 0xff00;
-             bus_set_resource(dev, SYS_RES_IOPORT, AMDPCI_PMBASE, base, 256);
+             bus_set_resource(dev, SYS_RES_IOPORT, AMDPCI_PMBASE,
+                              base+0xe0, 32);
              return (0);
        }
+
+       if ((vid == AMDPM_VENDORID_NVIDIA) &&
+           (did == AMDPM_DEVICEID_NF_SMB)) {
+               device_set_desc(dev, "nForce SMBus Controller");
+
+               /*
+                * We have to do this, since the BIOS won't give us the
+                * resource info (not mine, anyway).
+                */
+               base = pci_read_config(dev, NFPCI_PMBASE, 4);
+               base &= 0xff00;
+               bus_set_resource(dev, SYS_RES_IOPORT, NFPCI_PMBASE,
+                                base, 32);
+
+               return (0);
+       }
+
        return ENXIO;
 }
 
@@ -174,65 +185,55 @@ amdpm_attach(device_t dev)
 {
        struct amdpm_softc *amdpm_sc = device_get_softc(dev);
        u_char val_b;
-       int unit = device_get_unit(dev);
-       device_t smbinterface;
-       
+
        /* Enable I/O block access */
        val_b = pci_read_config(dev, AMDPCI_GEN_CONFIG_PM, 1);
        pci_write_config(dev, AMDPCI_GEN_CONFIG_PM, val_b | AMDPCI_PMIOEN, 1);
 
        /* Allocate I/O space */
-       amdpm_sc->rid = AMDPCI_PMBASE;
+       if (pci_get_vendor(dev) == AMDPM_VENDORID_AMD)
+               amdpm_sc->rid = AMDPCI_PMBASE;
+       else
+               amdpm_sc->rid = NFPCI_PMBASE;
        amdpm_sc->res = bus_alloc_resource(dev, SYS_RES_IOPORT, &amdpm_sc->rid, 0, ~0, 1, RF_ACTIVE);
-       
+
        if (amdpm_sc->res == NULL) {
                device_printf(dev, "could not map i/o space\n");
                return (ENXIO);
-       }            
+       }
 
        amdpm_sc->smbst = rman_get_bustag(amdpm_sc->res);
        amdpm_sc->smbsh = rman_get_bushandle(amdpm_sc->res);
-       
-       smbinterface = device_add_child(dev, "amdsmb", unit);
-       if (!smbinterface)
-               device_printf(dev, "could not add SMBus device\n");
-       else
-               device_probe_and_attach(smbinterface);
-
-       return (0);
-}
-
-static int
-amdsmb_probe(device_t dev)
-{
-       struct amdsmb_softc *amdsmb_sc = (struct amdsmb_softc *)device_get_softc(dev);
 
        /* Allocate a new smbus device */
-       amdsmb_sc->smbus = smbus_alloc_bus(dev);
-       if (!amdsmb_sc->smbus)
-               return (EINVAL);
+       amdpm_sc->smbus = device_add_child(dev, "smbus", -1);
+       if (!amdpm_sc->smbus)
+         return (EINVAL);
 
-       device_set_desc(dev, "AMD 756 SMBus interface");
-       device_printf(dev, "AMD 756 SMBus interface\n");
+       bus_generic_attach(dev);
 
        return (0);
 }
 
 static int
-amdsmb_attach(device_t dev)
+amdpm_detach(device_t dev)
 {
-       struct amdsmb_softc *amdsmb_sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *amdpm_sc = device_get_softc(dev);
 
-       amdsmb_sc->amdpm = device_get_softc(device_get_parent(dev));
-       
-       /* Probe and attach the smbus */
-       device_probe_and_attach(amdsmb_sc->smbus);
+       if (amdpm_sc->smbus) {
+         device_delete_child(dev, amdpm_sc->smbus);
+         amdpm_sc->smbus = NULL;
+       }
+
+       if (amdpm_sc->res)
+         bus_release_resource(dev, SYS_RES_IOPORT, amdpm_sc->rid,
+                                       amdpm_sc->res);
 
        return (0);
 }
 
 static int
-amdsmb_smb_callback(device_t dev, int index, caddr_t *data)
+amdpm_callback(device_t dev, int index, caddr_t *data)
 {
        int error = 0;
 
@@ -248,7 +249,7 @@ amdsmb_smb_callback(device_t dev, int index, caddr_t *data)
 }
 
 static int
-amdsmb_clear(struct amdsmb_softc *sc)
+amdpm_clear(struct amdpm_softc *sc)
 {
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_STATUS, AMDSMB_GS_CLEAR_STS);
        DELAY(10);
@@ -258,10 +259,10 @@ amdsmb_clear(struct amdsmb_softc *sc)
 
 #if 0
 static int
-amdsmb_abort(struct amdsmb_softc *sc)
+amdpm_abort(struct amdpm_softc *sc)
 {
        u_short l;
-       
+
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, l | AMDSMB_GE_ABORT);
 
@@ -270,7 +271,7 @@ amdsmb_abort(struct amdsmb_softc *sc)
 #endif
 
 static int
-amdsmb_idle(struct amdsmb_softc *sc)
+amdpm_idle(struct amdpm_softc *sc)
 {
        u_short sts;
 
@@ -285,7 +286,7 @@ amdsmb_idle(struct amdsmb_softc *sc)
  * Poll the SMBus controller
  */
 static int
-amdsmb_wait(struct amdsmb_softc *sc)
+amdpm_wait(struct amdpm_softc *sc)
 {
        int count = 10000;
        u_short sts = 0;
@@ -316,20 +317,20 @@ amdsmb_wait(struct amdsmb_softc *sc)
                error |= SMB_EBUSERR;
 
        if (error != SMB_ENOERR)
-               amdsmb_clear(sc);
+               amdpm_clear(sc);
 
        return (error);
 }
 
 static int
-amdsmb_smb_quick(device_t dev, u_char slave, int how)
+amdpm_quick(device_t dev, u_char slave, int how)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (EBUSY);
 
        switch (how) {
@@ -347,7 +348,7 @@ amdsmb_smb_quick(device_t dev, u_char slave, int how)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_QUICK | AMDSMB_GE_HOST_STC);
 
-       error = amdsmb_wait(sc);
+       error = amdpm_wait(sc);
 
        AMDPM_DEBUG(kprintf(", error=0x%x\n", error));
 
@@ -355,14 +356,14 @@ amdsmb_smb_quick(device_t dev, u_char slave, int how)
 }
 
 static int
-amdsmb_smb_sendb(device_t dev, u_char slave, char byte)
+amdpm_sendb(device_t dev, u_char slave, char byte)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave & ~LSB);
@@ -370,7 +371,7 @@ amdsmb_smb_sendb(device_t dev, u_char slave, char byte)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BYTE | AMDSMB_GE_HOST_STC);
 
-       error = amdsmb_wait(sc);
+       error = amdpm_wait(sc);
 
        AMDPM_DEBUG(kprintf("amdpm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
 
@@ -378,21 +379,21 @@ amdsmb_smb_sendb(device_t dev, u_char slave, char byte)
 }
 
 static int
-amdsmb_smb_recvb(device_t dev, u_char slave, char *byte)
+amdpm_recvb(device_t dev, u_char slave, char *byte)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB);
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BYTE | AMDSMB_GE_HOST_STC);
 
-       if ((error = amdsmb_wait(sc)) == SMB_ENOERR)
+       if ((error = amdpm_wait(sc)) == SMB_ENOERR)
                *byte = AMDPM_SMBINW(sc, AMDSMB_HSTDATA);
 
        AMDPM_DEBUG(kprintf("amdpm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
@@ -401,14 +402,14 @@ amdsmb_smb_recvb(device_t dev, u_char slave, char *byte)
 }
 
 static int
-amdsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
+amdpm_writeb(device_t dev, u_char slave, char cmd, char byte)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave & ~LSB);
@@ -417,7 +418,7 @@ amdsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BDATA | AMDSMB_GE_HOST_STC);
 
-       error = amdsmb_wait(sc);
+       error = amdpm_wait(sc);
 
        AMDPM_DEBUG(kprintf("amdpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
 
@@ -425,14 +426,14 @@ amdsmb_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
 }
 
 static int
-amdsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
+amdpm_readb(device_t dev, u_char slave, char cmd, char *byte)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB);
@@ -440,7 +441,7 @@ amdsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BDATA | AMDSMB_GE_HOST_STC);
 
-       if ((error = amdsmb_wait(sc)) == SMB_ENOERR)
+       if ((error = amdpm_wait(sc)) == SMB_ENOERR)
                *byte = AMDPM_SMBINW(sc, AMDSMB_HSTDATA);
 
        AMDPM_DEBUG(kprintf("amdpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
@@ -449,14 +450,14 @@ amdsmb_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
 }
 
 static int
-amdsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
+amdpm_writew(device_t dev, u_char slave, char cmd, short word)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave & ~LSB);
@@ -465,7 +466,7 @@ amdsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_WDATA | AMDSMB_GE_HOST_STC);
 
-       error = amdsmb_wait(sc);
+       error = amdpm_wait(sc);
 
        AMDPM_DEBUG(kprintf("amdpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
 
@@ -473,14 +474,14 @@ amdsmb_smb_writew(device_t dev, u_char slave, char cmd, short word)
 }
 
 static int
-amdsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
+amdpm_readw(device_t dev, u_char slave, char cmd, short *word)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        int error;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB);
@@ -488,7 +489,7 @@ amdsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
        l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
        AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_WDATA | AMDSMB_GE_HOST_STC);
 
-       if ((error = amdsmb_wait(sc)) == SMB_ENOERR)
+       if ((error = amdpm_wait(sc)) == SMB_ENOERR)
                *word = AMDPM_SMBINW(sc, AMDSMB_HSTDATA);
 
        AMDPM_DEBUG(kprintf("amdpm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
@@ -497,15 +498,15 @@ amdsmb_smb_readw(device_t dev, u_char slave, char cmd, short *word)
 }
 
 static int
-amdsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+amdpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        u_char remain, len, i;
        int error = SMB_ENOERR;
        u_short l;
 
-       amdsmb_clear(sc);
-       if(!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if(!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        remain = count;
@@ -513,7 +514,7 @@ amdsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                len = min(remain, 32);
 
                AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave & ~LSB);
-       
+
                /*
                 * Do we have to reset the internal 32-byte buffer?
                 * Can't see how to do this from the data sheet.
@@ -530,7 +531,7 @@ amdsmb_smb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
                AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BLOCK | AMDSMB_GE_HOST_STC);
 
-               if ((error = amdsmb_wait(sc)) != SMB_ENOERR)
+               if ((error = amdpm_wait(sc)) != SMB_ENOERR)
                        goto error;
 
                remain -= len;
@@ -543,27 +544,27 @@ error:
 }
 
 static int
-amdsmb_smb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+amdpm_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
 {
-       struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
+       struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev);
        u_char remain, len, i;
        int error = SMB_ENOERR;
        u_short l;
 
-       amdsmb_clear(sc);
-       if (!amdsmb_idle(sc))
+       amdpm_clear(sc);
+       if (!amdpm_idle(sc))
                return (SMB_EBUSY);
 
        remain = count;
        while (remain) {
                AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB);
-       
+
                AMDPM_SMBOUTB(sc, AMDSMB_HSTCMD, cmd);
 
                l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
                AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, (l & 0xfff8) | AMDSMB_GE_CYC_BLOCK | AMDSMB_GE_HOST_STC);
-               
-               if ((error = amdsmb_wait(sc)) != SMB_ENOERR)
+
+               if ((error = amdpm_wait(sc)) != SMB_ENOERR)
                        goto error;
 
                len = AMDPM_SMBINW(sc, AMDSMB_HSTDATA);
@@ -588,7 +589,20 @@ static device_method_t amdpm_methods[] = {
        /* Device interface */
        DEVMETHOD(device_probe,         amdpm_probe),
        DEVMETHOD(device_attach,        amdpm_attach),
-       
+       DEVMETHOD(device_detach,        amdpm_detach),
+
+       /* SMBus interface */
+       DEVMETHOD(smbus_callback,       amdpm_callback),
+       DEVMETHOD(smbus_quick,          amdpm_quick),
+       DEVMETHOD(smbus_sendb,          amdpm_sendb),
+       DEVMETHOD(smbus_recvb,          amdpm_recvb),
+       DEVMETHOD(smbus_writeb,         amdpm_writeb),
+       DEVMETHOD(smbus_readb,          amdpm_readb),
+       DEVMETHOD(smbus_writew,         amdpm_writew),
+       DEVMETHOD(smbus_readw,          amdpm_readw),
+       DEVMETHOD(smbus_bwrite,         amdpm_bwrite),
+       DEVMETHOD(smbus_bread,          amdpm_bread),
+
        { 0, 0 }
 };
 
@@ -598,36 +612,8 @@ static driver_t amdpm_driver = {
        sizeof(struct amdpm_softc),
 };
 
-static devclass_t amdsmb_devclass;
-
-static device_method_t amdsmb_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,         amdsmb_probe),
-       DEVMETHOD(device_attach,        amdsmb_attach),
-
-       /* Bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       
-       /* SMBus interface */
-       DEVMETHOD(smbus_callback,       amdsmb_smb_callback),
-       DEVMETHOD(smbus_quick,          amdsmb_smb_quick),
-       DEVMETHOD(smbus_sendb,          amdsmb_smb_sendb),
-       DEVMETHOD(smbus_recvb,          amdsmb_smb_recvb),
-       DEVMETHOD(smbus_writeb,         amdsmb_smb_writeb),
-       DEVMETHOD(smbus_readb,          amdsmb_smb_readb),
-       DEVMETHOD(smbus_writew,         amdsmb_smb_writew),
-       DEVMETHOD(smbus_readw,          amdsmb_smb_readw),
-       DEVMETHOD(smbus_bwrite,         amdsmb_smb_bwrite),
-       DEVMETHOD(smbus_bread,          amdsmb_smb_bread),
-       
-       { 0, 0 }
-};
-
-static driver_t amdsmb_driver = {
-       "amdsmb",
-       amdsmb_methods,
-       sizeof(struct amdsmb_softc),
-};
-
 DRIVER_MODULE(amdpm, pci, amdpm_driver, amdpm_devclass, 0, 0);
-DRIVER_MODULE(amdsmb, amdpm, amdsmb_driver, amdsmb_devclass, 0, 0);
+
+MODULE_DEPEND(amdpm, pci, 1, 1, 1);
+MODULE_DEPEND(amdpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(amdpm, 1);
diff --git a/sys/dev/powermng/i386/intpm/intpm.c b/sys/dev/powermng/i386/intpm/intpm.c
deleted file mode 100644 (file)
index 8a695b2..0000000
+++ /dev/null
@@ -1,749 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Takanori Watanabe
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *        notice, this list of conditions and the following disclaimer in the
- *        documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.    IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pci/intpm.c,v 1.16.2.1 2001/12/23 08:17:47 pirzyk Exp $
- * $DragonFly: src/sys/dev/powermng/i386/intpm/intpm.c,v 1.11 2006/12/22 23:26:23 swildner Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/uio.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/rman.h>
-#include <sys/thread2.h>
-
-#include <machine/clock.h>
-
-#include <bus/smbus/smbconf.h>
-
-#include "smbus_if.h"
-
-/*This should be removed if force_pci_map_int supported*/
-#include <sys/interrupt.h>
-
-#include <bus/pci/pcireg.h>
-#include <bus/pci/pcivar.h>
-#include "intpmreg.h"
-
-#include "opt_intpm.h"
-
-static struct _pcsid
-{
-        pcidi_t type;
-       char    *desc;
-} pci_ids[] =
-{
-       { 0x71138086,"Intel 82371AB Power management controller"},
-       { 0x719b8086,"Intel 82443MX Power management controller"},
-       { 0x00000000,   NULL                                    }
-};
-static int intsmb_probe(device_t);
-static int intsmb_attach(device_t);
-
-static int intsmb_intr(device_t dev);
-static int intsmb_slvintr(device_t dev);
-static void  intsmb_alrintr(device_t dev);
-static int intsmb_callback(device_t dev, int index, caddr_t data);
-static int intsmb_quick(device_t dev, u_char slave, int how);
-static int intsmb_sendb(device_t dev, u_char slave, char byte);
-static int intsmb_recvb(device_t dev, u_char slave, char *byte);
-static int intsmb_writeb(device_t dev, u_char slave, char cmd, char byte);
-static int intsmb_writew(device_t dev, u_char slave, char cmd, short word);
-static int intsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
-static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word);
-static int intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata);
-static int intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
-static int intsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf);
-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 devclass_t intsmb_devclass;
-
-static device_method_t intpm_methods[]={
-        DEVMETHOD(device_probe,intsmb_probe),
-        DEVMETHOD(device_attach,intsmb_attach),
-
-        DEVMETHOD(bus_print_child, bus_generic_print_child),
-        
-        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),
-        {0,0}
-};
-
-struct intpm_pci_softc{
-        bus_space_tag_t smbst;
-        bus_space_handle_t smbsh;
-       bus_space_tag_t pmst;
-       bus_space_handle_t pmsh;
-        pcici_t cfg;
-       device_t  smbus;
-};
-
-
-struct intsmb_softc{
-        struct intpm_pci_softc *pci_sc;
-        bus_space_tag_t st;
-        bus_space_handle_t sh;
-        device_t smbus;
-        int isbusy;
-};
-
-static driver_t intpm_driver = {
-        "intsmb",
-        intpm_methods,
-        sizeof(struct intsmb_softc),
-};
-
-static devclass_t intpm_devclass;
-static device_method_t intpm_pci_methods[] = {
-  DEVMETHOD(device_probe,intpm_probe),
-  DEVMETHOD(device_attach,intpm_attach),
-  {0,0}
-};
-static driver_t intpm_pci_driver = {
-  "intpm",
-  intpm_pci_methods,
-  sizeof(struct intpm_pci_softc)
-};
-
-static int 
-intsmb_probe(device_t dev)
-{
-        struct intsmb_softc *sc =(struct intsmb_softc *) device_get_softc(dev);
-        sc->smbus=smbus_alloc_bus(dev);
-        if (!sc->smbus)
-                return (EINVAL);    /* XXX don't know what to return else */
-        device_set_desc(dev,"Intel PIIX4 SMBUS Interface");
-        
-        return (0);          /* XXX don't know what to return else */
-}
-static int
-intsmb_attach(device_t dev)
-{
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-}
-
-static int 
-intsmb_callback(device_t dev, int index, caddr_t data)
-{
-       int error = 0;
-
-       crit_enter();
-       switch (index) {
-       case SMB_REQUEST_BUS:
-               break;
-       case SMB_RELEASE_BUS:
-               break;
-       default:
-               error = EINVAL;
-       }
-       crit_exit();
-       return (error);
-}
-/*counterpart of smbtx_smb_free*/
-static        int
-intsmb_free(device_t dev){
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        if((bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS)&
-           PIIX4_SMBHSTSTAT_BUSY)
-#ifdef ENABLE_ALART
-          ||(bus_space_read_1(sc->st,sc->sh,PIIX4_SMBSLVSTS)&
-             PIIX4_SMBSLVSTS_BUSY)
-#endif
-          || sc->isbusy)
-                return EBUSY;
-       crit_enter();
-        sc->isbusy=1;
-       /*Disable Intrrupt in slave part*/
-#ifndef ENABLE_ALART
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBSLVCNT,0);
-#endif
-        /*Reset INTR Flag to prepare INTR*/
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBHSTSTS,
-                         (PIIX4_SMBHSTSTAT_INTR|
-                          PIIX4_SMBHSTSTAT_ERR|
-                          PIIX4_SMBHSTSTAT_BUSC|
-                          PIIX4_SMBHSTSTAT_FAIL)
-               );
-       crit_exit();
-        return 0;
-}
-
-static int
-intsmb_intr(device_t dev)
-{
-       struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-       int status;
-       status=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS);
-       if(status&PIIX4_SMBHSTSTAT_BUSY){
-               return 1;
-               
-       }
-       if(status&(PIIX4_SMBHSTSTAT_INTR|
-                               PIIX4_SMBHSTSTAT_ERR|
-                               PIIX4_SMBHSTSTAT_BUSC|
-                               PIIX4_SMBHSTSTAT_FAIL)){
-               int tmp;
-               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);
-               if(sc->isbusy){
-                 sc->isbusy=0;
-                 wakeup(sc);
-               }
-               return 0;
-       }
-       return 1;/* Not Completed*/
-}
-static int
-intsmb_slvintr(device_t dev)
-{
-       struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        int status,retval;
-       retval=1;
-        status=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBSLVSTS);
-       if(status&PIIX4_SMBSLVSTS_BUSY)
-               return retval;
-       if(status&PIIX4_SMBSLVSTS_ALART){
-               intsmb_alrintr(dev);
-               retval=0;
-       }else if(status&~(PIIX4_SMBSLVSTS_ALART|PIIX4_SMBSLVSTS_SDW2
-                         |PIIX4_SMBSLVSTS_SDW1)){
-               retval=0;
-       }
-       /*Reset Status Register*/
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBSLVSTS,PIIX4_SMBSLVSTS_ALART|
-                         PIIX4_SMBSLVSTS_SDW2|PIIX4_SMBSLVSTS_SDW1|
-                         PIIX4_SMBSLVSTS_SLV);
-       return retval;
-}
-
-static void intsmb_alrintr(device_t dev)
-{
-       struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-       int slvcnt;
-#ifdef ENABLE_ALART
-       int error;
-#endif
-
-       /*stop generating INTR from ALART*/
-       slvcnt=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBSLVCNT);
-#ifdef ENABLE_ALART
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBSLVCNT,
-                         slvcnt&~PIIX4_SMBSLVCNT_ALTEN) ;
-#endif
-       DELAY(5);
-       /*ask bus who assert it and then ask it what's the matter. */   
-#ifdef ENABLE_ALART
-       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))){
-                       uint32_t addr;
-                       addr = bus_space_read_1(sc->st,sc->sh,
-                                               PIIX4_SMBHSTDAT0);
-                       kprintf("ALART_RESPONSE: %#x\n", addr);
-               }
-       }else{
-               kprintf("ERROR\n");
-       }
-
-       /*Re-enable INTR from ALART*/
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBSLVCNT,
-                         slvcnt|PIIX4_SMBSLVCNT_ALTEN) ;
-       DELAY(5);
-#endif
-
-       return;
-}
-static void
-intsmb_start(device_t dev,unsigned char cmd,int nointr)
-{
-       struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-       unsigned char tmp;
-       tmp=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTCNT);
-       tmp&= 0xe0;
-       tmp |= cmd;
-       tmp |=PIIX4_SMBHSTCNT_START;
-       /*While not in autoconfiguration Intrrupt Enabled*/
-       if(!cold||!nointr)
-               tmp |=PIIX4_SMBHSTCNT_INTREN;
-       bus_space_write_1(sc->st,sc->sh,PIIX4_SMBHSTCNT,tmp);
-}
-
-/*Polling Code. Polling is not encouraged 
- * because It is required to wait for the device get busy.
- *(29063505.pdf from Intel)
- * But during boot,intrrupt cannot be used.
- * so use polling code while in autoconfiguration.
- */
-
-static        int
-intsmb_stop_poll(device_t dev){
-        int error,i;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-       
-       /*
-        *  In smbtx driver ,Simply waiting.
-        *  This loops 100-200 times.
-        */
-       for(i=0;i<0x7fff;i++){
-                if((bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS)
-                   &PIIX4_SMBHSTSTAT_BUSY)){
-                        break;
-                }
-       }
-       for(i=0;i<0x7fff;i++){
-               int status;
-               status=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS);
-               if(!(status&PIIX4_SMBHSTSTAT_BUSY)){
-                       sc->isbusy=0;
-                       error=(status&PIIX4_SMBHSTSTAT_ERR)?EIO :
-                               (status&PIIX4_SMBHSTSTAT_BUSC)?EBUSY:
-                               (status&PIIX4_SMBHSTSTAT_FAIL)?EIO:0;
-                       if(error==0&&!(status&PIIX4_SMBHSTSTAT_INTR)){
-                               kprintf("unknown cause why?");
-                       }
-                       return error;
-               }
-       }
-       {
-         int tmp;
-         sc->isbusy=0;
-         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;
-}
-/*
- *wait for completion and return result.
- */
-static        int
-intsmb_stop(device_t dev){
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-       if(cold){
-               /*So that it can use device during probing device on SMBus.*/
-               error=intsmb_stop_poll(dev);
-               return error;
-       }else{
-               if(!tsleep(sc, PCATCH, "SMBWAI", hz/8)){
-                       int status;
-                       status=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS);
-                       if(!(status&PIIX4_SMBHSTSTAT_BUSY)){
-                               error=(status&PIIX4_SMBHSTSTAT_ERR)?EIO :
-                                       (status&PIIX4_SMBHSTSTAT_BUSC)?EBUSY:
-                                       (status&PIIX4_SMBHSTSTAT_FAIL)?EIO:0;
-                               if(error==0&&!(status&PIIX4_SMBHSTSTAT_INTR)){
-                                       kprintf("intsmb%d:unknown cause why?\n",
-                                              device_get_unit(dev));
-                               }
-#ifdef ENABLE_ALART
-                               bus_space_write_1(sc->st,sc->sh,
-                                                 PIIX4_SMBSLVCNT,PIIX4_SMBSLVCNT_ALTEN);
-#endif
-                               return error;
-                       }
-               }
-       }
-       /*Timeout Procedure*/
-       crit_enter();
-       sc->isbusy=0;
-       /*Re-enable supressed intrrupt from slave part*/
-       bus_space_write_1(sc->st,sc->sh,
-                         PIIX4_SMBSLVCNT,PIIX4_SMBSLVCNT_ALTEN);
-       crit_exit();
-        return EIO;
-}
-
-static int
-intsmb_quick(device_t dev, u_char slave, int how)
-{
-        int error=0;
-        u_char data;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        data=slave;
-       /*Quick command is part of Address, I think*/
-        switch(how){
-        case SMB_QWRITE:
-                data&=~LSB;
-               break;
-        case SMB_QREAD:
-                data|=LSB;
-                break;
-        default:
-                error=EINVAL;
-        }
-        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);
-                }
-        }
-
-        return (error);
-}
-
-static int
-intsmb_sendb(device_t dev, u_char slave, char byte)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-        }
-        return (error);
-}
-static int
-intsmb_recvb(device_t dev, u_char slave, char *byte)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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))){
-#ifdef RECV_IS_IN_CMD
-                       /*Linux SMBus stuff also troubles
-                         Because Intel's datasheet will not make clear.
-                        */
-                        *byte=bus_space_read_1(sc->st,sc->sh,
-                                              PIIX4_SMBHSTCMD);
-#else
-                        *byte=bus_space_read_1(sc->st,sc->sh,
-                                              PIIX4_SMBHSTDAT0);
-#endif
-                }
-        }
-        return (error);
-}
-static int
-intsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-        }
-        return (error);
-}
-static int
-intsmb_writew(device_t dev, u_char slave, char cmd, short word)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-        }
-        return (error);
-}
-
-static int
-intsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-                }
-        }
-        return (error);
-}
-static int
-intsmb_readw(device_t dev, u_char slave, char cmd, short *word)
-{
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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)&0xff;
-                        *word|=(bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTDAT1)&0xff)<<8;
-                }
-        }
-        return (error);
-}
-/*
- * Data sheet claims that it implements all function, but also claims
- * that it implements 7 function and not mention PCALL. So I don't know
- * whether it will work.
- */
-static int
-intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
-{
-#ifdef PROCCALL_TEST
-        int error;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        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);
-        }
-        if(!(error=intsmb_stop(dev))){
-                *rdata=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTDAT0)&0xff;
-                *rdata|=(bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTDAT1)&0xff)<<8;
-        }
-        return error;
-#else
-       return 0;
-#endif
-}
-static int
-intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
-{
-        int error,i;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        error=intsmb_free(dev);
-        if(count>SMBBLOCKTRANS_MAX||count==0)
-                error=EINVAL;
-        if(!error){
-                /*Reset internal array index*/
-                bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTCNT);
-               
-                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);
-        }
-        return (error);
-}
-
-static int
-intsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
-{
-        int error,i;
-        struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
-        error=intsmb_free(dev);
-        if(count>SMBBLOCKTRANS_MAX||count==0)
-                error=EINVAL;
-        if(!error){
-                /*Reset internal array index*/
-                bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTCNT);
-               
-                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){
-                        bzero(buf,count);/*Is it needed?*/
-                        count= bus_space_read_1(sc->st,sc->sh,
-                                               PIIX4_SMBHSTDAT0);
-                        if(count!=0&&count<=SMBBLOCKTRANS_MAX){
-                               for(i=0;i<count;i++){
-                                       buf[i]=bus_space_read_1(sc->st,
-                                                               sc->sh,
-                                                               PIIX4_SMBBLKDAT);
-                               }
-                       }
-                        else{
-                               error=EIO;
-                        }
-               }
-       }
-        return (error);
-}
-
-DRIVER_MODULE(intsmb, intpm , intpm_driver, intsmb_devclass, 0, 0);
-
-
-static void intpm_intr (void *arg);
-static int
-intpm_attach(device_t dev)
-{
-        int value;
-        int unit=device_get_unit(dev);
-       void *ih;
-       int error;
-        char * str;
-        {
-                struct intpm_pci_softc *sciic;
-                device_t smbinterface;
-               int rid;
-               struct resource *res;
-
-                sciic=device_get_softc(dev);
-                if(sciic==NULL){
-                        return ENOMEM;
-                }
-
-               rid=PCI_BASE_ADDR_SMB;
-               res=bus_alloc_resource(dev,SYS_RES_IOPORT,&rid,
-                                      0,~0,1,RF_ACTIVE);
-               if(res==NULL){
-                 device_printf(dev,"Could not allocate Bus space\n");
-                 return ENXIO;
-               }
-               sciic->smbst=rman_get_bustag(res);
-               sciic->smbsh=rman_get_bushandle(res);
-               
-               device_printf(dev,"%s %x\n",
-                             (sciic->smbst==I386_BUS_SPACE_IO)?
-                             "I/O mapped":"Memory",
-                             sciic->smbsh);
-               
-
-#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);
-                kprintf("revision %d\n",value);                
-                /*
-                 * Install intr HANDLER here
-                 */
-               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, 0,
-                                      (driver_intr_t *)intpm_intr, sciic,
-                                      &ih, NULL);
-                if(error){
-                        device_printf(dev,"Failed to map intr\n");
-                       return error;
-                }
-                smbinterface=device_add_child(dev,"intsmb",unit);
-               if(!smbinterface){
-                    kprintf("intsmb%d:could not add SMBus device\n",unit);
-               }
-                device_probe_and_attach(smbinterface);
-        }
-             
-        value=pci_read_config(dev,PCI_BASE_ADDR_PM,4);
-        kprintf("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;
-    u_int32_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 0;
-    }else{
-      return ENXIO;
-    }
-}
-DRIVER_MODULE(intpm, pci , intpm_pci_driver, intpm_devclass, 0, 0);
-
-static void intpm_intr(void *arg)
-{
-        struct intpm_pci_softc *sc;
-        sc=(struct intpm_pci_softc *)arg;
-       intsmb_intr(sc->smbus);
-       intsmb_slvintr(sc->smbus);
-       
-}
diff --git a/sys/dev/powermng/i386/intpm/intpmreg.h b/sys/dev/powermng/i386/intpm/intpmreg.h
deleted file mode 100644 (file)
index 261a1a4..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1998, 1999 Takanori Watanabe
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *        notice, this list of conditions and the following disclaimer in the
- *        documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.    IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pci/intpmreg.h,v 1.2 1999/08/28 00:51:01 peter Exp $
- * $DragonFly: src/sys/dev/powermng/i386/intpm/intpmreg.h,v 1.2 2003/06/17 04:28:57 dillon Exp $
- */
-
-/*Register Difinition for Intel Chipset with ACPI Support*/
-#define PCI_BASE_ADDR_SMB 0x90  /*Where to MAP IO*/
-#define PCI_BASE_ADDR_PM 0x40
-#define PCI_HST_CFG_SMB 0xd2  /*Host Configuration*/
-#define PCI_INTR_SMB_SMI 0
-#define PCI_INTR_SMB_IRQ9 8
-#define PCI_INTR_SMB_ENABLE 1
-#define PCI_SLV_CMD_SMB 0xd3 /*SLAVE COMMAND*/
-#define PCI_SLV_SDW_SMB_1 0xd4 /*SLAVE SHADOW PORT 1*/
-#define PCI_SLV_SDW_SMB_2 0xd5 /*SLAVE SHADOW PORT 2*/
-#define PCI_REVID_SMB 0xd6
-#define LSB 0x1
-#define PIIX4_SMBHSTSTS 0x00
-#define PIIX4_SMBHSTSTAT_BUSY (1<<0)
-#define PIIX4_SMBHSTSTAT_INTR (1<<1)
-#define PIIX4_SMBHSTSTAT_ERR (1<<2)
-#define PIIX4_SMBHSTSTAT_BUSC (1<<3)
-#define PIIX4_SMBHSTSTAT_FAIL (1<<4)
-#define PIIX4_SMBSLVSTS 0x01
-#define PIIX4_SMBSLVSTS_ALART (1<<5)
-#define PIIX4_SMBSLVSTS_SDW2 (1<<4)
-#define PIIX4_SMBSLVSTS_SDW1 (1<<3)
-#define PIIX4_SMBSLVSTS_SLV (1<<2)
-#define PIIX4_SMBSLVSTS_BUSY (1<<0)
-#define PIIX4_SMBHSTCNT 0x02
-#define PIIX4_SMBHSTCNT_START (1<<6)
-#define PIIX4_SMBHSTCNT_PROT_QUICK 0
-#define PIIX4_SMBHSTCNT_PROT_BYTE (1<<2)
-#define PIIX4_SMBHSTCNT_PROT_BDATA (2<<2)
-#define PIIX4_SMBHSTCNT_PROT_WDATA (3<<2)
-#define PIIX4_SMBHSTCNT_PROT_BLOCK (5<<2)
-#define SMBBLOCKTRANS_MAX 32
-#define PIIX4_SMBHSTCNT_KILL (1<<1)
-#define PIIX4_SMBHSTCNT_INTREN (1)
-#define PIIX4_SMBHSTCMD 0x03
-#define PIIX4_SMBHSTADD 0x04
-#define PIIX4_SMBHSTDAT0 0x05
-#define PIIX4_SMBHSTDAT1 0x06
-#define PIIX4_SMBBLKDAT 0x07
-#define PIIX4_SMBSLVCNT 0x08
-#define PIIX4_SMBSLVCNT_ALTEN (1<<3)
-#define PIIX4_SMBSLVCNT_SD2EN (1<<2)
-#define PIIX4_SMBSLVCNT_SD1EN (1<<1)
-#define PIIX4_SMBSLVCNT_SLVEN (1)
-#define PIIX4_SMBSLVCMD 0x09
-#define PIIX4_SMBSLVEVT 0x0a
-#define PIIX4_SMBSLVDAT 0x0c
-/*This is SMBus alart response address*/
-#define SMBALTRESP 0x18
diff --git a/sys/dev/powermng/ichsmb/Makefile b/sys/dev/powermng/ichsmb/Makefile
new file mode 100644 (file)
index 0000000..456442f
--- /dev/null
@@ -0,0 +1,8 @@
+#$FreeBSD: src/sys/modules/i2c/controllers/ichsmb/Makefile,v 1.1 2005/06/05 11:55:29 takawata Exp $
+
+.PATH:         ${.CURDIR}/..
+KMOD           = ichsmb
+SRCS           = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \
+                 ichsmb.c ichsmb_pci.c ichsmb_reg.h ichsmb_var.h
+
+.include <bsd.kmod.mk>
index 2bd8083..c3edd37 100644 (file)
@@ -1,10 +1,10 @@
-
-/*
+/*-
  * ichsmb.c
  *
+ * Author: Archie Cobbs <archie@freebsd.org>
  * Copyright (c) 2000 Whistle Communications, Inc.
  * All rights reserved.
- * 
+ *
  * Subject to the following obligations and disclaimer of warranty, use and
  * redistribution of this software, in source or object code forms, with or
  * without modifications are expressly permitted by Whistle Communications;
@@ -15,7 +15,7 @@
  *    Communications, Inc. trademarks, including the mark "WHISTLE
  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
  *    such appears in the above copyright notice or in the software.
- * 
+ *
  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
- * Author: Archie Cobbs <archie@freebsd.org>
- *
- * $FreeBSD: src/sys/dev/ichsmb/ichsmb.c,v 1.1.2.1 2000/10/09 00:52:43 archie Exp $
- * $DragonFly: src/sys/dev/powermng/ichsmb/ichsmb.c,v 1.7 2006/10/25 20:56:00 dillon Exp $
+ * $FreeBSD: src/sys/dev/ichsmb/ichsmb.c,v 1.20 2009/02/03 16:14:37 jhb Exp $
  */
 
 /*
  * Support for the SMBus controller logical device which is part of the
  * Intel 81801AA (ICH) and 81801AB (ICH0) I/O controller hub chips.
+ *
+ * This driver assumes that the generic SMBus code will ensure that
+ * at most one process at a time calls into the SMBus methods below.
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/errno.h>
+#include <sys/globaldata.h>
+#include <sys/lock.h>
+#include <sys/module.h>
 #include <sys/syslog.h>
 #include <sys/bus.h>
+
 #include <sys/rman.h>
-#include <sys/thread2.h>
 
 #include <bus/smbus/smbconf.h>
 
-#include "ichsmb_var.h"
-#include "ichsmb_reg.h"
+#include <dev/powermng/ichsmb/ichsmb_var.h>
+#include <dev/powermng/ichsmb/ichsmb_reg.h>
 
 /*
  * Enable debugging by defining ICHSMB_DEBUG to a non-zero value.
  */
 #define ICHSMB_DEBUG   0
-#if ICHSMB_DEBUG != 0 && defined(__GNUC__)
+#if ICHSMB_DEBUG != 0 && defined(__CC_SUPPORTS___FUNC__)
 #define DBG(fmt, args...)      \
-       do { log(LOG_DEBUG, "%s: " fmt, __func__ , ## args); } while (0)
+       do { printf("%s: " fmt, __func__ , ## args); } while (0)
 #else
 #define DBG(fmt, args...)      do { } while (0)
 #endif
@@ -91,15 +94,7 @@ static int ichsmb_wait(sc_p sc);
 int
 ichsmb_probe(device_t dev)
 {
-       device_t smb;
-
-       /* Add child: an instance of the "smbus" device */
-       if ((smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) {
-               log(LOG_ERR, "%s: no \"%s\" child found\n",
-                   device_get_nameunit(dev), DRIVER_SMBUS);
-               return (ENXIO);
-       }
-       return (0);
+       return (BUS_PROBE_DEFAULT);
 }
 
 /*
@@ -112,17 +107,37 @@ ichsmb_attach(device_t dev)
        const sc_p sc = device_get_softc(dev);
        int error;
 
+       /* Create mutex */
+       lockinit(&sc->mutex, "ichsmb", 0, LK_CANRECURSE);
+
+       /* Add child: an instance of the "smbus" device */
+       if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) {
+               device_printf(dev, "no \"%s\" child found\n", DRIVER_SMBUS);
+               error = ENXIO;
+               goto fail;
+       }
+
        /* Clear interrupt conditions */
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_STA, 0xff);
+       bus_write_1(sc->io_res, ICH_HST_STA, 0xff);
+
+       /* Set up interrupt handler */
+       error = bus_setup_intr(dev, sc->irq_res, 0,
+           ichsmb_device_intr, sc, &sc->irq_handle, NULL);
+       if (error != 0) {
+               device_printf(dev, "can't setup irq\n");
+               goto fail;
+       }
 
-       /* Add "smbus" child */
+       /* Attach "smbus" child */
        if ((error = bus_generic_attach(dev)) != 0) {
-               log(LOG_ERR, "%s: failed to attach child: %d\n",
-                   device_get_nameunit(dev), error);
-               error = ENXIO;
+               device_printf(dev, "failed to attach child: %d\n", error);
+               goto fail;
        }
 
-       /* Done */
+       return (0);
+
+fail:
+       lockuninit(&sc->mutex);
        return (error);
 }
 
@@ -130,8 +145,8 @@ ichsmb_attach(device_t dev)
                        SMBUS METHODS
 ********************************************************************/
 
-int 
-ichsmb_callback(device_t dev, int index, caddr_t data)
+int
+ichsmb_callback(device_t dev, int index, void *data)
 {
        int smb_error = 0;
 
@@ -161,15 +176,15 @@ ichsmb_quick(device_t dev, u_char slave, int how)
        switch (how) {
        case SMB_QREAD:
        case SMB_QWRITE:
-               crit_enter();
+               lockmgr(&sc->mutex, LK_EXCLUSIVE);
                sc->ich_cmd = ICH_HST_CNT_SMB_CMD_QUICK;
-               bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-                   (slave << 1) | (how == SMB_QREAD ?
+               bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+                   slave | (how == SMB_QREAD ?
                        ICH_XMIT_SLVA_READ : ICH_XMIT_SLVA_WRITE));
-               bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+               bus_write_1(sc->io_res, ICH_HST_CNT,
                    ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
                smb_error = ichsmb_wait(sc);
-               crit_exit();
+               lockmgr(&sc->mutex, LK_RELEASE);
                break;
        default:
                smb_error = SMB_ENOTSUPP;
@@ -187,15 +202,15 @@ ichsmb_sendb(device_t dev, u_char slave, char byte)
        DBG("slave=0x%02x byte=0x%02x\n", slave, (u_char)byte);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_WRITE);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, byte);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_WRITE);
+       bus_write_1(sc->io_res, ICH_HST_CMD, byte);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        smb_error = ichsmb_wait(sc);
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d\n", smb_error);
        return (smb_error);
 }
@@ -209,15 +224,15 @@ ichsmb_recvb(device_t dev, u_char slave, char *byte)
        DBG("slave=0x%02x\n", slave);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_READ);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_READ);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR)
-               *byte = bus_space_read_1(sc->io_bst, sc->io_bsh, ICH_D0);
-       crit_exit();
+               *byte = bus_read_1(sc->io_res, ICH_D0);
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d byte=0x%02x\n", smb_error, (u_char)*byte);
        return (smb_error);
 }
@@ -232,16 +247,16 @@ ichsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
            slave, (u_char)cmd, (u_char)byte);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_WRITE);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D0, byte);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_WRITE);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_D0, byte);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        smb_error = ichsmb_wait(sc);
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d\n", smb_error);
        return (smb_error);
 }
@@ -256,17 +271,17 @@ ichsmb_writew(device_t dev, u_char slave, char cmd, short word)
            slave, (u_char)cmd, (u_int16_t)word);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_WRITE);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D0, word & 0xff);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D1, word >> 8);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_WRITE);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_D0, word & 0xff);
+       bus_write_1(sc->io_res, ICH_D1, word >> 8);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        smb_error = ichsmb_wait(sc);
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d\n", smb_error);
        return (smb_error);
 }
@@ -280,16 +295,16 @@ ichsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
        DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BYTE_DATA;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_READ);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_READ);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR)
-               *byte = bus_space_read_1(sc->io_bst, sc->io_bsh, ICH_D0);
-       crit_exit();
+               *byte = bus_read_1(sc->io_res, ICH_D0);
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d byte=0x%02x\n", smb_error, (u_char)*byte);
        return (smb_error);
 }
@@ -303,20 +318,20 @@ ichsmb_readw(device_t dev, u_char slave, char cmd, short *word)
        DBG("slave=0x%02x cmd=0x%02x\n", slave, (u_char)cmd);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_WORD_DATA;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_READ);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_READ);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) {
-               *word = (bus_space_read_1(sc->io_bst,
-                       sc->io_bsh, ICH_D0) & 0xff)
-                 | (bus_space_read_1(sc->io_bst,
-                       sc->io_bsh, ICH_D1) << 8);
+               *word = (bus_read_1(sc->io_res,
+                       ICH_D0) & 0xff)
+                 | (bus_read_1(sc->io_res,
+                       ICH_D1) << 8);
        }
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d word=0x%04x\n", smb_error, (u_int16_t)*word);
        return (smb_error);
 }
@@ -331,22 +346,22 @@ ichsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
            slave, (u_char)cmd, (u_int16_t)sdata);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_PROC_CALL;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_WRITE);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D0, sdata & 0xff);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D1, sdata >> 8);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_WRITE);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_D0, sdata & 0xff);
+       bus_write_1(sc->io_res, ICH_D1, sdata >> 8);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) {
-               *rdata = (bus_space_read_1(sc->io_bst,
-                       sc->io_bsh, ICH_D0) & 0xff)
-                 | (bus_space_read_1(sc->io_bst,
-                       sc->io_bsh, ICH_D1) << 8);
+               *rdata = (bus_read_1(sc->io_res,
+                       ICH_D0) & 0xff)
+                 | (bus_read_1(sc->io_res,
+                       ICH_D1) << 8);
        }
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d rdata=0x%04x\n", smb_error, (u_int16_t)*rdata);
        return (smb_error);
 }
@@ -367,7 +382,7 @@ ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                DBG("%02x: %02x %02x %02x %02x %02x %02x %02x %02x"
                    "  %c%c%c%c%c%c%c%c", (p - (u_char *)buf),
                    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
-                   DISP(p[0]), DISP(p[1]), DISP(p[2]), DISP(p[3]), 
+                   DISP(p[0]), DISP(p[1]), DISP(p[2]), DISP(p[3]),
                    DISP(p[4]), DISP(p[5]), DISP(p[6]), DISP(p[7]));
            }
        }
@@ -376,29 +391,29 @@ ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
        if (count < 1 || count > 32)
-               return (EINVAL);
+               return (SMB_EINVAL);
        bcopy(buf, sc->block_data, count);
        sc->block_count = count;
        sc->block_index = 1;
        sc->block_write = 1;
 
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_WRITE);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D0, count);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_BLOCK_DB, buf[0]);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_WRITE);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_D0, count);
+       bus_write_1(sc->io_res, ICH_BLOCK_DB, buf[0]);
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
        smb_error = ichsmb_wait(sc);
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d\n", smb_error);
        return (smb_error);
 }
 
 int
-ichsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+ichsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
 {
        const sc_p sc = device_get_softc(dev);
        int smb_error;
@@ -406,24 +421,26 @@ ichsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
        DBG("slave=0x%02x cmd=0x%02x count=%d\n", slave, (u_char)cmd, count);
        KASSERT(sc->ich_cmd == -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-       if (count < 1 || count > 32)
-               return (EINVAL);
+       if (*count < 1 || *count > 32)
+               return (SMB_EINVAL);
        bzero(sc->block_data, sizeof(sc->block_data));
-       sc->block_count = count;
+       sc->block_count = 0;
        sc->block_index = 0;
        sc->block_write = 0;
 
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        sc->ich_cmd = ICH_HST_CNT_SMB_CMD_BLOCK;
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_XMIT_SLVA,
-           (slave << 1) | ICH_XMIT_SLVA_READ);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CMD, cmd);
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_D0, count); /* XXX? */
-       bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_CNT,
+       bus_write_1(sc->io_res, ICH_XMIT_SLVA,
+           slave | ICH_XMIT_SLVA_READ);
+       bus_write_1(sc->io_res, ICH_HST_CMD, cmd);
+       bus_write_1(sc->io_res, ICH_D0, *count); /* XXX? */
+       bus_write_1(sc->io_res, ICH_HST_CNT,
            ICH_HST_CNT_START | ICH_HST_CNT_INTREN | sc->ich_cmd);
-       if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR)
-               bcopy(sc->block_data, buf, sc->block_count);
-       crit_exit();
+       if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) {
+               bcopy(sc->block_data, buf, min(sc->block_count, *count));
+               *count = sc->block_count;
+       }
+       lockmgr(&sc->mutex, LK_RELEASE);
        DBG("smb_error=%d\n", smb_error);
 #if ICHSMB_DEBUG
 #define DISP(ch)       (((ch) < 0x20 || (ch) >= 0x7e) ? '.' : (ch))
@@ -434,7 +451,7 @@ ichsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
                DBG("%02x: %02x %02x %02x %02x %02x %02x %02x %02x"
                    "  %c%c%c%c%c%c%c%c", (p - (u_char *)buf),
                    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
-                   DISP(p[0]), DISP(p[1]), DISP(p[2]), DISP(p[3]), 
+                   DISP(p[0]), DISP(p[1]), DISP(p[2]), DISP(p[3]),
                    DISP(p[4]), DISP(p[5]), DISP(p[6]), DISP(p[7]));
            }
        }
@@ -485,11 +502,11 @@ ichsmb_device_intr(void *cookie)
        int cmd_index;
         int count;
 
-       crit_enter();
+       lockmgr(&sc->mutex, LK_EXCLUSIVE);
        for (count = 0; count < maxloops; count++) {
 
                /* Get and reset status bits */
-               status = bus_space_read_1(sc->io_bst, sc->io_bsh, ICH_HST_STA);
+               status = bus_read_1(sc->io_res, ICH_HST_STA);
 #if ICHSMB_DEBUG
                if ((status & ~(ICH_HST_STA_INUSE_STS | ICH_HST_STA_HOST_BUSY))
                    || count > 0) {
@@ -510,9 +527,9 @@ ichsmb_device_intr(void *cookie)
                        ok_bits |= ichsmb_state_irqs[cmd_index];
                }
                if ((status & ~ok_bits) != 0) {
-                       log(LOG_ERR, "%s: irq 0x%02x during %d\n",
-                           device_get_nameunit(dev), status, cmd_index);
-                       bus_space_write_1(sc->io_bst, sc->io_bsh,
+                       device_printf(dev, "irq 0x%02x during %d\n", status,
+                           cmd_index);
+                       bus_write_1(sc->io_res,
                            ICH_HST_STA, (status & ~ok_bits));
                        continue;
                }
@@ -521,12 +538,10 @@ ichsmb_device_intr(void *cookie)
                if (status & ICH_HST_STA_SMBALERT_STS) {
                        static int smbalert_count = 16;
                        if (smbalert_count > 0) {
-                               log(LOG_WARNING, "%s: SMBALERT# rec'd\n",
-                                   device_get_nameunit(dev));
+                               device_printf(dev, "SMBALERT# rec'd\n");
                                if (--smbalert_count == 0) {
-                                       log(LOG_WARNING,
-                                           "%s: not logging anymore\n",
-                                           device_get_nameunit(dev));
+                                       device_printf(dev,
+                                           "not logging anymore\n");
                                }
                        }
                }
@@ -549,16 +564,16 @@ ichsmb_device_intr(void *cookie)
                                if (sc->block_index < sc->block_count) {
 
                                        /* Write next byte */
-                                       bus_space_write_1(sc->io_bst,
-                                           sc->io_bsh, ICH_BLOCK_DB,
+                                       bus_write_1(sc->io_res,
+                                           ICH_BLOCK_DB,
                                            sc->block_data[sc->block_index++]);
                                }
                        } else {
 
                                /* First interrupt, get the count also */
                                if (sc->block_index == 0) {
-                                       sc->block_count = bus_space_read_1(
-                                           sc->io_bst, sc->io_bsh, ICH_D0);
+                                       sc->block_count = bus_read_1(
+                                           sc->io_res, ICH_D0);
                                }
 
                                /* Get next byte, if any */
@@ -566,15 +581,15 @@ ichsmb_device_intr(void *cookie)
 
                                        /* Read next byte */
                                        sc->block_data[sc->block_index++] =
-                                           bus_space_read_1(sc->io_bst,
-                                             sc->io_bsh, ICH_BLOCK_DB);
+                                           bus_read_1(sc->io_res,
+                                             ICH_BLOCK_DB);
 
                                        /* Set "LAST_BYTE" bit before reading
                                           the last byte of block data */
                                        if (sc->block_index
                                            >= sc->block_count - 1) {
-                                               bus_space_write_1(sc->io_bst,
-                                                   sc->io_bsh, ICH_HST_CNT,
+                                               bus_write_1(sc->io_res,
+                                                   ICH_HST_CNT,
                                                    ICH_HST_CNT_LAST_BYTE
                                                        | ICH_HST_CNT_INTREN
                                                        | sc->ich_cmd);
@@ -588,27 +603,26 @@ ichsmb_device_intr(void *cookie)
                        sc->smb_error = SMB_ENOERR;
 finished:
                        sc->ich_cmd = -1;
-                       bus_space_write_1(sc->io_bst, sc->io_bsh,
+                       bus_write_1(sc->io_res,
                            ICH_HST_STA, status);
                        wakeup(sc);
                        break;
                }
 
                /* Clear status bits and try again */
-               bus_space_write_1(sc->io_bst, sc->io_bsh, ICH_HST_STA, status);
+               bus_write_1(sc->io_res, ICH_HST_STA, status);
        }
-       crit_exit();
+       lockmgr(&sc->mutex, LK_RELEASE);
 
        /* Too many loops? */
        if (count == maxloops) {
-               log(LOG_ERR, "%s: interrupt loop, status=0x%02x\n",
-                   device_get_nameunit(dev),
-                   bus_space_read_1(sc->io_bst, sc->io_bsh, ICH_HST_STA));
+               device_printf(dev, "interrupt loop, status=0x%02x\n",
+                   bus_read_1(sc->io_res, ICH_HST_STA));
        }
 }
 
 /*
- * Wait for command completion. Assumes a critical section.
+ * Wait for command completion. Assumes mutex is held.
  * Returns an SMB_* error code.
  */
 static int
@@ -619,21 +633,16 @@ ichsmb_wait(sc_p sc)
 
        KASSERT(sc->ich_cmd != -1,
            ("%s: ich_cmd=%d\n", __func__ , sc->ich_cmd));
-sleep:
-       error = tsleep(sc, PCATCH, "ichsmb", hz / 4);
-       DBG("tsleep -> %d\n", error);
+       KKASSERT(lockstatus(&sc->mutex, curthread) != 0);
+       error = lksleep(sc, &sc->mutex, 0, "ichsmb", hz / 4);
+       DBG("msleep -> %d\n", error);
        switch (error) {
-       case ERESTART:
-               if (sc->ich_cmd != -1)
-                       goto sleep;
-               /* FALLTHROUGH */
        case 0:
                smb_error = sc->smb_error;
                break;
        case EWOULDBLOCK:
-               log(LOG_ERR, "%s: device timeout, status=0x%02x\n",
-                   device_get_nameunit(dev),
-                   bus_space_read_1(sc->io_bst, sc->io_bsh, ICH_HST_STA));
+               device_printf(dev, "device timeout, status=0x%02x\n",
+                   bus_read_1(sc->io_res, ICH_HST_STA));
                sc->ich_cmd = -1;
                smb_error = SMB_ETIMEOUT;
                break;
@@ -668,3 +677,20 @@ ichsmb_release_resources(sc_p sc)
        }
 }
 
+int
+ichsmb_detach(device_t dev)
+{
+       const sc_p sc = device_get_softc(dev);
+       int error;
+
+       error = bus_generic_detach(dev);
+       if (error)
+               return (error);
+       device_delete_child(dev, sc->smb);
+       ichsmb_release_resources(sc);
+       lockuninit(&sc->mutex);
+
+       return 0;
+}
+
+DRIVER_MODULE(smbus, ichsmb, smbus_driver, smbus_devclass, 0, 0);
index 6469fbd..5b6d2b4 100644 (file)
@@ -1,10 +1,11 @@
-
-/*
+/*-
  * ichsmb_pci.c
  *
+ * Author: Archie Cobbs <archie@freebsd.org>
  * Copyright (c) 2000 Whistle Communications, Inc.
  * All rights reserved.
- * 
+ * Author: Archie Cobbs <archie@freebsd.org>
+ *
  * Subject to the following obligations and disclaimer of warranty, use and
  * redistribution of this software, in source or object code forms, with or
  * without modifications are expressly permitted by Whistle Communications;
@@ -15,7 +16,7 @@
  *    Communications, Inc. trademarks, including the mark "WHISTLE
  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
  *    such appears in the above copyright notice or in the software.
- * 
+ *
  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
- * Author: Archie Cobbs <archie@freebsd.org>
- *
- * $FreeBSD: src/sys/dev/ichsmb/ichsmb_pci.c,v 1.1.2.3 2002/10/20 14:57:19 nyan Exp $
- * $DragonFly: src/sys/dev/powermng/ichsmb/ichsmb_pci.c,v 1.9 2007/09/23 22:06:10 hasso Exp $
+ * $FreeBSD: src/sys/dev/ichsmb/ichsmb_pci.c,v 1.25 2009/12/16 12:25:27 avg Exp $
  */
 
 /*
  * Support for the SMBus controller logical device which is part of the
- * Intel 81801AA (ICH) and 81801AB (ICH0) I/O controller hub chips.
+ * Intel 81801AA/AB/BA/CA/DC/EB (ICH/ICH[02345]) I/O controller hub chips.
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/module.h>
 #include <sys/errno.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
 #include <sys/syslog.h>
 #include <sys/bus.h>
+
 #include <sys/rman.h>
 
 #include <bus/pci/pcivar.h>
 
 #include <bus/smbus/smbconf.h>
 
-#include "ichsmb_var.h"
-#include "ichsmb_reg.h"
+#include <dev/powermng/ichsmb/ichsmb_var.h>
+#include <dev/powermng/ichsmb/ichsmb_reg.h>
 
 /* PCI unique identifiers */
-#define ID_6300ESB                     0x25A48086
-#define ID_63xxESB                     0x269B8086
 #define ID_82801AA                     0x24138086
 #define ID_82801AB                     0x24238086
 #define ID_82801BA                     0x24438086
-#define ID_82801E                      0x24538086
 #define ID_82801CA                     0x24838086
-#define ID_82801DB                     0x24C38086
+#define ID_82801DC                     0x24C38086
+#define ID_82801E                      0x24538086
 #define ID_82801EB                     0x24D38086
 #define ID_82801FB                     0x266A8086
-#define ID_82801G                      0x27DA8086
-#define ID_82801H                      0x283E8086
+#define ID_82801GB                     0x27da8086
+#define ID_82801H                      0x283e8086
 #define ID_82801I                      0x29308086
+#define ID_82801JI                     0x3a308086
+#define ID_PCH                         0x3b308086
+#define ID_6300ESB                     0x25a48086
+#define        ID_631xESB                      0x269b8086
 
 #define PCIS_SERIALBUS_SMBUS_PROGIF    0x00
 
 /* Internal functions */
 static int     ichsmb_pci_probe(device_t dev);
 static int     ichsmb_pci_attach(device_t dev);
+/*Use generic one for now*/
+#if 0
+static int     ichsmb_pci_detach(device_t dev);
+#endif
 
 /* Device methods */
 static device_method_t ichsmb_pci_methods[] = {
        /* Device interface */
         DEVMETHOD(device_probe, ichsmb_pci_probe),
         DEVMETHOD(device_attach, ichsmb_pci_attach),
+        DEVMETHOD(device_detach, ichsmb_detach),
 
        /* Bus methods */
         DEVMETHOD(bus_print_child, bus_generic_print_child),
@@ -121,12 +130,6 @@ ichsmb_pci_probe(device_t dev)
 {
        /* Check PCI identifier */
        switch (pci_get_devid(dev)) {
-       case ID_6300ESB:
-               device_set_desc(dev, "Intel 6300ESB (ESB) SMBus controller");
-               break;
-       case ID_63xxESB:
-               device_set_desc(dev, "Intel 63xxESB (ESB2) SMBus controller");
-               break;
        case ID_82801AA:
                device_set_desc(dev, "Intel 82801AA (ICH) SMBus controller");
                break;
@@ -139,8 +142,8 @@ ichsmb_pci_probe(device_t dev)
        case ID_82801CA:
                device_set_desc(dev, "Intel 82801CA (ICH3) SMBus controller");
                break;
-       case ID_82801DB:
-               device_set_desc(dev, "Intel 82801DB (ICH4) SMBus controller");
+       case ID_82801DC:
+               device_set_desc(dev, "Intel 82801DC (ICH4) SMBus controller");
                break;
        case ID_82801E:
                device_set_desc(dev, "Intel 82801E (C-ICH) SMBus controller");
@@ -151,8 +154,8 @@ ichsmb_pci_probe(device_t dev)
        case ID_82801FB:
                device_set_desc(dev, "Intel 82801FB (ICH6) SMBus controller");
                break;
-       case ID_82801G:
-               device_set_desc(dev, "Intel 82801G (ICH7) SMBus controller");
+       case ID_82801GB:
+               device_set_desc(dev, "Intel 82801GB (ICH7) SMBus controller");
                break;
        case ID_82801H:
                device_set_desc(dev, "Intel 82801H (ICH8) SMBus controller");
@@ -160,13 +163,19 @@ ichsmb_pci_probe(device_t dev)
        case ID_82801I:
                device_set_desc(dev, "Intel 82801I (ICH9) SMBus controller");
                break;
+       case ID_82801JI:
+               device_set_desc(dev, "Intel 82801JI (ICH10) SMBus controller");
+               break;
+       case ID_PCH:
+               device_set_desc(dev, "Intel PCH SMBus controller");
+               break;
+       case ID_6300ESB:
+               device_set_desc(dev, "Intel 6300ESB (ICH) SMBus controller");
+               break;
+       case ID_631xESB:
+               device_set_desc(dev, "Intel 631xESB/6321ESB (ESB2) SMBus controller");
+               break;
        default:
-               if (pci_get_class(dev) == PCIC_SERIALBUS
-                   && pci_get_subclass(dev) == PCIS_SERIALBUS_SMBUS
-                   && pci_get_progif(dev) == PCIS_SERIALBUS_SMBUS_PROGIF) {
-                       device_set_desc(dev, "SMBus controller");
-                       return (-2);            /* XXX */
-               }
                return (ENXIO);
        }
 
@@ -178,7 +187,6 @@ static int
 ichsmb_pci_attach(device_t dev)
 {
        const sc_p sc = device_get_softc(dev);
-       u_int32_t cmd;
        int error;
 
        /* Initialize private state */
@@ -190,40 +198,21 @@ ichsmb_pci_attach(device_t dev)
        sc->io_rid = ICH_SMB_BASE;
        sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
            &sc->io_rid, 0, ~0, 16, RF_ACTIVE);
+       if (sc->io_res == NULL)
+               sc->io_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
+                   &sc->io_rid, 0ul, ~0ul, 32, RF_ACTIVE);
        if (sc->io_res == NULL) {
-               log(LOG_ERR, "%s: can't map I/O\n", device_get_nameunit(dev));
+               device_printf(dev, "can't map I/O\n");
                error = ENXIO;
                goto fail;
        }
-       sc->io_bst = rman_get_bustag(sc->io_res);
-       sc->io_bsh = rman_get_bushandle(sc->io_res);
 
        /* Allocate interrupt */
        sc->irq_rid = 0;
-       sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
-           &sc->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
+       sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+           &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE);
        if (sc->irq_res == NULL) {
-               log(LOG_ERR, "%s: can't get IRQ\n", device_get_nameunit(dev));
-               error = ENXIO;
-               goto fail;
-       }
-
-       /* Set up interrupt handler */
-       error = bus_setup_intr(dev, sc->irq_res, 0, ichsmb_device_intr, sc,
-                              &sc->irq_handle, NULL);
-       if (error != 0) {
-               log(LOG_ERR, "%s: can't setup irq\n", device_get_nameunit(dev));
-               goto fail;
-       }
-
-       /* Enable I/O mapping */
-       cmd = pci_read_config(dev, PCIR_COMMAND, 4);
-       cmd |= PCIM_CMD_PORTEN;
-       pci_write_config(dev, PCIR_COMMAND, cmd, 4);
-       cmd = pci_read_config(dev, PCIR_COMMAND, 4);
-       if ((cmd & PCIM_CMD_PORTEN) == 0) {
-               log(LOG_ERR, "%s: can't enable memory map\n",
-                   device_get_nameunit(dev));
+               device_printf(dev, "can't get IRQ\n");
                error = ENXIO;
                goto fail;
        }
@@ -232,7 +221,10 @@ ichsmb_pci_attach(device_t dev)
        pci_write_config(dev, ICH_HOSTC, ICH_HOSTC_HST_EN, 1);
 
        /* Done */
-       return (ichsmb_attach(dev));
+       error = ichsmb_attach(dev);
+       if (error)
+               goto fail;
+       return (0);
 
 fail:
        /* Attach failed, release resources */
@@ -240,3 +232,7 @@ fail:
        return (error);
 }
 
+
+MODULE_DEPEND(ichsmb, pci, 1, 1, 1);
+MODULE_DEPEND(ichsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(ichsmb, 1);
index 852fe3d..e1b4c3b 100644 (file)
@@ -1,10 +1,9 @@
-
-/*
+/*-
  * ichsmb_reg.h
  *
  * Copyright (c) 2000 Whistle Communications, Inc.
  * All rights reserved.
- * 
+ *
  * Subject to the following obligations and disclaimer of warranty, use and
  * redistribution of this software, in source or object code forms, with or
  * without modifications are expressly permitted by Whistle Communications;
@@ -15,7 +14,7 @@
  *    Communications, Inc. trademarks, including the mark "WHISTLE
  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
  *    such appears in the above copyright notice or in the software.
- * 
+ *
  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
@@ -36,8 +35,7 @@
  *
  * Author: Archie Cobbs <archie@freebsd.org>
  *
- * $FreeBSD: src/sys/dev/ichsmb/ichsmb_reg.h,v 1.1.2.1 2000/10/09 00:52:43 archie Exp $
- * $DragonFly: src/sys/dev/powermng/ichsmb/ichsmb_reg.h,v 1.2 2003/06/17 04:28:27 dillon Exp $
+ * $FreeBSD: src/sys/dev/ichsmb/ichsmb_reg.h,v 1.2 2005/01/06 01:42:45 imp Exp $
  */
 
 #ifndef _DEV_ICHSMB_ICHSMB_REG_H_
index d907ec1..5df4ecd 100644 (file)
@@ -1,10 +1,9 @@
-
-/*
+/*-
  * ichsmb_var.h
  *
  * Copyright (c) 2000 Whistle Communications, Inc.
  * All rights reserved.
- * 
+ *
  * Subject to the following obligations and disclaimer of warranty, use and
  * redistribution of this software, in source or object code forms, with or
  * without modifications are expressly permitted by Whistle Communications;
@@ -15,7 +14,7 @@
  *    Communications, Inc. trademarks, including the mark "WHISTLE
  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
  *    such appears in the above copyright notice or in the software.
- * 
+ *
  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
@@ -36,8 +35,7 @@
  *
  * Author: Archie Cobbs <archie@freebsd.org>
  *
- * $FreeBSD: src/sys/dev/ichsmb/ichsmb_var.h,v 1.1.2.1 2000/10/09 00:52:43 archie Exp $
- * $DragonFly: src/sys/dev/powermng/ichsmb/ichsmb_var.h,v 1.2 2003/06/17 04:28:27 dillon Exp $
+ * $FreeBSD: src/sys/dev/ichsmb/ichsmb_var.h,v 1.5 2008/06/06 18:29:56 jhb Exp $
  */
 
 #ifndef _DEV_ICHSMB_ICHSMB_VAR_H
@@ -50,10 +48,9 @@ struct ichsmb_softc {
 
        /* Device/bus stuff */
        device_t                dev;            /* this device */
+       device_t                smb;            /* smb device */
        struct resource         *io_res;        /* i/o port resource */
        int                     io_rid;         /* i/o port bus id */
-       bus_space_tag_t         io_bst;         /* bus space tag */
-       bus_space_handle_t      io_bsh;         /* bus space handle */
        struct resource         *irq_res;       /* interrupt resource */
        int                     irq_rid;        /* interrupt bus id */
        void                    *irq_handle;    /* handle for interrupt code */
@@ -65,27 +62,29 @@ struct ichsmb_softc {
        int                     block_index;    /* index for block read/write */
        u_char                  block_write;    /* 0=read, 1=write */
        u_char                  block_data[32]; /* block read/write data */
+       struct lock             mutex;          /* device mutex */
 };
 typedef struct ichsmb_softc *sc_p;
 
 /* SMBus methods */
-extern smbus_callback_t        ichsmb_callback;        
-extern smbus_quick_t   ichsmb_quick;   
-extern smbus_sendb_t   ichsmb_sendb;   
-extern smbus_recvb_t   ichsmb_recvb;   
-extern smbus_writeb_t  ichsmb_writeb;  
-extern smbus_writew_t  ichsmb_writew;  
-extern smbus_readb_t   ichsmb_readb;   
-extern smbus_readw_t   ichsmb_readw;   
-extern smbus_pcall_t   ichsmb_pcall;   
-extern smbus_bwrite_t  ichsmb_bwrite;  
-extern smbus_bread_t   ichsmb_bread;   
+extern smbus_callback_t        ichsmb_callback;
+extern smbus_quick_t   ichsmb_quick;
+extern smbus_sendb_t   ichsmb_sendb;
+extern smbus_recvb_t   ichsmb_recvb;
+extern smbus_writeb_t  ichsmb_writeb;
+extern smbus_writew_t  ichsmb_writew;
+extern smbus_readb_t   ichsmb_readb;
+extern smbus_readw_t   ichsmb_readw;
+extern smbus_pcall_t   ichsmb_pcall;
+extern smbus_bwrite_t  ichsmb_bwrite;
+extern smbus_bread_t   ichsmb_bread;
 
 /* Other functions */
 extern void    ichsmb_device_intr(void *cookie);
 extern void    ichsmb_release_resources(sc_p sc);
 extern int     ichsmb_probe(device_t dev);
 extern int     ichsmb_attach(device_t dev);
+extern int     ichsmb_detach(device_t dev);
 
 #endif /* _DEV_ICHSMB_ICHSMB_VAR_H */
 
diff --git a/sys/dev/powermng/intpm/Makefile b/sys/dev/powermng/intpm/Makefile
new file mode 100644 (file)
index 0000000..86cb3f3
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/intpm/Makefile,v 1.1 2002/03/23 15:48:42 nsouch Exp $
+
+.PATH:         ${.CURDIR}/../../../../bus/pci
+KMOD           = intpm
+SRCS           = device_if.h bus_if.h iicbus_if.h smbus_if.h pci_if.h \
+                 opt_intpm.h intpmreg.h intpm.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/dev/powermng/intpm/intpm.c b/sys/dev/powermng/intpm/intpm.c
new file mode 100644 (file)
index 0000000..a64a249
--- /dev/null
@@ -0,0 +1,815 @@
+/*-
+ * Copyright (c) 1998, 1999 Takanori Watanabe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *        notice, this list of conditions and the following disclaimer in the
+ *        documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.    IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/pci/intpm.c,v 1.45 2009/09/19 08:56:28 avg Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/globaldata.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <bus/smbus/smbconf.h>
+
+#include "smbus_if.h"
+
+#include <bus/pci/pcireg.h>
+#include <bus/pci/pcivar.h>
+#include <dev/powermng/intpm/intpmreg.h>
+
+#include "opt_intpm.h"
+
+struct intsmb_softc {
+       device_t                dev;
+       struct resource         *io_res;
+       struct resource         *irq_res;
+       void                    *irq_hand;
+       device_t                smbus;
+       int                     isbusy;
+       int                     cfg_irq9;
+       int                     poll;
+       struct lock             lock;
+};
+
+#define        INTSMB_LOCK(sc)         lockmgr(&(sc)->lock, LK_EXCLUSIVE)
+#define        INTSMB_UNLOCK(sc)       lockmgr(&(sc)->lock, LK_RELEASE)
+#define        INTSMB_LOCK_ASSERT(sc)  KKASSERT(lockstatus(&(sc)->lock, curthread) != 0)
+
+static int intsmb_probe(device_t);
+static int intsmb_attach(device_t);
+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);
+static int intsmb_callback(device_t dev, int index, void *data);
+static int intsmb_quick(device_t dev, u_char slave, int how);
+static int intsmb_sendb(device_t dev, u_char slave, char byte);
+static int intsmb_recvb(device_t dev, u_char slave, char *byte);
+static int intsmb_writeb(device_t dev, u_char slave, char cmd, char byte);
+static int intsmb_writew(device_t dev, u_char slave, char cmd, short word);
+static int intsmb_readb(device_t dev, u_char slave, char cmd, char *byte);
+static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word);
+static int intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata);
+static int intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf);
+static int intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf);
+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);
+
+static int
+intsmb_probe(device_t dev)
+{
+
+       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;
+       case 0x43851002:
+               device_set_desc(dev, "AMD SB600/700/710/750 SMBus Controller");
+               /* XXX Maybe force polling right here? */
+               break;
+       default:
+               return (ENXIO);
+       }
+
+       return (BUS_PROBE_DEFAULT);
+}
+
+static int
+intsmb_attach(device_t dev)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error, rid, value;
+       int intr;
+       char *str;
+
+       sc->dev = dev;
+
+       lockinit(&sc->lock, "intsmb", 0, LK_CANRECURSE);
+
+       sc->cfg_irq9 = 0;
+#ifndef NO_CHANGE_PCICONF
+       switch (pci_get_devid(dev)) {
+       case 0x71138086:        /* Intel 82371AB */
+       case 0x719b8086:        /* Intel 82443MX */
+               /* Changing configuration is allowed. */
+               sc->cfg_irq9 = 1;
+               break;
+       }
+#endif
+
+       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;
+       }
+
+       if (sc->cfg_irq9) {
+               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);
+       }
+       value = pci_read_config(dev, PCI_HST_CFG_SMB, 1);
+       sc->poll = (value & PCI_INTR_SMB_ENABLE) == 0;
+       intr = value & PCI_INTR_SMB_MASK;
+       switch (intr) {
+       case PCI_INTR_SMB_SMI:
+               str = "SMI";
+               break;
+       case PCI_INTR_SMB_IRQ9:
+               str = "IRQ 9";
+               break;
+       case PCI_INTR_SMB_IRQ_PCI:
+               str = "PCI IRQ";
+               break;
+       default:
+               str = "BOGUS";
+       }
+
+       device_printf(dev, "intr %s %s ", str,
+           sc->poll == 0 ? "enabled" : "disabled");
+       kprintf("revision %d\n", pci_read_config(dev, PCI_REVID_SMB, 1));
+
+       if (!sc->poll && intr == PCI_INTR_SMB_SMI) {
+               device_printf(dev,
+                   "using polling mode when configured interrupt is SMI\n");
+               sc->poll = 1;
+       }
+
+       if (sc->poll)
+           goto no_intr;
+
+       if (intr != PCI_INTR_SMB_IRQ9 && intr != PCI_INTR_SMB_IRQ_PCI) {
+               device_printf(dev, "Unsupported interrupt mode\n");
+               error = ENXIO;
+               goto fail;
+       }
+
+       /* Force IRQ 9. */
+       rid = 0;
+       if (sc->cfg_irq9)
+               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;
+       }
+
+       error = bus_setup_intr(dev, sc->irq_res, 0,
+           intsmb_rawintr, sc, &sc->irq_hand, NULL);
+       if (error) {
+               device_printf(dev, "Failed to map intr\n");
+               goto fail;
+       }
+
+no_intr:
+       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;
+
+#ifdef ENABLE_ALART
+       /* Enable Arart */
+       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN);
+#endif
+       return (0);
+
+fail:
+       intsmb_detach(dev);
+       return (error);
+}
+
+static int
+intsmb_detach(device_t dev)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       error = bus_generic_detach(dev);
+       if (error)
+               return (error);
+
+       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);
+       lockuninit(&sc->lock);
+       return (0);
+}
+
+static void
+intsmb_rawintr(void *arg)
+{
+       struct intsmb_softc *sc = arg;
+
+       INTSMB_LOCK(sc);
+       intsmb_intr(sc);
+       intsmb_slvintr(sc);
+       INTSMB_UNLOCK(sc);
+}
+
+static int
+intsmb_callback(device_t dev, int index, void *data)
+{
+       int error = 0;
+
+       switch (index) {
+       case SMB_REQUEST_BUS:
+               break;
+       case SMB_RELEASE_BUS:
+               break;
+       default:
+               error = EINVAL;
+       }
+
+       return (error);
+}
+
+/* Counterpart of smbtx_smb_free(). */
+static int
+intsmb_free(struct intsmb_softc *sc)
+{
+
+       INTSMB_LOCK_ASSERT(sc);
+       if ((bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) & PIIX4_SMBHSTSTAT_BUSY) ||
+#ifdef ENABLE_ALART
+           (bus_read_1(sc->io_res, PIIX4_SMBSLVSTS) & PIIX4_SMBSLVSTS_BUSY) ||
+#endif
+           sc->isbusy)
+               return (SMB_EBUSY);
+
+       sc->isbusy = 1;
+       /* Disable Interrupt in slave part. */
+#ifndef ENABLE_ALART
+       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, 0);
+#endif
+       /* Reset INTR Flag to prepare INTR. */
+       bus_write_1(sc->io_res, PIIX4_SMBHSTSTS,
+           PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR |
+           PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL);
+       return (0);
+}
+
+static int
+intsmb_intr(struct intsmb_softc *sc)
+{
+       int status, tmp;
+
+       status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
+       if (status & PIIX4_SMBHSTSTAT_BUSY)
+               return (1);
+
+       if (status & (PIIX4_SMBHSTSTAT_INTR | PIIX4_SMBHSTSTAT_ERR |
+           PIIX4_SMBHSTSTAT_BUSC | PIIX4_SMBHSTSTAT_FAIL)) {
+
+               tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
+               bus_write_1(sc->io_res, PIIX4_SMBHSTCNT,
+                   tmp & ~PIIX4_SMBHSTCNT_INTREN);
+               if (sc->isbusy) {
+                       sc->isbusy = 0;
+                       wakeup(sc);
+               }
+               return (0);
+       }
+       return (1); /* Not Completed */
+}
+
+static int
+intsmb_slvintr(struct intsmb_softc *sc)
+{
+       int status;
+
+       status = bus_read_1(sc->io_res, PIIX4_SMBSLVSTS);
+       if (status & PIIX4_SMBSLVSTS_BUSY)
+               return (1);
+       if (status & PIIX4_SMBSLVSTS_ALART)
+               intsmb_alrintr(sc);
+       else if (status & ~(PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2
+               | PIIX4_SMBSLVSTS_SDW1)) {
+       }
+
+       /* Reset Status Register */
+       bus_write_1(sc->io_res, PIIX4_SMBSLVSTS,
+           PIIX4_SMBSLVSTS_ALART | PIIX4_SMBSLVSTS_SDW2 |
+           PIIX4_SMBSLVSTS_SDW1 | PIIX4_SMBSLVSTS_SLV);
+       return (0);
+}
+
+static void
+intsmb_alrintr(struct intsmb_softc *sc)
+{
+       int slvcnt;
+#ifdef ENABLE_ALART
+       int error;
+       uint8_t addr;
+#endif
+
+       /* Stop generating INTR from ALART. */
+       slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT);
+#ifdef ENABLE_ALART
+       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
+           slvcnt & ~PIIX4_SMBSLVCNT_ALTEN);
+#endif
+       DELAY(5);
+
+       /* Ask bus who asserted it and then ask it what's the matter. */
+#ifdef ENABLE_ALART
+       error = intsmb_free(sc);
+       if (error)
+               return;
+
+       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);
+       }
+
+       /* Re-enable INTR from ALART. */
+       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
+           slvcnt | PIIX4_SMBSLVCNT_ALTEN);
+       DELAY(5);
+#endif
+}
+
+static void
+intsmb_start(struct intsmb_softc *sc, unsigned char cmd, int nointr)
+{
+       unsigned char tmp;
+
+       INTSMB_LOCK_ASSERT(sc);
+       tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
+       tmp &= 0xe0;
+       tmp |= cmd;
+       tmp |= PIIX4_SMBHSTCNT_START;
+
+       /* While not in autoconfiguration enable interrupts. */
+       if (!sc->poll && !cold && !nointr)
+               tmp |= PIIX4_SMBHSTCNT_INTREN;
+       bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp);
+}
+
+static int
+intsmb_error(device_t dev, 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;
+
+       if (error != 0 && bootverbose)
+               device_printf(dev, "error = %d, status = %#x\n", error, status);
+
+       return (error);
+}
+
+/*
+ * Polling Code.
+ *
+ * Polling is not encouraged because it requires waiting for the
+ * device if it is busy.
+ * (29063505.pdf from Intel) But during boot, interrupt cannot be used, so use
+ * polling code then.
+ */
+static int
+intsmb_stop_poll(struct intsmb_softc *sc)
+{
+       int error, i, status, tmp;
+
+       INTSMB_LOCK_ASSERT(sc);
+
+       /* First, wait for busy to be set. */
+       for (i = 0; i < 0x7fff; i++)
+               if (bus_read_1(sc->io_res, PIIX4_SMBHSTSTS) &
+                   PIIX4_SMBHSTSTAT_BUSY)
+                       break;
+
+       /* Wait for busy to clear. */
+       for (i = 0; i < 0x7fff; i++) {
+               status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
+               if (!(status & PIIX4_SMBHSTSTAT_BUSY)) {
+                       sc->isbusy = 0;
+                       error = intsmb_error(sc->dev, status);
+                       return (error);
+               }
+       }
+
+       /* Timed out waiting for busy to clear. */
+       sc->isbusy = 0;
+       tmp = bus_read_1(sc->io_res, PIIX4_SMBHSTCNT);
+       bus_write_1(sc->io_res, PIIX4_SMBHSTCNT, tmp & ~PIIX4_SMBHSTCNT_INTREN);
+       return (SMB_ETIMEOUT);
+}
+
+/*
+ * Wait for completion and return result.
+ */
+static int
+intsmb_stop(struct intsmb_softc *sc)
+{
+       int error, status;
+
+       INTSMB_LOCK_ASSERT(sc);
+
+       if (sc->poll || cold)
+               /* So that it can use device during device probe on SMBus. */
+               return (intsmb_stop_poll(sc));
+
+       error = lksleep(sc, &sc->lock, PCATCH, "SMBWAI", hz / 8);
+       if (error == 0) {
+               status = bus_read_1(sc->io_res, PIIX4_SMBHSTSTS);
+               if (!(status & PIIX4_SMBHSTSTAT_BUSY)) {
+                       error = intsmb_error(sc->dev, status);
+                       if (error == 0 && !(status & PIIX4_SMBHSTSTAT_INTR))
+                               device_printf(sc->dev, "unknown cause why?\n");
+#ifdef ENABLE_ALART
+                       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT,
+                           PIIX4_SMBSLVCNT_ALTEN);
+#endif
+                       return (error);
+               }
+       }
+
+       /* Timeout Procedure. */
+       sc->isbusy = 0;
+
+       /* Re-enable supressed interrupt from slave part. */
+       bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, PIIX4_SMBSLVCNT_ALTEN);
+       if (error == EWOULDBLOCK)
+               return (SMB_ETIMEOUT);
+       else
+               return (SMB_EABORT);
+}
+
+static int
+intsmb_quick(device_t dev, u_char slave, int how)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+       u_char data;
+
+       data = slave;
+
+       /* Quick command is part of Address, I think. */
+       switch(how) {
+       case SMB_QWRITE:
+               data &= ~LSB;
+               break;
+       case SMB_QREAD:
+               data |= LSB;
+               break;
+       default:
+               return (EINVAL);
+       }
+
+       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);
+       return (error);
+}
+
+static int
+intsmb_sendb(device_t dev, u_char slave, char byte)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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);
+       return (error);
+}
+
+static int
+intsmb_recvb(device_t dev, u_char slave, char *byte)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       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) {
+#ifdef RECV_IS_IN_CMD
+               /*
+                * Linux SMBus stuff also troubles
+                * Because Intel's datasheet does not make clear.
+                */
+               *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD);
+#else
+               *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0);
+#endif
+       }
+       INTSMB_UNLOCK(sc);
+       return (error);
+}
+
+static int
+intsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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);
+       return (error);
+}
+
+static int
+intsmb_writew(device_t dev, u_char slave, char cmd, short word)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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);
+       return (error);
+}
+
+static int
+intsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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);
+       return (error);
+}
+
+static int
+intsmb_readw(device_t dev, u_char slave, char cmd, short *word)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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);
+       return (error);
+}
+
+/*
+ * Data sheet claims that it implements all function, but also claims
+ * that it implements 7 function and not mention PCALL. So I don't know
+ * whether it will work.
+ */
+static int
+intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
+{
+#ifdef PROCCALL_TEST
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error;
+
+       INTSMB_LOCK(sc);
+       error = intsmb_free(sc);
+       if (error) {
+               INTSMB_UNLOCK(sc);
+               return (error);
+       }
+       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;
+       }
+       INTSMB_UNLOCK(sc);
+       return (error);
+#else
+       return (SMB_ENOTSUPP);
+#endif
+}
+
+static int
+intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error, i;
+
+       if (count > SMBBLOCKTRANS_MAX || count == 0)
+               return (SMB_EINVAL);
+
+       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);
+       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);
+       return (error);
+}
+
+static int
+intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
+{
+       struct intsmb_softc *sc = device_get_softc(dev);
+       int error, i;
+       u_char data, nread;
+
+       if (*count > SMBBLOCKTRANS_MAX || *count == 0)
+               return (SMB_EINVAL);
+
+       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;
+                       }
+                       *count = nread;
+               } else
+                       error = EIO;
+       }
+       INTSMB_UNLOCK(sc);
+       return (error);
+}
+
+static devclass_t intsmb_devclass;
+
+static device_method_t intsmb_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         intsmb_probe),
+       DEVMETHOD(device_attach,        intsmb_attach),
+       DEVMETHOD(device_detach,        intsmb_detach),
+
+       /* Bus interface */
+       DEVMETHOD(bus_print_child,      bus_generic_print_child),
+
+       /* 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),
+
+       { 0, 0 }
+};
+
+static driver_t intsmb_driver = {
+       "intsmb",
+       intsmb_methods,
+       sizeof(struct intsmb_softc),
+};
+
+DRIVER_MODULE(intsmb, pci, intsmb_driver, intsmb_devclass, 0, 0);
+DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0);
+MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(intsmb, 1);
diff --git a/sys/dev/powermng/intpm/intpmreg.h b/sys/dev/powermng/intpm/intpmreg.h
new file mode 100644 (file)
index 0000000..d06cd6b
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 1998, 1999 Takanori Watanabe
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *        notice, this list of conditions and the following disclaimer in the
+ *        documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.    IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/pci/intpmreg.h,v 1.5 2009/09/12 18:24:31 avg Exp $
+ */
+
+#ifndef __INTPMREG_H__
+#define        __INTPMREG_H__
+
+/* Register definitions for non-ICH Intel Chipset SMBUS controllers. */
+
+/* PCI Config Registers. */
+#define        PCI_BASE_ADDR_SMB       0x90    /* IO BAR. */
+#define        PCI_BASE_ADDR_PM        0x40
+#define        PCI_HST_CFG_SMB         0xd2    /* Host Configuration */
+#define        PCI_INTR_SMB_MASK       0xe
+#define        PCI_INTR_SMB_SMI        0
+#define        PCI_INTR_SMB_IRQ_PCI    2
+#define        PCI_INTR_SMB_IRQ9       8
+#define        PCI_INTR_SMB_ENABLE     1
+#define        PCI_SLV_CMD_SMB         0xd3 /*SLAVE COMMAND*/
+#define        PCI_SLV_SDW_SMB_1       0xd4 /*SLAVE SHADOW PORT 1*/
+#define        PCI_SLV_SDW_SMB_2       0xd5 /*SLAVE SHADOW PORT 2*/
+#define        PCI_REVID_SMB           0xd6
+
+/* PIXX4 SMBus Registers in the SMB BAR. */
+#define        PIIX4_SMBHSTSTS         0x00
+#define        PIIX4_SMBHSTSTAT_BUSY   (1<<0)
+#define        PIIX4_SMBHSTSTAT_INTR   (1<<1)
+#define        PIIX4_SMBHSTSTAT_ERR    (1<<2)
+#define        PIIX4_SMBHSTSTAT_BUSC   (1<<3)
+#define        PIIX4_SMBHSTSTAT_FAIL   (1<<4)
+#define        PIIX4_SMBSLVSTS         0x01
+#define        PIIX4_SMBSLVSTS_ALART   (1<<5)
+#define        PIIX4_SMBSLVSTS_SDW2    (1<<4)
+#define        PIIX4_SMBSLVSTS_SDW1    (1<<3)
+#define        PIIX4_SMBSLVSTS_SLV     (1<<2)
+#define        PIIX4_SMBSLVSTS_BUSY    (1<<0)
+#define        PIIX4_SMBHSTCNT         0x02
+#define        PIIX4_SMBHSTCNT_START   (1<<6)
+#define        PIIX4_SMBHSTCNT_PROT_QUICK      0
+#define        PIIX4_SMBHSTCNT_PROT_BYTE       (1<<2)
+#define        PIIX4_SMBHSTCNT_PROT_BDATA      (2<<2)
+#define        PIIX4_SMBHSTCNT_PROT_WDATA      (3<<2)
+#define        PIIX4_SMBHSTCNT_PROT_BLOCK      (5<<2)
+#define        PIIX4_SMBHSTCNT_KILL    (1<<1)
+#define        PIIX4_SMBHSTCNT_INTREN  (1)
+#define        PIIX4_SMBHSTCMD         0x03
+#define        PIIX4_SMBHSTADD         0x04
+#define        LSB                     0x1
+#define        PIIX4_SMBHSTDAT0        0x05
+#define        PIIX4_SMBHSTDAT1        0x06
+#define        PIIX4_SMBBLKDAT         0x07
+#define        PIIX4_SMBSLVCNT         0x08
+#define        PIIX4_SMBSLVCNT_ALTEN   (1<<3)
+#define        PIIX4_SMBSLVCNT_SD2EN   (1<<2)
+#define        PIIX4_SMBSLVCNT_SD1EN   (1<<1)
+#define        PIIX4_SMBSLVCNT_SLVEN   (1)
+#define        PIIX4_SMBSLVCMD         0x09
+#define        PIIX4_SMBSLVEVT         0x0a
+#define        PIIX4_SMBSLVDAT         0x0c
+
+/* SMBus alert response address. */
+#define        SMBALTRESP              0x18
+
+#define        SMBBLOCKTRANS_MAX       32
+
+#endif /* !__INTPMREG_H__ */
diff --git a/sys/dev/powermng/viapm/Makefile b/sys/dev/powermng/viapm/Makefile
new file mode 100644 (file)
index 0000000..7861974
--- /dev/null
@@ -0,0 +1,8 @@
+# $FreeBSD: src/sys/modules/i2c/controllers/viapm/Makefile,v 1.3 2007/06/24 20:35:59 njl Exp $
+
+.PATH:         ${.CURDIR}/../../../../bus/pci
+KMOD           = viapm
+SRCS           = device_if.h bus_if.h iicbb_if.h isa_if.h pci_if.h smbus_if.h \
+                 opt_isa.h viapm.c
+
+.include <bsd.kmod.mk>
similarity index 86%
rename from sys/dev/powermng/i386/viapm/viapm.c
rename to sys/dev/powermng/viapm/viapm.c
index 225097a..a41f329 100644 (file)
@@ -1,6 +1,5 @@
 /*-
  * Copyright (c) 2001 Alcove - Nicolas Souchu
- * Copyright (c) 2002 Nicolas Souchu
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -24,8 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/pci/viapm.c,v 1.1.2.1 2002/04/19 05:52:15 nsouch Exp $
- * $DragonFly: src/sys/dev/powermng/i386/viapm/viapm.c,v 1.10 2006/12/22 23:26:23 swildner Exp $
+ * $FreeBSD: src/sys/pci/viapm.c,v 1.10.2.3 2006/09/22 19:19:16 jhb Exp $
  *
  */
 #include <sys/param.h>
 #include <bus/pci/pcireg.h>
 
 #include <bus/iicbus/iiconf.h>
-#include <bus/iicbus/iicbus.h>
 
 #include <bus/smbus/smbconf.h>
-#include <bus/smbus/smbus.h>
 
 #include "iicbb_if.h"
 #include "smbus_if.h"
@@ -63,11 +59,13 @@ static int viapm_debug = 0;
 #define VIA_596B_PMU_ID                0x30511106
 #define VIA_686A_PMU_ID                0x30571106
 #define VIA_8233_PMU_ID                0x30741106
+#define        VIA_8233A_PMU_ID        0x31471106
+#define        VIA_8235_PMU_ID         0x31771106
 
 #define VIAPM_INB(port) \
        ((u_char)bus_space_read_1(viapm->st, viapm->sh, port))
 #define VIAPM_OUTB(port,val) \
-       (bus_space_write_1(viapm->st, viapm->sh, port, (u_char)val))
+       (bus_space_write_1(viapm->st, viapm->sh, port, (u_char)(val)))
 
 #define VIAPM_TYP_UNKNOWN      0
 #define VIAPM_TYP_586B_3040E   1
@@ -223,7 +221,7 @@ viapm_586b_probe(device_t dev)
                        return ENXIO;
                }
                device_set_desc(dev, "VIA VT82C586B Power Management Unit");
-               return 0;
+               return (BUS_PROBE_DEFAULT);
 
        default:
                break;
@@ -263,11 +261,18 @@ viapm_pro_probe(device_t dev)
                goto viapro;
 
        case VIA_8233_PMU_ID:
+       case VIA_8233A_PMU_ID:
                desc = "VIA VT8233 Power Management Unit";
                viapm->type = VIAPM_TYP_UNKNOWN;
                base_cfgreg = VIAPM_8233_BASE;
                goto viapro;
 
+       case VIA_8235_PMU_ID:
+               desc = "VIA VT8235 Power Management Unit";
+               viapm->type = VIAPM_TYP_UNKNOWN;
+               base_cfgreg = VIAPM_8233_BASE;
+               goto viapro;
+
        viapro:
 
 #ifdef VIAPM_BASE_ADDR
@@ -301,7 +306,7 @@ viapm_pro_probe(device_t dev)
                }
 
                device_set_desc(dev, desc);
-               return 0;
+               return (BUS_PROBE_DEFAULT);
 
        default:
                break;
@@ -341,7 +346,7 @@ viapm_pro_attach(device_t dev)
        }
 
        error = bus_setup_intr(dev, viapm->irqres, 0,
-                              (driver_intr_t *) viasmb_intr, viapm, 
+                              (driver_intr_t *) viasmb_intr, viapm,
                               &viapm->irqih, NULL);
        if (error) {
                device_printf(dev, "could not setup irq\n");
@@ -388,7 +393,7 @@ static int
 viapm_586b_attach(device_t dev)
 {
        struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
-       
+
        if (!(viapm->iores = bus_alloc_resource(dev, SYS_RES_IOPORT,
                &viapm->iorid, 0ul, ~0ul, 1, RF_ACTIVE | RF_SHAREABLE))) {
                device_printf(dev, "could not allocate bus resource\n");
@@ -497,7 +502,7 @@ viabb_setsda(device_t dev, int data)
 
        return;
 }
-       
+
 static int
 viabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
 {
@@ -508,7 +513,6 @@ viabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
        return (IIC_ENOADDR);
 }
 
-#if 0
 static int
 viabb_getscl(device_t dev)
 {
@@ -516,7 +520,6 @@ viabb_getscl(device_t dev)
 
        return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SCL) != 0);
 }
-#endif
 
 static int
 viabb_getsda(device_t dev)
@@ -526,15 +529,6 @@ viabb_getsda(device_t dev)
        return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SDA) != 0);
 }
 
-static void
-viabb_setlines(device_t dev, int ctrl, int data)
-{
-       viabb_setscl(dev, ctrl);
-       viabb_setsda(dev, data);
-
-       return;
-}
-
 static int
 viapm_abort(struct viapm_softc *viapm)
 {
@@ -635,7 +629,7 @@ viasmb_quick(device_t dev, u_char slave, int how)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        switch (how) {
        case SMB_QWRITE:
@@ -665,7 +659,7 @@ viasmb_sendb(device_t dev, u_char slave, char byte)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
        VIAPM_OUTB(SMBHCMD, byte);
@@ -687,7 +681,7 @@ viasmb_recvb(device_t dev, u_char slave, char *byte)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave | LSB);
 
@@ -709,7 +703,7 @@ viasmb_writeb(device_t dev, u_char slave, char cmd, char byte)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
        VIAPM_OUTB(SMBHCMD, cmd);
@@ -732,7 +726,7 @@ viasmb_readb(device_t dev, u_char slave, char cmd, char *byte)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave | LSB);
        VIAPM_OUTB(SMBHCMD, cmd);
@@ -755,7 +749,7 @@ viasmb_writew(device_t dev, u_char slave, char cmd, short word)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
        VIAPM_OUTB(SMBHCMD, cmd);
@@ -780,7 +774,7 @@ viasmb_readw(device_t dev, u_char slave, char cmd, short *word)
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
+               return (SMB_EBUSY);
 
        VIAPM_OUTB(SMBHADDR, slave | LSB);
        VIAPM_OUTB(SMBHCMD, cmd);
@@ -803,37 +797,31 @@ static int
 viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
 {
        struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
-       u_char remain, len, i;
-       int error = SMB_ENOERR;
+       u_char i;
+       int error;
+
+       if (count < 1 || count > 32)
+               return (SMB_EINVAL);
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
-
-       remain = count;
-       while (remain) {
-               len = min(remain, 32);
-
-               VIAPM_OUTB(SMBHADDR, slave & ~LSB);
-               VIAPM_OUTB(SMBHCMD, cmd);
-               VIAPM_OUTB(SMBHDATA0, len);
-               i = VIAPM_INB(SMBHCTRL);
-
-               /* fill the 32-byte internal buffer */
-               for (i=0; i<len; i++) {
-                       VIAPM_OUTB(SMBHBLOCK, buf[count-remain+i]);
-                       DELAY(2);
-               }
-               VIAPM_OUTB(SMBHCMD, cmd);
-               VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
+               return (SMB_EBUSY);
 
-               if ((error = viapm_wait(viapm)) != SMB_ENOERR)
-                       goto error;
+       VIAPM_OUTB(SMBHADDR, slave & ~LSB);
+       VIAPM_OUTB(SMBHCMD, cmd);
+       VIAPM_OUTB(SMBHDATA0, count);
+       i = VIAPM_INB(SMBHCTRL);
 
-               remain -= len;
+       /* fill the 32-byte internal buffer */
+       for (i = 0; i < count; i++) {
+               VIAPM_OUTB(SMBHBLOCK, buf[i]);
+               DELAY(2);
        }
+       VIAPM_OUTB(SMBHCMD, cmd);
+       VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
+
+       error = viapm_wait(viapm);
 
-error:
        VIAPM_DEBUG(kprintf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
 
        return (error);
@@ -841,40 +829,40 @@ error:
 }
 
 static int
-viasmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+viasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
 {
        struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
-       u_char remain, len, i;
-       int error = SMB_ENOERR;
+       u_char data, len, i;
+       int error;
+
+       if (*count < 1 || *count > 32)
+               return (SMB_EINVAL);
 
        viapm_clear(viapm);
        if (viapm_busy(viapm))
-               return (EBUSY);
-
-       remain = count;
-       while (remain) {
-               VIAPM_OUTB(SMBHADDR, slave | LSB);
-               VIAPM_OUTB(SMBHCMD, cmd);
-               VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
+               return (SMB_EBUSY);
 
-               if ((error = viapm_wait(viapm)) != SMB_ENOERR)
-                       goto error;
-
-               len = VIAPM_INB(SMBHDATA0);
-               i = VIAPM_INB(SMBHCTRL);                /* reset counter */
+       VIAPM_OUTB(SMBHADDR, slave | LSB);
+       VIAPM_OUTB(SMBHCMD, cmd);
+       VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
 
-               len = min(len, remain);
+       if ((error = viapm_wait(viapm)) != SMB_ENOERR)
+               goto error;
 
-               /* read the 32-byte internal buffer */
-               for (i=0; i<len; i++) {
-                       buf[count-remain+i] = VIAPM_INB(SMBHBLOCK);
-                       DELAY(2);
-               }
+       len = VIAPM_INB(SMBHDATA0);
+       i = VIAPM_INB(SMBHCTRL);                /* reset counter */
 
-               remain -= len;
+       /* read the 32-byte internal buffer */
+       for (i = 0; i < len; i++) {
+               data = VIAPM_INB(SMBHBLOCK);
+               if (i < *count)
+                       buf[i] = data;
+               DELAY(2);
        }
+       *count = len;
+
 error:
-       VIAPM_DEBUG(kprintf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
+       VIAPM_DEBUG(kprintf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
 
        return (error);
 }
@@ -887,10 +875,21 @@ static device_method_t viapm_methods[] = {
 
        /* iicbb interface */
        DEVMETHOD(iicbb_callback,       viabb_callback),
-       DEVMETHOD(iicbb_setlines,       viabb_setlines),
-       DEVMETHOD(iicbb_getdataline,    viabb_getsda),
+       DEVMETHOD(iicbb_setscl,         viabb_setscl),
+       DEVMETHOD(iicbb_setsda,         viabb_setsda),
+       DEVMETHOD(iicbb_getscl,         viabb_getscl),
+       DEVMETHOD(iicbb_getsda,         viabb_getsda),
        DEVMETHOD(iicbb_reset,          viabb_reset),
 
+       /* Bus interface */
+       DEVMETHOD(bus_print_child,      bus_generic_print_child),
+       DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
+       DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+       DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+       DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+       DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
+       DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
+
        { 0, 0 }
 };
 
@@ -917,7 +916,16 @@ static device_method_t viapropm_methods[] = {
        DEVMETHOD(smbus_readw,          viasmb_readw),
        DEVMETHOD(smbus_bwrite,         viasmb_bwrite),
        DEVMETHOD(smbus_bread,          viasmb_bread),
-       
+
+       /* Bus interface */
+       DEVMETHOD(bus_print_child,      bus_generic_print_child),
+       DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
+       DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+       DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+       DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+       DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
+       DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
+
        { 0, 0 }
 };
 
@@ -930,7 +938,10 @@ static driver_t viapropm_driver = {
 DECLARE_DUMMY_MODULE(viapm);
 DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0);
 DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0);
+DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
 
+MODULE_DEPEND(viapm, pci, 1, 1, 1);
+MODULE_DEPEND(viapropm, pci, 1, 1, 1);
 MODULE_DEPEND(viapm, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
 MODULE_DEPEND(viapropm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
 MODULE_VERSION(viapm, 1);
index 813b4cf..aa8adb6 100644 (file)
@@ -1,6 +1,6 @@
 # $DragonFly: src/sys/dev/video/Makefile,v 1.2 2003/10/23 17:32:52 dillon Exp $
 #
 
-SUBDIR=bktr fb ${MACHINE_ARCH}
+SUBDIR=bktr cxm fb ${MACHINE_ARCH}
 
 .include <bsd.subdir.mk>
diff --git a/sys/dev/video/cxm/Makefile b/sys/dev/video/cxm/Makefile
new file mode 100644 (file)
index 0000000..a9bf524
--- /dev/null
@@ -0,0 +1,5 @@
+SUBDIR =
+SUBDIR += cxm
+SUBDIR += cxm_iic
+
+.include <bsd.subdir.mk>
diff --git a/sys/dev/video/cxm/cxm/Makefile b/sys/dev/video/cxm/cxm/Makefile
new file mode 100644 (file)
index 0000000..7b6df02
--- /dev/null
@@ -0,0 +1,7 @@
+.PATH: ${.CURDIR}/..
+KMOD   = cxm
+SRCS   = cxm.c cxm.h cxm_dec_fw.c cxm_enc_fw.c cxm_msp34xxx.c cxm_eeprom.c \
+         cxm_ir.c cxm_tuner.c cxm_saa7115.c opt_cxm.h \
+         bus_if.h device_if.h iicbb_if.h pci_if.h
+
+.include <bsd.kmod.mk>
index ce913a0..976e554 100644 (file)
@@ -65,13 +65,10 @@ static void cxm_iic_child_detached(device_t dev, device_t child);
 
 static int     cxm_iic_callback(device_t, int, caddr_t *);
 static int     cxm_iic_reset(device_t, u_char, u_char, u_char *);
-#if 0
 static int     cxm_iic_getscl(device_t);
-#endif
 static int     cxm_iic_getsda(device_t);
 static void    cxm_iic_setscl(device_t, int);
 static void    cxm_iic_setsda(device_t, int);
-static void    cxm_iic_setlines(device_t, int, int);
 
 static device_method_t cxm_iic_methods[] = {
        /* Device interface */
@@ -87,8 +84,10 @@ static device_method_t cxm_iic_methods[] = {
        /* iicbb interface */
        DEVMETHOD(iicbb_callback,       cxm_iic_callback),
        DEVMETHOD(iicbb_reset,          cxm_iic_reset),
-       DEVMETHOD(iicbb_getdataline,    cxm_iic_getsda),
-       DEVMETHOD(iicbb_setlines,       cxm_iic_setlines),
+       DEVMETHOD(iicbb_getscl,         cxm_iic_getscl),
+       DEVMETHOD(iicbb_getsda,         cxm_iic_getsda),
+       DEVMETHOD(iicbb_setscl,         cxm_iic_setscl),
+       DEVMETHOD(iicbb_setsda,         cxm_iic_setsda),
 
        { 0, 0 }
 };
@@ -101,8 +100,9 @@ static driver_t cxm_iic_driver = {
 
 static devclass_t cxm_iic_devclass;
 
-MODULE_VERSION(cxm_iic, 1);
 DRIVER_MODULE(cxm_iic, cxm, cxm_iic_driver, cxm_iic_devclass, 0, 0);
+MODULE_VERSION(cxm_iic, 1);
+MODULE_DEPEND(cxm_iic, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
 
 
 /*
@@ -300,7 +300,6 @@ cxm_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
 }
 
 
-#if 0
 static int
 cxm_iic_getscl(device_t dev)
 {
@@ -312,7 +311,6 @@ cxm_iic_getscl(device_t dev)
        /* Get sda */
        return CSR_READ_1(sc, CXM_REG_I2C_GETSCL);
 }
-#endif
 
 
 static int
@@ -368,15 +366,3 @@ cxm_iic_setsda(device_t dev, int val)
 
        CSR_READ_4(sc, CXM_REG_I2C_SETSDA);
 }
-
-
-static void
-cxm_iic_setlines(device_t dev, int ctrl, int data)
-{
-
-       cxm_iic_setscl(dev, ctrl);
-       cxm_iic_setsda(dev, data);
-
-       /* Wait for 10 usec */
-       DELAY(10);
-}
diff --git a/sys/dev/video/cxm/cxm_iic/Makefile b/sys/dev/video/cxm/cxm_iic/Makefile
new file mode 100644 (file)
index 0000000..6dca4f8
--- /dev/null
@@ -0,0 +1,6 @@
+.PATH: ${.CURDIR}/..
+KMOD   = cxm_iic
+SRCS   = cxm_i2c.c cxm.h \
+         opt_cxm.h bus_if.h device_if.h iicbb_if.h pci_if.h
+
+.include <bsd.kmod.mk>
index aed5ab7..a532b89 100644 (file)
@@ -228,7 +228,6 @@ dev/serial/stli/istallion.c         optional nowerror       stli
 dev/misc/labpc/labpc.c                 optional        labpc
 dev/misc/mse/mse.c                     optional        mse
 platform/pc32/isa/npx.c                        mandatory       npx
-bus/iicbus/i386/pcf.c                  optional        pcf
 bus/pci/i386/legacy.c                  optional        pci
 bus/pci/i386/pci_bus.c                 optional        pci
 bus/pci/i386/pci_cfgreg.c              optional        pci