int apmkqfilter(dev_t dev, struct knote *kn) { struct apm_softc *sc; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; switch (kn->kn_filter) { case EVFILT_READ: kn->kn_fop = &apmread_filtops; break; default: return (EINVAL); } kn->kn_hook = (caddr_t)sc; rw_enter_write(&sc->sc_lock); SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext); rw_exit_write(&sc->sc_lock); return (0); }
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; }
int apmopen(dev_t dev, int flag, int mode, struct proc *p) { struct apm_softc *sc; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; if (apm_flags & APM_BIOS_PM_DISABLED) return ENXIO; DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n", APMDEV(dev), p->p_pid, flag, mode)); rw_enter_write(&sc->sc_lock); switch (APMDEV(dev)) { case APMDEV_CTL: if (!(flag & FWRITE)) { error = EINVAL; break; } if (sc->sc_flags & SCFLAG_OWRITE) { error = EBUSY; break; } sc->sc_flags |= SCFLAG_OWRITE; break; case APMDEV_NORMAL: if (!(flag & FREAD) || (flag & FWRITE)) { error = EINVAL; break; } sc->sc_flags |= SCFLAG_OREAD; break; default: error = ENXIO; break; } rw_exit_write(&sc->sc_lock); return error; }
int apmclose(dev_t dev, int flag, int mode, struct proc *p) { struct apm_softc *sc; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode)); switch (APMDEV(dev)) { case APMDEV_CTL: sc->sc_flags &= ~SCFLAG_OWRITE; break; case APMDEV_NORMAL: sc->sc_flags &= ~SCFLAG_OREAD; break; } return 0; }
int apmopen(dev_t dev, int flag, int mode, struct proc *p) { struct pxa2x0_apm_softc *sc; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return (ENXIO); DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n", APMDEV(dev), p->p_pid, flag, mode)); switch (APMDEV(dev)) { case APMDEV_CTL: if (!(flag & FWRITE)) { error = EINVAL; break; } if (sc->sc_flags & SCFLAG_OWRITE) { error = EBUSY; break; } sc->sc_flags |= SCFLAG_OWRITE; break; case APMDEV_NORMAL: if (!(flag & FREAD) || (flag & FWRITE)) { error = EINVAL; break; } sc->sc_flags |= SCFLAG_OREAD; break; default: error = ENXIO; break; } return (error); }
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); }
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); }
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); }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct apm_softc *sc; struct apm_power_info *power; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: case APM_IOC_STANDBY_REQ: case APM_IOC_SUSPEND: case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; else if (sys_platform->suspend == NULL || sys_platform->resume == NULL) error = EOPNOTSUPP; else error = apm_suspend(APM_IOC_SUSPEND); break; #ifdef HIBERNATE case APM_IOC_HIBERNATE: if ((flag & FWRITE) == 0) error = EBADF; else if (sys_platform->suspend == NULL || sys_platform->resume == NULL) error = EOPNOTSUPP; else error = apm_suspend(APM_IOC_HIBERNATE); break; #endif case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; else error = EOPNOTSUPP; /* XXX */ break; case APM_IOC_GETPOWER: power = (struct apm_power_info *)data; error = (*get_apminfo)(power); break; default: error = ENOTTY; } return error; }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct pxa2x0_apm_softc *sc; struct apm_power_info *power; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return (ENXIO); switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: if ((flag & FWRITE) == 0) error = EBADF; else apm_userstandbys++; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) error = EBADF; else apm_suspends++; /* XXX */ break; case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_GETPOWER: power = (struct apm_power_info *)data; apm_power_info(sc, power); break; case APM_IOC_STANDBY_REQ: if ((flag & FWRITE) == 0) error = EBADF; else if (apm_record_event(sc, APM_USER_STANDBY_REQ)) error = EINVAL; /* ? */ break; case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; else if (apm_record_event(sc, APM_USER_SUSPEND_REQ)) error = EINVAL; /* ? */ default: error = ENOTTY; } return (error); }
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); }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct apm_softc *sc; struct apmregs regs; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; rw_enter_write(&sc->sc_lock); switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: if ((flag & FWRITE) == 0) error = EBADF; else apm_userstandbys++; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) error = EBADF; else apm_suspends++; break; case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { struct apm_ctl *actl = (struct apm_ctl *)data; bzero(®s, sizeof(regs)); if (!apmcall(APM_GET_POWER_STATE, actl->dev, ®s)) printf("%s: dev %04x state %04x\n", sc->sc_dev.dv_xname, dev, regs.cx); error = apm_set_powstate(actl->dev, actl->mode); } break; case APM_IOC_GETPOWER: if (apm_get_powstat(®s) == 0) { struct apm_power_info *powerp = (struct apm_power_info *)data; bzero(powerp, sizeof(*powerp)); if (BATT_LIFE(®s) != APM_BATT_LIFE_UNKNOWN) powerp->battery_life = BATT_LIFE(®s); powerp->ac_state = AC_STATE(®s); switch (apm_minver) { case 0: if (!(BATT_FLAGS(®s) & APM_BATT_FLAG_NOBATTERY)) powerp->battery_state = BATT_STATE(®s); break; case 1: default: if (BATT_FLAGS(®s) & APM_BATT_FLAG_HIGH) powerp->battery_state = APM_BATT_HIGH; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_LOW) powerp->battery_state = APM_BATT_LOW; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_CRITICAL) powerp->battery_state = APM_BATT_CRITICAL; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_CHARGING) powerp->battery_state = APM_BATT_CHARGING; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_NOBATTERY) powerp->battery_state = APM_BATTERY_ABSENT; else powerp->battery_state = APM_BATT_UNKNOWN; if (BATT_REM_VALID(®s)) { powerp->minutes_left = BATT_REMAINING(®s); if (sc->be_batt) powerp->minutes_left = swap16(powerp->minutes_left); } } } else { apm_perror("ioctl get power status", ®s); error = EIO; } break; case APM_IOC_STANDBY_REQ: if ((flag & FWRITE) == 0) error = EBADF; /* only fails if no one cares. apmd at least should */ else if (apm_record_event(sc, APM_USER_STANDBY_REQ)) error = EINVAL; /* ? */ break; case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; /* only fails if no one cares. apmd at least should */ else if (apm_record_event(sc, APM_USER_SUSPEND_REQ)) error = EINVAL; /* ? */ break; default: error = ENOTTY; } rw_exit_write(&sc->sc_lock); return error; }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct apm_softc *sc; struct pmu_battery_info batt; struct apm_power_info *power; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_GETPOWER: power = (struct apm_power_info *)data; pm_battery_info(0, &batt); power->ac_state = ((batt.flags & PMU_PWR_AC_PRESENT) ? APM_AC_ON : APM_AC_OFF); power->battery_life = ((batt.cur_charge * 100) / batt.max_charge); /* * If the battery is charging, return the minutes left until * charging is complete. apmd knows this. */ if (!(batt.flags & PMU_PWR_BATT_PRESENT)) { power->battery_state = APM_BATT_UNKNOWN; power->minutes_left = 0; power->battery_life = 0; } else if ((power->ac_state == APM_AC_ON) && (batt.draw > 0)) { power->minutes_left = (((batt.max_charge - batt.cur_charge) * 3600) / batt.draw) / 60; power->battery_state = APM_BATT_CHARGING; } else { power->minutes_left = ((batt.cur_charge * 3600) / (-batt.draw)) / 60; /* XXX - Arbitrary */ if (power->battery_life > 60) power->battery_state = APM_BATT_HIGH; else if (power->battery_life < 10) power->battery_state = APM_BATT_CRITICAL; else power->battery_state = APM_BATT_LOW; } break; case APM_IOC_STANDBY_REQ: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; break; default: error = ENOTTY; } return error; }