The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/opencrypto/criov.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason 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/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/11.2/sys/opencrypto/criov.c 329343 2018-02-15 21:27:24Z jhb $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/proc.h>
   36 #include <sys/errno.h>
   37 #include <sys/malloc.h>
   38 #include <sys/kernel.h>
   39 #include <sys/mbuf.h>
   40 #include <sys/uio.h>
   41 
   42 #include <opencrypto/cryptodev.h>
   43 
   44 /*
   45  * This macro is only for avoiding code duplication, as we need to skip
   46  * given number of bytes in the same way in three functions below.
   47  */
   48 #define CUIO_SKIP()     do {                                            \
   49         KASSERT(off >= 0, ("%s: off %d < 0", __func__, off));           \
   50         KASSERT(len >= 0, ("%s: len %d < 0", __func__, len));           \
   51         while (off > 0) {                                               \
   52                 KASSERT(iol >= 0, ("%s: empty in skip", __func__));     \
   53                 if (off < iov->iov_len)                                 \
   54                         break;                                          \
   55                 off -= iov->iov_len;                                    \
   56                 iol--;                                                  \
   57                 iov++;                                                  \
   58         }                                                               \
   59 } while (0)
   60 
   61 void
   62 cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
   63 {
   64         struct iovec *iov = uio->uio_iov;
   65         int iol = uio->uio_iovcnt;
   66         unsigned count;
   67 
   68         CUIO_SKIP();
   69         while (len > 0) {
   70                 KASSERT(iol >= 0, ("%s: empty", __func__));
   71                 count = min(iov->iov_len - off, len);
   72                 bcopy(((caddr_t)iov->iov_base) + off, cp, count);
   73                 len -= count;
   74                 cp += count;
   75                 off = 0;
   76                 iol--;
   77                 iov++;
   78         }
   79 }
   80 
   81 void
   82 cuio_copyback(struct uio* uio, int off, int len, c_caddr_t cp)
   83 {
   84         struct iovec *iov = uio->uio_iov;
   85         int iol = uio->uio_iovcnt;
   86         unsigned count;
   87 
   88         CUIO_SKIP();
   89         while (len > 0) {
   90                 KASSERT(iol >= 0, ("%s: empty", __func__));
   91                 count = min(iov->iov_len - off, len);
   92                 bcopy(cp, ((caddr_t)iov->iov_base) + off, count);
   93                 len -= count;
   94                 cp += count;
   95                 off = 0;
   96                 iol--;
   97                 iov++;
   98         }
   99 }
  100 
  101 /*
  102  * Return the index and offset of location in iovec list.
  103  */
  104 int
  105 cuio_getptr(struct uio *uio, int loc, int *off)
  106 {
  107         int ind, len;
  108 
  109         ind = 0;
  110         while (loc >= 0 && ind < uio->uio_iovcnt) {
  111                 len = uio->uio_iov[ind].iov_len;
  112                 if (len > loc) {
  113                         *off = loc;
  114                         return (ind);
  115                 }
  116                 loc -= len;
  117                 ind++;
  118         }
  119 
  120         if (ind > 0 && loc == 0) {
  121                 ind--;
  122                 *off = uio->uio_iov[ind].iov_len;
  123                 return (ind);
  124         }
  125 
  126         return (-1);
  127 }
  128 
  129 /*
  130  * Apply function f to the data in an iovec list starting "off" bytes from
  131  * the beginning, continuing for "len" bytes.
  132  */
  133 int
  134 cuio_apply(struct uio *uio, int off, int len, int (*f)(void *, void *, u_int),
  135     void *arg)
  136 {
  137         struct iovec *iov = uio->uio_iov;
  138         int iol = uio->uio_iovcnt;
  139         unsigned count;
  140         int rval;
  141 
  142         CUIO_SKIP();
  143         while (len > 0) {
  144                 KASSERT(iol >= 0, ("%s: empty", __func__));
  145                 count = min(iov->iov_len - off, len);
  146                 rval = (*f)(arg, ((caddr_t)iov->iov_base) + off, count);
  147                 if (rval)
  148                         return (rval);
  149                 len -= count;
  150                 off = 0;
  151                 iol--;
  152                 iov++;
  153         }
  154         return (0);
  155 }
  156 
  157 void
  158 crypto_copyback(int flags, caddr_t buf, int off, int size, c_caddr_t in)
  159 {
  160 
  161         if ((flags & CRYPTO_F_IMBUF) != 0)
  162                 m_copyback((struct mbuf *)buf, off, size, in);
  163         else if ((flags & CRYPTO_F_IOV) != 0)
  164                 cuio_copyback((struct uio *)buf, off, size, in);
  165         else
  166                 bcopy(in, buf + off, size);
  167 }
  168 
  169 void
  170 crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  171 {
  172 
  173         if ((flags & CRYPTO_F_IMBUF) != 0)
  174                 m_copydata((struct mbuf *)buf, off, size, out);
  175         else if ((flags & CRYPTO_F_IOV) != 0)
  176                 cuio_copydata((struct uio *)buf, off, size, out);
  177         else
  178                 bcopy(buf + off, out, size);
  179 }
  180 
  181 int
  182 crypto_apply(int flags, caddr_t buf, int off, int len,
  183     int (*f)(void *, void *, u_int), void *arg)
  184 {
  185         int error;
  186 
  187         if ((flags & CRYPTO_F_IMBUF) != 0)
  188                 error = m_apply((struct mbuf *)buf, off, len, f, arg);
  189         else if ((flags & CRYPTO_F_IOV) != 0)
  190                 error = cuio_apply((struct uio *)buf, off, len, f, arg);
  191         else
  192                 error = (*f)(arg, buf + off, len);
  193         return (error);
  194 }
  195 
  196 int
  197 crypto_mbuftoiov(struct mbuf *mbuf, struct iovec **iovptr, int *cnt,
  198     int *allocated)
  199 {
  200         struct iovec *iov;
  201         struct mbuf *m, *mtmp;
  202         int i, j;
  203 
  204         *allocated = 0;
  205         iov = *iovptr;
  206         if (iov == NULL)
  207                 *cnt = 0;
  208 
  209         m = mbuf;
  210         i = 0;
  211         while (m != NULL) {
  212                 if (i == *cnt) {
  213                         /* we need to allocate a larger array */
  214                         j = 1;
  215                         mtmp = m;
  216                         while ((mtmp = mtmp->m_next) != NULL)
  217                                 j++;
  218                         iov = malloc(sizeof *iov * (i + j), M_CRYPTO_DATA,
  219                             M_NOWAIT);
  220                         if (iov == NULL)
  221                                 return ENOMEM;
  222                         *allocated = 1;
  223                         *cnt = i + j;
  224                         memcpy(iov, *iovptr, sizeof *iov * i);
  225                 }
  226 
  227                 iov[i].iov_base = m->m_data;
  228                 iov[i].iov_len = m->m_len;
  229 
  230                 i++;
  231                 m = m->m_next;
  232         }
  233 
  234         if (*allocated)
  235                 KASSERT(*cnt == i, ("did not allocate correct amount: %d != %d",
  236                     *cnt, i));
  237 
  238         *iovptr = iov;
  239         *cnt = i;
  240         return 0;
  241 }

Cache object: 2870f5f96885bb20c8d4d8fd6917b6b5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.