quirks.c

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

C
1,758
字号
	 * reserve it (at least if it's in the 0x1000+ range), but	 * let's get enough confirmation reports first. 	 */	base &= -size;	printk("%s PIO at %04x-%04x\n", name, base, base + size - 1);}static void piix4_mem_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;	base = devres & 0xffff0000;	mask = (devres & 0x3f) << 16;	size = 128 << 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	 * reserve it, but let's get enough confirmation reports first. 	 */	base &= -size;	printk("%s MMIO at %04x-%04x\n", name, base, base + size - 1);}/* * PIIX4 ACPI: Two IO regions pointed to by longwords at *	0x40 (64 bytes of ACPI registers) *	0x90 (16 bytes of SMB registers) * and a few strange programmable PIIX4 device resources. */static void __devinit quirk_piix4_acpi(struct pci_dev *dev){	u32 region, res_a;	pci_read_config_dword(dev, 0x40, &region);	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");	pci_read_config_dword(dev, 0x90, &region);	quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");	/* Device resource A has enables for some of the other ones */	pci_read_config_dword(dev, 0x5c, &res_a);	piix4_io_quirk(dev, "PIIX4 devres B", 0x60, 3 << 21);	piix4_io_quirk(dev, "PIIX4 devres C", 0x64, 3 << 21);	/* Device resource D is just bitfields for static resources */	/* Device 12 enabled? */	if (res_a & (1 << 29)) {		piix4_io_quirk(dev, "PIIX4 devres E", 0x68, 1 << 20);		piix4_mem_quirk(dev, "PIIX4 devres F", 0x6c, 1 << 7);	}	/* Device 13 enabled? */	if (res_a & (1 << 30)) {		piix4_io_quirk(dev, "PIIX4 devres G", 0x70, 1 << 20);		piix4_mem_quirk(dev, "PIIX4 devres H", 0x74, 1 << 7);	}	piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20);	piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 1 << 20);}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_3,	quirk_piix4_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82443MX_3,	quirk_piix4_acpi );/* * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at *	0x40 (128 bytes of ACPI, GPIO & TCO registers) *	0x58 (64 bytes of GPIO I/O space) */static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev){	u32 region;	pci_read_config_dword(dev, 0x40, &region);	quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH4 ACPI/GPIO/TCO");	pci_read_config_dword(dev, 0x58, &region);	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO");}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AA_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AB_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801BA_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801BA_10,	quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801CA_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801CA_12,	quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801DB_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801DB_12,	quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801EB_0,		quirk_ich4_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,		quirk_ich4_lpc_acpi );static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev){	u32 region;	pci_read_config_dword(dev, 0x40, &region);	quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, "ICH6 ACPI/GPIO/TCO");	pci_read_config_dword(dev, 0x48, &region);	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH8_1, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH8_4, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH9_2, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH9_4, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH9_7, quirk_ich6_lpc_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ICH9_8, quirk_ich6_lpc_acpi );/* * VIA ACPI: One IO region pointed to by longword at *	0x48 or 0x20 (256 bytes of ACPI registers) */static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev){	u32 region;	if (dev->revision & 0x10) {		pci_read_config_dword(dev, 0x48, &region);		region &= PCI_BASE_ADDRESS_IO_MASK;		quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI");	}}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_vt82c586_acpi );/* * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at *	0x48 (256 bytes of ACPI registers) *	0x70 (128 bytes of hardware monitoring register) *	0x90 (16 bytes of SMB registers) */static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev){	u16 hm;	u32 smb;	quirk_vt82c586_acpi(dev);	pci_read_config_word(dev, 0x70, &hm);	hm &= PCI_BASE_ADDRESS_IO_MASK;	quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");	pci_read_config_dword(dev, 0x90, &smb);	smb &= PCI_BASE_ADDRESS_IO_MASK;	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt82c686_acpi );/* * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at *	0x88 (128 bytes of power management registers) *	0xd0 (16 bytes of SMB registers) */static void __devinit quirk_vt8235_acpi(struct pci_dev *dev){	u16 pm, smb;	pci_read_config_word(dev, 0x88, &pm);	pm &= PCI_BASE_ADDRESS_IO_MASK;	quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM");	pci_read_config_word(dev, 0xd0, &smb);	smb &= PCI_BASE_ADDRESS_IO_MASK;	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB");}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8235,	quirk_vt8235_acpi);#ifdef CONFIG_X86_IO_APIC #include <asm/io_apic.h>/* * VIA 686A/B: If an IO-APIC is active, we need to route all on-chip * devices to the external APIC. * * TODO: When we have device-specific interrupt routers, * this code will go away from quirks. */static void quirk_via_ioapic(struct pci_dev *dev){	u8 tmp;		if (nr_ioapics < 1)		tmp = 0;    /* nothing routed to external APIC */	else		tmp = 0x1f; /* all known bits (4-0) routed to external APIC */			printk(KERN_INFO "PCI: %sbling Via external APIC routing\n",	       tmp == 0 ? "Disa" : "Ena");	/* Offset 0x58: External APIC IRQ output control */	pci_write_config_byte (dev, 0x58, tmp);}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic );DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_ioapic );/* * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. * This leads to doubled level interrupt rates. * Set this bit to get rid of cycle wastage. * Otherwise uncritical. */static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev){	u8 misc_control2;#define BYPASS_APIC_DEASSERT 8	pci_read_config_byte(dev, 0x5B, &misc_control2);	if (!(misc_control2 & BYPASS_APIC_DEASSERT)) {		printk(KERN_INFO "PCI: Bypassing VIA 8237 APIC De-Assert Message\n");		pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT);	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237,		quirk_via_vt8237_bypass_apic_deassert);DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237,		quirk_via_vt8237_bypass_apic_deassert);/* * The AMD io apic can hang the box when an apic irq is masked. * We check all revs >= B0 (yet not in the pre production!) as the bug * is currently marked NoFix * * We have multiple reports of hangs with this chipset that went away with * noapic specified. For the moment we assume it's the erratum. We may be wrong * of course. However the advice is demonstrably good even if so.. */static void __devinit quirk_amd_ioapic(struct pci_dev *dev){	if (dev->revision >= 0x02) {		printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");		printk(KERN_WARNING "        : booting with the \"noapic\" option.\n");	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7410,	quirk_amd_ioapic );static void __init quirk_ioapic_rmw(struct pci_dev *dev){	if (dev->devfn == 0 && dev->bus->number == 0)		sis_apic_bug = 1;}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_ANY_ID,			quirk_ioapic_rmw );#define AMD8131_revA0        0x01#define AMD8131_revB0        0x11#define AMD8131_MISC         0x40#define AMD8131_NIOAMODE_BIT 0static void quirk_amd_8131_ioapic(struct pci_dev *dev){         unsigned char tmp;                if (nr_ioapics == 0)                 return;        if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) {                printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n");                 pci_read_config_byte( dev, AMD8131_MISC, &tmp);                tmp &= ~(1 << AMD8131_NIOAMODE_BIT);                pci_write_config_byte( dev, AMD8131_MISC, tmp);        }} DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);#endif /* CONFIG_X86_IO_APIC *//* * Some settings of MMRBC can lead to data corruption so block changes. * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide */static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev){	if (dev->subordinate && dev->revision <= 0x12) {		printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X "				"MMRBC\n", dev->revision);		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc);/* * FIXME: it is questionable that quirk_via_acpi * is needed.  It shows up as an ISA bridge, and does not * support the PCI_INTERRUPT_LINE register at all.  Therefore * it seems like setting the pci_dev's 'irq' to the * value of the ACPI SCI interrupt is only done for convenience. *	-jgarzik */static void __devinit quirk_via_acpi(struct pci_dev *d){	/*	 * VIA ACPI device: SCI IRQ line in PCI config byte 0x42	 */	u8 irq;	pci_read_config_byte(d, 0x42, &irq);	irq &= 0xf;	if (irq && (irq != 2))		d->irq = irq;}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );/* *	VIA bridges which have VLink */static int via_vlink_dev_lo = -1, via_vlink_dev_hi = 18;static void quirk_via_bridge(struct pci_dev *dev){	/* See what bridge we have and find the device ranges */	switch (dev->device) {	case PCI_DEVICE_ID_VIA_82C686:		/* The VT82C686 is special, it attaches to PCI and can have		   any device number. All its subdevices are functions of		   that single device. */		via_vlink_dev_lo = PCI_SLOT(dev->devfn);		via_vlink_dev_hi = PCI_SLOT(dev->devfn);		break;	case PCI_DEVICE_ID_VIA_8237:	case PCI_DEVICE_ID_VIA_8237A:		via_vlink_dev_lo = 15;		break;	case PCI_DEVICE_ID_VIA_8235:		via_vlink_dev_lo = 16;		break;	case PCI_DEVICE_ID_VIA_8231:	case PCI_DEVICE_ID_VIA_8233_0:	case PCI_DEVICE_ID_VIA_8233A:	case PCI_DEVICE_ID_VIA_8233C_0:		via_vlink_dev_lo = 17;		break;	}}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686,	quirk_via_bridge);DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8231,		quirk_via_bridge);DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8233_0,	quirk_via_bridge);DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8233A,	quirk_via_bridge);DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8233C_0,	quirk_via_bridge);DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8235,		quirk_via_bridge);

⌨️ 快捷键说明

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