criov.c revision 139825
1104476Ssam/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */ 2104476Ssam 3139825Simp/*- 4104476Ssam * Copyright (c) 1999 Theo de Raadt 5104476Ssam * 6104476Ssam * Redistribution and use in source and binary forms, with or without 7104476Ssam * modification, are permitted provided that the following conditions 8104476Ssam * are met: 9104476Ssam * 10104476Ssam * 1. Redistributions of source code must retain the above copyright 11104476Ssam * notice, this list of conditions and the following disclaimer. 12104476Ssam * 2. Redistributions in binary form must reproduce the above copyright 13104476Ssam * notice, this list of conditions and the following disclaimer in the 14104476Ssam * documentation and/or other materials provided with the distribution. 15104476Ssam * 3. The name of the author may not be used to endorse or promote products 16104476Ssam * derived from this software without specific prior written permission. 17104476Ssam * 18104476Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19104476Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20104476Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21104476Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22104476Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23104476Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24104476Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25104476Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26104476Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27104476Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28104476Ssam */ 29104476Ssam 30116191Sobrien#include <sys/cdefs.h> 31116191Sobrien__FBSDID("$FreeBSD: head/sys/opencrypto/criov.c 139825 2005-01-07 02:29:27Z imp $"); 32116191Sobrien 33104476Ssam#include <sys/param.h> 34104476Ssam#include <sys/systm.h> 35104476Ssam#include <sys/proc.h> 36104476Ssam#include <sys/errno.h> 37104476Ssam#include <sys/malloc.h> 38104476Ssam#include <sys/kernel.h> 39104476Ssam#include <sys/uio.h> 40104476Ssam 41104476Ssam#include <opencrypto/cryptodev.h> 42104476Ssam 43104476Ssamvoid 44104476Ssamcuio_copydata(struct uio* uio, int off, int len, caddr_t cp) 45104476Ssam{ 46104476Ssam struct iovec *iov = uio->uio_iov; 47104476Ssam int iol = uio->uio_iovcnt; 48104476Ssam unsigned count; 49104476Ssam 50104476Ssam if (off < 0) 51104476Ssam panic("cuio_copydata: off %d < 0", off); 52104476Ssam if (len < 0) 53104476Ssam panic("cuio_copydata: len %d < 0", len); 54104476Ssam while (off > 0) { 55104476Ssam if (iol == 0) 56104476Ssam panic("iov_copydata: empty in skip"); 57104476Ssam if (off < iov->iov_len) 58104476Ssam break; 59104476Ssam off -= iov->iov_len; 60104476Ssam iol--; 61104476Ssam iov++; 62104476Ssam } 63104476Ssam while (len > 0) { 64104476Ssam if (iol == 0) 65104476Ssam panic("cuio_copydata: empty"); 66104476Ssam count = min(iov->iov_len - off, len); 67104476Ssam bcopy(((caddr_t)iov->iov_base) + off, cp, count); 68104476Ssam len -= count; 69104476Ssam cp += count; 70104476Ssam off = 0; 71104476Ssam iol--; 72104476Ssam iov++; 73104476Ssam } 74104476Ssam} 75104476Ssam 76104476Ssamvoid 77104476Ssamcuio_copyback(struct uio* uio, int off, int len, caddr_t cp) 78104476Ssam{ 79104476Ssam struct iovec *iov = uio->uio_iov; 80104476Ssam int iol = uio->uio_iovcnt; 81104476Ssam unsigned count; 82104476Ssam 83104476Ssam if (off < 0) 84104476Ssam panic("cuio_copyback: off %d < 0", off); 85104476Ssam if (len < 0) 86104476Ssam panic("cuio_copyback: len %d < 0", len); 87104476Ssam while (off > 0) { 88104476Ssam if (iol == 0) 89104476Ssam panic("cuio_copyback: empty in skip"); 90104476Ssam if (off < iov->iov_len) 91104476Ssam break; 92104476Ssam off -= iov->iov_len; 93104476Ssam iol--; 94104476Ssam iov++; 95104476Ssam } 96104476Ssam while (len > 0) { 97104476Ssam if (iol == 0) 98104476Ssam panic("uio_copyback: empty"); 99104476Ssam count = min(iov->iov_len - off, len); 100104476Ssam bcopy(cp, ((caddr_t)iov->iov_base) + off, count); 101104476Ssam len -= count; 102104476Ssam cp += count; 103104476Ssam off = 0; 104104476Ssam iol--; 105104476Ssam iov++; 106104476Ssam } 107104476Ssam} 108104476Ssam 109104476Ssam/* 110104476Ssam * Return a pointer to iov/offset of location in iovec list. 111104476Ssam */ 112104476Ssamstruct iovec * 113104476Ssamcuio_getptr(struct uio *uio, int loc, int *off) 114104476Ssam{ 115104476Ssam struct iovec *iov = uio->uio_iov; 116104476Ssam int iol = uio->uio_iovcnt; 117104476Ssam 118104476Ssam while (loc >= 0) { 119104476Ssam /* Normal end of search */ 120104476Ssam if (loc < iov->iov_len) { 121104476Ssam *off = loc; 122104476Ssam return (iov); 123104476Ssam } 124104476Ssam 125104476Ssam loc -= iov->iov_len; 126104476Ssam if (iol == 0) { 127104476Ssam if (loc == 0) { 128104476Ssam /* Point at the end of valid data */ 129104476Ssam *off = iov->iov_len; 130104476Ssam return (iov); 131104476Ssam } else 132104476Ssam return (NULL); 133104476Ssam } else { 134104476Ssam iov++, iol--; 135104476Ssam } 136104476Ssam } 137104476Ssam 138104476Ssam return (NULL); 139104476Ssam} 140