diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-12-23 17:41:27 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-12-23 17:41:27 +0000 |
commit | 2da4a587cf08c4fd33f160fe0f40ff89d9d3a3c3 (patch) | |
tree | 6d38d369a994d81a2cfec847cdc1d983a56f9cea /sys/kern | |
parent | cabbc40b9fc9c7967d27aa19283263d4553ed17d (diff) |
kernel code implimemting the new two-level sensor api; written by
Constantine A. Murenin
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sensors.c | 115 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 24 |
2 files changed, 113 insertions, 26 deletions
diff --git a/sys/kern/kern_sensors.c b/sys/kern/kern_sensors.c index a01eedf108b..ff0ac07195a 100644 --- a/sys/kern/kern_sensors.c +++ b/sys/kern/kern_sensors.c @@ -1,7 +1,8 @@ -/* $OpenBSD: kern_sensors.c,v 1.15 2006/11/06 11:35:15 dlg Exp $ */ +/* $OpenBSD: kern_sensors.c,v 1.16 2006/12/23 17:41:26 deraadt Exp $ */ /* * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> + * Copyright (c) 2006 Constantine A. Murenin <cnst+openbsd@bugmail.mojo.ru> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -30,8 +31,8 @@ #include <sys/sensors.h> #include "hotplug.h" -int sensors_count = 0; -SLIST_HEAD(, sensor) sensors_list = SLIST_HEAD_INITIALIZER(&sensors_list); +int sensordev_count = 0; +SLIST_HEAD(, sensordev) sensordev_list = SLIST_HEAD_INITIALIZER(sensordev_list); struct sensor_task { void *arg; @@ -50,55 +51,127 @@ void sensor_task_schedule(struct sensor_task *); TAILQ_HEAD(, sensor_task) tasklist = TAILQ_HEAD_INITIALIZER(tasklist); void -sensor_add(struct sensor *sens) +sensordev_install(struct sensordev *sensdev) { - struct sensor *v, *nv; + struct sensordev *v, *nv; int s; s = splhigh(); - if (sensors_count == 0) { - sens->num = 0; - SLIST_INSERT_HEAD(&sensors_list, sens, list); + if (sensordev_count == 0) { + sensdev->num = 0; + SLIST_INSERT_HEAD(&sensordev_list, sensdev, list); } else { - for (v = SLIST_FIRST(&sensors_list); + for (v = SLIST_FIRST(&sensordev_list); (nv = SLIST_NEXT(v, list)) != NULL; v = nv) if (nv->num - v->num > 1) break; - sens->num = v->num + 1; - SLIST_INSERT_AFTER(v, sens, list); + sensdev->num = v->num + 1; + SLIST_INSERT_AFTER(v, sensdev, list); } - sensors_count++; + sensordev_count++; splx(s); #if NHOTPLUG > 0 - hotplug_device_attach(DV_DULL, "sensor"); + hotplug_device_attach(DV_DULL, "sensordev"); #endif } void -sensor_del(struct sensor *sens) +sensor_attach(struct sensordev *sensdev, struct sensor *sens) +{ + struct sensor *v, *nv; + struct sensors_head *sh; + int s, i; + + s = splhigh(); + sh = &sensdev->sensors_list; + if (sensdev->sensors_count == 0) { + for (i = 0; i < SENSOR_MAX_TYPES; i++) + sensdev->maxnumt[i] = 0; + sens->numt = 0; + SLIST_INSERT_HEAD(sh, sens, list); + } else { + for (v = SLIST_FIRST(sh); + (nv = SLIST_NEXT(v, list)) != NULL; v = nv) + if (v->type == sens->type && (v->type != nv->type || + (v->type == nv->type && nv->numt - v->numt > 1))) + break; + /* sensors of the same type go after each other */ + if (v->type == sens->type) + sens->numt = v->numt + 1; + else + sens->numt = 0; + SLIST_INSERT_AFTER(v, sens, list); + } + /* we only increment maxnumt[] if the sensor was added + * to the last position of sensors of this type + */ + if (sensdev->maxnumt[sens->type] == sens->numt) + sensdev->maxnumt[sens->type]++; + sensdev->sensors_count++; + splx(s); +} + +void +sensordev_deinstall(struct sensordev *sensdev) { int s; s = splhigh(); - sensors_count--; - SLIST_REMOVE(&sensors_list, sens, sensor, list); + sensordev_count--; + SLIST_REMOVE(&sensordev_list, sensdev, sensordev, list); splx(s); #if NHOTPLUG > 0 - hotplug_device_detach(DV_DULL, "sensor"); + hotplug_device_detach(DV_DULL, "sensordev"); #endif } +void +sensor_detach(struct sensordev *sensdev, struct sensor *sens) +{ + struct sensors_head *sh; + int s; + + s = splhigh(); + sh = &sensdev->sensors_list; + sensdev->sensors_count--; + SLIST_REMOVE(sh, sens, sensor, list); + /* we only decrement maxnumt[] if this is the tail + * sensor of this type + */ + if (sens->numt == sensdev->maxnumt[sens->type] - 1) + sensdev->maxnumt[sens->type]--; + splx(s); +} + +struct sensordev * +sensordev_get(int num) +{ + struct sensordev *sd; + + SLIST_FOREACH(sd, &sensordev_list, list) + if (sd->num == num) + return (sd); + + return (NULL); +} + struct sensor * -sensor_get(int num) +sensor_find(int dev, enum sensor_type type, int numt) { struct sensor *s; + struct sensordev *sensdev; + struct sensors_head *sh; + + sensdev = sensordev_get(dev); + if (sensdev == NULL) + return (NULL); - SLIST_FOREACH(s, &sensors_list, list) { - if (s->num == num) + sh = &sensdev->sensors_list; + SLIST_FOREACH(s, sh, list) + if (s->type == type && s->numt == numt) return (s); - } return (NULL); } diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 9fac3b66521..65f086f229e 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.145 2006/12/12 23:14:28 dim Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.146 2006/12/23 17:41:26 deraadt Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -1791,14 +1791,28 @@ sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { struct sensor *s; - int num; + struct sensordev *sd; + int dev; + enum sensor_type type; + int numt; - if (namelen != 1) + if (namelen != 1 && namelen != 3) return (ENOTDIR); - num = name[0]; + dev = name[0]; + if (namelen == 1) { + sd = sensordev_get(dev); + if (sd == NULL) + return (ENOENT); + + return (sysctl_rdstruct(oldp, oldlenp, newp, sd, + sizeof(struct sensordev))); + } + + type = name[1]; + numt = name[2]; - s = sensor_get(num); + s = sensor_find(dev, type, numt); if (s == NULL) return (ENOENT); |