STATUS: 33%

0000 T _bmap		not compatible
    0274 T _passc		not compatible
    0306 T _cpass		not compatible
    03a2 T _nodev		compatible
    03ac T _nulldev		compatible
    03ae T _timeout		not compatible
This commit is contained in:
Oliver Lehmann 2008-05-17 14:49:47 +00:00
parent b1a6a046f7
commit b696e0cca6
1 changed files with 250 additions and 0 deletions

250
WEGA/src/uts/sys/subr.c Normal file
View File

@ -0,0 +1,250 @@
/******************************************************************************
*******************************************************************************
W E G A - Quelle
KERN 3.2 Modul: sysent.c
Bearbeiter: O. Lehmann
Datum: 09.05.08
Version: 1.0
*******************************************************************************
******************************************************************************/
char subrwstr[] = "@[$]subr.c Rev : 4.1 08/27/83 11:58:09";
#include <sys/param.h>
#include <sys/sysinfo.h>
#include <sys/systm.h>
#include <sys/inode.h>
#include <sys/dir.h>
#include <sys/s.out.h>
#include <sys/mmu.h>
#include <sys/user.h>
#include <sys/buf.h>
#include <sys/callo.h>
/*
* Bmap defines the structure of file system storage
* by returning the physical block number on a device given the
* inode and the logical block number in a file.
* When convenient, it also leaves the physical
* block number of the next block of the file in rablock
* for use in read-ahead.
*/
daddr_t
bmap(ip, bn, rwflg)
register struct inode *ip;
daddr_t bn;
{
register int i;
register struct buf *bp;
struct buf *nbp;
register int j;
int sh;
daddr_t nb, *bap;
dev_t dev;
dev = ip->i_dev;
rablock = 0;
/*
* blocks 0..NADDR-4 are direct blocks
*/
if(bn < NADDR-3) {
i = bn;
nb = ip->i_addr[i];
if(nb == 0) {
if(rwflg==B_READ || (bp = alloc(dev))==NULL)
return((daddr_t)-1);
nb = bp->b_blkno;
bdwrite(bp);
ip->i_addr[i] = nb;
ip->i_flag |= IUPD|ICHG;
}
if(i < NADDR-4)
rablock = ip->i_addr[i+1];
return(nb);
}
/*
* addresses NADDR-3, NADDR-2, and NADDR-1
* have single, double, triple indirect blocks.
* the first step is to determine
* how many levels of indirection.
*/
sh = 0;
nb = 1;
bn -= NADDR-3;
for(j=3; j>0; j--) {
sh += NSHIFT;
nb <<= NSHIFT;
if(bn < nb)
break;
bn -= nb;
}
if(j == 0) {
u.u_error = EFBIG;
return((daddr_t)0);
}
/*
* fetch the address from the inode
*/
nb = ip->i_addr[NADDR-j];
if(nb == 0) {
if(rwflg==B_READ || (bp = alloc(dev))==NULL)
return((daddr_t)-1);
nb = bp->b_blkno;
bdwrite(bp);
ip->i_addr[NADDR-j] = nb;
ip->i_flag |= IUPD|ICHG;
}
/*
* fetch through the indirect blocks
*/
for(; j<=3; j++) {
bp = bread(dev, nb);
if(bp->b_flags & B_ERROR) {
brelse(bp);
return((daddr_t)0);
}
bap = bp->b_un.b_daddr;
sh -= NSHIFT;
i = (bn>>sh) & NMASK;
nb = bap[i];
if(nb == 0) {
if(rwflg==B_READ || (nbp = alloc(dev))==NULL) {
brelse(bp);
return((daddr_t)-1);
}
nb = nbp->b_blkno;
bdwrite(nbp);
bap[i] = nb;
bdwrite(bp);
} else
brelse(bp);
}
/*
* calculate read-ahead.
*/
if(i < NINDIR-1)
rablock = bap[i+1];
return(nb);
}
/*
* Pick up and return the next character from the user's
* write call at location u_base;
* update u_base, u_count, and u_offset. Return -1
* when u_count is exhausted. u_base is in the user's
* address space unless u_segflg is set.
*/
cpass()
{
register c, id;
if(u.u_count == 0)
return(-1);
if((id = u.u_segflg) == 1)
c = *u.u_base;
else
if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) {
u.u_error = EFAULT;
return(-1);
}
u.u_count--;
u.u_offset++;
u.u_base++;
return(c&0377);
}
/*
* Routine which sets a user error; placed in
* illegal entries in the bdevsw and cdevsw tables.
*/
nodev()
{
u.u_error = ENODEV;
}
/*
* Null routine; placed in insignificant entries
* in the bdevsw and cdevsw tables.
*/
nulldev()
{
}
/*
* Pass back c to the user at his location u_base;
* update u_base, u_count, and u_offset. Return -1
* on the last character of the user's read.
* u_base is in the user address space unless u_segflg is set.
*/
passc(c)
register c;
{
register id;
if((id = u.u_segflg) == 1)
*u.u_base = c;
else
if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) {
u.u_error = EFAULT;
return(-1);
}
u.u_count--;
u.u_offset++;
u.u_base++;
return(u.u_count == 0? -1: 0);
}
/*
* timeout is called to arrange that fun(arg) is called in tim/HZ seconds.
* An entry is sorted into the callout structure.
* The time in each structure entry is the number of HZ's more
* than the previous entry. In this way, decrementing the
* first entry has the effect of updating all entries.
*
* The panic is there because there is nothing
* intelligent to be done if an entry won't fit.
*/
timeout(fun, arg, tim)
int (*fun)();
caddr_t arg;
{
register struct callo *p1, *p2;
register int t;
int s;
t = tim;
p1 = &callout[0];
s = dvi();
while(p1->c_func != 0 && p1->c_time <= t) {
t -= p1->c_time;
p1++;
}
if (p1 >= &callout[NCALL-1])
panic("Timeout table overflow");
p1->c_time -= t;
p2 = p1;
while(p2->c_func != 0)
p2++;
while(p2 >= p1) {
(p2+1)->c_time = p2->c_time;
(p2+1)->c_func = p2->c_func;
(p2+1)->c_arg = p2->c_arg;
p2--;
}
p1->c_time = t;
p1->c_func = fun;
p1->c_arg = arg;
rvi(s);
}