14 void tdevice(int, int);
15 void tlonglnkmfc(int, int);
16 void tfuncid(int, int);
18 void tentry(int, int);
19 void tvers1(int, int);
21 void (*parse[256])(int, int) =
41 vseprint(buf, buf+sizeof(buf), fmt, arg);
43 fprint(2, "pcmcia: %s\n", buf);
56 print("%2.2ux ", *(uchar*)x);
61 tuple(int next, int expect)
71 print("type %.2uX\n", type & 0xff);
73 if(expect && expect != type){
74 print("expected %.2uX found %.2uX\n",
82 (*parse[type])(type, link);
91 main(int argc, char *argv[])
102 file = "#y/pcm0attr";
106 fd = open(file, OREAD);
108 fatal("opening %s: %r", file);
110 for(next = 0; next >= 0;)
111 next = tuple(next, 0);
173 for(i = 0; i < size; i++){
182 tdevice(int ttype, int len)
186 uchar speed, aespeed;
189 char *tname, *ttname;
198 /* PRISM cards have a device tuple with id = size = 0. */
200 if(readc(&size) != 1)
208 if(readc(&speed) != 1)
212 if(readc(&aespeed) != 1)
216 ns = (mantissa[(speed>>3)&0xf]*exponent[speed&7])/10;
218 ns = speedtab[speed];
222 if(readc(&type) != 1)
226 tname = typetab[type];
230 if(readc(&size) != 1)
233 bytes = ((size>>3)+1) * 512 * (1<<(2*(size&0x7)));
238 ttname = "attr device";
239 print("%s %ld bytes of %ldns %s\n", ttname, bytes, ns, tname);
244 tlonglnkmfc(int, int)
247 uchar nfn, space, expect;
251 for(i = 0; i < nfn; i++){
257 addr = tuple(addr, expect);
264 static char *funcids[] = {
282 print("Function %s\n",
283 (func >= nelem(funcids))? "unknown function": funcids[func]);
287 tvers1(int ttype, int len)
289 uchar c, major, minor;
294 if(readc(&major) != 1)
297 if(readc(&minor) != 1)
300 print("version %d.%d\n", major, minor);
302 for(i = 0; len > 0 && i < sizeof(string); i++){
303 if(readc(&string[i]) != 1)
312 print("\t%s<missing null>\n", string);
318 print("\t%s\n", string);
323 tcfig(int ttype, int len)
325 uchar size, rasize, rmsize;
332 if(readc(&size) != 1)
334 rasize = (size&0x3) + 1;
335 rmsize = ((size>>2)&0xf) + 1;
336 if(readc(&last) != 1)
338 caddr = getlong(rasize);
339 cregs = getlong(rmsize);
341 print("configuration registers at");
342 for(i = 0; i < 16; i++)
344 print(" (%d)0x%lux", i, caddr + i*2);
360 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
364 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90,
377 microv = vmant[(c>>3)&0xf]*exp;
383 break; /* high impedence when sleeping */
386 microv = 0; /* no connection */
390 microv += exp*(c&0x7f);
393 print(" V%s %lduV", name, microv);
404 amps = vexp[c&0x7]*vmant[(c>>3)&0xf];
408 if(c == 0x7d || c == 0x7e || c == 0x7f)
412 print(" I%s %ldmA", name, amps/100000);
413 else if(amps >= 1000)
414 print(" I%s %lduA", name, amps/100);
416 print(" I%s %ldnA", name, amps*10);
424 print("\t%s: ", name);
425 if(readc(&feature) != 1)
445 ttiming(char *name, int scale)
450 if(readc(&unscaled) != 1)
452 scaled = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
453 scaled = scaled * vexp[scale];
454 print("\t%s %ldns\n", name, scaled);
466 ttiming("max wait", i);
469 ttiming("max ready/busy wait", i);
472 ttiming("reserved wait", i);
476 range(int asize, int lsize)
480 address = getlong(asize);
481 len = getlong(lsize);
482 print("\t\t%lux - %lux\n", address, address+len);
489 " 8bit or 16bit access",
490 " selectable 8bit or 8&16bit access",
498 print("\tIO space %d address lines%s\n", c&0x1f, ioaccess[(c>>5)&3]);
505 for(i = (c&0xf)+1; i; i--)
506 range((c>>4)&0x3, (c>>6)&0x3);
530 if(readc(&irq1) != 1)
532 if(readc(&irq2) != 1)
534 irqs = irq1|(irq2<<8);
537 print("\tinterrupts%s%s%s", (c&0x20)?":level":"", (c&0x40)?":pulse":"",
538 (c&0x80)?":shared":"");
539 for(i = 0; i < 16; i++)
546 memspace(int asize, int lsize, int host)
548 ulong haddress, address, len;
550 len = getlong(lsize)*256;
551 address = getlong(asize)*256;
553 haddress = getlong(asize)*256;
554 print("\tmemory address range 0x%lux - 0x%lux hostaddr 0x%lux\n",
555 address, address+len, haddress);
557 print("\tmemory address range 0x%lux - 0x%lux\n", address, address+len);
566 tentry(int ttype, int len)
575 print("configuration %d%s\n", c&0x3f, (c&0x40)?" (default)":"");
579 tname = intrname[i & 0xf];
582 sprint(buf, "type %d", i & 0xf);
584 print("\t%s device, %s%s%s%s\n", tname,
585 (i&0x10)?" Battery status active":"",
586 (i&0x20)?" Write Protect active":"",
587 (i&0x40)?" Ready/Busy active":"",
588 (i&0x80)?" Memory Wait required":"");
590 if(readc(&feature) != 1)
612 switch((feature>>5)&0x3){
622 for(i = 0; i <= (c&0x7); i++)
623 memspace((c>>5)&0x3, (c>>3)&0x3, c&0x80);