]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_subr.c
xnu-344.49.tar.gz
[apple/xnu.git] / bsd / kern / kern_subr.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26/*
27 * Copyright (c) 1982, 1986, 1991, 1993
28 * The Regents of the University of California. All rights reserved.
29 * (c) UNIX System Laboratories, Inc.
30 * All or some portions of this file are derived from material licensed
31 * to the University of California by American Telephone and Telegraph
32 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
33 * the permission of UNIX System Laboratories, Inc.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the University of
46 * California, Berkeley and its contributors.
47 * 4. Neither the name of the University nor the names of its contributors
48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 *
63 * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
64 */
65
66#include <sys/param.h>
67#include <sys/systm.h>
68#include <sys/proc.h>
69#include <sys/malloc.h>
70#include <sys/queue.h>
71
72#include <kdebug.h>
73
74#include <sys/kdebug.h>
75#define DBG_UIO_COPYOUT 16
76#define DBG_UIO_COPYIN 17
77
de355530 78
1c79356b
A
79int
80uiomove(cp, n, uio)
81 register caddr_t cp;
82 register int n;
83 register struct uio *uio;
84{
85 register struct iovec *iov;
86 u_int cnt;
87 int error = 0;
88
89#if DIAGNOSTIC
90 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
91 panic("uiomove: mode");
92 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != current_proc())
93 panic("uiomove proc");
94#endif
95
96 while (n > 0 && uio->uio_resid) {
97 iov = uio->uio_iov;
98 cnt = iov->iov_len;
99 if (cnt == 0) {
100 uio->uio_iov++;
101 uio->uio_iovcnt--;
102 continue;
103 }
104 if (cnt > n)
105 cnt = n;
106 switch (uio->uio_segflg) {
107
108 case UIO_USERSPACE:
109 case UIO_USERISPACE:
110 if (uio->uio_rw == UIO_READ)
111 {
112 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
de355530 113 cp, iov->iov_base, cnt, 0,0);
1c79356b 114
de355530 115 error = copyout(cp, iov->iov_base, cnt);
1c79356b
A
116
117 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
de355530 118 cp, iov->iov_base, cnt, 0,0);
1c79356b
A
119 }
120 else
121 {
122 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
de355530 123 iov->iov_base, cp, cnt, 0,0);
1c79356b 124
de355530 125 error = copyin(iov->iov_base, cp, cnt);
1c79356b
A
126
127 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
de355530 128 iov->iov_base, cp, cnt, 0,0);
1c79356b
A
129 }
130 if (error)
131 return (error);
132 break;
133
134 case UIO_SYSSPACE:
135 if (uio->uio_rw == UIO_READ)
136 error = copywithin((caddr_t)cp, iov->iov_base,
137 cnt);
138 else
139 error = copywithin(iov->iov_base, (caddr_t)cp,
140 cnt);
141 break;
9bccf70c 142
1c79356b
A
143 case UIO_PHYS_USERSPACE:
144 if (uio->uio_rw == UIO_READ)
145 {
146 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
147 cp, iov->iov_base, cnt, 1,0);
148
de355530
A
149 error = copyp2v(cp, iov->iov_base, cnt);
150
1c79356b
A
151
152 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
153 cp, iov->iov_base, cnt, 1,0);
154 }
155 else
156 {
157 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
158 iov->iov_base, cp, cnt, 1,0);
159
de355530 160 panic("copyv2p not implemented yet\n");
1c79356b
A
161
162 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
163 iov->iov_base, cp, cnt, 1,0);
164 }
165 if (error)
166 return (error);
167 break;
1c79356b
A
168 }
169 iov->iov_base += cnt;
170 iov->iov_len -= cnt;
171 uio->uio_resid -= cnt;
172 uio->uio_offset += cnt;
173 cp += cnt;
174 n -= cnt;
175 }
176 return (error);
177}
178
179/*
180 * Give next character to user as result of read.
181 */
182int
183ureadc(c, uio)
184 register int c;
185 register struct uio *uio;
186{
187 register struct iovec *iov;
188
189 if (uio->uio_resid <= 0)
190 panic("ureadc: non-positive resid");
191again:
192 if (uio->uio_iovcnt == 0)
193 panic("ureadc: non-positive iovcnt");
194 iov = uio->uio_iov;
195 if (iov->iov_len <= 0) {
196 uio->uio_iovcnt--;
197 uio->uio_iov++;
198 goto again;
199 }
200 switch (uio->uio_segflg) {
201
202 case UIO_USERSPACE:
203 if (subyte(iov->iov_base, c) < 0)
204 return (EFAULT);
205 break;
206
207 case UIO_SYSSPACE:
208 *iov->iov_base = c;
209 break;
210
211 case UIO_USERISPACE:
212 if (suibyte(iov->iov_base, c) < 0)
213 return (EFAULT);
214 break;
215 }
216 iov->iov_base++;
217 iov->iov_len--;
218 uio->uio_resid--;
219 uio->uio_offset++;
220 return (0);
221}
222
223#if defined(vax) || defined(ppc)
224/* unused except by ct.c, other oddities XXX */
225/*
226 * Get next character written in by user from uio.
227 */
228uwritec(uio)
229 struct uio *uio;
230{
231 register struct iovec *iov;
232 register int c;
233
234 if (uio->uio_resid <= 0)
235 return (-1);
236again:
237 if (uio->uio_iovcnt <= 0)
238 panic("uwritec: non-positive iovcnt");
239 iov = uio->uio_iov;
240 if (iov->iov_len == 0) {
241 uio->uio_iov++;
242 if (--uio->uio_iovcnt == 0)
243 return (-1);
244 goto again;
245 }
246 switch (uio->uio_segflg) {
247
248 case UIO_USERSPACE:
249 c = fubyte(iov->iov_base);
250 break;
251
252 case UIO_SYSSPACE:
253 c = *iov->iov_base & 0377;
254 break;
255
256 case UIO_USERISPACE:
257 c = fuibyte(iov->iov_base);
258 break;
259
260 default:
261 c = 0; /* avoid uninitialized variable warning */
262 panic("uwritec: bogus uio_segflg");
263 break;
264 }
265 if (c < 0)
266 return (-1);
267 iov->iov_base++;
268 iov->iov_len--;
269 uio->uio_resid--;
270 uio->uio_offset++;
271 return (c);
272}
273#endif /* vax || ppc */
274
275/*
276 * General routine to allocate a hash table.
277 */
278void *
279hashinit(elements, type, hashmask)
280 int elements, type;
281 u_long *hashmask;
282{
283 long hashsize;
284 LIST_HEAD(generic, generic) *hashtbl;
285 int i;
286
287 if (elements <= 0)
288 panic("hashinit: bad cnt");
289 for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
290 continue;
291 hashsize >>= 1;
292 MALLOC(hashtbl, struct generic *,
293 (u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
294 bzero(hashtbl, (u_long)hashsize * sizeof(*hashtbl));
295 for (i = 0; i < hashsize; i++)
296 LIST_INIT(&hashtbl[i]);
297 *hashmask = hashsize - 1;
298 return (hashtbl);
299}