criov.c revision 116191
1104476Ssam/*      $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $	*/
2104476Ssam
3104476Ssam/*
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 116191 2003-06-11 05:57:50Z obrien $");
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