2021-10-11 18:37:13 -03:00

226 lines
4.3 KiB
C

#ifndef lint
static char sccsid[] = "@(#)bdev_vnodeops.c 1.1 94/10/31 SMI";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <sys/param.h>
#include "boot/systm.h"
#include <sys/user.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/vfs.h>
#include "boot/vnode.h"
#include <sys/bootconf.h>
#include <ufs/fs.h>
#include "boot/inode.h"
#include <stand/saio.h>
#include "boot/iob.h"
#include <mon/sunromvec.h>
#include "boot/conf.h"
extern struct bdevlist bdevlist[];
extern struct iob iob[NFILES];
#ifdef DUMP_DEBUG
static int dump_debug = 10;
#endif /* DUMP_DEBUG */
/*
* Convert a block dev into a vnode pointer suitable for bio.
*/
struct dev_vnode {
struct vnode dv_vnode;
struct dev_vnode *dv_link;
} *dev_vnode_headp;
bdev_badop()
{
#ifdef DUMP_DEBUG
dprint(dump_debug, 10, "bdev_badop()\n");
#endif /* DUMP_DEBUG */
panic("bdev_badop");
}
/*ARGSUSED*/
int
bdev_open(vpp, flag, cred)
struct vnode **vpp;
int flag;
struct ucred *cred;
{
#ifdef DUMP_DEBUG
dprint(dump_debug, 6, "bdev_open(vpp 0x%x flag 0x%x cred 0x%x)\n",
vpp, flag, cred);
#endif /* DUMP_DEBUG */
/*
* For the moment, all the open operations are being
* carried out on bdevvp() below. Maybe we should
* move them up here.
*/
return(0);
}
int
bdev_strategy(bp)
struct buf *bp;
{
struct vnode *vp;
int blkno, size;
struct iob *fp;
struct saioreq *sip;
#ifdef DUMP_DEBUG
dprint(dump_debug, 6, "bdev_strategy(bp 0x%x)\n", bp);
#endif /* DUMP_DEBUG */
vp = bp->b_vp;
blkno = bp->b_blkno;
size = bp->b_bcount;
fp = (struct iob *)vp->v_data;
sip = &(fp->i_si);
/*
* Set up the parameters of the read.
*/
sip->si_ma = bp->b_un.b_addr;
sip->si_bn = blkno;
sip->si_cc = size;
if (bp->b_flags | B_READ) {
if (devread(sip) < 0)
printf ("bdev_strategy: bad device read\n");
bp->b_flags |= B_DONE;
} else {
#ifdef DUMP_DEBUG
dprint(dump_debug, 0, "bdev_strategy: sorry, no write\n");
#endif /* DUMP_DEBUG */
}
return (0);
}
struct vnodeops dev_vnode_ops = {
bdev_open,
bdev_badop /* bdev_close */,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop /* bdev_getattr */,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop /* bdev_inactive */,
bdev_badop,
bdev_strategy,
bdev_badop,
bdev_badop,
bdev_badop,
bdev_badop,
/* bdev_dump, */
};
/*
* Convert a block device into a special purpose vnode for bio
*/
struct vnode *
bdevvp(dev)
dev_t dev;
{
register struct dev_vnode *dvp;
register struct dev_vnode *endvp;
register struct boottab *dp;
int lfdesc;
register struct iob *lfile;
int status;
#ifdef DUMP_DEBUG
dprint(dump_debug, 6, "bdevvp(dev 0x%x)\n", dev);
#endif /* DUMP_DEBUG */
endvp = (struct dev_vnode *)0;
for (dvp = dev_vnode_headp; dvp; dvp = dvp->dv_link) {
if (dvp->dv_vnode.v_rdev == dev) {
VN_HOLD(&dvp->dv_vnode);
return (&dvp->dv_vnode);
}
endvp = dvp;
}
dvp = (struct dev_vnode *)
kmem_alloc((u_int)sizeof (struct dev_vnode));
bzero((caddr_t)dvp, sizeof (struct dev_vnode));
dvp->dv_vnode.v_count = 1;
dvp->dv_vnode.v_op = &dev_vnode_ops;
dvp->dv_vnode.v_rdev = dev;
if (endvp != (struct dev_vnode *)0) {
endvp->dv_link = dvp;
} else {
dev_vnode_headp = dvp;
}
/*
* In addition to creating the dev-vnode, we create
* a file table entry and sip and leave the vnode
* pointing at them
*/
lfdesc = getiob();
lfile = &iob[lfdesc];
/*
* Find the devsw table entry for the device,
* and open it.
*/
dp = bdevlist[major(dev)].bl_driver;
lfile->i_boottab = dp;
lfile->i_ino.i_dev = dev;
status = opendev(lfdesc, lfile, 0);
if (status == -1) {
printf ("bdevvp: bad open\n");
return ((struct vnode *)-1);
} else
/*
* this will only happen on v_romvec_version > 0
*/
if (status == -2)
return ((struct vnode *)-1);
/*
* Make the vnode point at the iob.
*/
dvp->dv_vnode.v_data = (caddr_t)lfile;
#ifdef DUMP_DEBUG
dprint(dump_debug, 6, "bdevvp: returning &dvp->dv_vnode 0x%x\n",
&dvp->dv_vnode);
#endif /* DUMP_DEBUG */
return (&dvp->dv_vnode);
}
struct vfsops bdev_vfsops = {
bdev_badop, /* mount */
bdev_badop, /* unmount */
bdev_badop, /* root */
bdev_badop, /* statfs */
bdev_badop, /* sync */
bdev_badop, /* vget */
bdev_badop, /* mountroot */
bdev_badop /* bdev_swapvp */, /* swapvp */
};