1df074184STakanori Watanabe /*- 2df074184STakanori Watanabe * Copyright (c) 2013 Takanori Watanabe 3df074184STakanori Watanabe * All rights reserved. 4df074184STakanori Watanabe * 5df074184STakanori Watanabe * Redistribution and use in source and binary forms, with or without 6df074184STakanori Watanabe * modification, are permitted provided that the following conditions 7df074184STakanori Watanabe * are met: 8df074184STakanori Watanabe * 1. Redistributions of source code must retain the above copyright 9df074184STakanori Watanabe * notice, this list of conditions and the following disclaimer. 10df074184STakanori Watanabe * 2. Redistributions in binary form must reproduce the above copyright 11df074184STakanori Watanabe * notice, this list of conditions and the following disclaimer in the 12df074184STakanori Watanabe * documentation and/or other materials provided with the distribution. 13df074184STakanori Watanabe * 14df074184STakanori Watanabe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15df074184STakanori Watanabe * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16df074184STakanori Watanabe * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17df074184STakanori Watanabe * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18df074184STakanori Watanabe * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19df074184STakanori Watanabe * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20df074184STakanori Watanabe * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21df074184STakanori Watanabe * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22df074184STakanori Watanabe * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23df074184STakanori Watanabe * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24df074184STakanori Watanabe * SUCH DAMAGE. 25df074184STakanori Watanabe */ 26df074184STakanori Watanabe 27df074184STakanori Watanabe #include <sys/cdefs.h> 28df074184STakanori Watanabe __FBSDID("$FreeBSD$"); 29df074184STakanori Watanabe 30df074184STakanori Watanabe #include "opt_acpi.h" 31df074184STakanori Watanabe #include <sys/param.h> 32df074184STakanori Watanabe #include <sys/kernel.h> 33df074184STakanori Watanabe #include <sys/bus.h> 34df074184STakanori Watanabe 35df074184STakanori Watanabe #include <contrib/dev/acpica/include/acpi.h> 36df074184STakanori Watanabe 37df074184STakanori Watanabe #include "acpi_if.h" 38df074184STakanori Watanabe #include <sys/module.h> 39df074184STakanori Watanabe #include <dev/acpica/acpivar.h> 40df074184STakanori Watanabe #include <sys/sysctl.h> 41df074184STakanori Watanabe static int sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS); 42df074184STakanori Watanabe 43df074184STakanori Watanabe 44df074184STakanori Watanabe static struct acpi_rapidstart_name_list 45df074184STakanori Watanabe { 46df074184STakanori Watanabe char *nodename; 47df074184STakanori Watanabe char *getmethod; 48df074184STakanori Watanabe char *setmethod; 49df074184STakanori Watanabe char *comment; 50df074184STakanori Watanabe } acpi_rapidstart_oids[] ={ 51df074184STakanori Watanabe {"ffs","GFFS","SFFS","Flash Fast Store Flag"}, 52df074184STakanori Watanabe {"ftv","GFTV","SFTV","Time value"}, 53df074184STakanori Watanabe {NULL, NULL, NULL, NULL} 54df074184STakanori Watanabe }; 55df074184STakanori Watanabe 56df074184STakanori Watanabe struct acpi_rapidstart_softc { 57df074184STakanori Watanabe struct sysctl_ctx_list *sysctl_ctx; 58df074184STakanori Watanabe struct sysctl_oid *sysctl_tree; 59df074184STakanori Watanabe 60df074184STakanori Watanabe }; 61df074184STakanori Watanabe static char *rapidstart_ids[] = {"INT3392", NULL}; 62df074184STakanori Watanabe static int 63df074184STakanori Watanabe acpi_rapidstart_probe(device_t dev) 64df074184STakanori Watanabe { 65df074184STakanori Watanabe if (acpi_disabled("rapidstart") || 66df074184STakanori Watanabe ACPI_ID_PROBE(device_get_parent(dev), dev, rapidstart_ids) == NULL || 67df074184STakanori Watanabe device_get_unit(dev) != 0) 68df074184STakanori Watanabe return (ENXIO); 69df074184STakanori Watanabe 70df074184STakanori Watanabe device_set_desc(dev, "Intel Rapid Start ACPI device"); 71df074184STakanori Watanabe 72df074184STakanori Watanabe return (0); 73df074184STakanori Watanabe 74df074184STakanori Watanabe } 75df074184STakanori Watanabe 76df074184STakanori Watanabe static int 77df074184STakanori Watanabe acpi_rapidstart_attach(device_t dev) 78df074184STakanori Watanabe { 79df074184STakanori Watanabe struct acpi_rapidstart_softc *sc; 80df074184STakanori Watanabe int i; 81df074184STakanori Watanabe 82df074184STakanori Watanabe sc = device_get_softc(dev); 83df074184STakanori Watanabe 84df074184STakanori Watanabe sc->sysctl_ctx = device_get_sysctl_ctx(dev); 85df074184STakanori Watanabe sc->sysctl_tree = device_get_sysctl_tree(dev); 86df074184STakanori Watanabe for (i = 0 ; acpi_rapidstart_oids[i].nodename != NULL; i++){ 87df074184STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 88df074184STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 89df074184STakanori Watanabe i, acpi_rapidstart_oids[i].nodename , CTLTYPE_INT | 90df074184STakanori Watanabe ((acpi_rapidstart_oids[i].setmethod)? CTLFLAG_RW: CTLFLAG_RD), 91df074184STakanori Watanabe dev, i, sysctl_acpi_rapidstart_gen_handler, "I", 92df074184STakanori Watanabe acpi_rapidstart_oids[i].comment); 93df074184STakanori Watanabe } 94df074184STakanori Watanabe return (0); 95df074184STakanori Watanabe } 96df074184STakanori Watanabe 97df074184STakanori Watanabe static int 98df074184STakanori Watanabe sysctl_acpi_rapidstart_gen_handler(SYSCTL_HANDLER_ARGS) 99df074184STakanori Watanabe { 100df074184STakanori Watanabe device_t dev = arg1; 101df074184STakanori Watanabe int function = oidp->oid_arg2; 102df074184STakanori Watanabe int error = 0, val; 103df074184STakanori Watanabe 104df074184STakanori Watanabe acpi_GetInteger(acpi_get_handle(dev), 105df074184STakanori Watanabe acpi_rapidstart_oids[function].getmethod, &val); 106df074184STakanori Watanabe error = sysctl_handle_int(oidp, &val, 0, req); 107df074184STakanori Watanabe if (error || !req->newptr || !acpi_rapidstart_oids[function].setmethod) 108df074184STakanori Watanabe return (error); 109df074184STakanori Watanabe acpi_SetInteger(acpi_get_handle(dev), 110df074184STakanori Watanabe acpi_rapidstart_oids[function].setmethod, val); 111df074184STakanori Watanabe return (0); 112df074184STakanori Watanabe } 113df074184STakanori Watanabe 114df074184STakanori Watanabe static device_method_t acpi_rapidstart_methods[] = { 115df074184STakanori Watanabe /* Device interface */ 116df074184STakanori Watanabe DEVMETHOD(device_probe, acpi_rapidstart_probe), 117df074184STakanori Watanabe DEVMETHOD(device_attach, acpi_rapidstart_attach), 118df074184STakanori Watanabe 119df074184STakanori Watanabe DEVMETHOD_END 120df074184STakanori Watanabe }; 121df074184STakanori Watanabe 122df074184STakanori Watanabe static driver_t acpi_rapidstart_driver = { 123df074184STakanori Watanabe "acpi_rapidstart", 124df074184STakanori Watanabe acpi_rapidstart_methods, 125df074184STakanori Watanabe sizeof(struct acpi_rapidstart_softc), 126df074184STakanori Watanabe }; 127df074184STakanori Watanabe 128df074184STakanori Watanabe static devclass_t acpi_rapidstart_devclass; 129df074184STakanori Watanabe 130df074184STakanori Watanabe DRIVER_MODULE(acpi_rapidstart, acpi, acpi_rapidstart_driver, acpi_rapidstart_devclass, 131df074184STakanori Watanabe 0, 0); 132df074184STakanori Watanabe MODULE_DEPEND(acpi_rapidstart, acpi, 1, 1, 1); 133df074184STakanori Watanabe 134