/* * iicbus_request_bus() * * Allocate the device to perform transfers. * * how : IIC_WAIT or IIC_DONTWAIT */ int iicbus_request_bus(device_t bus, device_t dev, int how) { struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); int error = 0; /* first, ask the underlying layers if the request is ok */ IICBUS_LOCK(sc); do { error = IICBUS_CALLBACK(device_get_parent(bus), IIC_REQUEST_BUS, (caddr_t)&how); if (error) error = iicbus_poll(sc, how); } while (error == EWOULDBLOCK); while (!error) { if (sc->owner && sc->owner != dev) { error = iicbus_poll(sc, how); } else { sc->owner = dev; IICBUS_UNLOCK(sc); return (0); } /* free any allocated resource */ if (error) IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, (caddr_t)&how); } IICBUS_UNLOCK(sc); return (error); }
/* * iicbus_request_bus() * * Allocate the device to perform transfers. * * how : IIC_WAIT or IIC_DONTWAIT */ int iicbus_request_bus(device_t bus, device_t dev, int how) { struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus); int error = 0; IICBUS_LOCK(sc); while ((error == 0) && (sc->owner != NULL)) error = iicbus_poll(sc, how); if (error == 0) { sc->owner = dev; /* * Drop the lock around the call to the bus driver. * This call should be allowed to sleep in the IIC_WAIT case. * Drivers might also need to grab locks that would cause LOR * if our lock is held. */ IICBUS_UNLOCK(sc); /* Ask the underlying layers if the request is ok */ error = IICBUS_CALLBACK(device_get_parent(bus), IIC_REQUEST_BUS, (caddr_t)&how); IICBUS_LOCK(sc); if (error != 0) { sc->owner = NULL; wakeup_one(sc); } } IICBUS_UNLOCK(sc); return (error); }