The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/kern/kern_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    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
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   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.
   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 #include <vm/pmap.h>
   72 
   73 #include <kdebug.h>
   74 
   75 #include <sys/kdebug.h>
   76 #define DBG_UIO_COPYOUT 16
   77 #define DBG_UIO_COPYIN  17
   78 
   79 
   80 int
   81 uiomove(cp, n, uio)
   82         register caddr_t cp;
   83         register int n;
   84         register struct uio *uio;
   85 {
   86         return uiomove64((addr64_t)((unsigned int)cp), n, uio);
   87 }
   88 
   89 int
   90 uiomove64(addr64_t cp, int n, struct uio *uio)
   91 {
   92         register struct iovec *iov;
   93         u_int cnt;
   94         int error = 0;
   95 
   96 #if DIAGNOSTIC
   97         if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
   98                 panic("uiomove: mode");
   99         if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != current_proc())
  100                 panic("uiomove proc");
  101 #endif
  102 
  103         while (n > 0 && uio->uio_resid) {
  104                 iov = uio->uio_iov;
  105                 cnt = iov->iov_len;
  106                 if (cnt == 0) {
  107                         uio->uio_iov++;
  108                         uio->uio_iovcnt--;
  109                         continue;
  110                 }
  111                 if (cnt > n)
  112                         cnt = n;
  113                 switch (uio->uio_segflg) {
  114 
  115                 case UIO_USERSPACE:
  116                 case UIO_USERISPACE:
  117                         if (uio->uio_rw == UIO_READ)
  118                           {
  119                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
  120                                          (int)cp, (int)iov->iov_base, cnt, 0,0);
  121 
  122                                 error = copyout( CAST_DOWN(caddr_t, cp), iov->iov_base, cnt );
  123 
  124                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
  125                                          (int)cp, (int)iov->iov_base, cnt, 0,0);
  126                           }
  127                         else
  128                           {
  129                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
  130                                          (int)iov->iov_base, (int)cp, cnt, 0,0);
  131 
  132                                 error = copyin(iov->iov_base, CAST_DOWN(caddr_t, cp), cnt);
  133 
  134                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
  135                                          (int)iov->iov_base, (int)cp, cnt, 0,0);
  136                           }
  137                         if (error)
  138                                 return (error);
  139                         break;
  140 
  141                 case UIO_SYSSPACE:
  142                         if (uio->uio_rw == UIO_READ)
  143                                 error = copywithin(CAST_DOWN(caddr_t, cp), iov->iov_base,
  144                                                    cnt);
  145                         else
  146                                 error = copywithin(iov->iov_base, CAST_DOWN(caddr_t, cp),
  147                                                    cnt);
  148                         break;
  149 
  150                 case UIO_PHYS_USERSPACE:
  151                         if (uio->uio_rw == UIO_READ)
  152                           {
  153                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
  154                                          (int)cp, (int)iov->iov_base, cnt, 1,0);
  155 
  156                                 if (error = copypv((addr64_t)cp, (addr64_t)((unsigned int)iov->iov_base), cnt, cppvPsrc | cppvNoRefSrc))        /* Copy physical to virtual */
  157                                         error = EFAULT;
  158 
  159                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
  160                                          (int)cp, (int)iov->iov_base, cnt, 1,0);
  161                           }
  162                         else
  163                           {
  164                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
  165                                          (int)iov->iov_base, (int)cp, cnt, 1,0);
  166 
  167                                 if (error = copypv((addr64_t)((unsigned int)iov->iov_base), (addr64_t)cp, cnt, cppvPsnk | cppvNoRefSrc | cppvNoModSnk)) /* Copy virtual to physical */
  168                                         error = EFAULT;
  169 
  170                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
  171                                          (int)iov->iov_base, (int)cp, cnt, 1,0);
  172                           }
  173                         if (error)
  174                                 return (error);
  175                         break;
  176 
  177                 case UIO_PHYS_SYSSPACE:
  178                         if (uio->uio_rw == UIO_READ)
  179                           {
  180                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_START,
  181                                          (int)cp, (int)iov->iov_base, cnt, 2,0);
  182 
  183                                 if (error = copypv((addr64_t)cp, (addr64_t)((unsigned int)iov->iov_base), cnt, cppvKmap | cppvPsrc | cppvNoRefSrc))     /* Copy physical to virtual */
  184                                         error = EFAULT;
  185 
  186                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYOUT)) | DBG_FUNC_END,
  187                                          (int)cp, (int)iov->iov_base, cnt, 2,0);
  188                           }
  189                         else
  190                           {
  191                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_START,
  192                                          (int)iov->iov_base, (int)cp, cnt, 2,0);
  193 
  194                                 if (error = copypv((addr64_t)((unsigned int)iov->iov_base), (addr64_t)cp, cnt, cppvKmap | cppvPsnk | cppvNoRefSrc | cppvNoModSnk))      /* Copy virtual to physical */
  195                                         error = EFAULT;
  196 
  197                                 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, DBG_UIO_COPYIN)) | DBG_FUNC_END,
  198                                          (int)iov->iov_base, (int)cp, cnt, 2,0);
  199                           }
  200                         if (error)
  201                                 return (error);
  202                         break;
  203                 }
  204                 iov->iov_base += cnt;
  205                 iov->iov_len -= cnt;
  206                 uio->uio_resid -= cnt;
  207                 uio->uio_offset += cnt;
  208                 cp += cnt;
  209                 n -= cnt;
  210         }
  211         return (error);
  212 }
  213 
  214 /*
  215  * Give next character to user as result of read.
  216  */
  217 int
  218 ureadc(c, uio)
  219         register int c;
  220         register struct uio *uio;
  221 {
  222         register struct iovec *iov;
  223 
  224         if (uio->uio_resid <= 0)
  225                 panic("ureadc: non-positive resid");
  226 again:
  227         if (uio->uio_iovcnt == 0)
  228                 panic("ureadc: non-positive iovcnt");
  229         iov = uio->uio_iov;
  230         if (iov->iov_len <= 0) {
  231                 uio->uio_iovcnt--;
  232                 uio->uio_iov++;
  233                 goto again;
  234         }
  235         switch (uio->uio_segflg) {
  236 
  237         case UIO_USERSPACE:
  238                 if (subyte(iov->iov_base, c) < 0)
  239                         return (EFAULT);
  240                 break;
  241 
  242         case UIO_SYSSPACE:
  243                 *iov->iov_base = c;
  244                 break;
  245 
  246         case UIO_USERISPACE:
  247                 if (suibyte(iov->iov_base, c) < 0)
  248                         return (EFAULT);
  249                 break;
  250         }
  251         iov->iov_base++;
  252         iov->iov_len--;
  253         uio->uio_resid--;
  254         uio->uio_offset++;
  255         return (0);
  256 }
  257 
  258 #if defined(vax) || defined(ppc)
  259 /* unused except by ct.c, other oddities XXX */
  260 /*
  261  * Get next character written in by user from uio.
  262  */
  263 uwritec(uio)
  264         struct uio *uio;
  265 {
  266         register struct iovec *iov;
  267         register int c;
  268 
  269         if (uio->uio_resid <= 0)
  270                 return (-1);
  271 again:
  272         if (uio->uio_iovcnt <= 0)
  273                 panic("uwritec: non-positive iovcnt");
  274         iov = uio->uio_iov;
  275         if (iov->iov_len == 0) {
  276                 uio->uio_iov++;
  277                 if (--uio->uio_iovcnt == 0)
  278                         return (-1);
  279                 goto again;
  280         }
  281         switch (uio->uio_segflg) {
  282 
  283         case UIO_USERSPACE:
  284                 c = fubyte(iov->iov_base);
  285                 break;
  286 
  287         case UIO_SYSSPACE:
  288                 c = *iov->iov_base & 0377;
  289                 break;
  290 
  291         case UIO_USERISPACE:
  292                 c = fuibyte(iov->iov_base);
  293                 break;
  294 
  295         default:
  296                 c = 0;  /* avoid uninitialized variable warning */
  297                 panic("uwritec: bogus uio_segflg");
  298                 break;
  299         }
  300         if (c < 0)
  301                 return (-1);
  302         iov->iov_base++;
  303         iov->iov_len--;
  304         uio->uio_resid--;
  305         uio->uio_offset++;
  306         return (c);
  307 }
  308 #endif /* vax || ppc */
  309 
  310 /*
  311  * General routine to allocate a hash table.
  312  */
  313 void *
  314 hashinit(elements, type, hashmask)
  315         int elements, type;
  316         u_long *hashmask;
  317 {
  318         long hashsize;
  319         LIST_HEAD(generic, generic) *hashtbl;
  320         int i;
  321 
  322         if (elements <= 0)
  323                 panic("hashinit: bad cnt");
  324         for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
  325                 continue;
  326         hashsize >>= 1;
  327         MALLOC(hashtbl, struct generic *, 
  328                         (u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
  329         bzero(hashtbl, (u_long)hashsize * sizeof(*hashtbl));
  330         for (i = 0; i < hashsize; i++)
  331                 LIST_INIT(&hashtbl[i]);
  332         *hashmask = hashsize - 1;
  333         return (hashtbl);
  334 }

Cache object: e8f19a48674ba8196ccbd2b42266ca0d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.