static void apmdtor(void *data) { struct apm_clone_data *clone; struct acpi_softc *acpi_sc; clone = data; acpi_sc = clone->acpi_sc; /* We are about to lose a reference so check if suspend should occur */ if (acpi_sc->acpi_next_sstate != 0 && clone->notify_status != APM_EV_ACKED) acpi_AckSleepState(clone, 0); /* Remove this clone's data from the list and free it. */ ACPI_LOCK(acpi); STAILQ_REMOVE(&acpi_sc->apm_cdevs, clone, apm_clone_data, entries); seldrain(&clone->sel_read); knlist_destroy(&clone->sel_read.si_note); ACPI_UNLOCK(acpi); free(clone, M_APMDEV); }
static int apmclose(struct cdev *dev, int flag, int fmt, d_thread_t *td) { struct apm_clone_data *clone; struct acpi_softc *acpi_sc; clone = dev->si_drv1; acpi_sc = clone->acpi_sc; /* We are about to lose a reference so check if suspend should occur */ if (acpi_sc->acpi_next_sstate != 0 && clone->notify_status != APM_EV_ACKED) acpi_AckSleepState(clone, 0); /* Remove this clone's data from the list and free it. */ ACPI_LOCK(acpi); STAILQ_REMOVE(&acpi_sc->apm_cdevs, clone, apm_clone_data, entries); knlist_destroy(&clone->sel_read.si_note); ACPI_UNLOCK(acpi); free(clone, M_APMDEV); destroy_dev_sched(dev); return (0); }
static int apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { int error; struct apm_clone_data *clone; struct acpi_softc *acpi_sc; struct apm_info info; struct apm_event_info *ev_info; apm_info_old_t aiop; error = 0; clone = dev->si_drv1; acpi_sc = clone->acpi_sc; switch (cmd) { case APMIO_SUSPEND: if ((flag & FWRITE) == 0) return (EPERM); if (acpi_sc->acpi_next_sstate == 0) { if (acpi_sc->acpi_suspend_sx != ACPI_STATE_S5) { error = acpi_ReqSleepState(acpi_sc, acpi_sc->acpi_suspend_sx); } else { printf( "power off via apm suspend not supported\n"); error = ENXIO; } } else error = acpi_AckSleepState(clone, 0); break; case APMIO_STANDBY: if ((flag & FWRITE) == 0) return (EPERM); if (acpi_sc->acpi_next_sstate == 0) { if (acpi_sc->acpi_standby_sx != ACPI_STATE_S5) { error = acpi_ReqSleepState(acpi_sc, acpi_sc->acpi_standby_sx); } else { printf( "power off via apm standby not supported\n"); error = ENXIO; } } else error = acpi_AckSleepState(clone, 0); break; case APMIO_NEXTEVENT: printf("apm nextevent start\n"); ACPI_LOCK(acpi); if (acpi_sc->acpi_next_sstate != 0 && clone->notify_status == APM_EV_NONE) { ev_info = (struct apm_event_info *)addr; if (acpi_sc->acpi_next_sstate <= ACPI_STATE_S3) ev_info->type = PMEV_STANDBYREQ; else ev_info->type = PMEV_SUSPENDREQ; ev_info->index = 0; clone->notify_status = APM_EV_NOTIFIED; printf("apm event returning %d\n", ev_info->type); } else error = EAGAIN; ACPI_UNLOCK(acpi); break; case APMIO_GETINFO_OLD: if (acpi_capm_get_info(&info)) error = ENXIO; aiop = (apm_info_old_t)addr; aiop->ai_major = info.ai_major; aiop->ai_minor = info.ai_minor; aiop->ai_acline = info.ai_acline; aiop->ai_batt_stat = info.ai_batt_stat; aiop->ai_batt_life = info.ai_batt_life; aiop->ai_status = info.ai_status; break; case APMIO_GETINFO: if (acpi_capm_get_info((apm_info_t)addr)) error = ENXIO; break; case APMIO_GETPWSTATUS: if (acpi_capm_get_pwstatus((apm_pwstatus_t)addr)) error = ENXIO; break; case APMIO_ENABLE: if ((flag & FWRITE) == 0) return (EPERM); apm_active = 1; break; case APMIO_DISABLE: if ((flag & FWRITE) == 0) return (EPERM); apm_active = 0; break; case APMIO_HALTCPU: break; case APMIO_NOTHALTCPU: break; case APMIO_DISPLAY: if ((flag & FWRITE) == 0) return (EPERM); break; case APMIO_BIOS: if ((flag & FWRITE) == 0) return (EPERM); bzero(addr, sizeof(struct apm_bios_arg)); break; default: error = EINVAL; break; } return (error); }