Edit

IABSD.fr/src/sys/dev/acpi/acpi_apm.c

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2024-10-30 06:16:27
    Hash : a74a190b
    Message : directly use dev_t for swdevt[], remove struct swdevt ok mpi@ miod@

  • sys/dev/acpi/acpi_apm.c
  • /* $OpenBSD: acpi_apm.c,v 1.4 2024/10/30 06:16:27 jsg Exp $ */
    /*
     * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
     * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
     *
     * Permission to use, copy, modify, and distribute this software for any
     * purpose with or without fee is hereby granted, provided that the above
     * copyright notice and this permission notice appear in all copies.
     *
     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     */
    
    #include <sys/param.h>
    #include <sys/systm.h>
    #include <sys/fcntl.h>
    
    #include <dev/acpi/acpireg.h>
    #include <dev/acpi/acpivar.h>
    #include <dev/acpi/acpidev.h>
    #include <dev/acpi/dsdt.h>
    
    #include <machine/conf.h>
    #include <machine/cpufunc.h>
    
    #ifdef HIBERNATE
    #include <sys/hibernate.h>
    #endif
    
    #include <machine/apmvar.h>
    #define APMUNIT(dev)	(minor(dev)&0xf0)
    #define APMDEV(dev)	(minor(dev)&0x0f)
    #define APMDEV_NORMAL	0
    #define APMDEV_CTL	8
    
    #ifndef SMALL_KERNEL
    
    int
    acpiopen(dev_t dev, int flag, int mode, struct proc *p)
    {
    	int error = 0;
    	struct acpi_softc *sc = acpi_softc;
    	int s;
    
    	if (sc == NULL)
    		return (ENXIO);
    
    	s = splbio();
    	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;
    	}
    	splx(s);
    	return (error);
    }
    
    int
    acpiclose(dev_t dev, int flag, int mode, struct proc *p)
    {
    	int error = 0;
    	struct acpi_softc *sc = acpi_softc;
    	int s;
    
    	if (sc == NULL)
    		return (ENXIO);
    
    	s = splbio();
    	switch (APMDEV(dev)) {
    	case APMDEV_CTL:
    		sc->sc_flags &= ~SCFLAG_OWRITE;
    		break;
    	case APMDEV_NORMAL:
    		sc->sc_flags &= ~SCFLAG_OREAD;
    		break;
    	default:
    		error = ENXIO;
    		break;
    	}
    	splx(s);
    	return (error);
    }
    
    int
    acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
    {
    	int error = 0;
    	struct acpi_softc *sc = acpi_softc;
    	struct apm_power_info *pi = (struct apm_power_info *)data;
    	int s;
    
    	if (sc == NULL)
    		return (ENXIO);
    
    	s = splbio();
    	/* fake APM */
    	switch (cmd) {
    #ifdef SUSPEND
    	case APM_IOC_SUSPEND:
    	case APM_IOC_STANDBY:
    		if ((flag & FWRITE) == 0) {
    			error = EBADF;
    			break;
    		}
    		error = request_sleep(SLEEP_SUSPEND);
    		if (error)
    			break;
    		acpi_wakeup(sc);
    		break;
    #ifdef HIBERNATE
    	case APM_IOC_HIBERNATE:
    		if ((error = suser(p)) != 0)
    			break;
    		if ((flag & FWRITE) == 0) {
    			error = EBADF;
    			break;
    		}
    		if (get_hibernate_io_function(swdevt[0]) == NULL) {
    			error = EOPNOTSUPP;
    			break;
    		}
    		error = request_sleep(SLEEP_HIBERNATE);
    		if (error)
    			break;
    		acpi_wakeup(sc);
    		break;
    #endif
    #endif
    	case APM_IOC_GETPOWER:
    		error = acpi_apminfo(pi);
    		break;
    
    	default:
    		error = ENOTTY;
    	}
    
    	splx(s);
    	return (error);
    }
    
    void	acpi_filtdetach(struct knote *);
    int	acpi_filtread(struct knote *, long);
    
    const struct filterops acpiread_filtops = {
    	.f_flags	= FILTEROP_ISFD,
    	.f_attach	= NULL,
    	.f_detach	= acpi_filtdetach,
    	.f_event	= acpi_filtread,
    };
    
    int
    acpikqfilter(dev_t dev, struct knote *kn)
    {
    	struct acpi_softc *sc = acpi_softc;
    	int s;
    
    	if (sc == NULL)
    		return (ENXIO);
    
    	switch (kn->kn_filter) {
    	case EVFILT_READ:
    		kn->kn_fop = &acpiread_filtops;
    		break;
    	default:
    		return (EINVAL);
    	}
    
    	kn->kn_hook = sc;
    
    	s = splbio();
    	klist_insert_locked(&sc->sc_note, kn);
    	splx(s);
    
    	return (0);
    }
    
    void
    acpi_filtdetach(struct knote *kn)
    {
    	struct acpi_softc *sc = kn->kn_hook;
    	int s;
    
    	s = splbio();
    	klist_remove_locked(&sc->sc_note, kn);
    	splx(s);
    }
    
    int
    acpi_filtread(struct knote *kn, long hint)
    {
    	/* XXX weird kqueue_scan() semantics */
    	if (hint && !kn->kn_data)
    		kn->kn_data = hint;
    	return (1);
    }
    
    #ifdef SUSPEND
    int
    request_sleep(int sleepmode)
    {
    	struct acpi_softc *sc = acpi_softc;
    
    #ifdef HIBERNATE
    	if (sleepmode == SLEEP_HIBERNATE) {
    		if (get_hibernate_io_function(swdevt[0]) == NULL)
    			return EOPNOTSUPP;
    	}
    #endif
    	acpi_addtask(sc, acpi_sleep_task, sc, sleepmode);
    	return 0;
    }
    #endif /* SUSPEND */
    
    #else /* SMALL_KERNEL */
    
    int
    acpiopen(dev_t dev, int flag, int mode, struct proc *p)
    {
    	return (ENXIO);
    }
    
    int
    acpiclose(dev_t dev, int flag, int mode, struct proc *p)
    {
    	return (ENXIO);
    }
    
    int
    acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
    {
    	return (ENXIO);
    }
    
    int
    acpikqfilter(dev_t dev, struct knote *kn)
    {
    	return (EOPNOTSUPP);
    }
    
    #endif /* SMALL_KERNEL */