1*bbe4a97dSRui Paulo /* $NetBSD: atk0110.c,v 1.4 2010/02/11 06:54:57 cnst Exp $ */ 2*bbe4a97dSRui Paulo /* $OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $ */ 3*bbe4a97dSRui Paulo 4*bbe4a97dSRui Paulo /* 5*bbe4a97dSRui Paulo * Copyright (c) 2009, 2010 Constantine A. Murenin <cnst++@FreeBSD.org> 6*bbe4a97dSRui Paulo * 7*bbe4a97dSRui Paulo * Permission to use, copy, modify, and distribute this software for any 8*bbe4a97dSRui Paulo * purpose with or without fee is hereby granted, provided that the above 9*bbe4a97dSRui Paulo * copyright notice and this permission notice appear in all copies. 10*bbe4a97dSRui Paulo * 11*bbe4a97dSRui Paulo * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12*bbe4a97dSRui Paulo * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13*bbe4a97dSRui Paulo * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14*bbe4a97dSRui Paulo * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15*bbe4a97dSRui Paulo * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16*bbe4a97dSRui Paulo * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17*bbe4a97dSRui Paulo * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18*bbe4a97dSRui Paulo */ 19*bbe4a97dSRui Paulo 20*bbe4a97dSRui Paulo #include <sys/cdefs.h> 21*bbe4a97dSRui Paulo __FBSDID("$FreeBSD$"); 22*bbe4a97dSRui Paulo 23*bbe4a97dSRui Paulo #include <machine/_inttypes.h> 24*bbe4a97dSRui Paulo #include <sys/param.h> 25*bbe4a97dSRui Paulo #include <sys/systm.h> 26*bbe4a97dSRui Paulo #include <sys/kernel.h> 27*bbe4a97dSRui Paulo #include <sys/bus.h> 28*bbe4a97dSRui Paulo #include <sys/module.h> 29*bbe4a97dSRui Paulo #include <sys/malloc.h> 30*bbe4a97dSRui Paulo #include <sys/sysctl.h> 31*bbe4a97dSRui Paulo 32*bbe4a97dSRui Paulo #include <contrib/dev/acpica/include/acpi.h> 33*bbe4a97dSRui Paulo #include <dev/acpica/acpivar.h> 34*bbe4a97dSRui Paulo 35*bbe4a97dSRui Paulo /* 36*bbe4a97dSRui Paulo * ASUSTeK AI Booster (ACPI ASOC ATK0110). 37*bbe4a97dSRui Paulo * 38*bbe4a97dSRui Paulo * This code was originally written for OpenBSD after the techniques 39*bbe4a97dSRui Paulo * described in the Linux's asus_atk0110.c and FreeBSD's Takanori Watanabe's 40*bbe4a97dSRui Paulo * acpi_aiboost.c were verified to be accurate on the actual hardware kindly 41*bbe4a97dSRui Paulo * provided by Sam Fourman Jr. It was subsequently ported from OpenBSD to 42*bbe4a97dSRui Paulo * DragonFly BSD, to NetBSD's sysmon_envsys(9) and to FreeBSD's sysctl(9). 43*bbe4a97dSRui Paulo * 44*bbe4a97dSRui Paulo * -- Constantine A. Murenin <http://cnst.su/> 45*bbe4a97dSRui Paulo */ 46*bbe4a97dSRui Paulo 47*bbe4a97dSRui Paulo #define _COMPONENT ACPI_OEM 48*bbe4a97dSRui Paulo ACPI_MODULE_NAME("aibs"); 49*bbe4a97dSRui Paulo ACPI_SERIAL_DECL(aibs, "aibs"); 50*bbe4a97dSRui Paulo 51*bbe4a97dSRui Paulo #define AIBS_MORE_SENSORS 52*bbe4a97dSRui Paulo #define AIBS_VERBOSE 53*bbe4a97dSRui Paulo 54*bbe4a97dSRui Paulo enum aibs_type { 55*bbe4a97dSRui Paulo AIBS_VOLT, 56*bbe4a97dSRui Paulo AIBS_TEMP, 57*bbe4a97dSRui Paulo AIBS_FAN 58*bbe4a97dSRui Paulo }; 59*bbe4a97dSRui Paulo 60*bbe4a97dSRui Paulo struct aibs_sensor { 61*bbe4a97dSRui Paulo ACPI_INTEGER v; 62*bbe4a97dSRui Paulo ACPI_INTEGER i; 63*bbe4a97dSRui Paulo ACPI_INTEGER l; 64*bbe4a97dSRui Paulo ACPI_INTEGER h; 65*bbe4a97dSRui Paulo enum aibs_type t; 66*bbe4a97dSRui Paulo }; 67*bbe4a97dSRui Paulo 68*bbe4a97dSRui Paulo struct aibs_softc { 69*bbe4a97dSRui Paulo struct device *sc_dev; 70*bbe4a97dSRui Paulo ACPI_HANDLE sc_ah; 71*bbe4a97dSRui Paulo 72*bbe4a97dSRui Paulo struct aibs_sensor *sc_asens_volt; 73*bbe4a97dSRui Paulo struct aibs_sensor *sc_asens_temp; 74*bbe4a97dSRui Paulo struct aibs_sensor *sc_asens_fan; 75*bbe4a97dSRui Paulo }; 76*bbe4a97dSRui Paulo 77*bbe4a97dSRui Paulo static int aibs_probe(device_t); 78*bbe4a97dSRui Paulo static int aibs_attach(device_t); 79*bbe4a97dSRui Paulo static int aibs_detach(device_t); 80*bbe4a97dSRui Paulo static int aibs_sysctl(SYSCTL_HANDLER_ARGS); 81*bbe4a97dSRui Paulo 82*bbe4a97dSRui Paulo static void aibs_attach_sif(struct aibs_softc *, enum aibs_type); 83*bbe4a97dSRui Paulo 84*bbe4a97dSRui Paulo static device_method_t aibs_methods[] = { 85*bbe4a97dSRui Paulo DEVMETHOD(device_probe, aibs_probe), 86*bbe4a97dSRui Paulo DEVMETHOD(device_attach, aibs_attach), 87*bbe4a97dSRui Paulo DEVMETHOD(device_detach, aibs_detach), 88*bbe4a97dSRui Paulo { NULL, NULL } 89*bbe4a97dSRui Paulo }; 90*bbe4a97dSRui Paulo 91*bbe4a97dSRui Paulo static driver_t aibs_driver = { 92*bbe4a97dSRui Paulo "aibs", 93*bbe4a97dSRui Paulo aibs_methods, 94*bbe4a97dSRui Paulo sizeof(struct aibs_softc) 95*bbe4a97dSRui Paulo }; 96*bbe4a97dSRui Paulo 97*bbe4a97dSRui Paulo static devclass_t aibs_devclass; 98*bbe4a97dSRui Paulo 99*bbe4a97dSRui Paulo DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL); 100*bbe4a97dSRui Paulo 101*bbe4a97dSRui Paulo 102*bbe4a97dSRui Paulo static char* aibs_hids[] = { 103*bbe4a97dSRui Paulo "ATK0110", 104*bbe4a97dSRui Paulo NULL 105*bbe4a97dSRui Paulo }; 106*bbe4a97dSRui Paulo 107*bbe4a97dSRui Paulo static int 108*bbe4a97dSRui Paulo aibs_probe(device_t dev) 109*bbe4a97dSRui Paulo { 110*bbe4a97dSRui Paulo if (acpi_disabled("aibs") || 111*bbe4a97dSRui Paulo ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL) 112*bbe4a97dSRui Paulo return ENXIO; 113*bbe4a97dSRui Paulo 114*bbe4a97dSRui Paulo device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)"); 115*bbe4a97dSRui Paulo return 0; 116*bbe4a97dSRui Paulo } 117*bbe4a97dSRui Paulo 118*bbe4a97dSRui Paulo static int 119*bbe4a97dSRui Paulo aibs_attach(device_t dev) 120*bbe4a97dSRui Paulo { 121*bbe4a97dSRui Paulo struct aibs_softc *sc = device_get_softc(dev); 122*bbe4a97dSRui Paulo 123*bbe4a97dSRui Paulo sc->sc_dev = dev; 124*bbe4a97dSRui Paulo sc->sc_ah = acpi_get_handle(dev); 125*bbe4a97dSRui Paulo 126*bbe4a97dSRui Paulo aibs_attach_sif(sc, AIBS_VOLT); 127*bbe4a97dSRui Paulo aibs_attach_sif(sc, AIBS_TEMP); 128*bbe4a97dSRui Paulo aibs_attach_sif(sc, AIBS_FAN); 129*bbe4a97dSRui Paulo 130*bbe4a97dSRui Paulo return 0; 131*bbe4a97dSRui Paulo } 132*bbe4a97dSRui Paulo 133*bbe4a97dSRui Paulo static void 134*bbe4a97dSRui Paulo aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) 135*bbe4a97dSRui Paulo { 136*bbe4a97dSRui Paulo ACPI_STATUS s; 137*bbe4a97dSRui Paulo ACPI_BUFFER b; 138*bbe4a97dSRui Paulo ACPI_OBJECT *bp, *o; 139*bbe4a97dSRui Paulo int i, n; 140*bbe4a97dSRui Paulo const char *node; 141*bbe4a97dSRui Paulo char name[] = "?SIF"; 142*bbe4a97dSRui Paulo struct aibs_sensor *as; 143*bbe4a97dSRui Paulo struct sysctl_oid *so; 144*bbe4a97dSRui Paulo 145*bbe4a97dSRui Paulo switch (st) { 146*bbe4a97dSRui Paulo case AIBS_VOLT: 147*bbe4a97dSRui Paulo node = "volt"; 148*bbe4a97dSRui Paulo name[0] = 'V'; 149*bbe4a97dSRui Paulo break; 150*bbe4a97dSRui Paulo case AIBS_TEMP: 151*bbe4a97dSRui Paulo node = "temp"; 152*bbe4a97dSRui Paulo name[0] = 'T'; 153*bbe4a97dSRui Paulo break; 154*bbe4a97dSRui Paulo case AIBS_FAN: 155*bbe4a97dSRui Paulo node = "fan"; 156*bbe4a97dSRui Paulo name[0] = 'F'; 157*bbe4a97dSRui Paulo break; 158*bbe4a97dSRui Paulo default: 159*bbe4a97dSRui Paulo return; 160*bbe4a97dSRui Paulo } 161*bbe4a97dSRui Paulo 162*bbe4a97dSRui Paulo b.Length = ACPI_ALLOCATE_BUFFER; 163*bbe4a97dSRui Paulo s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b, 164*bbe4a97dSRui Paulo ACPI_TYPE_PACKAGE); 165*bbe4a97dSRui Paulo if (ACPI_FAILURE(s)) { 166*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s not found\n", name); 167*bbe4a97dSRui Paulo return; 168*bbe4a97dSRui Paulo } 169*bbe4a97dSRui Paulo 170*bbe4a97dSRui Paulo bp = b.Pointer; 171*bbe4a97dSRui Paulo o = bp->Package.Elements; 172*bbe4a97dSRui Paulo if (o[0].Type != ACPI_TYPE_INTEGER) { 173*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s[0]: invalid type\n", name); 174*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 175*bbe4a97dSRui Paulo return; 176*bbe4a97dSRui Paulo } 177*bbe4a97dSRui Paulo 178*bbe4a97dSRui Paulo n = o[0].Integer.Value; 179*bbe4a97dSRui Paulo if (bp->Package.Count - 1 < n) { 180*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s: invalid package\n", name); 181*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 182*bbe4a97dSRui Paulo return; 183*bbe4a97dSRui Paulo } else if (bp->Package.Count - 1 > n) { 184*bbe4a97dSRui Paulo int on = n; 185*bbe4a97dSRui Paulo 186*bbe4a97dSRui Paulo #ifdef AIBS_MORE_SENSORS 187*bbe4a97dSRui Paulo n = bp->Package.Count - 1; 188*bbe4a97dSRui Paulo #endif 189*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s: malformed package: %i/%i" 190*bbe4a97dSRui Paulo ", assume %i\n", name, on, bp->Package.Count - 1, n); 191*bbe4a97dSRui Paulo } 192*bbe4a97dSRui Paulo if (n < 1) { 193*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s: no members in the package\n", 194*bbe4a97dSRui Paulo name); 195*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 196*bbe4a97dSRui Paulo return; 197*bbe4a97dSRui Paulo } 198*bbe4a97dSRui Paulo 199*bbe4a97dSRui Paulo as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO); 200*bbe4a97dSRui Paulo if (as == NULL) { 201*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%s: malloc fail\n", name); 202*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 203*bbe4a97dSRui Paulo return; 204*bbe4a97dSRui Paulo } 205*bbe4a97dSRui Paulo switch (st) { 206*bbe4a97dSRui Paulo case AIBS_VOLT: 207*bbe4a97dSRui Paulo sc->sc_asens_volt = as; 208*bbe4a97dSRui Paulo break; 209*bbe4a97dSRui Paulo case AIBS_TEMP: 210*bbe4a97dSRui Paulo sc->sc_asens_temp = as; 211*bbe4a97dSRui Paulo break; 212*bbe4a97dSRui Paulo case AIBS_FAN: 213*bbe4a97dSRui Paulo sc->sc_asens_fan = as; 214*bbe4a97dSRui Paulo break; 215*bbe4a97dSRui Paulo } 216*bbe4a97dSRui Paulo 217*bbe4a97dSRui Paulo /* sysctl subtree for sensors of this type */ 218*bbe4a97dSRui Paulo so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev), 219*bbe4a97dSRui Paulo SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st, 220*bbe4a97dSRui Paulo node, CTLFLAG_RD, NULL, NULL); 221*bbe4a97dSRui Paulo 222*bbe4a97dSRui Paulo for (i = 0, o++; i < n; i++, o++) { 223*bbe4a97dSRui Paulo ACPI_OBJECT *oi; 224*bbe4a97dSRui Paulo char si[3]; 225*bbe4a97dSRui Paulo const char *desc; 226*bbe4a97dSRui Paulo 227*bbe4a97dSRui Paulo /* acpica5 automatically evaluates the referenced package */ 228*bbe4a97dSRui Paulo if (o[0].Type != ACPI_TYPE_PACKAGE) { 229*bbe4a97dSRui Paulo device_printf(sc->sc_dev, 230*bbe4a97dSRui Paulo "%s: %i: not a package: %i type\n", 231*bbe4a97dSRui Paulo name, i, o[0].Type); 232*bbe4a97dSRui Paulo continue; 233*bbe4a97dSRui Paulo } 234*bbe4a97dSRui Paulo oi = o[0].Package.Elements; 235*bbe4a97dSRui Paulo if (o[0].Package.Count != 5 || 236*bbe4a97dSRui Paulo oi[0].Type != ACPI_TYPE_INTEGER || 237*bbe4a97dSRui Paulo oi[1].Type != ACPI_TYPE_STRING || 238*bbe4a97dSRui Paulo oi[2].Type != ACPI_TYPE_INTEGER || 239*bbe4a97dSRui Paulo oi[3].Type != ACPI_TYPE_INTEGER || 240*bbe4a97dSRui Paulo oi[4].Type != ACPI_TYPE_INTEGER) { 241*bbe4a97dSRui Paulo device_printf(sc->sc_dev, 242*bbe4a97dSRui Paulo "%s: %i: invalid package\n", 243*bbe4a97dSRui Paulo name, i); 244*bbe4a97dSRui Paulo continue; 245*bbe4a97dSRui Paulo } 246*bbe4a97dSRui Paulo as[i].i = oi[0].Integer.Value; 247*bbe4a97dSRui Paulo desc = oi[1].String.Pointer; 248*bbe4a97dSRui Paulo as[i].l = oi[2].Integer.Value; 249*bbe4a97dSRui Paulo as[i].h = oi[3].Integer.Value; 250*bbe4a97dSRui Paulo as[i].t = st; 251*bbe4a97dSRui Paulo #ifdef AIBS_VERBOSE 252*bbe4a97dSRui Paulo device_printf(sc->sc_dev, "%c%i: " 253*bbe4a97dSRui Paulo "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64" " 254*bbe4a97dSRui Paulo "0x%"PRIx64"\n", 255*bbe4a97dSRui Paulo name[0], i, 256*bbe4a97dSRui Paulo as[i].i, desc, (int64_t)as[i].l, (int64_t)as[i].h, 257*bbe4a97dSRui Paulo oi[4].Integer.Value); 258*bbe4a97dSRui Paulo #endif 259*bbe4a97dSRui Paulo snprintf(si, sizeof(si), "%i", i); 260*bbe4a97dSRui Paulo SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev), 261*bbe4a97dSRui Paulo SYSCTL_CHILDREN(so), i, si, CTLTYPE_OPAQUE | CTLFLAG_RD, 262*bbe4a97dSRui Paulo sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc); 263*bbe4a97dSRui Paulo } 264*bbe4a97dSRui Paulo 265*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 266*bbe4a97dSRui Paulo } 267*bbe4a97dSRui Paulo 268*bbe4a97dSRui Paulo static int 269*bbe4a97dSRui Paulo aibs_detach(device_t dev) 270*bbe4a97dSRui Paulo { 271*bbe4a97dSRui Paulo struct aibs_softc *sc = device_get_softc(dev); 272*bbe4a97dSRui Paulo 273*bbe4a97dSRui Paulo if (sc->sc_asens_volt != NULL) 274*bbe4a97dSRui Paulo free(sc->sc_asens_volt, M_DEVBUF); 275*bbe4a97dSRui Paulo if (sc->sc_asens_temp != NULL) 276*bbe4a97dSRui Paulo free(sc->sc_asens_temp, M_DEVBUF); 277*bbe4a97dSRui Paulo if (sc->sc_asens_fan != NULL) 278*bbe4a97dSRui Paulo free(sc->sc_asens_fan, M_DEVBUF); 279*bbe4a97dSRui Paulo return 0; 280*bbe4a97dSRui Paulo } 281*bbe4a97dSRui Paulo 282*bbe4a97dSRui Paulo #ifdef AIBS_VERBOSE 283*bbe4a97dSRui Paulo #define ddevice_printf(x...) device_printf(x) 284*bbe4a97dSRui Paulo #else 285*bbe4a97dSRui Paulo #define ddevice_printf(x...) 286*bbe4a97dSRui Paulo #endif 287*bbe4a97dSRui Paulo 288*bbe4a97dSRui Paulo static int 289*bbe4a97dSRui Paulo aibs_sysctl(SYSCTL_HANDLER_ARGS) 290*bbe4a97dSRui Paulo { 291*bbe4a97dSRui Paulo struct aibs_softc *sc = arg1; 292*bbe4a97dSRui Paulo enum aibs_type st = arg2; 293*bbe4a97dSRui Paulo int i = oidp->oid_number; 294*bbe4a97dSRui Paulo ACPI_STATUS rs; 295*bbe4a97dSRui Paulo ACPI_OBJECT p, *bp; 296*bbe4a97dSRui Paulo ACPI_OBJECT_LIST mp; 297*bbe4a97dSRui Paulo ACPI_BUFFER b; 298*bbe4a97dSRui Paulo char *name; 299*bbe4a97dSRui Paulo struct aibs_sensor *as; 300*bbe4a97dSRui Paulo ACPI_INTEGER v, l, h; 301*bbe4a97dSRui Paulo int so[3]; 302*bbe4a97dSRui Paulo 303*bbe4a97dSRui Paulo switch (st) { 304*bbe4a97dSRui Paulo case AIBS_VOLT: 305*bbe4a97dSRui Paulo name = "RVLT"; 306*bbe4a97dSRui Paulo as = sc->sc_asens_volt; 307*bbe4a97dSRui Paulo break; 308*bbe4a97dSRui Paulo case AIBS_TEMP: 309*bbe4a97dSRui Paulo name = "RTMP"; 310*bbe4a97dSRui Paulo as = sc->sc_asens_temp; 311*bbe4a97dSRui Paulo break; 312*bbe4a97dSRui Paulo case AIBS_FAN: 313*bbe4a97dSRui Paulo name = "RFAN"; 314*bbe4a97dSRui Paulo as = sc->sc_asens_fan; 315*bbe4a97dSRui Paulo break; 316*bbe4a97dSRui Paulo default: 317*bbe4a97dSRui Paulo return ENOENT; 318*bbe4a97dSRui Paulo } 319*bbe4a97dSRui Paulo if (as == NULL) 320*bbe4a97dSRui Paulo return ENOENT; 321*bbe4a97dSRui Paulo l = as[i].l; 322*bbe4a97dSRui Paulo h = as[i].h; 323*bbe4a97dSRui Paulo p.Type = ACPI_TYPE_INTEGER; 324*bbe4a97dSRui Paulo p.Integer.Value = as[i].i; 325*bbe4a97dSRui Paulo mp.Count = 1; 326*bbe4a97dSRui Paulo mp.Pointer = &p; 327*bbe4a97dSRui Paulo b.Length = ACPI_ALLOCATE_BUFFER; 328*bbe4a97dSRui Paulo ACPI_SERIAL_BEGIN(aibs); 329*bbe4a97dSRui Paulo rs = AcpiEvaluateObjectTyped(sc->sc_ah, name, &mp, &b, 330*bbe4a97dSRui Paulo ACPI_TYPE_INTEGER); 331*bbe4a97dSRui Paulo if (ACPI_FAILURE(rs)) { 332*bbe4a97dSRui Paulo ddevice_printf(sc->sc_dev, 333*bbe4a97dSRui Paulo "%s: %i: evaluation failed\n", 334*bbe4a97dSRui Paulo name, i); 335*bbe4a97dSRui Paulo ACPI_SERIAL_END(aibs); 336*bbe4a97dSRui Paulo return EIO; 337*bbe4a97dSRui Paulo } 338*bbe4a97dSRui Paulo bp = b.Pointer; 339*bbe4a97dSRui Paulo v = bp->Integer.Value; 340*bbe4a97dSRui Paulo AcpiOsFree(b.Pointer); 341*bbe4a97dSRui Paulo ACPI_SERIAL_END(aibs); 342*bbe4a97dSRui Paulo 343*bbe4a97dSRui Paulo switch (st) { 344*bbe4a97dSRui Paulo case AIBS_VOLT: 345*bbe4a97dSRui Paulo break; 346*bbe4a97dSRui Paulo case AIBS_TEMP: 347*bbe4a97dSRui Paulo v += 2732; 348*bbe4a97dSRui Paulo l += 2732; 349*bbe4a97dSRui Paulo h += 2732; 350*bbe4a97dSRui Paulo break; 351*bbe4a97dSRui Paulo case AIBS_FAN: 352*bbe4a97dSRui Paulo break; 353*bbe4a97dSRui Paulo } 354*bbe4a97dSRui Paulo so[0] = v; 355*bbe4a97dSRui Paulo so[1] = l; 356*bbe4a97dSRui Paulo so[2] = h; 357*bbe4a97dSRui Paulo return sysctl_handle_opaque(oidp, &so, sizeof(so), req); 358*bbe4a97dSRui Paulo } 359