From 06450e3278aa79b6ab74586f212a64b3efedea89 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 23 Apr 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-04-23 --- gnot/dat.h | 3 +- gnot/devcons.c | 46 +++++++-- gnot/fns.h | 5 +- gnot/l.s | 49 +++++---- gnot/screen.c | 17 +++- port/chan.c | 264 +++++++++++++++++++++++++----------------------- port/devbit.c | 69 +++++++++---- port/devlance.c | 13 +-- port/devmnt.c | 30 ++++-- port/devscsi.c | 100 +++++++++++------- port/devwren.c | 47 +++------ port/stasync.c | 11 ++ 12 files changed, 388 insertions(+), 266 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index cc4e8284e3b14f6a7607f18d704c2470dbf6a77a..4d326c800f3214d2925c496d02782cebfa0f652f 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -628,8 +628,9 @@ struct Scsidata struct Scsi { QLock; + ulong pid; ushort target, lun; - ushort state; + ushort rflag; ushort status; Scsidata cmd; Scsidata data; diff --git a/gnot/devcons.c b/gnot/devcons.c index 42ed373e4b28944d7cccb9947241edae9983ba9f..d66f8c3a4d1fe131fa425f645691f1147399d5a8 100644 --- a/gnot/devcons.c +++ b/gnot/devcons.c @@ -69,9 +69,10 @@ struct Rs232{ int kstarted; /* true if kproc started */ Queue *wq; Alarm *a; /* alarm for waking the rs232 kernel process */ - int started; + int started; /* true if output interrupt pending */ int delay; /* time between character input and waking kproc */ Rendez r; + Rendez rempty; }; Rs232 rs232; @@ -108,6 +109,7 @@ printinit(void) lineq.out = lineq.buf; rs232.in.in = rs232.in.buf; rs232.in.out = rs232.in.buf; + rs232.delay = 64; /* msec */ qlock(&kbdq); /* allocate qlock */ qunlock(&kbdq); lock(&lineq); /* allocate lock */ @@ -293,6 +295,7 @@ echo(int c) { char ch; static int ctrlt; + extern void DEBUG(void), dumpqueues(void), mntdump(void); /* * ^t hack BUG @@ -337,6 +340,7 @@ echo(int c) * Put character into read queue at interrupt time. * Always called splhi from proc 0. */ + void kbdchar(int c) { @@ -699,7 +703,7 @@ consread(Chan *c, void *buf, long n, ulong offset) return i; default: - panic("consread %lux\n", c->qid); + panic("consread %lux\n", c->qid.path); return 0; } } @@ -820,6 +824,12 @@ rs232output(Rs232 *r) } r->out.f = next; + if(q==0){ + kprint("rs232output: null q\n"); + qunlock(&r->outlock); + return; + } + /* * stage new blocks * @@ -831,8 +841,13 @@ rs232output(Rs232 *r) if(bp == 0) break; if(bp->type == M_CTL){ + if(waserror()){ + freeb(bp); + qunlock(&r->outlock); + nexterror(); + } while(!rs232empty(r)) - sleep(&r->r, rs232empty, r); + sleep(&r->rempty, rs232empty, r); l = strtoul((char *)(bp->rptr+1), 0, 0); switch(*bp->rptr){ case 'B': @@ -853,6 +868,7 @@ rs232output(Rs232 *r) r->delay = l; break; } + poperror(); freeb(bp); break; } @@ -864,12 +880,8 @@ rs232output(Rs232 *r) * start output, the spl's sync with interrupt level * this wouldn't work on a multi-processor */ - splhi(); - if(r->started == 0){ - r->started = 1; + if(r->started == 0) duartstartrs232o(); - } - spllo(); qunlock(&r->outlock); } @@ -942,11 +954,14 @@ rs232open(Queue *q, Stream *c) WR(q)->ptr = r; r->wq = WR(q); + kprint("rs232open: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", + q, c->inuse, c->type, c->dev, c->id); if(r->kstarted == 0){ r->in.in = r->in.out = r->in.buf; kproc("rs232", rs232kproc, r); r->kstarted = 1; - } + }else + wakeup(&r->r); /* pick up any input characters */ } static void @@ -954,7 +969,14 @@ rs232close(Queue *q) { Rs232 *r; + kprint("rs232close: q=0x%ux\n", q); r = q->ptr; + qlock(&r->outlock); + while(!rs232empty(r)) + sleep(&r->rempty, rs232empty, r); + qunlock(&r->outlock); + kprint("rs232close: emptied\n"); + rs232output(r); /* reclaim blocks written */ qlock(r); r->wq = 0; qunlock(r); @@ -994,7 +1016,7 @@ rs232ichar(int c) screenputc('^'); /* - * pass upstream within 1/16 second + * pass upstream within r->delay milliseconds */ if(r->a==0){ if(r->delay == 0) @@ -1005,7 +1027,7 @@ rs232ichar(int c) } /* - * called by output interrupt. runs splhi + * called by output interrupt. runs spl5 */ int getrs232o(void) @@ -1016,6 +1038,7 @@ getrs232o(void) r = &rs232; if(r->out.r == r->out.w){ + wakeup(&r->rempty); r->started = 0; return -1; } @@ -1026,5 +1049,6 @@ getrs232o(void) if(r->out.r==r->out.w || NEXT(r->out.r)==r->out.w) wakeup(&r->r); } + r->started = 1; return c; } diff --git a/gnot/fns.h b/gnot/fns.h index acc3b5afbd69b2d8df054aa56ba2dd9559532749..8a840a2604906dd47fc7e89aee06ef9a910360ef 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -21,7 +21,6 @@ long clrfpintr(void); int compactpte(Orig*, ulong); void confinit(void); Env *copyenv(Env*, int); -Chan *createdir(Chan*); int decref(Ref*); void delay(int); void delete(List**, List*, List*); @@ -162,7 +161,7 @@ void schedinit(void); void screeninit(void); void screenputc(int); int scsicap(int, uchar *); -void scsicmd(Scsi *, int, int, uchar *, long); +Scsi *scsicmd(int, int, long); void scsictrlintr(void); void scsidmaintr(void); int scsiexec(Scsi *, int); @@ -182,6 +181,7 @@ int setlabel(Label*); char *skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); int spl1(void); +int splduart(void); int splhi(void); int spllo(void); void splx(int); @@ -214,7 +214,6 @@ void validaddr(ulong, ulong, int); void *vmemchr(void*, int, int); void wakeme(Alarm*); void wakeup(Rendez*); -Chan *walk(Chan*, char*, int); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) #define poperror() u->nerrlab-- diff --git a/gnot/l.s b/gnot/l.s index cd4f693e3e1a07b6ff887a6a6d8626ddea25801c..42c22564996345ddecdc1ff8f03d904f15bfb22b 100644 --- a/gnot/l.s +++ b/gnot/l.s @@ -54,6 +54,13 @@ TEXT splhi(SB), $0 MOVW $(SUPER|SPL(7)), SR RTS +TEXT splduart(SB), $0 + + MOVL $0, R0 + MOVW SR, R0 + MOVW $(SUPER|SPL(5)), SR + RTS + TEXT spllo(SB), $0 MOVL $0, R0 @@ -230,14 +237,9 @@ TEXT portintr(SB), $0 /* level 2 */ MOVL A0, ((8+8)*BY2WD)(A7) MOVL A7, -(A7) BSR devportintr(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE + BRA retintr -TEXT dkintr(SB), $0 /* level 2 */ +TEXT dkintr(SB), $0 /* level 3 */ MOVL $DBMAGIC, -(A7) SUBL $((8+8+1)*BY2WD), A7 @@ -247,12 +249,7 @@ TEXT dkintr(SB), $0 /* level 2 */ MOVL A0, ((8+8)*BY2WD)(A7) MOVL A7, -(A7) BSR inconintr(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x77FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE + BRA retintr TEXT mouseintr(SB), $0 /* level 4 */ @@ -280,12 +277,7 @@ TEXT uartintr(SB), $0 /* level 5 */ MOVL A0, ((8+8)*BY2WD)(A7) MOVL A7, -(A7) BSR duartintr(SB) - ADDL $4, A7 - MOVL ((8+8)*BY2WD)(A7), A0 - MOVL A0, USP - MOVEM (A7), $0x7FFF - ADDL $((8+8+1)*BY2WD+BY2WD), A7 - RTE + BRA retintr TEXT syncintr(SB), $0 /* level 6 */ @@ -297,6 +289,9 @@ TEXT syncintr(SB), $0 /* level 6 */ MOVL A0, ((8+8)*BY2WD)(A7) MOVL A7, -(A7) BSR clock(SB) + /* fall through */ +retintr: + BSR mousetry(SB) ADDL $4, A7 MOVL ((8+8)*BY2WD)(A7), A0 MOVL A0, USP @@ -304,6 +299,22 @@ TEXT syncintr(SB), $0 /* level 6 */ ADDL $((8+8+1)*BY2WD+BY2WD), A7 RTE +GLOBL duarttimer+0(SB),$4 + +TEXT duartreadtimer+0(SB), $0 + MOVW SR, R1 /* spl7() */ + MOVW $0x2700, SR + MOVL $0x40100000, A0 + CLRL R0 + TSTB 15(A0) /* stop timer */ + MOVW 6(A0), R0 /* read hi,lo */ + TSTB 14(A0) /* restart timer */ + NOTW R0 /* timer counts down from 0xffff */ + ADDL duarttimer(SB), R0 + MOVL R0, duarttimer(SB) + MOVW R1, SR + RTS + GLOBL mousetab(SB), $128 DATA mousetab+ 0(SB)/4, -1 /* x down, */ DATA mousetab+ 4(SB)/4, 1 /* y up */ diff --git a/gnot/screen.c b/gnot/screen.c index f9a045fc6ee22989c3cb5dbaea6f2d5a03e66fc4..906a8b7d73f4705544501ba70c6c592038c47fef 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -227,10 +227,9 @@ duartinputport(void) void duartbaud(int b) { - int x; + int x = 0; Duart *duart = DUARTREG; - x = 0; /* set */ switch(b){ case 38400: x = BD38400; @@ -333,8 +332,15 @@ duartrs232intr(void) void duartstartrs232o(void) { - DUARTREG[1].cmnd = ENB_TX; - duartrs232intr(); + int s; + Duart *duart; + + duart = DUARTREG; + s = splduart(); + duart[1].cmnd = ENB_TX; + if(duart[1].sr_csr & (XMT_RDY|XMT_EMT)) + duartrs232intr(); + splx(s); } struct latin @@ -542,13 +548,14 @@ duartintr(Ureg *ur) /* * Is it 2? */ - if(cause & IM_RRDYB){ /* rs232 input */ + while(cause & IM_RRDYB){ /* rs232 input */ status = duart[1].sr_csr; c = duart[1].data; if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) duart[1].cmnd = RESET_ERR; else rs232ichar(c); + cause = duart->is_imr; } /* * Is it 3? diff --git a/port/chan.c b/port/chan.c index ee34532104c4e030ce7ebb8bab497c22eaa9e23d..0ac2f568a4ab6a06959166475377c1fc433d6556 100644 --- a/port/chan.c +++ b/port/chan.c @@ -11,6 +11,18 @@ struct{ Chan *free; }chanalloc; +/* + * used by namec, domount, and walk to point + * to the current mount entry during name resolution + */ +typedef struct Finger Finger; +struct Finger { + Chan *c; /* channel we're walking */ + int needcl; /* true if we need to clone c before using it */ + Mount *mnt; /* last mount point we ran traversed */ + ulong mountid; /* id of that mount point */ +}; + int incref(Ref *r) { @@ -83,9 +95,7 @@ loop: c->dev = 0; c->offset = 0; c->mnt = 0; - c->stream = 0; c->aux = 0; - c->mntindex = 0; c->mchan = 0; c->mqid = (Qid){0, 0}; return c; @@ -294,15 +304,13 @@ clone(Chan *c, Chan *nc) return (*devtab[c->type].clone)(c, nc); } -Chan* -domount(Chan *c) +void +domount(Finger *f) { int i; - ulong mntid; Mtab *mt; - Mount *mnt; Pgrp *pg; - Chan *nc, *mc; + Chan *mc; pg = u->p->pgrp; /* @@ -310,110 +318,101 @@ domount(Chan *c) */ mt = pg->mtab; for(i=0; inmtab; i++,mt++) - if(mt->c && eqchan(mt->c, c, 1)) + if(mt->c && eqchan(mt->c, f->c, 1)) goto Found; /* * No; c is unaffected */ - return c; + return; /* * Yes; move c through table */ Found: lock(pg); - if(!eqchan(mt->c, c, 1)){ /* table changed underfoot */ + if(!eqchan(mt->c, f->c, 1)){ /* table changed underfoot */ pprint("domount: changed underfoot?\n"); unlock(pg); - return c; + return; } - mnt = mt->mnt; - mntid = mnt->mountid; - mc = mnt->c; + f->mnt = mt->mnt; + f->mountid = f->mnt->mountid; + mc = mt->mnt->c; incref(mc); unlock(pg); - if(waserror()){ - close(mc); - nexterror(); - } - nc = clone(mc, 0); - close(mc); - poperror(); - close(c); - nc->mnt = mnt; - nc->mountid = mntid; - return nc; + close(f->c); + f->c = mc; + f->needcl = 1; } -Chan* -walk(Chan *ac, char *name, int domnt) +int +walk(Finger *f, char *name, int domnt) { - Mount *mnt; int first = 1; - Chan *c = ac; - Chan *nc, *mc; + Mount *mnt = f->mnt; + ulong mountid = f->mountid; + Chan *c = f->c; + Chan *mc; Pgrp *pg = u->p->pgrp; /* * name may be empty if the file name is "/", "#c" etc. */ - Again: - if(name[0] && (*devtab[c->type].walk)(c, name)==0){ - if(!(c->flag&CMOUNT)) - goto Notfound; - mnt = c->mnt; - if(mnt == 0) - panic("walk"); - lock(pg); - if(mnt->term){ - unlock(pg); - goto Notfound; - } - if(c->mountid != mnt->mountid){ - pprint("walk: changed underfoot? '%s'\n", name); + if(name[0]){ + for(;;){ + if(!first || f->needcl){ + mc = (*devtab[c->type].clwalk)(c, name); + if(mc){ + close(c); + c = mc; + break; + } + } else { + if((*devtab[c->type].walk)(c, name) != 0){ + break; + } + } + if(!(c->flag&CMOUNT)) + goto Notfound; + if(mnt == 0) + panic("walk"); /* ??? is this safe ??? */ + lock(pg); + if(mnt->term){ + unlock(pg); + goto Notfound; + } + if(mountid != mnt->mountid){ + pprint("walk: changed underfoot? '%s'\n", name); + unlock(pg); + goto Notfound; + } + mnt = mnt->next; + mountid = mnt->mountid; + mc = mnt->c; + incref(mc); unlock(pg); - goto Notfound; - } - mnt = mnt->next; - mc = mnt->c; - incref(mc); - unlock(pg); - if(waserror()){ - close(mc); - nexterror(); - } - if(mnt == 0) - panic("walk 1"); - nc = clone(mc, 0); - close(mc); - poperror(); - if(!first) - close(c); - nc->mnt = mnt; - nc->mountid = mnt->mountid; - c = nc; - first = 0; - goto Again; - } - - if(name[0]) /* walk succeeded */ - c->flag &= ~CMOUNT; - - if(domnt){ - if(waserror()){ if(!first) close(c); - return 0; + c = mc; + first = 0; } - c = domount(c); - poperror(); - } - if(!first) - close(ac); + /* + * we get here only if we have a cloned and walked + * channel + */ + if(!first) + close(f->c); + f->c = c; + f->needcl = 0; + f->mnt = 0; + c->flag &= ~CMOUNT; + } + if(domnt) + domount(f); - return c; + return 1; Notfound: if(!first) @@ -422,22 +421,22 @@ walk(Chan *ac, char *name, int domnt) } /* - * c is a mounted non-creatable directory. find a creatable one. + * f->c is a mounted non-creatable directory. find a creatable one. */ -Chan* -createdir(Chan *c) +void +createdir(Finger *f) { Mount *mnt; Pgrp *pg = u->p->pgrp; - Chan *mc, *nc; + Chan *mc; lock(pg); if(waserror()){ unlock(pg); nexterror(); } - mnt = c->mnt; - if(c->mountid != mnt->mountid){ + mnt = f->mnt; + if(f->mountid != mnt->mountid){ pprint("createdir: changed underfoot?\n"); error(Enocreate); } @@ -449,16 +448,10 @@ createdir(Chan *c) mc = mnt->c; incref(mc); unlock(pg); - if(waserror()){ - close(mc); - nexterror(); - } - nc = clone(mc, 0); poperror(); - close(c); - close(mc); - nc->mnt = mnt; - return nc; + close(f->c); + f->needcl = 1; + f->c = mc; } void @@ -466,6 +459,19 @@ saveregisters(void) { } +void +doclone(Finger *f) +{ + Chan *nc; + + if(f->needcl == 0) + return; + nc = clone(f->c, 0); + close(f->c); + f->c = nc; + f->needcl = 0; +} + /* * Turn a name into a channel. * &name[0] is known to be a valid address. It may be a kernel address. @@ -473,11 +479,11 @@ saveregisters(void) Chan* namec(char *name, int amode, int omode, ulong perm) { - Chan *c, *nc; int t; int mntok, isdot; char *p; char *elem; + Finger f; if(name[0] == 0) error(Enonexist); @@ -498,8 +504,11 @@ namec(char *name, int amode, int omode, ulong perm) elem = u->elem; mntok = 1; isdot = 0; + f.mnt = 0; if(name[0] == '/'){ - c = clone(u->slash, 0); + f.c = u->slash; + incref(f.c); + f.needcl = 1; /* * Skip leading slashes. */ @@ -517,16 +526,19 @@ namec(char *name, int amode, int omode, ulong perm) elem[0]=0; }else name = nextelem(name, elem); - c = (*devtab[t].attach)(elem); + f.c = (*devtab[t].attach)(elem); + f.needcl = 0; }else{ - c = clone(u->dot, 0); + f.c = u->dot; + incref(f.c); + f.needcl = 1; name = skipslash(name); /* eat leading ./ */ if(*name == 0) isdot = 1; } if(waserror()){ - close(c); + close(f.c); nexterror(); } @@ -537,16 +549,15 @@ namec(char *name, int amode, int omode, ulong perm) * current directory. */ if(mntok && !isdot && !(amode==Amount && elem[0]==0)) - c = domount(c); /* see case Atodir below */ + domount(&f); /* see case Atodir below */ /* * How to treat the last element of the name depends on the operation. * Therefore do all but the last element by the easy algorithm. */ while(*name){ - if((nc=walk(c, elem, mntok)) == 0) + if(walk(&f, elem, mntok) == 0) error(Enonexist); - c = nc; name = nextelem(name, elem); } @@ -556,11 +567,10 @@ namec(char *name, int amode, int omode, ulong perm) switch(amode){ case Aaccess: if(isdot) - c = domount(c); + domount(&f); else{ - if((nc=walk(c, elem, mntok)) == 0) + if(walk(&f, elem, mntok) == 0) error(Enonexist); - c = nc; } break; @@ -569,26 +579,26 @@ namec(char *name, int amode, int omode, ulong perm) * Directories (e.g. for cd) are left before the mount point, * so one may mount on / or . and see the effect. */ - if((nc=walk(c, elem, 0)) == 0) + if(walk(&f, elem, 0) == 0) error(Enonexist); - c = nc; - if(!(c->qid.path & CHDIR)) + if(!(f.c->qid.path & CHDIR)) error(Enotdir); break; case Aopen: if(isdot) - c = domount(c); + domount(&f); else{ - if((nc=walk(c, elem, mntok)) == 0) + if(walk(&f, elem, mntok) == 0) error(Enonexist); - c = nc; } Open: - saveregisters(); /* else error() in open has wrong value of c saved */ - c = (*devtab[c->type].open)(c, omode); + saveregisters(); /* else error() in open has wrong value of c saved */ + if(f.needcl) + doclone(&f); + f.c = (*devtab[f.c->type].open)(f.c, omode); if(omode & OCEXEC) - c->flag |= CCEXEC; + f.c->flag |= CCEXEC; break; case Amount: @@ -597,31 +607,37 @@ namec(char *name, int amode, int omode, ulong perm) * the second mount to be attached to the original directory, not * the replacement. */ - if((nc=walk(c, elem, 0)) == 0) + if(walk(&f, elem, 0) == 0) error(Enonexist); - c = nc; break; case Acreate: if(isdot) error(Eisdir); - if((nc=walk(c, elem, 1)) != 0){ - c = nc; + if(walk(&f, elem, 1) != 0){ omode |= OTRUNC; goto Open; } - if((c->flag&(CMOUNT|CCREATE)) == CMOUNT) - c = createdir(c); - (*devtab[c->type].create)(c, elem, omode, perm); + if((f.c->flag&(CMOUNT|CCREATE)) == CMOUNT) + createdir(&f); + if(f.needcl) + doclone(&f); + (*devtab[f.c->type].create)(f.c, elem, omode, perm); if(omode & OCEXEC) - c->flag |= CCEXEC; + f.c->flag |= CCEXEC; break; default: panic("unknown namec access %d\n", amode); } + if(f.needcl) + doclone(&f); poperror(); - return c; + if(f.c->flag & CMOUNT){ + f.c->mnt = f.mnt; + f.c->mountid = f.mountid; + } + return f.c; } /* diff --git a/port/devbit.c b/port/devbit.c index 0c0b82ff0ae8785608c5288cae03a3a68d3f07b9..4df1bddc7a769ac9af2ad5f8061daeb98a3ad1de 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -6,6 +6,7 @@ #include "errno.h" #include "devtab.h" +#include "ureg.h" #include #include @@ -45,6 +46,7 @@ struct #define FREE 0x80000000 void bitcompact(void); void bitfree(GBitmap*); +void mouseupdate(int); extern GBitmap gscreen; struct{ @@ -54,6 +56,7 @@ struct{ int dx; /* interrupt-time delta */ int dy; int track; /* update cursor on screen */ + int clock; /* check mouse.track on RTE */ Mouse; int changed; /* mouse structure changed since last read */ int newbuttons; /* interrupt time access only */ @@ -526,6 +529,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) rect.min.y = GLONG(p+6); rect.max.x = GLONG(p+10); rect.max.y = GLONG(p+14); + if(Dx(rect) < 0 || Dy(rect) < 0) + error(Ebadblt); if(rect.min.x >= 0) l = (rect.max.x+ws-1)/ws - rect.min.x/ws; else{ /* make positive before divide */ @@ -1128,27 +1133,53 @@ mousebuttons(int b) /* called spl5 */ void mouseclock(void) /* called spl6 */ +{ + ++mouse.clock; +} + +void +mousetry(Ureg *ur) +{ + int s; + + if(mouse.clock && mouse.track && (ur->sr&SPL(7)) == 0 && canlock(&cursor)){ + s = spl1(); + mouseupdate(0); + splx(s); + unlock(&cursor); + wakeup(&mouse.r); + } +} + +void +mouseupdate(int dolock) { int x, y; - if(mouse.track && canlock(&cursor)){ - x = mouse.xy.x + mouse.dx; - if(x < gscreen.r.min.x) - x = gscreen.r.min.x; - if(x >= gscreen.r.max.x) - x = gscreen.r.max.x; - y = mouse.xy.y + mouse.dy; - if(y < gscreen.r.min.y) - y = gscreen.r.min.y; - if(y >= gscreen.r.max.y) - y = gscreen.r.max.y; - cursoroff(0); - mouse.xy = Pt(x, y); - cursoron(0); - mouse.dx = 0; - mouse.dy = 0; - mouse.track = 0; - mouse.buttons = mouse.newbuttons; - mouse.changed = 1; + + if(dolock && !canlock(&cursor)) + return; + + x = mouse.xy.x + mouse.dx; + if(x < gscreen.r.min.x) + x = gscreen.r.min.x; + if(x >= gscreen.r.max.x) + x = gscreen.r.max.x; + y = mouse.xy.y + mouse.dy; + if(y < gscreen.r.min.y) + y = gscreen.r.min.y; + if(y >= gscreen.r.max.y) + y = gscreen.r.max.y; + cursoroff(0); + mouse.xy = Pt(x, y); + cursoron(0); + mouse.dx = 0; + mouse.dy = 0; + mouse.clock = 0; + mouse.track = 0; + mouse.buttons = mouse.newbuttons; + mouse.changed = 1; + + if(dolock){ unlock(&cursor); wakeup(&mouse.r); } diff --git a/port/devlance.c b/port/devlance.c index 613c0e2bf45354078a2c6442572146df96c51ab9..6ed728028d42c3b645fb1f94cf4214a54abcbc36 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -208,19 +208,21 @@ void lancekproc(void *); /* * print a packet preceded by a message */ +int sprintpacket(char *buf, Trace *t) { Dpkt *p = &t->p; - int i; + int i, n; - sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(", + n = sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(", t->tag, t->ticks, t->len, p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1]); for(i=0; idata); i++) - sprint(buf+strlen(buf), "%.2ux", p->data[i]); - sprint(buf+strlen(buf), ")\n"); + n += sprint(buf+n, "%.2ux", p->data[i]); + n += sprint(buf+n, ")\n"); + return n; } /* @@ -642,8 +644,7 @@ lancetraceread(Chan *c, void *a, long n, ulong offset) int plen; rv = 0; - sprintpacket(buf, l.dq.t); - plen = strlen(buf); + plen = sprintpacket(buf, l.dq.t); off = offset % plen; for(t = &l.dq.t[offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){ if(t->tag == 0) diff --git a/port/devmnt.c b/port/devmnt.c index 7d10653c5e6dcbb06d203ef1e94a07c72ebb6357..a1dfea6800b0cc5ce6564db0889f87b0e2f861f2 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -199,6 +199,8 @@ mntdev(Chan *c, int noerr) return m; if(noerr) return 0; + print("mntdev shutdown %d %d %d %lux\n", c->dev, c->mntindex, + m->mntid, m->q); error(Eshutdown); } @@ -395,24 +397,34 @@ mntclwalk(Chan *c, char *name) Mnthdr *mh; Chan *nc; + if(waserror()){ /* BUG: can check type of error? */ + freechan(nc); + nc = 0; + goto Out; + } nc = newchan(); + nc->type = c->type; + nc->dev = c->dev; + nc->qid = c->qid; + nc->mode = c->mode; + nc->flag = c->flag; + nc->offset = c->offset; + nc->mnt = c->mnt; + nc->aux = c->aux; + nc->mchan = c->mchan; + nc->mqid = c->qid; m = mntdev(c, 0); mh = mhalloc(); mh->thdr.type = Tclwalk; mh->thdr.fid = c->fid; mh->thdr.newfid = nc->fid; strcpy(mh->thdr.name, name); - if(waserror()){ /* BUG: can check type of error? */ - print("mntclwalk(%d %lux) failed\n", c->type, c->qid.path); - freechan(nc); - nc = 0; - goto Out; - } mntxmit(m, mh); - nc->qid = mh->rhdr.qid; - print("mntclwalk(%d %lux)->%d %lux\n", c->type, c->qid.path, - nc->type, nc->qid.path); + if(mh->rhdr.fid == mh->thdr.fid) + errors("directory entry not found"); poperror(); + nc->qid = mh->rhdr.qid; + incref(m); Out: mhfree(mh); return nc; diff --git a/port/devscsi.c b/port/devscsi.c index 72a8713d644e79b7d2f3eee5c3a7e176d3a93a86..beeae49edd7350fc866a4887d9d47030a78a5d64 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -24,7 +24,8 @@ static Dirtab scsidir[]={ #define NSCSI (sizeof scsidir/sizeof(Dirtab)) static Scsi staticcmd; /* BUG */ -static uchar datablk[8192]; /* BUG */ +#define DATASIZE (8*1024) +static uchar datablk[DATASIZE]; /* BUG */ static int debugs[8]; static int isscsi; @@ -120,7 +121,18 @@ scsicreate(Chan *c, char *name, int omode, ulong perm) void scsiclose(Chan *c) -{} +{ + Scsi *cmd = &staticcmd; + + if((c->qid.path & CHDIR) || c->qid.path==1) + return; + if((c->qid.path & 0xf) == Qcmd){ + if(canqlock(cmd) || cmd->pid == u->p->pid){ + cmd->pid = 0; + qunlock(cmd); + } + } +} long scsiread(Chan *c, char *a, long n, ulong offset) @@ -132,6 +144,7 @@ scsiread(Chan *c, char *a, long n, ulong offset) return devdirread(c, a, n, 0, 0, scsigen); if(c->qid.path==1){ if(offset == 0){ + /*void scsidump(void); scsidump();*/ *a = ownid; n = 1; }else @@ -140,17 +153,26 @@ scsiread(Chan *c, char *a, long n, ulong offset) case Qcmd: if (n < 4) error(Ebadarg); - /*if(canqlock(cmd)){ + if(canqlock(cmd)){ qunlock(cmd); error(Egreg); - }*/ + } + if(cmd->pid != u->p->pid) + error(Egreg); n = 4; - *a++ = cmd->state>>8; *a++ = cmd->state; + *a++ = 0; *a++ = 0; *a++ = cmd->status>>8; *a = cmd->status; - /*qunlock(cmd);*/ + cmd->pid = 0; + qunlock(cmd); break; case Qdata: - if (n > sizeof datablk) + if(canqlock(cmd)){ + qunlock(cmd); + error(Egreg); + } + if(cmd->pid != u->p->pid) + error(Egreg); + if (n > DATASIZE) error(Ebadarg); cmd->data.base = datablk; cmd->data.lim = cmd->data.base + n; @@ -181,25 +203,31 @@ scsiwrite(Chan *c, char *a, long n, ulong offset) if(offset == 0){ n = 1; ownid=*a; - scsiinit(); + scsireset(); }else n = 0; }else switch ((int)c->qid.path & 0xf){ case Qcmd: if (n < 6 || n > sizeof cmd->cmdblk) error(Ebadarg); - /*qlock(cmd);*/ + qlock(cmd); + cmd->pid = u->p->pid; cmd->cmd.base = cmd->cmdblk; memmove(cmd->cmd.base, a, n); cmd->cmd.lim = cmd->cmd.base + n; cmd->cmd.ptr = cmd->cmd.base; cmd->target = (c->qid.path>>4)&7; cmd->lun = (a[1]>>5)&7; - cmd->state = 0; cmd->status = 0xFFFF; break; case Qdata: - if (n > sizeof datablk) + if(canqlock(cmd)){ + qunlock(cmd); + error(Egreg); + } + if(cmd->pid != u->p->pid) + error(Egreg); + if (n > DATASIZE) error(Ebadarg); cmd->data.base = datablk; cmd->data.lim = cmd->data.base + n; @@ -234,18 +262,21 @@ scsiwstat(Chan *c, char *dp) error(Eperm); } -void -scsicmd(Scsi *cmd, int dev, int cmdbyte, uchar *buf, long size) +Scsi * +scsicmd(int dev, int cmdbyte, long size) { + Scsi *cmd = &staticcmd; + + if(size > DATASIZE) + panic("scsicmd %d", size); qlock(cmd); cmd->target = dev>>3; cmd->lun = dev&7; cmd->cmd.base = cmd->cmdblk; - cmd->data.base = buf; cmd->cmd.ptr = cmd->cmd.base; memset(cmd->cmdblk, 0, sizeof cmd->cmdblk); cmd->cmdblk[0] = cmdbyte; - switch (cmdbyte>>5) { + switch(cmdbyte>>5){ case 0: cmd->cmd.lim = &cmd->cmdblk[6]; break; case 1: @@ -253,7 +284,7 @@ scsicmd(Scsi *cmd, int dev, int cmdbyte, uchar *buf, long size) default: cmd->cmd.lim = &cmd->cmdblk[12]; break; } - switch (cmdbyte) { + switch(cmdbyte){ case 0x00: /* test unit ready */ break; case 0x03: /* read sense data */ @@ -262,49 +293,49 @@ scsicmd(Scsi *cmd, int dev, int cmdbyte, uchar *buf, long size) case 0x25: /* read capacity */ break; } + cmd->data.base = datablk; cmd->data.lim = cmd->data.base + size; cmd->data.ptr = cmd->data.base; cmd->save = cmd->data.base; + return cmd; } int scsiready(int dev) { - static Scsi cmd; + Scsi *cmd = scsicmd(dev, 0x00, 0); int status; - scsicmd(&cmd, dev, 0x00, 0, 0); - status = scsiexec(&cmd, 0); - qunlock(&cmd); + + status = scsiexec(cmd, 0); + qunlock(cmd); if ((status&0xff00) != 0x6000) error(Eio); return status&0xff; } int -scsisense(int dev, uchar *p) +scsisense(int dev, void *p) { - static Scsi cmd; - static uchar buf[18]; + Scsi *cmd = scsicmd(dev, 0x03, 18); int status; - scsicmd(&cmd, dev, 0x03, buf, sizeof buf); - status = scsiexec(&cmd, 1); - memmove(p, buf, sizeof buf); - qunlock(&cmd); + + status = scsiexec(cmd, 1); + memmove(p, cmd->data.base, 18); + qunlock(cmd); if ((status&0xff00) != 0x6000) error(Eio); return status&0xff; } int -scsicap(int dev, uchar *p) +scsicap(int dev, void *p) { - static Scsi cmd; - static uchar buf[8]; + Scsi *cmd = scsicmd(dev, 0x25, 8); int status; - scsicmd(&cmd, dev, 0x25, buf, sizeof buf); - status = scsiexec(&cmd, 1); - memmove(p, buf, sizeof buf); - qunlock(&cmd); + + status = scsiexec(cmd, 1); + memmove(p, cmd->data.base, 8); + qunlock(cmd); if ((status&0xff00) != 0x6000) error(Eio); return status&0xff; @@ -381,6 +412,7 @@ scsiexec(Scsi *p, int rflag) nexterror(); } scsirflag = rflag; + p->rflag = rflag; datap = p->data.base; if ((ownid & 0x08) && rflag) PUT(Dest_id, 0x40|p->target); diff --git a/port/devwren.c b/port/devwren.c index 6dc53be1b1ff6b87fcf946bfe4e06469f232b005..448d08c9d172d1a0d5186159f8bf34945ae5ab53 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -37,8 +37,7 @@ struct Disk static Disk wren[Ndisk]; -static Scsi staticcmd; /* BUG */ -static uchar datablk[BY2PG]; /* BUG */ +#define DATASIZE (8*1024) /* BUG */ #define BGLONG(p) (((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3]) @@ -125,11 +124,7 @@ wrenreset(void) void wreninit(void) -{ - Scsi *cmd = &staticcmd; - cmd->cmd.base = cmd->cmdblk; - cmd->data.base = datablk; -} +{} /* * param is #r. @@ -210,8 +205,8 @@ wrenclose(Chan *c) long wrenread(Chan *c, char *a, long n, ulong offset) { - Scsi *cmd = &staticcmd; - unsigned long lbn; + Scsi *cmd; + ulong lbn; Part *p; Disk *d; @@ -230,26 +225,17 @@ wrenread(Chan *c, char *a, long n, ulong offset) lbn = (offset/d->blocksize) + p->firstblock; if (lbn >= p->maxblock) error(Ebadarg); - if (n > sizeof datablk) - n = sizeof datablk; - qlock(cmd); + if (n > DATASIZE) + n = DATASIZE; + cmd = scsicmd(c->dev, 0x08, n); if (waserror()) { qunlock(cmd); nexterror(); } - cmd->target = c->dev>>3; - cmd->lun = c->dev&7; - cmd->cmd.ptr = cmd->cmd.base; - cmd->cmdblk[0] = 0x08; cmd->cmdblk[1] = lbn>>16; cmd->cmdblk[2] = lbn>>8; cmd->cmdblk[3] = lbn; cmd->cmdblk[4] = n/d->blocksize; - cmd->cmdblk[5] = 0x00; - cmd->cmd.lim = &cmd->cmdblk[6]; - cmd->data.lim = cmd->data.base + n; - cmd->data.ptr = cmd->data.base; - cmd->save = cmd->data.base; scsiexec(cmd, 1); n = cmd->data.ptr - cmd->data.base; memmove(a, cmd->data.base, n); @@ -273,8 +259,8 @@ wrenread(Chan *c, char *a, long n, ulong offset) long wrenwrite(Chan *c, char *a, long n, ulong offset) { - Scsi *cmd = &staticcmd; - unsigned long lbn; + Scsi *cmd; + ulong lbn; Part *p; Disk *d; @@ -290,26 +276,17 @@ wrenwrite(Chan *c, char *a, long n, ulong offset) lbn = offset/d->blocksize + p->firstblock; if (lbn >= p->maxblock) error(Ebadarg); - if (n > sizeof datablk) - n = sizeof datablk; - qlock(cmd); + if (n > DATASIZE) + n = DATASIZE; + cmd = scsicmd(c->dev, 0x0a, n); if (waserror()) { qunlock(cmd); nexterror(); } - cmd->target = c->dev>>3; - cmd->lun = c->dev&7; - cmd->cmd.ptr = cmd->cmd.base; - cmd->cmdblk[0] = 0x0a; cmd->cmdblk[1] = lbn>>16; cmd->cmdblk[2] = lbn>>8; cmd->cmdblk[3] = lbn; cmd->cmdblk[4] = n/d->blocksize; - cmd->cmdblk[5] = 0x00; - cmd->cmd.lim = &cmd->cmdblk[6]; - cmd->data.lim = cmd->data.base + n; - cmd->data.ptr = cmd->data.base; - cmd->save = cmd->data.base; memmove(cmd->data.base, a, n); scsiexec(cmd, 0); n = cmd->data.ptr - cmd->data.base; diff --git a/port/stasync.c b/port/stasync.c index 04d64d0ea2816620f65c75e713af2a9096e1fc2d..fd24e265ba98c74500fb945216c31848f4760a0c 100644 --- a/port/stasync.c +++ b/port/stasync.c @@ -69,6 +69,7 @@ Qinfo asyncinfo = asyncreset }; +static int debugcount = 6; int asyncdebug = 3; int asyncerror; @@ -280,6 +281,10 @@ asyncoput(Queue *q, Block *bp) asputf(ap); ap->chan = chan; + if(asyncdebug > 1) + kprint("a%d->(%d)%3.3uo %d\n", + ap-async, chan, ctl, bp->wptr-bp->rptr); + /* * send the 8 bit data */ @@ -321,6 +326,8 @@ asyncoput(Queue *q, Block *bp) asputf(ap); } } + if(debugcount > 0 && --debugcount == 0) + asyncdebug = 1; qunlock(&ap->xmit); return; @@ -432,9 +439,13 @@ asynciput(Queue *q, Block *bp) showframe("in", ap, ap->buf, ap->icount); if(ap->icount < 5) { DPRINT("a%d pkt too short\n", ap-async); + if(asyncdebug && asyncdebug<=2) + showframe("shortin", ap, ap->buf, ap->icount); ap->tooshort++; } else if(ap->icrc != 0) { DPRINT("a%d bad crc\n", ap-async); + if(asyncdebug && asyncdebug<=2) + showframe("badin", ap, ap->buf, ap->icount); ap->badcrc++; } else { asdeliver(q, ap);