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