]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/tcpip/v2_0/src/sys/kern/kern_subr.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / tcpip / v2_0 / src / sys / kern / kern_subr.c
1 //==========================================================================
2 //
3 //      sys/kern/kern_subr.c
4 //
5 //     
6 //
7 //==========================================================================
8 //####BSDCOPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 //
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.
14 //
15 // -------------------------------------------
16 //
17 //####BSDCOPYRIGHTEND####
18 //==========================================================================
19 //#####DESCRIPTIONBEGIN####
20 //
21 // Author(s):    gthomas
22 // Contributors: gthomas
23 // Date:         2000-01-10
24 // Purpose:      
25 // Description:  
26 //              
27 //
28 //####DESCRIPTIONEND####
29 //
30 //==========================================================================
31
32
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 $     */
35
36 /*
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.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
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.
60  *
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
71  * SUCH DAMAGE.
72  *
73  *      @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
74  */
75
76 #include <sys/param.h>
77 #ifndef __ECOS
78 #include <sys/systm.h>
79 #include <sys/proc.h>
80 #endif // __ECOS
81 #include <sys/malloc.h>
82 #include <sys/queue.h>
83
84 int
85 uiomove(cp, n, uio)
86         register caddr_t cp;
87         register int n;
88         register struct uio *uio;
89 {
90         register struct iovec *iov;
91         u_int cnt;
92         int error = 0;
93
94 #ifdef DIAGNOSTIC
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");
99 #endif
100         while (n > 0 && uio->uio_resid) {
101                 iov = uio->uio_iov;
102                 cnt = iov->iov_len;
103                 if (cnt == 0) {
104                         uio->uio_iov++;
105                         uio->uio_iovcnt--;
106                         continue;
107                 }
108                 if (cnt > n)
109                         cnt = n;
110                 switch (uio->uio_segflg) {
111
112                 case UIO_USERSPACE:
113                         if (uio->uio_rw == UIO_READ)
114                                 error = copyout(cp, iov->iov_base, cnt);
115                         else
116                                 error = copyin(iov->iov_base, cp, cnt);
117                         if (error)
118                                 return (error);
119                         break;
120
121                 case UIO_SYSSPACE:
122 #if defined(UVM)
123                         if (uio->uio_rw == UIO_READ)
124                                 error = kcopy(cp, iov->iov_base, cnt);
125                         else
126                                 error = kcopy(iov->iov_base, cp, cnt);
127                         if (error)
128                                 return(error);
129 #else
130                         if (uio->uio_rw == UIO_READ)
131                                 bcopy((caddr_t)cp, iov->iov_base, cnt);
132                         else
133                                 bcopy(iov->iov_base, (caddr_t)cp, cnt);
134                         break;
135 #endif
136                 }
137                 iov->iov_base = (char *)iov->iov_base + cnt;
138                 iov->iov_len -= cnt;
139                 uio->uio_resid -= cnt;
140                 uio->uio_offset += cnt;
141                 cp += cnt;
142                 n -= cnt;
143         }
144         return (error);
145 }
146
147 #ifndef __ECOS
148 /*
149  * Give next character to user as result of read.
150  */
151 int
152 ureadc(c, uio)
153         register int c;
154         register struct uio *uio;
155 {
156         register struct iovec *iov;
157
158         if (uio->uio_resid == 0)
159 #ifdef DIAGNOSTIC
160                 panic("ureadc: zero resid");
161 #else
162                 return (EINVAL);
163 #endif
164 again:
165         if (uio->uio_iovcnt <= 0)
166 #ifdef DIAGNOSTIC
167                 panic("ureadc: non-positive iovcnt");
168 #else
169                 return (EINVAL);
170 #endif
171         iov = uio->uio_iov;
172         if (iov->iov_len <= 0) {
173                 uio->uio_iovcnt--;
174                 uio->uio_iov++;
175                 goto again;
176         }
177         switch (uio->uio_segflg) {
178
179         case UIO_USERSPACE:
180                 if (subyte(iov->iov_base, c) < 0)
181                         return (EFAULT);
182                 break;
183
184         case UIO_SYSSPACE:
185                 *(char *)iov->iov_base = c;
186                 break;
187         }
188         iov->iov_base++;
189         iov->iov_len--;
190         uio->uio_resid--;
191         uio->uio_offset++;
192         return (0);
193 }
194 #endif // __ECOS
195
196 /*
197  * General routine to allocate a hash table.
198  */
199 #ifdef __ECOS
200 void *
201 hashinit(int elements, int type, int flags, u_long *hashmask)
202 #else
203 void *
204 hashinit(elements, type, flags, hashmask)
205         int elements, type, flags;
206         u_long *hashmask;
207 #endif
208 {
209         long hashsize;
210         LIST_HEAD(generic, generic) *hashtbl;
211         int i;
212
213         if (elements <= 0)
214                 panic("hashinit: bad cnt");
215         for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
216                 continue;
217         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;
222         return (hashtbl);
223 }
224
225 #ifndef __ECOS
226 /*
227  * "Shutdown hook" types, functions, and variables.
228  */
229
230 struct shutdownhook_desc {
231         LIST_ENTRY(shutdownhook_desc) sfd_list;
232         void    (*sfd_fn) __P((void *));
233         void    *sfd_arg;
234 };
235
236 LIST_HEAD(, shutdownhook_desc) shutdownhook_list;
237
238 int shutdownhooks_done;
239
240 void *
241 shutdownhook_establish(fn, arg)
242         void (*fn) __P((void *));
243         void *arg;
244 {
245         struct shutdownhook_desc *ndp;
246
247         ndp = (struct shutdownhook_desc *)
248             malloc(sizeof (*ndp), M_DEVBUF, M_NOWAIT);
249         if (ndp == NULL)
250                 return NULL;
251
252         ndp->sfd_fn = fn;
253         ndp->sfd_arg = arg;
254         LIST_INSERT_HEAD(&shutdownhook_list, ndp, sfd_list);
255
256         return (ndp);
257 }
258
259 void
260 shutdownhook_disestablish(vhook)
261         void *vhook;
262 {
263 #ifdef DIAGNOSTIC
264         struct shutdownhook_desc *dp;
265
266         for (dp = shutdownhook_list.lh_first; dp != NULL;
267             dp = dp->sfd_list.le_next)
268                 if (dp == vhook)
269                         break;
270         if (dp == NULL)
271                 panic("shutdownhook_disestablish: hook not established");
272 #endif
273
274         LIST_REMOVE((struct shutdownhook_desc *)vhook, sfd_list);
275 }
276
277 /*
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.
281  */
282 void
283 doshutdownhooks()
284 {
285         struct shutdownhook_desc *dp;
286
287         if (shutdownhooks_done)
288                 return;
289
290         for (dp = shutdownhook_list.lh_first; dp != NULL; dp =
291             dp->sfd_list.le_next)
292                 (*dp->sfd_fn)(dp->sfd_arg);
293 }
294
295 /*
296  * "Power hook" types, functions, and variables.
297  */
298
299 struct powerhook_desc {
300         LIST_ENTRY(powerhook_desc) sfd_list;
301         void    (*sfd_fn) __P((int, void *));
302         void    *sfd_arg;
303 };
304
305 LIST_HEAD(, powerhook_desc) powerhook_list;
306
307 void *
308 powerhook_establish(fn, arg)
309         void (*fn) __P((int, void *));
310         void *arg;
311 {
312         struct powerhook_desc *ndp;
313
314         ndp = (struct powerhook_desc *)
315             malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT);
316         if (ndp == NULL)
317                 return NULL;
318
319         ndp->sfd_fn = fn;
320         ndp->sfd_arg = arg;
321         LIST_INSERT_HEAD(&powerhook_list, ndp, sfd_list);
322
323         return (ndp);
324 }
325
326 void
327 powerhook_disestablish(vhook)
328         void *vhook;
329 {
330 #ifdef DIAGNOSTIC
331         struct powerhook_desc *dp;
332
333         for (dp = powerhook_list.lh_first; dp != NULL;
334             dp = dp->sfd_list.le_next)
335                 if (dp == vhook)
336                         break;
337         if (dp == NULL)
338                 panic("powerhook_disestablish: hook not established");
339 #endif
340
341         LIST_REMOVE((struct powerhook_desc *)vhook, sfd_list);
342         free(vhook, M_DEVBUF);
343 }
344
345 /*
346  * Run power hooks.
347  */
348 void
349 dopowerhooks(why)
350         int why;
351 {
352         struct powerhook_desc *dp;
353
354         for (dp = LIST_FIRST(&powerhook_list); 
355              dp != NULL; 
356              dp = LIST_NEXT(dp, sfd_list)) {
357                 (*dp->sfd_fn)(why, dp->sfd_arg);
358         }
359 }
360 #endif // __ECOS