From 63327bb38850af3de9dc588afc2b0a32b50c25bf Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 19 Feb 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-02-19 --- pc/devhard.c | 26 +- pc/main.c | 2 +- port/bootp.h | 29 + port/devbit.c | 17 +- port/devdk.c | 3 + port/devip.c | 4 + port/devnonet.c | 1513 ----------------------------------------------- port/devwren.c | 18 +- power/boot.c | 112 ---- 9 files changed, 73 insertions(+), 1651 deletions(-) create mode 100644 port/bootp.h delete mode 100644 port/devnonet.c diff --git a/pc/devhard.c b/pc/devhard.c index 3d8b7f49acf44d14ab5d2de58a55f8cf681b665f..edb1ac6c6a12333761dc4aa53475606364e3dd72 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -623,23 +623,19 @@ hardpart(Drive *dp) * parse partition table. */ n = getfields(cp->buf, line, Npart+1, '\n'); - if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0){ - goto out; - } - for(i = 1; i < n; i++){ - pp++; - if(getfields(line[i], field, 3, ' ') != 3){ - break; - } - strncpy(pp->name, field[0], NAMELEN); - pp->start = strtoul(field[1], 0, 0); - pp->end = strtoul(field[2], 0, 0); - if(pp->start > pp->end || pp->start >= dp->p[0].end){ - break; + if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ + for(i = 1; i < n; i++){ + pp++; + if(getfields(line[i], field, 3, ' ') != 3) + break; + strncpy(pp->name, field[0], NAMELEN); + pp->start = strtoul(field[1], 0, 0); + pp->end = strtoul(field[2], 0, 0); + if(pp->start > pp->end || pp->start >= dp->p[0].end) + break; + dp->npart++; } - dp->npart++; } -out: qunlock(cp); poperror(); } diff --git a/pc/main.c b/pc/main.c index 9d36e0e25f6a2a7cc6f54fa9751b94c9ceee91bc..d286417a8cc81c8b1d791877fe3caafcce537d0e 100644 --- a/pc/main.c +++ b/pc/main.c @@ -21,7 +21,7 @@ main(void) confinit(); screeninit(); printinit(); - print("\n\n%ludK bytes of physical memory\n", (conf.base1 + conf.npage1*BY2PG)/1024); + print("%ludK bytes of physical memory\n", (conf.base1 + conf.npage1*BY2PG)/1024); mmuinit(); trapinit(); mathinit(); diff --git a/port/bootp.h b/port/bootp.h new file mode 100644 index 0000000000000000000000000000000000000000..8a1dd2128796a7b9e378a6263434adb87ac4a6d1 --- /dev/null +++ b/port/bootp.h @@ -0,0 +1,29 @@ +/* + * this file used by (at least) snoopy, tboot and bootp + */ +enum +{ + Bootrequest = 1, + Bootreply = 2, +}; + +typedef struct Bootp Bootp; +struct Bootp +{ + uchar op; /* opcode */ + uchar htype; /* hardware type */ + uchar hlen; /* hardware address len */ + uchar hops; /* hops */ + uchar xid[4]; /* a random number */ + uchar secs[2]; /* elapsed snce client started booting */ + uchar pad[2]; + uchar ciaddr[4]; /* client IP address (client tells server) */ + uchar yiaddr[4]; /* client IP address (server tells client) */ + uchar siaddr[4]; /* server IP address */ + uchar giaddr[4]; /* gateway IP address */ + uchar chaddr[16]; /* client hardware address */ + char sname[64]; /* server host name (optional) */ + char file[128]; /* boot file name */ + char vend[128]; /* vendor-specific goo */ +}; + diff --git a/port/devbit.c b/port/devbit.c index 9b73b421d57cae6b5826f2a0c181b6347fef7fc7..caca620fa71819220a70e7436ac8e044b6a3e8a9 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -1324,11 +1324,19 @@ bitloadchar(GFont *f, int ci, GSubfont *subf, int si) GCacheinfo *c; Rectangle rect; Fontchar *fi; + int y; c = &f->cache[ci]; fi = &subf->info[si]; - c->top = fi->top + (f->ascent-subf->ascent); - c->bottom = fi->bottom + (f->ascent-subf->ascent); + /* careful about sign extension: top and bottom are uchars */ + y = fi->top + (f->ascent-subf->ascent); + if(y < 0) + y = 0; + c->top = y; + y = fi->bottom + (f->ascent-subf->ascent); + if(y < 0) + y = 0; + c->bottom = y; c->width = fi->width; c->left = fi->left; c->x = ci*f->width; @@ -1340,7 +1348,12 @@ bitloadchar(GFont *f, int ci, GSubfont *subf, int si) gbitblt(f->b, rect.min, f->b, rect, 0); rect.min.x = fi->x; rect.max.x = (fi+1)->x; + rect.max.y = subf->height; gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); +/* +gbitblt(&gscreen, Pt(0,0), f->b, f->b->r, S); +gbitblt(&gscreen, Pt(0,30), f->b, Rect(c->x, 0, c->x+f->width,f->height), S); +*/ } QLock bitlock; diff --git a/port/devdk.c b/port/devdk.c index 866030f74937e5f598e66047efbdbd18d869ba0c..96c9e67df6f9cd2d070f07301e09a907ab60dcb4 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -316,6 +316,9 @@ dkmuxopen(Queue *q, Stream *s) { RD(q)->ptr = s; WR(q)->ptr = 0; + + s->opens++; /* Hold this queue in place */ + s->inuse++; } /* diff --git a/port/devip.c b/port/devip.c index ceaab492b8a31985486dc8436375d4b596f4bf45..e9a6890f51e5e3764de3c5cbe374efdec9428f9d 100644 --- a/port/devip.c +++ b/port/devip.c @@ -100,6 +100,10 @@ ipattach(char *spec) Chan *c; int i; + /* fail if ip is not yet configured */ + if(Ipoutput == 0) + error(Enoproto); + for(i = 0; protocols[i]; i++) { if(strcmp(spec, protocols[i]->name) == 0) { c = devattach('I', spec); diff --git a/port/devnonet.c b/port/devnonet.c deleted file mode 100644 index 079e72666a73b1a5aa505961ce7ae55f33098fb2..0000000000000000000000000000000000000000 --- a/port/devnonet.c +++ /dev/null @@ -1,1513 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/nonet.h" - -#define DPRINT if(pnonet)print -#define NOW (MACHP(0)->ticks*MS2HZ) -#define MSUCC(x) (((x)+1)%Nnomsg) - -static Noifc *noifc; -int pnonet; - -enum { - /* - * tuning parameters - */ - MSrexmit = 250, /* retranmission interval in ms */ - - /* - * relative or immutable - */ - Nsubdir = 5, /* entries in the nonet directory */ - Nmask = Nnomsg - 1, /* mask for log(Nnomsg) bits */ -}; - -/* predeclared */ -static void nohangup(Noconv*); -static void noreset(Noconv*); -static Block* nohdr(Noconv*, int); -static void nolisten(Chan*, Noifc*); -static void noannounce(Chan*, char*); -static void noconnect(Chan*, char*); -static void norack(Noconv*, int); -static void nosendctl(Noconv*, int, int); -static void nosend(Noconv*, Nomsg*); -static void nostartconv(Noconv*, int, char*, int); -static void noqack(Noconv*, int); -static void nokproc(void*); -static void noiput(Queue*, Block*); -static void nooput(Queue*, Block*); -static void noclose(Queue*); -static void noopen(Queue*, Stream*); - -extern Qinfo noetherinfo; -extern Qinfo nonetinfo; - -/* - * nonet directory and subdirectory - */ -enum { - /* - * per conversation - */ - Naddrqid, - Nlistenqid, - Nraddrqid, - Nruserqid, - Nstatsqid, - Nchanqid, - - /* - * per noifc - */ - Ncloneqid, -}; - -Dirtab *nonetdir; -Dirtab nosubdir[]={ - "addr", {Naddrqid}, 0, 0666, - "listen", {Nlistenqid}, 0, 0666, - "raddr", {Nraddrqid}, 0, 0666, - "ruser", {Nruserqid}, 0, 0666, - "stats", {Nstatsqid}, 0, 0666, -}; - -/* - * Nonet conversation states (for Noconv.state) - */ -enum { - Cclosed= 0, - Copen= 1, - Cannounced= 2, - Cconnected= 3, - Cconnecting= 4, - Chungup= 5, - Creset= 6, -}; - -/* - * nonet kproc - */ -static int kstarted; -static Rendez nonetkr; - -/* - * nonet file system. most of the calls use dev.c to access the nonet - * directory and stream.c to access the nonet devices. - * create the nonet directory. the files are `clone' and stream - * directories '1' to '32' (or whatever conf.noconv is in decimal) - */ -void -nonetreset(void) -{ - int i; - - /* - * allocate the interfaces - */ - noifc = (Noifc *)ialloc(sizeof(Noifc) * conf.nnoifc, 0); - for(i = 0; i < conf.nnoifc; i++) - noifc[i].conv = (Noconv *)ialloc(sizeof(Noconv) * conf.nnoconv, 0); - - /* - * create the directory. - */ - nonetdir = (Dirtab *)ialloc(sizeof(Dirtab) * (conf.nnoconv+1), 0); - - /* - * the circuits - */ - for(i = 0; i < conf.nnoconv; i++) { - sprint(nonetdir[i].name, "%d", i); - nonetdir[i].qid.path = CHDIR|STREAMQID(i, Nchanqid); - nonetdir[i].qid.vers = 0; - nonetdir[i].length = 0; - nonetdir[i].perm = 0777; - } - - /* - * the clone device - */ - strcpy(nonetdir[i].name, "clone"); - nonetdir[i].qid.path = Ncloneqid; - nonetdir[i].qid.vers = 0; - nonetdir[i].length = 0; - nonetdir[i].perm = 0666; -} - -void -nonetinit(void) -{ -} - -/* - * find an noifc and increment its count - */ -Chan* -nonetattach(char *spec) -{ - Noifc *ifc; - Chan *c; - - /* - * find an noifc with the same name - */ - if(*spec == 0) - spec = "nonet"; - for(ifc = noifc; ifc < &noifc[conf.nnoifc]; ifc++){ - lock(ifc); - if(strcmp(spec, ifc->name)==0 && ifc->wq) { - ifc->ref++; - unlock(ifc); - break; - } - unlock(ifc); - } - if(ifc == &noifc[conf.nnoifc]) - error(Enoifc); - c = devattach('n', spec); - c->dev = ifc - noifc; - - return c; -} - -/* - * up the reference count to the noifc - */ -Chan* -nonetclone(Chan *c, Chan *nc) -{ - Noifc *ifc; - - c = devclone(c, nc); - ifc = &noifc[c->dev]; - lock(ifc); - ifc->ref++; - unlock(ifc); - return c; -} - -int -nonetwalk(Chan *c, char *name) -{ - if(c->qid.path == CHDIR) - return devwalk(c, name, nonetdir, conf.nnoconv+1, devgen); - else - return devwalk(c, name, nosubdir, Nsubdir, streamgen); -} - -void -nonetstat(Chan *c, char *dp) -{ - if(c->qid.path == CHDIR) - devstat(c, dp, nonetdir, conf.nnoconv+1, devgen); - else if(c->qid.path == Ncloneqid) - devstat(c, dp, &nonetdir[conf.nnoconv], 1, devgen); - else - devstat(c, dp, nosubdir, Nsubdir, streamgen); -} - -/* - * opening a nonet device allocates a Noconv. Opening the `clone' - * device is a ``macro'' for finding a free Noconv and opening - * it's ctl file. - */ -Noconv * -nonetopenclone(Chan *c, Noifc *ifc) -{ - Noconv *cp; - Noconv *ep; - - ep = &ifc->conv[conf.nnoconv]; - for(cp = &ifc->conv[0]; cp < ep; cp++){ - if(cp->state == Cclosed && canqlock(cp)){ - if(cp->state != Cclosed){ - qunlock(cp); - continue; - } - c->qid.path = CHDIR|STREAMQID(cp-ifc->conv, Nchanqid); - devwalk(c, "ctl", 0, 0, streamgen); - streamopen(c, &nonetinfo); - qunlock(cp); - break; - } - } - if(cp == ep) - error(Enodev); - return cp; -} - -Chan* -nonetopen(Chan *c, int omode) -{ - Stream *s; - Noifc *ifc; - int line; - - if(!kstarted){ - kproc("nonetack", nokproc, 0); - kstarted = 1; - } - - if(c->qid.path & CHDIR){ - /* - * directories are read only - */ - if(omode != OREAD) - error(Ebadarg); - } else switch(STREAMTYPE(c->qid.path)){ - case Ncloneqid: - /* - * get an unused device and open it's control file - */ - ifc = &noifc[c->dev]; - nonetopenclone(c, ifc); - break; - case Nlistenqid: - /* - * listen for a call and open the control file for the - * channel on which the call arrived. - */ - line = STREAMID(c->qid.path); - ifc = &noifc[c->dev]; - if(ifc->conv[line].state != Cannounced) - error(Enolisten); - nolisten(c, ifc); - break; - case Nraddrqid: - /* - * read only files - */ - if(omode != OREAD) - error(Ebadarg); - break; - default: - /* - * open whatever c points to - */ - streamopen(c, &nonetinfo); - break; - } - - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -nonetcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -nonetclose(Chan *c) -{ - Noifc *ifc; - - if(c->stream) - streamclose(c); - - /* - * let go of the multiplexor - */ - nonetfreeifc(&noifc[c->dev]); -} - -long -nonetread(Chan *c, void *a, long n, ulong offset) -{ - int t; - Noconv *cp; - char stats[256]; - - /* - * pass data/ctl reads onto the stream code - */ - t = STREAMTYPE(c->qid.path); - if(t >= Slowqid) - return streamread(c, a, n); - - if(c->qid.path == CHDIR) - return devdirread(c, a, n, nonetdir, conf.nnoconv+1, devgen); - if(c->qid.path & CHDIR) - return devdirread(c, a, n, nosubdir, Nsubdir, streamgen); - - cp = &noifc[c->dev].conv[STREAMID(c->qid.path)]; - switch(t){ - case Nraddrqid: - return stringread(a, n, cp->raddr, offset); - case Naddrqid: - return stringread(a, n, cp->addr, offset); - case Nruserqid: - return stringread(a, n, cp->ruser, offset); - case Nstatsqid: - sprint(stats, "sent: %d\nrcved: %d\nrexmit: %d\nbad: %d\n", - cp->sent, cp->rcvd, cp->rexmit, cp->bad); - return stringread(a, n, stats, offset); - } - error(Eperm); -} - -long -nonetwrite(Chan *c, void *a, long n, ulong offset) -{ - int t; - int m; - char buf[256]; - char *field[5]; - - t = STREAMTYPE(c->qid.path); - - /* - * get data dispatched as quickly as possible - */ - if(t == Sdataqid) - return streamwrite(c, a, n, 0); - - /* - * easier to do here than in nooput - */ - if(t == Sctlqid){ - if(n > sizeof buf - 1) - n = sizeof buf - 1; - strncpy(buf, a, n); - buf[n] = '\0'; - m = getfields(buf, field, 5, ' '); - if(strcmp(field[0], "connect")==0){ - if(m < 2) - error(Ebadarg); - noconnect(c, field[1]); - } else if(strcmp(field[0], "announce")==0){ - noannounce(c, field[1]); - } else if(strcmp(field[0], "accept")==0){ - /* ignore */; - } else if(strcmp(field[0], "reject")==0){ - /* ignore */; - } else - return streamwrite(c, a, n, 0); - return n; - } - - error(Eperm); -} - -void -nonetremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -nonetwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -/* - * the device stream module definition - */ -Qinfo nonetinfo = -{ - noiput, - nooput, - noopen, - noclose, - "nonet" -}; - -/* - * store the device end of the stream so that the multiplexor can - * send blocks upstream. - * - * State Transition: Cclosed -> Copen - */ -static void -noopen(Queue *q, Stream *s) -{ - Noifc *ifc; - Noconv *cp; - - ifc = &noifc[s->dev]; - cp = &ifc->conv[s->id]; - cp->s = s; - cp->ifc = ifc; - cp->rq = RD(q); - cp->state = Copen; - RD(q)->ptr = WR(q)->ptr = (void *)cp; -} - -/* - * wait until a hangup is received. - * then send a hangup message (until one is received). - * - * State Transitions: * -> Cclosed - */ -static int -ishungup(void *a) -{ - Noconv *cp; - - cp = (Noconv *)a; - switch(cp->state){ - case Chungup: - case Creset: - case Cclosed: - return 1; - } - return 0; -} -static int -isempty(void *a) -{ - Noconv *cp; - - cp = (Noconv *)a; - switch(cp->state){ - case Cconnecting: - case Cconnected: - return cp->first == cp->next; - default: - return 1; - } -} -static void -noclose(Queue *q) -{ - Noconv *cp; - Nomsg *mp; - int i; - - cp = (Noconv *)q->ptr; - - if(!waserror()){ - /* - * wait till we have nothing to transmit - */ - while(!isempty(cp)) - tsleep(&cp->r, isempty, cp, MSrexmit); - - /* - * send hangup messages to the other side - * until it hangs up or we get tired. - */ - switch(cp->state){ - case Cconnecting: - case Cconnected: - /* - * send close till we get one back - */ - nosendctl(cp, NO_HANGUP, 1); - for(i=0; i<10 && !ishungup(cp); i++){ - nosendctl(cp, NO_HANGUP, 0); - tsleep(&cp->r, ishungup, cp, MSrexmit); - } - break; - case Chungup: - /* - * ack any close - */ - nosendctl(cp, NO_HANGUP, 1); - break; - } - poperror(); - } - - /* - * we give up, ack any unacked messages - */ - qlock(cp); - for(i = cp->first; i != cp->next; i = MSUCC(i)) - norack(cp, cp->out[i].mid); - cp->rcvcircuit = -1; - cp->state = Cclosed; - if(cp->media){ - freeb(cp->media); - cp->media = 0; - } - qunlock(cp); -} - -/* - * send all messages up stream. this should only be control messages - * - * State Transition: (on M_HANGUP) * -> Chungup - */ -static void -noiput(Queue *q, Block *bp) -{ - Noconv *cp; - - if(bp->type == M_HANGUP){ - cp = (Noconv *)q->ptr; - cp->state = Chungup; - } - PUTNEXT(q, bp); -} - -/* - * queue a block - */ -enum { - Window= 1, -}; - -static int -windowopen(void *a) -{ - Noconv *cp; - int i; - - cp = (Noconv *)a; - i = cp->next - cp->first; - if(i>=0 && iptr); - - /* - * do all control functions - */ - if(bp->type != M_DATA){ - freeb(bp); - error(Ebadctl); - } - - /* - * collect till we see a delim - */ - qlock(&cp->mlock); - if(!putb(q, bp)){ - qunlock(&cp->mlock); - return; - } - - /* - * take the collected message out of the queue - */ - first = q->first; - last = q->last; - len = q->len; - q->len = q->nb = 0; - q->first = q->last = 0; - if(len == 0){ - freeb(first); - qunlock(&cp->mlock); - return; - } - - /* - * block till we get an output buffer - */ - if(waserror()){ - freeb(first); - qunlock(&cp->mlock); - nexterror(); - } - while(!windowopen(cp)) - sleep(&cp->r, windowopen, cp); - mp = &cp->out[cp->next]; - cp->next = MSUCC(cp->next); - qlock(cp); - qunlock(&cp->mlock); - poperror(); - - /* - * point the output buffer to the message - */ - mp->time = NOW + MSrexmit; - mp->first = first; - mp->last = last; - mp->len = len; - mp->mid ^= Nnomsg; - mp->acked = 0; - - cp->sent++; - - /* - * send the message, the kproc will retry - */ - if(!waserror()){ - nosend(cp, mp); - poperror(); - } - qunlock(cp); -} - -/* - * start a new conversation. start an ack/retransmit process if - * none already exists for this circuit. - */ -void -nostartconv(Noconv *cp, int circuit, char *raddr, int state) -{ - int i; - char name[32]; - Noifc *ifc; - - ifc = cp->ifc; - - /* - * allocate the prototype header - */ - cp->media = allocb(ifc->hsize + NO_HDRSIZE); - cp->media->wptr += ifc->hsize + NO_HDRSIZE; - cp->hdr = (Nohdr *)(cp->media->rptr + ifc->hsize); - - /* - * fill in the circuit number - */ - cp->hdr->flag = NO_NEWCALL|NO_ACKME; - cp->hdr->circuit[2] = circuit>>16; - cp->hdr->circuit[1] = circuit>>8; - cp->hdr->circuit[0] = circuit; - - /* - * set the state variables - */ - cp->state = state; - for(i = 1; i < Nnomsg; i++){ - cp->in[i].mid = i; - cp->in[i].acked = 0; - cp->in[i].rem = 0; - cp->out[i].mid = i | Nnomsg; - cp->out[i].acked = 1; - cp->out[i].rem = 0; - } - cp->in[0].mid = Nnomsg; - cp->in[0].acked = 0; - cp->in[0].rem = 0; - cp->out[0].mid = 0; - cp->out[0].acked = 1; - cp->out[0].rem = 0; - cp->ack = 0; - cp->sendack = 0; - cp->first = cp->next = 1; - cp->rexmit = cp->bad = cp->sent = cp->rcvd = 0; - cp->lastacked = Nnomsg|(Nnomsg-1); - - /* - * used for demultiplexing - */ - cp->rcvcircuit = circuit ^ 1; - - /* - * media dependent header - */ - (*ifc->connect)(cp, raddr); - - /* - * status files - */ - strncpy(cp->raddr, raddr, sizeof(cp->raddr)); - strcpy(cp->ruser, "none"); -} - -/* - * announce willingness to take calls - * - * State Transition: Copen -> Chungup - */ -static void -noannounce(Chan *c, char *addr) -{ - Noconv *cp; - - cp = (Noconv *)(c->stream->devq->ptr); - if(cp->state != Copen) - error(Einuse); - cp->state = Cannounced; -} - -/* - * connect to the destination whose name is pointed to by bp->rptr. - * - * a service is separated from the destination system by a '!' - * - * State Transition: Copen -> Cconnecting - */ -static void -noconnect(Chan *c, char *addr) -{ - Noifc *ifc; - Noconv *cp; - char *service; - char buf[2*NAMELEN+2]; - - cp = (Noconv *)(c->stream->devq->ptr); - if(cp->state != Copen) - error(Einuse); - ifc = cp->ifc; - service = strchr(addr, '!'); - if(service){ - *service++ = 0; - if(strchr(service, ' ')) - error(Ebadctl); - if(strlen(service) > NAMELEN) - error(Ebadctl); - } - - nostartconv(cp, 2*(cp - ifc->conv), addr, Cconnecting); - - if(service){ - /* - * send service name and user name - */ - cp->hdr->flag |= NO_SERVICE; - sprint(buf, "%s %s", service, u->p->user); - c->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid); - streamwrite(c, buf, strlen(buf), 1); - c->qid.path = STREAMQID(STREAMID(c->qid.path), Sctlqid); - } -} - -/* - * listen for a call. There can be many listeners, but only one can sleep - * on the circular queue at a time. ifc->listenl lets only one at a time into - * the sleep. - * - * State Transition: Cclosed -> Copen -> Cconnecting - */ -static int -iscall(void *a) -{ - Noifc *ifc; - - ifc = (Noifc *)a; - return ifc->rptr != ifc->wptr; -} -static void -nolisten(Chan *c, Noifc *ifc) -{ - Noconv *cp, *ep; - Nocall call; - int f; - char buf[2*NAMELEN+4]; - char *user; - long n; - Block *bp; - - call.msg = 0; - - if(waserror()){ - if(call.msg) - freeb(call.msg); - qunlock(&ifc->listenl); - nexterror(); - } - - for(;;){ - /* - * one listener at a time - */ - qlock(&ifc->listenl); - - /* - * wait for a call - */ - sleep(&ifc->listenr, iscall, ifc); - call = ifc->call[ifc->rptr]; - ifc->rptr = (ifc->rptr+1) % Nnocalls; - qunlock(&ifc->listenl); - - /* - * make sure we aren't already using this circuit - */ - ep = &ifc->conv[conf.nnoconv]; - for(cp = &ifc->conv[0]; cp < ep; cp++){ - if(cp->state>Cannounced && (call.circuit^1)==cp->rcvcircuit - && strcmp(call.raddr, cp->raddr)==0) - break; - } - if(cp != ep){ - freeb(call.msg); - call.msg = 0; - continue; - } - - /* - * get a free channel - */ - cp = nonetopenclone(c, ifc); - c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid); - - /* - * start the protocol and - * stuff the connect message into it - */ - f = ((Nohdr *)(call.msg->rptr))->flag; - nostartconv(cp, call.circuit, call.raddr, Cconnecting); - bp = call.msg; - call.msg = 0; - switch(nonetrcvmsg(cp, bp)){ - case -1: - print("bad call message"); - streamclose(c); - continue; - case 0: - if(f & NO_SERVICE){ - streamclose(c); - print("bad call message"); - continue; - } - break; - default: - if(f & NO_SERVICE){ - c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid); - n = streamread(c, buf, sizeof(buf)); - c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid); - if(n <= 0) - error(Ebadctl); - buf[n] = 0; - user = strchr(buf, ' '); - if(user){ - *user++ = 0; - strncpy(cp->ruser, user, NAMELEN); - } else - strcpy(cp->ruser, "none"); - strncpy(cp->addr, buf, NAMELEN); - } - break; - } - break; - } - poperror(); -} - -/* - * send a hangup signal up the stream to get all line disciplines - * to cease and desist - * - * State Transition: {Cconnected, Cconnecting} -> Chungup - */ -static void -nohangup(Noconv *cp) -{ - Block *bp; - Queue *q; - - switch(cp->state){ - case Cconnected: - case Cconnecting: - cp->state = Chungup; - bp = allocb(0); - bp->type = M_HANGUP; - q = cp->rq; - PUTNEXT(q, bp); - break; - } - wakeup(&cp->r); -} - -/* - * Send a hangup signal up the stream to get all line disciplines - * to cease and desist. Disassociate this conversation from a circuit - * number. Any subsequent close of the conversation will - * not send hangup messages. - * - * State Transition: {Cconnected, Cconnecting, Chungup} -> Creset - */ -static void -noreset(Noconv *cp) -{ - Block *bp; - Queue *q; - - switch(cp->state){ - case Cconnected: - case Cconnecting: - case Chungup: - cp->state = Creset; - cp->rcvcircuit = -1; - bp = allocb(0); - bp->type = M_HANGUP; - q = cp->rq; - PUTNEXT(q, bp); - break; - } - wakeup(&cp->r); -} - -/* - * process a message acknowledgement. if the message - * has any xmit buffers queued, free them. - */ -static void -norack(Noconv *cp, int mid) -{ - Nomsg *mp; - Block *bp; - int i; - - mp = &cp->out[mid & Nmask]; - - /* - * if already acked, ignore - */ - if(mp->acked || mp->mid != mid) - return; - - /* - * free it - */ - cp->rexmit = 0; - cp->lastacked = mid; - mp->acked = 1; - if(mp->first) - freeb(mp->first); - mp->first = 0; - - /* - * advance first if this is the first - */ - if((mid&Nmask) == cp->first){ - while(cp->first != cp->next){ - if(cp->out[cp->first].acked == 0) - break; - cp->first = MSUCC(cp->first); - } - wakeup(&cp->r); - } -} - -/* - * queue an acknowledgement to be sent. ignore it if we already have Nnomsg - * acknowledgements queued. - */ -static void -noqack(Noconv *cp, int mid) -{ - cp->ack = mid; - cp->sendack = 1; -} - -/* - * make a packet header - */ -Block * -nohdr(Noconv *cp, int rem) -{ - Block *bp; - Nohdr *hp; - - bp = allocb(cp->ifc->hsize + NO_HDRSIZE + cp->ifc->mintu); - memmove(bp->wptr, cp->media->rptr, cp->ifc->hsize + NO_HDRSIZE); - bp->wptr += cp->ifc->hsize + NO_HDRSIZE; - hp = (Nohdr *)(bp->rptr + cp->ifc->hsize); - hp->remain[1] = rem>>8; - hp->remain[0] = rem; - hp->sum[0] = hp->sum[1] = 0; - - return bp; -} - -/* - * transmit a message. this involves breaking a possibly multi-block message into - * a train of packets on the media. - * - * called by nooput(). the qlock(mp) synchronizes these two - * processes. - */ -static void -nosend(Noconv *cp, Nomsg *mp) -{ - Noifc *ifc; - Queue *wq; - int msgrem; - int pktrem; - int n; - Block *bp, *pkt, *last; - uchar *rptr; - - ifc = cp->ifc; - if(ifc == 0) - return; - wq = ifc->wq->next; - - /* - * get the next acknowledge to use if the next queue up - * is not full. - */ - cp->sendack = 0; - cp->hdr->ack = cp->ack; - cp->hdr->mid = mp->mid; - - /* - * package n blocks into m packets. make sure - * no packet is < mintu or > maxtu in length. - */ - if(ifc->mintu > mp->len) { - /* - * short message: - * copy the whole message into the header block - */ - last = pkt = nohdr(cp, mp->len); - for(bp = mp->first; bp; bp = bp->next){ - memmove(pkt->wptr, bp->rptr, n = BLEN(bp)); - pkt->wptr += n; - } - /* - * round up to mintu - */ - memset(pkt->wptr, 0, n = ifc->mintu-mp->len); - pkt->wptr += n; - } else { - /* - * long message: - * break up the message into noifc packets and send them. - * once around this loop for each non-header block generated. - */ - msgrem = mp->len; - pktrem = msgrem > ifc->maxtu ? ifc->maxtu : msgrem; - bp = mp->first; - SET(rptr); - if(bp) - rptr = bp->rptr; - last = pkt = nohdr(cp, msgrem); - n = 0; - while(bp){ - /* - * if pkt full, send and create new header block - */ - if(pktrem == 0){ - nonetcksum(pkt, ifc->hsize); - last->flags |= S_DELIM; - (*wq->put)(wq, pkt); - last = pkt = nohdr(cp, -msgrem); - pktrem = msgrem > ifc->maxtu ? ifc->maxtu : msgrem; - } - n = bp->wptr - rptr; - if(n > pktrem) - n = pktrem; - last = last->next = allocb(0); - last->rptr = rptr; - last->wptr = rptr = rptr + n; - msgrem -= n; - pktrem -= n; - if(rptr >= bp->wptr){ - bp = bp->next; - if(bp) - rptr = bp->rptr; - } - } - /* - * round up last packet to mintu - */ - if(n < ifc->mintu){ - n = ifc->mintu - n; - last = last->next = allocb(n); - memset(last->wptr, 0, n); - last->wptr += n; - } - } - nonetcksum(pkt, ifc->hsize); - last->flags |= S_DELIM; - if(cp->rexmit > 10) - mp->time = NOW + 10*MSrexmit; - else - mp->time = NOW + (cp->rexmit+1)*MSrexmit; - - (*wq->put)(wq, pkt); -} - -/* - * send a control message (hangup or acknowledgement). - */ -static void -nosendctl(Noconv *cp, int flag, int new) -{ - Nomsg ctl; - - ctl.len = 0; - ctl.first = 0; - ctl.acked = 0; - if(new) - ctl.mid = Nnomsg^cp->out[cp->next].mid; - else - ctl.mid = cp->lastacked; - cp->hdr->flag |= flag; - nosend(cp, &ctl); -} - -/* - * receive a message (called by the multiplexor; noetheriput, nofddiiput, ...) - * - * State Transition: (no NO_NEWCALL in msg) Cconnecting -> Cconnected - */ -int -nonetrcvmsg(Noconv *cp, Block *bp) -{ - Block *nbp; - Nohdr *h; - short r; - int c; - Nomsg *mp; - int f; - Queue *q; - - q = cp->rq; - - /* - * grab the packet header, push the pointer past the nonet header - */ - h = (Nohdr *)bp->rptr; - bp->rptr += NO_HDRSIZE; - mp = &cp->in[h->mid & Nmask]; - r = (h->remain[1]<<8) | h->remain[0]; - f = h->flag; - - /* - * Obey reset even if the message id is bogus - */ - if(f & NO_RESET){ - DPRINT("reset received\n"); - noreset(cp); - freeb(bp); - return -1; - } - - /* - * A new call request (maybe), treat it as a reset if seen on a - * connected, hungup, or reset channel. - * - * On a connecting channel, treat as a reset if this is an - * invalid message ID. - */ - if(f & NO_NEWCALL){ - switch(cp->state){ - case Cclosed: - case Copen: - case Cannounced: - case Creset: - DPRINT("nonetrcvmsg %d %d\n", cp->rcvcircuit, cp - cp->ifc->conv); - freeb(bp); - return -1; - case Chungup: - case Cconnected: - DPRINT("Nonet call on connected/hanging-up circ %d conv %d\n", - cp->rcvcircuit, cp - cp->ifc->conv); - freeb(bp); - noreset(cp); - return -1; - case Cconnecting: - break; - } - } - - /* - * ignore old messages and process the acknowledgement - */ - if(h->mid!=mp->mid || (f&NO_NULL)){ - DPRINT("old msg %d instead of %d r==%d\n", h->mid, mp->mid, r); - if(r == 0){ - norack(cp, h->ack); - if(f & NO_HANGUP) - nohangup(cp); - } else { - if(r>0){ - norack(cp, h->ack); - noqack(cp, h->mid); - } - cp->bad++; - } - freeb(bp); - return -1; - } - - if(r>=0){ - /* - * start of message packet - */ - if(mp->first){ - DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r); - freeb(mp->first); - mp->first = mp->last = 0; - mp->len = 0; - } - mp->rem = r; - } else { - /* - * a continuation - */ - if(-r != mp->rem) { - DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r); - cp->bad++; - freeb(bp); - return -1; - } - } - - /* - * take care of packets that were padded up - */ - mp->rem -= BLEN(bp); - if(mp->rem < 0){ - if(-mp->rem <= BLEN(bp)){ - bp->wptr += mp->rem; - mp->rem = 0; - } else - panic("nonetrcvmsg: short packet"); - } - putb(mp, bp); - - /* - * if the last chunk - pass it up the stream and wake any - * waiting process. - * - * if not, strip off the delimiter. - */ - if(mp->rem == 0){ - cp->hdr->flag &= ~(NO_NEWCALL|NO_SERVICE); - norack(cp, h->ack); - if(f & NO_ACKME) - noqack(cp, h->mid); - mp->last->flags |= S_DELIM; - PUTNEXT(q, mp->first); - r = mp->len; - mp->first = mp->last = 0; - mp->len = 0; - cp->rcvd++; - - /* - * cycle bufffer to next expected mid - */ - mp->mid ^= Nnomsg; - - /* - * any NO_NEWCALL after this is another call - */ - if(cp->state==Cconnecting && !(f&NO_NEWCALL)) - cp->state = Cconnected; - - /* - * hangup (after processing message) - */ - if(f & NO_HANGUP){ - DPRINT("hangup with message\n"); - nohangup(cp); - return -1; - } - return r; - } else { - mp->last->flags &= ~S_DELIM; - return 0; - } -} - - -/* - * noifc - */ -/* - * Create an ifc. - */ -Noifc * -nonetnewifc(Queue *q, Stream *s, int maxtu, int mintu, int hsize, - void (*connect)(Noconv *, char *)) -{ - Noifc *ifc; - int i; - - for(ifc = noifc; ifc < &noifc[conf.nnoifc]; ifc++){ - if(ifc->ref == 0){ - lock(ifc); - if(ifc->ref) { - /* someone was faster than us */ - unlock(ifc); - continue; - } - RD(q)->ptr = WR(q)->ptr = (void *)ifc; - for(i = 0; i < conf.nnoconv; i++) - ifc->conv[i].rcvcircuit = -1; - ifc->maxtu = maxtu - hsize - NO_HDRSIZE; - ifc->mintu = mintu - hsize - NO_HDRSIZE; - ifc->hsize = hsize; - ifc->connect = connect; - ifc->name[0] = 0; - ifc->wq = WR(q); - ifc->ref = 1; - unlock(ifc); - return ifc; - } - } - error(Enoifc); -} - -/* - * Free an noifc. - */ -void -nonetfreeifc(Noifc *ifc) -{ - lock(ifc); - ifc->ref--; - if(ifc->ref == 0) - ifc->wq = 0; - unlock(ifc); -} - -/* - * calculate the checksum of a list of blocks. ignore the first `offset' bytes. - */ -int -nonetcksum(Block *bp, int offset) -{ - uchar *ep, *p; - int n; - ulong s; - Nohdr *hp; - Block *first; - - s = 0; - p = bp->rptr + offset; - n = bp->wptr - p; - hp = (Nohdr *)p; - hp->sum[0] = hp->sum[1] = 0; - for(;;){ - ep = p+(n&~0x7); - while(p < ep) { - s = s + s + p[0]; - s = s + s + p[1]; - s = s + s + p[2]; - s = s + s + p[3]; - s = s + s + p[4]; - s = s + s + p[5]; - s = s + s + p[6]; - s = s + s + p[7]; - s = (s&0xffff) + (s>>16); - p += 8; - } - ep = p+(n&0x7); - while(p < ep) { - s = s + s + *p; - p++; - } - s = (s&0xffff) + (s>>16); - bp = bp->next; - if(bp == 0) - break; - p = bp->rptr; - n = BLEN(bp); - } - s = (s&0xffff) + (s>>16); - hp->sum[1] = s>>8; - hp->sum[0] = s; - s &= 0xffff; -if(0) - switch(s){ - case 0xac9f: - case 0xc1a4: - case 0xc41c: - case 0xc46d: - { int i; - print("%lux s,", s); - for(bp = first; bp; bp = bp->next) - for(i = 0; i < BLEN(bp); i++) - print(" %ux", bp->rptr[i]); - } - } - return s; -} - -/* - * send acknowledges that need to be sent. this happens at 1/2 - * the retransmission interval. - */ -static void -nokproc(void *arg) -{ - Noifc *ifc; - Noconv *cp, *ep; - Nomsg *mp; - - USED(arg); - cp = 0; - ifc = 0; - if(waserror()){ - if(ifc) - unlock(ifc); - if(cp) - qunlock(cp); - } - - for(;;){ - /* - * loop through all active interfaces - */ - for(ifc = noifc; ifc < &noifc[conf.nnoifc]; ifc++){ - if(ifc->wq==0) - continue; - lock(ifc); - if(ifc->wq==0){ - unlock(ifc); - continue; - } - ifc->ref++; - unlock(ifc); - - /* - * loop through all active conversations - */ - ep = ifc->conv + conf.nnoconv; - for(cp = ifc->conv; cp < ep; cp++){ - if(cp->state<=Copen || !canqlock(cp)) - continue; - if(cp->state != Cconnected && cp->state != Cconnecting){ - qunlock(cp); - continue; - } - - /* - * resend the first message - */ - if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ - mp = &(cp->out[cp->first]); - if(cp->rexmit++ > 15){ - norack(cp, mp->mid); - noreset(cp); - } else - nosend(cp, mp); - } - - /* - * get the acknowledges out - */ - if(cp->sendack){ - DPRINT("sending ack %d\n", cp->ack); - nosendctl(cp, /*NO_NULL*/0, 0); - } - qunlock(cp); - } - nonetfreeifc(ifc); - } - tsleep(&nonetkr, return0, 0, MSrexmit); - } -} - -void -nonettoggle(void) -{ - pnonet ^= 1; -} - diff --git a/port/devwren.c b/port/devwren.c index 2815e14f66e769e97c9ce111766606a114e2ed1f..f2e4e0a19eceaab1a15b8aaacdc4a8fe84260b7c 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -263,9 +263,13 @@ wrenpart(int dev) ulong n; int i; - scsiready(dev); - scsisense(dev, buf); - if (scsicap(dev, buf)) + if(scsiready(dev)){ + scsisense(dev, buf); + if(scsiready(dev)) + print("scsi %d.%d not ready: sense 0x%2.2ux, code 0x%2.2ux\n", + dev>>3, dev&7, buf[2], buf[12]); + } + if(scsicap(dev, buf)) error(Eio); dp = &wren[dev]; dp->drive = dev; @@ -301,18 +305,16 @@ wrenpart(int dev) * parse partition table. */ n = getfields(rawpart, line, Npart+1, '\n'); - if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ + if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ for(i = 1; i < n; i++){ pp++; - if(getfields(line[i], field, 3, ' ') != 3){ + if(getfields(line[i], field, 3, ' ') != 3) break; - } strncpy(pp->name, field[0], NAMELEN); pp->start = strtoul(field[1], 0, 0); pp->end = strtoul(field[2], 0, 0); - if(pp->start > pp->end || pp->start >= dp->p[0].end){ + if(pp->start > pp->end || pp->start >= dp->p[0].end) break; - } dp->npart++; } } diff --git a/power/boot.c b/power/boot.c index e8b3d9562580823036a14cab3396586dd4ad6ace..a1b14132e27e001eb3faff83713a76e1e8924621 100644 --- a/power/boot.c +++ b/power/boot.c @@ -5,9 +5,6 @@ #define DEFSYS "bit!bootes" #define DEFFILE "/mips/9" -char *net; -char *netdev; - Fcall hdr; char *scmd; @@ -22,21 +19,6 @@ int cfd; int efd; int setkey; -typedef -struct address { - char *name; - char *cmd; -} Address; - -Address addr[] = { - { "bootes", "connect 0800690203f3" }, - { "helix", "connect 080069020427" }, - { "spindle", "connect 0800690202df" }, - { "r70", "connect 08002b04265d" }, - { "fornax", "connect 00007701d2ba" }, - { 0 } -}; - /* * predeclared */ @@ -45,7 +27,6 @@ void prerror(char *); void error(char *); void boot(int); int dkdial(char *); -int nonetdial(char *); int bitdial(char *); int preamble(int); void srvcreate(char*, int); @@ -115,75 +96,6 @@ bitdial(char *arg) return open("#3/bit3", ORDWR); } -int -nonetdial(char *arg) -{ - int efd, cfd, fd; - Address *a; - static int mounted; - - for(a = addr; a->name; a++){ - if(strcmp(a->name, arg) == 0) - break; - } - if(a->name == 0){ - print("can't convert nonet address to ether address\n"); - return -1; - } - - if(!mounted){ - /* - * grab a lance channel, make it recognize ether type 0x900, - * and push the nonet ethernet multiplexor onto it. - */ - efd = open("#l/ether/0/ctl", ORDWR); - if(efd < 0){ - prerror("opening #l/ether/0/ctl"); - return -1; - } - if(write(efd, "connect 0x900", sizeof("connect 0x900")-1)<0){ - close(efd); - prerror("connect 0x900"); - return -1; - } - if(write(efd, "push noether", sizeof("push noether")-1)<0){ - close(efd); - prerror("push noether"); - return -1; - } - if(write(efd, "config nonet", sizeof("config nonet")-1)<0){ - close(efd); - prerror("config nonet"); - return -1; - } - mounted = 1; - } - - /* - * grab a nonet channel and call up the file server - */ - fd = open("#nnonet/2/data", ORDWR); - if(fd < 0) { - prerror("opening #nnonet/2/data"); - return -1; - } - cfd = open("#nnonet/2/ctl", ORDWR); - if(cfd < 0){ - close(fd); - prerror("opening #nnonet/2/ctl"); - return -1; - } - if(write(cfd, a->cmd, strlen(a->cmd))<0){ - close(cfd); - close(fd); - prerror(a->cmd); - return -1; - } - net = "nonet"; - netdev = "#nnonet"; - return fd; -} - int dkdial(char *arg) { @@ -235,8 +147,6 @@ dkdial(char *arg) prerror(cmd); return -1; } - net = "dk"; - netdev = "#k"; return fd; } @@ -370,10 +280,6 @@ boot(int ask) fd = hotdial(&sys[4]); else if(strncmp(sys, "dk!", 3) == 0) fd = dkdial(&sys[3]); - else if(strncmp(sys, "nonet!", 6) == 0) - fd = nonetdial(&sys[6]); - else - fd = nonetdial(sys); if(fd >= 0) break; print("can't connect, retrying...\n"); @@ -391,8 +297,6 @@ boot(int ask) srvcreate("bootes", fd); print("mount..."); - if(bind("/", "/", MREPL) < 0) - error("bind"); if(mount(fd, "/", MAFTER|MCREATE, "", "") < 0) error("mount"); @@ -400,22 +304,6 @@ boot(int ask) print("success\n"); - if(netdev){ - char buf[64]; - sprint(buf, "/net/%s", net); - if(strcmp(netdev, "#k")==0) - bind(netdev, "/net", MBEFORE); - else - bind(netdev, buf, MREPL); - bind(buf, "/net/net", MREPL); - } - if(net){ - char buf[64]; - sprint(buf, "/lib/netaddr.%s", net); - print("binding %s onto /lib/netaddr.net\n", buf); - bind(buf, "/lib/netaddr.net", MREPL); - } - if(ask){ execl("/mips/init", "init", "-mc", 0); } else {