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

📄 pciprobe.c

📁 Probe PCI devices, and compare information with standard file
💻 C
字号:
//***********************
//*     Description     *
//***********************
//This Program is a utility for probing PCI devices.
//It will display devices' vendor/subvendor ID, device/subdevice ID and version number.
//
//**********************************
//*        REVISON HISTORY         *
//**********************************
//MM.DD.YY    Rev   Who          Change Description
//11/03/2004  0.3   Warren.Sun   Initional Version
//11/02/2005  0.4   Yuanjie.Xu   Probe PCI device, and ignore onboard PCI slot
//11/04/2005  0.5   Yuanjie.Xu   Solve the compair bug and detail class name.
//01/10/2006  0.6   Yuanjie.Xu   In compare part, ignore Ven/Dev/SubVen/SubDev,
//                               for manufacture's requirement.
//23/05/2007  0.7   Jessie.Jing  Modify get_PCI()

#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mem.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <mem.h>
#include <conio.h>
#pragma inline

typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned long	DWORD;

int ignore_count=0;
DWORD ignore_bus[10];
DWORD ignore_dev[10];
DWORD ignore_func[10];

char filename[20];

struct PCI_Device_ID
{
	DWORD BUS;
	DWORD DEVICE;
	DWORD FUNCTION;
	DWORD VENDOR;
	DWORD DEV;
	DWORD SUBVEN;
	DWORD SUBDEV;
	DWORD VERSION;
	DWORD TYPE;
}PCI_ID[100];
int PCI_ID_count = 0;

struct File_Device_ID
{
	DWORD BUS;
	DWORD DEVICE;
	DWORD FUNCTION;
	DWORD VENDOR;
	DWORD DEV;
	DWORD SUBVEN;
	DWORD SUBDEV;
	DWORD VERSION;
	DWORD TYPE;
}File_ID[100];
int File_ID_count = 0;

struct Device_classes
{
	DWORD ID;
	char type[40];
};

static struct Device_classes classes[] = 
{
	{0x0100, "Storage_SCSI"},
	{0x0101, "Storage_IDE"},
	{0x0102, "Storage_Floppy"},
	{0x0103, "Storage_IPI"},
	{0x0104, "Storage_RAID"},
	{0x0105, "Storage_ATA"},
	{0x0106, "Storage_SATA"},
	{0x0107, "Storage_SAS"},
	{0x0180, "Storage_Other"},
	{0x0200, "Network_Ethernet"},
	{0x0201, "Network_Token_Ring"},
	{0x0202, "Network_FDDI"},
	{0x0203, "Network_ATM"},
	{0x0204, "Network_ISDN"},
	{0x0205, "Network_WorldFip"},
	{0x0206, "Network_PICMG"},
	{0x0280, "Network_Other"},
	{0x0300, "Display_VGA"},
	{0x0301, "Display_XGA"},
	{0x0302, "Display_3D"},
	{0x0380, "Display_Other"},
	{0x0400, "Multimedia_VIDEO"},
	{0x0401, "Multimedia_AUDIO"},
	{0x0402, "Multimedia_Phone"},
	{0x0480, "Multimedia_Other"},
	{0x0500, "Memory_RAM"},
	{0x0501, "Memory_Flash"},
	{0x0580, "Memory_Other"},
	{0x0600, "Bridge_Host"},
	{0x0601, "Bridge_ISA"},
	{0x0602, "Bridge_EISA"},
	{0x0603, "Bridge_MCA"},
	{0x0604, "Bridge_PCI"},
	{0x0605, "Bridge_PCMCIA"},
	{0x0606, "Bridge_NUBUS"},
	{0x0607, "Bridge_CARDBUS"},
	{0x0608, "Bridge_RACEWAY"},
	{0x0680, "Bridge_Other"},
	{0x0700, "Communication_Serial"},
	{0x0701, "Communication_Parallel"},
	{0x0702, "Communication_MultiSerial"},
	{0x0703, "Communication_Modem"},
	{0x0780, "Communication_Other"},
	{0x0800, "System_PIC"},
	{0x0801, "System_DMA"},
	{0x0802, "System_Timer"},
	{0x0803, "System_RTC"},
	{0x0804, "System_PCI_HotPlug"},
	{0x0805, "System_SD"},
	{0x0880, "System_Other"},
	{0x0900, "Input_Keyboard"},
	{0x0901, "Input_Pen"},
	{0x0902, "Input_Mouse"},
	{0x0903, "Input_Scanner"},
	{0x0904, "Input_GamePort"},
	{0x0980, "Input_Other"},
	{0x0a00, "Docking_Generic"},
	{0x0a80, "Docking_Other"},
	{0x0b00, "Processor_386"},
	{0x0b01, "Processor_486"},
	{0x0b02, "Processor_Pentium"},
	{0x0b10, "Processor_Alpha"},
	{0x0b20, "Processor_PowerPC"},
	{0x0b30, "Processor_MIPS"},
	{0x0b40, "Processor_Coprocessor"},
	{0x0c00, "Serial_IEEE1394"},
	{0x0c01, "Serial_Access"},
	{0x0c02, "Serial_SSA"},
	{0x0c03, "Serial_USB"},
	{0x0c04, "Serial_Fibre"},
	{0x0c05, "Serial_SMBUS"},
	{0x0c06, "Serial_InfiniBand"},
	{0x0c07, "Serial_IPMI"},
	{0x0c08, "Serial_SERCOS"},
	{0x0c09, "Serial_CANBUS"},
	{0x0d00, "Wireless"},
	{0x0e00, "Intelligent_I2C"},
	{0x0f00, "Satellite_TV"},
	{0x0f01, "Satellite_AUDIO"},
	{0x0f03, "Satellite_VOICE"},
	{0x0f04, "Satellite_Data"},
	{0x1000, "Crypt_Network"},
	{0x1001, "Crypt_Entertainment"},
	{0x1080, "Crypt_Other"},
	{0x1100, "Signal_Processing_DPIO"},
	{0x1180, "Signal_Processing_Other"},
	{0, "",}
};


