M alphapc/trap.c => alphapc/trap.c +1 -0
@@ 782,6 782,7 @@ linkproc(void)
{
spllo();
up->kpfun(up->kparg);
+ pexit("kproc exiting", 0);
}
void
M bitsy/dat.h => bitsy/dat.h +1 -1
@@ 260,6 260,6 @@ struct DevConf
ulong port; /* mapped i/o regs */
int size; /* access size */
int itype; /* type of interrupt */
- ulong interrupt; /* interrupt number */
+ ulong intnum; /* interrupt number */
char *type; /* card type, mallocated */
};
M bitsy/devether.c => bitsy/devether.c +9 -3
@@ 39,6 39,7 @@ etherconfig(int on, char *spec, DevConf *cf)
char *p, *e;
ctlrno = atoi(spec);
+ sprint(name, "ether%d", ctlrno);
if(on == 0){
ether = etherxx[ctlrno];
@@ 52,6 53,13 @@ print("unconfigure\n");
}
if(ether == &noether)
error(Enodev);
+
+ if(ether->detach)
+ ether->detach(ether);
+
+ if(ether->interrupt != nil)
+ intrdisable(ether->itype, ether->intnum, ether->interrupt, ether, name);
+
etherxx[ctlrno] = &noether;
wunlock(ether);
poperror();
@@ 65,7 73,6 @@ print("unconfigure: done\n");
ether = malloc(sizeof(Ether));
if(ether == nil)
panic("etherconfig");
- memset(ether, 0, sizeof(Ether));
*(DevConf*)ether = *cf;
for(n = 0; cards[n].type; n++){
@@ 73,7 80,6 @@ print("unconfigure: done\n");
continue;
if(cards[n].reset(ether))
break;
- sprint(name, "ether%d", ctlrno);
if(ether->mbps >= 100){
netifinit(ether, name, Ntypes, 256*1024);
@@ 95,7 101,7 @@ print("unconfigure: done\n");
ether->maxmtu = ETHERMAXTU;
if(ether->interrupt != nil)
- intrenable(cf->itype, cf->interrupt, ether->interrupt, ether, name);
+ intrenable(cf->itype, cf->intnum, ether->interrupt, ether, name);
p = buf;
e = buf+sizeof(buf);
M bitsy/devpcmcia.c => bitsy/devpcmcia.c +1 -1
@@ 353,7 353,7 @@ pcmctlwrite(char *p, long n, ulong, PCMslot *sp)
cf.mem = (ulong)sp->mem;
cf.port = (ulong)sp->regs;
cf.itype = GPIOfalling;
- cf.interrupt = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i);
+ cf.intnum = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i);
if(devtab[dtx]->config(1, p, &cf) < 0)
error("couldn't configure device");
M bitsy/etherif.h => bitsy/etherif.h +1 -0
@@ 16,6 16,7 @@ struct Ether {
int encry;
void (*attach)(Ether*); /* filled in by reset routine */
+ void (*detach)(Ether*);
void (*transmit)(Ether*);
void (*interrupt)(Ureg*, void*);
long (*ifstat)(Ether*, void*, long, ulong);
M bitsy/fns.h => bitsy/fns.h +1 -1
@@ 39,7 39,6 @@ ulong getttb(void);
void* getlink(void);
#define getpgcolor(a) 0
ulong getsp(void);
-void gpiointrenable(ulong, int, void (*)(Ureg*, void*), void*, char*);
void h3650uartsetup(void);
int havetimer(void);
void _hibernate(void);
@@ 51,6 50,7 @@ uchar inb(ulong);
ushort ins(ulong);
void inss(ulong, void*, int);
ulong inl(ulong);
+void intrdisable(int, int, void (*)(Ureg*, void*), void*, char*);
void intrenable(int, int, void (*)(Ureg*, void*), void*, char*);
void irpower(int);
#define kmapinval()
M bitsy/sdata.c => bitsy/sdata.c +2 -2
@@ 2054,10 2054,10 @@ ataconfig(int on, char *, void *pf)
rc = nil;
for (try = &tries[0]; try->p != 0 || try->c != 0; try++){
ataitype = cf->itype;
- atairq = cf->interrupt;
+ atairq = cf->intnum;
cmdport = cf->port + try->p;
ctlport = cmdport + try->c;
- irq = cf->interrupt;
+ irq = cf->intnum;
rc = ataprobe(cmdport, ctlport, irq);
if (rc)
break;
M bitsy/trap.c => bitsy/trap.c +99 -7
@@ 119,7 119,7 @@ warnregs(Ureg *ur, char *tag)
/*
* enable an irq interrupt
*/
-void
+static void
irqenable(int irq, IntrHandler *f, void* a, char *name)
{
Vctl *v;
@@ 127,7 127,9 @@ irqenable(int irq, IntrHandler *f, void* a, char *name)
if(irq >= nelem(vctl) || irq < 0)
panic("intrenable");
- v = xalloc(sizeof(Vctl));
+ print("irqenable %s, handler 0x%p\n", name, f);
+
+ v = malloc(sizeof(Vctl));
v->f = f;
v->a = a;
v->name = xalloc(strlen(name)+1);
@@ 141,6 143,34 @@ irqenable(int irq, IntrHandler *f, void* a, char *name)
}
/*
+ * disable an irq interrupt
+ */
+static void
+irqdisable(int irq, IntrHandler *f, void* a, char *name)
+{
+ Vctl **vp, *v;
+
+ if(irq >= nelem(vctl) || irq < 0)
+ panic("intrdisable");
+
+ lock(&vctllock);
+ for(vp = &vctl[irq]; v = *vp; vp = &v->next)
+ if (v->f == f && v->a == a && strcmp(v->name, name) == 0){
+ print("irqdisable: remove %s\n", name);
+ *vp = v->next;
+ free(v);
+ break;
+ }
+ if (v == nil)
+ print("irqdisable: irq %d, name %s not enabled\n", irq, name);
+ if (vctl[irq] == nil){
+ print("irqdisable: clear icmr bit %d\n", irq);
+ intrregs->icmr &= ~(1<<irq);
+ }
+ unlock(&vctllock);
+}
+
+/*
* enable an interrupt
*/
void
@@ 154,19 184,21 @@ intrenable(int type, int which, IntrHandler *f, void* a, char *name)
return;
}
+ print("intrenable %s, handler 0x%p\n", name, f);
+
/* from here down, it must be a GPIO edge interrupt */
irq = which;
if(which >= nelem(gpiovctl) || which < 0)
- panic("gpiointrenable");
+ panic("intrenable");
if(which > 11)
irq = 11;
/* the pin had better be configured as input */
if((1<<which) & gpioregs->direction)
- panic("gpiointrenable of output pin %d", which);
+ panic("intrenable of output pin %d", which);
/* create a second level vctl for the gpio edge interrupt */
- v = xalloc(sizeof(Vctl));
+ v = malloc(sizeof(Vctl));
v->f = f;
v->a = a;
v->name = xalloc(strlen(name)+1);
@@ 175,7 207,6 @@ intrenable(int type, int which, IntrHandler *f, void* a, char *name)
lock(&vctllock);
v->next = gpiovctl[which];
gpiovctl[which] = v;
- unlock(&vctllock);
/* set edge register to enable interrupt */
switch(type){
@@ 190,13 221,73 @@ intrenable(int type, int which, IntrHandler *f, void* a, char *name)
gpioregs->rising |= 1<<which;
break;
}
-
+ unlock(&vctllock);
/* point the irq to the gpio interrupt handler */
if(gpioirqref[irq]++ == 0)
irqenable(irq, gpiointr, nil, "gpio edge");
}
/*
+ * disable an interrupt
+ */
+void
+intrdisable(int type, int which, IntrHandler *f, void* a, char *name)
+{
+ int irq;
+ Vctl **vp, *v;
+
+
+ if(type == IRQ){
+ irqdisable(which, f, a, name);
+ return;
+ }
+
+ /* from here down, it must be a GPIO edge interrupt */
+ irq = which;
+ if(which >= nelem(gpiovctl) || which < 0)
+ panic("intrdisable");
+ if(which > 11)
+ irq = 11;
+
+ lock(&vctllock);
+ for(vp = &gpiovctl[which]; v = *vp; vp = &v->next)
+ if (v->f == f && v->a == a && strcmp(v->name, name) == 0){
+ break;
+ }
+ if (gpiovctl[which] == nil){
+ /* set edge register to enable interrupt */
+ switch(type){
+ case GPIOboth:
+ print("intrdisable: gpio-rising+falling clear bit %d\n", which);
+ gpioregs->rising &= ~(1<<which);
+ gpioregs->falling &= ~(1<<which);
+ break;
+ case GPIOfalling:
+ print("intrdisable: gpio-falling clear bit %d\n", which);
+ gpioregs->falling &= ~(1<<which);
+ break;
+ case GPIOrising:
+ print("intrdisable: gpio-rising clear bit %d\n", which);
+ gpioregs->rising &= ~(1<<which);
+ break;
+ }
+
+ }
+ if (v) {
+ print("intrdisable: removing %s\n", name);
+ *vp = v->next;
+ }else
+ print("intrdisable: which %d, name %s not enabled\n", which, name);
+ unlock(&vctllock);
+ /* disable the gpio interrupt handler if necessary */
+ if(--gpioirqref[irq] == 0){
+ print("intrdisable: inrqdisable gpiointr\n");
+ irqdisable(irq, gpiointr, nil, "gpio edge");
+ }
+ free(v);
+}
+
+/*
* called by trap to handle access faults
*/
static void
@@ 679,6 770,7 @@ linkproc(void)
{
spllo();
up->kpfun(up->kparg);
+ pexit("kproc exiting", 0);
}
/*
M ip/ip.c => ip/ip.c +1 -1
@@ 21,7 21,7 @@ enum
IP_DF = 0x4000, /* Don't fragment */
IP_MF = 0x2000, /* More fragments */
IP6FHDR = 8, /* sizeof(Fraghdr6) */
- IP_MAX = (32*1024), /* Maximum Internet packet size */
+ IP_MAX = 64*1024, /* Maximum Internet packet size */
};
#define BLKIPVER(xp) (((Ip4hdr*)((xp)->rp))->vihl&0xF0)
M ip/ipifc.c => ip/ipifc.c +6 -3
@@ 168,6 168,7 @@ ipifcunbind(Ipifc *ifc)
char *av[4];
char ip[32];
char mask[32];
+ char *err;
if(waserror()){
wunlock(ifc);
@@ 202,7 203,8 @@ ipifcunbind(Ipifc *ifc)
else
sprint(ip, "%I", ifc->lifc->local);
sprint(mask, "%M", ifc->lifc->mask);
- ipifcrem(ifc, av, 3, 0);
+ if (err = ipifcrem(ifc, av, 3, 0))
+ print("ipifcunbind, addr %s, mask %s: %s\n", ip, mask, err);
}
ifc->m = nil;
@@ 573,8 575,8 @@ ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock)
addr = lifc->local;
if(type == Rptpt)
addr = lifc->remote;
- if(memcmp(ip, addr, IPaddrlen) == 0)
- if(memcmp(mask, lifc->mask, IPaddrlen) == 0) {
+ if (memcmp(ip, addr, IPaddrlen) == 0
+ && memcmp(mask, lifc->mask, IPaddrlen) == 0) {
*l = lifc->next;
break;
}
@@ 584,6 586,7 @@ ipifcrem(Ipifc *ifc, char **argv, int argc, int dolock)
if(lifc == nil){
if(dolock)
wunlock(ifc);
+ print("ipifcrem: wrong address\n");
return "address not on this interface";
}
M ip/netlog.c => ip/netlog.c +1 -1
@@ 207,7 207,7 @@ netlogctl(Fs *f, char* s, int n)
cmderror(cb, "unknown ip control message");
}
- for(i = 1; i < n; i++){
+ for(i = 1; i < cb->nf; i++){
for(fp = flags; fp->name; fp++)
if(strcmp(fp->name, cb->f[i]) == 0)
break;
M ip/udp.c => ip/udp.c +2 -2
@@ 146,8 146,8 @@ udpannounce(Conv *c, char** argv, int argc)
static void
udpcreate(Conv *c)
{
- c->rq = qopen(64*1024, 1, 0, 0);
- c->wq = qopen(64*1024, 0, 0, 0);
+ c->rq = qopen(128*1024, 1, 0, 0);
+ c->wq = qopen(128*1024, 0, 0, 0);
}
static void
M pc/etherif.h => pc/etherif.h +1 -0
@@ 15,6 15,7 @@ struct Ether {
uchar ea[Eaddrlen];
void (*attach)(Ether*); /* filled in by reset routine */
+ void (*detach)(Ether*);
void (*transmit)(Ether*);
void (*interrupt)(Ureg*, void*);
long (*ifstat)(Ether*, void*, long, ulong);
M pc/trap.c => pc/trap.c +1 -0
@@ 819,6 819,7 @@ linkproc(void)
{
spllo();
up->kpfun(up->kparg);
+ pexit("kproc dying", 0);
}
void
M pc/vgamach64xx.c => pc/vgamach64xx.c +2 -2
@@ 118,8 118,8 @@ static int mach64revb; /* Revision B or greater? */
static ulong mach64overlay; /* Overlay buffer */
static mach64types mach64s[] = {
- ('C'<<8)|'T', 0, 0, 0, /* 4354: CT */
- ('E'<<8)|'T', 0, 0, 0, /* 4554: ET */
+ ('C'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4354: CT */
+ ('E'<<8)|'T', 0, 1350000, /*?*/ 0, /* 4554: ET */
('G'<<8)|'B', 1, 1250000, 1, /* 4742: 264GT PRO */
('G'<<8)|'D', 1, 1250000, 1, /* 4744: 264GT PRO */
('G'<<8)|'I', 1, 1250000, 1, /* 4749: 264GT PRO */
M pc/wavelan.c => pc/wavelan.c +32 -1
@@ 609,6 609,11 @@ w_timer(void* arg)
Ether* ether = (Ether*) arg;
Ctlr* ctlr = (Ctlr*)ether->ctlr;
+ if (waserror()){
+ print("timerporc dying\n");
+ pexit("aaargh!", 0);
+ }
+ ctlr->timerproc = up;
for(;;){
tsleep(&ctlr->timer, return0, 0, 50);
ctlr = (Ctlr*)ether->ctlr;
@@ 655,7 660,8 @@ w_timer(void* arg)
}
iunlock(ctlr);
}
- pexit("terminated",0);
+ poperror();
+ pexit("terminated", 0);
}
void
@@ 688,6 694,30 @@ w_attach(Ether* ether)
}
}
+void
+w_detach(Ether* ether)
+{
+ Ctlr* ctlr;
+ char name[64];
+
+ if (ether->ctlr == 0)
+ return;
+
+ snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno);
+ ctlr = (Ctlr*) ether->ctlr;
+ if (ctlr->attached){
+ ilock(ctlr);
+ w_intdis(ctlr);
+ if (ctlr->timerproc){
+ if (!postnote(ctlr->timerproc, 1, "kill", NExit))
+ print("timerproc note not posted\n");
+ print("w_detach, killing 0x%p\n", ctlr->timerproc);
+ }
+ ctlr->attached = 0;
+ iunlock(ctlr);
+ }
+}
+
#define PRINTSTAT(fmt,val) l += snprint(p+l, READSTR-l, (fmt), (val))
#define PRINTSTR(fmt) l += snprint(p+l, READSTR-l, (fmt))
@@ 1049,6 1079,7 @@ wavelanreset(Ether* ether, Ctlr *ctlr)
ether->ctlr = ctlr;
ether->mbps = 10;
ether->attach = w_attach;
+ ether->detach = w_detach;
ether->interrupt = w_interrupt;
ether->transmit = w_transmit;
ether->ifstat = w_ifstat;
M pc/wavelan.h => pc/wavelan.h +2 -0
@@ 260,6 260,8 @@ struct Ctlr
int pmena;
int pmwait;
+ Proc *timerproc;
+
char netname[WNameLen];
char wantname[WNameLen];
char nodename[WNameLen];
M port/devmnt.c => port/devmnt.c +3 -3
@@ 83,7 83,7 @@ mntreset(void)
mntalloc.rpctag = Tagspace;
fmtinstall('F', fcallfmt);
fmtinstall('D', dirfmt);
- fmtinstall('M', dirmodefmt);
+/* fmtinstall('M', dirmodefmt); No! Clashes with eipfmt [sape] */
cinit();
}
@@ 836,7 836,7 @@ mntrpcread(Mnt *m, Mntrpc *r)
/* read at least length, type, and tag and pullup to a single block */
while(qlen(m->q) < BIT32SZ+BIT8SZ+BIT16SZ){
- b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0);
+ b = devtab[m->c->type]->bread(m->c, m->msize, 0);
if(b == nil)
return -1;
qaddlist(m->q, b);
@@ 846,7 846,7 @@ mntrpcread(Mnt *m, Mntrpc *r)
/* read in the rest of the message */
while(qlen(m->q) < len){
- b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0);
+ b = devtab[m->c->type]->bread(m->c, m->msize, 0);
if(b == nil)
return -1;
qaddlist(m->q, b);