1 //==========================================================================
3 // sys/kern/kern_subr.c
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
10 // -------------------------------------------
12 // Portions of this software may have been derived from OpenBSD or other sources,
13 // and are covered by the appropriate copyright disclaimers included herein.
15 // -------------------------------------------
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
22 // Contributors: gthomas
28 //####DESCRIPTIONEND####
30 //==========================================================================
33 /* $OpenBSD: kern_subr.c,v 1.10 1999/11/07 17:39:14 provos Exp $ */
34 /* $NetBSD: kern_subr.c,v 1.15 1996/04/09 17:21:56 ragge Exp $ */
37 * Copyright (c) 1982, 1986, 1991, 1993
38 * The Regents of the University of California. All rights reserved.
39 * (c) UNIX System Laboratories, Inc.
40 * All or some portions of this file are derived from material licensed
41 * to the University of California by American Telephone and Telegraph
42 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
43 * the permission of UNIX System Laboratories, Inc.
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 * must display the following acknowledgement:
55 * This product includes software developed by the University of
56 * California, Berkeley and its contributors.
57 * 4. Neither the name of the University nor the names of its contributors
58 * may be used to endorse or promote products derived from this software
59 * without specific prior written permission.
61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
76 #include <sys/param.h>
78 #include <sys/systm.h>
81 #include <sys/malloc.h>
82 #include <sys/queue.h>
88 register struct uio *uio;
90 register struct iovec *iov;
95 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
96 panic("uiomove: mode");
97 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)
98 panic("uiomove proc");
100 while (n > 0 && uio->uio_resid) {
110 switch (uio->uio_segflg) {
113 if (uio->uio_rw == UIO_READ)
114 error = copyout(cp, iov->iov_base, cnt);
116 error = copyin(iov->iov_base, cp, cnt);
123 if (uio->uio_rw == UIO_READ)
124 error = kcopy(cp, iov->iov_base, cnt);
126 error = kcopy(iov->iov_base, cp, cnt);
130 if (uio->uio_rw == UIO_READ)
131 bcopy((caddr_t)cp, iov->iov_base, cnt);
133 bcopy(iov->iov_base, (caddr_t)cp, cnt);
137 iov->iov_base = (char *)iov->iov_base + cnt;
139 uio->uio_resid -= cnt;
140 uio->uio_offset += cnt;
149 * Give next character to user as result of read.
154 register struct uio *uio;
156 register struct iovec *iov;
158 if (uio->uio_resid == 0)
160 panic("ureadc: zero resid");
165 if (uio->uio_iovcnt <= 0)
167 panic("ureadc: non-positive iovcnt");
172 if (iov->iov_len <= 0) {
177 switch (uio->uio_segflg) {
180 if (subyte(iov->iov_base, c) < 0)
185 *(char *)iov->iov_base = c;
197 * General routine to allocate a hash table.
201 hashinit(int elements, int type, int flags, u_long *hashmask)
204 hashinit(elements, type, flags, hashmask)
205 int elements, type, flags;
210 LIST_HEAD(generic, generic) *hashtbl;
214 panic("hashinit: bad cnt");
215 for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
218 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, flags);
219 for (i = 0; i < hashsize; i++)
220 LIST_INIT(&hashtbl[i]);
221 *hashmask = hashsize - 1;
227 * "Shutdown hook" types, functions, and variables.
230 struct shutdownhook_desc {
231 LIST_ENTRY(shutdownhook_desc) sfd_list;
232 void (*sfd_fn) __P((void *));
236 LIST_HEAD(, shutdownhook_desc) shutdownhook_list;
238 int shutdownhooks_done;
241 shutdownhook_establish(fn, arg)
242 void (*fn) __P((void *));
245 struct shutdownhook_desc *ndp;
247 ndp = (struct shutdownhook_desc *)
248 malloc(sizeof (*ndp), M_DEVBUF, M_NOWAIT);
254 LIST_INSERT_HEAD(&shutdownhook_list, ndp, sfd_list);
260 shutdownhook_disestablish(vhook)
264 struct shutdownhook_desc *dp;
266 for (dp = shutdownhook_list.lh_first; dp != NULL;
267 dp = dp->sfd_list.le_next)
271 panic("shutdownhook_disestablish: hook not established");
274 LIST_REMOVE((struct shutdownhook_desc *)vhook, sfd_list);
278 * Run shutdown hooks. Should be invoked immediately before the
279 * system is halted or rebooted, i.e. after file systems unmounted,
280 * after crash dump done, etc.
285 struct shutdownhook_desc *dp;
287 if (shutdownhooks_done)
290 for (dp = shutdownhook_list.lh_first; dp != NULL; dp =
291 dp->sfd_list.le_next)
292 (*dp->sfd_fn)(dp->sfd_arg);
296 * "Power hook" types, functions, and variables.
299 struct powerhook_desc {
300 LIST_ENTRY(powerhook_desc) sfd_list;
301 void (*sfd_fn) __P((int, void *));
305 LIST_HEAD(, powerhook_desc) powerhook_list;
308 powerhook_establish(fn, arg)
309 void (*fn) __P((int, void *));
312 struct powerhook_desc *ndp;
314 ndp = (struct powerhook_desc *)
315 malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT);
321 LIST_INSERT_HEAD(&powerhook_list, ndp, sfd_list);
327 powerhook_disestablish(vhook)
331 struct powerhook_desc *dp;
333 for (dp = powerhook_list.lh_first; dp != NULL;
334 dp = dp->sfd_list.le_next)
338 panic("powerhook_disestablish: hook not established");
341 LIST_REMOVE((struct powerhook_desc *)vhook, sfd_list);
342 free(vhook, M_DEVBUF);
352 struct powerhook_desc *dp;
354 for (dp = LIST_FIRST(&powerhook_list);
356 dp = LIST_NEXT(dp, sfd_list)) {
357 (*dp->sfd_fn)(why, dp->sfd_arg);