]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_subr.c
xnu-1228.9.59.tar.gz
[apple/xnu.git] / bsd / kern / kern_subr.c
index 0a40c0a19dca2f5bdc328ba8c808ee9822926fa1..711dc5fe70d84efa9fa3c3f93a0f7e533f4c6824 100644 (file)
@@ -1,14 +1,19 @@
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -18,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 /*
 #if DEBUG
 #include <kern/simple_lock.h>
 
-static int                             uio_t_count = 0;
+static uint32_t                                uio_t_count = 0;
 #endif /* DEBUG */
 
 
+/*
+ * Returns:    0                       Success
+ *     uiomove64:EFAULT
+ *
+ * Notes:      The first argument should be a caddr_t, but const poisoning
+ *             for typedef'ed types doesn't work in gcc.
+ */
 int
-uiomove(cp, n, uio)
-       register caddr_t cp;
-       register int n;
-       register uio_t uio;
+uiomove(const char * cp, int n, uio_t uio)
 {
-       return uiomove64((addr64_t)((unsigned int)cp), n, uio);
+       return uiomove64((const addr64_t)((const unsigned int)cp), n, uio);
 }
 
+/*
+ * Returns:    0                       Success
+ *             EFAULT
+ *     copyout:EFAULT
+ *     copyin:EFAULT
+ *     copywithin:EFAULT
+ *     copypv:EFAULT
+ */
        // LP64todo - fix this! 'n' should be int64_t?
 int
