From 621a87403d5134a096baaf5894649b5b521b565a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 18 Jun 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-06-18 --- bitsy/dat.h | 2 ++ bitsy/devether.c | 85 +++++++++++------------------------------------ bitsy/devpcmcia.c | 57 +++++++++++++++++++++++++++---- bitsy/etherif.h | 2 +- bitsy/fns.h | 1 + bitsy/power.c | 2 ++ bitsy/trap.c | 4 --- pc/sdata.c | 2 +- pc/wavelan.c | 54 +++++++++++++++++++++--------- pc/wavelan.h | 7 +++- port/portdat.h | 2 +- 11 files changed, 122 insertions(+), 96 deletions(-) diff --git a/bitsy/dat.h b/bitsy/dat.h index cfcdeca5ebbdd781f341319c5e81d3fca1df175b..47e2da42fc0739337e153adbced5110ff6a77195 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -236,6 +236,8 @@ struct PCMslot uchar occupied; /* card in the slot */ uchar configed; /* card configured */ + Dev *dev; /* set in ctlwrite `configure' */ + /* cis info */ int cisread; /* set when the cis has been read */ char verstr[512]; /* version string */ diff --git a/bitsy/devether.c b/bitsy/devether.c index e1e2eb526f706e2b60af4ca295623c6a3d2ddce8..41b61b59799879976454f5c2b361cac8833d26ba 100644 --- a/bitsy/devether.c +++ b/bitsy/devether.c @@ -10,7 +10,6 @@ #include "etherif.h" -static Ether noether; static volatile Ether *etherxx[MaxEther]; static struct { @@ -33,14 +32,17 @@ addethercard(char* t, int (*r)(Ether*)) void etherpower(int on) { + int i; + Ether *ether; /* Power all ether cards on or off */ +print("etherpower %d\n", on); for (i = 0; i < MaxEther; i++){ ether = etherxx[i]; if (ether == nil) continue; if(on){ - if (ether->write == 0){ + if (ether->writer == 0){ print("etherpower: already powered up\n"); continue; } @@ -49,17 +51,12 @@ etherpower(int on) wunlock(ether); /* Unlock when power restored */ }else{ - if (ether->write != 0){ + if (ether->writer != 0){ print("etherpower: already powered down\n"); continue; } /* Keep locked until power goes back on */ wlock(ether); - if (ether == &noether){ - /* Locked an unconfigured card, undo */ - wunlock(ether); - continue; - } if (ether->power) ether->power(ether, on); } @@ -77,33 +74,10 @@ etherconfig(int on, char *spec, DevConf *cf) ctlrno = atoi(spec); sprint(name, "ether%d", ctlrno); - if(on == 0){ - 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); - - 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(); -print("unconfigure: done\n"); - return 0; - } + if(on == 0) + return -1; - if(etherxx[ctlrno] != nil && etherxx[ctlrno] != &noether) + if(etherxx[ctlrno] != nil) return -1; ether = malloc(sizeof(Ether)); @@ -178,15 +152,13 @@ etherattach(char* spec) error(Ebadarg); } ether = etherxx[ctlrno]; - if(ether == 0 || ether == &noether) + if(ether == 0) error(Enodev); rlock(ether); if(waserror()) { runlock(ether); nexterror(); } - if(etherxx[ctlrno] == &noether) - error(Enodev); chan = devattach('l', spec); chan->dev = ctlrno; if(ether->attach) @@ -208,8 +180,6 @@ etherwalk(Chan* chan, Chan* nchan, char** name, int nname) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); q = netifwalk(ether, chan, nchan, name, nname); poperror(); runlock(ether); @@ -228,8 +198,6 @@ etherstat(Chan* chan, uchar* dp, int n) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); s = netifstat(ether, chan, dp, n); poperror(); runlock(ether); @@ -248,8 +216,6 @@ etheropen(Chan* chan, int omode) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); c = netifopen(ether, chan, omode); poperror(); runlock(ether); @@ -272,8 +238,6 @@ etherclose(Chan* chan) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); netifclose(ether, chan); poperror(); runlock(ether); @@ -284,6 +248,7 @@ etherread(Chan* chan, void* buf, long n, vlong off) { Ether *ether; ulong offset = off; + long r; ether = etherxx[chan->dev]; rlock(ether); @@ -291,24 +256,23 @@ etherread(Chan* chan, void* buf, long n, vlong off) runlock(ether); nexterror(); } - if(ether == &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) - 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); + if(NETTYPE(chan->qid.path) == Nifstatqid){ + r = ether->ifstat(ether, buf, n, offset); + goto out; } - }else - n = netifread(ether, chan, buf, n, offset); + if(NETTYPE(chan->qid.path) == Nstatqid) + ether->ifstat(ether, buf, 0, offset); + } + r = netifread(ether, chan, buf, n, offset); +out: poperror(); runlock(ether); - return n; + return r; } static Block* @@ -318,14 +282,11 @@ etherbread(Chan* chan, long n, ulong offset) Ether *ether; ether = etherxx[chan->dev]; - error(Enodev); rlock(ether); if(waserror()) { runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); b = netifbread(ether, chan, n, offset); poperror(); runlock(ether); @@ -343,8 +304,6 @@ etherwstat(Chan* chan, uchar* dp, int n) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); n = netifwstat(ether, chan, dp, n); poperror(); runlock(ether); @@ -501,8 +460,6 @@ etherwrite(Chan* chan, void* buf, long n, vlong) runlock(ether); nexterror(); } - if(ether == &noether) - error(Enodev); if(NETTYPE(chan->qid.path) != Ndataqid) { l = netifwrite(ether, chan, buf, n); if(l >= 0) @@ -553,10 +510,6 @@ etherbwrite(Chan* chan, Block* bp, ulong) runlock(ether); nexterror(); } - if(ether == &noether){ - freeb(bp); - error(Enodev); - } if(n > ether->maxmtu){ freeb(bp); error(Etoobig); diff --git a/bitsy/devpcmcia.c b/bitsy/devpcmcia.c index abaf2860b5f35595104fcc23cf59d233d05cb7dd..ac9be6e30f3f62aaa1d51d7ad48a198022a759d1 100644 --- a/bitsy/devpcmcia.c +++ b/bitsy/devpcmcia.c @@ -108,13 +108,15 @@ bitno(ulong x) /* * power up/down pcmcia */ -static void -pcmciapower(int up) +void +pcmciapower(int on) { + PCMslot *sp; + /* if there's no pcmcia sleave, no interrupts */ if(gpioregs->level & GPIO_OPT_IND_i) return; - if (up){ + if (on){ /* set timing to the default, 300 */ slottiming(0, 300, 300, 300, 0); slottiming(1, 300, 300, 300, 0); @@ -123,10 +125,38 @@ pcmciapower(int up) if(gpioregs->level & GPIO_OPT_IND_i) return; - /* sleave there, interrupt on card removal */ - intrenable(GPIOrising, bitno(GPIO_CARD_IND1_i), slotinfo, nil, "pcmcia slot1 status"); - intrenable(GPIOrising, bitno(GPIO_CARD_IND0_i), slotinfo, nil, "pcmcia slot0 status"); + egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1); + delay(200); + egpiobits(EGPIO_pcmcia_reset, 1); + delay(100); + egpiobits(EGPIO_pcmcia_reset, 0); + delay(500); + + slotinfo(nil, nil); // See what's there + for (sp = slot; sp < slot + nslot; sp++){ + if (sp->occupied == 0) + continue; + if(sp->cisread == 0) + pcmcisread(sp); + if (sp->dev){ +print("pcmciapower: dev 0x%p", sp->dev); +print(", power 0x%p\n", sp->dev->power); + if (sp->dev->power) + sp->dev->power(on); + } + } }else{ + for (sp = slot; sp < slot + nslot; sp++){ + if (sp->occupied == 0) + continue; + if (sp->dev){ +print("pcmciapower: dev 0x%p", sp->dev); +print(", power 0x%p\n", sp->dev->power); + if (sp->dev->power) + sp->dev->power(on); + } + } + egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0); } } @@ -140,7 +170,17 @@ pcmciareset(void) slotmap(0, PHYSPCM0REGS, PYHSPCM0ATTR, PYHSPCM0MEM); slotmap(1, PHYSPCM1REGS, PYHSPCM1ATTR, PYHSPCM1MEM); - pcmciapower(1); + /* set timing to the default, 300 */ + slottiming(0, 300, 300, 300, 0); + slottiming(1, 300, 300, 300, 0); + + /* if there's no pcmcia sleave, no interrupts */ + if(gpioregs->level & GPIO_OPT_IND_i) + return; + + /* sleave there, interrupt on card removal */ + intrenable(GPIOrising, bitno(GPIO_CARD_IND1_i), slotinfo, nil, "pcmcia slot1 status"); + intrenable(GPIOrising, bitno(GPIO_CARD_IND0_i), slotinfo, nil, "pcmcia slot0 status"); } static Chan* @@ -356,6 +396,8 @@ pcmctlwrite(char *p, long n, ulong, PCMslot *sp) 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"); + sp->dev = devtab[dtx]; +print("pcmctlwrite: configure %s: 0x%p\n", cmd->f[1], sp->dev); wunlock(sp); poperror(); @@ -431,6 +473,7 @@ Dev pcmciadevtab = { devbwrite, devremove, devwstat, + pcmciapower, }; /* see what's there */ diff --git a/bitsy/etherif.h b/bitsy/etherif.h index c6427989af42aa5329f17a1ec8458c23bd141c55..1066ecbbef2067dd6bc43f2f19beb2d935dda330 100644 --- a/bitsy/etherif.h +++ b/bitsy/etherif.h @@ -21,7 +21,7 @@ struct Ether { void (*interrupt)(Ureg*, void*); long (*ifstat)(Ether*, void*, long, ulong); long (*ctl)(Ether*, void*, long); /* custom ctl messages */ - long (*power)(Ether*, int); /* power on/off */ + void (*power)(Ether*, int); /* power on/off */ void *ctlr; Queue* oq; diff --git a/bitsy/fns.h b/bitsy/fns.h index 77318e0ac0a0aeb2b35f7df9f8c75df33cc04691..1173fd5bb82007b49f7bd96c0d0765000aa28a8e 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -76,6 +76,7 @@ void outb(ulong, uchar); void outs(ulong, ushort); void outss(ulong, void*, int); void outl(ulong, ulong); +void pcmciapower(int); void pcmcisread(PCMslot*); int pcmcistuple(int, int, int, void*, int); PCMmap* pcmmap(int, ulong, int, int); diff --git a/bitsy/power.c b/bitsy/power.c index 96899359db6006b0510f39be5bf5b352099d05d3..45c5ef06a3912a9dd85b535f418e499dbebd8038 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -172,6 +172,7 @@ deepsleep(void) { xlink = getcallerpc(&xlink); /* Power down */ + pcmciapower(0); irpower(0); audiopower(0); screenpower(0); @@ -216,6 +217,7 @@ deepsleep(void) { // audiopower(1); µcpower(1); screenpower(1); + pcmciapower(1); splx(power_pl); return; } diff --git a/bitsy/trap.c b/bitsy/trap.c index ef87dccce07646d4727db459154ec9f6ace6f9e6..cda9fbe00f0aa1a88fe82803c9571e899945cebc 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -127,8 +127,6 @@ irqenable(int irq, IntrHandler *f, void* a, char *name) if(irq >= nelem(vctl) || irq < 0) panic("intrenable"); - print("irqenable %s, handler 0x%p\n", name, f); - v = malloc(sizeof(Vctl)); v->f = f; v->a = a; @@ -184,8 +182,6 @@ 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) diff --git a/pc/sdata.c b/pc/sdata.c index c08f79382ae0fcc4bfc48d98932f209b033505c6..731300ecf340fafc75853f1bc0021b391d160632 100644 --- a/pc/sdata.c +++ b/pc/sdata.c @@ -476,7 +476,7 @@ atadmamode(Drive* drive) dma = drive->info[Imwdma] & 0x0707; drive->dma = (dma>>8) & dma; if(drive->dma == 0 && (drive->info[Ivalid] & 0x04)){ - dma = drive->info[Iudma] & 0x1F1F; + dma = drive->info[Iudma] & 0x3F3F; drive->dma = (dma>>8) & dma; if(drive->dma) drive->dma |= 'U'<<16; diff --git a/pc/wavelan.c b/pc/wavelan.c index d199ff8cd9e885a5e26745ddeeddcae2360e950e..5d39112e3e00e90f3a804d19719d51fa2b22950b 100644 --- a/pc/wavelan.c +++ b/pc/wavelan.c @@ -471,7 +471,7 @@ w_txstart(Ether* ether) Block *bp; int len, off; - if((ctlr = ether->ctlr) == nil || ctlr->attached == 0 || ctlr->txbusy) + if((ctlr = ether->ctlr) == nil || (ctlr->state & (Attached|Power)) == 0 || ctlr->txbusy) return; if((bp = qget(ether->oq)) == nil) @@ -558,7 +558,10 @@ w_intr(Ether *ether) int rc, txid; Ctlr* ctlr = (Ctlr*) ether->ctlr; - if (ctlr->attached == 0){ + if ((ctlr->state & Power) == 0) + return; + + if ((ctlr->state & Attached) == 0){ csr_ack(ctlr, 0xffff); csr_outs(ctlr, WR_IntEna, 0); return; @@ -609,17 +612,13 @@ 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; if (ctlr == 0) break; - if (ctlr->attached == 0) + if ((ctlr->state & Attached) == 0) continue; ctlr->ticks++; @@ -660,7 +659,6 @@ w_timer(void* arg) } iunlock(ctlr); } - poperror(); pexit("terminated", 0); } @@ -682,12 +680,12 @@ w_attach(Ether* ether) snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno); ctlr = (Ctlr*) ether->ctlr; - if (ctlr->attached == 0){ + if ((ctlr->state & Attached) == 0){ ilock(ctlr); rc = w_enable(ether); iunlock(ctlr); if(rc == 0){ - ctlr->attached = 1; + ctlr->state |= Attached; kproc(name, w_timer, ether); } else print("#l%d: enable failed\n",ether->ctlrno); @@ -705,7 +703,7 @@ w_detach(Ether* ether) snprint(name, sizeof(name), "#l%dtimer", ether->ctlrno); ctlr = (Ctlr*) ether->ctlr; - if (ctlr->attached){ + if (ctlr->state & Attached){ ilock(ctlr); w_intdis(ctlr); if (ctlr->timerproc){ @@ -713,11 +711,34 @@ w_detach(Ether* ether) print("timerproc note not posted\n"); print("w_detach, killing 0x%p\n", ctlr->timerproc); } - ctlr->attached = 0; + ctlr->state &= ~Attached; iunlock(ctlr); } } +void +w_power(Ether* ether, int on) +{ + Ctlr *ctlr; + + ctlr = (Ctlr*) ether->ctlr; + ilock(ctlr); + if (on){ + if ((ctlr->state & Power) == 0){ + if (ctlr->state & Attached) + w_enable(ether); + ctlr->state |= Power; + } + }else{ + if (ctlr->state & Power){ + if (ctlr->state & Attached) + w_intdis(ctlr); + ctlr->state &= ~Power; + } + } + iunlock(ctlr); +} + #define PRINTSTAT(fmt,val) l += snprint(p+l, READSTR-l, (fmt), (val)) #define PRINTSTR(fmt) l += snprint(p+l, READSTR-l, (fmt)) @@ -760,8 +781,10 @@ w_ifstat(Ether* ether, void* a, long n, ulong offset) PRINTSTAT("WatchDogs: %lud\n", ctlr->nwatchdogs); PRINTSTAT("Ticks: %ud\n", ctlr->ticks); PRINTSTAT("TickIntr: %ud\n", ctlr->tickintr); - k = ((ctlr->attached) ? "attached" : "not attached"); + k = ((ctlr->state & Attached) ? "attached" : "not attached"); PRINTSTAT("Card %s", k); + k = ((ctlr->state & Power) ? "on" : "off"); + PRINTSTAT("PCardower %s", k); k = ((ctlr->txbusy)? ", txbusy" : ""); PRINTSTAT("%s\n", k); @@ -967,7 +990,7 @@ w_ctl(Ether* ether, void* buf, long n) if((ctlr = ether->ctlr) == nil) error(Enonexist); - if(ctlr->attached == 0) + if((ctlr->state & Attached) == 0) error(Eshutdown); ilock(ctlr); @@ -1006,7 +1029,7 @@ w_promiscuous(void* arg, int on) if (ctlr == nil) error("card not found"); - if (ctlr->attached == 0) + if ((ctlr->state & Attached) == 0) error("card not attached"); ilock(ctlr); ltv_outs(ctlr, WTyp_Prom, (on?1:0)); @@ -1088,6 +1111,7 @@ wavelanreset(Ether* ether, Ctlr *ctlr) ether->transmit = w_transmit; ether->ifstat = w_ifstat; ether->ctl = w_ctl; + ether->power = w_power; ether->promiscuous = w_promiscuous; ether->multicast = w_multicast; ether->arg = ether; diff --git a/pc/wavelan.h b/pc/wavelan.h index b61e2e5721a118fc415cf071c4fca71764786528..8ec56974fa9f0277494a5d9414fd7b5aebed6d25 100644 --- a/pc/wavelan.h +++ b/pc/wavelan.h @@ -238,12 +238,17 @@ struct Stats int noise; }; +enum { + Attached = 0x01, + Power = 0x02, +}; + struct Ctlr { Lock; Rendez timer; - int attached; + int state; // Attached | Power int slot; int iob; int createibss; diff --git a/port/portdat.h b/port/portdat.h index 0fc6657f113f39bb5cf45b7eb3e1b45421e91f48..120be85b83f22ec5e70d0985e2b738650aeded51 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -202,7 +202,7 @@ struct Dev void (*remove)(Chan*); int (*wstat)(Chan*, uchar*, int); void (*power)(int); /* power mgt: power(1) => on, power (0) => off */ - int (*config)(int, char*, DevConf*); + int (*config)(int, char*, DevConf*); // returns nil on error }; struct Dirtab