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