1 /*======================================================================
3 PC Card CIS dump utility
5 dump_cis.c 1.63 2001/11/30 23:10:17
7 The contents of this file are subject to the Mozilla Public
8 License Version 2.0 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in
23 which case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
32 ======================================================================*/
34 #include <sys/types.h>
42 #include <sys/ioctl.h>
45 #include <pcmcia/cs_types.h>
46 #include <pcmcia/cs.h>
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/ds.h>
50 static int verbose = 0;
51 static char indent[10] = " ";
53 extern int parse_tuple(tuple_t *tup, cisparse_t *parse);
55 /*====================================================================*/
57 static void print_tuple(tuple_parse_t *tup)
60 printf("%soffset 0x%2.2x, tuple 0x%2.2x, link 0x%2.2x\n",
61 indent, tup->tuple.CISOffset, tup->tuple.TupleCode,
62 tup->tuple.TupleLink);
63 for (i = 0; i < tup->tuple.TupleDataLen; i++) {
64 if ((i % 16) == 0) printf("%s ", indent);
65 printf("%2.2x ", (u_char)tup->data[i]);
66 if ((i % 16) == 15) putchar('\n');
68 if ((i % 16) != 0) putchar('\n');
71 /*====================================================================*/
73 static void print_funcid(cistpl_funcid_t *fn)
75 printf("%sfuncid ", indent);
77 case CISTPL_FUNCID_MULTI:
78 printf("multi_function"); break;
79 case CISTPL_FUNCID_MEMORY:
80 printf("memory_card"); break;
81 case CISTPL_FUNCID_SERIAL:
82 printf("serial_port"); break;
83 case CISTPL_FUNCID_PARALLEL:
84 printf("parallel_port"); break;
85 case CISTPL_FUNCID_FIXED:
86 printf("fixed_disk"); break;
87 case CISTPL_FUNCID_VIDEO:
88 printf("video_adapter"); break;
89 case CISTPL_FUNCID_NETWORK:
90 printf("network_adapter"); break;
91 case CISTPL_FUNCID_AIMS:
92 printf("aims_card"); break;
93 case CISTPL_FUNCID_SCSI:
94 printf("scsi_adapter"); break;
96 printf("unknown"); break;
98 if (fn->sysinit & CISTPL_SYSINIT_POST)
100 if (fn->sysinit & CISTPL_SYSINIT_ROM)
105 /*====================================================================*/
107 static void print_size(u_int size)
111 else if (size < 1024*1024)
112 printf("%ukb", size/1024);
114 printf("%umb", size/(1024*1024));
117 static void print_unit(u_int v, char *unit, char tag)
120 for (n = 0; (v % 1000) == 0; n++) v /= 1000;
122 if (n < strlen(unit)) putchar(unit[n]);
126 static void print_time(u_int tm, u_long scale)
128 print_unit(tm * scale, "num", 's');
131 static void print_volt(u_int vi)
133 print_unit(vi * 10, "um", 'V');
136 static void print_current(u_int ii)
138 print_unit(ii / 10, "um", 'A');
141 static void print_speed(u_int b)
144 printf("%u bits/sec", b);
145 else if (b < 1000000)
146 printf("%u kb/sec", b/1000);
148 printf("%u mb/sec", b/1000000);
151 /*====================================================================*/
153 static const char *dtype[] = {
154 "NULL", "ROM", "OTPROM", "EPROM", "EEPROM", "FLASH", "SRAM",
155 "DRAM", "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", "fn_specific",
159 static void print_device(cistpl_device_t *dev)
162 for (i = 0; i < dev->ndev; i++) {
163 printf("%s %s ", indent, dtype[dev->dev[i].type]);
164 printf("%uns, ", dev->dev[i].speed);
165 print_size(dev->dev[i].size);
169 printf("%s no_info\n", indent);
172 /*====================================================================*/
174 static void print_power(char *tag, cistpl_power_t *power)
177 for (i = n = 0; i < 8; i++)
178 if (power->present & (1<<i)) n++;
180 printf("%s %s", indent, tag);
181 if (power->present & (1<<CISTPL_POWER_VNOM)) {
182 printf(" Vnom "); i++;
183 print_volt(power->param[CISTPL_POWER_VNOM]);
185 if (power->present & (1<<CISTPL_POWER_VMIN)) {
186 printf(" Vmin "); i++;
187 print_volt(power->param[CISTPL_POWER_VMIN]);
189 if (power->present & (1<<CISTPL_POWER_VMAX)) {
190 printf(" Vmax "); i++;
191 print_volt(power->param[CISTPL_POWER_VMAX]);
193 if (power->present & (1<<CISTPL_POWER_ISTATIC)) {
194 printf(" Istatic "); i++;
195 print_current(power->param[CISTPL_POWER_ISTATIC]);
197 if (power->present & (1<<CISTPL_POWER_IAVG)) {
198 if (++i == 5) printf("\n%s ", indent);
200 print_current(power->param[CISTPL_POWER_IAVG]);
202 if (power->present & (1<<CISTPL_POWER_IPEAK)) {
203 if (++i == 5) printf("\n%s ", indent);
205 print_current(power->param[CISTPL_POWER_IPEAK]);
207 if (power->present & (1<<CISTPL_POWER_IDOWN)) {
208 if (++i == 5) printf("\n%s ", indent);
210 print_current(power->param[CISTPL_POWER_IDOWN]);
212 if (power->flags & CISTPL_POWER_HIGHZ_OK) {
213 if (++i == 5) printf("\n%s ", indent);
214 printf(" [highz OK]");
216 if (power->flags & CISTPL_POWER_HIGHZ_REQ) {
222 /*====================================================================*/
224 static void print_cftable_entry(cistpl_cftable_entry_t *entry)
228 printf("%scftable_entry 0x%2.2x%s\n", indent, entry->index,
229 (entry->flags & CISTPL_CFTABLE_DEFAULT) ? " [default]" : "");
231 if (entry->flags & ~CISTPL_CFTABLE_DEFAULT) {
232 printf("%s ", indent);
233 if (entry->flags & CISTPL_CFTABLE_BVDS)
235 if (entry->flags & CISTPL_CFTABLE_WP)
237 if (entry->flags & CISTPL_CFTABLE_RDYBSY)
239 if (entry->flags & CISTPL_CFTABLE_MWAIT)
241 if (entry->flags & CISTPL_CFTABLE_AUDIO)
243 if (entry->flags & CISTPL_CFTABLE_READONLY)
244 printf(" [readonly]");
245 if (entry->flags & CISTPL_CFTABLE_PWRDOWN)
246 printf(" [pwrdown]");
250 if (entry->vcc.present)
251 print_power("Vcc", &entry->vcc);
252 if (entry->vpp1.present)
253 print_power("Vpp1", &entry->vpp1);
254 if (entry->vpp2.present)
255 print_power("Vpp2", &entry->vpp2);
257 if ((entry->timing.wait != 0) || (entry->timing.ready != 0) ||
258 (entry->timing.reserved != 0)) {
259 printf("%s timing", indent);
260 if (entry->timing.wait != 0) {
262 print_time(entry->timing.wait, entry->timing.waitscale);
264 if (entry->timing.ready != 0) {
266 print_time(entry->timing.ready, entry->timing.rdyscale);
268 if (entry->timing.reserved != 0) {
269 printf(" reserved ");
270 print_time(entry->timing.reserved, entry->timing.rsvscale);
275 if (entry->io.nwin) {
276 cistpl_io_t *io = &entry->io;
277 printf("%s io", indent);
278 for (i = 0; i < io->nwin; i++) {
280 printf(" 0x%4.4x-0x%4.4x", io->win[i].base,
281 io->win[i].base+io->win[i].len-1);
283 printf(" [lines=%d]", io->flags & CISTPL_IO_LINES_MASK);
284 if (io->flags & CISTPL_IO_8BIT) printf(" [8bit]");
285 if (io->flags & CISTPL_IO_16BIT) printf(" [16bit]");
286 if (io->flags & CISTPL_IO_RANGE) printf(" [range]");
290 if (entry->irq.IRQInfo1) {
291 printf("%s irq ", indent);
292 if (entry->irq.IRQInfo1 & IRQ_INFO2_VALID)
293 printf("mask 0x%04x", entry->irq.IRQInfo2);
295 printf("%u", entry->irq.IRQInfo1 & IRQ_MASK);
296 if (entry->irq.IRQInfo1 & IRQ_LEVEL_ID) printf(" [level]");
297 if (entry->irq.IRQInfo1 & IRQ_PULSE_ID) printf(" [pulse]");
298 if (entry->irq.IRQInfo1 & IRQ_SHARE_ID) printf(" [shared]");
302 if (entry->mem.nwin) {
303 cistpl_mem_t *mem = &entry->mem;
304 printf("%s memory", indent);
305 for (i = 0; i < mem->nwin; i++) {
307 printf(" 0x%4.4x-0x%4.4x @ 0x%4.4x", mem->win[i].card_addr,
308 mem->win[i].card_addr + mem->win[i].len-1,
309 mem->win[i].host_addr);
314 if (verbose && entry->subtuples)
315 printf("%s %d bytes in subtuples\n", indent, entry->subtuples);
319 /*====================================================================*/
321 static void print_cftable_entry_cb(cistpl_cftable_entry_cb_t *entry)
325 printf("%scftable_entry_cb 0x%2.2x%s\n", indent, entry->index,
326 (entry->flags & CISTPL_CFTABLE_DEFAULT) ? " [default]" : "");
328 if (entry->flags & ~CISTPL_CFTABLE_DEFAULT) {
329 printf("%s ", indent);
330 if (entry->flags & CISTPL_CFTABLE_MASTER)
332 if (entry->flags & CISTPL_CFTABLE_INVALIDATE)
333 printf(" [invalidate]");
334 if (entry->flags & CISTPL_CFTABLE_VGA_PALETTE)
335 printf(" [vga palette]");
336 if (entry->flags & CISTPL_CFTABLE_PARITY)
338 if (entry->flags & CISTPL_CFTABLE_WAIT)
340 if (entry->flags & CISTPL_CFTABLE_SERR)
342 if (entry->flags & CISTPL_CFTABLE_FAST_BACK)
343 printf(" [fast back]");
344 if (entry->flags & CISTPL_CFTABLE_BINARY_AUDIO)
345 printf(" [binary audio]");
346 if (entry->flags & CISTPL_CFTABLE_PWM_AUDIO)
347 printf(" [pwm audio]");
351 if (entry->vcc.present)
352 print_power("Vcc", &entry->vcc);
353 if (entry->vpp1.present)
354 print_power("Vpp1", &entry->vpp1);
355 if (entry->vpp2.present)
356 print_power("Vpp2", &entry->vpp2);
359 printf("%s io_base", indent);
360 for (i = 0; i < 8; i++)
361 if (entry->io & (1<<i)) printf(" %d", i);
365 if (entry->irq.IRQInfo1) {
366 printf("%s irq ", indent);
367 if (entry->irq.IRQInfo1 & IRQ_INFO2_VALID)
368 printf("mask 0x%4.4x", entry->irq.IRQInfo2);
370 printf("%u", entry->irq.IRQInfo1 & IRQ_MASK);
371 if (entry->irq.IRQInfo1 & IRQ_LEVEL_ID) printf(" [level]");
372 if (entry->irq.IRQInfo1 & IRQ_PULSE_ID) printf(" [pulse]");
373 if (entry->irq.IRQInfo1 & IRQ_SHARE_ID) printf(" [shared]");
378 printf("%s mem_base", indent);
379 for (i = 0; i < 8; i++)
380 if (entry->mem & (1<<i)) printf(" %d", i);
384 if (verbose && entry->subtuples)
385 printf("%s %d bytes in subtuples\n", indent, entry->subtuples);
389 /*====================================================================*/
391 static void print_jedec(cistpl_jedec_t *j)
394 for (i = 0; i < j->nid; i++) {
395 if (i != 0) putchar(',');
396 printf(" 0x%02x 0x%02x", j->id[i].mfr, j->id[i].info);
401 /*====================================================================*/
403 static void print_device_geo(cistpl_device_geo_t *geo)
406 for (i = 0; i < geo->ngeo; i++) {
407 printf("%s width %d erase 0x%x read 0x%x write 0x%x "
408 "partition 0x%x interleave 0x%x\n", indent,
409 geo->geo[i].buswidth, geo->geo[i].erase_block,
410 geo->geo[i].read_block, geo->geo[i].write_block,
411 geo->geo[i].partition, geo->geo[i].interleave);
415 /*====================================================================*/
417 static void print_org(cistpl_org_t *org)
419 printf("%sdata_org ", indent);
420 switch (org->data_org) {
422 printf("[filesystem]"); break;
423 case CISTPL_ORG_APPSPEC:
424 printf("[app_specific]"); break;
426 printf("[code]"); break;
428 if (org->data_org < 0x80)
429 printf("[reserved]");
431 printf("[vendor_specific]");
433 printf(", \"%s\"\n", org->desc);
436 /*====================================================================*/
438 static char *data_mod[] = {
439 "Bell103", "V.21", "V.23", "V.22", "Bell212A", "V.22bis",
440 "V.26", "V.26bis", "V.27bis", "V.29", "V.32", "V.32bis",
441 "V.34", "rfu", "rfu", "rfu"
443 static char *fax_mod[] = {
444 "V.21-C2", "V.27ter", "V.29", "V.17", "V.33", "rfu", "rfu", "rfu"
446 static char *fax_features[] = {
447 "T.3", "T.4", "T.6", "error", "voice", "poll", "file", "passwd"
449 static char *cmd_protocol[] = {
450 "AT1", "AT2", "AT3", "MNP_AT", "V.25bis", "V.25A", "DMCL"
452 static char *uart[] = {
453 "8250", "16450", "16550", "8251", "8530", "85230"
455 static char *parity[] = { "space", "mark", "odd", "even" };
456 static char *stop[] = { "1", "1.5", "2" };
457 static char *flow[] = {
458 "XON/XOFF xmit", "XON/XOFF rcv", "hw xmit", "hw rcv", "transparent"
460 static void print_serial(cistpl_funce_t *funce)
463 cistpl_data_serv_t *ds;
464 cistpl_fax_serv_t *fs;
465 cistpl_modem_cap_t *cp;
468 switch (funce->type & 0x0f) {
469 case CISTPL_FUNCE_SERIAL_IF:
470 case CISTPL_FUNCE_SERIAL_IF_DATA:
471 case CISTPL_FUNCE_SERIAL_IF_FAX:
472 case CISTPL_FUNCE_SERIAL_IF_VOICE:
473 s = (cistpl_serial_t *)(funce->data);
474 printf("%sserial_interface", indent);
475 if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_DATA)
477 else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_FAX)
479 else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_IF_VOICE)
481 printf("\n%s uart %s", indent,
482 (s->uart_type < 6) ? uart[s->uart_type] : "reserved");
485 for (i = 0; i < 4; i++)
486 if (s->uart_cap_0 & (1<<i))
487 printf("%s%s", parity[i],
488 (s->uart_cap_0 >= (2<<i)) ? "/" : "]");
491 int m = s->uart_cap_1 & 0x0f;
492 int n = s->uart_cap_1 >> 4;
494 for (i = 0; i < 4; i++)
496 printf("%d%s", i+5, (m >= (2<<i)) ? "/" : "");
498 for (i = 0; i < 3; i++)
500 printf("%s%s", stop[i], (n >= (2<<i)) ? "/" : "]");
504 case CISTPL_FUNCE_SERIAL_CAP:
505 case CISTPL_FUNCE_SERIAL_CAP_DATA:
506 case CISTPL_FUNCE_SERIAL_CAP_FAX:
507 case CISTPL_FUNCE_SERIAL_CAP_VOICE:
508 cp = (cistpl_modem_cap_t *)(funce->data);
509 printf("%sserial_modem_cap", indent);
510 if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_DATA)
512 else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_FAX)
514 else if ((funce->type & 0x0f) == CISTPL_FUNCE_SERIAL_CAP_VOICE)
517 printf("\n%s flow", indent);
518 for (i = 0; i < 5; i++)
519 if (cp->flow & (1<<i))
520 printf(" [%s]", flow[i]);
522 printf("\n%s cmd_buf %d rcv_buf %d xmit_buf %d\n",
523 indent, 4*(cp->cmd_buf+1),
524 cp->rcv_buf_0+(cp->rcv_buf_1<<8)+(cp->rcv_buf_2<<16),
525 cp->xmit_buf_0+(cp->xmit_buf_1<<8)+(cp->xmit_buf_2<<16));
527 case CISTPL_FUNCE_SERIAL_SERV_DATA:
528 ds = (cistpl_data_serv_t *)(funce->data);
529 printf("%sserial_data_services\n", indent);
530 printf("%s data_rate %d\n", indent,
531 75*((ds->max_data_0<<8) + ds->max_data_1));
532 printf("%s modulation", indent);
533 for (i = j = 0; i < 16; i++)
534 if (((ds->modulation_1<<8) + ds->modulation_0) & (1<<i)) {
536 printf("\n%s ", indent);
537 printf(" [%s]", data_mod[i]);
540 if (ds->error_control) {
541 printf("%s error_control", indent);
542 if (ds->error_control & CISTPL_SERIAL_ERR_MNP2_4)
544 if (ds->error_control & CISTPL_SERIAL_ERR_V42_LAPM)
545 printf(" [V.42/LAPM]");
548 if (ds->compression) {
549 printf("%s compression", indent);
550 if (ds->compression & CISTPL_SERIAL_CMPR_V42BIS)
551 printf(" [V.42bis]");
552 if (ds->compression & CISTPL_SERIAL_CMPR_MNP5)
556 if (ds->cmd_protocol) {
557 printf("%s cmd_protocol", indent);
558 for (i = 0; i < 7; i++)
559 if (ds->cmd_protocol & (1<<i))
560 printf(" [%s]", cmd_protocol[i]);
565 case CISTPL_FUNCE_SERIAL_SERV_FAX:
566 fs = (cistpl_fax_serv_t *)(funce->data);
567 printf("%sserial_fax_services [class=%d]\n",
568 indent, funce->type>>4);
569 printf("%s data_rate %d\n", indent,
570 75*((fs->max_data_0<<8) + fs->max_data_1));
571 printf("%s modulation", indent);
572 for (i = 0; i < 8; i++)
573 if (fs->modulation & (1<<i))
574 printf(" [%s]", fax_mod[i]);
576 if (fs->features_0) {
577 printf("%s features", indent);
578 for (i = 0; i < 8; i++)
579 if (fs->features_0 & (1<<i))
580 printf(" [%s]", fax_features[i]);
587 /*====================================================================*/
589 static void print_fixed(cistpl_funce_t *funce)
591 cistpl_ide_interface_t *i;
592 cistpl_ide_feature_t *f;
594 switch (funce->type) {
595 case CISTPL_FUNCE_IDE_IFACE:
596 i = (cistpl_ide_interface_t *)(funce->data);
597 printf("%sdisk_interface ", indent);
598 if (i->interface == CISTPL_IDE_INTERFACE)
601 printf("[undefined]\n");
603 case CISTPL_FUNCE_IDE_MASTER:
604 case CISTPL_FUNCE_IDE_SLAVE:
605 f = (cistpl_ide_feature_t *)(funce->data);
606 printf("%sdisk_features", indent);
607 if (f->feature1 & CISTPL_IDE_SILICON)
608 printf(" [silicon]");
610 printf(" [rotating]");
611 if (f->feature1 & CISTPL_IDE_UNIQUE)
613 if (f->feature1 & CISTPL_IDE_DUAL)
617 if (f->feature1 && f->feature2)
618 printf("\n%s ", indent);
619 if (f->feature2 & CISTPL_IDE_HAS_SLEEP)
621 if (f->feature2 & CISTPL_IDE_HAS_STANDBY)
622 printf(" [standby]");
623 if (f->feature2 & CISTPL_IDE_HAS_IDLE)
625 if (f->feature2 & CISTPL_IDE_LOW_POWER)
626 printf(" [low power]");
627 if (f->feature2 & CISTPL_IDE_REG_INHIBIT)
628 printf(" [reg inhibit]");
629 if (f->feature2 & CISTPL_IDE_HAS_INDEX)
631 if (f->feature2 & CISTPL_IDE_IOIS16)
638 /*====================================================================*/
640 static const char *tech[] = {
641 "undefined", "ARCnet", "ethernet", "token_ring", "localtalk",
642 "FDDI/CDDI", "ATM", "wireless"
645 static const char *media[] = {
646 "undefined", "unshielded_twisted_pair", "shielded_twisted_pair",
647 "thin_coax", "thick_coax", "fiber", "900_MHz", "2.4_GHz",
648 "5.4_GHz", "diffuse_infrared", "point_to_point_infrared"
651 static void print_network(cistpl_funce_t *funce)
653 cistpl_lan_tech_t *t;
654 cistpl_lan_speed_t *s;
655 cistpl_lan_media_t *m;
656 cistpl_lan_node_id_t *n;
657 cistpl_lan_connector_t *c;
660 switch (funce->type) {
661 case CISTPL_FUNCE_LAN_TECH:
662 t = (cistpl_lan_tech_t *)(funce->data);
663 printf("%slan_technology %s\n", indent, tech[t->tech]);
665 case CISTPL_FUNCE_LAN_SPEED:
666 s = (cistpl_lan_speed_t *)(funce->data);
667 printf("%slan_speed ", indent);
668 print_speed(s->speed);
671 case CISTPL_FUNCE_LAN_MEDIA:
672 m = (cistpl_lan_media_t *)(funce->data);
673 printf("%slan_media %s\n", indent, media[m->media]);
675 case CISTPL_FUNCE_LAN_NODE_ID:
676 n = (cistpl_lan_node_id_t *)(funce->data);
677 printf("%slan_node_id", indent);
678 for (i = 0; i < n->nb; i++)
679 printf(" %02x", n->id[i]);
682 case CISTPL_FUNCE_LAN_CONNECTOR:
683 c = (cistpl_lan_connector_t *)(funce->data);
684 printf("%slan_connector ", indent);
686 printf("Open connector standard\n");
688 printf("Closed connector standard\n");
693 /*====================================================================*/
695 static void print_vers_1(cistpl_vers_1_t *v1)
699 sprintf(s, "%svers_1 %d.%d", indent, v1->major, v1->minor);
702 for (i = 0; i < v1->ns; i++) {
703 if (n + strlen(v1->str + v1->ofs[i]) + 4 > 72) {
704 n = strlen(indent) + 2;
705 printf(",\n%s ", indent);
710 printf("\"%s\"", v1->str + v1->ofs[i]);
711 n += strlen(v1->str + v1->ofs[i]) + 2;
716 /*====================================================================*/
718 static void print_vers_2(cistpl_vers_2_t *v2)
720 printf("%sversion 0x%2.2x, compliance 0x%2.2x, dindex 0x%4.4x\n",
721 indent, v2->vers, v2->comply, v2->dindex);
722 printf("%s vspec8 0x%2.2x, vspec9 0x%2.2x, nhdr %d\n",
723 indent, v2->vspec8, v2->vspec9, v2->nhdr);
724 printf("%s vendor \"%s\"\n", indent, v2->str+v2->vendor);
725 printf("%s info \"%s\"\n", indent, v2->str+v2->info);
728 /*====================================================================*/
730 #ifdef CISTPL_FORMAT_DISK
731 static void print_format(cistpl_format_t *fmt)
733 if (fmt->type == CISTPL_FORMAT_DISK)
734 printf("%s [disk]", indent);
735 else if (fmt->type == CISTPL_FORMAT_MEM)
736 printf("%s [memory]", indent);
738 printf("%s [type 0x%02x]\n", indent, fmt->type);
739 if (fmt->edc == CISTPL_EDC_NONE)
741 else if (fmt->edc == CISTPL_EDC_CKSUM)
743 else if (fmt->edc == CISTPL_EDC_CRC)
745 else if (fmt->edc == CISTPL_EDC_PCC)
748 printf(" [edc 0x%02x]", fmt->edc);
749 printf(" offset 0x%04x length ", fmt->offset);
750 print_size(fmt->length);
755 /*====================================================================*/
757 static void print_config(int code, cistpl_config_t *cfg)
759 printf("%sconfig%s base 0x%4.4x", indent,
760 (code == CISTPL_CONFIG_CB) ? "_cb" : "",
762 if (code == CISTPL_CONFIG)
763 printf(" mask 0x%4.4x", cfg->rmask[0]);
764 printf(" last_index 0x%2.2x\n", cfg->last_idx);
765 if (verbose && cfg->subtuples)
766 printf("%s %d bytes in subtuples\n", indent, cfg->subtuples);
769 /*====================================================================*/
771 static int nfn = 0, cur = 0;
773 static void print_parse(tuple_parse_t *tup)
778 switch (tup->tuple.TupleCode) {
780 case CISTPL_DEVICE_A:
781 if (tup->tuple.TupleCode == CISTPL_DEVICE)
782 printf("%sdev_info\n", indent);
784 printf("%sattr_dev_info\n", indent);
785 print_device(&tup->parse.device);
787 case CISTPL_CHECKSUM:
788 printf("%schecksum 0x%04x-0x%04x = 0x%02x\n",
789 indent, tup->parse.checksum.addr,
790 tup->parse.checksum.addr+tup->parse.checksum.len-1,
791 tup->parse.checksum.sum);
793 case CISTPL_LONGLINK_A:
795 printf("%slong_link_attr 0x%04x\n", indent,
796 tup->parse.longlink.addr);
798 case CISTPL_LONGLINK_C:
800 printf("%slong_link 0x%04x\n", indent,
801 tup->parse.longlink.addr);
803 case CISTPL_LONGLINK_MFC:
805 printf("%smfc_long_link\n", indent);
806 for (i = 0; i < tup->parse.longlink_mfc.nfn; i++)
807 printf("%s function %d: %s 0x%04x\n", indent, i,
808 tup->parse.longlink_mfc.fn[i].space ? "common" : "attr",
809 tup->parse.longlink_mfc.fn[i].addr);
811 printf("%smfc {\n", indent);
812 nfn = tup->parse.longlink_mfc.nfn;
819 printf("%sno_long_link\n", indent);
821 #ifdef CISTPL_INDIRECT
822 case CISTPL_INDIRECT:
824 printf("%sindirect_access\n", indent);
827 case CISTPL_LINKTARGET:
829 printf("%slink_target\n", indent);
831 if (cur++) printf("%s}, {\n", indent+2);
835 print_vers_1(&tup->parse.version_1);
841 if (tup->tuple.TupleCode == CISTPL_JEDEC_C)
842 printf("%scommon_jedec", indent);
844 printf("%sattr_jedec", indent);
845 print_jedec(&tup->parse.jedec);
847 case CISTPL_DEVICE_GEO:
848 case CISTPL_DEVICE_GEO_A:
849 if (tup->tuple.TupleCode == CISTPL_DEVICE_GEO)
850 printf("%scommon_geometry\n", indent);
852 printf("%sattr_geometry\n", indent);
853 print_device_geo(&tup->parse.device_geo);
856 printf("%smanfid 0x%4.4x, 0x%4.4x\n", indent,
857 tup->parse.manfid.manf, tup->parse.manfid.card);
860 print_funcid(&tup->parse.funcid);
861 func = tup->parse.funcid.func;
865 case CISTPL_FUNCID_SERIAL:
866 print_serial(&tup->parse.funce);
868 case CISTPL_FUNCID_FIXED:
869 print_fixed(&tup->parse.funce);
871 case CISTPL_FUNCID_NETWORK:
872 print_network(&tup->parse.funce);
877 printf("%sBAR %d size ", indent,
878 tup->parse.bar.attr & CISTPL_BAR_SPACE);
879 print_size(tup->parse.bar.size);
880 if (tup->parse.bar.attr & CISTPL_BAR_SPACE_IO)
884 if (tup->parse.bar.attr & CISTPL_BAR_PREFETCH)
885 printf(" [prefetch]");
886 if (tup->parse.bar.attr & CISTPL_BAR_CACHEABLE)
887 printf(" [cacheable]");
888 if (tup->parse.bar.attr & CISTPL_BAR_1MEG_MAP)
893 case CISTPL_CONFIG_CB:
894 print_config(tup->tuple.TupleCode, &tup->parse.config);
896 case CISTPL_CFTABLE_ENTRY:
897 print_cftable_entry(&tup->parse.cftable_entry);
899 case CISTPL_CFTABLE_ENTRY_CB:
900 print_cftable_entry_cb(&tup->parse.cftable_entry_cb);
903 print_vers_2(&tup->parse.vers_2);
906 print_org(&tup->parse.org);
908 #ifdef CISTPL_FORMAT_DISK
910 case CISTPL_FORMAT_A:
911 if (tup->tuple.TupleCode == CISTPL_FORMAT)
912 printf("%scommon_format\n", indent);
914 printf("%sattr_format\n", indent);
915 print_format(&tup->parse.format);
920 /*====================================================================*/
922 static int get_tuple_buf(int fd, ds_ioctl_arg_t *arg, int first)
926 static u_char buf[1024];
929 nb = read(fd, buf, sizeof(buf));
930 arg->tuple.TupleLink = arg->tuple.CISOffset = 0;
932 ofs = arg->tuple.CISOffset + arg->tuple.TupleLink;
933 if (nb < 0 || ofs >= (u_int)nb)
935 arg->tuple.TupleCode = buf[ofs++];
936 arg->tuple.TupleDataLen = arg->tuple.TupleLink = buf[ofs++];
937 arg->tuple.CISOffset = ofs;
938 memcpy(arg->tuple_parse.data, buf+ofs, arg->tuple.TupleLink);
942 /*====================================================================*/
944 int main(int argc, char *argv[])
948 int optch, errflg, first;
952 while ((optch = getopt(argc, argv, "fvi:")) != -1) {
957 infile = strdup(optarg); break;
962 if (errflg || !infile || (optind < argc)) {
963 fprintf(stderr, "usage: %s [-v] -i infile\n", argv[0]);
969 fd = open(infile, O_RDONLY);
975 arg.tuple.TupleDataMax = sizeof(arg.tuple_parse.data);
976 arg.tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
977 arg.tuple.DesiredTuple = RETURN_FIRST_TUPLE;
978 arg.tuple.TupleOffset = 0;
979 arg.tuple.TupleData = arg.tuple_parse.data;
981 for (first = 1; ; first = 0) {
982 if (get_tuple_buf(fd, &arg, first) != 0) break;
983 if (verbose) print_tuple(&arg.tuple_parse);
984 if (arg.tuple.TupleCode == CISTPL_END)
986 if (parse_tuple(&arg.tuple_parse.tuple, &arg.tuple_parse.parse) == 0)
987 print_parse(&arg.tuple_parse);
989 printf("%sparse error\n", indent);
990 if (verbose) putchar('\n');
993 if (!verbose && (nfn > 0))
994 printf("%s}\n", indent+2);