DWORD read_dword_pci(DWORD bus,DWORD device,DWORD function,DWORD index);
void get_PCI(void);
void Build_Info_Table(void);
void get_Info_Table(void);
int Compare(void);
void Usage(void);

DWORD read_dword_pci(DWORD bus,DWORD device,DWORD function,DWORD index)
{
	DWORD value;
	unsigned long configuration;
	configuration = 0x80000000|(bus <<16) |(device << 11) | (function << 8) | (index << 2);
	asm{
	   .386
	   mov  dx, 0cf8h
	   mov  eax,configuration
	   out  dx, eax
	   mov  dx, 0cfch
	   in   eax, dx
	   mov  value,eax
	 };
	return value;
}

void display_devtype(DWORD index, FILE *handle)
{
	int loop = 0;
	while(classes[loop].ID != 0)
	{
		if(index == classes[loop].ID)
		{
			fprintf(handle, "%s\n", classes[loop].type);
			return;
		}
		loop++;
	}
	fprintf(handle, "ClassCode:%xh, Unknown Type\n", index);
}

void get_PCI()
{
	DWORD bus = 0, device = 0, function = 0;
	DWORD vendor = 0, dev = 0, subven = 0, subdev = 0, ver = 0, type = 0;

	for(bus = 0; bus < 256; bus++)
		for(device = 0; device < 32; device++)
			for(function = 0; function < 8; function++)
			{
				if((read_dword_pci(bus, device, function, 0) &0xFFFF) == 0xFFFF)
					continue;
				else
				{
					int j, ignore = 0;
					for (j = 0; j < ignore_count; j++)
					{
						if ((bus == ignore_bus[j]) && (device == ignore_dev[j]) && (function == ignore_func[j])) 
						{
							ignore = 1;
							break;
						}
					}
					if (ignore != 1)
					{
						PCI_ID[PCI_ID_count].BUS		= bus;
						PCI_ID[PCI_ID_count].DEVICE		= device;
						PCI_ID[PCI_ID_count].FUNCTION	= function;
						PCI_ID[PCI_ID_count].VENDOR		= (read_dword_pci(bus, device, function, 0) & 0xFFFF);
						PCI_ID[PCI_ID_count].DEV		= ((read_dword_pci(bus, device, function, 0x00) & 0xFFFF0000) >> 16) ;
						PCI_ID[PCI_ID_count].SUBVEN		= (read_dword_pci(bus, device, function, 11) & 0xFFFF);
						PCI_ID[PCI_ID_count].SUBDEV		= ((read_dword_pci(bus, device, function, 11) & 0xFFFF0000) >> 16);
						PCI_ID[PCI_ID_count].VERSION	= (read_dword_pci(bus, device, function, 2) & 0xFF);
						PCI_ID[PCI_ID_count].TYPE		= ((read_dword_pci(bus, device, function, 2) & 0xFFFF0000) >> 16);
						PCI_ID_count++;
					}
				}
			}
}

