pcidump.c
上传用户:wudi5211
上传日期:2010-01-21
资源大小:607k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

C/C++

  1. /*
  2.  * pcidump.c --  a tool to decode /proc/pcidata
  3.  *
  4.  * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
  5.  * Copyright (C) 2001 O'Reilly & Associates
  6.  *
  7.  * The source code in this file can be freely used, adapted,
  8.  * and redistributed in source or binary form, so long as an
  9.  * acknowledgment appears in derived source files.  The citation
  10.  * should list that the code comes from the book "Linux Device
  11.  * Drivers" by Alessandro Rubini and Jonathan Corbet, published
  12.  * by O'Reilly & Associates.   No warranty is attached;
  13.  * we cannot take responsibility for errors or fitness for use.
  14.  *
  15.  * $Id: pcidump.c,v 1.5 2001/07/18 22:28:16 rubini Exp $
  16.  */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <errno.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <linux/pci.h>
  26. #include <asm/page.h>
  27. #include <linux/version.h>
  28. /* A structure to declare how data is decoded */
  29. struct pcidump_info {
  30.     int offset; /* the data item to retrieve */
  31.     unsigned long bitmask;
  32.     int bool; /* true or false */
  33.     char *string;
  34. };
  35. #define ONEBYTE 0xFF
  36. #define TWOBYTES 0xFFFF
  37. #define FOURBYTES 0xFFFFFFFF
  38. struct pcidump_info dumpinfo[] = {
  39.     {0,                    0,                       0, "tCompulsory registers:n"},
  40.     {PCI_VENDOR_ID,        TWOBYTES,                0, "Vendor id: %04xn"},
  41.     {PCI_DEVICE_ID,        TWOBYTES,                0, "Device id: %04xn"},
  42.     {PCI_COMMAND,          PCI_COMMAND_IO,          1, "I/O space enabled: %cn"},
  43.     {PCI_COMMAND,          PCI_COMMAND_MEMORY,      1, "Memory enabled: %cn"},
  44.     {PCI_COMMAND,          PCI_COMMAND_MASTER,      1, "Master enabled: %cn"},
  45.     {PCI_COMMAND,          PCI_COMMAND_SPECIAL,     1, "Special command enabled: %cn"},
  46.     {PCI_COMMAND,          PCI_COMMAND_INVALIDATE,  1, "Write-invalidate enabled: %cn"},
  47.     {PCI_COMMAND,          PCI_COMMAND_VGA_PALETTE, 1, "Palette-snoop enabled: %cn"},
  48.     {PCI_COMMAND,          PCI_COMMAND_PARITY,      1, "Parity enabled: %cn"},
  49.     {PCI_COMMAND,          PCI_COMMAND_WAIT,        1, "Wait-cycle enabled: %cn"},
  50.     {PCI_COMMAND,          PCI_COMMAND_SERR,        1, "System-error enabled: %cn"},
  51.     {PCI_COMMAND,          PCI_COMMAND_FAST_BACK,   1, "Fast-back-to-back enabled: %cn"},
  52.     {PCI_STATUS,           PCI_STATUS_66MHZ,        1, "Can do 66MHz: %cn"},
  53.     {PCI_STATUS,           PCI_STATUS_UDF,          1, "Supports User Defined Features: %cn"},
  54.     {PCI_STATUS,           PCI_STATUS_FAST_BACK,    1, "Fast-back-to-back capable: %cn"},
  55.     {PCI_STATUS,           PCI_STATUS_PARITY,        1, "Data Parity Reported: %cn"},
  56.     {PCI_STATUS,           PCI_STATUS_DEVSEL_MASK,    0, "Device Select Timing bits are %xn"},
  57.     {PCI_STATUS,           PCI_STATUS_SIG_TARGET_ABORT,1, "Signalled abort as target: %cn"},
  58.     {PCI_STATUS,           PCI_STATUS_REC_TARGET_ABORT, 1, "Received abort from target: %cn"},
  59.     {PCI_STATUS,           PCI_STATUS_REC_MASTER_ABORT, 1, "Aborted transaction as master: %cn"},
  60.     {PCI_STATUS,           PCI_STATUS_SIG_SYSTEM_ERROR, 1, "Did send a system error: %cn"},
  61.     {PCI_STATUS,           PCI_STATUS_DETECTED_PARITY, 1, "Detected a parity error: %cn"},
  62.     {PCI_REVISION_ID,      ONEBYTE,                   0, "Revision id (decimal): %in"},
  63.     {PCI_CLASS_PROG,       ONEBYTE,                  0, "Programmer Interface: %02xn"},
  64.     {PCI_CLASS_DEVICE,     TWOBYTES,                0, "Class of device: %04xn"},
  65.     {PCI_HEADER_TYPE,      0x7f,                    0, "Header type: %02xn"},
  66.     {PCI_HEADER_TYPE,      0x80,                    1, "Multi function device: %cn"},
  67.     {0,                    0,                       0, "tOptional registers:n"},
  68.     {PCI_CACHE_LINE_SIZE,  ONEBYTE,                 0, "Cache line size (decimal): %in"},
  69.     {PCI_LATENCY_TIMER,    ONEBYTE,                 0, "Latency timer (decimal): %in"},
  70.     {PCI_BIST,             PCI_BIST_CAPABLE,        1, "Is Built-In-Self-Test available: %cn"},
  71.     {PCI_BIST,             PCI_BIST_CODE_MASK,      1, "Did Built-In-Self-Test fail: %cn"},
  72.     {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_MASK,  0, "Base Address 0: %08xn"},
  73.     {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE,      1, "Base Address 0 Is I/O: %cn"},
  74.     {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_TYPE_64, 1, "Base Address 0 is 64-bits: %cn"},
  75.     {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_TYPE_1M,  1, "Base Address 0 is below-1M: %cn"},
  76.     {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_PREFETCH, 1, "Base Address 0 is prefetchable: %cn"},
  77.     {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_MASK,     0, "Base Address 1: %08xn"},
  78.     {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_SPACE,        1, "Base Address 1 Is I/O: %cn"},
  79.     {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_TYPE_64,  1, "Base Address 1 is 64-bits: %cn"},
  80.     {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_TYPE_1M,  1, "Base Address 1 is below-1M: %cn"},
  81.     {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_PREFETCH, 1, "Base Address 1 is prefetchable: %cn"},
  82. #if 0
  83. #define PCI_BASE_ADDRESS_2      0x18    /* 32 bits */
  84. #define PCI_BASE_ADDRESS_3      0x1c    /* 32 bits */
  85. #define PCI_BASE_ADDRESS_4      0x20    /* 32 bits */
  86. #define PCI_BASE_ADDRESS_5      0x24    /* 32 bits */
  87. #define PCI_CARDBUS_CIS         0x28
  88. #endif
  89.     {PCI_SUBSYSTEM_ID,        TWOBYTES,                0, "Subsystem id: %04xn"},
  90.     {PCI_SUBSYSTEM_VENDOR_ID, TWOBYTES,                0, "Subsystem vendor: %04xn"},
  91.     {PCI_ROM_ADDRESS,         ~0x7FF,                  0, "Rom address: %08xn"},
  92.     {PCI_ROM_ADDRESS,         PCI_ROM_ADDRESS_ENABLE,  1, "Rom is enabled: %cn"},
  93.     {PCI_INTERRUPT_PIN,       ONEBYTE,                 1, "Does generate interrupts: %cn"},
  94.     {PCI_INTERRUPT_LINE,      ONEBYTE,                 0, "Interrupt line (decimal): %in"},
  95.     {PCI_INTERRUPT_PIN,       ONEBYTE,                 0, "Interrupt pin (decimal): %in"},
  96.     {PCI_MIN_GNT,             ONEBYTE,                 0, "Min bus grant time (decimal): %in"},
  97.     {PCI_MAX_LAT,             ONEBYTE,                 0, "Max bus latency acceptable (decimal): %in"},
  98.     {0x00,                 0,                       0, NULL}
  99. };
  100. unsigned char buffer[PAGE_SIZE];
  101. int main(int argc, char **argv)
  102. {
  103.     int fd, len;
  104.     char *fname="/proc/pcidata";
  105.     
  106.     unsigned char *curr, *end;
  107.     if (argc > 2 || (argc == 2 && argv[1][0] == '-')) { 
  108.         fprintf(stderr,"%s: Usage: "%s <filename>"n"
  109.                 "tfilename should embed binary pci configuration datan"
  110.                 "tif filename is missing, %s is usedn",
  111.                 argv[0], argv[0], fname);
  112.         exit(1);
  113.     }
  114.     if (argc>1) {
  115. fname = argv[1];
  116.     }
  117.     fd=open(fname, O_RDONLY);
  118.     if (fd<0) {
  119. fprintf(stderr,"%s: %s: %sn", argv[0], fname, strerror(errno));
  120. exit(1);
  121.     }
  122.     switch (len=read(fd,buffer,PAGE_SIZE)) {
  123.       case 0:
  124.         fprintf(stderr,"%s: %s: no datan", argv[0], fname);
  125.         exit(1);
  126.       case -1:
  127.         fprintf(stderr,"%s: %s: %sn", argv[0], fname, strerror(errno));
  128.         exit(1);
  129.       default: break;
  130.     }
  131.     if (len < 256) {
  132.         buffer[len]='';
  133.         fprintf(stderr," %s: %s: %sn", argv[0], fname, buffer);
  134.         exit(1);
  135.     }
  136.     if (len % 256) {
  137.         fprintf(stderr," %s: %s: incorrect data size: %in", 
  138. argv[0], fname, len);
  139.         exit(1);
  140.     }
  141.     for (end = buffer+len, curr = buffer; curr < end; curr += 256) {
  142.         struct pcidump_info *ptr;
  143.         unsigned int datum;
  144.         for (ptr = dumpinfo; ptr->string; ptr++) {
  145.             /*
  146.              * Perform a little-endian read of the item
  147.              */
  148.             datum = curr[ptr->offset]
  149.                 | (curr[ptr->offset+1]<<8)
  150.                     | (curr[ptr->offset+2]<<16)
  151.                         | (curr[ptr->offset+3]<<24);
  152.             datum &= ptr->bitmask;
  153.             printf(ptr->string, ptr->bool ? (datum ? 'y' : 'n') : datum);
  154.         }
  155.         printf("n");
  156.     }
  157.     return 0;
  158. }