-/* $OpenBSD: acpi.c,v 1.204 2010/08/06 14:20:14 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.205 2010/08/06 21:12:27 marco Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
}
}
+ /* disable _LID for wakeup */
+ acpibtn_disable_psw();
+
/* Reset the indicator lights to "working" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_WORKING;
}
}
+ /* disable _LID for wakeup */
+ acpibtn_disable_psw();
+
/* Reset the indicator lights to "working" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_WORKING;
goto fail;
}
+ /* enable _LID for wakeup */
+ acpibtn_enable_psw();
+
/* Reset the indicator lights to "sleeping" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_SLEEPING;
-/* $OpenBSD: acpibtn.c,v 1.31 2010/08/05 21:10:06 deraadt Exp $ */
+/* $OpenBSD: acpibtn.c,v 1.32 2010/08/06 21:12:27 marco Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
struct aml_node *sc_devnode;
int sc_btn_type;
-#define ACPIBTN_UNKNOWN -1
-#define ACPIBTN_LID 0
-#define ACPIBTN_POWER 1
-#define ACPIBTN_SLEEP 2
+#define ACPIBTN_UNKNOWN 0
+#define ACPIBTN_LID 1
+#define ACPIBTN_POWER 2
+#define ACPIBTN_SLEEP 3
};
int acpibtn_getsta(struct acpibtn_softc *);
+int acpibtn_setpsw(struct acpibtn_softc *, int);
+
+struct acpi_lid {
+ struct acpibtn_softc *abl_softc;
+ SLIST_ENTRY(acpi_lid) abl_link;
+};
+SLIST_HEAD(acpi_lid_head, acpi_lid) acpibtn_lids =
+ SLIST_HEAD_INITIALIZER(acpibtn_lids);
struct cfattach acpibtn_ca = {
sizeof(struct acpibtn_softc), acpibtn_match, acpibtn_attach
const char *acpibtn_hids[] = { ACPI_DEV_LD, ACPI_DEV_PBD, ACPI_DEV_SBD, 0 };
+int
+acpibtn_setpsw(struct acpibtn_softc *sc, int psw)
+{
+ struct aml_value val;
+
+ bzero(&val, sizeof val);
+ val.type = AML_OBJTYPE_INTEGER;
+ val.v_integer = psw;
+ val.length = 1;
+
+ return (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSW", 1, &val,
+ NULL));
+}
+
+void
+acpibtn_disable_psw(void)
+{
+ struct acpi_lid *lid;
+
+ /* disable _LID for wakeup */
+ SLIST_FOREACH(lid, &acpibtn_lids, abl_link)
+ acpibtn_setpsw(lid->abl_softc, 0);
+}
+
+void
+acpibtn_enable_psw(void)
+{
+ struct acpi_lid *lid;
+
+ /* enable _LID for wakeup */
+ SLIST_FOREACH(lid, &acpibtn_lids, abl_link)
+ acpibtn_setpsw(lid->abl_softc, 1);
+}
+
int
acpibtn_match(struct device *parent, void *match, void *aux)
{
{
struct acpibtn_softc *sc = (struct acpibtn_softc *)self;
struct acpi_attach_args *aa = aux;
+ struct acpi_lid *lid;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node;
if (!strcmp(aa->aaa_dev, ACPI_DEV_LD)) {
- struct aml_value val;
-
sc->sc_btn_type = ACPIBTN_LID;
- bzero(&val, sizeof val);
- val.type = AML_OBJTYPE_INTEGER;
- val.v_integer = 1;
- val.length = 1;
- (void) aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSW",
- 1, &val, NULL);
+ if (acpibtn_setpsw(sc, 0) == 0) {
+ lid = malloc(sizeof(*lid), M_DEVBUF, M_WAITOK | M_ZERO);
+ lid->abl_softc = sc;
+ SLIST_INSERT_HEAD(&acpibtn_lids, lid, abl_link);
+ }
} else if (!strcmp(aa->aaa_dev, ACPI_DEV_PBD))
sc->sc_btn_type = ACPIBTN_POWER;
else if (!strcmp(aa->aaa_dev, ACPI_DEV_SBD))
sc->sc_btn_type = ACPIBTN_SLEEP;
- else
- sc->sc_btn_type = ACPIBTN_UNKNOWN;
acpibtn_getsta(sc);