apple_smc_temp.c revision 1.7 1 1.7 mrg /* $NetBSD: apple_smc_temp.c,v 1.7 2023/08/08 05:20:14 mrg Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*
4 1.1 riastrad * Apple System Management Controller: Temperature Sensors
5 1.1 riastrad */
6 1.1 riastrad
7 1.1 riastrad /*-
8 1.1 riastrad * Copyright (c) 2013 The NetBSD Foundation, Inc.
9 1.1 riastrad * All rights reserved.
10 1.1 riastrad *
11 1.1 riastrad * This code is derived from software contributed to The NetBSD Foundation
12 1.1 riastrad * by Taylor R. Campbell.
13 1.1 riastrad *
14 1.1 riastrad * Redistribution and use in source and binary forms, with or without
15 1.1 riastrad * modification, are permitted provided that the following conditions
16 1.1 riastrad * are met:
17 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
18 1.1 riastrad * notice, this list of conditions and the following disclaimer.
19 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
20 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
21 1.1 riastrad * documentation and/or other materials provided with the distribution.
22 1.1 riastrad *
23 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
34 1.1 riastrad */
35 1.1 riastrad
36 1.1 riastrad #include <sys/cdefs.h>
37 1.7 mrg __KERNEL_RCSID(0, "$NetBSD: apple_smc_temp.c,v 1.7 2023/08/08 05:20:14 mrg Exp $");
38 1.1 riastrad
39 1.1 riastrad #include <sys/types.h>
40 1.1 riastrad #include <sys/param.h>
41 1.1 riastrad #include <sys/device.h>
42 1.1 riastrad #include <sys/kmem.h>
43 1.2 riastrad #include <sys/module.h>
44 1.1 riastrad #include <sys/systm.h>
45 1.1 riastrad
46 1.1 riastrad #include <dev/ic/apple_smc.h>
47 1.1 riastrad
48 1.1 riastrad #include <dev/sysmon/sysmonvar.h>
49 1.1 riastrad
50 1.1 riastrad struct apple_smc_temp_softc {
51 1.1 riastrad device_t sc_dev;
52 1.1 riastrad struct apple_smc_tag *sc_smc;
53 1.1 riastrad struct sysmon_envsys *sc_sme;
54 1.1 riastrad struct {
55 1.1 riastrad struct apple_smc_key *sensor_key;
56 1.1 riastrad struct envsys_data sensor_data;
57 1.1 riastrad } *sc_sensors;
58 1.1 riastrad size_t sc_nsensors;
59 1.1 riastrad };
60 1.1 riastrad
61 1.1 riastrad static int apple_smc_temp_match(device_t, cfdata_t, void *);
62 1.1 riastrad static void apple_smc_temp_attach(device_t, device_t, void *);
63 1.1 riastrad static int apple_smc_temp_detach(device_t, int);
64 1.1 riastrad static void apple_smc_temp_refresh(struct sysmon_envsys *,
65 1.1 riastrad struct envsys_data *);
66 1.1 riastrad static int apple_smc_temp_count_sensors(struct apple_smc_tag *,
67 1.1 riastrad uint32_t *);
68 1.1 riastrad static void apple_smc_temp_count_sensors_scanner(struct apple_smc_tag *,
69 1.1 riastrad void *, struct apple_smc_key *);
70 1.1 riastrad static int apple_smc_temp_find_sensors(struct apple_smc_temp_softc *);
71 1.1 riastrad static int apple_smc_temp_find_sensors_init(struct apple_smc_tag *,
72 1.1 riastrad void *, uint32_t);
73 1.1 riastrad static void apple_smc_temp_find_sensors_scanner(struct apple_smc_tag *,
74 1.1 riastrad void *, struct apple_smc_key *);
75 1.1 riastrad static void apple_smc_temp_release_keys(struct apple_smc_temp_softc *);
76 1.1 riastrad static int apple_smc_scan_temp_sensors(struct apple_smc_tag *, void *,
77 1.1 riastrad int (*)(struct apple_smc_tag *, void *, uint32_t),
78 1.1 riastrad void (*)(struct apple_smc_tag *, void *,
79 1.1 riastrad struct apple_smc_key *));
80 1.1 riastrad static int apple_smc_bound_temp_sensors(struct apple_smc_tag *,
81 1.1 riastrad uint32_t *, uint32_t *);
82 1.1 riastrad static bool apple_smc_temp_sensor_p(const struct apple_smc_key *);
83 1.1 riastrad
84 1.1 riastrad CFATTACH_DECL_NEW(apple_smc_temp, sizeof(struct apple_smc_temp_softc),
85 1.1 riastrad apple_smc_temp_match, apple_smc_temp_attach, apple_smc_temp_detach, NULL);
86 1.1 riastrad
87 1.1 riastrad static int
88 1.1 riastrad apple_smc_temp_match(device_t parent, cfdata_t match, void *aux)
89 1.1 riastrad {
90 1.4 riastrad const struct apple_smc_attach_args *const asa = aux;
91 1.1 riastrad uint32_t nsensors;
92 1.1 riastrad int error;
93 1.1 riastrad
94 1.4 riastrad /* Find how many temperature sensors we have. */
95 1.1 riastrad error = apple_smc_temp_count_sensors(asa->asa_smc, &nsensors);
96 1.1 riastrad if (error)
97 1.1 riastrad return 0;
98 1.1 riastrad
99 1.4 riastrad /* If there aren't any, don't bother attaching. */
100 1.1 riastrad if (nsensors == 0)
101 1.1 riastrad return 0;
102 1.1 riastrad
103 1.1 riastrad return 1;
104 1.1 riastrad }
105 1.1 riastrad
106 1.1 riastrad static void
107 1.1 riastrad apple_smc_temp_attach(device_t parent, device_t self, void *aux)
108 1.1 riastrad {
109 1.4 riastrad struct apple_smc_temp_softc *const sc = device_private(self);
110 1.4 riastrad const struct apple_smc_attach_args *const asa = aux;
111 1.4 riastrad int error;
112 1.4 riastrad
113 1.4 riastrad /* Identify ourselves. */
114 1.4 riastrad aprint_normal(": Apple SMC temperature sensors\n");
115 1.1 riastrad
116 1.4 riastrad /* Initialize the softc. */
117 1.1 riastrad sc->sc_dev = self;
118 1.1 riastrad sc->sc_smc = asa->asa_smc;
119 1.4 riastrad
120 1.4 riastrad /* Create a sysmon_envsys record, but don't register it yet. */
121 1.1 riastrad sc->sc_sme = sysmon_envsys_create();
122 1.1 riastrad sc->sc_sme->sme_name = device_xname(self);
123 1.1 riastrad sc->sc_sme->sme_cookie = sc;
124 1.1 riastrad sc->sc_sme->sme_refresh = apple_smc_temp_refresh;
125 1.1 riastrad
126 1.4 riastrad /* Find and attach all the sensors. */
127 1.4 riastrad error = apple_smc_temp_find_sensors(sc);
128 1.4 riastrad if (error) {
129 1.4 riastrad aprint_error_dev(self, "failed to find sensors: %d\n", error);
130 1.4 riastrad goto fail;
131 1.4 riastrad }
132 1.4 riastrad
133 1.4 riastrad /* Sensors are all attached. Register with sysmon_envsys now. */
134 1.4 riastrad error = sysmon_envsys_register(sc->sc_sme);
135 1.4 riastrad if (error) {
136 1.4 riastrad aprint_error_dev(self, "failed to register with sysmon_envsys:"
137 1.4 riastrad " %d\n", error);
138 1.4 riastrad goto fail;
139 1.4 riastrad }
140 1.4 riastrad
141 1.4 riastrad /* Success! */
142 1.4 riastrad return;
143 1.4 riastrad
144 1.4 riastrad fail: sysmon_envsys_destroy(sc->sc_sme);
145 1.4 riastrad sc->sc_sme = NULL;
146 1.1 riastrad }
147 1.1 riastrad
148 1.1 riastrad static int
149 1.1 riastrad apple_smc_temp_detach(device_t self, int flags)
150 1.1 riastrad {
151 1.4 riastrad struct apple_smc_temp_softc *const sc = device_private(self);
152 1.1 riastrad
153 1.4 riastrad /* If we registered with sysmon_envsys, unregister. */
154 1.4 riastrad if (sc->sc_sme != NULL) {
155 1.4 riastrad sysmon_envsys_unregister(sc->sc_sme);
156 1.1 riastrad
157 1.4 riastrad KASSERT(sc->sc_sensors != NULL);
158 1.1 riastrad KASSERT(sc->sc_nsensors > 0);
159 1.4 riastrad
160 1.4 riastrad /* Release the keys and free the memory for sensor records. */
161 1.1 riastrad apple_smc_temp_release_keys(sc);
162 1.1 riastrad kmem_free(sc->sc_sensors,
163 1.1 riastrad (sizeof(sc->sc_sensors[0]) * sc->sc_nsensors));
164 1.1 riastrad sc->sc_sensors = NULL;
165 1.1 riastrad sc->sc_nsensors = 0;
166 1.1 riastrad }
167 1.1 riastrad
168 1.4 riastrad /* Success! */
169 1.1 riastrad return 0;
170 1.1 riastrad }
171 1.1 riastrad
172 1.1 riastrad static void
173 1.1 riastrad apple_smc_temp_refresh(struct sysmon_envsys *sme, struct envsys_data *edata)
174 1.1 riastrad {
175 1.4 riastrad struct apple_smc_temp_softc *const sc = sme->sme_cookie;
176 1.1 riastrad const struct apple_smc_key *key;
177 1.1 riastrad uint16_t utemp16;
178 1.1 riastrad int32_t temp;
179 1.1 riastrad int error;
180 1.1 riastrad
181 1.4 riastrad /* Sanity-check the sensor number out of paranoia. */
182 1.1 riastrad if (edata->sensor >= sc->sc_nsensors) {
183 1.1 riastrad aprint_error_dev(sc->sc_dev, "unknown sensor %"PRIu32"\n",
184 1.1 riastrad edata->sensor);
185 1.1 riastrad return;
186 1.1 riastrad }
187 1.1 riastrad
188 1.4 riastrad /* Read the raw temperature sensor value. */
189 1.1 riastrad key = sc->sc_sensors[edata->sensor].sensor_key;
190 1.4 riastrad KASSERT(key != NULL);
191 1.1 riastrad error = apple_smc_read_key_2(sc->sc_smc, key, &utemp16);
192 1.1 riastrad if (error) {
193 1.1 riastrad aprint_error_dev(sc->sc_dev,
194 1.1 riastrad "failed to read temperature sensor %"PRIu32" (%s): %d\n",
195 1.1 riastrad edata->sensor, apple_smc_key_name(key), error);
196 1.1 riastrad edata->state = ENVSYS_SINVALID;
197 1.1 riastrad return;
198 1.1 riastrad }
199 1.1 riastrad
200 1.1 riastrad /* Sign-extend, in case we ever get below freezing... */
201 1.1 riastrad temp = (int16_t)utemp16;
202 1.1 riastrad
203 1.1 riastrad /* Convert to `millicentigrade'. */
204 1.1 riastrad temp *= 250;
205 1.1 riastrad temp >>= 6;
206 1.1 riastrad
207 1.1 riastrad /* Convert to millikelvins. */
208 1.1 riastrad temp += 273150;
209 1.1 riastrad
210 1.1 riastrad /* Finally, convert to microkelvins as sysmon_envsys wants. */
211 1.1 riastrad temp *= 1000;
212 1.1 riastrad
213 1.4 riastrad /* Success! */
214 1.1 riastrad edata->value_cur = temp;
215 1.1 riastrad edata->state = ENVSYS_SVALID;
216 1.1 riastrad }
217 1.1 riastrad
218 1.1 riastrad static int
219 1.1 riastrad apple_smc_temp_count_sensors(struct apple_smc_tag *smc, uint32_t *nsensors)
220 1.1 riastrad {
221 1.1 riastrad
222 1.4 riastrad /* Start with zero sensors. */
223 1.1 riastrad *nsensors = 0;
224 1.1 riastrad
225 1.4 riastrad /* Count 'em. */
226 1.1 riastrad return apple_smc_scan_temp_sensors(smc, nsensors,
227 1.1 riastrad NULL,
228 1.1 riastrad &apple_smc_temp_count_sensors_scanner);
229 1.1 riastrad }
230 1.1 riastrad
231 1.1 riastrad static void
232 1.1 riastrad apple_smc_temp_count_sensors_scanner(struct apple_smc_tag *smc, void *arg,
233 1.1 riastrad struct apple_smc_key *key)
234 1.1 riastrad {
235 1.4 riastrad uint32_t *const nsensors = arg;
236 1.1 riastrad
237 1.1 riastrad (*nsensors)++;
238 1.1 riastrad apple_smc_release_key(smc, key);
239 1.1 riastrad }
240 1.1 riastrad
241 1.1 riastrad struct fss { /* Find Sensors State */
242 1.4 riastrad struct apple_smc_temp_softc *fss_sc;
243 1.4 riastrad unsigned int fss_sensor;
244 1.1 riastrad };
245 1.1 riastrad
246 1.1 riastrad static int
247 1.1 riastrad apple_smc_temp_find_sensors(struct apple_smc_temp_softc *sc)
248 1.1 riastrad {
249 1.1 riastrad struct fss fss;
250 1.1 riastrad int error;
251 1.1 riastrad
252 1.4 riastrad /* Start with zero sensors. */
253 1.1 riastrad fss.fss_sc = sc;
254 1.1 riastrad fss.fss_sensor = 0;
255 1.1 riastrad
256 1.4 riastrad /* Find 'em. */
257 1.1 riastrad error = apple_smc_scan_temp_sensors(sc->sc_smc, &fss,
258 1.1 riastrad &apple_smc_temp_find_sensors_init,
259 1.1 riastrad &apple_smc_temp_find_sensors_scanner);
260 1.1 riastrad if (error)
261 1.1 riastrad return error;
262 1.1 riastrad
263 1.4 riastrad /*
264 1.4 riastrad * Success guarantees that sc->sc_nsensors will be nonzero and
265 1.4 riastrad * sc->sc_sensors will be allocated.
266 1.4 riastrad */
267 1.4 riastrad KASSERT(sc->sc_sensors != NULL);
268 1.4 riastrad KASSERT(sc->sc_nsensors > 0);
269 1.4 riastrad
270 1.4 riastrad /* If we didn't find any sensors, bail. */
271 1.4 riastrad if (fss.fss_sensor == 0) {
272 1.4 riastrad kmem_free(sc->sc_sensors, sc->sc_nsensors);
273 1.4 riastrad sc->sc_sensors = NULL;
274 1.4 riastrad sc->sc_nsensors = 0;
275 1.4 riastrad return EIO;
276 1.4 riastrad }
277 1.4 riastrad
278 1.1 riastrad /* Shrink the array if we overshot. */
279 1.1 riastrad if (fss.fss_sensor < sc->sc_nsensors) {
280 1.4 riastrad void *const sensors = kmem_alloc((fss.fss_sensor *
281 1.1 riastrad sizeof(sc->sc_sensors[0])), KM_SLEEP);
282 1.4 riastrad
283 1.1 riastrad (void)memcpy(sensors, sc->sc_sensors,
284 1.1 riastrad (fss.fss_sensor * sizeof(sc->sc_sensors[0])));
285 1.1 riastrad kmem_free(sc->sc_sensors, sc->sc_nsensors);
286 1.4 riastrad sc->sc_sensors = sensors;
287 1.1 riastrad sc->sc_nsensors = fss.fss_sensor;
288 1.1 riastrad }
289 1.1 riastrad
290 1.4 riastrad /* Success! */
291 1.1 riastrad return 0;
292 1.1 riastrad }
293 1.1 riastrad
294 1.1 riastrad static int
295 1.1 riastrad apple_smc_temp_find_sensors_init(struct apple_smc_tag *smc, void *arg,
296 1.1 riastrad uint32_t nsensors)
297 1.1 riastrad {
298 1.4 riastrad struct fss *const fss = arg;
299 1.1 riastrad
300 1.4 riastrad /* Record the maximum number of sensors we may have. */
301 1.1 riastrad fss->fss_sc->sc_nsensors = nsensors;
302 1.4 riastrad
303 1.4 riastrad /* If we found a maximum of zero sensors, bail. */
304 1.4 riastrad if (nsensors == 0) {
305 1.1 riastrad fss->fss_sc->sc_sensors = NULL;
306 1.4 riastrad return EIO;
307 1.4 riastrad }
308 1.4 riastrad
309 1.4 riastrad /*
310 1.4 riastrad * If there may be any sensors, optimistically allocate as many
311 1.4 riastrad * records for them as we may possibly need.
312 1.4 riastrad */
313 1.4 riastrad fss->fss_sc->sc_sensors = kmem_alloc((nsensors *
314 1.4 riastrad sizeof(fss->fss_sc->sc_sensors[0])), KM_SLEEP);
315 1.1 riastrad
316 1.4 riastrad /* Success! */
317 1.1 riastrad return 0;
318 1.1 riastrad }
319 1.1 riastrad
320 1.1 riastrad static void
321 1.1 riastrad apple_smc_temp_find_sensors_scanner(struct apple_smc_tag *smc, void *arg,
322 1.1 riastrad struct apple_smc_key *key)
323 1.1 riastrad {
324 1.4 riastrad struct fss *const fss = arg;
325 1.1 riastrad const uint32_t sensor = fss->fss_sensor;
326 1.4 riastrad struct envsys_data *const edata =
327 1.1 riastrad &fss->fss_sc->sc_sensors[sensor].sensor_data;
328 1.1 riastrad int error;
329 1.1 riastrad
330 1.4 riastrad /* Initialize the envsys_data record for this temperature sensor. */
331 1.1 riastrad edata->units = ENVSYS_STEMP;
332 1.1 riastrad edata->state = ENVSYS_SINVALID;
333 1.1 riastrad edata->flags = ENVSYS_FHAS_ENTROPY;
334 1.1 riastrad
335 1.1 riastrad /*
336 1.4 riastrad * Use the SMC key name as the temperature sensor's name.
337 1.4 riastrad *
338 1.4 riastrad * XXX We ought to use a more meaningful name based on a table
339 1.4 riastrad * of known temperature sensors.
340 1.1 riastrad */
341 1.1 riastrad CTASSERT(sizeof(edata->desc) >= 4);
342 1.1 riastrad (void)strlcpy(edata->desc, apple_smc_key_name(key), 4);
343 1.1 riastrad
344 1.4 riastrad /* Attach this temperature sensor to sysmon_envsys. */
345 1.1 riastrad error = sysmon_envsys_sensor_attach(fss->fss_sc->sc_sme, edata);
346 1.1 riastrad if (error) {
347 1.1 riastrad aprint_error_dev(fss->fss_sc->sc_dev,
348 1.1 riastrad "failed to attach temperature sensor %s: %d\n",
349 1.1 riastrad apple_smc_key_name(key), error);
350 1.1 riastrad return;
351 1.1 riastrad }
352 1.1 riastrad
353 1.4 riastrad /* Success! */
354 1.1 riastrad fss->fss_sc->sc_sensors[sensor].sensor_key = key;
355 1.1 riastrad fss->fss_sensor++;
356 1.1 riastrad }
357 1.1 riastrad
358 1.1 riastrad static void
359 1.1 riastrad apple_smc_temp_release_keys(struct apple_smc_temp_softc *sc)
360 1.1 riastrad {
361 1.1 riastrad uint32_t sensor;
362 1.1 riastrad
363 1.1 riastrad for (sensor = 0; sensor < sc->sc_nsensors; sensor++) {
364 1.1 riastrad KASSERT(sc->sc_sensors[sensor].sensor_key != NULL);
365 1.1 riastrad apple_smc_release_key(sc->sc_smc,
366 1.1 riastrad sc->sc_sensors[sensor].sensor_key);
367 1.1 riastrad }
368 1.1 riastrad }
369 1.1 riastrad
370 1.1 riastrad static int
371 1.1 riastrad apple_smc_scan_temp_sensors(struct apple_smc_tag *smc, void *arg,
372 1.1 riastrad int (*init)(struct apple_smc_tag *, void *, uint32_t),
373 1.1 riastrad void (*scanner)(struct apple_smc_tag *, void *, struct apple_smc_key *))
374 1.1 riastrad {
375 1.1 riastrad uint32_t tstart, ustart, i;
376 1.1 riastrad struct apple_smc_key *key;
377 1.1 riastrad int error;
378 1.1 riastrad
379 1.4 riastrad /* Find [start, end) bounds on the temperature sensor key indices. */
380 1.1 riastrad error = apple_smc_bound_temp_sensors(smc, &tstart, &ustart);
381 1.1 riastrad if (error)
382 1.1 riastrad return error;
383 1.1 riastrad KASSERT(tstart <= ustart);
384 1.1 riastrad
385 1.4 riastrad /* Inform the caller of the number of candidates. */
386 1.1 riastrad if (init != NULL) {
387 1.1 riastrad error = (*init)(smc, arg, (ustart - tstart));
388 1.1 riastrad if (error)
389 1.1 riastrad return error;
390 1.1 riastrad }
391 1.1 riastrad
392 1.4 riastrad /* Take a closer look at all the candidates. */
393 1.1 riastrad for (i = tstart; i < ustart; i++) {
394 1.1 riastrad error = apple_smc_nth_key(smc, i, NULL, &key);
395 1.1 riastrad if (error)
396 1.1 riastrad continue;
397 1.1 riastrad
398 1.4 riastrad /* Skip it if it's not a temperature sensor. */
399 1.1 riastrad if (!apple_smc_temp_sensor_p(key)) {
400 1.1 riastrad apple_smc_release_key(smc, key);
401 1.1 riastrad continue;
402 1.1 riastrad }
403 1.1 riastrad
404 1.4 riastrad /* Scan it if it is one. */
405 1.1 riastrad (*scanner)(smc, arg, key);
406 1.1 riastrad }
407 1.1 riastrad
408 1.4 riastrad /* Success! */
409 1.1 riastrad return 0;
410 1.1 riastrad }
411 1.1 riastrad
412 1.1 riastrad static bool
413 1.1 riastrad apple_smc_temp_sensor_p(const struct apple_smc_key *key)
414 1.1 riastrad {
415 1.1 riastrad
416 1.4 riastrad /* It's a temperature sensor iff its type is sp78. */
417 1.1 riastrad return (0 == memcmp(apple_smc_key_desc(key)->asd_type,
418 1.1 riastrad APPLE_SMC_TYPE_SP78, 4));
419 1.1 riastrad }
420 1.1 riastrad
421 1.1 riastrad static int
422 1.1 riastrad apple_smc_bound_temp_sensors(struct apple_smc_tag *smc, uint32_t *tstart,
423 1.1 riastrad uint32_t *ustart)
424 1.1 riastrad {
425 1.1 riastrad int error;
426 1.1 riastrad
427 1.4 riastrad /* Find the first `T...' key. */
428 1.7 mrg error = apple_smc_key_search(smc, "T\0\0\0", tstart);
429 1.1 riastrad if (error)
430 1.1 riastrad return error;
431 1.1 riastrad
432 1.4 riastrad /* Find the first `U...' key. */
433 1.7 mrg error = apple_smc_key_search(smc, "U\0\0\0", ustart);
434 1.1 riastrad if (error)
435 1.1 riastrad return error;
436 1.1 riastrad
437 1.4 riastrad /* Sanity check: `T...' keys had better precede `U...' keys. */
438 1.1 riastrad if (!(*tstart <= *ustart))
439 1.1 riastrad return EIO;
440 1.1 riastrad
441 1.4 riastrad /* Success! */
442 1.1 riastrad return 0;
443 1.1 riastrad }
444 1.2 riastrad
445 1.5 pgoyette MODULE(MODULE_CLASS_DRIVER, apple_smc_temp, "apple_smc,sysmon_envsys");
446 1.2 riastrad
447 1.2 riastrad #ifdef _MODULE
448 1.2 riastrad #include "ioconf.c"
449 1.2 riastrad #endif
450 1.2 riastrad
451 1.2 riastrad static int
452 1.2 riastrad apple_smc_temp_modcmd(modcmd_t cmd, void *arg __unused)
453 1.2 riastrad {
454 1.4 riastrad #ifdef _MODULE
455 1.2 riastrad int error;
456 1.4 riastrad #endif
457 1.2 riastrad
458 1.2 riastrad switch (cmd) {
459 1.2 riastrad case MODULE_CMD_INIT:
460 1.2 riastrad #ifdef _MODULE
461 1.2 riastrad error = config_init_component(cfdriver_ioconf_apple_smc_temp,
462 1.2 riastrad cfattach_ioconf_apple_smc_temp,
463 1.2 riastrad cfdata_ioconf_apple_smc_temp);
464 1.3 riastrad if (error)
465 1.2 riastrad return error;
466 1.2 riastrad #endif
467 1.2 riastrad return 0;
468 1.2 riastrad
469 1.2 riastrad case MODULE_CMD_FINI:
470 1.2 riastrad #ifdef _MODULE
471 1.2 riastrad error = config_fini_component(cfdriver_ioconf_apple_smc_temp,
472 1.2 riastrad cfattach_ioconf_apple_smc_temp,
473 1.2 riastrad cfdata_ioconf_apple_smc_temp);
474 1.2 riastrad if (error)
475 1.2 riastrad return error;
476 1.2 riastrad #endif
477 1.2 riastrad return 0;
478 1.2 riastrad
479 1.2 riastrad default:
480 1.2 riastrad return ENOTTY;
481 1.2 riastrad }
482 1.2 riastrad }
483