subr_device.c revision 1.1.2.2 1 1.1.2.2 cube /* $NetBSD: subr_device.c,v 1.1.2.2 2008/01/30 22:08:51 cube Exp $ */
2 1.1.2.1 cube
3 1.1.2.1 cube /*
4 1.1.2.1 cube * Copyright (c) 1996, 2000 Christopher G. Demetriou
5 1.1.2.1 cube * All rights reserved.
6 1.1.2.1 cube *
7 1.1.2.1 cube * Redistribution and use in source and binary forms, with or without
8 1.1.2.1 cube * modification, are permitted provided that the following conditions
9 1.1.2.1 cube * are met:
10 1.1.2.1 cube * 1. Redistributions of source code must retain the above copyright
11 1.1.2.1 cube * notice, this list of conditions and the following disclaimer.
12 1.1.2.1 cube * 2. Redistributions in binary form must reproduce the above copyright
13 1.1.2.1 cube * notice, this list of conditions and the following disclaimer in the
14 1.1.2.1 cube * documentation and/or other materials provided with the distribution.
15 1.1.2.1 cube * 3. All advertising materials mentioning features or use of this software
16 1.1.2.1 cube * must display the following acknowledgement:
17 1.1.2.1 cube * This product includes software developed for the
18 1.1.2.1 cube * NetBSD Project. See http://www.NetBSD.org/ for
19 1.1.2.1 cube * information about NetBSD.
20 1.1.2.1 cube * 4. The name of the author may not be used to endorse or promote products
21 1.1.2.1 cube * derived from this software without specific prior written permission.
22 1.1.2.1 cube *
23 1.1.2.1 cube * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1.2.1 cube * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1.2.1 cube * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1.2.1 cube * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1.2.1 cube * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1.2.1 cube * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1.2.1 cube * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1.2.1 cube * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1.2.1 cube * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1.2.1 cube * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1.2.1 cube *
34 1.1.2.1 cube * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
35 1.1.2.1 cube */
36 1.1.2.1 cube
37 1.1.2.1 cube /*
38 1.1.2.1 cube * Copyright (c) 1992, 1993
39 1.1.2.1 cube * The Regents of the University of California. All rights reserved.
40 1.1.2.1 cube *
41 1.1.2.1 cube * This software was developed by the Computer Systems Engineering group
42 1.1.2.1 cube * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
43 1.1.2.1 cube * contributed to Berkeley.
44 1.1.2.1 cube *
45 1.1.2.1 cube * All advertising materials mentioning features or use of this software
46 1.1.2.1 cube * must display the following acknowledgement:
47 1.1.2.1 cube * This product includes software developed by the University of
48 1.1.2.1 cube * California, Lawrence Berkeley Laboratories.
49 1.1.2.1 cube *
50 1.1.2.1 cube * Redistribution and use in source and binary forms, with or without
51 1.1.2.1 cube * modification, are permitted provided that the following conditions
52 1.1.2.1 cube * are met:
53 1.1.2.1 cube * 1. Redistributions of source code must retain the above copyright
54 1.1.2.1 cube * notice, this list of conditions and the following disclaimer.
55 1.1.2.1 cube * 2. Redistributions in binary form must reproduce the above copyright
56 1.1.2.1 cube * notice, this list of conditions and the following disclaimer in the
57 1.1.2.1 cube * documentation and/or other materials provided with the distribution.
58 1.1.2.1 cube * 3. Neither the name of the University nor the names of its contributors
59 1.1.2.1 cube * may be used to endorse or promote products derived from this software
60 1.1.2.1 cube * without specific prior written permission.
61 1.1.2.1 cube *
62 1.1.2.1 cube * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 1.1.2.1 cube * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 1.1.2.1 cube * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 1.1.2.1 cube * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 1.1.2.1 cube * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 1.1.2.1 cube * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 1.1.2.1 cube * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 1.1.2.1 cube * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 1.1.2.1 cube * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 1.1.2.1 cube * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 1.1.2.1 cube * SUCH DAMAGE.
73 1.1.2.1 cube *
74 1.1.2.1 cube * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp (LBL)
75 1.1.2.1 cube *
76 1.1.2.1 cube * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94
77 1.1.2.1 cube */
78 1.1.2.1 cube
79 1.1.2.1 cube #include <sys/cdefs.h>
80 1.1.2.2 cube __KERNEL_RCSID(0, "$NetBSD: subr_device.c,v 1.1.2.2 2008/01/30 22:08:51 cube Exp $");
81 1.1.2.1 cube
82 1.1.2.1 cube #include <sys/param.h>
83 1.1.2.1 cube #include <sys/device.h>
84 1.1.2.1 cube #include <sys/malloc.h>
85 1.1.2.1 cube
86 1.1.2.1 cube /* list of all devices */
87 1.1.2.1 cube struct devicelist alldevs = TAILQ_HEAD_INITIALIZER(alldevs);
88 1.1.2.1 cube
89 1.1.2.1 cube /*
90 1.1.2.1 cube * device_lookup:
91 1.1.2.1 cube *
92 1.1.2.1 cube * Look up a device instance for a given driver.
93 1.1.2.1 cube */
94 1.1.2.1 cube void *
95 1.1.2.1 cube device_lookup(cfdriver_t cd, int unit)
96 1.1.2.1 cube {
97 1.1.2.1 cube
98 1.1.2.1 cube if (unit < 0 || unit >= cd->cd_ndevs)
99 1.1.2.1 cube return (NULL);
100 1.1.2.1 cube
101 1.1.2.1 cube return (cd->cd_devs[unit]);
102 1.1.2.1 cube }
103 1.1.2.1 cube
104 1.1.2.1 cube /*
105 1.1.2.1 cube * Accessor functions for the device_t type.
106 1.1.2.1 cube */
107 1.1.2.1 cube devclass_t
108 1.1.2.1 cube device_class(device_t dev)
109 1.1.2.1 cube {
110 1.1.2.1 cube
111 1.1.2.1 cube return (dev->dv_class);
112 1.1.2.1 cube }
113 1.1.2.1 cube
114 1.1.2.1 cube cfdata_t
115 1.1.2.1 cube device_cfdata(device_t dev)
116 1.1.2.1 cube {
117 1.1.2.1 cube
118 1.1.2.1 cube return (dev->dv_cfdata);
119 1.1.2.1 cube }
120 1.1.2.1 cube
121 1.1.2.1 cube cfdriver_t
122 1.1.2.1 cube device_cfdriver(device_t dev)
123 1.1.2.1 cube {
124 1.1.2.1 cube
125 1.1.2.1 cube return (dev->dv_cfdriver);
126 1.1.2.1 cube }
127 1.1.2.1 cube
128 1.1.2.1 cube cfattach_t
129 1.1.2.1 cube device_cfattach(device_t dev)
130 1.1.2.1 cube {
131 1.1.2.1 cube
132 1.1.2.1 cube return (dev->dv_cfattach);
133 1.1.2.1 cube }
134 1.1.2.1 cube
135 1.1.2.1 cube int
136 1.1.2.1 cube device_unit(device_t dev)
137 1.1.2.1 cube {
138 1.1.2.1 cube
139 1.1.2.1 cube return (dev->dv_unit);
140 1.1.2.1 cube }
141 1.1.2.1 cube
142 1.1.2.1 cube const char *
143 1.1.2.1 cube device_xname(device_t dev)
144 1.1.2.1 cube {
145 1.1.2.1 cube
146 1.1.2.1 cube return (dev->dv_xname);
147 1.1.2.1 cube }
148 1.1.2.1 cube
149 1.1.2.1 cube device_t
150 1.1.2.1 cube device_parent(device_t dev)
151 1.1.2.1 cube {
152 1.1.2.1 cube
153 1.1.2.1 cube return (dev->dv_parent);
154 1.1.2.1 cube }
155 1.1.2.1 cube
156 1.1.2.1 cube bool
157 1.1.2.1 cube device_is_active(device_t dev)
158 1.1.2.1 cube {
159 1.1.2.1 cube int active_flags;
160 1.1.2.1 cube
161 1.1.2.1 cube active_flags = DVF_ACTIVE;
162 1.1.2.1 cube active_flags |= DVF_CLASS_SUSPENDED;
163 1.1.2.1 cube active_flags |= DVF_DRIVER_SUSPENDED;
164 1.1.2.1 cube active_flags |= DVF_BUS_SUSPENDED;
165 1.1.2.1 cube
166 1.1.2.1 cube return ((dev->dv_flags & active_flags) == DVF_ACTIVE);
167 1.1.2.1 cube }
168 1.1.2.1 cube
169 1.1.2.1 cube bool
170 1.1.2.1 cube device_is_enabled(device_t dev)
171 1.1.2.1 cube {
172 1.1.2.1 cube return (dev->dv_flags & DVF_ACTIVE) == DVF_ACTIVE;
173 1.1.2.1 cube }
174 1.1.2.1 cube
175 1.1.2.1 cube bool
176 1.1.2.1 cube device_has_power(device_t dev)
177 1.1.2.1 cube {
178 1.1.2.1 cube int active_flags;
179 1.1.2.1 cube
180 1.1.2.1 cube active_flags = DVF_ACTIVE | DVF_BUS_SUSPENDED;
181 1.1.2.1 cube
182 1.1.2.1 cube return ((dev->dv_flags & active_flags) == DVF_ACTIVE);
183 1.1.2.1 cube }
184 1.1.2.1 cube
185 1.1.2.1 cube int
186 1.1.2.1 cube device_locator(device_t dev, u_int locnum)
187 1.1.2.1 cube {
188 1.1.2.1 cube
189 1.1.2.1 cube KASSERT(dev->dv_locators != NULL);
190 1.1.2.1 cube return (dev->dv_locators[locnum]);
191 1.1.2.1 cube }
192 1.1.2.1 cube
193 1.1.2.1 cube void *
194 1.1.2.1 cube device_private(device_t dev)
195 1.1.2.1 cube {
196 1.1.2.1 cube
197 1.1.2.2 cube /*
198 1.1.2.2 cube * The reason why device_private(NULL) is allowed is to simplify the
199 1.1.2.2 cube * work of a lot of userspace request handlers (i.e., c/bdev
200 1.1.2.2 cube * handlers) which grab cfdriver_t->cd_units[n].
201 1.1.2.2 cube * It avoids having them test for it to be NULL and only then calling
202 1.1.2.2 cube * device_private.
203 1.1.2.2 cube */
204 1.1.2.2 cube return dev == NULL ? NULL : dev->dv_private;
205 1.1.2.1 cube }
206 1.1.2.1 cube
207 1.1.2.1 cube prop_dictionary_t
208 1.1.2.1 cube device_properties(device_t dev)
209 1.1.2.1 cube {
210 1.1.2.1 cube
211 1.1.2.1 cube return (dev->dv_properties);
212 1.1.2.1 cube }
213 1.1.2.1 cube
214 1.1.2.1 cube /*
215 1.1.2.1 cube * device_is_a:
216 1.1.2.1 cube *
217 1.1.2.1 cube * Returns true if the device is an instance of the specified
218 1.1.2.1 cube * driver.
219 1.1.2.1 cube */
220 1.1.2.1 cube bool
221 1.1.2.1 cube device_is_a(device_t dev, const char *dname)
222 1.1.2.1 cube {
223 1.1.2.1 cube
224 1.1.2.1 cube return (strcmp(dev->dv_cfdriver->cd_name, dname) == 0);
225 1.1.2.1 cube }
226 1.1.2.1 cube
227 1.1.2.1 cube /*
228 1.1.2.1 cube * Power management related functions.
229 1.1.2.1 cube */
230 1.1.2.1 cube
231 1.1.2.1 cube bool
232 1.1.2.1 cube device_pmf_is_registered(device_t dev)
233 1.1.2.1 cube {
234 1.1.2.1 cube return (dev->dv_flags & DVF_POWER_HANDLERS) != 0;
235 1.1.2.1 cube }
236 1.1.2.1 cube
237 1.1.2.1 cube bool
238 1.1.2.1 cube device_pmf_driver_suspend(device_t dev)
239 1.1.2.1 cube {
240 1.1.2.1 cube if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
241 1.1.2.1 cube return true;
242 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
243 1.1.2.1 cube return false;
244 1.1.2.1 cube if (*dev->dv_driver_suspend != NULL &&
245 1.1.2.1 cube !(*dev->dv_driver_suspend)(dev))
246 1.1.2.1 cube return false;
247 1.1.2.1 cube
248 1.1.2.1 cube dev->dv_flags |= DVF_DRIVER_SUSPENDED;
249 1.1.2.1 cube return true;
250 1.1.2.1 cube }
251 1.1.2.1 cube
252 1.1.2.1 cube bool
253 1.1.2.1 cube device_pmf_driver_resume(device_t dev)
254 1.1.2.1 cube {
255 1.1.2.1 cube if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
256 1.1.2.1 cube return true;
257 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
258 1.1.2.1 cube return false;
259 1.1.2.1 cube if (*dev->dv_driver_resume != NULL &&
260 1.1.2.1 cube !(*dev->dv_driver_resume)(dev))
261 1.1.2.1 cube return false;
262 1.1.2.1 cube
263 1.1.2.1 cube dev->dv_flags &= ~DVF_DRIVER_SUSPENDED;
264 1.1.2.1 cube return true;
265 1.1.2.1 cube }
266 1.1.2.1 cube
267 1.1.2.1 cube void
268 1.1.2.1 cube device_pmf_driver_register(device_t dev,
269 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t))
270 1.1.2.1 cube {
271 1.1.2.1 cube dev->dv_driver_suspend = suspend;
272 1.1.2.1 cube dev->dv_driver_resume = resume;
273 1.1.2.1 cube dev->dv_flags |= DVF_POWER_HANDLERS;
274 1.1.2.1 cube }
275 1.1.2.1 cube
276 1.1.2.1 cube void
277 1.1.2.1 cube device_pmf_driver_deregister(device_t dev)
278 1.1.2.1 cube {
279 1.1.2.1 cube dev->dv_driver_suspend = NULL;
280 1.1.2.1 cube dev->dv_driver_resume = NULL;
281 1.1.2.1 cube dev->dv_flags &= ~DVF_POWER_HANDLERS;
282 1.1.2.1 cube }
283 1.1.2.1 cube
284 1.1.2.1 cube bool
285 1.1.2.1 cube device_pmf_driver_child_register(device_t dev)
286 1.1.2.1 cube {
287 1.1.2.1 cube device_t parent = device_parent(dev);
288 1.1.2.1 cube
289 1.1.2.1 cube if (parent == NULL || parent->dv_driver_child_register == NULL)
290 1.1.2.1 cube return true;
291 1.1.2.1 cube return (*parent->dv_driver_child_register)(dev);
292 1.1.2.1 cube }
293 1.1.2.1 cube
294 1.1.2.1 cube void
295 1.1.2.1 cube device_pmf_driver_set_child_register(device_t dev,
296 1.1.2.1 cube bool (*child_register)(device_t))
297 1.1.2.1 cube {
298 1.1.2.1 cube dev->dv_driver_child_register = child_register;
299 1.1.2.1 cube }
300 1.1.2.1 cube
301 1.1.2.1 cube void *
302 1.1.2.1 cube device_pmf_bus_private(device_t dev)
303 1.1.2.1 cube {
304 1.1.2.1 cube return dev->dv_bus_private;
305 1.1.2.1 cube }
306 1.1.2.1 cube
307 1.1.2.1 cube bool
308 1.1.2.1 cube device_pmf_bus_suspend(device_t dev)
309 1.1.2.1 cube {
310 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
311 1.1.2.1 cube return true;
312 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0 ||
313 1.1.2.1 cube (dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
314 1.1.2.1 cube return false;
315 1.1.2.1 cube if (*dev->dv_bus_suspend != NULL &&
316 1.1.2.1 cube !(*dev->dv_bus_suspend)(dev))
317 1.1.2.1 cube return false;
318 1.1.2.1 cube
319 1.1.2.1 cube dev->dv_flags |= DVF_BUS_SUSPENDED;
320 1.1.2.1 cube return true;
321 1.1.2.1 cube }
322 1.1.2.1 cube
323 1.1.2.1 cube bool
324 1.1.2.1 cube device_pmf_bus_resume(device_t dev)
325 1.1.2.1 cube {
326 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) == 0)
327 1.1.2.1 cube return true;
328 1.1.2.1 cube if (*dev->dv_bus_resume != NULL &&
329 1.1.2.1 cube !(*dev->dv_bus_resume)(dev))
330 1.1.2.1 cube return false;
331 1.1.2.1 cube
332 1.1.2.1 cube dev->dv_flags &= ~DVF_BUS_SUSPENDED;
333 1.1.2.1 cube return true;
334 1.1.2.1 cube }
335 1.1.2.1 cube
336 1.1.2.1 cube void
337 1.1.2.1 cube device_pmf_bus_register(device_t dev, void *priv,
338 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t),
339 1.1.2.1 cube void (*deregister)(device_t))
340 1.1.2.1 cube {
341 1.1.2.1 cube dev->dv_bus_private = priv;
342 1.1.2.1 cube dev->dv_bus_resume = resume;
343 1.1.2.1 cube dev->dv_bus_suspend = suspend;
344 1.1.2.1 cube dev->dv_bus_deregister = deregister;
345 1.1.2.1 cube }
346 1.1.2.1 cube
347 1.1.2.1 cube void
348 1.1.2.1 cube device_pmf_bus_deregister(device_t dev)
349 1.1.2.1 cube {
350 1.1.2.1 cube if (dev->dv_bus_deregister == NULL)
351 1.1.2.1 cube return;
352 1.1.2.1 cube (*dev->dv_bus_deregister)(dev);
353 1.1.2.1 cube dev->dv_bus_private = NULL;
354 1.1.2.1 cube dev->dv_bus_suspend = NULL;
355 1.1.2.1 cube dev->dv_bus_resume = NULL;
356 1.1.2.1 cube dev->dv_bus_deregister = NULL;
357 1.1.2.1 cube }
358 1.1.2.1 cube
359 1.1.2.1 cube void *
360 1.1.2.1 cube device_pmf_class_private(device_t dev)
361 1.1.2.1 cube {
362 1.1.2.1 cube return dev->dv_class_private;
363 1.1.2.1 cube }
364 1.1.2.1 cube
365 1.1.2.1 cube bool
366 1.1.2.1 cube device_pmf_class_suspend(device_t dev)
367 1.1.2.1 cube {
368 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) != 0)
369 1.1.2.1 cube return true;
370 1.1.2.1 cube if (*dev->dv_class_suspend != NULL &&
371 1.1.2.1 cube !(*dev->dv_class_suspend)(dev))
372 1.1.2.1 cube return false;
373 1.1.2.1 cube
374 1.1.2.1 cube dev->dv_flags |= DVF_CLASS_SUSPENDED;
375 1.1.2.1 cube return true;
376 1.1.2.1 cube }
377 1.1.2.1 cube
378 1.1.2.1 cube bool
379 1.1.2.1 cube device_pmf_class_resume(device_t dev)
380 1.1.2.1 cube {
381 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
382 1.1.2.1 cube return true;
383 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0 ||
384 1.1.2.1 cube (dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
385 1.1.2.1 cube return false;
386 1.1.2.1 cube if (*dev->dv_class_resume != NULL &&
387 1.1.2.1 cube !(*dev->dv_class_resume)(dev))
388 1.1.2.1 cube return false;
389 1.1.2.1 cube
390 1.1.2.1 cube dev->dv_flags &= ~DVF_CLASS_SUSPENDED;
391 1.1.2.1 cube return true;
392 1.1.2.1 cube }
393 1.1.2.1 cube
394 1.1.2.1 cube void
395 1.1.2.1 cube device_pmf_class_register(device_t dev, void *priv,
396 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t),
397 1.1.2.1 cube void (*deregister)(device_t))
398 1.1.2.1 cube {
399 1.1.2.1 cube dev->dv_class_private = priv;
400 1.1.2.1 cube dev->dv_class_suspend = suspend;
401 1.1.2.1 cube dev->dv_class_resume = resume;
402 1.1.2.1 cube dev->dv_class_deregister = deregister;
403 1.1.2.1 cube }
404 1.1.2.1 cube
405 1.1.2.1 cube void
406 1.1.2.1 cube device_pmf_class_deregister(device_t dev)
407 1.1.2.1 cube {
408 1.1.2.1 cube if (dev->dv_class_deregister == NULL)
409 1.1.2.1 cube return;
410 1.1.2.1 cube (*dev->dv_class_deregister)(dev);
411 1.1.2.1 cube dev->dv_class_private = NULL;
412 1.1.2.1 cube dev->dv_class_suspend = NULL;
413 1.1.2.1 cube dev->dv_class_resume = NULL;
414 1.1.2.1 cube dev->dv_class_deregister = NULL;
415 1.1.2.1 cube }
416 1.1.2.1 cube
417 1.1.2.1 cube bool
418 1.1.2.1 cube device_active(device_t dev, devactive_t type)
419 1.1.2.1 cube {
420 1.1.2.1 cube size_t i;
421 1.1.2.1 cube
422 1.1.2.1 cube if (dev->dv_activity_count == 0)
423 1.1.2.1 cube return false;
424 1.1.2.1 cube
425 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i)
426 1.1.2.1 cube (*dev->dv_activity_handlers[i])(dev, type);
427 1.1.2.1 cube
428 1.1.2.1 cube return true;
429 1.1.2.1 cube }
430 1.1.2.1 cube
431 1.1.2.1 cube bool
432 1.1.2.1 cube device_active_register(device_t dev, void (*handler)(device_t, devactive_t))
433 1.1.2.1 cube {
434 1.1.2.1 cube void (**new_handlers)(device_t, devactive_t);
435 1.1.2.1 cube void (**old_handlers)(device_t, devactive_t);
436 1.1.2.1 cube size_t i, new_size;
437 1.1.2.1 cube int s;
438 1.1.2.1 cube
439 1.1.2.1 cube old_handlers = dev->dv_activity_handlers;
440 1.1.2.1 cube
441 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i) {
442 1.1.2.1 cube if (old_handlers[i] == handler)
443 1.1.2.1 cube panic("Double registering of idle handlers");
444 1.1.2.1 cube }
445 1.1.2.1 cube
446 1.1.2.1 cube new_size = dev->dv_activity_count + 1;
447 1.1.2.1 cube new_handlers = malloc(sizeof(void *) * new_size, M_DEVBUF, M_WAITOK);
448 1.1.2.1 cube
449 1.1.2.1 cube memcpy(new_handlers, old_handlers,
450 1.1.2.1 cube sizeof(void *) * dev->dv_activity_count);
451 1.1.2.1 cube new_handlers[new_size - 1] = handler;
452 1.1.2.1 cube
453 1.1.2.1 cube s = splhigh();
454 1.1.2.1 cube dev->dv_activity_count = new_size;
455 1.1.2.1 cube dev->dv_activity_handlers = new_handlers;
456 1.1.2.1 cube splx(s);
457 1.1.2.1 cube
458 1.1.2.1 cube if (old_handlers != NULL)
459 1.1.2.1 cube free(old_handlers, M_DEVBUF);
460 1.1.2.1 cube
461 1.1.2.1 cube return true;
462 1.1.2.1 cube }
463 1.1.2.1 cube
464 1.1.2.1 cube void
465 1.1.2.1 cube device_active_deregister(device_t dev, void (*handler)(device_t, devactive_t))
466 1.1.2.1 cube {
467 1.1.2.1 cube void (**new_handlers)(device_t, devactive_t);
468 1.1.2.1 cube void (**old_handlers)(device_t, devactive_t);
469 1.1.2.1 cube size_t i, new_size;
470 1.1.2.1 cube int s;
471 1.1.2.1 cube
472 1.1.2.1 cube old_handlers = dev->dv_activity_handlers;
473 1.1.2.1 cube
474 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i) {
475 1.1.2.1 cube if (old_handlers[i] == handler)
476 1.1.2.1 cube break;
477 1.1.2.1 cube }
478 1.1.2.1 cube
479 1.1.2.1 cube if (i == dev->dv_activity_count)
480 1.1.2.1 cube return; /* XXX panic? */
481 1.1.2.1 cube
482 1.1.2.1 cube new_size = dev->dv_activity_count - 1;
483 1.1.2.1 cube
484 1.1.2.1 cube if (new_size == 0) {
485 1.1.2.1 cube new_handlers = NULL;
486 1.1.2.1 cube } else {
487 1.1.2.1 cube new_handlers = malloc(sizeof(void *) * new_size, M_DEVBUF,
488 1.1.2.1 cube M_WAITOK);
489 1.1.2.1 cube memcpy(new_handlers, old_handlers, sizeof(void *) * i);
490 1.1.2.1 cube memcpy(new_handlers + i, old_handlers + i + 1,
491 1.1.2.1 cube sizeof(void *) * (new_size - i));
492 1.1.2.1 cube }
493 1.1.2.1 cube
494 1.1.2.1 cube s = splhigh();
495 1.1.2.1 cube dev->dv_activity_count = new_size;
496 1.1.2.1 cube dev->dv_activity_handlers = new_handlers;
497 1.1.2.1 cube splx(s);
498 1.1.2.1 cube
499 1.1.2.1 cube free(old_handlers, M_DEVBUF);
500 1.1.2.1 cube }
501