1/* $NetBSD: subr_device.c,v 1.3 2015/03/09 15:35:11 pooka Exp $ */
2
3/*
4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: subr_device.c,v 1.3 2015/03/09 15:35:11 pooka Exp $");
31
32#include <sys/param.h>
33#include <sys/device.h>
34#include <sys/systm.h>
35
36/* Root device. */
37device_t root_device;
38
39/*
40 * Accessor functions for the device_t type.
41 */
42devclass_t
43device_class(device_t dev)
44{
45
46 return dev->dv_class;
47}
48
49cfdata_t
50device_cfdata(device_t dev)
51{
52
53 return dev->dv_cfdata;
54}
55
56cfdriver_t
57device_cfdriver(device_t dev)
58{
59
60 return dev->dv_cfdriver;
61}
62
63cfattach_t
64device_cfattach(device_t dev)
65{
66
67 return dev->dv_cfattach;
68}
69
70int
71device_unit(device_t dev)
72{
73
74 return dev->dv_unit;
75}
76
77const char *
78device_xname(device_t dev)
79{
80
81 return dev->dv_xname;
82}
83
84device_t
85device_parent(device_t dev)
86{
87
88 return dev->dv_parent;
89}
90
91bool
92device_activation(device_t dev, devact_level_t level)
93{
94 int active_flags;
95
96 active_flags = DVF_ACTIVE;
97 switch (level) {
98 case DEVACT_LEVEL_FULL:
99 active_flags |= DVF_CLASS_SUSPENDED;
100 /*FALLTHROUGH*/
101 case DEVACT_LEVEL_DRIVER:
102 active_flags |= DVF_DRIVER_SUSPENDED;
103 /*FALLTHROUGH*/
104 case DEVACT_LEVEL_BUS:
105 active_flags |= DVF_BUS_SUSPENDED;
106 break;
107 }
108
109 return (dev->dv_flags & active_flags) == DVF_ACTIVE;
110}
111
112bool
113device_is_active(device_t dev)
114{
115 int active_flags;
116
117 active_flags = DVF_ACTIVE;
118 active_flags |= DVF_CLASS_SUSPENDED;
119 active_flags |= DVF_DRIVER_SUSPENDED;
120 active_flags |= DVF_BUS_SUSPENDED;
121
122 return (dev->dv_flags & active_flags) == DVF_ACTIVE;
123}
124
125bool
126device_is_enabled(device_t dev)
127{
128 return (dev->dv_flags & DVF_ACTIVE) == DVF_ACTIVE;
129}
130
131bool
132device_has_power(device_t dev)
133{
134 int active_flags;
135
136 active_flags = DVF_ACTIVE | DVF_BUS_SUSPENDED;
137
138 return (dev->dv_flags & active_flags) == DVF_ACTIVE;
139}
140
141int
142device_locator(device_t dev, u_int locnum)
143{
144
145 KASSERT(dev->dv_locators != NULL);
146 return dev->dv_locators[locnum];
147}
148
149void *
150device_private(device_t dev)
151{
152
153 /*
154 * The reason why device_private(NULL) is allowed is to simplify the
155 * work of a lot of userspace request handlers (i.e., c/bdev
156 * handlers) which grab cfdriver_t->cd_units[n].
157 * It avoids having them test for it to be NULL and only then calling
158 * device_private.
159 */
160 return dev == NULL ? NULL : dev->dv_private;
161}
162
163prop_dictionary_t
164device_properties(device_t dev)
165{
166
167 return dev->dv_properties;
168}
169
170/*
171 * device_is_a:
172 *
173 * Returns true if the device is an instance of the specified
174 * driver.
175 */
176bool
177device_is_a(device_t dev, const char *dname)
178{
179
180 return strcmp(dev->dv_cfdriver->cd_name, dname) == 0;
181}
182