-uiomove64(addr64_t cp, int n, register struct uio *uio)
+uiomove64(const addr64_t c_cp, int n, struct uio *uio)
 {
+       addr64_t cp = c_cp;
 #if LP64KERN
-       register uint64_t acnt;
+       uint64_t acnt;
 #else
-       register u_int acnt;
+       u_int acnt;
 #endif
        int error = 0;
 
@@ -302,9 +320,7 @@ uiomove64(addr64_t cp, int n, register struct uio *uio)
  * Give next character to user as result of read.
  */
 int
-ureadc(c, uio)
-       register int c;
-       register struct uio *uio;
+ureadc(int c, struct uio *uio)
 {
        if (uio_resid(uio) <= 0)
                panic("ureadc: non-positive resid");
@@ -356,10 +372,9 @@ again:
  * Get next character written in by user from uio.
  */
 int
-uwritec(uio)
-       uio_t uio;
+uwritec(uio_t uio)
 {
-       register int c = 0;
+       int c = 0;
 
        if (uio_resid(uio) <= 0)
                return (-1);
@@ -413,9 +428,7 @@ again:
  * General routine to allocate a hash table.
  */
 void *
-hashinit(elements, type, hashmask)
-       int elements, type;
-       u_long *hashmask;
+hashinit(int elements, int type, u_long *hashmask)
 {
        long hashsize;
        LIST_HEAD(generic, generic) *hashtbl;
@@ -443,7 +456,7 @@ user_ssize_t uio_resid( uio_t a_uio )
 {
 #if DEBUG
        if (a_uio == NULL) {
-               panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); 
+               printf("%s :%d - invalid uio_t\n", __FILE__, __LINE__); 
        }
 /*     if (IS_VALID_UIO_SEGFLG(a_uio->uio_segflg) == 0) { */
 /*             panic("%s :%d - invalid uio_segflg\n", __FILE__, __LINE__);  */
@@ -496,44 +509,6 @@ void uio_setresid( uio_t a_uio, user_ssize_t a_value )
        return;
 }
 
-#if 0 // obsolete
-/*
- * uio_proc_t - return the proc_t for the given uio_t
- * WARNING - This call is going away.  Find another way to get the proc_t!!
- */
-__private_extern__ proc_t uio_proc_t( uio_t a_uio )
-{
-#if LP64_DEBUG
-       if (a_uio == NULL) {
-               panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); 
-       }
-#endif /* LP64_DEBUG */
-
-       /* return 0 if there are no active iovecs */
-       if (a_uio == NULL) {
-               return( NULL );
-       }
-       return( a_uio->uio_procp );
-}
-
-/*
- * uio_setproc_t - set the residual IO value for the given uio_t
- * WARNING - This call is going away. 
- */
-__private_extern__ void uio_setproc_t( uio_t a_uio, proc_t a_proc_t )
-{
-       if (a_uio == NULL) {
-#if LP64_DEBUG
-               panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); 
-#endif /* LP64_DEBUG */
-               return;
-       }
-
-       a_uio->uio_procp = a_proc_t;
-       return;
-}
-#endif // obsolete
-
 /*
  * uio_curriovbase - return the base address of the current iovec associated 
  *     with the given uio_t.  May return 0.
@@ -738,7 +713,7 @@ uio_t uio_create( int a_iovcount,           /* number of iovecs */
        int                                     my_size;
        uio_t                           my_uio;
        
-       my_size = sizeof(struct uio) + (sizeof(struct user_iovec) * a_iovcount);
+       my_size = UIO_SIZEOF(a_iovcount);
        my_buf_p = kalloc(my_size);
        my_uio = uio_createwithbuffer( a_iovcount, 
                                                                         a_offset,
@@ -750,7 +725,7 @@ uio_t uio_create( int a_iovcount,           /* number of iovecs */
                /* leave a note that we allocated this uio_t */
                my_uio->uio_flags |= UIO_FLAGS_WE_ALLOCED;
 #if DEBUG
-               hw_atomic_add(&uio_t_count, 1);
+               (void)hw_atomic_add(&uio_t_count, 1);
 #endif
        }
        
@@ -942,9 +917,8 @@ void uio_free( uio_t a_uio )
 
        if (a_uio != NULL && (a_uio->uio_flags & UIO_FLAGS_WE_ALLOCED) != 0) {
 #if DEBUG
-               if ((int)(hw_atomic_sub(&uio_t_count, 1)) < 0) {
-                       panic("%s :%d - uio_t_count has gone negative\n", __FILE__, __LINE__); 
-               }
+               if (hw_atomic_sub(&uio_t_count, 1) == UINT_MAX)
+                       panic("%s :%d - uio_t_count underflow\n", __FILE__, __LINE__); 
 #endif
                kfree(a_uio, a_uio->uio_size);
        }
@@ -1056,7 +1030,7 @@ __private_extern__ void uio_calculateresid( uio_t a_uio )
                return;
        }
 
-       a_uio->uio_iovcnt = 0;
+       a_uio->uio_iovcnt = a_uio->uio_max_iovs;
        if (UIO_IS_64_BIT_SPACE(a_uio)) {
 #if 1 // LP64todo - remove this temp workaround once we go live with uio KPI
                a_uio->uio_resid = 0;
@@ -1065,7 +1039,6 @@ __private_extern__ void uio_calculateresid( uio_t a_uio )
 #endif
                for ( i = 0; i < a_uio->uio_max_iovs; i++ ) {
                        if (a_uio->uio_iovs.uiovp[i].iov_len != 0 && a_uio->uio_iovs.uiovp[i].iov_base != 0) {
-                               a_uio->uio_iovcnt++;
 #if 1 // LP64todo - remove this temp workaround once we go live with uio KPI
                                a_uio->uio_resid += a_uio->uio_iovs.uiovp[i].iov_len;
 #else
@@ -1073,16 +1046,32 @@ __private_extern__ void uio_calculateresid( uio_t a_uio )
 #endif
                        }
                }
+
+               /* position to first non zero length iovec (4235922) */
+               while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.uiovp->iov_len == 0) {
+                       a_uio->uio_iovcnt--;
+                       if (a_uio->uio_iovcnt > 0) {
+                               a_uio->uio_iovs.uiovp++;
+                       }
+               }
        }
        else {
                a_uio->uio_resid = 0;
                for ( i = 0; i < a_uio->uio_max_iovs; i++ ) {
                        if (a_uio->uio_iovs.kiovp[i].iov_len != 0 && a_uio->uio_iovs.kiovp[i].iov_base != 0) {
-                               a_uio->uio_iovcnt++;
                                a_uio->uio_resid += a_uio->uio_iovs.kiovp[i].iov_len;
                        }
                }
+
+               /* position to first non zero length iovec (4235922) */
+               while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.kiovp->iov_len == 0) {
+                       a_uio->uio_iovcnt--;
+                       if (a_uio->uio_iovcnt > 0) {
+                               a_uio->uio_iovs.kiovp++;
+                       }
+               }
        }
+
        return;
 }
 
@@ -1243,6 +1232,8 @@ uio_t uio_duplicate( uio_t a_uio )
                }
        }
 
+       my_uio->uio_flags = UIO_FLAGS_WE_ALLOCED | UIO_FLAGS_INITED;
+
        return(my_uio);
 }