Nsys/sys/nsys/dmr/bio.c
#include "/sys/nsys/param.h"
#include "/sys/nsys/user.h"
#include "/sys/nsys/buf.h"
#include "/sys/nsys/conf.h"
#include "/sys/nsys/systm.h"
char buffers[NBUF][512];
struct buf swbuf;
struct { int int;};
#define PS 0177776
#define JTM 3
bread(dev, blkno)
{
struct buf *bp;
register struct buf *rbp;
rbp = bp = getblk(dev, blkno);
if (rbp->b_flags&B_DONE)
return(rbp);
rbp->b_flags =| B_READ;
rbp->b_wcount = -256;
(*bdevsw[dev.d_major].d_strategy)(rbp);
iowait(bp);
return(bp);
}
bwrite(bp)
struct buf *bp;
{
register struct buf *rbp;
rbp = bp;
rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
rbp->b_wcount = -256;
(*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp);
if ((bp->b_flags&B_ASYNC) == 0) {
iowait(bp);
brelse(bp);
}
}
bdwrite(bp)
struct buf *bp;
{
register struct buf *rbp;
rbp = bp;
if (rbp->b_dev.d_major == JTM)
bawrite(rbp);
else {
rbp->b_flags =| B_DELWRI | B_DONE;
brelse(rbp);
}
}
bawrite(bp)
struct buf *bp;
{
bp->b_flags =| B_ASYNC;
bwrite(bp);
}
brelse(bp)
struct buf *bp;
{
register struct buf *rbp;
register int sps;
if (bp->b_flags&B_WANTED)
wakeup(bp);
if (bfreelist.b_flags&B_WANTED) {
bfreelist.b_flags =& ~B_WANTED;
wakeup(&bfreelist);
}
rbp = bp;
sps = PS->int;
PS->int =| 0300;
rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC);
bfreelist.av_back->av_forw = rbp;
rbp->av_back = bfreelist.av_back;
bfreelist.av_back = rbp;
rbp->av_forw = &bfreelist;
PS->int = sps;
}
getblk(dev, blkno)
{
register struct buf *bp;
struct buf *bp1;
struct devtab *dp;
register struct devtab *rdp;
extern lbolt;
loop:
if (dev < 0)
dp = &bfreelist;
else {
dp = &devtab[dev.d_major];
for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) {
if (bp->b_blkno!=blkno || bp->b_dev!=dev)
continue;
if (bp->b_flags&B_BUSY) {
bp->b_flags =| B_WANTED;
sleep(bp, PRIBIO);
goto loop;
}
bp1 = bp;
notavail(bp);
return(bp1);
}
}
spl6();
if (bfreelist.av_forw == bfreelist.av_back) {
bfreelist.b_flags =| B_WANTED;
sleep(&bfreelist, PRIBIO);
spl0();
goto loop;
}
spl0();
notavail(bp1 = bfreelist.av_forw);
bp = bp1;
if (bp->b_flags & B_DELWRI) {
bp->b_flags =| B_ASYNC;
bwrite(bp);
goto loop;
}
rdp = dp;
bp->b_flags = B_BUSY | B_RELOC;
bp->b_back->b_forw = bp->b_forw;
bp->b_forw->b_back = bp->b_back;
bp->b_forw = rdp->b_forw;
bp->b_back = rdp;
rdp->b_forw->b_back = bp;
rdp->b_forw = bp;
bp->b_dev = dev;
bp->b_blkno = blkno;
return(bp);
}
iowait(bp)
struct buf *bp;
{
spl6();
while ((bp->b_flags&B_DONE)==0)
sleep(bp, PRIBIO);
spl0();
if (bp->b_flags&B_ERROR)
u.u_error = EIO;
}
notavail(bp)
struct buf *bp;
{
register struct buf *rbp;
register int sps;
rbp = bp;
sps = PS->int;
PS->int =| 0300;
rbp->av_back->av_forw = rbp->av_forw;
rbp->av_forw->av_back = rbp->av_back;
rbp->b_flags =| B_BUSY;
PS->int = sps;
}
iodone(bp)
struct buf *bp;
{
register struct buf *rbp;
rbp = bp;
rbp->b_flags =| B_DONE;
if (rbp->b_flags&B_ASYNC)
brelse(rbp);
else {
rbp->b_flags =& ~B_WANTED;
wakeup(rbp);
}
}
clrbuf(bp)
int *bp;
{
register *p, *ep;
p = bp->b_addr;
for (ep = p+256; p<ep;)
*p++ = 0;
}
binit()
{
register struct buf *bp;
register struct devtab *dp;
int i;
bfreelist.b_forw = bfreelist.b_back =
bfreelist.av_forw = bfreelist.av_back = &bfreelist;
for (i=0; i<NBUF; i++) {
bp = &buf[i];
bp->b_dev = -1;
bp->b_addr = buffers[i];
bp->b_back = &bfreelist;
bp->b_forw = bfreelist.b_forw;
bfreelist.b_forw->b_back = bp;
bfreelist.b_forw = bp;
brelse(bp);
}
for (dp = devtab; dp < &devtab[NMAJ]; dp++) {
dp->b_forw = dp;
dp->b_back = dp;
}
}
/*
* Device start routine for disks
*/
#define IENABLE 0100
#define WCOM 02
#define RCOM 04
#define GO 01
devstart(bp, devloc, devblk)
struct buf *bp;
int *devloc;
{
register int *dp;
register struct buf *rbp;
register int com;
dp = devloc;
rbp = bp;
*dp = devblk; /* block address */
*--dp = rbp->b_addr; /* buffer address */
*--dp = rbp->b_wcount; /* word count */
com = IENABLE|GO | rbp->b_flags&B_XMEM;
if (rbp->b_flags&B_READ) /* command + x-mem */
com =| RCOM;
else
com =| WCOM;
*--dp = com;
}
/*
* swap I/O
*/
swap(blkno, coreaddr, count, rdflg)
{
spl6();
while (swbuf.b_flags&B_BUSY) {
swbuf.b_flags =| B_WANTED;
sleep(&swbuf.b_flags, PSWP);
}
swbuf.b_flags = B_BUSY | rdflg;
swbuf.b_dev = SWAPDEV;
swbuf.b_wcount = - (count<<5); /* 32 w/block */
swbuf.b_blkno = blkno;
swbuf.b_addr = coreaddr<<6; /* 64 b/block */
swbuf.b_flags =| (coreaddr>>6)&B_XMEM;
(*bdevsw[SWAPDEV>>8].d_strategy)(&swbuf);
spl6();
while((swbuf.b_flags&B_DONE)==0)
sleep(&swbuf, PSWP);
if (swbuf.b_flags&B_WANTED)
wakeup(&swbuf.b_flags);
spl0();
swbuf.b_flags =& ~(B_BUSY|B_WANTED);
return(swbuf.b_flags&B_ERROR);
}
/*
* make sure all write-behind blocks
* on dev (or NODEV for all)
* are flushed out.
*/
bflush(dev)
{
struct buf *nbp, *xbp;
register struct buf *bp;
spl6();
for (nbp = bfreelist.av_forw; nbp != &bfreelist; ) {
bp = nbp;
nbp = bp->av_forw;
if (bp->b_flags&B_DELWRI && (dev == -1||dev==bp->b_dev)) {
bp->b_flags =| B_ASYNC;
xbp = bp;
notavail(bp);
bwrite(xbp);
}
}
spl0();
}