summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2006-12-23 17:41:27 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2006-12-23 17:41:27 +0000
commit2da4a587cf08c4fd33f160fe0f40ff89d9d3a3c3 (patch)
tree6d38d369a994d81a2cfec847cdc1d983a56f9cea /sys/kern
parentcabbc40b9fc9c7967d27aa19283263d4553ed17d (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.c115
-rw-r--r--sys/kern/kern_sysctl.c24
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);