quirks.c

来自「linux 内核源代码」· C语言 代码 · 共 1,758 行 · 第 1/5 页

C
1,758
字号
/* *  This file contains work-arounds for many known PCI hardware *  bugs.  Devices present only on certain architectures (host *  bridges et cetera) should be handled in arch-specific code. * *  Note: any quirks for hotpluggable devices must _NOT_ be declared __init. * *  Copyright (c) 1999 Martin Mares <mj@ucw.cz> * *  Init/reset quirks for USB host controllers should be in the *  USB quirks file, where their drivers can access reuse it. * *  The bridge optimization stuff has been removed. If you really *  have a silly BIOS which is unable to set your host bridge right, *  use the PowerTweak utility (see http://powertweak.sourceforge.net). */#include <linux/types.h>#include <linux/kernel.h>#include <linux/pci.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/acpi.h>#include "pci.h"/* The Mellanox Tavor device gives false positive parity errors * Mark this device with a broken_parity_status, to allow * PCI scanning code to "skip" this now blacklisted device. */static void __devinit quirk_mellanox_tavor(struct pci_dev *dev){	dev->broken_parity_status = 1;	/* This device gives false positives */}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor);DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor);/* Deal with broken BIOS'es that neglect to enable passive release,   which can cause problems in combination with the 82441FX/PPro MTRRs */static void quirk_passive_release(struct pci_dev *dev){	struct pci_dev *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_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {		pci_read_config_byte(d, 0x82, &dlc);		if (!(dlc & 1<<1)) {			printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d));			dlc |= 1<<1;			pci_write_config_byte(d, 0x82, dlc);		}	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release );DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_passive_release );/*  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 */int isa_dma_bridge_buggy;EXPORT_SYMBOL(isa_dma_bridge_buggy);    static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev){	if (!isa_dma_bridge_buggy) {		isa_dma_bridge_buggy=1;		printk(KERN_INFO "Activating ISA DMA hang workarounds.\n");	}}	/*	 * Its not totally clear which chipsets are the problematic ones	 * We know 82C586 and 82C596 variants are affected.	 */DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_0,	quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C596,	quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371SB_0,  quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M1533, 	quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,	PCI_DEVICE_ID_NEC_CBUS_1,	quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,	PCI_DEVICE_ID_NEC_CBUS_2,	quirk_isa_dma_hangs );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,	PCI_DEVICE_ID_NEC_CBUS_3,	quirk_isa_dma_hangs );int pci_pci_problems;EXPORT_SYMBOL(pci_pci_problems);/* *	Chipsets where PCI->PCI transfers vanish or hang */static void __devinit quirk_nopcipci(struct pci_dev *dev){	if ((pci_pci_problems & PCIPCI_FAIL)==0) {		printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_FAIL;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		quirk_nopcipci );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_496,		quirk_nopcipci );static void __devinit quirk_nopciamd(struct pci_dev *dev){	u8 rev;	pci_read_config_byte(dev, 0x08, &rev);	if (rev == 0x13) {		/* Erratum 24 */		printk(KERN_INFO "Chipset erratum: Disabling direct PCI/AGP transfers.\n");		pci_pci_problems |= PCIAGP_FAIL;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8151_0,	quirk_nopciamd );/* *	Triton requires workarounds to be used by the drivers */static void __devinit quirk_triton(struct pci_dev *dev){	if ((pci_pci_problems&PCIPCI_TRITON)==0) {		printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_TRITON;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82437, 	quirk_triton ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82437VX, 	quirk_triton ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82439, 	quirk_triton ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82439TX, 	quirk_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://www.au-ja.org/review-kt133a-1-en.phtml 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  */static void quirk_vialatency(struct pci_dev *dev){	struct pci_dev *p;	u8 rev;	u8 busarb;	/* Ok we have a potential problem chipset here. Now see if we have	   a buggy southbridge */	   	p = pci_get_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)			goto exit;	} else {		p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);		if (p==NULL)	/* No problem parts */			goto exit;		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);		/* Check for buggy part revisions */		if (rev < 0x10 || rev > 0x12) 			goto exit;	}		/*	 *	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....	 *	 *	VIA only apply this fix when an SB Live! is present but under	 *	both Linux and Windows this isnt enough, and we have seen	 *	corruption without SB Live! but with things like 3 UDMA IDE	 *	controllers. So we ignore that bit of the VIA recommendation..	 */	pci_read_config_byte(dev, 0x76, &busarb);	/* Set bit 4 and bi 5 of byte 76 to 0x01 	   "Master priority rotation on every PCI master grant */	busarb &= ~(1<<5);	busarb |= (1<<4);	pci_write_config_byte(dev, 0x76, busarb);	printk(KERN_INFO "Applying VIA southbridge workaround.\n");exit:	pci_dev_put(p);}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,		quirk_vialatency );/* Must restore this on a resume from RAM */DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,		quirk_vialatency );/* *	VIA Apollo VP3 needs ETBF on BT848/878 */static void __devinit quirk_viaetbf(struct pci_dev *dev){	if ((pci_pci_problems&PCIPCI_VIAETBF)==0) {		printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_VIAETBF;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_viaetbf );static void __devinit quirk_vsfx(struct pci_dev *dev){	if ((pci_pci_problems&PCIPCI_VSFX)==0) {		printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_VSFX;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C576,	quirk_vsfx );/* *	Ali Magik requires workarounds to be used by the drivers *	that DMA to AGP space. Latency must be set to 0xA and triton *	workaround applied too *	[Info kindly provided by ALi] */	static void __init quirk_alimagik(struct pci_dev *dev){	if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) {		printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 	PCI_DEVICE_ID_AL_M1647, 	quirk_alimagik );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 	PCI_DEVICE_ID_AL_M1651, 	quirk_alimagik );/* *	Natoma has some interesting boundary conditions with Zoran stuff *	at least */static void __devinit quirk_natoma(struct pci_dev *dev){	if ((pci_pci_problems&PCIPCI_NATOMA)==0) {		printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n");		pci_pci_problems |= PCIPCI_NATOMA;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82441, 	quirk_natoma ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443LX_0, 	quirk_natoma ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443LX_1, 	quirk_natoma ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443BX_0, 	quirk_natoma ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443BX_1, 	quirk_natoma ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 	PCI_DEVICE_ID_INTEL_82443BX_2, 	quirk_natoma );/* *  This chip can cause PCI parity errors if config register 0xA0 is read *  while DMAs are occurring. */static void __devinit quirk_citrine(struct pci_dev *dev){	dev->cfg_size = 0xA0;}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CITRINE,	quirk_citrine );/* *  S3 868 and 968 chips report region size equal to 32M, but they decode 64M. *  If it's needed, re-allocate the region. */static void __devinit quirk_s3_64M(struct pci_dev *dev){	struct resource *r = &dev->resource[0];	if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) {		r->start = 0;		r->end = 0x3ffffff;	}}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3,	PCI_DEVICE_ID_S3_868,		quirk_s3_64M );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3,	PCI_DEVICE_ID_S3_968,		quirk_s3_64M );static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,	unsigned size, int nr, const char *name){	region &= ~(size-1);	if (region) {		struct pci_bus_region bus_region;		struct resource *res = dev->resource + nr;		res->name = pci_name(dev);		res->start = region;		res->end = region + size - 1;		res->flags = IORESOURCE_IO;		/* Convert from PCI bus to resource space.  */		bus_region.start = res->start;		bus_region.end = res->end;		pcibios_bus_to_resource(dev, res, &bus_region);		pci_claim_resource(dev, nr);		printk("PCI quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name);	}}	/* *	ATI Northbridge setups MCE the processor if you even *	read somewhere between 0x3b0->0x3bb or read 0x3d3 */static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev){	printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n");	/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */	request_region(0x3b0, 0x0C, "RadeonIGP");	request_region(0x3d3, 0x01, "RadeonIGP");}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_RS100,   quirk_ati_exploding_mce );/* * Let's make the southbridge information explicit instead * of having to worry about people probing the ACPI areas, * for example.. (Yes, it happens, and if you read the wrong * ACPI register it will put the machine to sleep with no * way of waking it up again. Bummer). * * ALI M7101: Two IO regions pointed to by words at *	0xE0 (64 bytes of ACPI registers) *	0xE2 (32 bytes of SMB registers) */static void __devinit quirk_ali7101_acpi(struct pci_dev *dev){	u16 region;	pci_read_config_word(dev, 0xE0, &region);	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI");	pci_read_config_word(dev, 0xE2, &region);	quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB");}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M7101,		quirk_ali7101_acpi );static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable){	u32 devres;	u32 mask, size, base;	pci_read_config_dword(dev, port, &devres);	if ((devres & enable) != enable)		return;	mask = (devres >> 16) & 15;	base = devres & 0xffff;	size = 16;	for (;;) {		unsigned bit = size >> 1;		if ((bit & mask) == bit)			break;		size = bit;	}	/*	 * For now we only print it out. Eventually we'll want to

⌨️ 快捷键说明

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