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