1/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source.  A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright 2020 Oxide Computer Company
14 */
15
16/*
17 * Kernel Sensor Framework
18 *
19 * The kernel sensor framework exists to provide a simple and straightforward
20 * means for various parts of the system to declare and instantiate sensor
21 * information. Between this and the ksensor character device
22 * (uts/common/io/ksensor/ksensor_drv.c) this exposes per-device sensors and
23 * character devices.
24 *
25 * --------------------------
26 * Driver and User Interfaces
27 * --------------------------
28 *
29 * Each sensor that is registered with the framework is exposed as a character
30 * device under /dev/sensors. The device class and node name are often ':'
31 * delineated and must begin with 'ddi_sensor'. Everything after 'ddi_sensor'
32 * will be created in a directory under /dev/sensors. So for example the Intel
33 * PCH driver uses a class "ddi_sensor:temperature:pch" and a node name of
34 * 'ts.%d'. This creates the node /dev/sensors/temperature/pch/ts.0. The
35 * devfsadm plugin automatically handles the creation of directories which makes
36 * the addition of additional sensor types easy to create.
37 *
38 * Strictly speaking, any device can manage their own sensors and minor nodes by
39 * using the appropriate class and implementing the corresponding ioctls. That
40 * was how the first kernel sensors were written; however, there are a lot of
41 * issues with that which led to this:
42 *
43 * 1. Every driver had to actually implement character devices.
44 *
45 * 2. Every driver had to duplicate a lot of the logic around open(9E),
46 *    close(9E), and ioctl(9E).
47 *
48 * 3. Drivers that tied into frameworks like mac(9E) or SCSAv3 needed a lot more
49 *    work to fit into this model. For example, because the minor state is
50 *    shared between all the instances and the frameworks, they would have
51 *    required shared, global state that they don't have today.
52 *
53 * Ultimately, having an operations vector and a callback argument makes work a
54 * lot simpler for the producers of sensor data and that simplicity makes it
55 * worthwhile to take on additional effort and work here.
56 *
57 * ----------
58 * Components
59 * ----------
60 *
61 * The ksensor framework is made of a couple of different pieces:
62 *
63 * 1. This glue that is a part of genunix.
64 * 2. The ksensor character device driver.
65 * 3. Sensor providers, which are generally drivers that register with the
66 *    ksensor framework.
67 *
68 * The implementation of (1) is all in this file. The implementation of (2) is
69 * in uts/common/io/ksensor/ksensor_drv.c. The implementation of (3) is found in
70 * all of the different leaf devices. Examples of (3) include pchtemp(7D) and
71 * igb(7D).
72 *
73 * We separate numbers one and two into two different components for a few
74 * reasons. The most important thing is that drivers that provide sensors should
75 * not be dependent on some other part of the system having been loaded. This
76 * makes a compelling argument for it being a part of the core kernel. However,
77 * like other subsystems (e.g. kstats, smbios, etc.), it's useful to separate
78 * out the thing that provides the interface to users with the thing that is
79 * used to glue together providers in the kernel. There's the added benefit that
80 * it's practically simpler to spin up a pseudo-device through a module.
81 *
82 * The ksensor character device driver (2) registers with the main genunix
83 * ksensor code (1) when it attaches and when it detaches. The kernel only
84 * allows a single driver to be attached to it. When that character device
85 * driver attaches, the ksensor framework will walk through all of the currently
86 * registered sensors and inform the character device driver of the nodes that
87 * it needs to create. While the character device driver is attached, the
88 * ksensor framework will also call back into it when a sensor needs to be
89 * removed.
90 *
91 * Generally speaking, this distinction of responsibilities allows the kernel
92 * sensor character device driver to attach and detach without impact to the
93 * sensor providers or them even being notified at all, it's all transparent to
94 * them.
95 *
96 * ------------------------------
97 * Sensor Lifetime and detach(9E)
98 * ------------------------------
99 *
100 * Traditionally, a device driver may be detached by the broader kernel whenever
101 * the kernel desires it. On debug builds this happens by a dedicated thread. On
102 * a non-debug build this may happen due to memory pressure or as an attempt to
103 * reclaim idle resources (though this is much less common). However, when the
104 * module is detached, the system remembers that minor nodes previously existed
105 * and that entries in /devices had been created. When something proceeds to
106 * access an entry in /devices again, the system will use that to bring a driver
107 * back to life. It doesn't matter whether it's a pseudo-device driver or
108 * something else, this can happen.
109 *
110 * One downside to the sensor framework, is that we need to emulate this
111 * behavior which leads to some amount of complexity here. But this is a
112 * worthwhile tradeoff as it makes things much simpler for providers and it's
113 * not too hard for us to emulate this behavior.
114 *
115 * When a sensor provider registers the sensor, the sensor becomes available to
116 * the system. When the sensor provider unregisters with the system, which
117 * happens during its detach routine, then we note that it has been detached;
118 * however, we don't delete its minor node and if something accesses it, we
119 * attempt to load the driver again, the same way that devfs (the file system
120 * behind /devices) does.
121 *
122 * For each dev_info_t that registers a sensor we register a callback such that
123 * when the device is removed, e.g. someone called rem_drv or physically pulls
124 * the device, then we'll be able to finally clean up the device. This lifetime
125 * can be represented in the following image:
126 *
127 *         |
128 *         |
129 *         +-----<-------------------------------------+
130 *         |                                           |
131 *         | . . call ksensor_create()                 |
132 *         v                                           |
133 *     +-------+                                       |
134 *     | Valid |                                       |
135 *     +-------+                                       |
136 *         |                                           ^
137 *         | . . call ksensor_remove()                 |
138 *         v                                           |
139 *    +---------+                                      |
140 *    | Invalid |                                      |
141 *    +---------+                                      |
142 *      |     |                                        |
143 *      |     | . . user uses sensor again             |
144 *      |     |                                        |
145 *      |     +-------------------+                    |
146 *      |                         |                    |
147 *      |                         v                    |
148 *      |                 +---------------+            |
149 *      |                 | Attatching... |-->---------+
150 *      |                 +---------------+
151 *      | . . ddi unbind cb       |
152 *      |                         |
153 *      v                         | . . attatch fails or
154 *   +---------+                  |     no call to ksensor_create()
155 *   | Deleted |--<---------------+     again
156 *   +---------+
157 *
158 * When the DDI unbind callback is called, we know that the device is going to
159 * be removed. However, this happens within a subtle context with a majority of
160 * the device tree held (at least the dip's parent). In particular, another
161 * thread may be trying to obtain a hold on it and be blocked in
162 * ndi_devi_enter(). As the callback thread holds that, that could lead to a
163 * deadlock. As a result, we clean things up in two phases. One during the
164 * synchronous callback and the other via a taskq. In the first phase we
165 * logically do the following:
166 *
167 *  o Remove the dip from the list of ksensor dips and set the flag that
168 *    indicates that it's been removed.
169 *  o Remove all of the sensors from the global avl to make sure that new
170 *    threads cannot look it up.
171 *
172 * Then, after the taskq is dispatched, we do the following in taskq context:
173 *
174 *  o Tell the ksensor driver that it should remove the minor node.
175 *  o Block on each sensor until it is no-longer busy and then clean it up.
176 *  o Clean up the ksensor_dip_t.
177 *
178 * ------------------
179 * Accessing a Sensor
180 * ------------------
181 *
182 * Access to a particular sensor is serialized in the system. In addition to
183 * that, a number of steps are required to access one that is not unlike
184 * accessing a character device. When a given sensor is held the KSENSOR_F_BUSY
185 * flag is set in the ksensor_flags member. In addition, as part of taking a
186 * hold a number of side effects occur that ensure that the sensor provider's
187 * dev_info_t is considered busy and can't be detached.
188 *
189 * To obtain a hold on a sensor the following logical steps are required (see
190 * ksensor_hold_by_id() for the implementation):
191 *
192 *  1. Map the minor to the ksensor_t via the avl tree
193 *  2. Check that the ksensor's dip is valid
194 *  3. If the sensor is busy, wait until it is no longer so, and restart from
195 *     the top. Otherwise, mark the sensor as busy.
196 *  4. Enter the parent and place a hold on the sensor provider's dip.
197 *  5. Once again check if the dip is removed or not because we have to drop
198 *     locks during that operation.
199 *  6. Check if the ksensor has the valid flag set. If not, attempt to configure
200 *     the dip.
201 *  7. Assuming the sensor is now valid, we can return it.
202 *
203 * After this point, the sensor is considered valid for use. Once the consumer
204 * is finished with the sensor, it should be released by calling
205 * ksensor_release().
206 *
207 * An important aspect of the above scheme is that the KSENSOR_F_BUSY flag is
208 * required to progress through the validation and holding of the device. This
209 * makes sure that only one thread is attempting to attach it at a given time. A
210 * reasonable future optimization would be to amortize this cost in open(9E)
211 * and close(9E) of the minor and to bump a count as it being referenced as long
212 * as it is open.
213 *
214 * -----------------------------
215 * Character Device Registration
216 * -----------------------------
217 *
218 * The 'ksensor' character device driver can come and go. To support this, the
219 * ksensor framework communicates with the ksensor character device by a
220 * well-defined set of callbacks, used to indicate sensor addition and removal.
221 * The ksensor character device is found in uts/common/io/ksensor/ksensor_drv.c.
222 * The ksensor character device is responsible for creating and destroying minor
223 * nodes.
224 *
225 * Each ksensor_t has a flag, KSENSOR_F_NOTIFIED, that is used to indicate
226 * whether or not the registered driver has been notified of the sensor. When a
227 * callback is first registered, we'll walk through the entire list of nodes to
228 * make sure that its minor has been created. When unregistering, the minor node
229 * remove callback will not be called; however, this can generally by dealt with
230 * by calling something like ddi_remove_minor_node(dip, NULL).
231 *
232 * -------
233 * Locking
234 * -------
235 *
236 * The following rules apply to dealing with lock ordering:
237 *
238 * 1. The global ksensor_g_mutex protects all global data and must be taken
239 *    before a ksensor_t's individual mutex.
240 *
241 * 2. A thread should not hold any two ksensor_t's mutex at any time.
242 *
243 * 3. No locks should be held when attempting to grab or manipulate a
244 *    dev_info_t, e.g. ndi_devi_enter().
245 *
246 * 4. Unless the ksensor is actively being held, whenever a ksensor is found,
247 *    one must check whether the ksensor_dip_t flag KSENSOR_DIP_F_REMOVED is
248 *    set or not and whether the ksensor_t's KSENSOR_F_VALID flag is set.
249 */
250
251#include <sys/types.h>
252#include <sys/file.h>
253#include <sys/errno.h>
254#include <sys/cred.h>
255#include <sys/ddi.h>
256#include <sys/stat.h>
257#include <sys/sunddi.h>
258#include <sys/sunndi.h>
259#include <sys/esunddi.h>
260#include <sys/ksensor_impl.h>
261#include <sys/ddi_impldefs.h>
262#include <sys/pci.h>
263#include <sys/avl.h>
264#include <sys/list.h>
265#include <sys/stddef.h>
266#include <sys/sysmacros.h>
267#include <sys/fs/dv_node.h>
268
269typedef enum {
270	/*
271	 * This flag indicates that the subscribing ksensor character device has
272	 * been notified about this flag.
273	 */
274	KSENSOR_F_NOTIFIED	= 1 << 0,
275	/*
276	 * This indicates that the sensor is currently valid, meaning that the
277	 * ops vector and argument are safe to use. This is removed when a
278	 * driver with a sensor is detached.
279	 */
280	KSENSOR_F_VALID		= 1 << 1,
281	/*
282	 * Indicates that a client has a hold on the sensor for some purpose.
283	 * This must be set before trying to get an NDI hold. Once this is set
284	 * and a NDI hold is in place, it is safe to use the operations vector
285	 * and argument.
286	 */
287	KSENSOR_F_BUSY		= 1 << 2,
288} ksensor_flags_t;
289
290typedef enum {
291	KSENSOR_DIP_F_REMOVED	= 1 << 0
292} ksensor_dip_flags_t;
293
294typedef struct {
295	list_node_t ksdip_link;
296	ksensor_dip_flags_t ksdip_flags;
297	dev_info_t *ksdip_dip;
298	ddi_unbind_callback_t ksdip_cb;
299	list_t ksdip_sensors;
300} ksensor_dip_t;
301
302typedef struct {
303	kmutex_t ksensor_mutex;
304	kcondvar_t ksensor_cv;
305	ksensor_flags_t ksensor_flags;
306	list_node_t ksensor_dip_list;
307	avl_node_t ksensor_id_avl;
308	uint_t ksensor_nwaiters;
309	ksensor_dip_t *ksensor_ksdip;
310	char *ksensor_name;
311	char *ksensor_class;
312	id_t ksensor_id;
313	const ksensor_ops_t *ksensor_ops;
314	void *ksensor_arg;
315} ksensor_t;
316
317static kmutex_t ksensor_g_mutex;
318static id_space_t *ksensor_ids;
319static list_t ksensor_dips;
320static avl_tree_t ksensor_avl;
321static dev_info_t *ksensor_cb_dip;
322static ksensor_create_f ksensor_cb_create;
323static ksensor_remove_f ksensor_cb_remove;
324
325static int
326ksensor_avl_compare(const void *l, const void *r)
327{
328	const ksensor_t *kl = l;
329	const ksensor_t *kr = r;
330
331	if (kl->ksensor_id > kr->ksensor_id) {
332		return (1);
333	} else if (kl->ksensor_id < kr->ksensor_id) {
334		return (-1);
335	} else {
336		return (0);
337	}
338}
339
340static ksensor_t *
341ksensor_find_by_id(id_t id)
342{
343	ksensor_t k, *ret;
344
345	ASSERT(MUTEX_HELD(&ksensor_g_mutex));
346
347	k.ksensor_id = id;
348	return (avl_find(&ksensor_avl, &k, NULL));
349
350}
351
352static ksensor_t *
353ksensor_search_ksdip(ksensor_dip_t *ksdip, const char *name, const char *class)
354{
355	ksensor_t *s;
356
357	ASSERT(MUTEX_HELD(&ksensor_g_mutex));
358
359	for (s = list_head(&ksdip->ksdip_sensors); s != NULL;
360	    s = list_next(&ksdip->ksdip_sensors, s)) {
361		if (strcmp(s->ksensor_name, name) == 0 &&
362		    strcmp(s->ksensor_class, class) == 0) {
363			return (s);
364		}
365	}
366
367	return (NULL);
368}
369
370static void
371ksensor_free_sensor(ksensor_t *sensor)
372{
373	strfree(sensor->ksensor_name);
374	strfree(sensor->ksensor_class);
375	id_free(ksensor_ids, sensor->ksensor_id);
376	mutex_destroy(&sensor->ksensor_mutex);
377	kmem_free(sensor, sizeof (ksensor_t));
378}
379
380static void
381ksensor_free_dip(ksensor_dip_t *ksdip)
382{
383	list_destroy(&ksdip->ksdip_sensors);
384	kmem_free(ksdip, sizeof (ksensor_dip_t));
385}
386
387static void
388ksensor_dip_unbind_taskq(void *arg)
389{
390	ksensor_dip_t *k = arg;
391	ksensor_t *sensor;
392
393	/*
394	 * First notify an attached driver that the nodes are going away
395	 * before we block and wait on them.
396	 */
397	mutex_enter(&ksensor_g_mutex);
398	for (sensor = list_head(&k->ksdip_sensors); sensor != NULL;
399	    sensor = list_next(&k->ksdip_sensors, sensor)) {
400		mutex_enter(&sensor->ksensor_mutex);
401		if (sensor->ksensor_flags & KSENSOR_F_NOTIFIED) {
402			ksensor_cb_remove(sensor->ksensor_id,
403			    sensor->ksensor_name);
404			sensor->ksensor_flags &= ~KSENSOR_F_NOTIFIED;
405		}
406		mutex_exit(&sensor->ksensor_mutex);
407	}
408	mutex_exit(&ksensor_g_mutex);
409
410	/*
411	 * Now that the driver has destroyed its minor, wait for anything that's
412	 * still there.
413	 */
414	while ((sensor = list_remove_head(&k->ksdip_sensors)) != NULL) {
415		mutex_enter(&sensor->ksensor_mutex);
416		while ((sensor->ksensor_flags & KSENSOR_F_BUSY) != 0 ||
417		    sensor->ksensor_nwaiters > 0) {
418			cv_wait(&sensor->ksensor_cv, &sensor->ksensor_mutex);
419		}
420		mutex_exit(&sensor->ksensor_mutex);
421		ksensor_free_sensor(sensor);
422	}
423	ksensor_free_dip(k);
424}
425
426static void
427ksensor_dip_unbind_cb(void *arg, dev_info_t *dip)
428{
429	ksensor_dip_t *k = arg;
430	ksensor_t *sensor;
431
432	/*
433	 * Remove the dip and the associated sensors from global visibility.
434	 * This will ensure that no new clients can find this; however, others
435	 * may have extent attempts to grab it (but lost the race in an NDI
436	 * hold).
437	 */
438	mutex_enter(&ksensor_g_mutex);
439	list_remove(&ksensor_dips, k);
440	k->ksdip_flags |= KSENSOR_DIP_F_REMOVED;
441	for (sensor = list_head(&k->ksdip_sensors); sensor != NULL;
442	    sensor = list_next(&k->ksdip_sensors, sensor)) {
443		avl_remove(&ksensor_avl, sensor);
444	}
445	mutex_exit(&ksensor_g_mutex);
446
447	(void) taskq_dispatch(system_taskq, ksensor_dip_unbind_taskq, k,
448	    TQ_SLEEP);
449}
450
451static ksensor_dip_t *
452ksensor_dip_create(dev_info_t *dip)
453{
454	ksensor_dip_t *k;
455
456	k = kmem_zalloc(sizeof (ksensor_dip_t), KM_SLEEP);
457	k->ksdip_dip = dip;
458	k->ksdip_cb.ddiub_cb = ksensor_dip_unbind_cb;
459	k->ksdip_cb.ddiub_arg = k;
460	list_create(&k->ksdip_sensors, sizeof (ksensor_t),
461	    offsetof(ksensor_t, ksensor_dip_list));
462	e_ddi_register_unbind_callback(dip, &k->ksdip_cb);
463
464	return (k);
465}
466
467static ksensor_dip_t *
468ksensor_dip_find(dev_info_t *dip)
469{
470	ksensor_dip_t *k;
471
472	ASSERT(MUTEX_HELD(&ksensor_g_mutex));
473	for (k = list_head(&ksensor_dips); k != NULL;
474	    k = list_next(&ksensor_dips, k)) {
475		if (dip == k->ksdip_dip) {
476			return (k);
477		}
478	}
479
480	return (NULL);
481}
482
483int
484ksensor_create(dev_info_t *dip, const ksensor_ops_t *ops, void *arg,
485    const char *name, const char *class, id_t *idp)
486{
487	ksensor_dip_t *ksdip;
488	ksensor_t *sensor;
489
490	if (dip == NULL || ops == NULL || name == NULL || class == NULL ||
491	    idp == NULL) {
492		return (EINVAL);
493	}
494
495	if (!DEVI_IS_ATTACHING(dip)) {
496		return (EAGAIN);
497	}
498
499	mutex_enter(&ksensor_g_mutex);
500	ksdip = ksensor_dip_find(dip);
501	if (ksdip == NULL) {
502		ksdip = ksensor_dip_create(dip);
503		list_insert_tail(&ksensor_dips, ksdip);
504	}
505
506	sensor = ksensor_search_ksdip(ksdip, name, class);
507	if (sensor != NULL) {
508		ASSERT3P(sensor->ksensor_ksdip, ==, ksdip);
509		if ((sensor->ksensor_flags & KSENSOR_F_VALID) != 0) {
510			mutex_exit(&ksensor_g_mutex);
511			dev_err(dip, CE_WARN, "tried to create sensor %s:%s "
512			    "which is currently active", class, name);
513			return (EEXIST);
514		}
515
516		sensor->ksensor_ops = ops;
517		sensor->ksensor_arg = arg;
518	} else {
519		sensor = kmem_zalloc(sizeof (ksensor_t), KM_SLEEP);
520		sensor->ksensor_ksdip = ksdip;
521		sensor->ksensor_name = ddi_strdup(name, KM_SLEEP);
522		sensor->ksensor_class = ddi_strdup(class, KM_SLEEP);
523		sensor->ksensor_id = id_alloc(ksensor_ids);
524		sensor->ksensor_ops = ops;
525		sensor->ksensor_arg = arg;
526		list_insert_tail(&ksdip->ksdip_sensors, sensor);
527		avl_add(&ksensor_avl, sensor);
528	}
529
530	sensor->ksensor_flags |= KSENSOR_F_VALID;
531
532	if (ksensor_cb_create != NULL) {
533
534		if (ksensor_cb_create(sensor->ksensor_id, sensor->ksensor_class,
535		    sensor->ksensor_name) == 0) {
536			sensor->ksensor_flags |= KSENSOR_F_NOTIFIED;
537		}
538	}
539
540	*idp = sensor->ksensor_id;
541	mutex_exit(&ksensor_g_mutex);
542
543	return (0);
544}
545
546int
547ksensor_create_scalar_pcidev(dev_info_t *dip, uint_t kind,
548    const ksensor_ops_t *ops, void *arg, const char *name, id_t *idp)
549{
550	char *pci_name, *type;
551	const char *class;
552	int *regs, ret;
553	uint_t nregs;
554	uint16_t bus, dev;
555
556	switch (kind) {
557	case SENSOR_KIND_TEMPERATURE:
558		class = "ddi_sensor:temperature:pci";
559		break;
560	case SENSOR_KIND_VOLTAGE:
561		class = "ddi_sensor:voltage:pci";
562		break;
563	case SENSOR_KIND_CURRENT:
564		class = "ddi_sensor:current:pci";
565		break;
566	default:
567		return (ENOTSUP);
568	}
569
570	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "device_type",
571	    &type) != DDI_PROP_SUCCESS) {
572		return (EINVAL);
573	}
574
575	if (strcmp(type, "pciex") != 0 && strcmp(type, "pci") != 0) {
576		ddi_prop_free(type);
577		return (EINVAL);
578	}
579	ddi_prop_free(type);
580
581	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "reg",
582	    &regs, &nregs) != DDI_PROP_SUCCESS) {
583		return (EINVAL);
584	}
585
586	if (nregs < 1) {
587		ddi_prop_free(regs);
588		return (EIO);
589	}
590
591	bus = PCI_REG_BUS_G(regs[0]);
592	dev = PCI_REG_DEV_G(regs[0]);
593	ddi_prop_free(regs);
594
595	pci_name = kmem_asprintf("%x.%x:%s", bus, dev, name);
596
597	ret = ksensor_create(dip, ops, arg, pci_name, class, idp);
598	strfree(pci_name);
599	return (ret);
600}
601
602/*
603 * When a driver removes a sensor, we basically mark it as invalid. This happens
604 * because drivers can detach and we will need to reattach them when the sensor
605 * is used again.
606 */
607int
608ksensor_remove(dev_info_t *dip, id_t id)
609{
610	ksensor_dip_t *kdip;
611	ksensor_t *sensor;
612
613	if (!DEVI_IS_ATTACHING(dip) && !DEVI_IS_DETACHING(dip)) {
614		return (EAGAIN);
615	}
616
617	mutex_enter(&ksensor_g_mutex);
618	kdip = ksensor_dip_find(dip);
619	if (kdip == NULL) {
620		mutex_exit(&ksensor_g_mutex);
621		return (ENOENT);
622	}
623
624	for (sensor = list_head(&kdip->ksdip_sensors); sensor != NULL;
625	    sensor = list_next(&kdip->ksdip_sensors, sensor)) {
626		if (sensor->ksensor_id == id || id == KSENSOR_ALL_IDS) {
627			mutex_enter(&sensor->ksensor_mutex);
628			sensor->ksensor_flags &= ~KSENSOR_F_VALID;
629			sensor->ksensor_ops = NULL;
630			sensor->ksensor_arg = NULL;
631			mutex_exit(&sensor->ksensor_mutex);
632		}
633	}
634	mutex_exit(&ksensor_g_mutex);
635	return (0);
636}
637
638static void
639ksensor_release(ksensor_t *sensor)
640{
641	int circ;
642	dev_info_t *pdip;
643
644	ddi_release_devi(sensor->ksensor_ksdip->ksdip_dip);
645
646	mutex_enter(&sensor->ksensor_mutex);
647	sensor->ksensor_flags &= ~KSENSOR_F_BUSY;
648	cv_broadcast(&sensor->ksensor_cv);
649	mutex_exit(&sensor->ksensor_mutex);
650}
651
652static int
653ksensor_hold_by_id(id_t id, ksensor_t **outp)
654{
655	int circ;
656	ksensor_t *sensor;
657	dev_info_t *pdip;
658
659restart:
660	mutex_enter(&ksensor_g_mutex);
661	sensor = ksensor_find_by_id(id);
662	if (sensor == NULL) {
663		mutex_exit(&ksensor_g_mutex);
664		*outp = NULL;
665		return (ESTALE);
666	}
667
668	if ((sensor->ksensor_ksdip->ksdip_flags & KSENSOR_DIP_F_REMOVED) != 0) {
669		mutex_exit(&ksensor_g_mutex);
670		*outp = NULL;
671		return (ESTALE);
672	}
673
674	mutex_enter(&sensor->ksensor_mutex);
675	if ((sensor->ksensor_flags & KSENSOR_F_BUSY) != 0) {
676		mutex_exit(&ksensor_g_mutex);
677		sensor->ksensor_nwaiters++;
678		while ((sensor->ksensor_flags & KSENSOR_F_BUSY) != 0) {
679			int cv = cv_wait_sig(&sensor->ksensor_cv,
680			    &sensor->ksensor_mutex);
681			if (cv == 0) {
682				sensor->ksensor_nwaiters--;
683				cv_broadcast(&sensor->ksensor_cv);
684				mutex_exit(&sensor->ksensor_mutex);
685				*outp = NULL;
686				return (EINTR);
687			}
688		}
689		sensor->ksensor_nwaiters--;
690		cv_broadcast(&sensor->ksensor_cv);
691		mutex_exit(&sensor->ksensor_mutex);
692		goto restart;
693	}
694
695	/*
696	 * We have obtained ownership of the sensor. At this point, we should
697	 * check to see if it's valid or not.
698	 */
699	sensor->ksensor_flags |= KSENSOR_F_BUSY;
700	pdip = ddi_get_parent(sensor->ksensor_ksdip->ksdip_dip);
701	mutex_exit(&sensor->ksensor_mutex);
702	mutex_exit(&ksensor_g_mutex);
703
704	/*
705	 * Grab a reference on the device node to ensure that it won't go away.
706	 */
707	ndi_devi_enter(pdip, &circ);
708	e_ddi_hold_devi(sensor->ksensor_ksdip->ksdip_dip);
709	ndi_devi_exit(pdip, circ);
710
711	/*
712	 * Now that we have an NDI hold, check if it's valid or not. It may have
713	 * become invalid while we were waiting due to a race.
714	 */
715	mutex_enter(&ksensor_g_mutex);
716	if ((sensor->ksensor_ksdip->ksdip_flags & KSENSOR_DIP_F_REMOVED) != 0) {
717		mutex_exit(&ksensor_g_mutex);
718		ksensor_release(sensor);
719		return (ESTALE);
720	}
721
722	mutex_enter(&sensor->ksensor_mutex);
723	if ((sensor->ksensor_flags & KSENSOR_F_VALID) == 0) {
724		mutex_exit(&sensor->ksensor_mutex);
725		mutex_exit(&ksensor_g_mutex);
726		(void) ndi_devi_config(pdip, NDI_NO_EVENT);
727		mutex_enter(&ksensor_g_mutex);
728		mutex_enter(&sensor->ksensor_mutex);
729
730		/*
731		 * If we attempted to reattach it and it isn't now valid, fail
732		 * this request.
733		 */
734		if ((sensor->ksensor_ksdip->ksdip_flags &
735		    KSENSOR_DIP_F_REMOVED) != 0 ||
736		    (sensor->ksensor_flags & KSENSOR_F_VALID) == 0) {
737			mutex_exit(&sensor->ksensor_mutex);
738			mutex_exit(&ksensor_g_mutex);
739			ksensor_release(sensor);
740			return (ESTALE);
741		}
742	}
743	mutex_exit(&sensor->ksensor_mutex);
744	mutex_exit(&ksensor_g_mutex);
745	*outp = sensor;
746
747	return (0);
748}
749
750int
751ksensor_op_kind(id_t id, sensor_ioctl_kind_t *kind)
752{
753	int ret;
754	ksensor_t *sensor;
755
756	if ((ret = ksensor_hold_by_id(id, &sensor)) != 0) {
757		return (ret);
758	}
759
760	ret = sensor->ksensor_ops->kso_kind(sensor->ksensor_arg, kind);
761	ksensor_release(sensor);
762
763	return (ret);
764}
765
766int
767ksensor_op_scalar(id_t id, sensor_ioctl_scalar_t *scalar)
768{
769	int ret;
770	ksensor_t *sensor;
771
772	if ((ret = ksensor_hold_by_id(id, &sensor)) != 0) {
773		return (ret);
774	}
775
776	ret = sensor->ksensor_ops->kso_scalar(sensor->ksensor_arg, scalar);
777	ksensor_release(sensor);
778
779	return (ret);
780}
781
782void
783ksensor_unregister(dev_info_t *reg_dip)
784{
785	ksensor_t *sensor;
786
787	mutex_enter(&ksensor_g_mutex);
788	if (ksensor_cb_dip != reg_dip) {
789		dev_err(reg_dip, CE_PANIC, "asked to unregister illegal dip");
790	}
791
792	for (sensor = avl_first(&ksensor_avl); sensor != NULL; sensor =
793	    AVL_NEXT(&ksensor_avl, sensor)) {
794		mutex_enter(&sensor->ksensor_mutex);
795		sensor->ksensor_flags &= ~KSENSOR_F_NOTIFIED;
796		mutex_exit(&sensor->ksensor_mutex);
797	}
798
799	ksensor_cb_dip = NULL;
800	ksensor_cb_create = NULL;
801	ksensor_cb_remove = NULL;
802	mutex_exit(&ksensor_g_mutex);
803}
804
805int
806ksensor_register(dev_info_t *reg_dip, ksensor_create_f create,
807    ksensor_remove_f remove)
808{
809	ksensor_t *sensor;
810
811	mutex_enter(&ksensor_g_mutex);
812	if (ksensor_cb_dip != NULL) {
813		dev_err(reg_dip, CE_WARN, "kernel sensors are already "
814		    "registered");
815		mutex_exit(&ksensor_g_mutex);
816		return (EEXIST);
817	}
818
819	ksensor_cb_dip = reg_dip;
820	ksensor_cb_create = create;
821	ksensor_cb_remove = remove;
822
823	for (sensor = avl_first(&ksensor_avl); sensor != NULL; sensor =
824	    AVL_NEXT(&ksensor_avl, sensor)) {
825		mutex_enter(&sensor->ksensor_mutex);
826		ASSERT0(sensor->ksensor_flags & KSENSOR_F_NOTIFIED);
827
828		if (ksensor_cb_create(sensor->ksensor_id, sensor->ksensor_class,
829		    sensor->ksensor_name) == 0) {
830			sensor->ksensor_flags |= KSENSOR_F_NOTIFIED;
831		}
832
833		mutex_exit(&sensor->ksensor_mutex);
834	}
835
836	mutex_exit(&ksensor_g_mutex);
837
838	return (0);
839}
840
841int
842ksensor_kind_temperature(void *unused, sensor_ioctl_kind_t *k)
843{
844	k->sik_kind = SENSOR_KIND_TEMPERATURE;
845	return (0);
846}
847
848int
849ksensor_kind_current(void *unused, sensor_ioctl_kind_t *k)
850{
851	k->sik_kind = SENSOR_KIND_CURRENT;
852	return (0);
853}
854
855int
856ksensor_kind_voltage(void *unused, sensor_ioctl_kind_t *k)
857{
858	k->sik_kind = SENSOR_KIND_VOLTAGE;
859	return (0);
860}
861
862void
863ksensor_init(void)
864{
865	mutex_init(&ksensor_g_mutex, NULL, MUTEX_DRIVER, NULL);
866	list_create(&ksensor_dips, sizeof (ksensor_dip_t),
867	    offsetof(ksensor_dip_t, ksdip_link));
868	ksensor_ids = id_space_create("ksensor", 1, L_MAXMIN32);
869	avl_create(&ksensor_avl, ksensor_avl_compare, sizeof (ksensor_t),
870	    offsetof(ksensor_t, ksensor_id_avl));
871}
872