2 #include "../port/lib.h"
6 #include "../port/error.h"
14 * read and crack the card information structure enough to set
15 * important parameters like power
17 /* cis memory walking */
18 typedef struct Cisdat {
25 static void tcfig(PCMslot*, Cisdat*, int);
26 static void tentry(PCMslot*, Cisdat*, int);
27 static void tvers1(PCMslot*, Cisdat*, int);
28 static void tlonglnkmfc(PCMslot*, Cisdat*, int);
31 readc(Cisdat *cis, uchar *x)
33 if(cis->cispos >= cis->cislen)
35 *x = cis->cisbase[cis->cisskip*cis->cispos];
41 xcistuple(int slotno, int tuple, int subtuple, void *v, int nv, int attr)
47 uchar type, link, n, c;
50 m = pcmmap(slotno, 0, 0, attr);
54 cis.cisbase = KADDR(m->isa);
56 cis.cisskip = attr ? 2 : 1;
59 /* loop through all the tuples */
60 for(i = 0; i < 1000; i++){
62 if(readc(&cis, &type) != 1)
66 if(readc(&cis, &link) != 1)
72 if(link > 1 && subtuple != -1){
73 if(readc(&cis, &c) != 1)
80 if(type == tuple && subtype == subtuple){
82 for(l=0; l<nv && l<n; l++)
83 if(readc(&cis, p++) != 1)
88 cis.cispos = this + (2+link);
95 pcmcistuple(int slotno, int tuple, int subtuple, void *v, int nv)
99 /* try attribute space, then memory */
100 if((n = xcistuple(slotno, tuple, subtuple, v, nv, 1)) >= 0)
102 return xcistuple(slotno, tuple, subtuple, v, nv, 0);
106 pcmcisread(PCMslot *pp)
113 memset(pp->ctab, 0, sizeof(pp->ctab));
115 memset(pp->cfg, 0, sizeof(pp->cfg));
121 * Read all tuples in attribute space.
123 m = pcmmap(pp->slotno, 0, 0, 1);
127 cis.cisbase = KADDR(m->isa);
132 /* loop through all the tuples */
135 if(readc(&cis, &type) != 1)
139 if(readc(&cis, &link) != 1)
146 tlonglnkmfc(pp, &cis, type);
149 tvers1(pp, &cis, type);
152 tcfig(pp, &cis, type);
155 tentry(pp, &cis, type);
161 cis.cispos = this + (2+link);
163 pcmunmap(pp->slotno, m);
167 getlong(Cisdat *cis, int size)
174 for(i = 0; i < size; i++){
175 if(readc(cis, &c) != 1)
183 tcfig(PCMslot *pp, Cisdat *cis, int )
185 uchar size, rasize, rmsize;
188 if(readc(cis, &size) != 1)
190 rasize = (size&0x3) + 1;
191 rmsize = ((size>>2)&0xf) + 1;
192 if(readc(cis, &last) != 1)
196 print("tcfig: too many configuration registers\n");
200 pp->cfg[pp->ncfg].caddr = getlong(cis, rasize);
201 pp->cfg[pp->ncfg].cpresent = getlong(cis, rmsize);
205 static ulong vexp[8] =
207 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
209 static ulong vmant[16] =
211 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
215 microvolt(Cisdat *cis)
221 if(readc(cis, &c) != 1)
224 microvolts = vmant[(c>>3)&0xf]*exp;
226 if(readc(cis, &c) != 1)
230 break; /* high impedence when sleeping */
233 microvolts = 0; /* no connection */
237 microvolts += exp*(c&0x7f);
244 nanoamps(Cisdat *cis)
249 if(readc(cis, &c) != 1)
251 nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
253 if(readc(cis, &c) != 1)
255 if(c == 0x7d || c == 0x7e || c == 0x7f)
262 * only nominal voltage (feature 1) is important for config,
263 * other features must read card to stay in sync.
272 if(readc(cis, &feature) != 1)
291 static ulong mantissa[16] =
292 { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, };
294 static ulong exponent[8] =
295 { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };
298 ttiming(Cisdat *cis, int scale)
303 if(readc(cis, &unscaled) != 1)
305 nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
306 nanosecs = nanosecs * vexp[scale];
311 timing(Cisdat *cis, PCMconftab *ct)
315 if(readc(cis, &c) != 1)
319 ct->maxwait = ttiming(cis, i); /* max wait */
322 ct->readywait = ttiming(cis, i); /* max ready/busy wait */
325 ct->otherwait = ttiming(cis, i); /* reserved wait */
329 iospaces(Cisdat *cis, PCMconftab *ct)
335 if(readc(cis, &c) != 1)
338 ct->bit16 = ((c>>5)&3) >= 2;
341 ct->io[0].len = 1<<(c&0x1f);
346 if(readc(cis, &c) != 1)
350 * For each of the range descriptions read the
351 * start address and the length (value is length-1).
354 for(i = 0; i < nio; i++){
355 ct->io[i].start = getlong(cis, (c>>4)&0x3);
356 ct->io[i].len = getlong(cis, (c>>6)&0x3)+1;
362 irq(Cisdat *cis, PCMconftab *ct)
366 if(readc(cis, &c) != 1)
368 ct->irqtype = c & 0xe0;
370 ct->irqs = getlong(cis, 2);
372 ct->irqs = 1<<(c&0xf);
373 ct->irqs &= 0xDEB8; /* levels available to card */
377 memspace(Cisdat *cis, int asize, int lsize, int host)
379 ulong haddress, address, len;
381 len = getlong(cis, lsize)*256;
382 address = getlong(cis, asize)*256;
385 haddress = getlong(cis, asize)*256;
391 tentry(PCMslot *pp, Cisdat *cis, int )
396 if(pp->nctab >= nelem(pp->ctab))
398 if(readc(cis, &c) != 1)
400 ct = &pp->ctab[pp->nctab++];
402 /* copy from last default config */
406 ct->index = c & 0x3f;
408 /* is this the new default? */
412 /* memory wait specified? */
414 if(readc(cis, &i) != 1)
420 if(readc(cis, &feature) != 1)
424 ct->vpp1 = ct->vpp2 = power(cis);
428 ct->vpp1 = ct->vpp2 = power(cis);
432 ct->vpp1 = power(cis);
433 ct->vpp2 = power(cis);
444 switch((feature>>5)&0x3){
446 memspace(cis, 0, 2, 0);
449 memspace(cis, 2, 2, 0);
452 if(readc(cis, &c) != 1)
454 for(i = 0; i <= (c&0x7); i++)
455 memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
462 tvers1(PCMslot *pp, Cisdat *cis, int )
464 uchar c, major, minor, last;
467 if(readc(cis, &major) != 1)
469 if(readc(cis, &minor) != 1)
472 for(i = 0; i < sizeof(pp->verstr)-1; i++){
473 if(readc(cis, &c) != 1)
481 if(c == ';' && last == ';')
490 tlonglnkmfc(PCMslot *pp, Cisdat *cis, int)
493 uchar nfn, space, expect, type, this, link;
496 for(i = 0; i < nfn; i++){
498 npos = getlong(cis, 4);
505 if(readc(cis, &type) != 1)
509 if(readc(cis, &link) != 1)
512 if(expect && expect != type){
513 print("tlonglnkmfc: expected %X found %X\n",
523 tvers1(pp, cis, type);
526 tcfig(pp, cis, type);
529 tentry(pp, cis, type);
535 cis->cispos = this + (2+link);