diff options
Diffstat (limited to 'sys/dev/iicbus')
-rw-r--r-- | sys/dev/iicbus/iic.c | 20 | ||||
-rw-r--r-- | sys/dev/iicbus/iiconf.c | 17 |
2 files changed, 28 insertions, 9 deletions
diff --git a/sys/dev/iicbus/iic.c b/sys/dev/iicbus/iic.c index e41d08b..6bcadf9 100644 --- a/sys/dev/iicbus/iic.c +++ b/sys/dev/iicbus/iic.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: iic.c,v 1.5 1998/12/07 21:58:16 archie Exp $ + * $Id: iic.c,v 1.6 1999/01/09 18:08:24 nsouch Exp $ * */ #include <sys/param.h> @@ -35,6 +35,7 @@ #include <sys/buf.h> #include <sys/uio.h> #include <sys/malloc.h> +#include <sys/fcntl.h> #include <machine/clock.h> @@ -169,12 +170,17 @@ iicwrite(dev_t dev, struct uio * uio, int ioflag) if (sc->sc_count == 0) return (EINVAL); + if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT))) + return (error); + count = min(uio->uio_resid, BUFSIZE); uiomove(sc->sc_buffer, count, uio); error = iicbus_block_write(device_get_parent(iicdev), sc->sc_addr, sc->sc_buffer, count, &sent); + iicbus_release_bus(device_get_parent(iicdev), iicdev); + return(error); } @@ -192,6 +198,9 @@ iicread(dev_t dev, struct uio * uio, int ioflag) if (sc->sc_count == 0) return (EINVAL); + if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT))) + return (error); + /* max amount of data to read */ len = min(uio->uio_resid, BUFSIZE); @@ -202,6 +211,8 @@ iicread(dev_t dev, struct uio * uio, int ioflag) if (bufsize > uio->uio_resid) panic("%s: too much data read!", __FUNCTION__); + iicbus_release_bus(device_get_parent(iicdev), iicdev); + return (uiomove(sc->sc_inbuf, bufsize, uio)); } @@ -217,6 +228,11 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) if (!sc) return (EINVAL); + if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, + (flags & O_NONBLOCK) ? IIC_DONTWAIT : + (IIC_WAIT | IIC_INTR)))) + return (error); + switch (cmd) { case I2CSTART: error = iicbus_start(parent, s->slave, 0); @@ -242,6 +258,8 @@ iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) error = ENODEV; } + iicbus_release_bus(device_get_parent(iicdev), iicdev); + return (error); } diff --git a/sys/dev/iicbus/iiconf.c b/sys/dev/iicbus/iiconf.c index b84a6cd..5727c05 100644 --- a/sys/dev/iicbus/iiconf.c +++ b/sys/dev/iicbus/iiconf.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: iiconf.c,v 1.5 1999/01/28 15:59:15 roger Exp $ + * $Id: iiconf.c,v 1.6 1999/02/06 10:56:09 roger Exp $ * */ #include <sys/param.h> @@ -104,16 +104,12 @@ iicbus_request_bus(device_t bus, device_t dev, int how) int s, error = 0; /* first, ask the underlying layers if the request is ok */ - do { - error = IICBUS_CALLBACK(device_get_parent(bus), - IIC_REQUEST_BUS, (caddr_t)&how); - if (error) - error = iicbus_poll(sc, how); - } while (error); + error = IICBUS_CALLBACK(device_get_parent(bus), IIC_REQUEST_BUS, + (caddr_t)&how); while (!error) { s = splhigh(); - if (sc->owner) { + if (sc->owner && sc->owner != dev) { splx(s); error = iicbus_poll(sc, how); @@ -123,6 +119,11 @@ iicbus_request_bus(device_t bus, device_t dev, int how) splx(s); return (0); } + + /* free any allocated resource */ + if (error) + IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, + (caddr_t)&how); } return (error); |