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

📄 pcifixup.c

📁 PCI总线在DOS操作系统下的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>

#include "typedef.h"
#include "low.h"
#include "list.h"
#include "pci.h"

void pci_fixup_i450nx(struct pci_dev far * d)
{
	/*
	 * i450NX -- Find and scan all secondary buses on all PXB's.
	 */
	long pxb, reg;
	u8 busno, suba, subb;

	#ifdef DEBUG_VERSION
		safe_printf("PCI: Searching for i450NX host bridges on %s\n", d->slot_name);
	#endif			
	reg = 0xd0;
	for(pxb=0; pxb<2; pxb++) 
	{
		pci_read_config_byte(d, reg++, &busno);
		pci_read_config_byte(d, reg++, &suba);
		pci_read_config_byte(d, reg++, &subb);

		#ifdef DEBUG_VERSION
			safe_printf("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
		#endif

		if (busno)
			pci_scan_bus(busno, pci_root_ops, NULL);	/* Bus A */
		if (suba < subb)
			pci_scan_bus(suba+1, pci_root_ops, NULL);	/* Bus B */
	}

	pcibios_last_bus = -1;
}

void pci_fixup_i450gx(struct pci_dev far *d)
{
	/*
	 * i450GX and i450KX -- Find and scan all secondary buses.
	 * (called separately for each PCI bridge found)
	 */
	u8 busno;
	pci_read_config_byte(d, 0x4a, &busno);

	#ifdef DEBUG_VERSION
		safe_printf("PCI: i440KX/GX host bridge %s: secondary bus %02x\n",
			d->slot_name,busno);
	#endif
	pci_scan_bus(busno, pci_root_ops, NULL);
	pcibios_last_bus = -1;
}

#if 0
/* Until we get proper handling pray the BIOS gets it right */
/*
 * ServerWorks host bridges -- Find and scan all secondary buses.
 * Register 0x44 contains first, 0x45 last bus number routed there.
 */
void pci_fixup_serverworks(struct pci_dev far * d)
{
	u8 busno1, busno2;

	pci_read_config_byte(d, 0x44, &busno1);
	pci_read_config_byte(d, 0x45, &busno2);
	if (busno2 < busno1)
		busno2 = busno1;
	if (busno2 > pcibios_last_bus) 
	{
		pcibios_last_bus = busno2;

		#ifdef DEBUG_VERSION
			safe_printf("PCI: ServerWorks host bridge: last bus %02x\n", pcibios_last_bus);
		#endif
	}
}
#endif

#if 1
/* Our bus code shouldnt need this fixup any more. Delete once verified */
/*	
 * Compaq host bridges -- Find and scan all secondary buses.
 * This time registers 0xc8 and 0xc9.
 */
void pci_fixup_compaq(struct pci_dev far *d)
{
	u8 busno1, busno2;

	pci_read_config_byte(d, 0xc8, &busno1);
	pci_read_config_byte(d, 0xc9, &busno2);
	if (busno2 < busno1)
		busno2 = busno1;
	if (busno2 > pcibios_last_bus) 
	{
		pcibios_last_bus = busno2;

		#ifdef DEBUG_VERSION
			safe_printf("PCI: Compaq host bridge: last bus %02x\n", busno2);
		#endif
	}
}
#endif	

void pci_fixup_umc_ide(struct pci_dev far * d)
{
	/*
	 * UM8886BF IDE controller sets region type bits incorrectly,
	 * therefore they look like memory despite of them being I/O.
	 */
	int i;

	safe_printf("PCI: Fixing base address flags for device %s\n", d->slot_name);
	for(i=0; i<4; i++)
		d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
}

void pci_fixup_ide_bases(struct pci_dev far * d)
{
	int i;

	/*
	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
	 */
	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
		return;

	#ifdef DEBUG_VERSION
		safe_printf("PCI: IDE base address fixup for %s\n", d->slot_name);
	#endif

	for(i=0; i<4; i++) 
	{
		struct resource *r = &d->resource[i];
		if ((r->start & ~0x80) == 0x374) 
		{
			r->start |= 2;
			r->end = r->start;
		}
	}
}

void pci_fixup_ide_trash(struct pci_dev far *d)
{
	int i;

	/*
	 * There exist PCI IDE controllers which have utter garbage
	 * in first four base registers. Ignore that.
	 */
	#ifdef DEBUG_VERSION
		safe_printf("PCI: IDE base address trash cleared for %s\n", d->slot_name);
	#endif

	for(i=0; i<4; i++)
	{
		d->resource[i].start = d->resource[i].end =
		       d->resource[i].flags = 0;
	}
}

void pci_fixup_latency(struct pci_dev far * d)
{
	/*
	 *  SiS 5597 and 5598 chipsets require latency timer set to
	 *  at most 32 to avoid lockups.
	 */
	#ifdef DEBUG_VERSION
		safe_printf("PCI: Setting max latency to 32\n");
	#endif
	pcibios_max_latency = 32;
}

void pci_fixup_piix4_acpi(struct pci_dev far * d)
{
	/*
	 * PIIX4 ACPI device: hardwired IRQ9
	 */
	d->irq = 9;
}

/*
 * Nobody seems to know what this does. Damn.
 *
 * But it does seem to fix some unspecified problem
 * with 'movntq' copies on Athlons.
 *
 * VIA 8363 chipset:
 *  - bit 7 at offset 0x55: Debug (RW)
 */
void pci_fixup_via_athlon_bug(struct pci_dev far * d)
{
	u8 v;

	pci_read_config_byte(d, 0x55, &v);
	if (v & 0x80) 
	{
		#ifdef DEBUG_VERSION
			safe_printf("Trying to stomp on Athlon bug...\n");
		#endif
		v &= 0x7f; /* clear bit 55.7 */
		pci_write_config_byte(d, 0x55, v);
	}
}


extern struct pci_fixup pcibios_fixups[];

void quirk_passive_release(struct pci_dev far * dev)
{
	struct pci_dev far * d = NULL;
	unsigned char dlc;

	/* We have to make sure a particular bit is set in the PIIX3
	   ISA bridge, so we have to go out and find it. */
	while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) 
	{
		pci_read_config_byte(d, 0x82, &dlc);
		if (!(dlc & 1<<1)) 
		{
			#ifdef DEBUG_VERSION
				safe_printf("PCI: PIIX3: Enabling Passive Release on %s\n", d->slot_name);
			#endif

			dlc |= 1<<1;
			pci_write_config_byte(d, 0x82, dlc);
		}
	}
}

