123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
- * The President and Fellows of Harvard College.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include <types.h>
- #include <lib.h>
- #include <uio.h>
- #include <proc.h>
- #include <current.h>
- #include <copyinout.h>
- /*
- * See uio.h for a description.
- */
- int
- uiomove(void *ptr, size_t n, struct uio *uio)
- {
- struct iovec *iov;
- size_t size;
- int result;
- if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) {
- panic("uiomove: Invalid uio_rw %d\n", (int) uio->uio_rw);
- }
- if (uio->uio_segflg==UIO_SYSSPACE) {
- KASSERT(uio->uio_space == NULL);
- }
- else {
- KASSERT(uio->uio_space == curproc_getas());
- }
- while (n > 0 && uio->uio_resid > 0) {
- /* get the first iovec */
- iov = uio->uio_iov;
- size = iov->iov_len;
- if (size > n) {
- size = n;
- }
- if (size == 0) {
- /* move to the next iovec and try again */
- uio->uio_iov++;
- uio->uio_iovcnt--;
- if (uio->uio_iovcnt == 0) {
- /*
- * This should only happen if you set
- * uio_resid incorrectly (to more than
- * the total length of buffers the uio
- * points to).
- */
- panic("uiomove: ran out of buffers\n");
- }
- continue;
- }
- switch (uio->uio_segflg) {
- case UIO_SYSSPACE:
- result = 0;
- if (uio->uio_rw == UIO_READ) {
- memmove(iov->iov_kbase, ptr, size);
- }
- else {
- memmove(ptr, iov->iov_kbase, size);
- }
- iov->iov_kbase = ((char *)iov->iov_kbase+size);
- break;
- case UIO_USERSPACE:
- case UIO_USERISPACE:
- if (uio->uio_rw == UIO_READ) {
- result = copyout(ptr, iov->iov_ubase,size);
- }
- else {
- result = copyin(iov->iov_ubase, ptr, size);
- }
- if (result) {
- return result;
- }
- iov->iov_ubase += size;
- break;
- default:
- panic("uiomove: Invalid uio_segflg %d\n",
- (int)uio->uio_segflg);
- }
- iov->iov_len -= size;
- uio->uio_resid -= size;
- uio->uio_offset += size;
- ptr = ((char *)ptr + size);
- n -= size;
- }
- return 0;
- }
- int
- uiomovezeros(size_t n, struct uio *uio)
- {
- /* static, so initialized as zero */
- static char zeros[16];
- size_t amt;
- int result;
- /* This only makes sense when reading */
- KASSERT(uio->uio_rw == UIO_READ);
- while (n > 0) {
- amt = sizeof(zeros);
- if (amt > n) {
- amt = n;
- }
- result = uiomove(zeros, amt, uio);
- if (result) {
- return result;
- }
- n -= amt;
- }
- return 0;
- }
- /*
- * Convenience function to initialize an iovec and uio for kernel I/O.
- */
- void
- uio_kinit(struct iovec *iov, struct uio *u,
- void *kbuf, size_t len, off_t pos, enum uio_rw rw)
- {
- iov->iov_kbase = kbuf;
- iov->iov_len = len;
- u->uio_iov = iov;
- u->uio_iovcnt = 1;
- u->uio_offset = pos;
- u->uio_resid = len;
- u->uio_segflg = UIO_SYSSPACE;
- u->uio_rw = rw;
- u->uio_space = NULL;
- }
|