void Build_Info_Table()
{
	FILE *handle = NULL;
	int i = 0;

	handle = fopen(filename, "wt+");
	if(!handle)
	{
		printf("Can not open %s for write\n", filename);
		exit(-1);
	}
	fprintf(handle, "Bus:Dev.Func    Vendor	DevID   SubVen  SubDev  Rev     DevType\n");
	fprintf(handle, "===================================================================\n");

	get_PCI();
	for (i = 0; i < PCI_ID_count; i++)
	{
		fprintf(handle, "%x:", PCI_ID[i].BUS);
		fprintf(handle, "%2x.", PCI_ID[i].DEVICE);
		fprintf(handle, "%x\t\t", PCI_ID[i].FUNCTION);
		fprintf(handle, "%4xh\t", PCI_ID[i].VENDOR);
		fprintf(handle, "%4xh\t", PCI_ID[i].DEV);
		fprintf(handle, "%4xh\t", PCI_ID[i].SUBVEN);
		fprintf(handle, "%4xh\t", PCI_ID[i].SUBDEV);
		fprintf(handle, "%2xh\t", PCI_ID[i].VERSION);
		display_devtype(PCI_ID[i].TYPE, handle);
	}

	fclose(handle);
}

void get_Info_Table(void)
{
	FILE *handle;
	char buffer[80];

	handle = fopen(filename, "r");
	if(!handle)
	{
		printf("Can not open %s for read\n", filename);
		exit(-1);
	}

	fgets(buffer, sizeof(buffer), handle);
	fgets(buffer, sizeof(buffer), handle);

	while (fgets(buffer, sizeof(buffer), handle))
	{
		sscanf(buffer, "%x:%x.%x\t\t%xh\t%xh\t%xh\t%xh\t%xh\t", &File_ID[File_ID_count].BUS,
			&File_ID[File_ID_count].DEVICE, &File_ID[File_ID_count].FUNCTION,
			&File_ID[File_ID_count].VENDOR, &File_ID[File_ID_count].DEV,
			&File_ID[File_ID_count].SUBVEN, &File_ID[File_ID_count].SUBDEV,
			&File_ID[File_ID_count].VERSION);
		File_ID_count++;
	}
	fclose(handle);
}

int Compare(void)
{
	int i = 0;

	get_PCI();
	get_Info_Table();
	if (PCI_ID_count != File_ID_count)
	{
		printf("Probe PCI device and Compare with example file %s Failed\n", filename);
		printf("Count Fail. PCI_ID_count: %d, File_ID_count: %d\n", PCI_ID_count, File_ID_count);
		return 1;
	}
	else 
	{
		for(i = 0; i < PCI_ID_count; i++)
		{
			if((PCI_ID[i].BUS == File_ID[i].BUS) && (PCI_ID[i].DEVICE == File_ID[i].DEVICE) &&
			(PCI_ID[i].FUNCTION == File_ID[i].FUNCTION))
			{
			   continue;
			}
			else
			{
				printf("Probe PCI device and Compare with example file %s Failed\n", filename);
				return 1;
			}
		}
		printf("Probe PCI device and Compare with example file %s Passed\n", filename);
		return 0;
	}
}

void Usage(void)
{
	printf("Usage:\n");
	printf("w -- Probe PCI devices, and save the infomation to a target file.\n");
	printf("c -- Probe PCI devices, and compare information with standard file.\n");
	printf("h -- Display Help message\n");
}

int main(int argc,char **argv)
{
	int result = 0;
	FILE *fp;
	char buf[80];

	clrscr();
	printf("MiTAC Probe PCI Device Utility\n");
	printf("By: MiTAC Shanghai ESBU/SW2   V0.7   2007-05-23\n\n");

	if((argc == 1) || (argc > 3))
	{
		Usage();
		return 0;
	}

	if( (fp = fopen("ignore.cfg", "rt")) == NULL )
	{ 
	 	printf("You Lose ignore.cfg File !\n");
	   	exit(1);
	}

	while(fgets(buf, sizeof(buf), fp))
	{
		if (strstr(buf, "="))
		{
			sscanf(buf, "= %x %x %x", &ignore_bus[ignore_count], &ignore_dev[ignore_count], &ignore_func[ignore_count]);
			ignore_count++;
		}
	}
	fclose(fp);

	switch(*argv[1])
	{
	case 'W':
	case 'w':
		printf("PCI Device(s) found\n\n");
		strcpy(filename, argv[2]);
		Build_Info_Table();
		break;
	case 'C':
	case 'c':
		printf("\nPCI Device(s) found\n\n");
		strcpy(filename, argv[2]);
		result = Compare();
		break;
	case 'H':
	case 'h':
	default:
		Usage();
		break;
	}
	return result;
}

⌨️ 快捷键说明

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