1 /* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */ 2 3 /* 4 * Copyright (c) 1999 Theo de Raadt 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/proc.h> 36 #include <sys/errno.h> 37 #include <sys/malloc.h> 38 #include <sys/kernel.h> 39 #include <sys/uio.h> 40 41 #include <opencrypto/cryptodev.h> 42 43 void 44 cuio_copydata(struct uio* uio, int off, int len, caddr_t cp) 45 { 46 struct iovec *iov = uio->uio_iov; 47 int iol = uio->uio_iovcnt; 48 unsigned count; 49 50 if (off < 0) 51 panic("cuio_copydata: off %d < 0", off); 52 if (len < 0) 53 panic("cuio_copydata: len %d < 0", len); 54 while (off > 0) { 55 if (iol == 0) 56 panic("iov_copydata: empty in skip"); 57 if (off < iov->iov_len) 58 break; 59 off -= iov->iov_len; 60 iol--; 61 iov++; 62 } 63 while (len > 0) { 64 if (iol == 0) 65 panic("cuio_copydata: empty"); 66 count = min(iov->iov_len - off, len); 67 bcopy(((caddr_t)iov->iov_base) + off, cp, count); 68 len -= count; 69 cp += count; 70 off = 0; 71 iol--; 72 iov++; 73 } 74 } 75 76 void 77 cuio_copyback(struct uio* uio, int off, int len, caddr_t cp) 78 { 79 struct iovec *iov = uio->uio_iov; 80 int iol = uio->uio_iovcnt; 81 unsigned count; 82 83 if (off < 0) 84 panic("cuio_copyback: off %d < 0", off); 85 if (len < 0) 86 panic("cuio_copyback: len %d < 0", len); 87 while (off > 0) { 88 if (iol == 0) 89 panic("cuio_copyback: empty in skip"); 90 if (off < iov->iov_len) 91 break; 92 off -= iov->iov_len; 93 iol--; 94 iov++; 95 } 96 while (len > 0) { 97 if (iol == 0) 98 panic("uio_copyback: empty"); 99 count = min(iov->iov_len - off, len); 100 bcopy(cp, ((caddr_t)iov->iov_base) + off, count); 101 len -= count; 102 cp += count; 103 off = 0; 104 iol--; 105 iov++; 106 } 107 } 108 109 /* 110 * Return a pointer to iov/offset of location in iovec list. 111 */ 112 struct iovec * 113 cuio_getptr(struct uio *uio, int loc, int *off) 114 { 115 struct iovec *iov = uio->uio_iov; 116 int iol = uio->uio_iovcnt; 117 118 while (loc >= 0) { 119 /* Normal end of search */ 120 if (loc < iov->iov_len) { 121 *off = loc; 122 return (iov); 123 } 124 125 loc -= iov->iov_len; 126 if (iol == 0) { 127 if (loc == 0) { 128 /* Point at the end of valid data */ 129 *off = iov->iov_len; 130 return (iov); 131 } else 132 return (NULL); 133 } else { 134 iov++, iol--; 135 } 136 } 137 138 return (NULL); 139 } 140