/* * smbus_request_bus() * * Allocate the device to perform transfers. * * how : SMB_WAIT or SMB_DONTWAIT */ int smbus_request_bus(device_t bus, device_t dev, int how) { struct smbus_softc *sc = (struct smbus_softc *)device_get_softc(bus); int s, error = 0; /* first, ask the underlying layers if the request is ok */ do { error = SMBUS_CALLBACK(device_get_parent(bus), SMB_REQUEST_BUS, (caddr_t)&how); if (error) error = smbus_poll(sc, how); } while (error == EWOULDBLOCK); while (!error) { s = splhigh(); if (sc->owner && sc->owner != dev) { splx(s); error = smbus_poll(sc, how); } else { sc->owner = dev; splx(s); return (0); } /* free any allocated resource */ if (error) SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, (caddr_t)&how); } return (error); }
/* * smbus_release_bus() * * Release the device allocated with smbus_request_dev() */ int smbus_release_bus(device_t bus, device_t dev) { struct smbus_softc *sc = (struct smbus_softc *)device_get_softc(bus); int s, error; /* first, ask the underlying layers if the release is ok */ error = SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, NULL); if (error) return (error); s = splhigh(); if (sc->owner != dev) { splx(s); return (EACCES); } sc->owner = 0; splx(s); /* wakeup waiting processes */ wakeup(sc); return (0); }
/* * smbus_request_bus() * * Allocate the device to perform transfers. * * how : SMB_WAIT or SMB_DONTWAIT */ int smbus_request_bus(device_t bus, device_t dev, int how) { struct smbus_softc *sc = device_get_softc(bus); device_t parent; int error; /* first, ask the underlying layers if the request is ok */ parent = device_get_parent(bus); mtx_lock(&sc->lock); do { mtx_unlock(&sc->lock); error = SMBUS_CALLBACK(parent, SMB_REQUEST_BUS, &how); mtx_lock(&sc->lock); if (error) error = smbus_poll(sc, how); } while (error == EWOULDBLOCK); while (error == 0) { if (sc->owner && sc->owner != dev) error = smbus_poll(sc, how); else { sc->owner = dev; break; } /* free any allocated resource */ if (error) { mtx_unlock(&sc->lock); SMBUS_CALLBACK(parent, SMB_RELEASE_BUS, &how); return (error); } } mtx_unlock(&sc->lock); return (error); }
/* * smbus_release_bus() * * Release the device allocated with smbus_request_dev() */ int smbus_release_bus(device_t bus, device_t dev) { struct smbus_softc *sc = device_get_softc(bus); int error; /* first, ask the underlying layers if the release is ok */ error = SMBUS_CALLBACK(device_get_parent(bus), SMB_RELEASE_BUS, NULL); if (error) return (error); mtx_lock(&sc->lock); if (sc->owner == dev) { sc->owner = NULL; /* wakeup waiting processes */ wakeup(sc); } else error = EACCES; mtx_unlock(&sc->lock); return (error); }