From 2fedf8d14d0e741282a501a04d5723929eb8437f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 14 Jun 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-06-14 --- bitsy/devether.c | 230 ++++++++++++++++++++++++++++++++++------------ bitsy/devpcmcia.c | 26 ++++-- 2 files changed, 185 insertions(+), 71 deletions(-) diff --git a/bitsy/devether.c b/bitsy/devether.c index a25c39a68f2a0c1830825758d7705d5b8987de0d..9593bae5ef575a6d80bc1b720ae42875f803a2e4 100644 --- a/bitsy/devether.c +++ b/bitsy/devether.c @@ -10,7 +10,8 @@ #include "etherif.h" -static Ether *etherxx[MaxEther]; +static Ether noether; +static volatile Ether *etherxx[MaxEther]; static struct { char* type; @@ -38,14 +39,29 @@ etherconfig(int on, char *spec, DevConf *cf) char *p, *e; ctlrno = atoi(spec); - if(etherxx[ctlrno] != nil) - return -1; - /* can't unconfigure yet */ if(on == 0){ - return -1; + ether = etherxx[ctlrno]; + if(ether == nil || ether == &noether) + return -1; +print("unconfigure\n"); + wlock(ether); + if(waserror()) { + wunlock(ether); + nexterror(); + } + if(ether == &noether) + error(Enodev); + etherxx[ctlrno] = &noether; + wunlock(ether); + poperror(); +print("unconfigure: done\n"); + return 0; } + if(etherxx[ctlrno] != nil && etherxx[ctlrno] != &noether) + return -1; + ether = malloc(sizeof(Ether)); if(ether == nil) panic("etherconfig"); @@ -105,14 +121,13 @@ etherconfig(int on, char *spec, DevConf *cf) return -1; } - - Chan* etherattach(char* spec) { ulong ctlrno; char *p; Chan *chan; + Ether *ether; ctlrno = 0; if(spec && *spec){ @@ -120,15 +135,22 @@ etherattach(char* spec) if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) error(Ebadarg); } - if(etherxx[ctlrno] == 0) + ether = etherxx[ctlrno]; + if(ether == 0 || ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[ctlrno] == &noether) error(Enodev); - - rlock(etherxx[ctlrno]); chan = devattach('l', spec); chan->dev = ctlrno; - if(etherxx[ctlrno]->attach) - etherxx[ctlrno]->attach(etherxx[ctlrno]); - runlock(etherxx[ctlrno]); + if(ether->attach) + ether->attach(ether); + poperror(); + runlock(ether); return chan; } @@ -136,10 +158,21 @@ static Walkqid* etherwalk(Chan* chan, Chan* nchan, char** name, int nname) { Walkqid *q; + Ether *ether; - rlock(etherxx[chan->dev]); - q = netifwalk(etherxx[chan->dev], chan, nchan, name, nname); - runlock(etherxx[chan->dev]); + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + q = netifwalk(ether, chan, nchan, name, nname); + poperror(); + runlock(ether); return q; } @@ -147,10 +180,21 @@ static int etherstat(Chan* chan, uchar* dp, int n) { int s; + Ether *ether; - rlock(etherxx[chan->dev]); - s = netifstat(etherxx[chan->dev], chan, dp, n); - runlock(etherxx[chan->dev]); + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + s = netifstat(ether, chan, dp, n); + poperror(); + runlock(ether); return s; } @@ -158,10 +202,21 @@ static Chan* etheropen(Chan* chan, int omode) { Chan *c; + Ether *ether; - rlock(etherxx[chan->dev]); - c = netifopen(etherxx[chan->dev], chan, omode); - runlock(etherxx[chan->dev]); + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + c = netifopen(ether, chan, omode); + poperror(); + runlock(ether); return c; } @@ -173,9 +228,21 @@ ethercreate(Chan*, char*, int, ulong) static void etherclose(Chan* chan) { - rlock(etherxx[chan->dev]); - netifclose(etherxx[chan->dev], chan); - runlock(etherxx[chan->dev]); + Ether *ether; + + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + netifclose(ether, chan); + poperror(); + runlock(ether); } static long @@ -183,22 +250,31 @@ etherread(Chan* chan, void* buf, long n, vlong off) { Ether *ether; ulong offset = off; - long n; ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); if((chan->qid.type & QTDIR) == 0 && ether->ifstat){ /* * With some controllers it is necessary to reach * into the chip to extract statistics. */ if(NETTYPE(chan->qid.path) == Nifstatqid) - return ether->ifstat(ether, buf, n, offset); - else if(NETTYPE(chan->qid.path) == Nstatqid) + n = ether->ifstat(ether, buf, n, offset); + else if(NETTYPE(chan->qid.path) == Nstatqid){ ether->ifstat(ether, buf, 0, offset); - } - - n = netifread(ether, chan, buf, n, offset); + n = netifread(ether, chan, buf, n, offset); + } + }else + n = netifread(ether, chan, buf, n, offset); + poperror(); runlock(ether); return n; } @@ -207,19 +283,42 @@ static Block* etherbread(Chan* chan, long n, ulong offset) { Block *b; + Ether *ether; - rlock(etherxx[chan->dev]); - b = netifbread(etherxx[chan->dev], chan, n, offset); - runlock(etherxx[chan->dev]); + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + b = netifbread(ether, chan, n, offset); + poperror(); + runlock(ether); return b; } static int etherwstat(Chan* chan, uchar* dp, int n) { - rlock(etherxx[chan->dev]); - n = netifwstat(etherxx[chan->dev], chan, dp, n); - runlock(etherxx[chan->dev]); + Ether *ether; + + ether = etherxx[chan->dev]; + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); + n = netifwstat(ether, chan, dp, n); + poperror(); + runlock(ether); return n; } @@ -365,41 +464,42 @@ etherwrite(Chan* chan, void* buf, long n, vlong) { Ether *ether; Block *bp; - int nn; long l; ether = etherxx[chan->dev]; - rlock(etherxx[chan->dev]); + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether) + error(Enodev); if(NETTYPE(chan->qid.path) != Ndataqid) { - nn = netifwrite(ether, chan, buf, n); - if(nn >= 0){ - runlock(etherxx[chan->dev]); - return nn; - } + l = netifwrite(ether, chan, buf, n); + if(l >= 0) + goto out; if(ether->ctl!=nil){ l = ether->ctl(ether,buf,n); - runlock(etherxx[chan->dev]); - return l; + goto out; } - runlock(etherxx[chan->dev]); error(Ebadctl); } - if(n > ether->maxmtu){ - runlock(etherxx[chan->dev]); + if(n > ether->maxmtu) error(Etoobig); - } - if(n < ether->minmtu){ - runlock(etherxx[chan->dev]); + if(n < ether->minmtu) error(Etoosmall); - } bp = allocb(n); memmove(bp->rp, buf, n); memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen); bp->wp += n; l = etheroq(ether, bp); - runlock(etherxx[chan->dev]); +out: + poperror(); + runlock(ether); return l; } @@ -420,22 +520,30 @@ etherbwrite(Chan* chan, Block* bp, ulong) freeb(bp); return n; } - rlock(etherxx[chan->dev]); ether = etherxx[chan->dev]; - + if(ether == &noether) + error(Enodev); + rlock(ether); + if(waserror()) { + runlock(ether); + nexterror(); + } + if(etherxx[chan->dev] == &noether){ + freeb(bp); + error(Enodev); + } if(n > ether->maxmtu){ freeb(bp); - runlock(etherxx[chan->dev]); error(Etoobig); } if(n < ether->minmtu){ freeb(bp); - runlock(etherxx[chan->dev]); error(Etoosmall); } - runlock(etherxx[chan->dev]); - - return etheroq(ether, bp); + n = etheroq(ether, bp); + poperror(); + runlock(ether); + return n; } int diff --git a/bitsy/devpcmcia.c b/bitsy/devpcmcia.c index 5477297d3532491165e596a5a1cda87dd9a7c894..8f3d227f055762e47ac758796ce7240fc2e0429b 100644 --- a/bitsy/devpcmcia.c +++ b/bitsy/devpcmcia.c @@ -349,7 +349,6 @@ pcmctlwrite(char *p, long n, ulong, PCMslot *sp) /* configure device */ memset(&cf, 0, sizeof cf); - wlock(&cf); kstrdup(&cf.type, cmd->f[2]); cf.mem = (ulong)sp->mem; cf.port = (ulong)sp->regs; @@ -357,7 +356,6 @@ pcmctlwrite(char *p, long n, ulong, PCMslot *sp) cf.interrupt = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i); if(devtab[dtx]->config(1, p, &cf) < 0) error("couldn't configure device"); - wunlock(&cf); wunlock(sp); poperror(); @@ -365,15 +363,23 @@ pcmctlwrite(char *p, long n, ulong, PCMslot *sp) /* don't let the power turn off */ increfp(sp); }else if(strcmp(cmd->f[0], "remove") == 0){ - wlock(sp); - if(waserror()){ - wunlock(sp); - nexterror(); - } - + /* see if driver exists and is configurable */ + if(cmd->nf != 2) + error(Ebadarg); + p = cmd->f[1]; + if(*p++ != '#') + error(Ebadarg); + p += chartorune(&r, p); + dtx = devno(r, 1); + if(dtx < 0) + error("no such device type"); + if(devtab[dtx]->config == nil) + error("not a dynamicly configurable device"); + if(devtab[dtx]->config(0, p, nil) < 0) + error("couldn't unconfigure device"); - wunlock(sp); - poperror(); + /* let the power turn off */ + decrefp(sp); } free(cmd);