226 lines
4.3 KiB
C
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 */
|
|
};
|