1 1.9 riastrad /* $NetBSD: criov.c,v 1.9 2018/09/03 16:29:37 riastradh Exp $ */ 2 1.1 jonathan /* $OpenBSD: criov.c,v 1.11 2002/06/10 19:36:43 espie Exp $ */ 3 1.1 jonathan 4 1.1 jonathan /* 5 1.1 jonathan * Copyright (c) 1999 Theo de Raadt 6 1.1 jonathan * 7 1.1 jonathan * Redistribution and use in source and binary forms, with or without 8 1.1 jonathan * modification, are permitted provided that the following conditions 9 1.1 jonathan * are met: 10 1.1 jonathan * 11 1.1 jonathan * 1. Redistributions of source code must retain the above copyright 12 1.1 jonathan * notice, this list of conditions and the following disclaimer. 13 1.1 jonathan * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 jonathan * notice, this list of conditions and the following disclaimer in the 15 1.1 jonathan * documentation and/or other materials provided with the distribution. 16 1.1 jonathan * 3. The name of the author may not be used to endorse or promote products 17 1.1 jonathan * derived from this software without specific prior written permission. 18 1.1 jonathan * 19 1.1 jonathan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 1.1 jonathan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 1.1 jonathan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 1.1 jonathan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 1.1 jonathan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 1.1 jonathan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 1.1 jonathan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 1.1 jonathan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 1.1 jonathan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 1.1 jonathan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 1.1 jonathan */ 30 1.1 jonathan 31 1.1 jonathan #include <sys/cdefs.h> 32 1.9 riastrad __KERNEL_RCSID(0, "$NetBSD: criov.c,v 1.9 2018/09/03 16:29:37 riastradh Exp $"); 33 1.1 jonathan 34 1.1 jonathan #include <sys/param.h> 35 1.1 jonathan #include <sys/systm.h> 36 1.1 jonathan #include <sys/proc.h> 37 1.1 jonathan #include <sys/errno.h> 38 1.1 jonathan #include <sys/malloc.h> 39 1.1 jonathan #include <sys/kernel.h> 40 1.1 jonathan #include <sys/mbuf.h> 41 1.1 jonathan 42 1.1 jonathan #include <uvm/uvm_extern.h> 43 1.1 jonathan 44 1.1 jonathan #include <opencrypto/cryptodev.h> 45 1.1 jonathan int cuio_getindx(struct uio *uio, int loc, int *off); 46 1.1 jonathan 47 1.1 jonathan 48 1.1 jonathan void 49 1.7 dsl cuio_copydata(struct uio *uio, int off, int len, void *cp) 50 1.1 jonathan { 51 1.1 jonathan struct iovec *iov = uio->uio_iov; 52 1.1 jonathan int iol = uio->uio_iovcnt; 53 1.1 jonathan unsigned count; 54 1.1 jonathan 55 1.1 jonathan if (off < 0) 56 1.1 jonathan panic("cuio_copydata: off %d < 0", off); 57 1.1 jonathan if (len < 0) 58 1.1 jonathan panic("cuio_copydata: len %d < 0", len); 59 1.1 jonathan while (off > 0) { 60 1.1 jonathan if (iol == 0) 61 1.1 jonathan panic("iov_copydata: empty in skip"); 62 1.1 jonathan if (off < iov->iov_len) 63 1.1 jonathan break; 64 1.1 jonathan off -= iov->iov_len; 65 1.1 jonathan iol--; 66 1.1 jonathan iov++; 67 1.1 jonathan } 68 1.1 jonathan while (len > 0) { 69 1.1 jonathan if (iol == 0) 70 1.1 jonathan panic("cuio_copydata: empty"); 71 1.9 riastrad count = uimin(iov->iov_len - off, len); 72 1.5 christos memcpy(cp, (char *)iov->iov_base + off, count); 73 1.1 jonathan len -= count; 74 1.5 christos cp = (char *)cp + count; 75 1.1 jonathan off = 0; 76 1.1 jonathan iol--; 77 1.1 jonathan iov++; 78 1.1 jonathan } 79 1.1 jonathan } 80 1.1 jonathan 81 1.1 jonathan void 82 1.7 dsl cuio_copyback(struct uio *uio, int off, int len, void *cp) 83 1.1 jonathan { 84 1.1 jonathan struct iovec *iov = uio->uio_iov; 85 1.1 jonathan int iol = uio->uio_iovcnt; 86 1.1 jonathan unsigned count; 87 1.1 jonathan 88 1.1 jonathan if (off < 0) 89 1.1 jonathan panic("cuio_copyback: off %d < 0", off); 90 1.1 jonathan if (len < 0) 91 1.1 jonathan panic("cuio_copyback: len %d < 0", len); 92 1.1 jonathan while (off > 0) { 93 1.8 drochner if (iol == 0) { 94 1.8 drochner #ifdef DEBUG 95 1.8 drochner printf("cuio_copyback: empty in skip\n"); 96 1.8 drochner #endif 97 1.8 drochner return; 98 1.8 drochner } 99 1.1 jonathan if (off < iov->iov_len) 100 1.1 jonathan break; 101 1.1 jonathan off -= iov->iov_len; 102 1.1 jonathan iol--; 103 1.1 jonathan iov++; 104 1.1 jonathan } 105 1.1 jonathan while (len > 0) { 106 1.8 drochner if (iol == 0) { 107 1.8 drochner #ifdef DEBUG 108 1.8 drochner printf("uio_copyback: empty\n"); 109 1.8 drochner #endif 110 1.8 drochner return; 111 1.8 drochner } 112 1.9 riastrad count = uimin(iov->iov_len - off, len); 113 1.5 christos memcpy((char *)iov->iov_base + off, cp, count); 114 1.1 jonathan len -= count; 115 1.5 christos cp = (char *)cp + count; 116 1.1 jonathan off = 0; 117 1.1 jonathan iol--; 118 1.1 jonathan iov++; 119 1.1 jonathan } 120 1.1 jonathan } 121 1.1 jonathan 122 1.1 jonathan /* 123 1.1 jonathan * Return a pointer to iov/offset of location in iovec list. 124 1.1 jonathan */ 125 1.1 jonathan 126 1.1 jonathan int 127 1.1 jonathan cuio_getptr(struct uio *uio, int loc, int *off) 128 1.1 jonathan { 129 1.1 jonathan int ind, len; 130 1.1 jonathan 131 1.1 jonathan ind = 0; 132 1.1 jonathan while (loc >= 0 && ind < uio->uio_iovcnt) { 133 1.1 jonathan len = uio->uio_iov[ind].iov_len; 134 1.1 jonathan if (len > loc) { 135 1.1 jonathan *off = loc; 136 1.1 jonathan return (ind); 137 1.1 jonathan } 138 1.1 jonathan loc -= len; 139 1.1 jonathan ind++; 140 1.1 jonathan } 141 1.1 jonathan 142 1.1 jonathan if (ind > 0 && loc == 0) { 143 1.1 jonathan ind--; 144 1.1 jonathan *off = uio->uio_iov[ind].iov_len; 145 1.1 jonathan return (ind); 146 1.1 jonathan } 147 1.1 jonathan 148 1.1 jonathan return (-1); 149 1.1 jonathan } 150 1.1 jonathan 151 1.1 jonathan int 152 1.1 jonathan cuio_apply(struct uio *uio, int off, int len, 153 1.5 christos int (*f)(void *, void *, unsigned int), void *fstate) 154 1.1 jonathan { 155 1.1 jonathan int rval, ind, uiolen; 156 1.1 jonathan unsigned int count; 157 1.1 jonathan 158 1.1 jonathan if (len < 0) 159 1.1 jonathan panic("%s: len %d < 0", __func__, len); 160 1.1 jonathan if (off < 0) 161 1.1 jonathan panic("%s: off %d < 0", __func__, off); 162 1.3 perry 163 1.1 jonathan ind = 0; 164 1.1 jonathan while (off > 0) { 165 1.1 jonathan if (ind >= uio->uio_iovcnt) 166 1.2 lha panic("cuio_apply: out of ivecs before data in uio"); 167 1.1 jonathan uiolen = uio->uio_iov[ind].iov_len; 168 1.1 jonathan if (off < uiolen) 169 1.1 jonathan break; 170 1.1 jonathan off -= uiolen; 171 1.1 jonathan ind++; 172 1.1 jonathan } 173 1.1 jonathan while (len > 0) { 174 1.1 jonathan if (ind >= uio->uio_iovcnt) 175 1.2 lha panic("cuio_apply: out of ivecs when processing uio"); 176 1.9 riastrad count = uimin(uio->uio_iov[ind].iov_len - off, len); 177 1.1 jonathan 178 1.3 perry rval = f(fstate, 179 1.5 christos ((char *)uio->uio_iov[ind].iov_base + off), count); 180 1.1 jonathan if (rval) 181 1.1 jonathan return (rval); 182 1.1 jonathan 183 1.1 jonathan len -= count; 184 1.1 jonathan off = 0; 185 1.1 jonathan ind++; 186 1.1 jonathan } 187 1.1 jonathan 188 1.1 jonathan return (0); 189 1.1 jonathan } 190