summaryrefslogtreecommitdiffstats
path: root/sys/pci/amdsmb.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-01-11 19:56:24 +0000
committerjhb <jhb@FreeBSD.org>2007-01-11 19:56:24 +0000
commitafb4cfc54730fc4d0a2e88684ce0e206183e1e12 (patch)
tree939162cf86e1bf400a9cd9525a74dde0f62ddc2a /sys/pci/amdsmb.c
parent13d4be4423daeef02c737b4e4cc24cbb9b9b46b1 (diff)
downloadFreeBSD-src-afb4cfc54730fc4d0a2e88684ce0e206183e1e12.zip
FreeBSD-src-afb4cfc54730fc4d0a2e88684ce0e206183e1e12.tar.gz
Various updates to most of the smbus(4) drivers:
- Use printf() and device_printf() instead of log() in ichsmb(4). - Create the mutex sooner during ichsmb(4) attach. - Attach the interrupt handler later during ichsmb(4) attach to avoid races. - Don't try to set PCIM_CMD_PORTEN in ichsmb(4) attach as the PCI bus driver does this already. - Add locking to alpm(4), amdpm(4), amdsmb(4), intsmb(4), nfsmb(4), and viapm(4). - Axe ALPM_SMBIO_BASE_ADDR, it's not really safe to write arbitrary values into BARs, and the PCI bus layer will allocate resources now if needed. - Merge intpm(4) and intsmb(4) into just intsmb(4). Previously, intpm(4) attached to the PCI device and created an intsmb(4) child. Now, intsmb(4) just attaches to PCI directly. - Change several intsmb functions to take a softc instead of a device_t to make things simpler.
Diffstat (limited to 'sys/pci/amdsmb.c')
-rw-r--r--sys/pci/amdsmb.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/sys/pci/amdsmb.c b/sys/pci/amdsmb.c
index dde1f12..1b59a5a 100644
--- a/sys/pci/amdsmb.c
+++ b/sys/pci/amdsmb.c
@@ -2,11 +2,12 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
-#include <sys/systm.h>
+#include <sys/lock.h>
#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/uio.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -15,7 +16,6 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
-#include <dev/iicbus/iiconf.h>
#include <dev/smbus/smbconf.h>
#include "smbus_if.h"
@@ -86,15 +86,21 @@ struct amdsmb_softc {
struct resource *res;
bus_space_tag_t smbst;
bus_space_handle_t smbsh;
-
device_t smbus;
+ struct mtx lock;
};
-#define AMDSMB_ECINB(amdsmb, register) \
+#define AMDSMB_LOCK(amdsmb) mtx_lock(&(amdsmb)->lock)
+#define AMDSMB_UNLOCK(amdsmb) mtx_unlock(&(amdsmb)->lock)
+#define AMDSMB_LOCK_ASSERT(amdsmb) mtx_assert(&(amdsmb)->lock, MA_OWNED)
+
+#define AMDSMB_ECINB(amdsmb, register) \
(bus_space_read_1(amdsmb->smbst, amdsmb->smbsh, register))
#define AMDSMB_ECOUTB(amdsmb, register, value) \
(bus_space_write_1(amdsmb->smbst, amdsmb->smbsh, register, value))
+static int amdsmb_detach(device_t dev);
+
static int
amdsmb_probe(device_t dev)
{
@@ -133,11 +139,14 @@ amdsmb_attach(device_t dev)
amdsmb_sc->smbst = rman_get_bustag(amdsmb_sc->res);
amdsmb_sc->smbsh = rman_get_bushandle(amdsmb_sc->res);
+ mtx_init(&amdsmb_sc->lock, device_get_nameunit(dev), "amdsmb", MTX_DEF);
/* Allocate a new smbus device */
amdsmb_sc->smbus = device_add_child(dev, "smbus", -1);
- if (!amdsmb_sc->smbus)
+ if (!amdsmb_sc->smbus) {
+ amdsmb_detach(dev);
return (EINVAL);
+ }
bus_generic_attach(dev);
@@ -154,6 +163,7 @@ amdsmb_detach(device_t dev)
amdsmb_sc->smbus = NULL;
}
+ mtx_destroy(&amdsmb_sc->lock);
if (amdsmb_sc->res)
bus_release_resource(dev, SYS_RES_IOPORT, amdsmb_sc->rid,
amdsmb_sc->res);
@@ -209,6 +219,7 @@ static int
amdsmb_ec_read(struct amdsmb_softc *sc, u_char addr, u_char *data)
{
+ AMDSMB_LOCK_ASSERT(sc);
if (amdsmb_ec_wait_write(sc))
return (1);
AMDSMB_ECOUTB(sc, EC_CMD, EC_CMD_RD);
@@ -228,6 +239,7 @@ static int
amdsmb_ec_write(struct amdsmb_softc *sc, u_char addr, u_char data)
{
+ AMDSMB_LOCK_ASSERT(sc);
if (amdsmb_ec_wait_write(sc))
return (1);
AMDSMB_ECOUTB(sc, EC_CMD, EC_CMD_WR);
@@ -249,6 +261,7 @@ amdsmb_wait(struct amdsmb_softc *sc)
u_char sts, temp;
int error, count;
+ AMDSMB_LOCK_ASSERT(sc);
amdsmb_ec_read(sc, SMB_PRTCL, &temp);
if (temp != 0)
{
@@ -313,12 +326,14 @@ amdsmb_quick(device_t dev, u_char slave, int how)
panic("%s: unknown QUICK command (%x)!", __func__, how);
}
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_ADDR, slave);
amdsmb_ec_write(sc, SMB_PRTCL, protocol);
error = amdsmb_wait(sc);
AMDSMB_DEBUG(printf(", error=0x%x\n", error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -329,6 +344,7 @@ amdsmb_sendb(device_t dev, u_char slave, char byte)
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
int error;
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_CMD, byte);
amdsmb_ec_write(sc, SMB_ADDR, slave);
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE);
@@ -337,6 +353,7 @@ amdsmb_sendb(device_t dev, u_char slave, char byte)
AMDSMB_DEBUG(printf("amdsmb: SENDB to 0x%x, byte=0x%x, error=0x%x\n",
slave, byte, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -347,6 +364,7 @@ amdsmb_recvb(device_t dev, u_char slave, char *byte)
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
int error;
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_ADDR, slave);
amdsmb_ec_write(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE);
@@ -355,6 +373,7 @@ amdsmb_recvb(device_t dev, u_char slave, char *byte)
AMDSMB_DEBUG(printf("amdsmb: RECVB from 0x%x, byte=0x%x, error=0x%x\n",
slave, *byte, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -365,6 +384,7 @@ amdsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
int error;
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_CMD, cmd);
amdsmb_ec_write(sc, SMB_DATA, byte);
amdsmb_ec_write(sc, SMB_ADDR, slave);
@@ -374,6 +394,7 @@ amdsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
AMDSMB_DEBUG(printf("amdsmb: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, "
"error=0x%x\n", slave, cmd, byte, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -384,6 +405,7 @@ amdsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
int error;
+ AMDSMB_LOCK(sc);
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_BYTE_DATA);
@@ -393,6 +415,7 @@ amdsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
AMDSMB_DEBUG(printf("amdsmb: READB from 0x%x, cmd=0x%x, byte=0x%x, "
"error=0x%x\n", slave, cmd, (unsigned char)*byte, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -403,6 +426,7 @@ amdsmb_writew(device_t dev, u_char slave, char cmd, short word)
struct amdsmb_softc *sc = (struct amdsmb_softc *)device_get_softc(dev);
int error;
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_CMD, cmd);
amdsmb_ec_write(sc, SMB_DATA, word);
amdsmb_ec_write(sc, SMB_DATA + 1, word >> 8);
@@ -413,6 +437,7 @@ amdsmb_writew(device_t dev, u_char slave, char cmd, short word)
AMDSMB_DEBUG(printf("amdsmb: WRITEW to 0x%x, cmd=0x%x, word=0x%x, "
"error=0x%x\n", slave, cmd, word, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -424,6 +449,7 @@ amdsmb_readw(device_t dev, u_char slave, char cmd, short *word)
u_char temp[2];
int error;
+ AMDSMB_LOCK(sc);
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_WORD_DATA);
@@ -436,6 +462,7 @@ amdsmb_readw(device_t dev, u_char slave, char cmd, short *word)
AMDSMB_DEBUG(printf("amdsmb: READW from 0x%x, cmd=0x%x, word=0x%x, "
"error=0x%x\n", slave, cmd, (unsigned short)*word, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -449,6 +476,8 @@ amdsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
if (count < 1 || count > 32)
return (SMB_EINVAL);
+
+ AMDSMB_LOCK(sc);
amdsmb_ec_write(sc, SMB_CMD, cmd);
amdsmb_ec_write(sc, SMB_BCNT, count);
for (i = 0; i < count; i++)
@@ -460,6 +489,7 @@ amdsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
AMDSMB_DEBUG(printf("amdsmb: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, "
"error=0x%x", slave, count, cmd, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
@@ -473,6 +503,8 @@ amdsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
if (*count < 1 || *count > 32)
return (SMB_EINVAL);
+
+ AMDSMB_LOCK(sc);
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);
@@ -489,6 +521,7 @@ amdsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
AMDSMB_DEBUG(printf("amdsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, "
"error=0x%x", slave, *count, cmd, error));
+ AMDSMB_UNLOCK(sc);
return (error);
}
OpenPOWER on IntegriCloud