## diffname mpc/devpcmcia.c 1999/0608
## diff -e /dev/null /n/emeliedump/1999/0608/sys/src/brazil/mpc/devpcmcia.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
/*
* MPC8xx PCMCIA driver
*
*/
typedef struct PCMmap PCMmap;
typedef struct Slot Slot;
typedef struct Conftab Conftab;
enum
{
Maxctlr= 1,
/* pipr */
Cvs1= 1<<15, // voltage sense 1
Cvs2= 1<<14, // voltage sense 2
Cwp= 1<<13, // write protect
Ccd2= 1<<12, // card detect 2
Ccd1= 1<<11, // card detect 1
Cbvd2= 1<<10, // battery voltage 2
Cbvd1= 1<<9, // battery voltage 1
Crdy= 1<<8, // ready
/* pscr */
Cvs1_c= 1<<15, // voltage sense 1 changed
Cvs2_c= 1<<14, // voltage sense 2 changed
Cwp_c= 1<<13, // write protect changed
Ccd2_c= 1<<12, // card detect 2 changed
Ccd1_c= 1<<11, // card detect 1 changed
Cbvd2_c= 1<<10, // battery voltage 2 changed
Cbvd1_c= 1<<9, // battery voltage 1 changed
Crdy_l= 1<<7, // ready is low
Crdy_h= 1<<6, // ready is hi
Crdy_r= 1<<5, // ready raising edge
Crdy_f= 1<<4, // ready falling edge
/* pgcrx */
Creset = IBIT(25), // card reset
Coe = IBIT(24), // output enable
/* porN */
Rport8= 0<<6,
Rport16= 1<<6,
Rmem= 0<<3, /* common memory space */
Rattrib= 2<<3, /* attribute space */
Rio= 3<<3,
Rdma= 4<<3, /* normal DMA */
Rdmalx= 5<<3, /* DMA, last transaction */
RA22_23= 6<<3, /* ``drive A22 and A23 signals on CE2 and CE1'' */
RslotB= 1<<2, /* select slot B (always, on MPC823) */
Rwp= 1<<1, /* write protect */
Rvalid= 1<<0, /* region valid */
/*
* configuration registers - they start at an offset in attribute
* memory found in the CIS.
*/
Rconfig= 0,
Clevel= (1<<6), /* level sensitive interrupt line */
Maxctab= 8, /* maximum configuration table entries */
Nmap= 4, // map entries per slot
Mshift= 12,
Mgran= (1<<Mshift), /* granularity of maps */
Mmask= ~(Mgran-1), /* mask for address bits important to the chip */
};
/* configuration table entry */
struct Conftab
{
int index;
ushort irqs; /* legal irqs */
uchar irqtype;
uchar bit16; /* true for 16 bit access */
struct {
ulong start;
ulong len;
} io[16];
int nio;
uchar vpp1;
uchar vpp2;
uchar memwait;
ulong maxwait;
ulong readywait;
ulong otherwait;
};
/*
* Map between ISA memory space and PCMCIA card memory space.
*/
struct PCMmap {
ulong ca; /* card address */
ulong cea; /* card end address */
ulong isa; /* ISA address */
int len; /* length of the ISA area */
int attr; /* attribute memory */
int ref;
};
/* a card slot */
struct Slot
{
Lock;
int ref;
long memlen; /* memory length */
uchar base; /* index register base */
uchar slotno; /* slot number */
/* status */
uchar special; /* in use for a special device */
uchar already; /* already inited */
uchar occupied;
uchar voltage;
uchar battery;
uchar wrprot;
uchar powered;
uchar configed;
uchar enabled;
uchar busy;
/* cis info */
char verstr[512]; /* version string */
uchar cpresent; /* config registers present */
ulong caddr; /* relative address of config registers */
int nctab; /* number of config table entries */
Conftab ctab[Maxctab];
Conftab *def; /* default conftab */
/* for walking through cis */
int cispos; /* current position scanning cis */
uchar *cisbase;
/* memory maps */
Lock mlock; /* lock down the maps */
int time;
PCMmap mmap[Nmap]; /* maps, last is always for the kernel */
};
enum
{
Qdir,
Qmem,
Qattr,
Qctl,
};
#define SLOTNO(c) ((c->qid.path>>8)&0xff)
#define TYPE(c) (c->qid.path&0xff)
#define QID(s,t) (((s)<<8)|(t))
static void pcmciaintr(Ureg *, void *);
static void increfp(Slot *pp);
static void decrefp(Slot *pp);
static PCMmap* pcmmap(Slot*, ulong, int, int);
static void pcmunmap(Slot*, PCMmap*);
static Slot *slot;
static nslot;
static int
pcmgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)
{
int slotno;
Qid qid;
long len;
Slot *pp;
char name[NAMELEN];
USED(tab, ntab);
if(i>=3*nslot)
return -1;
slotno = i/3;
pp = slot + slotno;
len = 0;
switch(i%3){
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;
}
/*
* set up for slot cards
*/
static void
pcmciareset(void)
{
static int already;
int i;
IMM *io;
Slot *pp;
if(already)
return;
already = 1;
nslot = 2;
slot = xalloc(nslot * sizeof(Slot));
io = m->iomem;
for(i=0; i<8; i++){
io->pcmr[i].option = 0;
io->pcmr[i].base = 0;
}
for(i=0; i<2; i++)
io->pgcr[i] = (1<<(31-PCMCIAlevel)) | (1<<(23-PCMCIAlevel));
for(i = 0; i < nslot; i++){
pp = slot + i;
pp->slotno = i;
pp->memlen = 512*1024;
}
/* 512K - slow - attr */
io->pcmr[0].base = ISAMEM + 512*1024;
io->pcmr[0].option = (0x1a<<27) | (8<<16) | (6<<12) | (24<<7)
| Rport16 | Rattrib | Rvalid;
// 64K io
io->pcmr[1].base = ISAMEM+0x300;
io->pcmr[1].option = (0x6<<27) | (2<<16) | (4<<12) | (8<<7)
| Rport16 | Rio | Rvalid;
// intrenable(VectorPIC+PCMCIAlevel, pcmciaintr, 0, BUSUNKNOWN);
io->pscr = 0xFEF0FEF0; /* reset status */
io->per = 0x00800000; /* enable interrupts */
print("pcmcia reset\n");
}
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++;
}
static long
pcmread(int slotno, int attr, void *a, long n, vlong offset)
{
int i, len;
PCMmap *m;
ulong ka;
uchar *ac;
Slot *pp;
pp = slot + slotno;
if(pp->memlen < offset)
return 0;
if(pp->memlen < offset + n)
n = pp->memlen - offset;
m = 0;
if(waserror()){
if(m)
pcmunmap(pp, m);
nexterror();
}
ac = a;
for(len = n; len > 0; len -= i){
m = pcmmap(pp, offset, 0, attr);
if(m == 0)
error("can't map PCMCIA card");
if(offset + len > m->cea)
i = m->cea - offset;
else
i = len;
ka = KZERO|(m->isa + offset - m->ca);
memmoveb(ac, (void*)ka, i);
pcmunmap(pp, m);
offset += i;
ac += i;
}
poperror();
return n;
}
static long
pcmciaread(Chan *c, void *a, long n, vlong offset)
{
char *cp, *buf;
ulong p;
Slot *pp;
p = TYPE(c);
switch(p){
case Qdir:
return devdirread(c, a, n, 0, 0, pcmgen);
case Qmem:
case Qattr:
return pcmread(SLOTNO(c), p==Qattr, a, n, offset);
case Qctl:
buf = malloc(2048);
if(buf == nil)
error(Enomem);
if(waserror()){
free(buf);
nexterror();
}
cp = buf;
pp = slot + SLOTNO(c);
if(pp->occupied)
cp += sprint(cp, "occupied\n");
if(pp->enabled)
cp += sprint(cp, "enabled\n");
if(pp->powered)
cp += sprint(cp, "powered\n");
if(pp->configed)
cp += sprint(cp, "configed\n");
if(pp->wrprot)
cp += sprint(cp, "write protected\n");
if(pp->busy)
cp += sprint(cp, "busy\n");
cp += sprint(cp, "battery lvl %d\n", pp->battery);
cp += sprint(cp, "voltage select %d\n", pp->voltage);
cp += sprint(cp, "pipr %ux\n", m->iomem->pipr);
cp += sprint(cp, "pcsr %ux\n", m->iomem->pscr);
*cp = 0;
n = readstr(offset, a, n, buf);
poperror();
free(buf);
break;
default:
n=0;
break;
}
return n;
}
static long
pcmwrite(int dev, int attr, void *a, long n, vlong offset)
{
int i, len;
PCMmap *m;
ulong ka;
uchar *ac;
Slot *pp;
pp = slot + dev;
if(pp->memlen < offset)
return 0;
if(pp->memlen < offset + n)
n = pp->memlen - offset;
#ifdef xxx
m = 0;
if(waserror()){
if(m)
pcmunmap(pp->slotno, m);
nexterror();
}
ac = a;
for(len = n; len > 0; len -= i){
m = pcmmap(pp, offset, 0, attr);
if(m == 0)
error("can't map PCMCIA card");
if(offset + len > m->cea)
i = m->cea - offset;
else
i = len;
ka = KZERO|(m->isa + offset - m->ca);
memmoveb((void*)ka, ac, i);
pcmunmap(pp->slotno, m);
offset += i;
ac += i;
}
poperror();
#endif
return n;
}
static long
pcmciawrite(Chan *c, void *a, long n, vlong offset)
{
ulong p;
Slot *pp;
char buf[32];
p = TYPE(c);
switch(p){
case Qctl:
if(n >= sizeof(buf))
n = sizeof(buf) - 1;
strncpy(buf, a, n);
buf[n] = 0;
pp = slot + SLOTNO(c);
if(!pp->occupied)
error(Eio);
break;
case Qmem:
case Qattr:
pp = slot + SLOTNO(c);
if(pp->occupied == 0 || pp->enabled == 0)
error(Eio);
n = pcmwrite(pp->slotno, p == Qattr, a, n, offset);
if(n < 0)
error(Eio);
break;
default:
error(Ebadusefd);
}
return n;
}
Dev pcmciadevtab = {
'y',
"pcmcia",
pcmciareset,
devinit,
pcmciaattach,
devclone,
pcmciawalk,
pcmciastat,
pcmciaopen,
devcreate,
pcmciaclose,
pcmciaread,
devbread,
pcmciawrite,
devbwrite,
devremove,
devwstat,
};
static void
pcmciaintr(Ureg *, void *)
{
print("pcmciaintr\n");
}
/*
* get a map for pc card region, return corrected len
*/
static PCMmap*
pcmmap(Slot *pp, ulong offset, int len, int attr)
{
PCMmap *m;
ulong e;
if(attr == 0)
panic("pcmmap");
/* convert offset to granularity */
if(len <= 0)
len = 1;
e = ROUND(offset+len, Mgran);
offset &= Mmask;
len = e - offset;
m = pp->mmap;
m->ca = 0;
m->cea = 512*1024;
m->isa = ISAMEM + 512*1024;
m->len = 512*1024;
m->attr = attr;
m->ref = 1;
return m;
}
static void
pcmunmap(Slot *pp, PCMmap *m)
{
}
static int
pcmio(int slotno, ISAConf *isa)
{
uchar we, x, *p;
Slot *pp;
Conftab *ct, *et, *t;
PCMmap *m;
int i, index, irq;
char *cp;
isa->irq = VectorPIC+PCMCIAlevel;
irq = isa->irq;
if(slotno > nslot)
return -1;
pp = slot + slotno;
if(!pp->occupied)
return -1;
et = &pp->ctab[pp->nctab];
ct = 0;
for(i = 0; i < isa->nopt; i++){
if(strncmp(isa->opt[i], "index=", 6))
continue;
index = strtol(&isa->opt[i][6], &cp, 0);
if(cp == &isa->opt[i][6] || index >= pp->nctab)
return -1;
ct = &pp->ctab[index];
}
if(ct == 0){
/* assume default is right */
if(pp->def)
ct = pp->def;
else
ct = pp->ctab;
/* try for best match */
if(ct->nio == 0
|| ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){
for(t = pp->ctab; t < et; t++)
if(t->nio
&& t->io[0].start == isa->port
&& ((1<<irq) & t->irqs)){
ct = t;
break;
}
}
if(ct->nio == 0 || ((1<<irq) & ct->irqs) == 0){
for(t = pp->ctab; t < et; t++)
if(t->nio && ((1<<irq) & t->irqs)){
ct = t;
break;
}
}
if(ct->nio == 0){
for(t = pp->ctab; t < et; t++)
if(t->nio){
ct = t;
break;
}
}
}
if(ct == et || ct->nio == 0)
return -1;
/* enable io port map 0 */
if(isa->port == 0)
isa->port = ct->io[0].start;
if(isa->port == 0 && ct->io[0].start == 0)
return -1;
if(pp->cpresent & (1<<Rconfig)){
/* Reset adapter */
m = pcmmap(pp, pp->caddr + Rconfig, 1, 1);
p = KADDR(m->isa + pp->caddr + Rconfig - m->ca);
/* set configuration and interrupt type */
x = 1;
x |= ct->index<<1;
if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7)) {
x |= Clevel;
}
*p = x;
delay(5);
pcmunmap(pp, m);
}
return 0;
}
/*
* look for a card whose version contains 'idstr'
*/
int
pcmspecial(char *idstr, ISAConf *isa)
{
Slot *pp;
extern char *strstr(char*, char*);
for(pp = slot; pp < slot+nslot; pp++){
if(pp->special)
continue; /* already taken */
increfp(pp);
if(pp->occupied)
if(strstr(pp->verstr, idstr))
if(isa == 0 || pcmio(pp->slotno, isa) == 0){
pp->special = 1;
return pp->slotno;
}
decrefp(pp);
}
return -1;
}
void
pcmspecialclose(int slotno)
{
Slot *pp;
if(slotno >= nslot)
panic("pcmspecialclose");
pp = slot + slotno;
pp->special = 0;
decrefp(pp);
}
static void
slotinfo(Slot *pp)
{
ulong pipr;
pipr = m->iomem->pipr;
if(pp->slotno == 0)
pipr >>= 16;
pp->occupied = (pipr&(Ccd1|Ccd2))==0;
pp->battery = (pipr & (Cbvd1|Cbvd2)) != 0;
pp->voltage = ((pipr & Cvs1) != 0) | (((pipr & Cvs2) != 0)<<1);
pp->wrprot = (pipr&Cwp)==0;
pp->busy = (pipr&Crdy)==0;
pp->powered = 1; // assume power is always on for the momment
}
/*
* read and crack the card information structure enough to set
* important parameters like power
*/
static void tcfig(Slot*, int);
static void tentry(Slot*, int);
static void tvers1(Slot*, int);
static void (*parse[256])(Slot*, int) =
{
[0x15] tvers1,
[0x1A] tcfig,
[0x1B] tentry,
};
static int
readc(Slot *pp, uchar *x)
{
if(pp->cispos >= Mgran)
return 0;
*x = pp->cisbase[2*pp->cispos];
pp->cispos++;
return 1;
}
static void
cisread(Slot *pp)
{
uchar link;
uchar type;
int this, i;
PCMmap *m;
memset(pp->ctab, 0, sizeof(pp->ctab));
pp->caddr = 0;
pp->cpresent = 0;
pp->configed = 0;
pp->nctab = 0;
m = pcmmap(pp, 0, 0, 1);
if(m == 0)
return;
pp->cisbase = KADDR(m->isa);
pp->cispos = 0;
/* loop through all the tuples */
for(i = 0; i < 1000; i++){
this = pp->cispos;
if(readc(pp, &type) != 1)
break;
if(type == 0xFF)
break;
if(readc(pp, &link) != 1)
break;
if(parse[type])
(*parse[type])(pp, type);
if(link == 0xff)
break;
pp->cispos = this + (2+link);
}
pcmunmap(pp, m);
}
static ulong
getlong(Slot *pp, int size)
{
uchar c;
int i;
ulong x;
x = 0;
for(i = 0; i < size; i++){
if(readc(pp, &c) != 1)
break;
x |= c<<(i*8);
}
return x;
}
static void
tcfig(Slot *pp, int )
{
uchar size, rasize, rmsize;
uchar last;
if(readc(pp, &size) != 1)
return;
rasize = (size&0x3) + 1;
rmsize = ((size>>2)&0xf) + 1;
if(readc(pp, &last) != 1)
return;
pp->caddr = getlong(pp, rasize);
pp->cpresent = getlong(pp, rmsize);
}
/*
* enable the slot card
*/
static void
slotena(Slot *pp)
{
IMM *io;
int shift;
if(pp->enabled)
return;
shift = (pp->slotno == 0)?16:0;
io = m->iomem;
// io->pgcr[pp->slotno] |= Coe;
io->pgcr[pp->slotno] &= ~Coe; // active low
delay(300);
io->pgcr[pp->slotno] |= Creset;
delay(100);
io->pgcr[pp->slotno] &= ~Creset;
delay(500);
#ifdef XXX
eieio();
delay(300);
io->pgcrb |= Cbreset; /* TO DO: active high? active low? */
eieio();
delay(100);
io->pgcrb &= ~Cbreset;
eieio();
delay(500);
#endif
/* get configuration */
slotinfo(pp);
if(pp->occupied){
cisread(pp);
pp->enabled = 1;
}
}
/*
* disable the slot card
*/
static void
slotdis(Slot *pp)
{
pp->enabled = 0;
}
static void
increfp(Slot *pp)
{
lock(pp);
if(pp->ref++ == 0)
slotena(pp);
unlock(pp);
}
static void
decrefp(Slot *pp)
{
lock(pp);
if(pp->ref-- == 1)
slotdis(pp);
unlock(pp);
}
static ulong vexp[8] =
{
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
};
static ulong vmant[16] =
{
10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
};
static ulong
microvolt(Slot *pp)
{
uchar c;
ulong microvolts;
ulong exp;
if(readc(pp, &c) != 1)
return 0;
exp = vexp[c&0x7];
microvolts = vmant[(c>>3)&0xf]*exp;
while(c & 0x80){
if(readc(pp, &c) != 1)
return 0;
switch(c){
case 0x7d:
break; /* high impedence when sleeping */
case 0x7e:
case 0x7f:
microvolts = 0; /* no connection */
break;
default:
exp /= 10;
microvolts += exp*(c&0x7f);
}
}
return microvolts;
}
static ulong
nanoamps(Slot *pp)
{
uchar c;
ulong nanoamps;
if(readc(pp, &c) != 1)
return 0;
nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
while(c & 0x80){
if(readc(pp, &c) != 1)
return 0;
if(c == 0x7d || c == 0x7e || c == 0x7f)
nanoamps = 0;
}
return nanoamps;
}
/*
* only nominal voltage is important for config
*/
static ulong
power(Slot *pp)
{
uchar feature;
ulong mv;
mv = 0;
if(readc(pp, &feature) != 1)
return 0;
if(feature & 1)
mv = microvolt(pp);
if(feature & 2)
microvolt(pp);
if(feature & 4)
microvolt(pp);
if(feature & 8)
nanoamps(pp);
if(feature & 0x10)
nanoamps(pp);
if(feature & 0x20)
nanoamps(pp);
if(feature & 0x40)
nanoamps(pp);
return mv/1000000;
}
static ulong mantissa[16] =
{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };
static ulong exponent[8] =
{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };
static ulong
ttiming(Slot *pp, int scale)
{
uchar unscaled;
ulong nanosecs;
if(readc(pp, &unscaled) != 1)
return 0;
nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
nanosecs = nanosecs * vexp[scale];
return nanosecs;
}
static void
timing(Slot *pp, Conftab *ct)
{
uchar c, i;
if(readc(pp, &c) != 1)
return;
i = c&0x3;
if(i != 3)
ct->maxwait = ttiming(pp, i); /* max wait */
i = (c>>2)&0x7;
if(i != 7)
ct->readywait = ttiming(pp, i); /* max ready/busy wait */
i = (c>>5)&0x7;
if(i != 7)
ct->otherwait = ttiming(pp, i); /* reserved wait */
}
static void
iospaces(Slot *pp, Conftab *ct)
{
uchar c;
int i, nio;
ct->nio = 0;
if(readc(pp, &c) != 1)
return;
ct->bit16 = ((c>>5)&3) >= 2;
if(!(c & 0x80)){
ct->io[0].start = 0;
ct->io[0].len = 1<<(c&0x1f);
ct->nio = 1;
return;
}
if(readc(pp, &c) != 1)
return;
nio = (c&0xf)+1;
for(i = 0; i < nio; i++){
ct->io[i].start = getlong(pp, (c>>4)&0x3);
ct->io[0].len = getlong(pp, (c>>6)&0x3);
}
ct->nio = nio;
}
static void
irq(Slot *pp, Conftab *ct)
{
uchar c;
if(readc(pp, &c) != 1)
return;
ct->irqtype = c & 0xe0;
if(c & 0x10)
ct->irqs = getlong(pp, 2);
else
ct->irqs = 1<<(c&0xf);
ct->irqs &= 0xDEB8; /* levels available to card */
}
static void
memspace(Slot *pp, int asize, int lsize, int host)
{
ulong haddress, address, len;
len = getlong(pp, lsize)*256;
address = getlong(pp, asize)*256;
USED(len, address);
if(host){
haddress = getlong(pp, asize)*256;
USED(haddress);
}
}
static void
tentry(Slot *pp, int )
{
uchar c, i, feature;
Conftab *ct;
if(pp->nctab >= Maxctab)
return;
if(readc(pp, &c) != 1)
return;
ct = &pp->ctab[pp->nctab++];
/* copy from last default config */
if(pp->def)
*ct = *pp->def;
ct->index = c & 0x3f;
/* is this the new default? */
if(c & 0x40)
pp->def = ct;
/* memory wait specified? */
if(c & 0x80){
if(readc(pp, &i) != 1)
return;
if(i&0x80)
ct->memwait = 1;
}
if(readc(pp, &feature) != 1)
return;
switch(feature&0x3){
case 1:
ct->vpp1 = ct->vpp2 = power(pp);
break;
case 2:
power(pp);
ct->vpp1 = ct->vpp2 = power(pp);
break;
case 3:
power(pp);
ct->vpp1 = power(pp);
ct->vpp2 = power(pp);
break;
default:
break;
}
if(feature&0x4)
timing(pp, ct);
if(feature&0x8)
iospaces(pp, ct);
if(feature&0x10)
irq(pp, ct);
switch((feature>>5)&0x3){
case 1:
memspace(pp, 0, 2, 0);
break;
case 2:
memspace(pp, 2, 2, 0);
break;
case 3:
if(readc(pp, &c) != 1)
return;
for(i = 0; i <= (c&0x7); i++)
memspace(pp, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
break;
}
pp->configed++;
}
static void
tvers1(Slot *pp, int )
{
uchar c, major, minor;
int i;
if(readc(pp, &major) != 1)
return;
if(readc(pp, &minor) != 1)
return;
for(i = 0; i < sizeof(pp->verstr)-1; i++){
if(readc(pp, &c) != 1)
return;
if(c == 0)
c = '\n';
if(c == 0xff)
break;
pp->verstr[i] = c;
}
pp->verstr[i] = 0;
}
.
## diffname mpc/devpcmcia.c 1999/0623
## diff -e /n/emeliedump/1999/0608/sys/src/brazil/mpc/devpcmcia.c /n/emeliedump/1999/0623/sys/src/brazil/mpc/devpcmcia.c
746c
pcmunmap(pp->slotno, m);
.
725c
m = pcmmap(pp->slotno, 0, 0, 1);
.
627c
pcmunmap(pp->slotno, m);
.
624a
print("devpcmcia: x = %ux!\n", x);
.
621c
// x |= ct->index<<1;
.
616c
m = pcmmap(pp->slotno, pp->caddr + Rconfig, 1, 1);
.
614a
print("devpcmcia: reset caddr = %x!\n", pp->caddr);
.
535a
USED(slotno, m);
.
533,534c
void
pcmunmap(int slotno, PCMmap *m)
.
510a
pp = slot + slotno;
.
509a
Slot *pp;
.
505,506c
PCMmap*
pcmmap(int slotno, ulong offset, int len, int attr)
.
336c
pcmunmap(pp->slotno, m);
.
327c
m = pcmmap(pp->slotno, offset, 0, attr);
.
321c
pcmunmap(pp->slotno, m);
.
246c
| Rport8 | Rio | Rvalid;
.
163,164d
96,107d
14d
## diffname mpc/devpcmcia.c 1999/0727
## diff -e /n/emeliedump/1999/0623/sys/src/brazil/mpc/devpcmcia.c /n/emeliedump/1999/0727/sys/src/brazil/mpc/devpcmcia.c
792,801d
782d
778d
617c
pcmunmap(pp->slotno, mm);
.
614d
610c
x |= ct->index<<1;
.
605,606c
mm = pcmmap(pp->slotno, pp->caddr + Rconfig, 1, 1);
p = KADDR(mm->isa + pp->caddr + Rconfig - mm->ca);
.
603d
601a
// setup io space - this could be better
io->pcmr[1].base = ISAMEM+isa->port;
x = (0x6<<27) | (2<<16) | (4<<12) | (8<<7) | Rio | Rvalid;
/* 16-bit data path */
if(ct->bit16)
x |= Rport16;
else
x |= Rport8;
io->pcmr[1].option = x;
.
535a
io = m->iomem;
.
534a
IMM *io;
ulong x;
.
532c
PCMmap *mm;
.
529c
uchar *p;
.
506a
USED(len);
.
421d
406c
m = pcmmap(pp->slotno, offset, 0, attr);
.
396d
388a
uchar *ac;
ulong ka;
.
386,387d
367,368c
cp += sprint(cp, "pipr %ulx\n", m->iomem->pipr);
cp += sprint(cp, "pcsr %ulx\n", m->iomem->pscr);
.
228,231d
## diffname mpc/devpcmcia.c 1999/0930
## diff -e /n/emeliedump/1999/0727/sys/src/brazil/mpc/devpcmcia.c /n/emeliedump/1999/0930/sys/src/brazil/mpc/devpcmcia.c
603a
// x = (0x6<<27) | (8<<16) | (6<<12) | (24<<7) | Rio | Rvalid;
.
## diffname mpc/devpcmcia.c 1999/1231
## diff -e /n/emeliedump/1999/0930/sys/src/brazil/mpc/devpcmcia.c /n/emeliedump/1999/1231/sys/src/9/mpc/devpcmcia.c
163a
if(i == DEVDOTDOT){
devdir(c, c->qid, "#y", 0, eve, 0550, dp);
return 1;
}
.
## diffname mpc/devpcmcia.c 2001/0527 # deleted
## diff -e /n/emeliedump/1999/1231/sys/src/9/mpc/devpcmcia.c /n/emeliedump/2001/0527/sys/src/9/mpc/devpcmcia.c
1,1109d
|