summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/bktr/bktr_i2c.c4
-rw-r--r--sys/dev/ichsmb/ichsmb.c33
-rw-r--r--sys/dev/iicbus/iicsmb.c12
-rw-r--r--sys/dev/smbus/smb.c21
-rw-r--r--sys/dev/smbus/smb.h3
-rw-r--r--sys/dev/smbus/smbconf.c90
-rw-r--r--sys/dev/smbus/smbconf.h18
-rw-r--r--sys/dev/smbus/smbus.c46
-rw-r--r--sys/dev/smbus/smbus.h4
-rw-r--r--sys/dev/smbus/smbus_if.m4
10 files changed, 139 insertions, 96 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;
};
OpenPOWER on IntegriCloud