예제 #1
0
void
apm_thread(void *v)
{
	struct pxa2x0_apm_softc *sc = v;
	u_int	type;

	for (;;) {
		APM_LOCK(sc);

		while (1) {
			if (apm_get_event(sc, &type) != 0)
				break;
			if (apm_handle_event(sc, type) != 0)
				break;
		}
		if (apm_suspends || apm_userstandbys /* || apm_battlow*/) {
			apm_suspend(sc);
			apm_resume(sc);
		}
		apm_battlow = apm_suspends = apm_userstandbys = 0;

		APM_UNLOCK(sc);
		tsleep(&lbolt, PWAIT, "apmev", 0);
	}
}
예제 #2
0
파일: apm.c 프로젝트: goroutines/rumprun
int
apmclose(dev_t dev, int flag, int mode,
	struct lwp *l)
{
	struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev));
	int ctl = APM(dev);

	DPRINTF(APMDEBUG_DEVICE,
	    ("apmclose: pid %d flag %x mode %x\n", l->l_proc->p_pid, flag, mode));

	APM_LOCK(sc);
	switch (ctl) {
	case APM_CTL:
		sc->sc_flags &= ~SCFLAG_OWRITE;
		break;
	case APM_NORMAL:
		sc->sc_flags &= ~SCFLAG_OREAD;
		break;
	}
	if ((sc->sc_flags & SCFLAG_OPEN) == 0) {
		sc->sc_event_count = 0;
		sc->sc_event_ptr = 0;
	}
	APM_UNLOCK(sc);
	return 0;
}
예제 #3
0
파일: apm.c 프로젝트: goroutines/rumprun
static void
filt_apmrdetach(struct knote *kn)
{
	struct apm_softc *sc = kn->kn_hook;

	APM_LOCK(sc);
	SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext);
	APM_UNLOCK(sc);
}
예제 #4
0
파일: apm.c 프로젝트: goroutines/rumprun
void
apm_thread(void *arg)
{
	struct apm_softc *apmsc = arg;

	/*
	 * Loop forever, doing a periodic check for APM events.
	 */
	for (;;) {
		APM_LOCK(apmsc);
		apm_periodic_check(apmsc);
		APM_UNLOCK(apmsc);
		(void) tsleep(apmsc, PWAIT, "apmev",  (8 * hz) / 7);
	}
}
예제 #5
0
파일: apm.c 프로젝트: goroutines/rumprun
int
apmpoll(dev_t dev, int events, struct lwp *l)
{
	struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev));
	int revents = 0;

	APM_LOCK(sc);
	if (events & (POLLIN | POLLRDNORM)) {
		if (sc->sc_event_count)
			revents |= events & (POLLIN | POLLRDNORM);
		else
			selrecord(l, &sc->sc_rsel);
	}
	APM_UNLOCK(sc);

	return (revents);
}
예제 #6
0
파일: apm.c 프로젝트: goroutines/rumprun
int
apmopen(dev_t dev, int flag, int mode, struct lwp *l)
{
	int ctl = APM(dev);
	int error = 0;
	struct apm_softc *sc;

	sc = device_lookup_private(&apm_cd, APMUNIT(dev));
	if (!sc)
		return ENXIO;

	if (!apm_inited)
		return ENXIO;

	DPRINTF(APMDEBUG_DEVICE,
	    ("apmopen: pid %d flag %x mode %x\n", l->l_proc->p_pid, flag, mode));

	APM_LOCK(sc);
	switch (ctl) {
	case APM_CTL:
		if (!(flag & FWRITE)) {
			error = EINVAL;
			break;
		}
		if (sc->sc_flags & SCFLAG_OWRITE) {
			error = EBUSY;
			break;
		}
		sc->sc_flags |= SCFLAG_OWRITE;
		break;
	case APM_NORMAL:
		if (!(flag & FREAD) || (flag & FWRITE)) {
			error = EINVAL;
			break;
		}
		sc->sc_flags |= SCFLAG_OREAD;
		break;
	default:
		error = ENXIO;
		break;
	}
	APM_UNLOCK(sc);

	return (error);
}
예제 #7
0
파일: apm.c 프로젝트: goroutines/rumprun
int
apmkqfilter(dev_t dev, struct knote *kn)
{
	struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev));
	struct klist *klist;

	switch (kn->kn_filter) {
	case EVFILT_READ:
		klist = &sc->sc_rsel.sel_klist;
		kn->kn_fop = &apmread_filtops;
		break;

	default:
		return (EINVAL);
	}

	kn->kn_hook = sc;

	APM_LOCK(sc);
	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
	APM_UNLOCK(sc);

	return (0);
}
예제 #8
0
파일: apm.c 프로젝트: goroutines/rumprun
int
apmioctl(dev_t dev, u_long cmd, void *data, int flag,
	struct lwp *l)
{
	struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev));
	struct apm_power_info *powerp;
	struct apm_event_info *evp;
#if 0
	struct apm_ctl *actl;
#endif
	int i, error = 0;
	int batt_flags;
	struct apm_ctl *actl;

	APM_LOCK(sc);
	switch (cmd) {
	case APM_IOC_STANDBY:
		if (!apm_do_standby) {
			error = EOPNOTSUPP;
			break;
		}

		if ((flag & FWRITE) == 0) {
			error = EBADF;
			break;
		}
		apm_userstandbys++;
		break;

	case APM_IOC_DEV_CTL:
		actl = (struct apm_ctl *)data;
		if ((flag & FWRITE) == 0) {
			error = EBADF;
			break;
		}
#if 0
		apm_get_powstate(actl->dev); /* XXX */
#endif
		error = (*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, actl->dev,
		    actl->mode);
		apm_suspends++;
 		break;

	case APM_IOC_SUSPEND:
		if ((flag & FWRITE) == 0) {
			error = EBADF;
			break;
		}
		apm_suspends++;
		break;

	case APM_IOC_NEXTEVENT:
		if (!sc->sc_event_count)
			error = EAGAIN;
		else {
			evp = (struct apm_event_info *)data;
			i = sc->sc_event_ptr + APM_NEVENTS - sc->sc_event_count;
			i %= APM_NEVENTS;
			*evp = sc->sc_event_list[i];
			sc->sc_event_count--;
		}
		break;

	case OAPM_IOC_GETPOWER:
	case APM_IOC_GETPOWER:
		powerp = (struct apm_power_info *)data;
		if ((error = (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0,
		    powerp)) != 0) {
			apm_perror("ioctl get power status", error);
			error = EIO;
			break;
		}
		switch (apm_minver) {
		case 0:
			break;
		case 1:
		default:
			batt_flags = powerp->battery_flags;
			powerp->battery_state = APM_BATT_UNKNOWN;
			if (batt_flags & APM_BATT_FLAG_HIGH)
				powerp->battery_state = APM_BATT_HIGH;
			else if (batt_flags & APM_BATT_FLAG_LOW)
				powerp->battery_state = APM_BATT_LOW;
			else if (batt_flags & APM_BATT_FLAG_CRITICAL)
				powerp->battery_state = APM_BATT_CRITICAL;
			else if (batt_flags & APM_BATT_FLAG_CHARGING)
				powerp->battery_state = APM_BATT_CHARGING;
			else if (batt_flags & APM_BATT_FLAG_NO_SYSTEM_BATTERY)
				powerp->battery_state = APM_BATT_ABSENT;
			break;
		}
		break;

	default:
		error = ENOTTY;
	}
	APM_UNLOCK(sc);

	return (error);
}