diff options
-rw-r--r-- | sys/dev/bktr/bktr_i2c.c | 4 | ||||
-rw-r--r-- | sys/dev/ichsmb/ichsmb.c | 33 | ||||
-rw-r--r-- | sys/dev/iicbus/iicsmb.c | 12 | ||||
-rw-r--r-- | sys/dev/smbus/smb.c | 21 | ||||
-rw-r--r-- | sys/dev/smbus/smb.h | 3 | ||||
-rw-r--r-- | sys/dev/smbus/smbconf.c | 90 | ||||
-rw-r--r-- | sys/dev/smbus/smbconf.h | 18 | ||||
-rw-r--r-- | sys/dev/smbus/smbus.c | 46 | ||||
-rw-r--r-- | sys/dev/smbus/smbus.h | 4 | ||||
-rw-r--r-- | sys/dev/smbus/smbus_if.m | 4 | ||||
-rw-r--r-- | sys/pci/alpm.c | 87 | ||||
-rw-r--r-- | sys/pci/amdpm.c | 95 | ||||
-rw-r--r-- | sys/pci/amdsmb.c | 29 | ||||
-rw-r--r-- | sys/pci/intpm.c | 30 | ||||
-rw-r--r-- | sys/pci/nfsmb.c | 29 | ||||
-rw-r--r-- | sys/pci/viapm.c | 103 |
16 files changed, 327 insertions, 281 deletions
diff --git a/sys/dev/bktr/bktr_i2c.c b/sys/dev/bktr/bktr_i2c.c index 20802f4..0bf5262 100644 --- a/sys/dev/bktr/bktr_i2c.c +++ b/sys/dev/bktr/bktr_i2c.c @@ -119,7 +119,7 @@ error: return (error); } -int bti2c_smb_callback(device_t dev, int index, caddr_t *data) +int bti2c_smb_callback(device_t dev, int index, void *data) { struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; @@ -338,4 +338,6 @@ bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte) return (0); } +DRIVER_MODULE(smbus, bktr, smbus_driver, smbus_devclass, 0, 0); + #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */ diff --git a/sys/dev/ichsmb/ichsmb.c b/sys/dev/ichsmb/ichsmb.c index 53a91d0..18aa32b 100644 --- a/sys/dev/ichsmb/ichsmb.c +++ b/sys/dev/ichsmb/ichsmb.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/errno.h> #include <sys/lock.h> +#include <sys/module.h> #include <sys/mutex.h> #include <sys/syslog.h> #include <sys/bus.h> @@ -136,7 +137,7 @@ ichsmb_attach(device_t dev) ********************************************************************/ int -ichsmb_callback(device_t dev, int index, caddr_t data) +ichsmb_callback(device_t dev, int index, void *data) { int smb_error = 0; @@ -381,7 +382,7 @@ 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; @@ -403,7 +404,7 @@ ichsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) } 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; @@ -411,10 +412,10 @@ 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; @@ -423,11 +424,13 @@ ichsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf) 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_D0, *count); /* XXX? */ bus_space_write_1(sc->io_bst, sc->io_bsh, 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); + if ((smb_error = ichsmb_wait(sc)) == SMB_ENOERR) { + bcopy(sc->block_data, buf, min(sc->block_count, *count)); + *count = sc->block_count; + } mtx_unlock(&sc->mutex); DBG("smb_error=%d\n", smb_error); #if ICHSMB_DEBUG @@ -669,14 +672,20 @@ ichsmb_release_resources(sc_p sc) } } -int ichsmb_detach(device_t dev) +int +ichsmb_detach(device_t dev) { const sc_p sc = device_get_softc(dev); + int error; - mtx_destroy(&sc->mutex); - bus_generic_detach(dev); + error = bus_generic_detach(dev); + if (error) + return (error); device_delete_child(dev, sc->smb); ichsmb_release_resources(sc); + mtx_destroy(&sc->mutex); return 0; } + +DRIVER_MODULE(smbus, ichsmb, smbus_driver, smbus_devclass, 0, 0); diff --git a/sys/dev/iicbus/iicsmb.c b/sys/dev/iicbus/iicsmb.c index c2d45d4..0788184 100644 --- a/sys/dev/iicbus/iicsmb.c +++ b/sys/dev/iicbus/iicsmb.c @@ -83,7 +83,7 @@ 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_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); @@ -93,7 +93,7 @@ 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; @@ -247,7 +247,7 @@ end: } 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; @@ -482,7 +482,7 @@ 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; @@ -496,9 +496,10 @@ iicsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf) if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT))) goto error; - if ((error = iicbus_read(parent, buf, (int)count, &read, + if ((error = iicbus_read(parent, buf, (int)*count, &read, IIC_LAST_READ, IICBUS_TIMEOUT))) goto error; + *count = read; error: iicbus_stop(parent); @@ -506,6 +507,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/dev/smbus/smb.c b/sys/dev/smbus/smb.c index ca4fbe6..e5944bd 100644 --- a/sys/dev/smbus/smb.c +++ b/sys/dev/smbus/smb.c @@ -55,6 +55,7 @@ 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); @@ -63,6 +64,7 @@ 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), @@ -92,6 +94,14 @@ static struct cdevsw smb_cdevsw = { .d_name = "smb", }; +static void +smb_identify(driver_t *driver, device_t parent) +{ + + if (device_find_child(parent, "smb", -1) == NULL) + BUS_ADD_CHILD(parent, 0, "smb", -1); +} + static int smb_probe(device_t dev) { @@ -171,6 +181,7 @@ smbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t device_t smbdev = IIC_DEVICE(minor(dev)); int error; short w; + u_char count; char c; if (sc == NULL) @@ -259,15 +270,17 @@ smbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t } break; + case SMB_OLD_BREAD: case SMB_BREAD: if (s->count && s->data.byte_ptr) { - if (s->count > SMB_MAXBLOCKSIZE) - s->count = SMB_MAXBLOCKSIZE; + count = min(s->count, SMB_MAXBLOCKSIZE); error = smbus_error(smbus_bread(parent, s->slave, - s->cmd, s->count, buf)); + s->cmd, &count, buf)); if (error) break; - error = copyout(buf, s->data.byte_ptr, s->count); + error = copyout(buf, s->data.byte_ptr, + min(count, s->count)); + s->count = count; } break; diff --git a/sys/dev/smbus/smb.h b/sys/dev/smbus/smb.h index 387515f..32347f8 100644 --- a/sys/dev/smbus/smb.h +++ b/sys/dev/smbus/smb.h @@ -64,6 +64,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/dev/smbus/smbconf.c b/sys/dev/smbus/smbconf.c index 8a85009..06d225a 100644 --- a/sys/dev/smbus/smbconf.c +++ b/sys/dev/smbus/smbconf.c @@ -30,7 +30,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <dev/smbus/smbconf.h> @@ -43,13 +45,13 @@ __FBSDID("$FreeBSD$"); void smbus_intr(device_t bus, u_char devaddr, char low, char high, int error) { - struct smbus_softc *sc = (struct smbus_softc *)device_get_softc(bus); + struct smbus_softc *sc = device_get_softc(bus); /* call owner's intr routine */ + mtx_lock(&sc->lock); if (sc->owner) SMBUS_INTR(sc->owner, devaddr, low, high, error); - - return; + mtx_unlock(&sc->lock); } /* @@ -65,17 +67,18 @@ 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); } @@ -86,16 +89,16 @@ smbus_poll(struct smbus_softc *sc, int how) int error; switch (how) { - case (SMB_WAIT | SMB_INTR): - error = tsleep(sc, SMBPRI|PCATCH, "smbreq", 0); + case SMB_WAIT | SMB_INTR: + error = msleep(sc, &sc->lock, SMBPRI|PCATCH, "smbreq", 0); break; - case (SMB_WAIT | SMB_NOINTR): - error = tsleep(sc, SMBPRI, "smbreq", 0); + case SMB_WAIT | SMB_NOINTR: + error = msleep(sc, &sc->lock, SMBPRI, "smbreq", 0); break; default: - return (EWOULDBLOCK); + error = EWOULDBLOCK; break; } @@ -112,35 +115,38 @@ 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 s, 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); + mtx_lock(&sc->lock); do { - error = SMBUS_CALLBACK(device_get_parent(bus), - SMB_REQUEST_BUS, (caddr_t)&how); + mtx_unlock(&sc->lock); + error = SMBUS_CALLBACK(parent, SMB_REQUEST_BUS, &how); + mtx_lock(&sc->lock); + if (error) error = smbus_poll(sc, how); } while (error == EWOULDBLOCK); - while (!error) { - s = splhigh(); - if (sc->owner && sc->owner != dev) { - splx(s); - + while (error == 0) { + if (sc->owner && sc->owner != dev) error = smbus_poll(sc, how); - } else { + else { sc->owner = dev; - - splx(s); - return (0); + break; } /* free any allocated resource */ - if (error) - SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, - (caddr_t)&how); + if (error) { + mtx_unlock(&sc->lock); + SMBUS_CALLBACK(parent, SMB_RELEASE_BUS, &how); + return (error); + } } + mtx_unlock(&sc->lock); return (error); } @@ -153,8 +159,8 @@ smbus_request_bus(device_t bus, device_t dev, int how) int smbus_release_bus(device_t bus, device_t dev) { - struct smbus_softc *sc = (struct smbus_softc *)device_get_softc(bus); - int s, error; + struct smbus_softc *sc = device_get_softc(bus); + int error; /* first, ask the underlying layers if the release is ok */ error = SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, NULL); @@ -162,17 +168,15 @@ smbus_release_bus(device_t bus, device_t dev) if (error) return (error); - s = splhigh(); - if (sc->owner != dev) { - splx(s); - return (EACCES); - } - - sc->owner = 0; - splx(s); + mtx_lock(&sc->lock); + if (sc->owner == dev) { + sc->owner = NULL; - /* wakeup waiting processes */ - wakeup(sc); + /* wakeup waiting processes */ + wakeup(sc); + } else + error = EACCES; + mtx_unlock(&sc->lock); - return (0); + return (error); } diff --git a/sys/dev/smbus/smbconf.h b/sys/dev/smbus/smbconf.h index 64b0a33..a3d403d 100644 --- a/sys/dev/smbus/smbconf.h +++ b/sys/dev/smbus/smbconf.h @@ -59,6 +59,7 @@ #define SMB_EABORT 0x10 #define SMB_ETIMEOUT 0x20 #define SMB_EBUSY 0x40 +#define SMB_EINVAL 0x100 /* * How Quick command is executed @@ -69,16 +70,19 @@ /* * ivars codes */ -#define SMBUS_IVAR_ADDR 0x1 /* I2C address of the device */ +#define SMBUS_IVAR_ADDR 0x1 /* slave address of the device */ -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); +int smbus_request_bus(device_t, device_t, int); +int smbus_release_bus(device_t, device_t); +device_t smbus_alloc_bus(device_t); +int smbus_error(int error); -extern void smbus_intr(device_t, u_char, char low, char high, int error); +void smbus_intr(device_t, u_char, char low, char high, int error); -extern u_char smbus_get_addr(device_t); +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)) diff --git a/sys/dev/smbus/smbus.c b/sys/dev/smbus/smbus.c index 6a67eb6..ce7bdc6 100644 --- a/sys/dev/smbus/smbus.c +++ b/sys/dev/smbus/smbus.c @@ -30,32 +30,30 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <dev/smbus/smbconf.h> #include <dev/smbus/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)) - -static devclass_t smbus_devclass; - /* * Device methods */ static int smbus_probe(device_t); static int smbus_attach(device_t); +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_detach, smbus_detach), /* bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), @@ -63,12 +61,14 @@ static device_method_t smbus_methods[] = { { 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 @@ -77,6 +77,7 @@ static driver_t smbus_driver = { static int smbus_probe(device_t dev) { + device_set_desc(dev, "System Management Bus"); return (0); @@ -85,25 +86,32 @@ smbus_probe(device_t dev) static int smbus_attach(device_t dev) { - device_add_child(dev, NULL, -1); + struct smbus_softc *sc = device_get_softc(dev); + + mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF); + bus_generic_probe(dev); bus_generic_attach(dev); return (0); } +static int +smbus_detach(device_t dev) +{ + struct smbus_softc *sc = device_get_softc(dev); + int error; + + error = bus_generic_detach(dev); + if (error) + return (error); + mtx_destroy(&sc->lock); + + return (0); +} + void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high) { - return; } -DRIVER_MODULE(smbus, iicsmb, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, bktr, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, alpm, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, ichsmb, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, amdpm, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, amdsmb, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, nfsmb, smbus_driver, smbus_devclass, 0, 0); -DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0); MODULE_VERSION(smbus, SMBUS_MODVER); diff --git a/sys/dev/smbus/smbus.h b/sys/dev/smbus/smbus.h index cd84cc8..f8335e8 100644 --- a/sys/dev/smbus/smbus.h +++ b/sys/dev/smbus/smbus.h @@ -30,10 +30,10 @@ #define __SMBUS_H struct smbus_softc { - device_t owner; /* smbus owner device structure */ + struct mtx lock; }; -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/dev/smbus/smbus_if.m b/sys/dev/smbus/smbus_if.m index 6b213e1..d969e25 100644 --- a/sys/dev/smbus/smbus_if.m +++ b/sys/dev/smbus/smbus_if.m @@ -47,7 +47,7 @@ METHOD void intr { METHOD int callback { device_t dev; int index; - caddr_t data; + void *data; }; # @@ -146,6 +146,6 @@ METHOD int bread { device_t dev; u_char slave; char cmd; - u_char count; + u_char *count; char *buf; }; diff --git a/sys/pci/alpm.c b/sys/pci/alpm.c index e6f8149..d90d919 100644 --- a/sys/pci/alpm.c +++ b/sys/pci/alpm.c @@ -259,7 +259,7 @@ alpm_detach(device_t dev) } static int -alpm_callback(device_t dev, int index, caddr_t *data) +alpm_callback(device_t dev, int index, void *data) { int error = 0; @@ -525,82 +525,76 @@ static int alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { struct alpm_softc *sc = (struct alpm_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); alpm_clear(sc); if(!alpm_idle(sc)) return (SMB_EBUSY); - remain = count; - while (remain) { - len = min(remain, 32); - - ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB); + 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); - - ALPM_SMBOUTB(sc, SMBHDATA, len); + /* set the cmd and reset the + * 32-byte long internal buffer */ + ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR); - /* fill the 32-byte internal buffer */ - for (i=0; i<len; i++) { - ALPM_SMBOUTB(sc, SMBHBLOCK, buf[count-remain+i]); - DELAY(2); - } - ALPM_SMBOUTB(sc, SMBHCMD, cmd); - ALPM_SMBOUTB(sc, SMBSTART, 0xff); + ALPM_SMBOUTB(sc, SMBHDATA, count); - if ((error = alpm_wait(sc)) != SMB_ENOERR) - goto error; - - remain -= len; + /* fill the 32-byte internal buffer */ + for (i = 0; i < count; i++) { + ALPM_SMBOUTB(sc, SMBHBLOCK, buf[i]); + DELAY(2); } + ALPM_SMBOUTB(sc, SMBHCMD, cmd); + ALPM_SMBOUTB(sc, SMBSTART, 0xff); + + error = alpm_wait(sc); -error: ALPM_DEBUG(printf("alpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); return (error); } static int -alpm_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 alpm_softc *sc = (struct alpm_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); alpm_clear(sc); if (!alpm_idle(sc)) return (SMB_EBUSY); - remain = count; - while (remain) { - ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB); + 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); + /* set the cmd and reset the + * 32-byte long internal buffer */ + ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR); - ALPM_SMBOUTB(sc, SMBHCMD, cmd); - ALPM_SMBOUTB(sc, SMBSTART, 0xff); + ALPM_SMBOUTB(sc, SMBHCMD, cmd); + ALPM_SMBOUTB(sc, SMBSTART, 0xff); - if ((error = alpm_wait(sc)) != SMB_ENOERR) + if ((error = alpm_wait(sc)) != SMB_ENOERR) goto error; - len = ALPM_SMBINB(sc, SMBHDATA); + len = ALPM_SMBINB(sc, SMBHDATA); - /* read the 32-byte internal buffer */ - for (i=0; i<len; i++) { - buf[count-remain+i] = ALPM_SMBINB(sc, SMBHBLOCK); - DELAY(2); - } - - remain -= len; + /* read the 32-byte internal buffer */ + for (i = 0; i < len; i++) { + data = ALPM_SMBINB(sc, SMBHBLOCK); + if (i < *count) + buf[i] = data; + DELAY(2); } + *count = len; + error: - ALPM_DEBUG(printf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); + ALPM_DEBUG(printf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); return (error); } @@ -635,6 +629,7 @@ static driver_t alpm_driver = { }; DRIVER_MODULE(alpm, pci, alpm_driver, alpm_devclass, 0, 0); +DRIVER_MODULE(smbus, alpm, smbus_driver, smbus_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/pci/amdpm.c b/sys/pci/amdpm.c index 841b037..fb34642 100644 --- a/sys/pci/amdpm.c +++ b/sys/pci/amdpm.c @@ -236,7 +236,7 @@ amdpm_detach(device_t dev) } static int -amdpm_callback(device_t dev, int index, caddr_t *data) +amdpm_callback(device_t dev, int index, void *data) { int error = 0; @@ -504,84 +504,79 @@ static int amdpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { struct amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev); - u_char remain, len, i; - int error = SMB_ENOERR; + u_char i; + int error; u_short l; + if (count < 1 || count > 32) + return (SMB_EINVAL); amdpm_clear(sc); if(!amdpm_idle(sc)) return (SMB_EBUSY); - remain = count; - while (remain) { - len = min(remain, 32); - - AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave & ~LSB); + 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. - */ - - AMDPM_SMBOUTW(sc, AMDSMB_HSTDATA, len); - - /* Fill the 32-byte internal buffer */ - for (i=0; i<len; i++) { - AMDPM_SMBOUTB(sc, AMDSMB_HSTDFIFO, buf[count-remain+i]); - DELAY(2); - } - 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 = amdpm_wait(sc)) != SMB_ENOERR) - goto error; - - remain -= len; + /* + * Do we have to reset the internal 32-byte buffer? + * Can't see how to do this from the data sheet. + */ + AMDPM_SMBOUTW(sc, AMDSMB_HSTDATA, count); + + /* Fill the 32-byte internal buffer */ + for (i = 0; i < count; i++) { + AMDPM_SMBOUTB(sc, AMDSMB_HSTDFIFO, buf[i]); + DELAY(2); } + 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); + + error = amdpm_wait(sc); -error: AMDPM_DEBUG(printf("amdpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); return (error); } static int -amdpm_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 amdpm_softc *sc = (struct amdpm_softc *)device_get_softc(dev); - u_char remain, len, i; - int error = SMB_ENOERR; + u_char data, len, i; + int error; u_short l; + if (*count < 1 || *count > 32) + return (SMB_EINVAL); amdpm_clear(sc); if (!amdpm_idle(sc)) return (SMB_EBUSY); - remain = count; - while (remain) { - AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB); + AMDPM_SMBOUTW(sc, AMDSMB_HSTADDR, slave | LSB); - AMDPM_SMBOUTB(sc, AMDSMB_HSTCMD, cmd); + 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); + 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 = amdpm_wait(sc)) != SMB_ENOERR) - goto error; - - len = AMDPM_SMBINW(sc, AMDSMB_HSTDATA); + if ((error = amdpm_wait(sc)) != SMB_ENOERR) + goto error; - /* Read the 32-byte internal buffer */ - for (i=0; i<len; i++) { - buf[count-remain+i] = AMDPM_SMBINB(sc, AMDSMB_HSTDFIFO); - DELAY(2); - } + len = AMDPM_SMBINW(sc, AMDSMB_HSTDATA); - remain -= len; + /* Read the 32-byte internal buffer */ + for (i = 0; i < len; i++) { + data = AMDPM_SMBINB(sc, AMDSMB_HSTDFIFO); + if (i < *count) + buf[i] = data; + DELAY(2); } + *count = len; + error: - AMDPM_DEBUG(printf("amdpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); + AMDPM_DEBUG(printf("amdpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); return (error); } @@ -616,8 +611,8 @@ static driver_t amdpm_driver = { }; DRIVER_MODULE(amdpm, pci, amdpm_driver, amdpm_devclass, 0, 0); +DRIVER_MODULE(smbus, amdpm, smbus_driver, smbus_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/pci/amdsmb.c b/sys/pci/amdsmb.c index 60febd5..dde1f12 100644 --- a/sys/pci/amdsmb.c +++ b/sys/pci/amdsmb.c @@ -162,7 +162,7 @@ amdsmb_detach(device_t dev) } static int -amdsmb_callback(device_t dev, int index, caddr_t *data) +amdsmb_callback(device_t dev, int index, void *data) { int error = 0; @@ -444,13 +444,14 @@ static int amdsmb_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); - u_char len, i; + u_char i; int error; - len = min(count, 32); + if (count < 1 || count > 32) + return (SMB_EINVAL); amdsmb_ec_write(sc, SMB_CMD, cmd); - amdsmb_ec_write(sc, SMB_BCNT, len); - for (i = 0; i < len; i++) + amdsmb_ec_write(sc, SMB_BCNT, count); + for (i = 0; i < count; i++) amdsmb_ec_write(sc, SMB_DATA + i, buf[i]); amdsmb_ec_write(sc, SMB_ADDR, slave); amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA); @@ -464,25 +465,30 @@ amdsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) } static int -amdsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf) +amdsmb_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); - u_char len, i; + u_char data, len, i; int error; + if (*count < 1 || *count > 32) + return (SMB_EINVAL); amdsmb_ec_write(sc, SMB_CMD, cmd); amdsmb_ec_write(sc, SMB_ADDR, slave); amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA); if ((error = amdsmb_wait(sc)) == SMB_ENOERR) { amdsmb_ec_read(sc, SMB_BCNT, &len); - len = min(len, 32); - for (i = 0; i < len; i++) - amdsmb_ec_read(sc, SMB_DATA + i, buf + i); + for (i = 0; i < len; i++) { + amdsmb_ec_read(sc, SMB_DATA + i, &data); + if (i < *count) + buf[i] = data; + } + *count = len; } AMDSMB_DEBUG(printf("amdsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, " - "error=0x%x", slave, count, cmd, error)); + "error=0x%x", slave, *count, cmd, error)); return (error); } @@ -517,6 +523,7 @@ static driver_t amdsmb_driver = { }; DRIVER_MODULE(amdsmb, pci, amdsmb_driver, amdsmb_devclass, 0, 0); +DRIVER_MODULE(smbus, amdsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(amdsmb, pci, 1, 1, 1); MODULE_DEPEND(amdsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); diff --git a/sys/pci/intpm.c b/sys/pci/intpm.c index 1e454bb..3bf1c2c 100644 --- a/sys/pci/intpm.c +++ b/sys/pci/intpm.c @@ -71,7 +71,7 @@ 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_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); @@ -81,7 +81,7 @@ 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 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); @@ -175,7 +175,7 @@ intsmb_attach(device_t dev) } static int -intsmb_callback(device_t dev, int index, caddr_t data) +intsmb_callback(device_t dev, int index, void *data) { int error = 0; intrmask_t s; @@ -585,7 +585,7 @@ intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev); error=intsmb_free(dev); if(count>SMBBLOCKTRANS_MAX||count==0) - error=EINVAL; + error=SMB_EINVAL; if(!error){ /*Reset internal array index*/ bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTCNT); @@ -603,32 +603,35 @@ 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) +intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) { int error,i; + u_char data, nread; struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev); error=intsmb_free(dev); - if(count>SMBBLOCKTRANS_MAX||count==0) - error=EINVAL; + if(*count>SMBBLOCKTRANS_MAX||*count==0) + error=SMB_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); + 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, + nread= 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, + if(nread!=0&&nread<=SMBBLOCKTRANS_MAX){ + for(i=0;i<nread;i++){ + data = bus_space_read_1(sc->st, sc->sh, PIIX4_SMBBLKDAT); + if (i < *count) + buf[i] = data; } + *count = nread; } else{ error=EIO; @@ -739,6 +742,7 @@ intpm_probe(device_t dev) } } DRIVER_MODULE(intpm, pci , intpm_pci_driver, intpm_devclass, 0, 0); +DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(intpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); MODULE_VERSION(intpm, 1); diff --git a/sys/pci/nfsmb.c b/sys/pci/nfsmb.c index 5cd1b08..1511121 100644 --- a/sys/pci/nfsmb.c +++ b/sys/pci/nfsmb.c @@ -252,7 +252,7 @@ nfsmb_detach(device_t dev) } static int -nfsmb_callback(device_t dev, int index, caddr_t *data) +nfsmb_callback(device_t dev, int index, void *data) { int error = 0; @@ -456,13 +456,14 @@ static int nfsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev); - u_char len, i; + u_char i; int error; - len = min(count, 32); + if (count < 1 || count > 32) + return (SMB_EINVAL); NFSMB_SMBOUTB(sc, SMB_CMD, cmd); - NFSMB_SMBOUTB(sc, SMB_BCNT, len); - for (i = 0; i < len; i++) + NFSMB_SMBOUTB(sc, SMB_BCNT, count); + for (i = 0; i < count; i++) NFSMB_SMBOUTB(sc, SMB_DATA + i, buf[i]); NFSMB_SMBOUTB(sc, SMB_ADDR, slave); NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA); @@ -475,24 +476,29 @@ nfsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) } static int -nfsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf) +nfsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) { struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev); - u_char len, i; + u_char data, len, i; int error; + if (*count < 1 || *count > 32) + return (SMB_EINVAL); NFSMB_SMBOUTB(sc, SMB_CMD, cmd); NFSMB_SMBOUTB(sc, SMB_ADDR, slave); NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA); if ((error = nfsmb_wait(sc)) == SMB_ENOERR) { len = NFSMB_SMBINB(sc, SMB_BCNT); - len = min(len, 32); - for (i = 0; i < len; i++) - buf[i] = NFSMB_SMBINB(sc, SMB_DATA + i); + for (i = 0; i < len; i++) { + data = NFSMB_SMBINB(sc, SMB_DATA + i); + if (i < *count) + buf[i] = data; + } + *count = len; } - NFSMB_DEBUG(printf("nfsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); + NFSMB_DEBUG(printf("nfsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); return (error); } @@ -555,6 +561,7 @@ static driver_t nfsmbsub_driver = { DRIVER_MODULE(nfsmb, pci, nfsmb_driver, nfsmb_devclass, 0, 0); DRIVER_MODULE(nfsmb, nfsmb, nfsmbsub_driver, nfsmb_devclass, 0, 0); +DRIVER_MODULE(smbus, nfsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(nfsmb, pci, 1, 1, 1); MODULE_DEPEND(nfsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); diff --git a/sys/pci/viapm.c b/sys/pci/viapm.c index 0bddb22..a26703e 100644 --- a/sys/pci/viapm.c +++ b/sys/pci/viapm.c @@ -640,7 +640,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: @@ -670,7 +670,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); @@ -692,7 +692,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); @@ -714,7 +714,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); @@ -737,7 +737,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); @@ -760,7 +760,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); @@ -785,7 +785,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); @@ -808,37 +808,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(printf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); return (error); @@ -846,40 +840,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); - - if ((error = viapm_wait(viapm)) != SMB_ENOERR) - goto error; + return (SMB_EBUSY); - 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(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); + VIAPM_DEBUG(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); return (error); } @@ -954,6 +948,7 @@ static driver_t viapropm_driver = { 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); |