⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcidump.c

📁 本源码是将述嵌入式LINUX驱动程序例程
💻 C
字号:
/*
 * pcidump.c --  a tool to decode /proc/pcidata
 *
 * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
 * Copyright (C) 2001 O'Reilly & Associates
 *
 * The source code in this file can be freely used, adapted,
 * and redistributed in source or binary form, so long as an
 * acknowledgment appears in derived source files.  The citation
 * should list that the code comes from the book "Linux Device
 * Drivers" by Alessandro Rubini and Jonathan Corbet, published
 * by O'Reilly & Associates.   No warranty is attached;
 * we cannot take responsibility for errors or fitness for use.
 *
 * $Id: pcidump.c,v 1.5 2001/07/18 22:28:16 rubini Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <linux/pci.h>
#include <asm/page.h>

#include <linux/version.h>

/* A structure to declare how data is decoded */
struct pcidump_info {
    int offset; /* the data item to retrieve */
    unsigned long bitmask;
    int bool; /* true or false */
    char *string;
};

#define ONEBYTE 0xFF
#define TWOBYTES 0xFFFF
#define FOURBYTES 0xFFFFFFFF

struct pcidump_info dumpinfo[] = {
    {0,                    0,                       0, "\tCompulsory registers:\n"},
    {PCI_VENDOR_ID,        TWOBYTES,                0, "Vendor id: %04x\n"},
    {PCI_DEVICE_ID,        TWOBYTES,                0, "Device id: %04x\n"},
    {PCI_COMMAND,          PCI_COMMAND_IO,          1, "I/O space enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_MEMORY,      1, "Memory enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_MASTER,      1, "Master enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_SPECIAL,     1, "Special command enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_INVALIDATE,  1, "Write-invalidate enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_VGA_PALETTE, 1, "Palette-snoop enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_PARITY,      1, "Parity enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_WAIT,        1, "Wait-cycle enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_SERR,        1, "System-error enabled: %c\n"},
    {PCI_COMMAND,          PCI_COMMAND_FAST_BACK,   1, "Fast-back-to-back enabled: %c\n"},
    {PCI_STATUS,           PCI_STATUS_66MHZ,        1, "Can do 66MHz: %c\n"},
    {PCI_STATUS,           PCI_STATUS_UDF,          1, "Supports User Defined Features: %c\n"},
    {PCI_STATUS,           PCI_STATUS_FAST_BACK,    1, "Fast-back-to-back capable: %c\n"},
    {PCI_STATUS,           PCI_STATUS_PARITY,        1, "Data Parity Reported: %c\n"},
    {PCI_STATUS,           PCI_STATUS_DEVSEL_MASK,    0, "Device Select Timing bits are %x\n"},
    {PCI_STATUS,           PCI_STATUS_SIG_TARGET_ABORT,1, "Signalled abort as target: %c\n"},
    {PCI_STATUS,           PCI_STATUS_REC_TARGET_ABORT, 1, "Received abort from target: %c\n"},
    {PCI_STATUS,           PCI_STATUS_REC_MASTER_ABORT, 1, "Aborted transaction as master: %c\n"},
    {PCI_STATUS,           PCI_STATUS_SIG_SYSTEM_ERROR, 1, "Did send a system error: %c\n"},
    {PCI_STATUS,           PCI_STATUS_DETECTED_PARITY, 1, "Detected a parity error: %c\n"},
    {PCI_REVISION_ID,      ONEBYTE,                   0, "Revision id (decimal): %i\n"},
    {PCI_CLASS_PROG,       ONEBYTE,                  0, "Programmer Interface: %02x\n"},
    {PCI_CLASS_DEVICE,     TWOBYTES,                0, "Class of device: %04x\n"},
    {PCI_HEADER_TYPE,      0x7f,                    0, "Header type: %02x\n"},
    {PCI_HEADER_TYPE,      0x80,                    1, "Multi function device: %c\n"},
    {0,                    0,                       0, "\tOptional registers:\n"},
    {PCI_CACHE_LINE_SIZE,  ONEBYTE,                 0, "Cache line size (decimal): %i\n"},
    {PCI_LATENCY_TIMER,    ONEBYTE,                 0, "Latency timer (decimal): %i\n"},
    {PCI_BIST,             PCI_BIST_CAPABLE,        1, "Is Built-In-Self-Test available: %c\n"},
    {PCI_BIST,             PCI_BIST_CODE_MASK,      1, "Did Built-In-Self-Test fail: %c\n"},
    {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_MASK,  0, "Base Address 0: %08x\n"},
    {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE,      1, "Base Address 0 Is I/O: %c\n"},
    {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_TYPE_64, 1, "Base Address 0 is 64-bits: %c\n"},
    {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_TYPE_1M,  1, "Base Address 0 is below-1M: %c\n"},
    {PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_MEM_PREFETCH, 1, "Base Address 0 is prefetchable: %c\n"},
    {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_MASK,     0, "Base Address 1: %08x\n"},
    {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_SPACE,        1, "Base Address 1 Is I/O: %c\n"},
    {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_TYPE_64,  1, "Base Address 1 is 64-bits: %c\n"},
    {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_TYPE_1M,  1, "Base Address 1 is below-1M: %c\n"},
    {PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_MEM_PREFETCH, 1, "Base Address 1 is prefetchable: %c\n"},

#if 0
#define PCI_BASE_ADDRESS_2      0x18    /* 32 bits */
#define PCI_BASE_ADDRESS_3      0x1c    /* 32 bits */
#define PCI_BASE_ADDRESS_4      0x20    /* 32 bits */
#define PCI_BASE_ADDRESS_5      0x24    /* 32 bits */
#define PCI_CARDBUS_CIS         0x28
#endif

