subr_device.c revision 1.1.2.1 1 1.1.2.1 cube /* $NetBSD: subr_device.c,v 1.1.2.1 2007/12/16 18:54:06 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.1 cube __KERNEL_RCSID(0, "$NetBSD: subr_device.c,v 1.1.2.1 2007/12/16 18:54:06 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.1 cube return (dev->dv_private);
198 1.1.2.1 cube }
199 1.1.2.1 cube
200 1.1.2.1 cube prop_dictionary_t
201 1.1.2.1 cube device_properties(device_t dev)
202 1.1.2.1 cube {
203 1.1.2.1 cube
204 1.1.2.1 cube return (dev->dv_properties);
205 1.1.2.1 cube }
206 1.1.2.1 cube
207 1.1.2.1 cube /*
208 1.1.2.1 cube * device_is_a:
209 1.1.2.1 cube *
210 1.1.2.1 cube * Returns true if the device is an instance of the specified
211 1.1.2.1 cube * driver.
212 1.1.2.1 cube */
213 1.1.2.1 cube bool
214 1.1.2.1 cube device_is_a(device_t dev, const char *dname)
215 1.1.2.1 cube {
216 1.1.2.1 cube
217 1.1.2.1 cube return (strcmp(dev->dv_cfdriver->cd_name, dname) == 0);
218 1.1.2.1 cube }
219 1.1.2.1 cube
220 1.1.2.1 cube /*
221 1.1.2.1 cube * Power management related functions.
222 1.1.2.1 cube */
223 1.1.2.1 cube
224 1.1.2.1 cube bool
225 1.1.2.1 cube device_pmf_is_registered(device_t dev)
226 1.1.2.1 cube {
227 1.1.2.1 cube return (dev->dv_flags & DVF_POWER_HANDLERS) != 0;
228 1.1.2.1 cube }
229 1.1.2.1 cube
230 1.1.2.1 cube bool
231 1.1.2.1 cube device_pmf_driver_suspend(device_t dev)
232 1.1.2.1 cube {
233 1.1.2.1 cube if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
234 1.1.2.1 cube return true;
235 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
236 1.1.2.1 cube return false;
237 1.1.2.1 cube if (*dev->dv_driver_suspend != NULL &&
238 1.1.2.1 cube !(*dev->dv_driver_suspend)(dev))
239 1.1.2.1 cube return false;
240 1.1.2.1 cube
241 1.1.2.1 cube dev->dv_flags |= DVF_DRIVER_SUSPENDED;
242 1.1.2.1 cube return true;
243 1.1.2.1 cube }
244 1.1.2.1 cube
245 1.1.2.1 cube bool
246 1.1.2.1 cube device_pmf_driver_resume(device_t dev)
247 1.1.2.1 cube {
248 1.1.2.1 cube if ((dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
249 1.1.2.1 cube return true;
250 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
251 1.1.2.1 cube return false;
252 1.1.2.1 cube if (*dev->dv_driver_resume != NULL &&
253 1.1.2.1 cube !(*dev->dv_driver_resume)(dev))
254 1.1.2.1 cube return false;
255 1.1.2.1 cube
256 1.1.2.1 cube dev->dv_flags &= ~DVF_DRIVER_SUSPENDED;
257 1.1.2.1 cube return true;
258 1.1.2.1 cube }
259 1.1.2.1 cube
260 1.1.2.1 cube void
261 1.1.2.1 cube device_pmf_driver_register(device_t dev,
262 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t))
263 1.1.2.1 cube {
264 1.1.2.1 cube dev->dv_driver_suspend = suspend;
265 1.1.2.1 cube dev->dv_driver_resume = resume;
266 1.1.2.1 cube dev->dv_flags |= DVF_POWER_HANDLERS;
267 1.1.2.1 cube }
268 1.1.2.1 cube
269 1.1.2.1 cube void
270 1.1.2.1 cube device_pmf_driver_deregister(device_t dev)
271 1.1.2.1 cube {
272 1.1.2.1 cube dev->dv_driver_suspend = NULL;
273 1.1.2.1 cube dev->dv_driver_resume = NULL;
274 1.1.2.1 cube dev->dv_flags &= ~DVF_POWER_HANDLERS;
275 1.1.2.1 cube }
276 1.1.2.1 cube
277 1.1.2.1 cube bool
278 1.1.2.1 cube device_pmf_driver_child_register(device_t dev)
279 1.1.2.1 cube {
280 1.1.2.1 cube device_t parent = device_parent(dev);
281 1.1.2.1 cube
282 1.1.2.1 cube if (parent == NULL || parent->dv_driver_child_register == NULL)
283 1.1.2.1 cube return true;
284 1.1.2.1 cube return (*parent->dv_driver_child_register)(dev);
285 1.1.2.1 cube }
286 1.1.2.1 cube
287 1.1.2.1 cube void
288 1.1.2.1 cube device_pmf_driver_set_child_register(device_t dev,
289 1.1.2.1 cube bool (*child_register)(device_t))
290 1.1.2.1 cube {
291 1.1.2.1 cube dev->dv_driver_child_register = child_register;
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_bus_private(device_t dev)
296 1.1.2.1 cube {
297 1.1.2.1 cube return dev->dv_bus_private;
298 1.1.2.1 cube }
299 1.1.2.1 cube
300 1.1.2.1 cube bool
301 1.1.2.1 cube device_pmf_bus_suspend(device_t dev)
302 1.1.2.1 cube {
303 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0)
304 1.1.2.1 cube return true;
305 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0 ||
306 1.1.2.1 cube (dev->dv_flags & DVF_DRIVER_SUSPENDED) == 0)
307 1.1.2.1 cube return false;
308 1.1.2.1 cube if (*dev->dv_bus_suspend != NULL &&
309 1.1.2.1 cube !(*dev->dv_bus_suspend)(dev))
310 1.1.2.1 cube return false;
311 1.1.2.1 cube
312 1.1.2.1 cube dev->dv_flags |= DVF_BUS_SUSPENDED;
313 1.1.2.1 cube return true;
314 1.1.2.1 cube }
315 1.1.2.1 cube
316 1.1.2.1 cube bool
317 1.1.2.1 cube device_pmf_bus_resume(device_t dev)
318 1.1.2.1 cube {
319 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) == 0)
320 1.1.2.1 cube return true;
321 1.1.2.1 cube if (*dev->dv_bus_resume != NULL &&
322 1.1.2.1 cube !(*dev->dv_bus_resume)(dev))
323 1.1.2.1 cube return false;
324 1.1.2.1 cube
325 1.1.2.1 cube dev->dv_flags &= ~DVF_BUS_SUSPENDED;
326 1.1.2.1 cube return true;
327 1.1.2.1 cube }
328 1.1.2.1 cube
329 1.1.2.1 cube void
330 1.1.2.1 cube device_pmf_bus_register(device_t dev, void *priv,
331 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t),
332 1.1.2.1 cube void (*deregister)(device_t))
333 1.1.2.1 cube {
334 1.1.2.1 cube dev->dv_bus_private = priv;
335 1.1.2.1 cube dev->dv_bus_resume = resume;
336 1.1.2.1 cube dev->dv_bus_suspend = suspend;
337 1.1.2.1 cube dev->dv_bus_deregister = deregister;
338 1.1.2.1 cube }
339 1.1.2.1 cube
340 1.1.2.1 cube void
341 1.1.2.1 cube device_pmf_bus_deregister(device_t dev)
342 1.1.2.1 cube {
343 1.1.2.1 cube if (dev->dv_bus_deregister == NULL)
344 1.1.2.1 cube return;
345 1.1.2.1 cube (*dev->dv_bus_deregister)(dev);
346 1.1.2.1 cube dev->dv_bus_private = NULL;
347 1.1.2.1 cube dev->dv_bus_suspend = NULL;
348 1.1.2.1 cube dev->dv_bus_resume = NULL;
349 1.1.2.1 cube dev->dv_bus_deregister = NULL;
350 1.1.2.1 cube }
351 1.1.2.1 cube
352 1.1.2.1 cube void *
353 1.1.2.1 cube device_pmf_class_private(device_t dev)
354 1.1.2.1 cube {
355 1.1.2.1 cube return dev->dv_class_private;
356 1.1.2.1 cube }
357 1.1.2.1 cube
358 1.1.2.1 cube bool
359 1.1.2.1 cube device_pmf_class_suspend(device_t dev)
360 1.1.2.1 cube {
361 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) != 0)
362 1.1.2.1 cube return true;
363 1.1.2.1 cube if (*dev->dv_class_suspend != NULL &&
364 1.1.2.1 cube !(*dev->dv_class_suspend)(dev))
365 1.1.2.1 cube return false;
366 1.1.2.1 cube
367 1.1.2.1 cube dev->dv_flags |= DVF_CLASS_SUSPENDED;
368 1.1.2.1 cube return true;
369 1.1.2.1 cube }
370 1.1.2.1 cube
371 1.1.2.1 cube bool
372 1.1.2.1 cube device_pmf_class_resume(device_t dev)
373 1.1.2.1 cube {
374 1.1.2.1 cube if ((dev->dv_flags & DVF_CLASS_SUSPENDED) == 0)
375 1.1.2.1 cube return true;
376 1.1.2.1 cube if ((dev->dv_flags & DVF_BUS_SUSPENDED) != 0 ||
377 1.1.2.1 cube (dev->dv_flags & DVF_DRIVER_SUSPENDED) != 0)
378 1.1.2.1 cube return false;
379 1.1.2.1 cube if (*dev->dv_class_resume != NULL &&
380 1.1.2.1 cube !(*dev->dv_class_resume)(dev))
381 1.1.2.1 cube return false;
382 1.1.2.1 cube
383 1.1.2.1 cube dev->dv_flags &= ~DVF_CLASS_SUSPENDED;
384 1.1.2.1 cube return true;
385 1.1.2.1 cube }
386 1.1.2.1 cube
387 1.1.2.1 cube void
388 1.1.2.1 cube device_pmf_class_register(device_t dev, void *priv,
389 1.1.2.1 cube bool (*suspend)(device_t), bool (*resume)(device_t),
390 1.1.2.1 cube void (*deregister)(device_t))
391 1.1.2.1 cube {
392 1.1.2.1 cube dev->dv_class_private = priv;
393 1.1.2.1 cube dev->dv_class_suspend = suspend;
394 1.1.2.1 cube dev->dv_class_resume = resume;
395 1.1.2.1 cube dev->dv_class_deregister = deregister;
396 1.1.2.1 cube }
397 1.1.2.1 cube
398 1.1.2.1 cube void
399 1.1.2.1 cube device_pmf_class_deregister(device_t dev)
400 1.1.2.1 cube {
401 1.1.2.1 cube if (dev->dv_class_deregister == NULL)
402 1.1.2.1 cube return;
403 1.1.2.1 cube (*dev->dv_class_deregister)(dev);
404 1.1.2.1 cube dev->dv_class_private = NULL;
405 1.1.2.1 cube dev->dv_class_suspend = NULL;
406 1.1.2.1 cube dev->dv_class_resume = NULL;
407 1.1.2.1 cube dev->dv_class_deregister = NULL;
408 1.1.2.1 cube }
409 1.1.2.1 cube
410 1.1.2.1 cube bool
411 1.1.2.1 cube device_active(device_t dev, devactive_t type)
412 1.1.2.1 cube {
413 1.1.2.1 cube size_t i;
414 1.1.2.1 cube
415 1.1.2.1 cube if (dev->dv_activity_count == 0)
416 1.1.2.1 cube return false;
417 1.1.2.1 cube
418 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i)
419 1.1.2.1 cube (*dev->dv_activity_handlers[i])(dev, type);
420 1.1.2.1 cube
421 1.1.2.1 cube return true;
422 1.1.2.1 cube }
423 1.1.2.1 cube
424 1.1.2.1 cube bool
425 1.1.2.1 cube device_active_register(device_t dev, void (*handler)(device_t, devactive_t))
426 1.1.2.1 cube {
427 1.1.2.1 cube void (**new_handlers)(device_t, devactive_t);
428 1.1.2.1 cube void (**old_handlers)(device_t, devactive_t);
429 1.1.2.1 cube size_t i, new_size;
430 1.1.2.1 cube int s;
431 1.1.2.1 cube
432 1.1.2.1 cube old_handlers = dev->dv_activity_handlers;
433 1.1.2.1 cube
434 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i) {
435 1.1.2.1 cube if (old_handlers[i] == handler)
436 1.1.2.1 cube panic("Double registering of idle handlers");
437 1.1.2.1 cube }
438 1.1.2.1 cube
439 1.1.2.1 cube new_size = dev->dv_activity_count + 1;
440 1.1.2.1 cube new_handlers = malloc(sizeof(void *) * new_size, M_DEVBUF, M_WAITOK);
441 1.1.2.1 cube
442 1.1.2.1 cube memcpy(new_handlers, old_handlers,
443 1.1.2.1 cube sizeof(void *) * dev->dv_activity_count);
444 1.1.2.1 cube new_handlers[new_size - 1] = handler;
445 1.1.2.1 cube
446 1.1.2.1 cube s = splhigh();
447 1.1.2.1 cube dev->dv_activity_count = new_size;
448 1.1.2.1 cube dev->dv_activity_handlers = new_handlers;
449 1.1.2.1 cube splx(s);
450 1.1.2.1 cube
451 1.1.2.1 cube if (old_handlers != NULL)
452 1.1.2.1 cube free(old_handlers, M_DEVBUF);
453 1.1.2.1 cube
454 1.1.2.1 cube return true;
455 1.1.2.1 cube }
456 1.1.2.1 cube
457 1.1.2.1 cube void
458 1.1.2.1 cube device_active_deregister(device_t dev, void (*handler)(device_t, devactive_t))
459 1.1.2.1 cube {
460 1.1.2.1 cube void (**new_handlers)(device_t, devactive_t);
461 1.1.2.1 cube void (**old_handlers)(device_t, devactive_t);
462 1.1.2.1 cube size_t i, new_size;
463 1.1.2.1 cube int s;
464 1.1.2.1 cube
465 1.1.2.1 cube old_handlers = dev->dv_activity_handlers;
466 1.1.2.1 cube
467 1.1.2.1 cube for (i = 0; i < dev->dv_activity_count; ++i) {
468 1.1.2.1 cube if (old_handlers[i] == handler)
469 1.1.2.1 cube break;
470 1.1.2.1 cube }
471 1.1.2.1 cube
472 1.1.2.1 cube if (i == dev->dv_activity_count)
473 1.1.2.1 cube return; /* XXX panic? */
474 1.1.2.1 cube
475 1.1.2.1 cube new_size = dev->dv_activity_count - 1;
476 1.1.2.1 cube
477 1.1.2.1 cube if (new_size == 0) {
478 1.1.2.1 cube new_handlers = NULL;
479 1.1.2.1 cube } else {
480 1.1.2.1 cube new_handlers = malloc(sizeof(void *) * new_size, M_DEVBUF,
481 1.1.2.1 cube M_WAITOK);
482 1.1.2.1 cube memcpy(new_handlers, old_handlers, sizeof(void *) * i);
483 1.1.2.1 cube memcpy(new_handlers + i, old_handlers + i + 1,
484 1.1.2.1 cube sizeof(void *) * (new_size - i));
485 1.1.2.1 cube }
486 1.1.2.1 cube
487 1.1.2.1 cube s = splhigh();
488 1.1.2.1 cube dev->dv_activity_count = new_size;
489 1.1.2.1 cube dev->dv_activity_handlers = new_handlers;
490 1.1.2.1 cube splx(s);
491 1.1.2.1 cube
492 1.1.2.1 cube free(old_handlers, M_DEVBUF);
493 1.1.2.1 cube }
494