Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Mar 2000 11:06:05 -0500 (EST)
From:      Darrell Anderson <anderson@cs.duke.edu>
To:        garycor@home.com
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: How to read a file from a device driver?
Message-ID:  <200003201606.LAA12793@cold.cs.duke.edu>

next in thread | raw e-mail | index | archive | help
On Fri, 17 Mar 2000, Gary T. Corcoran wrote:
>
> I'm trying to initialize a network device, and I'm trying to download
> code *into* my device from some binary system files.  There is no "user
> space" or user process, for that matter, to deal with at this point. I
> just want to (at this step) open a file(s) directly from my device
> driver, read the file(s), and download the relevant parts to my device.

sysctl might also do the trick.  to answer your question, here's some code:

struct vnode *
vp_open(char *fname)
{
        struct vnode *vp;
        struct nameidata nd;
	int error;

        NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, fname, curproc);
        if ((error = vn_open(&nd, FREAD|FWRITE|O_CREAT, 
                             S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) != 0) {
                printf("vp_open: failed for %s with error %d\n", fname, error);
                return NULL;
        }
        vp = nd.ni_vp;
        NDFREE(&nd, NDF_ONLY_PNBUF);
        VOP_UNLOCK(vp, 0, curproc);
        if (vp->v_type != VREG) {
                printf("vp_open: %s not a regular file\n", fname);
                vn_close(vp, FREAD|FWRITE, curproc->p_ucred, curproc);
                return NULL;
        }
        return vp;      
}

int
vp_close(struct vnode *vp)
{
        int error;

        if (vp == NULL) {
                printf("vp_close: caller supplied NULL vp\n");
                return ENOENT;
        }
	if ((error = vn_close(vp, FREAD|FWRITE, curproc->p_ucred, curproc)) {
                printf("vp_close: vn_close error %d\n", error);
        }
        return error;
}

int
vp_read(struct vnode *vp, off_t offset, int len, caddr_t data)
{
        struct iovec iov;
        struct uio uio;
        int error;

        iov.iov_base = data;
        iov.iov_len = len;
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
        uio.uio_offset = offset;
        uio.uio_resid = iov.iov_len;
        uio.uio_segflg = UIO_SYSSPACE;
        uio.uio_rw = UIO_READ;
        uio.uio_procp = NULL;

        if ((error = vn_lock(vp, LK_SHARED|LK_RETRY, curproc)) == 0) {
                error = VOP_READ(vp, &uio, IO_SYNC, curproc->p_ucred);
                VOP_UNLOCK(vp, 0, curproc);
                if (uio.uio_resid) {
                        bzero(data + (len - uio.uio_resid), uio.uio_resid);
                }
        }
        return error;
}

-Darrell
-- 
Department of Computer Science, Duke University, Durham, NC 27708-0129
Darrell Anderson, anderson@cs.duke.edu, http://www.cs.duke.edu/~anderson


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003201606.LAA12793>