1 /* $OpenBSD: criov.c,v 1.7 2001/08/12 20:06:08 mickey 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/param.h> 31 #include <sys/systm.h> 32 #include <sys/proc.h> 33 #include <sys/errno.h> 34 #include <sys/malloc.h> 35 #include <sys/kernel.h> 36 #include <sys/mbuf.h> 37 38 #include <vm/vm.h> 39 40 #include <crypto/cryptodev.h> 41 42 int 43 iov2pages(uio, np, pp, lp, maxp, nicep) 44 struct uio *uio; 45 int *np; 46 long *pp; 47 int *lp; 48 int maxp; 49 int *nicep; 50 { 51 int npa = 0, tlen = 0; 52 int i; 53 54 for (i = 0; i < uio->uio_iovcnt; i++) { 55 vaddr_t va, off; 56 paddr_t pa; 57 int len; 58 59 if ((len = uio->uio_iov[i].iov_len) == 0) 60 continue; 61 tlen += len; 62 va = (vaddr_t)uio->uio_iov[i].iov_base; 63 off = va & PAGE_MASK; 64 va -= off; 65 66 next_page: 67 68 if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) 69 panic("iov2pages: unmapped pages"); 70 71 pa += off; 72 73 lp[npa] = len; 74 pp[npa] = pa; 75 76 if (++npa > maxp) 77 return (0); 78 79 if (len + off > PAGE_SIZE) { 80 lp[npa - 1] = PAGE_SIZE - off; 81 va += PAGE_SIZE; 82 len -= PAGE_SIZE; 83 goto next_page; 84 } 85 } 86 87 if (nicep) { 88 int nice = 1; 89 int i; 90 91 /* see if each [pa,len] entry is long-word aligned */ 92 for (i = 0; i < npa; i++) 93 if ((lp[i] & 3) || (pp[i] & 3)) 94 nice = 0; 95 *nicep = nice; 96 } 97 98 *np = npa; 99 return (tlen); 100 } 101 102 void 103 cuio_copydata(uio, off, len, cp) 104 struct uio *uio; 105 int off, len; 106 caddr_t cp; 107 { 108 struct iovec *iov = uio->uio_iov; 109 int iol = uio->uio_iovcnt; 110 unsigned count; 111 112 if (off < 0) 113 panic("cuio_copydata: off %d < 0", off); 114 if (len < 0) 115 panic("cuio_copydata: len %d < 0", len); 116 while (off > 0) { 117 if (iol == 0) 118 panic("iov_copydata: empty in skip"); 119 if (off < iov->iov_len) 120 break; 121 off -= iov->iov_len; 122 iol--; 123 iov++; 124 } 125 while (len > 0) { 126 if (iol == 0) 127 panic("cuio_copydata: empty"); 128 count = min(iov->iov_len - off, len); 129 bcopy(((caddr_t)iov->iov_base) + off, cp, count); 130 len -= count; 131 cp += count; 132 off = 0; 133 iol--; 134 iov++; 135 } 136 } 137 138 void 139 cuio_copyback(uio, off, len, cp) 140 struct uio *uio; 141 int off, len; 142 caddr_t cp; 143 { 144 struct iovec *iov = uio->uio_iov; 145 int iol = uio->uio_iovcnt; 146 unsigned count; 147 148 if (off < 0) 149 panic("cuio_copyback: off %d < 0", off); 150 if (len < 0) 151 panic("cuio_copyback: len %d < 0", len); 152 while (off > 0) { 153 if (iol == 0) 154 panic("cuio_copyback: empty in skip"); 155 if (off < iov->iov_len) 156 break; 157 off -= iov->iov_len; 158 iol--; 159 iov++; 160 } 161 while (len > 0) { 162 if (iol == 0) 163 panic("uio_copyback: empty"); 164 count = min(iov->iov_len - off, len); 165 bcopy(cp, ((caddr_t)iov->iov_base) + off, count); 166 len -= count; 167 cp += count; 168 off = 0; 169 iol--; 170 iov++; 171 } 172 } 173