/*  The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
    but VIA don't answer queries. If you happen to have good contacts at VIA
    ask them for me please -- Alan 
    
    This appears to be BIOS not version dependent. So presumably there is a 
    chipset level fix */
    

extern long isa_dma_bridge_buggy;		/* Exported */
extern long pci_pci_problems;

void quirk_isa_dma_hangs(struct pci_dev far * dev)
{
	if (!isa_dma_bridge_buggy) 
	{
		isa_dma_bridge_buggy=1;

		#ifdef DEBUG_VERSION
			safe_printf("Activating ISA DMA hang workarounds.\n");
		#endif
	}
}

/*
 *	Chipsets where PCI->PCI transfers vanish or hang
 */

void quirk_nopcipci(struct pci_dev far * dev)
{
	if((pci_pci_problems & PCIPCI_FAIL) == 0)
	{
		#ifdef DEBUG_VERSION
			safe_printf("Disabling direct PCI/PCI transfers.\n");
		#endif
		pci_pci_problems |= PCIPCI_FAIL;
	}
}

/*
 *	Triton requires workarounds to be used by the drivers
 */
 
void quirk_triton(struct pci_dev far * dev)
{
	if((pci_pci_problems & PCIPCI_TRITON) == 0)
	{
		#ifdef DEBUG_VERSION
			safe_printf("Limiting direct PCI/PCI transfers.\n");
		#endif
		pci_pci_problems |= PCIPCI_TRITON;
	}
}

/*
 *	VIA Apollo KT133 needs PCI latency patch
 *	Made according to a windows driver based patch by George E. Breese
 *	see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm
 *      Also see http://home.tiscalinet.de/au-ja/review-kt133a-1-en.html for
 *      the info on which Mr Breese based his work.
 *
 *	Updated based on further information from the site and also on
 *	information provided by VIA 
 */
void quirk_vialatency(struct pci_dev far * dev)
{
	struct pci_dev far * p;
	u8 rev;
	u8 busarb;
	/* Ok we have a potential problem chipset here. Now see if we have
	   a buggy southbridge */
	   
	p=	pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
	if(p != NULL)
	{
		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
		/* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */
		/* Check for buggy part revisions */
		if (rev < 0x40 || rev > 0x42) 
			return;
	}
	else
	{
		p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
		if(p == NULL)	/* No problem parts */
			return;
		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
		/* Check for buggy part revisions */
		if (rev < 0x10 || rev > 0x12) 
			return;
	}
	
	/*
	 *	Ok we have the problem. Now set the PCI master grant to 
	 *	occur every master grant. The apparent bug is that under high
	 *	PCI load (quite common in Linux of course) you can get data
	 *	loss when the CPU is held off the bus for 3 bus master requests
	 *	This happens to include the IDE controllers....

⌨️ 快捷键说明

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