M gnot/devpipe.c => gnot/devpipe.c +20 -27
@@ 178,7 178,7 @@ pipeopen(Chan *c, int omode)
* pointer from the other stream.
*/
if(streamenter(local)<0)
- panic("pipeattach");
+ panic("pipeopen");
}
unlock(p);
poperror();
@@ 208,43 208,29 @@ pipewstat(Chan *c, char *db)
}
void
-pipeexit(Pipe *p)
-{
- if(decref(p) < 0)
- panic("pipeexit");
- if(p->ref == 0){
- lock(&pipealloc);
- p->next = pipealloc.free;
- pipealloc.free = p;
- unlock(&pipealloc);
- }
-}
-
-void
pipeclose(Chan *c)
{
- Stream *remote;
- Stream *local;
Pipe *p;
p = &pipealloc.pipe[STREAMID(c->qid)/2];
- lock(p);
- if(waserror()){
- unlock(p);
- nexterror();
- }
/*
* take care of associated streams
*/
- if(local = c->stream){
- remote = (Stream *)c->stream->devq->ptr;
+ if(c->stream)
streamclose(c); /* close this stream */
- streamexit(remote, 0); /* release stream for other half of pipe */
+
+ /*
+ * free the structure
+ */
+ if(decref(p) == 0){
+ lock(&pipealloc);
+ p->next = pipealloc.free;
+ pipealloc.free = p;
+ unlock(&pipealloc);
}
- unlock(p);
- poperror();
- pipeexit(p);
+ if(p->ref < 0)
+ panic("pipeexit");
}
long
@@ 315,6 301,7 @@ static void
pipestclose(Queue *q)
{
Block *bp;
+ Stream *remote;
/*
* point to the bit-bucket and let any in-progress
@@ 330,4 317,10 @@ pipestclose(Queue *q)
bp = allocb(0);
bp->type = M_HANGUP;
PUTNEXT(q, bp);
+
+ /*
+ * release stream for other half of pipe
+ */
+ remote = RD(q)->ptr;
+ streamexit(remote, 0);
}
M gnot/stream.c => gnot/stream.c +11 -9
@@ 810,9 810,9 @@ streamclose1(Stream *s)
if(!waserror()){
if(q->info->close)
(*q->info->close)(q->other);
- WR(q)->put = nullput;
+ poperror();
}
- poperror();
+ WR(q)->put = nullput;
/*
* this may be 2 streams joined device end to device end
@@ 820,14 820,14 @@ streamclose1(Stream *s)
if(q == s->devq->other)
break;
}
- }
- /*
- * ascend the stream flushing the queues
- */
- for(q = s->devq; q; q = nq){
- nq = q->next;
- flushq(q);
+ /*
+ * ascend the stream flushing the queues
+ */
+ for(q = s->devq; q; q = nq){
+ nq = q->next;
+ flushq(q);
+ }
}
s->opens--;
@@ 1013,6 1013,8 @@ streamread(Chan *c, void *vbuf, long n)
* hangup -- send an M_HANGUP up the stream
* push ldname -- push the line discipline named ldname
* pop -- pop a line discipline
+ *
+ * This routing is entrered with s->wrlock'ed and must unlock.
*/
static long
streamctlwrite(Chan *c, void *a, long n)
M port/devcons.c => port/devcons.c +9 -0
@@ 311,6 311,7 @@ enum{
Qppid,
Qtime,
Quser,
+ Qvmereset,
};
Dirtab consdir[]={
@@ 324,6 325,7 @@ Dirtab consdir[]={
"ppid", Qppid, 12, 0600,
"time", Qtime, 12, 0600,
"user", Quser, 0, 0600,
+ "vmereset", Qvmereset, 0, 0600,
};
#define NCONS (sizeof consdir/sizeof(Dirtab))
@@ 579,6 581,13 @@ conswrite(Chan *c, void *va, long n)
case Qnull:
break;
+
+ case Qvmereset:
+ if(strcmp(u->p->pgrp->user, "bootes") != 0)
+ error(0, Eperm);
+ vmereset();
+ break;
+
default:
error(0, Egreg);
}
M port/devdk.c => port/devdk.c +2 -1
@@ 6,7 6,7 @@
#include "io.h"
#include "errno.h"
-#define DPRINT if(0) /*kprint*/
+#define DPRINT if(0) print
#define NOW (MACHP(0)->ticks)
@@ 1668,6 1668,7 @@ dktimer(void *a)
/*
* send keep alive
*/
+ DPRINT("keep alive\n");
dkmesg(c, T_ALIVE, D_CONTINUE, 0, 0);
/*
M port/devpipe.c => port/devpipe.c +20 -27
@@ 178,7 178,7 @@ pipeopen(Chan *c, int omode)
* pointer from the other stream.
*/
if(streamenter(local)<0)
- panic("pipeattach");
+ panic("pipeopen");
}
unlock(p);
poperror();
@@ 208,43 208,29 @@ pipewstat(Chan *c, char *db)
}
void
-pipeexit(Pipe *p)
-{
- if(decref(p) < 0)
- panic("pipeexit");
- if(p->ref == 0){
- lock(&pipealloc);
- p->next = pipealloc.free;
- pipealloc.free = p;
- unlock(&pipealloc);
- }
-}
-
-void
pipeclose(Chan *c)
{
- Stream *remote;
- Stream *local;
Pipe *p;
p = &pipealloc.pipe[STREAMID(c->qid)/2];
- lock(p);
- if(waserror()){
- unlock(p);
- nexterror();
- }
/*
* take care of associated streams
*/
- if(local = c->stream){
- remote = (Stream *)c->stream->devq->ptr;
+ if(c->stream)
streamclose(c); /* close this stream */
- streamexit(remote, 0); /* release stream for other half of pipe */
+
+ /*
+ * free the structure
+ */
+ if(decref(p) == 0){
+ lock(&pipealloc);
+ p->next = pipealloc.free;
+ pipealloc.free = p;
+ unlock(&pipealloc);
}
- unlock(p);
- poperror();
- pipeexit(p);
+ if(p->ref < 0)
+ panic("pipeexit");
}
long
@@ 315,6 301,7 @@ static void
pipestclose(Queue *q)
{
Block *bp;
+ Stream *remote;
/*
* point to the bit-bucket and let any in-progress
@@ 330,4 317,10 @@ pipestclose(Queue *q)
bp = allocb(0);
bp->type = M_HANGUP;
PUTNEXT(q, bp);
+
+ /*
+ * release stream for other half of pipe
+ */
+ remote = RD(q)->ptr;
+ streamexit(remote, 0);
}
M port/stream.c => port/stream.c +27 -27
@@ 652,10 652,10 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
*/
for(s = slist; s < &slist[conf.nstream]; s++) {
if(s->inuse == 0){
- if(canlock(s)){
+ if(canqlock(s)){
if(s->inuse == 0)
break;
- unlock(s);
+ qunlock(s);
}
}
}
@@ 664,7 664,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
error(0, Enostream);
}
if(waserror()){
- unlock(s);
+ qunlock(s);
streamclose1(s);
nexterror();
}
@@ 697,7 697,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
if(qi->open)
(*qi->open)(RD(s->devq), s);
- unlock(s);
+ qunlock(s);
poperror();
return s;
}
@@ 717,17 717,17 @@ streamopen(Chan *c, Qinfo *qi)
for(s = slist; s < &slist[conf.nstream]; s++) {
if(s->inuse && s->type == c->type && s->dev == c->dev
&& s->id == STREAMID(c->qid)){
- lock(s);
+ qlock(s);
if(s->inuse && s->type == c->type
&& s->dev == c->dev
&& s->id == STREAMID(c->qid)){
s->inuse++;
s->opens++;
c->stream = s;
- unlock(s);
+ qunlock(s);
return;
}
- unlock(s);
+ qunlock(s);
}
}
@@ 744,13 744,13 @@ streamopen(Chan *c, Qinfo *qi)
int
streamenter(Stream *s)
{
- lock(s);
+ qlock(s);
if(s->opens == 0){
- unlock(s);
+ qunlock(s);
return -1;
}
s->inuse++;
- unlock(s);
+ qunlock(s);
return 0;
}
@@ 767,7 767,7 @@ streamexit(Stream *s, int locked)
char *name;
if(!locked)
- lock(s);
+ qlock(s);
if(s->inuse == 1){
if(s->opens != 0)
panic("streamexit %d %s\n", s->opens, s->devq->info->name);
@@ 784,7 784,7 @@ streamexit(Stream *s, int locked)
s->inuse--;
rv = s->inuse;
if(!locked)
- unlock(s);
+ qunlock(s);
return rv;
}
@@ 801,24 801,24 @@ streamclose1(Stream *s)
/*
* decrement the reference count
*/
- lock(s);
+ qlock(s);
if(s->opens == 1){
- if(!waserror()){
- /*
- * descend the stream closing the queues
- */
- for(q = s->procq; q; q = q->next){
+ /*
+ * descend the stream closing the queues
+ */
+ for(q = s->procq; q; q = q->next){
+ if(!waserror()){
if(q->info->close)
(*q->info->close)(q->other);
- WR(q)->put = nullput;
-
- /*
- * this may be 2 streams joined device end to device end
- */
- if(q == s->devq->other)
- break;
+ poperror();
}
- poperror();
+ WR(q)->put = nullput;
+
+ /*
+ * this may be 2 streams joined device end to device end
+ */
+ if(q == s->devq->other)
+ break;
}
/*
@@ 835,7 835,7 @@ streamclose1(Stream *s)
* leave it and free it
*/
streamexit(s, 1);
- unlock(s);
+ qunlock(s);
}
void
streamclose(Chan *c)
M power/dat.h => power/dat.h +1 -1
@@ 454,7 454,7 @@ struct Queue {
* a stream head
*/
struct Stream {
- Lock; /* structure lock */
+ QLock; /* structure lock */
short inuse; /* number of processes in stream */
short opens; /* number of processes with stream open */
ushort hread; /* number of reads after hangup */
M power/fns.h => power/fns.h +1 -0
@@ 198,6 198,7 @@ void validaddr(ulong, ulong, int);
void vecinit(void);
void vector80(void);
void* vmemchr(void*, int, int);
+void vmereset(void);
void wakeme(Alarm*);
void wakeup(Rendez*);
void wbflush(void);
M power/main.c => power/main.c +22 -13
@@ 103,6 103,25 @@ vecinit(void)
}
/*
+ * reset the vme bus
+ */
+void
+vmereset(void)
+{
+ long i;
+ int noforce;
+
+ if(ioid >= IO3R1)
+ noforce = 1;
+ else
+ noforce = 0;
+ MODEREG->resetforce = (1<<1) | noforce;
+ for(i=0; i<1000000; i++)
+ ;
+ MODEREG->resetforce = noforce;
+}
+
+/*
* We have to program both the IO2 board to generate interrupts
* and the SBCC on CPU 0 to accept them.
*/
@@ 110,25 129,15 @@ void
ioboardinit(void)
{
long i;
- int noforce;
int maxlevel;
ioid = *IOID;
- if(ioid >= IO3R1){
+ if(ioid >= IO3R1)
maxlevel = 11;
- noforce = 1;
- } else {
+ else
maxlevel = 8;
- noforce = 0;
- }
- /*
- * reset VME bus (MODEREG is on the IO2)
- */
- MODEREG->resetforce = (1<<1) | noforce;
- for(i=0; i<1000000; i++)
- ;
- MODEREG->resetforce = noforce;
+ vmereset();
MODEREG->masterslave = (SLAVE<<4) | MASTER;
/*