M boot/local.c => boot/local.c +1 -1
@@ 7,7 7,7 @@ static char *disk;
void
configlocal(Method *mp)
{
- disk = mp->arg;
+ disk = *sys ? sys : mp->arg;
USED(mp);
}
A pc/devconfig.c => pc/devconfig.c +215 -0
@@ 0,0 1,215 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#include <libg.h>
+#include <gnot.h>
+#include "devtab.h"
+#include "vga.h"
+
+/*
+ * Driver for various VGA cards
+ */
+
+char monitor[NAMELEN]; /* monitor name and type */
+char vgacard[NAMELEN]; /* vga card type */
+struct screeninfo {
+ int maxx, maxy; /* current bits per screen */
+ int packed; /* 0=planar, 1=packed */
+ int interlaced; /* != 0 if interlaced */
+} screeninfo;
+
+enum {
+ Qdir= 0,
+ Qvgamonitor= 1,
+ Qvgasize= 2,
+ Qvgatype= 3,
+ Qvgaport= 4,
+ Qvgamem= 5,
+ Qmouse= 6,
+ Nvga= 6,
+};
+
+Dirtab vgadir[]={
+ "mouseconf", {Qmouse}, 0, 0666,
+ "vgamonitor", {Qvgamonitor}, 0, 0666,
+ "vgatype", {Qvgatype}, 0, 0666,
+ "vgasize", {Qvgasize}, 0, 0666,
+ "vgaport", {Qvgaport}, 0, 0666,
+ "vgamem", {Qvgamem}, 0, 0666,
+};
+
+/* a routine from ../port/devcons.c */
+extern int readstr(ulong, char *, ulong, char *);
+
+void
+configsetup(void) {
+}
+
+void
+configreset(void) {
+ strcpy(monitor, "generic");
+ strcpy(vgacard, "generic");
+ screeninfo.maxx = 640;
+ screeninfo.maxy = 480;
+ screeninfo.packed = 0;
+ screeninfo.interlaced = 0;
+}
+
+void
+configinit(void)
+{
+}
+
+Chan*
+configattach(char *upec)
+{
+ return devattach('v', upec);
+}
+
+Chan*
+configclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+configwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, vgadir, Nvga, devgen);
+}
+
+void
+configstat(Chan *c, char *dp)
+{
+ devstat(c, dp, vgadir, Nvga, devgen);
+}
+
+Chan*
+configopen(Chan *c, int omode)
+{
+ return devopen(c, omode, vgadir, Nvga, devgen);
+}
+
+void
+configcreate(Chan *c, char *name, int omode, ulong perm)
+{
+ USED(c, name, omode, perm);
+ error(Eperm);
+}
+
+void
+configclose(Chan *c)
+{
+ USED(c);
+}
+
+long
+configread(Chan *c, void *buf, long n, ulong offset)
+{
+ char obuf[60];
+ int port;
+ uchar *cp = buf;
+
+ switch(c->qid.path&~CHDIR){
+ case Qdir:
+ return devdirread(c, buf, n, vgadir, Nvga, devgen);
+ case Qvgamonitor:
+ return readstr(offset, buf, n, monitor);
+ case Qvgatype:
+ return readstr(offset, buf, n, vgacard);
+ case Qvgasize:
+ sprint(obuf, "%d %d",
+ gscreen.r.max.x, gscreen.r.max.y);
+ return readstr(offset, buf, n, obuf);
+ case Qvgaport:
+ if (offset + n >= 0x8000)
+ error(Ebadarg);
+ for (port=offset; port<offset+n; port++)
+ *cp++ = inb(port);
+ return n;
+ case Qvgamem:
+ if (offset > 0x10000)
+ return 0;
+ if (offset + n > 0x10000)
+ n = 0x10000 - offset;
+ memmove(cp, (void *)(SCREENMEM+offset), n);
+ return n;
+ }
+ error(Eperm);
+ return 0;
+}
+
+long
+configwrite(Chan *c, void *buf, long n, ulong offset)
+{
+ char cbuf[20], *cp;
+ int port, maxx, maxy;
+
+ switch(c->qid.path&~CHDIR){
+ case Qdir:
+ error(Eperm);
+ case Qvgamonitor:
+ error(Eperm);
+ case Qvgatype:
+ error(Eperm);
+ case Qvgasize:
+ if(offset != 0)
+ error(Ebadarg);
+ if(n >= sizeof(cbuf))
+ n = sizeof(cbuf) - 1;
+ memmove(cbuf, buf, n);
+ cbuf[n] = 0;
+ cp = cbuf;
+ maxx = strtoul(cp, &cp, 0);
+ maxy = strtoul(cp, &cp, 0);
+ if (maxx == 0 || maxy == 0 ||
+ maxx > 1280 || maxy > 1024)
+ error(Ebadarg);
+ setscreen(maxx, maxy, 1);
+ return n;
+ case Qvgaport:
+ cp = buf;
+ if (offset + n >= 0x8000)
+ error(Ebadarg);
+ for (port=offset; port<offset+n; port++) {
+ outb(port, *cp++);
+ }
+ return n;
+ case Qvgamem:
+ if (offset + n > 0x10000)
+ error(Ebadarg);
+ memmove((void *)(SCREENMEM+offset), buf, n);
+ return n;
+ case Qmouse:
+ if(n >= sizeof(cbuf))
+ n = sizeof(cbuf) - 1;
+ memmove(cbuf, buf, n);
+ cbuf[n] = 0;
+ if(strncmp("accelerated", cbuf, 11) == 0)
+ mouseaccelerate(1);
+ else if(strncmp("linear", cbuf, 6) == 0)
+ mouseaccelerate(0);
+ return n;
+ }
+ error(Eperm);
+ return 0;
+}
+
+void
+configremove(Chan *c)
+{
+ USED(c);
+ error(Eperm);
+}
+
+void
+configwstat(Chan *c, char *dp)
+{
+ USED(c, dp);
+ error(Eperm);
+}
M pc/fns.h => pc/fns.h +1 -0
@@ 37,6 37,7 @@ void ksetpcinfo(void);
void mathinit(void);
void mmuinit(void);
int modem(int);
+void mouseaccelerate(int);
void outb(int, int);
void outss(int, void*, int);
void pmubuzz(int, int);
M pc/kbd.c => pc/kbd.c +18 -1
@@ 214,7 214,7 @@ kbdinit(void)
print("can't initialize mouse\n");
/* turn on mouse acceleration */
- mousecmd(0xE7);
+ mouseaccelerate(0);
break;
case At:
/* enable kbd xfers and interrupts */
@@ 230,6 230,23 @@ kbdinit(void)
}
/*
+ * turn mouse acceleration on/off
+ */
+void
+mouseaccelerate(int on)
+{
+
+ switch(machtype){
+ case Attnsx:
+ if(on)
+ mousecmd(0xE7);
+ else
+ mousecmd(0xE6);
+ break;
+ }
+}
+
+/*
* mouse message is three bytes
*
* byte 0 - 0 0 SDY SDX 1 M R L
M port/chan.c => port/chan.c +8 -4
@@ 306,12 306,13 @@ undomount(Chan *c)
he = &pg->mnthash[MNTHASH];
for(h = pg->mnthash; h < he; h++) {
for(f = *h; f; f = f->hash) {
- for(t = f->mount; t; t = t->next)
+ for(t = f->mount; t; t = t->next) {
if(eqchan(c, t->to, 1)) {
close(c);
c = clone(t->head->from, 0);
break;
}
+ }
}
}
poperror();
@@ 452,13 453,15 @@ namec(char *name, int amode, int omode, ulong perm)
elem = u->elem;
mntok = 1;
isdot = 0;
- if(name[0] == '/'){
+ if(name[0] == '/') {
c = clone(u->slash, 0);
/*
* Skip leading slashes.
*/
name = skipslash(name);
- }else if(name[0] == '#'){
+ }
+ else
+ if(name[0] == '#') {
mntok = 0;
if(name[1]=='M')
error(Enonexist);
@@ 472,7 475,8 @@ namec(char *name, int amode, int omode, ulong perm)
}else
name = nextelem(name, elem);
c = (*devtab[t].attach)(elem);
- }else{
+ }
+ else {
c = clone(u->dot, 0);
name = skipslash(name); /* eat leading ./ */
if(*name == 0)
M port/devcons.c => port/devcons.c +8 -13
@@ 188,15 188,13 @@ pprint(char *fmt, ...)
return 0;
n = sprint(buf, "%s %d: ", u->p->text, u->p->pid);
n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
- qlock(&c->wrl);
- if(waserror()){
- qunlock(&c->wrl);
- return 0;
- }
+
(*devtab[c->type].write)(c, buf, n, c->offset);
+
+ lock(c);
c->offset += n;
- qunlock(&c->wrl);
- poperror();
+ unlock(c);
+
return n;
}
@@ 887,8 885,9 @@ conswrite(Chan *c, void *va, long n, ulong offset)
error(Egreg);
memmove(buf, va, n); /* so we can NUL-terminate */
buf[n] = 0;
+ /* start a pager if not already started */
if(strncmp(buf, "start", 5) == 0){
- kickpager(); /* start a pager if not already started */
+ kickpager();
break;
}
if(cpuserver && strcmp(u->p->user, eve) != 0)
@@ 896,7 895,7 @@ conswrite(Chan *c, void *va, long n, ulong offset)
if(buf[0]<'0' || '9'<buf[0])
error(Ebadarg);
fd = strtoul(buf, 0, 0);
- swc = fdtochan(fd, -1, 1);
+ swc = fdtochan(fd, -1, 1, 0);
setswapchan(swc);
break;
@@ 932,10 931,6 @@ conswstat(Chan *c, char *dp)
error(Eperm);
}
-/*
- * Rand is huge and not worth it here. Be small.
- * Borrowed from the white book.
- */
int
nrand(int n)
{
M port/devdup.c => port/devdup.c +1 -1
@@ 74,7 74,7 @@ dupopen(Chan *c, int omode)
c->offset = 0;
return c;
}
- fdtochan(c->qid.path, openmode(omode), 0); /* error check only */
+ fdtochan(c->qid.path, openmode(omode), 0, 0); /* error check only */
f = u->p->fgrp->fd[c->qid.path];
close(c);
incref(f);
M port/devmnt.c => port/devmnt.c +22 -49
@@ 48,23 48,23 @@ struct Mntalloc
#define MAXRPC (MAXFDATA+MAXMSG)
#define limit(n, max) (n > max ? max : n)
-Chan *mattach(Mnt*, char*, char*);
-Mntrpc *mntralloc(void);
-void mntfree(Mntrpc*);
-int rpcattn(Mntrpc*);
-void mountrpc(Mnt*, Mntrpc*);
-void mountio(Mnt*, Mntrpc*);
-Mnt *mntchk(Chan*);
-void mountmux(Mnt*, Mntrpc*);
-long mntrdwr(int , Chan*, void*,long , ulong);
-int mntflush(Mnt*, Mntrpc*);
-void mntqrm(Mnt*, Mntrpc*);
+Chan* mattach(Mnt*, char*, char*);
+void mntauth(Mnt *, Mntrpc *, char *, ushort);
+Mnt* mntchk(Chan*);
void mntdirfix(uchar*, Chan*);
-void mntgate(Mnt*);
-void mntrpcread(Mnt*, Mntrpc*);
void mntdoclunk(Mnt *, Mntrpc *);
-void mntauth(Mnt *, Mntrpc *, char *, ushort);
+int mntflush(Mnt*, Mntrpc*);
+void mntfree(Mntrpc*);
+void mntgate(Mnt*);
void mntpntfree(Mnt*);
+void mntqrm(Mnt*, Mntrpc*);
+Mntrpc* mntralloc(void);
+long mntrdwr(int , Chan*, void*,long , ulong);
+void mntrpcread(Mnt*, Mntrpc*);
+void mountio(Mnt*, Mntrpc*);
+void mountmux(Mnt*, Mntrpc*);
+void mountrpc(Mnt*, Mntrpc*);
+int rpcattn(Mntrpc*);
enum
{
@@ 203,9 203,9 @@ mattach(Mnt *m, char *spec, char *serv)
void
mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid)
{
+ int i;
Mntrpc *r;
uchar chal[AUTHLEN];
- int i;
r = mntralloc();
if(waserror()) {
@@ 493,8 493,8 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset)
{
Mnt *m;
Mntrpc *r;
- ulong cnt, nr;
char *uba;
+ ulong cnt, nr;
m = mntchk(c);
uba = buf;
@@ 561,23 561,12 @@ mountio(Mnt *m, Mntrpc *r)
/* Transmit a file system rpc */
n = convS2M(&r->request, r->rpc);
if(waserror()) {
- if(!m->mux)
- qunlock(&m->c->wrl);
if(mntflush(m, r) == 0)
nexterror();
}
else {
-
- if(m->mux) {
- if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n)
- error(Emountrpc);
- }
- else {
- qlock(&m->c->wrl);
- if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n)
- error(Emountrpc);
- qunlock(&m->c->wrl);
- }
+ if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n)
+ error(Emountrpc);
poperror();
}
if(m->mux) {
@@ 618,8 607,6 @@ mntrpcread(Mnt *m, Mntrpc *r)
for(;;) {
if(waserror()) {
- if(!m->mux)
- qunlock(&m->c->rdl);
if(mntflush(m, r) == 0) {
if(m->mux == 0)
mntgate(m);
@@ 629,13 616,7 @@ mntrpcread(Mnt *m, Mntrpc *r)
}
r->reply.type = 0;
r->reply.tag = 0;
- if(m->mux)
- n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0);
- else {
- qlock(&m->c->rdl);
- n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0);
- qunlock(&m->c->rdl);
- }
+ n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0);
poperror();
if(n == 0)
continue;
@@ 669,8 650,8 @@ mntgate(Mnt *m)
void
mountmux(Mnt *m, Mntrpc *r)
{
- Mntrpc **l, *q;
char *dp;
+ Mntrpc **l, *q;
lock(m);
l = &m->queue;
@@ 698,8 679,8 @@ mountmux(Mnt *m, Mntrpc *r)
int
mntflush(Mnt *m, Mntrpc *r)
{
- Fcall flush;
int n;
+ Fcall flush;
lock(m);
r->flushtag = m->flushtag++;
@@ 714,20 695,12 @@ mntflush(Mnt *m, Mntrpc *r)
n = convS2M(&flush, r->flush);
if(waserror()) {
- if(!m->mux)
- qunlock(&m->c->wrl);
if(strcmp(u->error, Eintr) == 0)
return 1;
mntqrm(m, r);
return 0;
}
- if(m->mux)
- (*devtab[m->c->type].write)(m->c, r->flush, n, 0);
- else {
- qlock(&m->c->wrl);
- (*devtab[m->c->type].write)(m->c, r->flush, n, 0);
- qunlock(&m->c->wrl);
- }
+ (*devtab[m->c->type].write)(m->c, r->flush, n, 0);
poperror();
return 1;
}
M port/devmux.c => port/devmux.c +1 -1
@@ 465,7 465,7 @@ muxwrite(Chan *c, void *va, long n, ulong offset)
memmove(buf, va, n); /* so we can NUL-terminate */
buf[n] = 0;
fd = strtoul(buf, 0, 0);
- fdtochan(fd, -1, 0); /* error check */
+ fdtochan(fd, -1, 0, 0); /* error check */
m->c = u->p->fgrp->fd[fd];
incref(m->c);
return n;
M port/devscsi.c => port/devscsi.c +48 -0
@@ 326,6 326,7 @@ scsicmd(int dev, int cmdbyte, Scsibuf *b, long size)
cmd->cmdblk[2] = 1;
/* fall through */
case ScsiExtsens:
+ case ScsiInquiry:
cmd->cmdblk[4] = size;
break;
case ScsiGetcap:
@@ 407,6 408,30 @@ scsicap(int dev, void *p)
}
int
+scsiinquiry(int dev, void *p, int size)
+{
+ Scsi *cmd;
+ int status;
+
+ cmd = scsicmd(dev, ScsiInquiry, scsibuf(), size);
+ if(waserror()){
+ scsifree(cmd->b);
+ qunlock(cmd);
+ nexterror();
+ }
+ status = scsiexec(cmd, ScsiIn);
+ memmove(p, cmd->data.base, size);
+ poperror();
+ scsifree(cmd->b);
+ qunlock(cmd);
+ if((status&0xff00) != 0x6000)
+ error(Eio);
+ if(status & 0xFF)
+ scsisense(dev, p);
+ return status&0xff;
+}
+
+int
scsiwp(int dev)
{
Scsi *cmd;
@@ 429,6 454,29 @@ scsiwp(int dev)
}
int
+scsimodesense(int dev, int page, void *p, int size)
+{
+ Scsi *cmd;
+ int status;
+
+ cmd = scsicmd(dev, ScsiModesense, scsibuf(), size);
+ cmd->cmdblk[2] = page;
+ if(waserror()){
+ scsifree(cmd->b);
+ qunlock(cmd);
+ nexterror();
+ }
+ status = scsiexec(cmd, ScsiIn);
+ memmove(p, cmd->data.base, size);
+ poperror();
+ scsifree(cmd->b);
+ qunlock(cmd);
+ if ((status&0xffff) != 0x6000)
+ error(Eio);
+ return status&0xff;
+}
+
+int
scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno)
{
Scsi *cmd;
M port/devsrv.c => port/devsrv.c +1 -12
@@ 207,7 207,6 @@ long
srvwrite(Chan *c, void *va, long n, ulong offset)
{
Srv *sp;
- Fgrp *f;
Chan *c1;
int fd;
char buf[32];
@@ 219,17 218,7 @@ srvwrite(Chan *c, void *va, long n, ulong offset)
buf[n] = 0;
fd = strtoul(buf, 0, 0);
- f = u->p->fgrp;
- lock(f);
- if(waserror()){
- unlock(f);
- nexterror();
- }
- fdtochan(fd, -1, 0); /* error check only */
- c1 = f->fd[fd];
- incref(c1);
- unlock(f);
- poperror();
+ c1 = fdtochan(fd, -1, 0, 1); /* error check only */
qlock(&srvlk);
if(waserror()) {
M port/devwren.c => port/devwren.c +4 -1
@@ 261,7 261,7 @@ wrenpart(int dev)
{
Drive *dp;
Partition *pp;
- uchar buf[32];
+ uchar buf[128];
Scsibuf *b;
char *rawpart, *line[Npart+1], *field[3];
ulong n;
@@ 294,6 294,9 @@ wrenpart(int dev)
pp->start = dp->p[0].end - 1;
pp->end = dp->p[0].end;
+ scsiinquiry(dev, buf, sizeof buf);
+ if(memcmp(&buf[8], "INSITE I325VM *F", 24) == 0)
+ scsimodesense(dev, 0x2e, buf, 0x2a);
/*
* read partition table from disk, null terminate
*/
M port/fault.c => port/fault.c +0 -6
@@ 185,11 185,9 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
if(loadrec == 0) { /* This is demand load */
c = s->image->c;
- qlock(&c->rdl);
while(waserror()) {
if(strcmp(u->error, Eintr) == 0)
continue;
- qunlock(&c->rdl);
kunmap(k);
putpage(new);
faulterror("sys: demand load I/O error");
@@ 207,7 205,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
poperror();
kunmap(k);
- qunlock(&c->rdl);
qlock(&s->lk);
if(*p == 0) { /* Someone may have got there first */
new->daddr = daddr;
@@ 219,10 216,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
}
else { /* This is paged out */
c = swapimage.c;
- qlock(&c->rdl);
if(waserror()) {
- qunlock(&c->rdl);
kunmap(k);
putpage(new);
qlock(&s->lk);
@@ 236,7 231,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
poperror();
kunmap(k);
- qunlock(&c->rdl);
qlock(&s->lk);
if(pagedout(*p)) {
M port/portdat.h => port/portdat.h +1 -3
@@ 149,9 149,6 @@ enum
struct Chan
{
- QLock rdl; /* read access */
- QLock wrl; /* write access */
- Lock offl; /* offset access */
Ref;
union{
Chan *next; /* allocation */
@@ 231,6 228,7 @@ enum
{
ScsiTestunit = 0x00,
ScsiExtsens = 0x03,
+ ScsiInquiry = 0x12,
ScsiModesense = 0x1a,
ScsiGetcap = 0x25,
ScsiRead = 0x08,
M port/portfns.h => port/portfns.h +3 -1
@@ 60,7 60,7 @@ void exit(int);
Block* expandb(Block*, int);
int fault(ulong, int);
void fdclose(int, int);
-Chan* fdtochan(int, int, int);
+Chan* fdtochan(int, int, int, int);
int fixfault(Segment*, ulong, int, int);
void flowctl(Queue*, Block*);
void flushmmu(void);
@@ 205,6 205,8 @@ int scsicap(int, void*);
Scsi* scsicmd(int, int, Scsibuf*, long);
int scsiexec(Scsi*, int);
void scsifree(Scsibuf*);
+int scsiinquiry(int, void*, int);
+int scsimodesense(int, int, void*, int);
int scsiready(int);
int scsisense(int, void*);
int scsiwp(int);
M port/stsplice.c => port/stsplice.c +1 -1
@@ 61,7 61,7 @@ spliceoput(Queue *q, Block *bp)
freeb(bp);
if(RD(q)->ptr)
error("stream already spliced");
- c = fdtochan(fd, ORDWR, 0);
+ c = fdtochan(fd, ORDWR, 0, 0);
s = c->stream;
if(s == 0)
error("splice attempt on non-stream");
M port/swap.c => port/swap.c +0 -3
@@ 292,7 292,6 @@ executeio(void)
k = kmap(out);
kaddr = (char*)VA(k);
- qlock(&c->wrl);
if(waserror())
panic("executeio: page out I/O error");
@@ 301,7 300,6 @@ executeio(void)
if(n != BY2PG)
nexterror();
- qunlock(&c->wrl);
kunmap(k);
poperror();
@@ 332,4 330,3 @@ setswapchan(Chan *c)
incref(c);
swapimage.c = c;
}
-
M port/sysfile.c => port/sysfile.c +98 -40
@@ 30,21 30,44 @@ newfd(Chan *c)
}
Chan*
-fdtochan(int fd, int mode, int chkmnt)
+fdtochan(int fd, int mode, int chkmnt, int iref)
{
Chan *c;
+ Fgrp *f;
c = 0;
- if(fd<0 || NFD<=fd || (c = u->p->fgrp->fd[fd])==0)
+ f = u->p->fgrp;
+
+ lock(f);
+ if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) {
+ unlock(f);
error(Ebadfd);
- if(chkmnt && (c->flag&CMSG))
+ }
+ if(iref)
+ incref(c);
+ unlock(f);
+
+ if(chkmnt && (c->flag&CMSG)) {
+ if(iref)
+ close(c);
error(Ebadusefd);
+ }
+
if(mode<0 || c->mode==ORDWR)
return c;
- if((mode&OTRUNC) && c->mode==OREAD)
+
+ if((mode&OTRUNC) && c->mode==OREAD) {
+ if(iref)
+ close(c);
error(Ebadusefd);
- if((mode&~OTRUNC) != c->mode)
+ }
+
+ if((mode&~OTRUNC) != c->mode) {
+ if(iref)
+ close(c);
error(Ebadusefd);
+ }
+
return c;
}
@@ 109,16 132,17 @@ sysdup(ulong *arg)
/*
* Close after dup'ing, so date > #d/1 works
*/
- c = fdtochan(arg[0], -1, 0);
+ c = fdtochan(arg[0], -1, 0, 1);
fd = arg[1];
if(fd != -1){
- if(fd<0 || NFD<=fd)
+ if(fd<0 || NFD<=fd) {
+ close(c);
error(Ebadfd);
-
+ }
lock(f);
if(fd > f->maxfd)
f->maxfd = fd;
- incref(c);
+
oc = f->fd[fd];
f->fd[fd] = c;
unlock(f);
@@ 129,7 153,6 @@ sysdup(ulong *arg)
close(c);
nexterror();
}
- incref(c);
fd = newfd(c);
poperror();
}
@@ 188,7 211,7 @@ fdclose(int fd, int flag)
long
sysclose(ulong *arg)
{
- fdtochan(arg[0], -1, 0);
+ fdtochan(arg[0], -1, 0, 0);
fdclose(arg[0], 0);
return 0;
@@ 252,32 275,38 @@ unionread(Chan *c, void *va, long n)
long
sysread(ulong *arg)
{
- Chan *c;
+ int dir;
long n;
+ Chan *c;
- c = fdtochan(arg[0], OREAD, 1);
validaddr(arg[1], arg[2], 1);
- qlock(&c->rdl);
-
- if(waserror()){
- qunlock(&c->rdl);
+ c = fdtochan(arg[0], OREAD, 1, 1);
+ if(waserror()) {
+ close(c);
nexterror();
}
+
n = arg[2];
- if(c->qid.path & CHDIR){
+ dir = c->qid.path&CHDIR;
+
+ if(dir) {
n -= n%DIRLEN;
if(c->offset%DIRLEN || n==0)
error(Etoosmall);
}
- if((c->qid.path&CHDIR) && c->mnt)
+
+ if(dir && c->mnt)
n = unionread(c, (void*)arg[1], n);
else
n = (*devtab[c->type].read)(c, (void*)arg[1], n, c->offset);
- qunlock(&c->rdl);
- poperror();
- lock(&c->offl);
+
+ lock(c);
c->offset += n;
- unlock(&c->offl);
+ unlock(c);
+
+ poperror();
+ close(c);
+
return n;
}
@@ 287,22 316,25 @@ syswrite(ulong *arg)
Chan *c;
long n;
- c = fdtochan(arg[0], OWRITE, 1);
validaddr(arg[1], arg[2], 0);
- qlock(&c->wrl);
-
- if(waserror()){
- qunlock(&c->wrl);
+ c = fdtochan(arg[0], OWRITE, 1, 1);
+ if(waserror()) {
+ close(c);
nexterror();
}
+
if(c->qid.path & CHDIR)
error(Eisdir);
+
n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2], c->offset);
- qunlock(&c->wrl);
- poperror();
- lock(&c->offl);
+
+ lock(c);
c->offset += n;
- unlock(&c->offl);
+ unlock(c);
+
+ poperror();
+ close(c);
+
return n;
}
@@ 314,11 346,13 @@ sysseek(ulong *arg)
Dir dir;
long off;
- c = fdtochan(arg[0], -1, 1);
+ c = fdtochan(arg[0], -1, 1, 0);
if(c->qid.path & CHDIR)
error(Eisdir);
+
if(devchar[c->type] == '|')
error(Eisstream);
+
off = 0;
switch(arg[2]){
case 0:
@@ 326,10 360,10 @@ sysseek(ulong *arg)
break;
case 1:
- lock(&c->offl); /* lock for read/write update */
+ lock(c); /* lock for read/write update */
c->offset += (long)arg[1];
off = c->offset;
- unlock(&c->offl);
+ unlock(c);
break;
case 2:
@@ 349,8 383,14 @@ sysfstat(ulong *arg)
validaddr(arg[1], DIRLEN, 1);
evenaddr(arg[1]);
- c = fdtochan(arg[0], -1, 0);
+ c = fdtochan(arg[0], -1, 0, 1);
+ if(waserror()) {
+ close(c);
+ nexterror();
+ }
(*devtab[c->type].stat)(c, (char*)arg[1]);
+ poperror();
+ close(c);
return 0;
}
@@ 388,7 428,7 @@ syschdir(ulong *arg)
long
bindmount(ulong *arg, int ismount)
{
- Chan *c0, *c1;
+ Chan *c0, *c1, *bc;
ulong flag;
long ret;
int fd;
@@ 403,18 443,30 @@ bindmount(ulong *arg, int ismount)
if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER))
error(Ebadarg);
if(ismount){
- bogus.chan = fdtochan(fd, 2, 0);
+ bc = fdtochan(fd, 2, 0, 1);
+ if(waserror()) {
+ close(bc);
+ nexterror();
+ }
+ bogus.chan = bc;
+
validaddr(arg[3], 1, 0);
if(vmemchr((char*)arg[3], '\0', NAMELEN) == 0)
error(Ebadarg);
+
bogus.spec = (char*)arg[3];
validaddr(arg[4], 1, 0);
if(vmemchr((char*)arg[4], '\0', NAMELEN) == 0)
error(Ebadarg);
+
bogus.serv = (char*)arg[4];
ret = devno('M', 0);
c0 = (*devtab[ret].attach)((char*)&bogus);
- }else{
+
+ poperror();
+ close(bc);
+ }
+ else {
validaddr(arg[0], 1, 0);
c0 = namec((char*)arg[0], Aaccess, 0, 0);
}
@@ 556,7 608,13 @@ sysfwstat(ulong *arg)
validaddr(arg[1], DIRLEN, 0);
nameok((char*)arg[1]);
- c = fdtochan(arg[0], -1, 1);
+ c = fdtochan(arg[0], -1, 1, 1);
+ if(waserror()) {
+ close(c);
+ nexterror();
+ }
(*devtab[c->type].wstat)(c, (char*)arg[1]);
+ poperror();
+ close(c);
return 0;
}
D ss/div.c => ss/div.c +0 -134
@@ 1,134 0,0 @@
-#include <u.h>
-
-#define W 32
-
-ulong
-_udiv(ulong dividend, ulong divisor)
-{
- long R; /* partial remainder */
- ulong Q; /* partial quotient */
- int iter;
- ulong logQ, m;
-
- m = (1<<(W-1))+1;
- if(dividend < m)
- m = dividend;
- for(logQ=0; logQ<W; logQ++)
- if((divisor<<logQ) >= m)
- break;
-
- R = dividend;
- Q = 0;
- for(iter=logQ; iter>=0; iter--){
- if(R >= 0){
- R -= divisor<<iter;
- Q += 1<<iter;
- }else{
- R += divisor<<iter;
- Q -= 1<<iter;
- }
- }
- if(R < 0)
- Q--;
- return Q;
-}
-
-ulong
-_urem(ulong dividend, ulong divisor)
-{
- long R; /* partial remainder */
- int iter;
- ulong logQ, m;
-
- m = (1<<(W-1))+1;
- if(dividend < m)
- m = dividend;
- for(logQ=0; logQ<W; logQ++)
- if((divisor<<logQ) >= m)
- break;
-
- R = dividend;
- for(iter=logQ; iter>=0; iter--){
- if(R >= 0)
- R -= divisor<<iter;
- else
- R += divisor<<iter;
- }
- if(R < 0)
- R += divisor;
- return R;
-}
-
-ulong
-_div(long dividend, long divisor)
-{
- if(dividend>=0 && divisor>=0)
- return _udiv(dividend, divisor);
- if(dividend<0 && divisor<0)
- return _udiv(-dividend, -divisor);
- if(dividend < 0)
- return -_udiv(-dividend, divisor);
- return -_udiv(dividend, -divisor);
-}
-
-ulong
-_rem(long dividend, long divisor)
-{
- if(dividend>=0 && divisor>=0)
- return _urem(dividend, divisor);
- if(dividend<0 && divisor<0)
- return _urem(-dividend, -divisor);
- if(dividend < 0)
- return -_urem(-dividend, divisor);
- return -_urem(dividend, -divisor);
-}
-
-long
-_asmul(long *a, long b)
-{
- long c;
-
- c = *a * b;
- *a = c;
- return c;
-}
-
-long
-_asdiv(long *a, long b)
-{
- long c;
-
- c = *a / b;
- *a = c;
- return c;
-}
-
-long
-_asrem(long *a, long b)
-{
- long c;
-
- c = *a % b;
- *a = c;
- return c;
-}
-
-ulong
-_asudiv(ulong *a, ulong b)
-{
- ulong c;
-
- c = *a / b;
- *a = c;
- return c;
-}
-
-ulong
-_asurem(ulong *a, ulong b)
-{
- ulong c;
-
- c = *a % b;
- *a = c;
- return c;
-}