diff options
author | jhb <jhb@FreeBSD.org> | 2007-01-11 19:56:24 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-01-11 19:56:24 +0000 |
commit | afb4cfc54730fc4d0a2e88684ce0e206183e1e12 (patch) | |
tree | 939162cf86e1bf400a9cd9525a74dde0f62ddc2a /sys/pci/viapm.c | |
parent | 13d4be4423daeef02c737b4e4cc24cbb9b9b46b1 (diff) | |
download | FreeBSD-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/viapm.c')
-rw-r--r-- | sys/pci/viapm.c | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/sys/pci/viapm.c b/sys/pci/viapm.c index 4c990c2..6a7fac5 100644 --- a/sys/pci/viapm.c +++ b/sys/pci/viapm.c @@ -30,11 +30,12 @@ __FBSDID("$FreeBSD$"); #include "opt_isa.h" #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> @@ -82,6 +83,10 @@ static int viapm_debug = 0; #define VIAPM_TYP_686A 4 #define VIAPM_TYP_8233 5 +#define VIAPM_LOCK(sc) mtx_lock(&(sc)->lock) +#define VIAPM_UNLOCK(sc) mtx_unlock(&(sc)->lock) +#define VIAPM_LOCK_ASSERT(sc) mtx_assert(&(sc)->lock, MA_OWNED) + struct viapm_softc { int type; u_int32_t base; @@ -92,9 +97,9 @@ struct viapm_softc { struct resource *iores; struct resource *irqres; void *irqih; - device_t iicbb; device_t smbus; + struct mtx lock; }; static devclass_t viapm_devclass; @@ -329,6 +334,7 @@ viapm_pro_attach(device_t dev) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); u_int32_t l; + mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF); if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &viapm->iorid, RF_ACTIVE))) { device_printf(dev, "could not allocate bus space\n"); @@ -394,6 +400,7 @@ error: if (viapm->irqres) bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres); #endif + mtx_destroy(&viapm->lock); return ENXIO; } @@ -402,11 +409,12 @@ static int viapm_586b_attach(device_t dev) { struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); - + + mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF); if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &viapm->iorid, RF_ACTIVE | RF_SHAREABLE))) { device_printf(dev, "could not allocate bus resource\n"); - return ENXIO; + goto error; } viapm->st = rman_get_bustag(viapm->iores); viapm->sh = rman_get_bushandle(viapm->iores); @@ -425,6 +433,7 @@ error: if (viapm->iores) bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores); + mtx_destroy(&viapm->lock); return ENXIO; } @@ -432,16 +441,16 @@ static int viapm_586b_detach(device_t dev) { struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); - int error; bus_generic_detach(dev); if (viapm->iicbb) { device_delete_child(dev, viapm->iicbb); } - if (viapm->iores && (error = bus_release_resource(dev, SYS_RES_IOPORT, - viapm->iorid, viapm->iores))) - return (error); + if (viapm->iores) + bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, + viapm->iores); + mtx_destroy(&viapm->lock); return 0; } @@ -450,22 +459,18 @@ static int viapm_pro_detach(device_t dev) { struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); - int error; bus_generic_detach(dev); if (viapm->smbus) { device_delete_child(dev, viapm->smbus); } - if ((error = bus_release_resource(dev, SYS_RES_IOPORT, - viapm->iorid, viapm->iores))) - return (error); + bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores); #ifdef notyet - if ((error = bus_release_resource(dev, SYS_RES_IRQ, - viapm->irqrid, viapm->irqres)) - return (error); + bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres); #endif + mtx_destroy(&viapm->lock); return 0; } @@ -482,6 +487,7 @@ viabb_setscl(device_t dev, int ctrl) struct viapm_softc *viapm = device_get_softc(dev); u_char val; + VIAPM_LOCK(viapm); val = VIAPM_INB(GPIO_VAL); if (ctrl) @@ -490,6 +496,7 @@ viabb_setscl(device_t dev, int ctrl) val &= ~VIAPM_SCL; VIAPM_OUTB(GPIO_VAL, val); + VIAPM_UNLOCK(viapm); return; } @@ -500,6 +507,7 @@ viabb_setsda(device_t dev, int data) struct viapm_softc *viapm = device_get_softc(dev); u_char val; + VIAPM_LOCK(viapm); val = VIAPM_INB(GPIO_VAL); if (data) @@ -508,6 +516,7 @@ viabb_setsda(device_t dev, int data) val &= ~VIAPM_SDA; VIAPM_OUTB(GPIO_VAL, val); + VIAPM_UNLOCK(viapm); return; } @@ -526,16 +535,24 @@ static int viabb_getscl(device_t dev) { struct viapm_softc *viapm = device_get_softc(dev); + u_char val; - return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SCL) != 0); + VIAPM_LOCK(viapm); + val = VIAPM_INB(EXTSMI_VAL); + VIAPM_UNLOCK(viapm); + return ((val & VIAPM_SCL) != 0); } static int viabb_getsda(device_t dev) { struct viapm_softc *viapm = device_get_softc(dev); + u_char val; - return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SDA) != 0); + VIAPM_LOCK(viapm); + val = VIAPM_INB(EXTSMI_VAL); + VIAPM_UNLOCK(viapm); + return ((val & VIAPM_SDA) != 0); } static int @@ -579,6 +596,8 @@ viapm_wait(struct viapm_softc *viapm) u_char sts = 0; int error; + VIAPM_LOCK_ASSERT(viapm); + /* wait for command to complete and SMBus controller is idle */ while(count--) { DELAY(10); @@ -636,9 +655,12 @@ viasmb_quick(device_t dev, u_char slave, int how) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } switch (how) { case SMB_QWRITE: @@ -656,6 +678,7 @@ viasmb_quick(device_t dev, u_char slave, int how) VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_QUICK); error = viapm_wait(viapm); + VIAPM_UNLOCK(viapm); return (error); } @@ -666,9 +689,12 @@ viasmb_sendb(device_t dev, u_char slave, char byte) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave & ~ LSB); VIAPM_OUTB(SMBHCMD, byte); @@ -678,6 +704,7 @@ viasmb_sendb(device_t dev, u_char slave, char byte) error = viapm_wait(viapm); VIAPM_DEBUG(printf("viapm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -688,9 +715,12 @@ viasmb_recvb(device_t dev, u_char slave, char *byte) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave | LSB); @@ -700,6 +730,7 @@ viasmb_recvb(device_t dev, u_char slave, char *byte) *byte = VIAPM_INB(SMBHDATA0); VIAPM_DEBUG(printf("viapm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -710,9 +741,12 @@ viasmb_writeb(device_t dev, u_char slave, char cmd, char byte) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave & ~ LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -723,6 +757,7 @@ viasmb_writeb(device_t dev, u_char slave, char cmd, char byte) error = viapm_wait(viapm); VIAPM_DEBUG(printf("viapm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -733,9 +768,12 @@ viasmb_readb(device_t dev, u_char slave, char cmd, char *byte) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave | LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -746,6 +784,7 @@ viasmb_readb(device_t dev, u_char slave, char cmd, char *byte) *byte = VIAPM_INB(SMBHDATA0); VIAPM_DEBUG(printf("viapm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -756,9 +795,12 @@ viasmb_writew(device_t dev, u_char slave, char cmd, short word) struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev); int error; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave & ~ LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -770,6 +812,7 @@ viasmb_writew(device_t dev, u_char slave, char cmd, short word) error = viapm_wait(viapm); VIAPM_DEBUG(printf("viapm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -781,9 +824,12 @@ viasmb_readw(device_t dev, u_char slave, char cmd, short *word) int error; u_char high, low; + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave | LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -798,6 +844,7 @@ viasmb_readw(device_t dev, u_char slave, char cmd, short *word) } VIAPM_DEBUG(printf("viapm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error)); + VIAPM_UNLOCK(viapm); return (error); } @@ -812,9 +859,12 @@ viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) if (count < 1 || count > 32) return (SMB_EINVAL); + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave & ~LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -832,6 +882,7 @@ viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) error = viapm_wait(viapm); VIAPM_DEBUG(printf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); + VIAPM_UNLOCK(viapm); return (error); @@ -847,9 +898,12 @@ viasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) if (*count < 1 || *count > 32) return (SMB_EINVAL); + VIAPM_LOCK(viapm); viapm_clear(viapm); - if (viapm_busy(viapm)) + if (viapm_busy(viapm)) { + VIAPM_UNLOCK(viapm); return (SMB_EBUSY); + } VIAPM_OUTB(SMBHADDR, slave | LSB); VIAPM_OUTB(SMBHCMD, cmd); @@ -872,6 +926,7 @@ viasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) error: VIAPM_DEBUG(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); + VIAPM_UNLOCK(viapm); return (error); } |