root/dev/firmload.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. loadfirmware

    1 /*      $OpenBSD: firmload.c,v 1.8 2006/06/27 03:51:29 pedro Exp $      */
    2 
    3 /*
    4  * Copyright (c) 2004 Theo de Raadt <deraadt@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/syslimits.h>
   22 #include <sys/time.h>
   23 #include <sys/namei.h>
   24 #include <sys/vnode.h>
   25 #include <sys/mount.h>
   26 #include <sys/errno.h>
   27 #include <sys/malloc.h>
   28 #include <sys/proc.h>
   29 #include <sys/device.h>
   30 
   31 int
   32 loadfirmware(const char *name, u_char **bufp, size_t *buflen)
   33 {
   34         struct proc *p = curproc;
   35         struct nameidata nid;
   36         char *path, *ptr;
   37         struct iovec iov;
   38         struct uio uio;
   39         struct vattr va;
   40         int error;
   41 
   42         if (!rootvp || !vcount(rootvp))
   43                 return (EIO);
   44 
   45         path = malloc(MAXPATHLEN, M_TEMP, M_NOWAIT);
   46         if (path == NULL)
   47                 return (ENOMEM);
   48                 
   49         if (snprintf(path, MAXPATHLEN, "/etc/firmware/%s", name) >=
   50             MAXPATHLEN) {
   51                 error = ENAMETOOLONG;
   52                 goto err;
   53         }
   54 
   55         NDINIT(&nid, LOOKUP, NOFOLLOW|LOCKLEAF, UIO_SYSSPACE, path, p);
   56         error = namei(&nid);
   57         if (error)
   58                 goto err;
   59         error = VOP_GETATTR(nid.ni_vp, &va, p->p_ucred, p);
   60         if (error)
   61                 goto fail;
   62         if (nid.ni_vp->v_type != VREG || va.va_size == 0) {
   63                 error = EINVAL;
   64                 goto fail;
   65         }
   66         if (va.va_size > FIRMWARE_MAX) {
   67                 error = E2BIG;
   68                 goto fail;
   69         }
   70         ptr = malloc(va.va_size, M_DEVBUF, M_NOWAIT);
   71         if (ptr == NULL) {
   72                 error = ENOMEM;
   73                 goto fail;
   74         }
   75 
   76         iov.iov_base = ptr;
   77         iov.iov_len = va.va_size;
   78         uio.uio_iov = &iov;
   79         uio.uio_iovcnt = 1;
   80         uio.uio_offset = 0;
   81         uio.uio_resid = va.va_size;
   82         uio.uio_segflg = UIO_SYSSPACE;
   83         uio.uio_rw = UIO_READ;
   84         uio.uio_procp = p;
   85 
   86         error = VOP_READ(nid.ni_vp, &uio, 0, p->p_ucred);
   87 
   88         if (error == 0) {
   89                 *bufp = ptr;
   90                 *buflen = va.va_size;
   91         } else
   92                 free(ptr, M_DEVBUF);
   93 
   94 fail:
   95         vput(nid.ni_vp);
   96 err:
   97         if (path)
   98                 free(path, M_TEMP);
   99         return (error);
  100 }

/* [<][>][^][v][top][bottom][index][help] */