## diffname bitsy/devpcmcia.c 2000/1118 ## diff -e /dev/null /n/emeliedump/2000/1118/sys/src/9/bitsy/devpcmcia.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include "io.h" static PCMslot slot[2]; int nslot = 2; struct { Ref; } pcmcia; enum { Qdir, Qmem, Qattr, Qctl, Nents = 3, }; #define SLOTNO(c) ((c->qid.path>>8)&0xff) #define TYPE(c) (c->qid.path&0xff) #define QID(s,t) (((s)<<8)|(t)) static int pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) { int slotno; Qid qid; long len; PCMslot *pp; char name[NAMELEN]; if(i == DEVDOTDOT){ devdir(c, (Qid){CHDIR, 0}, "#y", 0, eve, 0555, dp); return 1; } if(i >= Nents*nslot) return -1; slotno = i/Nents; pp = slot + slotno; len = 0; switch(i%Nents){ case 0: qid.path = QID(slotno, Qmem); sprint(name, "pcm%dmem", slotno); len = pp->memlen; break; case 1: qid.path = QID(slotno, Qattr); sprint(name, "pcm%dattr", slotno); len = pp->memlen; break; case 2: qid.path = QID(slotno, Qctl); sprint(name, "pcm%dctl", slotno); break; } qid.vers = 0; devdir(c, qid, name, len, eve, 0660, dp); return 1; } static void slotinfo(void) { ulong x = gpioregs->level; if(x & GPIO_OPT_IND_i){ /* no expansion pack */ slot[0].occupied = 0; slot[1].occupied = 0; } else { slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0; slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0; } } static void increfp(PCMslot *pp) { if(incref(&pcmcia) == 1) exppackpower(1); lock(pp); if(pp->ref++ == 0) ; unlock(pp); slotinfo(); } static void decrefp(PCMslot *pp) { slotinfo(); lock(pp); if(pp->ref-- == 1) ; unlock(pp); if(decref(&pcmcia) == 0) exppackpower(0); } /* * get a map for pc card region, return corrected len */ PCMmap* pcmmap(int slotno, ulong, int, int attr) { if(slotno > nslot) panic("pcmmap"); if(attr) return &slot[slotno].attrmap; else return &slot[slotno].memmap; } void pcmunmap(int, PCMmap*) { } /* * map in the space for the cards */ static void pcmciareset(void) { int j; PCMslot *pp; for(j = 0; j < nslot; j++){ pp = &slot[j]; pp->slotno = j; pp->memlen = 64*OneMeg; pp->msec = ~0; pp->verstr[0] = 0; pp->mem = mapmem(j == 0 ? PYHSPCM0MEM : PYHSPCM1MEM, 64*OneMeg); pp->memmap.ca = 0; pp->memmap.cea = 64*MB; pp->memmap.isa = (ulong)pp->mem; pp->memmap.len = 64*OneMeg; pp->memmap.attr = 0; pp->attr = mapmem(j == 0 ? PYHSPCM0ATTR : PYHSPCM1ATTR, OneMeg); pp->attrmap.ca = 0; pp->attrmap.cea = 64*MB; pp->attrmap.isa = (ulong)pp->attr; pp->attrmap.len = OneMeg; pp->attrmap.attr = 1; pp->regs = mapspecial(j == 0 ? PHYSPCM0REGS : PHYSPCM1REGS, 32*1024); } } static Chan* pcmciaattach(char *spec) { return devattach('y', spec); } static int pcmciawalk(Chan *c, char *name) { return devwalk(c, name, 0, 0, pcmgen); } static void pcmciastat(Chan *c, char *db) { devstat(c, db, 0, 0, pcmgen); } static Chan* pcmciaopen(Chan *c, int omode) { if(c->qid.path == CHDIR){ if(omode != OREAD) error(Eperm); } else increfp(slot + SLOTNO(c)); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } static void pcmciaclose(Chan *c) { if(c->flag & COPEN) if(c->qid.path != CHDIR) decrefp(slot+SLOTNO(c)); } /* a memmove using only bytes */ static void memmoveb(uchar *to, uchar *from, int n) { while(n-- > 0) *to++ = *from++; } /* a memmove using only shorts & bytes */ static void memmoves(uchar *to, uchar *from, int n) { ushort *t, *f; if((((ulong)to) & 1) || (((ulong)from) & 1) || (n & 1)){ while(n-- > 0) *to++ = *from++; } else { n = n/2; t = (ushort*)to; f = (ushort*)from; while(n-- > 0) *t++ = *f++; } } static long pcmread(void *a, long n, ulong off, uchar *start, ulong len) { if(off > len) return 0; if(off + n > len) n = len - off; memmoves(a, start+off, n); return n; } static long pcmctlread(void *a, long n, ulong off, PCMslot *pp) { char *p, *buf, *e; buf = p = malloc(READSTR); if(waserror()){ free(buf); nexterror(); } e = p + READSTR; buf[0] = 0; if(pp->occupied){ p = seprint(p, e, "occupied\n"); if(pp->verstr[0]) p = seprint(p, e, "version %s\n", pp->verstr); } USED(p); n = readstr(off, a, n, buf); free(buf); poperror(); return n; } static long pcmciaread(Chan *c, void *a, long n, vlong off) { PCMslot *pp; ulong offset = off; pp = slot + SLOTNO(c); switch(TYPE(c)){ case Qdir: return devdirread(c, a, n, 0, 0, pcmgen); case Qmem: if(!pp->occupied) error(Eio); return pcmread(a, n, offset, pp->mem, 64*OneMeg); case Qattr: if(!pp->occupied) error(Eio); return pcmread(a, n, offset, pp->attr, OneMeg); case Qctl: return pcmctlread(a, n, offset, pp); } error(Ebadarg); return -1; /* not reached */ } static long pcmwrite(void *a, long n, ulong off, uchar *start, ulong len) { if(off > len) error(Eio); if(off + n > len) error(Eio); memmoveb(start+off, a, n); return n; } static long pcmctlwrite(char *p, long n, ulong off, PCMslot *pp) { /* nothing yet */ USED(p, n, off, pp); error(Ebadarg); return 0; } static long pcmciawrite(Chan *c, void *a, long n, vlong off) { PCMslot *pp; ulong offset = off; pp = slot + SLOTNO(c); switch(TYPE(c)){ case Qmem: if(!pp->occupied) error(Eio); return pcmwrite(a, n, offset, pp->mem, 64*OneMeg); case Qattr: if(!pp->occupied) error(Eio); return pcmwrite(a, n, offset, pp->attr, OneMeg); case Qctl: if(!pp->occupied) error(Eio); return pcmctlwrite(a, n, offset, pp); } error(Ebadarg); return -1; /* not reached */ } Dev pcmciadevtab = { 'y', "pcmcia", pcmciareset, devinit, pcmciaattach, devclone, pcmciawalk, pcmciastat, pcmciaopen, devcreate, pcmciaclose, pcmciaread, devbread, pcmciawrite, devbwrite, devremove, devwstat, }; . ## diffname bitsy/devpcmcia.c 2000/1121 ## diff -e /n/emeliedump/2000/1118/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1121/sys/src/9/bitsy/devpcmcia.c 355a /* see what's there */ static void slotinfo(void) { ulong x = gpioregs->level; if(x & GPIO_OPT_IND_i){ /* no expansion pack */ slot[0].occupied = 0; slot[1].occupied = 0; } else { slot[0].occupied = (x & GPIO_CARD_IND0_i) == 0; slot[1].occupied = (x & GPIO_CARD_IND1_i) == 0; } } /* use reference card to turn cards on and off */ static void increfp(PCMslot *pp) { if(incref(&pcmcia) == 1){ egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 1); egpiobits(EGPIO_pcmcia_reset, 0); delay(100); /* time to power up */ } incref(pp); slotinfo(); } static void decrefp(PCMslot *pp) { slotinfo(); decref(pp); if(decref(&pcmcia) == 0) egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0); } /* * the regions are staticly mapped */ static void slotmap(int slotno, ulong regs, ulong attr, ulong mem) { PCMslot *pp; pp = &slot[slotno]; pp->slotno = slotno; pp->memlen = 64*OneMeg; pp->msec = ~0; pp->verstr[0] = 0; pp->mem = mapmem(mem, 64*OneMeg, 0); pp->memmap.ca = 0; pp->memmap.cea = 64*MB; pp->memmap.isa = (ulong)pp->mem; pp->memmap.len = 64*OneMeg; pp->memmap.attr = 0; pp->attr = mapmem(attr, OneMeg, 0); pp->attrmap.ca = 0; pp->attrmap.cea = MB; pp->attrmap.isa = (ulong)pp->attr; pp->attrmap.len = OneMeg; pp->attrmap.attr = 1; pp->regs = mapspecial(regs, 32*1024); } PCMmap* pcmmap(int slotno, ulong, int, int attr) { if(slotno > nslot) panic("pcmmap"); if(attr) return &slot[slotno].attrmap; else return &slot[slotno].memmap; } void pcmunmap(int, PCMmap*) { } /* * setup card timings * times are in ns * count = ceiling[access-time/(2*3*T)] - 1, where T is a processor cycle * */ static int ns2count(int ns) { ulong y; /* get 100 times cycle time */ y = 100000000/(conf.hz/1000); /* get 10 times ns/(cycle*6) */ y = (1000*ns)/(6*y); /* round up */ y += 9; y /= 10; /* subtract 1 */ return y-1; } static void slottiming(int slotno, int tio, int tattr, int tmem, int fast) { ulong x; x = 0; if(fast) x |= 1<mecr & 0xffff0000; } else { x <<= 16; x |= memconfregs->mecr & 0xffff; } memconfregs->mecr = x; } . 234c memmoveb(a, start+off, n); . 136,158c /* set timing to the default, 300 */ slottiming(0, 300, 300, 300, 0); slottiming(1, 300, 300, 300, 0); . 133,134c /* staticly map the whole area */ slotmap(0, PHYSPCM0REGS, PYHSPCM0ATTR, PYHSPCM0MEM); slotmap(1, PHYSPCM1REGS, PYHSPCM1ATTR, PYHSPCM1MEM); . 112,129d 110c * set up the cards, default timing is 300 ns . 71,108d 29a static void increfp(PCMslot*); static void decrefp(PCMslot*); static void slotmap(int, ulong, ulong, ulong); static void slottiming(int, int, int, int, int); . ## diffname bitsy/devpcmcia.c 2000/1122 ## diff -e /n/emeliedump/2000/1121/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1122/sys/src/9/bitsy/devpcmcia.c 321d 314,315c if(pp->occupied && pp->cisread == 0) pcmcisread(pp); . 312d 310c delay(200); /* time to power up */ . 306a slotinfo(nil, nil); . 298,299c if(!slot[0].occupied && (x & GPIO_CARD_IND0_i)){ slot[0].occupied = 1; slot[0].cisread = 0; } if(!slot[1].occupied && (x & GPIO_CARD_IND1_i)){ slot[1].occupied = 1; slot[0].cisread = 0; } . 289c slotinfo(Ureg*, void*) . 88a /* interrupt on card insertion */ gpiointrenable( . ## diffname bitsy/devpcmcia.c 2000/1128 ## diff -e /n/emeliedump/2000/1122/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1128/sys/src/9/bitsy/devpcmcia.c 330c decref(&pp->ref); . 322c incref(&pp->ref); . 90,91c /* interrupt on card insertion/removal */ gpiointrenable(GPIO_CARD_IND1_i, GPIOboth, slotinfo, nil, "pcmcia slot1 status"); gpiointrenable(GPIO_CARD_IND0_i, GPIOboth, slotinfo, nil, "pcmcia slot0 status"); . 33a static void slotinfo(Ureg*, void*); . ## diffname bitsy/devpcmcia.c 2000/1130 ## diff -e /n/emeliedump/2000/1128/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1130/sys/src/9/bitsy/devpcmcia.c 318d ## diffname bitsy/devpcmcia.c 2000/1201 ## diff -e /n/emeliedump/2000/1130/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1201/sys/src/9/bitsy/devpcmcia.c 360c pp->attrmap.isa = (ulong)attr; . 353c pp->memmap.isa = (ulong)mem; . 309c slot[1].cisread = 0; . 307c if(x & GPIO_CARD_IND1_i){ slot[1].occupied = 0; slot[1].cisread = 0; } else if(slot[1].occupied == 0){ . 303c if(x & GPIO_CARD_IND0_i){ slot[0].occupied = 0; slot[0].cisread = 0; } else if(slot[0].occupied == 0){ . ## diffname bitsy/devpcmcia.c 2000/1205 ## diff -e /n/emeliedump/2000/1201/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1205/sys/src/9/bitsy/devpcmcia.c 370c sp->regs = mapspecial(regs, 32*1024); . 363,368c sp->attr = mapmem(attr, OneMeg, 0); sp->attrmap.ca = 0; sp->attrmap.cea = MB; sp->attrmap.isa = (ulong)attr; sp->attrmap.len = OneMeg; sp->attrmap.attr = 1; . 356,361c sp->mem = mapmem(mem, 64*OneMeg, 0); sp->memmap.ca = 0; sp->memmap.cea = 64*MB; sp->memmap.isa = (ulong)mem; sp->memmap.len = 64*OneMeg; sp->memmap.attr = 0; . 350,354c sp = &slot[slotno]; sp->slotno = slotno; sp->memlen = 64*OneMeg; sp->verstr[0] = 0; . 348c PCMslot *sp; . 343c * the regions are staticly masped . 337c decref(&sp->ref); . 335c decrefp(PCMslot *sp) . 329,331c incref(&sp->ref); slotinfo(nil, nil); if(sp->occupied && sp->cisread == 0) pcmcisread(sp); wunlock(sp); poperror(); . 327c delay(500); . 325a delay(200); egpiobits(EGPIO_pcmcia_reset, 1); delay(100); . 323a wlock(sp); if(waserror()){ wunlock(sp); nexterror(); } . 322c increfp(PCMslot *sp) . 315d 313c } else { if(slot[1].occupied == 0) slot[1].cisread = 0; . 308d 306c } else { if(slot[0].occupied == 0) slot[0].cisread = 0; . 265c return pcmctlwrite(a, n, offset, sp); . 263c if(!sp->occupied) . 261c return pcmwrite(a, n, offset, sp, sp->attr, OneMeg); . 259c if(!sp->occupied) . 257c return pcmwrite(a, n, offset, sp, sp->mem, 64*OneMeg); . 255c if(!sp->occupied) . 251c sp = slot + SLOTNO(c); . 248c PCMslot *sp; . 239,241c Cmdbuf *cmd; uchar *cp; int index, i, dtx; Rune r; DevConf cf; cmd = parsecmd(p, n); if(strcmp(cmd->f[0], "configure") == 0){ wlock(sp); if(waserror()){ wunlock(sp); nexterror(); } /* see if driver exists and is configurable */ if(cmd->nf < 3) 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"); /* set pcmcia card configuration */ index = 0; if(sp->def != nil) index = sp->def->index; if(cmd->nf > 3){ i = atoi(cmd->f[3]); if(i < 0 || i >= sp->nctab) error("bad configuration index"); index = i; } if(sp->cpresent & (1<attr; cp += sp->caddr + Rconfig; print("writing configuration register (%lux) with index %d\n", cp, index); *cp = index; } /* configure device */ strncpy(cf.type, cmd->f[2], sizeof(cf.type)-1); cf.type[sizeof(cf.type)-1] = 0; 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.size = 0; if(devtab[dtx]->config(1, p, &cf) < 0) error("couldn't configure device"); wunlock(sp); poperror(); /* don't let the power turn off */ increfp(sp); } free(cmd); . 237c pcmctlwrite(char *p, long n, ulong, PCMslot *sp) . 232a poperror(); runlock(sp); . 227a rlock(sp); if(waserror()){ runlock(sp); nexterror(); } . 226c pcmwrite(void *a, long n, ulong off, PCMslot *sp, uchar *start, ulong len) . 219c return pcmctlread(a, n, offset, sp); . 217c return pcmread(a, n, offset, sp, sp->attr, OneMeg); . 215c if(!sp->occupied) . 213c return pcmread(a, n, offset, sp, sp->mem, 64*OneMeg); . 211c if(!sp->occupied) . 205c sp = slot + SLOTNO(c); . 202c PCMslot *sp; . 188,189c if(sp->verstr[0]) p = seprint(p, e, "version %s\n", sp->verstr); . 186c if(sp->occupied){ . 174c pcmctlread(void *a, long n, ulong off, PCMslot *sp) . 169a runlock(sp); poperror(); . 164a rlock(sp); if(waserror()){ runlock(sp); nexterror(); } . 163c pcmread(void *a, long n, ulong off, PCMslot *sp, uchar *start, ulong len) . 91,93c /* 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"); . 76a static int bitno(ulong x) { int i; for(i = 0; i < 8*sizeof(x); i++) if((1<memlen; . 60c len = sp->memlen; . 54c sp = slot + slotno; . 42c PCMslot *sp; . 25a enum { /* * configuration registers - they start at an offset in attribute * memory found in the CIS. */ Rconfig= 0, Creset= (1<<7), /* reset device */ Clevel= (1<<6), /* level sensitive interrupt line */ }; . ## diffname bitsy/devpcmcia.c 2000/1206 ## diff -e /n/emeliedump/2000/1205/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2000/1206/sys/src/9/bitsy/devpcmcia.c 319d ## diffname bitsy/devpcmcia.c 2001/0529 ## diff -e /n/emeliedump/2000/1206/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devpcmcia.c 377d 323,324c kstrdup(&cf.type, cmd->f[2]); . 158c if((c->qid.type & QTDIR) == 0) . 143c if(c->qid.type & QTDIR){ . 137c return devstat(c, db, n, 0, 0, pcmgen); . 134,135c static int pcmciastat(Chan *c, uchar *db, int n) . 131c return devwalk(c, nc, name, nname, 0, 0, pcmgen); . 128,129c static Walkqid* pcmciawalk(Chan *c, Chan *nc, char **name, int nname) . 84c devdir(c, qid, up->genbuf, len, eve, 0660, dp); . 80c snprint(up->genbuf, sizeof up->genbuf, "pcm%dctl", slotno); . 75c snprint(up->genbuf, sizeof up->genbuf, "pcm%dattr", slotno); . 70c snprint(up->genbuf, sizeof up->genbuf, "pcm%dmem", slotno); . 57c mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, "#y", 0, eve, 0555, dp); . 54d 48c pcmgen(Chan *c, char *, Dirtab * , int, int i, Dir *dp) . 37,38c #define SLOTNO(c) ((ulong)((c->qid.path>>8)&0xff)) #define TYPE(c) ((ulong)(c->qid.path&0xff)) . ## diffname bitsy/devpcmcia.c 2001/0616 ## diff -e /n/emeliedump/2001/0529/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2001/0616/sys/src/9/bitsy/devpcmcia.c 440a } . 439c if(sp->occupied && sp->cisread == 0) { . 422a print("increfp\n"); . 349c sp = slotno(c); . 238c sp = slotno(c); . 159c decrefp(slotno(c)); . 147c increfp(slotno(c)); . 142a print("pcmciaopen\n"); . 79c qid.path = PATH(slotno, Qctl); . 74c qid.path = PATH(slotno, Qattr); . 69c qid.path = PATH(slotno, Qmem); . 46a #define TYPE(c) (((ulong)c->qid.path)&0xff) #define PATH(s,t) (((s)<<8)|(t)) static PCMslot* slotno(Chan *c) { ulong x; x = c->qid.path; return slot + ((x>>8)&0xff); } . 37,40d ## diffname bitsy/devpcmcia.c 2001/0617 ## diff -e /n/emeliedump/2001/0616/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2001/0617/sys/src/9/bitsy/devpcmcia.c 331a cf.type = nil; . ## diffname bitsy/devpcmcia.c 2001/0619 ## diff -e /n/emeliedump/2001/0617/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2001/0619/sys/src/9/bitsy/devpcmcia.c 433d 359c sp = slotof(c); . 247c sp = slotof(c); . 168c decrefp(slotof(c)); . 155,156c } else { slotp = slotof(c); increfp(slotp); } . 151c PCMslot *slotp; . 91a qid.type = QTFILE; . 47c slotof(Chan *c) . ## diffname bitsy/devpcmcia.c 2001/0815 ## diff -e /n/emeliedump/2001/0619/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2001/0815/sys/src/9/bitsy/devpcmcia.c 507a . 497a . ## diffname bitsy/devpcmcia.c 2002/0109 ## diff -e /n/emeliedump/2001/0815/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0109/sys/src/9/bitsy/devpcmcia.c 388a devshutdown, . ## diffname bitsy/devpcmcia.c 2002/0607 ## diff -e /n/emeliedump/2002/0109/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0607/sys/src/9/bitsy/devpcmcia.c 350a }else if(strcmp(cmd->f[0], "remove") == 0){ wlock(sp); if(waserror()){ wunlock(sp); nexterror(); } wunlock(sp); poperror(); . 118,128c pcmciapower(1); . 108a * power up/down pcmcia */ static void pcmciapower(int up) { /* if there's no pcmcia sleave, no interrupts */ if(gpioregs->level & GPIO_OPT_IND_i) return; if (up){ /* 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"); }else{ } } /* . ## diffname bitsy/devpcmcia.c 2002/0613 ## diff -e /n/emeliedump/2002/0607/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0613/sys/src/9/bitsy/devpcmcia.c 359a wunlock(&cf); . 357d 351c memset(&cf, 0, sizeof cf); wlock(&cf); . ## diffname bitsy/devpcmcia.c 2002/0614 ## diff -e /n/emeliedump/2002/0613/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0614/sys/src/9/bitsy/devpcmcia.c 374,376c /* let the power turn off */ decrefp(sp); . 368,372c /* 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"); . 360d 352d ## diffname bitsy/devpcmcia.c 2002/0615 ## diff -e /n/emeliedump/2002/0614/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0615/sys/src/9/bitsy/devpcmcia.c 356c cf.intnum = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i); . ## diffname bitsy/devpcmcia.c 2002/0618 ## diff -e /n/emeliedump/2002/0615/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0618/sys/src/9/bitsy/devpcmcia.c 433a pcmciapower, . 358a sp->dev = devtab[dtx]; print("pcmctlwrite: configure %s: 0x%p\n", cmd->f[1], sp->dev); . 143c /* 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"); . 129a 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); . 126,128c 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); } } . 117c if (on){ . 113a PCMslot *sp; . 111,112c void pcmciapower(int on) . ## diffname bitsy/devpcmcia.c 2002/0619 ## diff -e /n/emeliedump/2002/0618/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0619/sys/src/9/bitsy/devpcmcia.c 400,401d 153,154d 142,145c // if (sp->dev->power) // sp->dev->power(on); . ## diffname bitsy/devpcmcia.c 2002/0626 ## diff -e /n/emeliedump/2002/0619/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0626/sys/src/9/bitsy/devpcmcia.c 540c * the regions are staticly mapped . 536a } . 535c if(decref(&pcmcia) == 0){ iprint("increfp power down\n"); . 533a iprint("decrefp %ld\n", sp - slot); . 513a iprint("increfp full power\n"); . 512a iprint("increfp %ld\n", sp - slot); . 450a /* * power up/down pcmcia */ void pcmciapower(int on) { PCMslot *sp; /* if there's no pcmcia sleave, no interrupts */ iprint("pcmciapower %d\n", on); if (on){ /* 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){ iprint("pcmciapower: no sleeve\n"); return; } for (sp = slot; sp < slot + nslot; sp++){ if (sp->dev){ increfp(sp); iprint("pcmciapower: %s\n", sp->verstr); if (sp->dev->power) sp->dev->power(on); } } }else{ if(gpioregs->level & GPIO_OPT_IND_i){ iprint("pcmciapower: no sleeve\n"); return; } for (sp = slot; sp < slot + nslot; sp++){ if (sp->dev){ if (sp->dev->power) sp->dev->power(on); decrefp(sp); } sp->occupied = 0; sp->cisread = 0; } egpiobits(EGPIO_exp_nvram_power|EGPIO_exp_full_power, 0); } } . 109,159d ## diffname bitsy/devpcmcia.c 2002/0702 ## diff -e /n/emeliedump/2002/0626/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0702/sys/src/9/bitsy/devpcmcia.c 425a delay(10000); . ## diffname bitsy/devpcmcia.c 2002/0703 ## diff -e /n/emeliedump/2002/0702/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/0703/sys/src/9/bitsy/devpcmcia.c 341c cf.irq = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i); . ## diffname bitsy/devpcmcia.c 2002/1112 ## diff -e /n/emeliedump/2002/0703/sys/src/9/bitsy/devpcmcia.c /n/emeliedump/2002/1112/sys/src/9/bitsy/devpcmcia.c 630a } /* For compat with ../pc devices. Don't use it for the bitsy */ int pcmspecial(char*, ISAConf*) { return -1; . 498a if (inserted(nil)) wakeup(&pcmcia.event); . 496a } . 495c if(slot[1].occupied == 0){ slot[1].inserted = 1; . 492c slot[1].occupied = slot[1].inserted = 0; . 488a } . 487c if(slot[0].occupied == 0){ slot[0].inserted = 1; . 484c slot[0].occupied = slot[0].inserted = 0; . 480,481c slot[0].occupied = slot[0].inserted = 0; slot[1].occupied = slot[1].inserted = 0; . 390a case Qevs: break; . 341c cf.intnum = bitno(sp == slot ? GPIO_CARD_IRQ0_i : GPIO_CARD_IRQ1_i); . 339c cf.ports = &port; cf.ports[0].port = (ulong)sp->regs; cf.ports[0].size = 0; cf.nports = 1; . 296a port_t port; . 263a case Qevs: return pcmevsread(a, n, offset); . 245a pcmevsread(void *a, long n, ulong off) { int i; char *buf = nil; char *e; if (pcmcia.evreader) error("At most one reader"); off = 0; pcmcia.evreader++; if (waserror()){ free(buf); pcmcia.evreader--; nexterror(); } while((i = inserted(nil)) == 0){ slotinfo(nil, nil); tsleep(&pcmcia.event, inserted, nil, 500); } pcmcia.evreader--; slot[i-1].inserted = 0; buf = malloc(READSTR); e = buf + READSTR; buf[0] = 0; seprint(buf, e, "#y/pcm%dctl\n", i-1); n = readstr(off, a, n, buf); free(buf); poperror(); return n; } static long . 244a static int inserted(void *) { if (slot[0].inserted) return 1; if (slot[1].inserted) return 2; return 0; } . 90a found: . 70a if(i == Nents*nslot){ len = 0; qid.path = PATH(0, Qevs); snprint(up->genbuf, sizeof up->genbuf, "pcmevs"); goto found; } . 69c if(i >= Nents*nslot + 1) . 21a Qevs, . 13a Rendez event; // where to wait for card events int evreader; // there's a reader for events . 8a /* * BUG: insertion events are detected by polling. * Should look into the compaq docs to see if * there's an interrupt for card insertion * there's probably one. */ .