M gnot/dat.h => gnot/dat.h +2 -1
@@ 628,8 628,9 @@ struct Scsidata
struct Scsi
{
QLock;
+ ulong pid;
ushort target, lun;
- ushort state;
+ ushort rflag;
ushort status;
Scsidata cmd;
Scsidata data;
M gnot/devcons.c => gnot/devcons.c +35 -11
@@ 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;
}
M gnot/fns.h => gnot/fns.h +2 -3
@@ 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--
M gnot/l.s => gnot/l.s +30 -19
@@ 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 */
M gnot/screen.c => gnot/screen.c +12 -5
@@ 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?
M port/chan.c => port/chan.c +140 -124
@@ 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; i<pg->nmtab; 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;
}
/*
M port/devbit.c => port/devbit.c +50 -19
@@ 6,6 6,7 @@
#include "errno.h"
#include "devtab.h"
+#include "ureg.h"
#include <libg.h>
#include <gnot.h>
@@ 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 */
@@ 1129,26 1134,52 @@ 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);
}
M port/devlance.c => port/devlance.c +7 -6
@@ 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; i<sizeof(p->data); 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)
M port/devmnt.c => port/devmnt.c +21 -9
@@ 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;
M port/devscsi.c => port/devscsi.c +66 -34
@@ 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);
M port/devwren.c => port/devwren.c +12 -35
@@ 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<target>.<lun>
@@ 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;
M port/stasync.c => port/stasync.c +11 -0
@@ 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);