1*a74a190bSjsg /* $OpenBSD: acpi_apm.c,v 1.4 2024/10/30 06:16:27 jsg Exp $ */ 2c7569092Stobhe /* 3c7569092Stobhe * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> 4c7569092Stobhe * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> 5c7569092Stobhe * 6c7569092Stobhe * Permission to use, copy, modify, and distribute this software for any 7c7569092Stobhe * purpose with or without fee is hereby granted, provided that the above 8c7569092Stobhe * copyright notice and this permission notice appear in all copies. 9c7569092Stobhe * 10c7569092Stobhe * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11c7569092Stobhe * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12c7569092Stobhe * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13c7569092Stobhe * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14c7569092Stobhe * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15c7569092Stobhe * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16c7569092Stobhe * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17c7569092Stobhe */ 18c7569092Stobhe 19c7569092Stobhe #include <sys/param.h> 20c7569092Stobhe #include <sys/systm.h> 21c7569092Stobhe #include <sys/fcntl.h> 22c7569092Stobhe 23c7569092Stobhe #include <dev/acpi/acpireg.h> 24c7569092Stobhe #include <dev/acpi/acpivar.h> 25c7569092Stobhe #include <dev/acpi/acpidev.h> 26c7569092Stobhe #include <dev/acpi/dsdt.h> 27c7569092Stobhe 28c7569092Stobhe #include <machine/conf.h> 29c7569092Stobhe #include <machine/cpufunc.h> 30c7569092Stobhe 31c7569092Stobhe #ifdef HIBERNATE 32c7569092Stobhe #include <sys/hibernate.h> 33c7569092Stobhe #endif 34c7569092Stobhe 35c7569092Stobhe #include <machine/apmvar.h> 36c7569092Stobhe #define APMUNIT(dev) (minor(dev)&0xf0) 37c7569092Stobhe #define APMDEV(dev) (minor(dev)&0x0f) 38c7569092Stobhe #define APMDEV_NORMAL 0 39c7569092Stobhe #define APMDEV_CTL 8 40c7569092Stobhe 41c7569092Stobhe #ifndef SMALL_KERNEL 42c7569092Stobhe 43c7569092Stobhe int 44c7569092Stobhe acpiopen(dev_t dev, int flag, int mode, struct proc *p) 45c7569092Stobhe { 46c7569092Stobhe int error = 0; 47c7569092Stobhe struct acpi_softc *sc = acpi_softc; 48c7569092Stobhe int s; 49c7569092Stobhe 50a3c01fdfStobhe if (sc == NULL) 51a3c01fdfStobhe return (ENXIO); 52a3c01fdfStobhe 53c7569092Stobhe s = splbio(); 54c7569092Stobhe switch (APMDEV(dev)) { 55c7569092Stobhe case APMDEV_CTL: 56c7569092Stobhe if (!(flag & FWRITE)) { 57c7569092Stobhe error = EINVAL; 58c7569092Stobhe break; 59c7569092Stobhe } 60c7569092Stobhe if (sc->sc_flags & SCFLAG_OWRITE) { 61c7569092Stobhe error = EBUSY; 62c7569092Stobhe break; 63c7569092Stobhe } 64c7569092Stobhe sc->sc_flags |= SCFLAG_OWRITE; 65c7569092Stobhe break; 66c7569092Stobhe case APMDEV_NORMAL: 67c7569092Stobhe if (!(flag & FREAD) || (flag & FWRITE)) { 68c7569092Stobhe error = EINVAL; 69c7569092Stobhe break; 70c7569092Stobhe } 71c7569092Stobhe sc->sc_flags |= SCFLAG_OREAD; 72c7569092Stobhe break; 73c7569092Stobhe default: 74c7569092Stobhe error = ENXIO; 75c7569092Stobhe break; 76c7569092Stobhe } 77c7569092Stobhe splx(s); 78c7569092Stobhe return (error); 79c7569092Stobhe } 80c7569092Stobhe 81c7569092Stobhe int 82c7569092Stobhe acpiclose(dev_t dev, int flag, int mode, struct proc *p) 83c7569092Stobhe { 84c7569092Stobhe int error = 0; 85c7569092Stobhe struct acpi_softc *sc = acpi_softc; 86c7569092Stobhe int s; 87c7569092Stobhe 88a3c01fdfStobhe if (sc == NULL) 89a3c01fdfStobhe return (ENXIO); 90a3c01fdfStobhe 91c7569092Stobhe s = splbio(); 92c7569092Stobhe switch (APMDEV(dev)) { 93c7569092Stobhe case APMDEV_CTL: 94c7569092Stobhe sc->sc_flags &= ~SCFLAG_OWRITE; 95c7569092Stobhe break; 96c7569092Stobhe case APMDEV_NORMAL: 97c7569092Stobhe sc->sc_flags &= ~SCFLAG_OREAD; 98c7569092Stobhe break; 99c7569092Stobhe default: 100c7569092Stobhe error = ENXIO; 101c7569092Stobhe break; 102c7569092Stobhe } 103c7569092Stobhe splx(s); 104c7569092Stobhe return (error); 105c7569092Stobhe } 106c7569092Stobhe 107c7569092Stobhe int 108c7569092Stobhe acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 109c7569092Stobhe { 110c7569092Stobhe int error = 0; 111c7569092Stobhe struct acpi_softc *sc = acpi_softc; 112c7569092Stobhe struct apm_power_info *pi = (struct apm_power_info *)data; 113c7569092Stobhe int s; 114c7569092Stobhe 115a3c01fdfStobhe if (sc == NULL) 116a3c01fdfStobhe return (ENXIO); 117a3c01fdfStobhe 118c7569092Stobhe s = splbio(); 119c7569092Stobhe /* fake APM */ 120c7569092Stobhe switch (cmd) { 1218cae9a59Stobhe #ifdef SUSPEND 122c7569092Stobhe case APM_IOC_SUSPEND: 123c7569092Stobhe case APM_IOC_STANDBY: 124c7569092Stobhe if ((flag & FWRITE) == 0) { 125c7569092Stobhe error = EBADF; 126c7569092Stobhe break; 127c7569092Stobhe } 1288cae9a59Stobhe error = request_sleep(SLEEP_SUSPEND); 1298cae9a59Stobhe if (error) 1308cae9a59Stobhe break; 131c7569092Stobhe acpi_wakeup(sc); 132c7569092Stobhe break; 133c7569092Stobhe #ifdef HIBERNATE 134c7569092Stobhe case APM_IOC_HIBERNATE: 135c7569092Stobhe if ((error = suser(p)) != 0) 136c7569092Stobhe break; 137c7569092Stobhe if ((flag & FWRITE) == 0) { 138c7569092Stobhe error = EBADF; 139c7569092Stobhe break; 140c7569092Stobhe } 141*a74a190bSjsg if (get_hibernate_io_function(swdevt[0]) == NULL) { 142c7569092Stobhe error = EOPNOTSUPP; 143c7569092Stobhe break; 144c7569092Stobhe } 1458cae9a59Stobhe error = request_sleep(SLEEP_HIBERNATE); 1468cae9a59Stobhe if (error) 1478cae9a59Stobhe break; 148c7569092Stobhe acpi_wakeup(sc); 149c7569092Stobhe break; 150c7569092Stobhe #endif 1518cae9a59Stobhe #endif 152c7569092Stobhe case APM_IOC_GETPOWER: 153c7569092Stobhe error = acpi_apminfo(pi); 154c7569092Stobhe break; 155c7569092Stobhe 156c7569092Stobhe default: 157c7569092Stobhe error = ENOTTY; 158c7569092Stobhe } 159c7569092Stobhe 160c7569092Stobhe splx(s); 161c7569092Stobhe return (error); 162c7569092Stobhe } 163c7569092Stobhe 164c7569092Stobhe void acpi_filtdetach(struct knote *); 165c7569092Stobhe int acpi_filtread(struct knote *, long); 166c7569092Stobhe 167c7569092Stobhe const struct filterops acpiread_filtops = { 168c7569092Stobhe .f_flags = FILTEROP_ISFD, 169c7569092Stobhe .f_attach = NULL, 170c7569092Stobhe .f_detach = acpi_filtdetach, 171c7569092Stobhe .f_event = acpi_filtread, 172c7569092Stobhe }; 173c7569092Stobhe 174c7569092Stobhe int 175c7569092Stobhe acpikqfilter(dev_t dev, struct knote *kn) 176c7569092Stobhe { 177c7569092Stobhe struct acpi_softc *sc = acpi_softc; 178c7569092Stobhe int s; 179c7569092Stobhe 180a3c01fdfStobhe if (sc == NULL) 181a3c01fdfStobhe return (ENXIO); 182a3c01fdfStobhe 183c7569092Stobhe switch (kn->kn_filter) { 184c7569092Stobhe case EVFILT_READ: 185c7569092Stobhe kn->kn_fop = &acpiread_filtops; 186c7569092Stobhe break; 187c7569092Stobhe default: 188c7569092Stobhe return (EINVAL); 189c7569092Stobhe } 190c7569092Stobhe 191c7569092Stobhe kn->kn_hook = sc; 192c7569092Stobhe 193c7569092Stobhe s = splbio(); 194c7569092Stobhe klist_insert_locked(&sc->sc_note, kn); 195c7569092Stobhe splx(s); 196c7569092Stobhe 197c7569092Stobhe return (0); 198c7569092Stobhe } 199c7569092Stobhe 200c7569092Stobhe void 201c7569092Stobhe acpi_filtdetach(struct knote *kn) 202c7569092Stobhe { 203c7569092Stobhe struct acpi_softc *sc = kn->kn_hook; 204c7569092Stobhe int s; 205c7569092Stobhe 206c7569092Stobhe s = splbio(); 207c7569092Stobhe klist_remove_locked(&sc->sc_note, kn); 208c7569092Stobhe splx(s); 209c7569092Stobhe } 210c7569092Stobhe 211c7569092Stobhe int 212c7569092Stobhe acpi_filtread(struct knote *kn, long hint) 213c7569092Stobhe { 214c7569092Stobhe /* XXX weird kqueue_scan() semantics */ 215c7569092Stobhe if (hint && !kn->kn_data) 216c7569092Stobhe kn->kn_data = hint; 217c7569092Stobhe return (1); 218c7569092Stobhe } 219c7569092Stobhe 2208cae9a59Stobhe #ifdef SUSPEND 2218cae9a59Stobhe int 2228cae9a59Stobhe request_sleep(int sleepmode) 2238cae9a59Stobhe { 2248cae9a59Stobhe struct acpi_softc *sc = acpi_softc; 2258cae9a59Stobhe 2268cae9a59Stobhe #ifdef HIBERNATE 2278cae9a59Stobhe if (sleepmode == SLEEP_HIBERNATE) { 228*a74a190bSjsg if (get_hibernate_io_function(swdevt[0]) == NULL) 2298cae9a59Stobhe return EOPNOTSUPP; 2308cae9a59Stobhe } 2318cae9a59Stobhe #endif 2328cae9a59Stobhe acpi_addtask(sc, acpi_sleep_task, sc, sleepmode); 2338cae9a59Stobhe return 0; 2348cae9a59Stobhe } 2358cae9a59Stobhe #endif /* SUSPEND */ 2368cae9a59Stobhe 237c7569092Stobhe #else /* SMALL_KERNEL */ 238c7569092Stobhe 239c7569092Stobhe int 240c7569092Stobhe acpiopen(dev_t dev, int flag, int mode, struct proc *p) 241c7569092Stobhe { 242c7569092Stobhe return (ENXIO); 243c7569092Stobhe } 244c7569092Stobhe 245c7569092Stobhe int 246c7569092Stobhe acpiclose(dev_t dev, int flag, int mode, struct proc *p) 247c7569092Stobhe { 248c7569092Stobhe return (ENXIO); 249c7569092Stobhe } 250c7569092Stobhe 251c7569092Stobhe int 252c7569092Stobhe acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 253c7569092Stobhe { 254c7569092Stobhe return (ENXIO); 255c7569092Stobhe } 256c7569092Stobhe 257c7569092Stobhe int 258c7569092Stobhe acpikqfilter(dev_t dev, struct knote *kn) 259c7569092Stobhe { 260c7569092Stobhe return (EOPNOTSUPP); 261c7569092Stobhe } 262c7569092Stobhe 263c7569092Stobhe #endif /* SMALL_KERNEL */ 264