Handle correctly iicbus request/release mechanism. Add iicbus allocation

to the general purpose i/o iic(4) driver.
This commit is contained in:
nsouch 1999-02-13 18:01:55 +00:00
parent b54915a02a
commit a05e5f3178
2 changed files with 28 additions and 9 deletions

View File

@ -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);
}

View File

@ -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);