Annotation of sys/dev/firmload.c, Revision 1.1
1.1 ! nbrk 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: }
CVSweb