    {PCI_SUBSYSTEM_ID,        TWOBYTES,                0, "Subsystem id: %04x\n"},
    {PCI_SUBSYSTEM_VENDOR_ID, TWOBYTES,                0, "Subsystem vendor: %04x\n"},
    {PCI_ROM_ADDRESS,         ~0x7FF,                  0, "Rom address: %08x\n"},
    {PCI_ROM_ADDRESS,         PCI_ROM_ADDRESS_ENABLE,  1, "Rom is enabled: %c\n"},
    {PCI_INTERRUPT_PIN,       ONEBYTE,                 1, "Does generate interrupts: %c\n"},
    {PCI_INTERRUPT_LINE,      ONEBYTE,                 0, "Interrupt line (decimal): %i\n"},
    {PCI_INTERRUPT_PIN,       ONEBYTE,                 0, "Interrupt pin (decimal): %i\n"},
    {PCI_MIN_GNT,             ONEBYTE,                 0, "Min bus grant time (decimal): %i\n"},
    {PCI_MAX_LAT,             ONEBYTE,                 0, "Max bus latency acceptable (decimal): %i\n"},

    {0x00,                 0,                       0, NULL}
};



unsigned char buffer[PAGE_SIZE];

int main(int argc, char **argv)
{
    int fd, len;
    char *fname="/proc/pcidata";
    
    unsigned char *curr, *end;

    if (argc > 2 || (argc == 2 && argv[1][0] == '-')) { 
        fprintf(stderr,"%s: Usage: \"%s <filename>\"\n"
                "\tfilename should embed binary pci configuration data\n"
                "\tif filename is missing, %s is used\n",
                argv[0], argv[0], fname);
        exit(1);
    }
    if (argc>1) {
	fname = argv[1];
    }
    fd=open(fname, O_RDONLY);
    if (fd<0) {
	fprintf(stderr,"%s: %s: %s\n", argv[0], fname, strerror(errno));
	exit(1);
    }

    switch (len=read(fd,buffer,PAGE_SIZE)) {
      case 0:
        fprintf(stderr,"%s: %s: no data\n", argv[0], fname);
        exit(1);
      case -1:
        fprintf(stderr,"%s: %s: %s\n", argv[0], fname, strerror(errno));
        exit(1);
      default: break;
    }
    if (len < 256) {
        buffer[len]='\0';
        fprintf(stderr," %s: %s: %s\n", argv[0], fname, buffer);
        exit(1);
    }
    if (len % 256) {
        fprintf(stderr," %s: %s: incorrect data size: %i\n", 
		argv[0], fname, len);
        exit(1);
    }

    for (end = buffer+len, curr = buffer; curr < end; curr += 256) {
        struct pcidump_info *ptr;
        unsigned int datum;

        for (ptr = dumpinfo; ptr->string; ptr++) {
            /*
             * Perform a little-endian read of the item
             */
            datum = curr[ptr->offset]
                | (curr[ptr->offset+1]<<8)
                    | (curr[ptr->offset+2]<<16)
                        | (curr[ptr->offset+3]<<24);
            datum &= ptr->bitmask;
            printf(ptr->string, ptr->bool ? (datum ? 'y' : 'n') : datum);
        }
        printf("\n");
    }
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -