quirks.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,029 行 · 第 1/3 页

C
1,029
字号
 *	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);	pci_read_config_dword(dev, 0x90, &smb);	smb &= PCI_BASE_ADDRESS_IO_MASK;	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2);}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt82c686_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 __devinit 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 );/* * 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 its the errata. 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){	u8 rev;	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);	if (rev >= 0x02) {		printk(KERN_WARNING "I/O APIC: AMD Errata #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 __init quirk_amd_8131_ioapic(struct pci_dev *dev) {         unsigned char revid, tmp;                if (nr_ioapics == 0)                 return;        pci_read_config_byte(dev, PCI_REVISION_ID, &revid);        if (revid == AMD8131_revA0 || revid == 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_APIC,         quirk_amd_8131_ioapic ); #endif /* CONFIG_X86_IO_APIC *//* * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: * when written, it makes an internal connection to the PIC. * For these devices, this register is defined to be 4 bits wide. * Normally this is fine.  However for IO-APIC motherboards, or * non-x86 architectures (yes Via exists on PPC among other places), * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get * interrupts delivered properly. * * TODO: When we have device-specific interrupt routers, * quirk_via_irqpic will go away from quirks. *//* * 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 );static void __devinit quirk_via_irqpic(struct pci_dev *dev){	u8 irq, new_irq = dev->irq & 0xf;	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);	if (new_irq != irq) {		printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n",		       pci_name(dev), irq, new_irq);		udelay(15);		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );/* * PIIX3 USB: We have to disable USB interrupts that are * hardwired to PIRQD# and may be shared with an * external device. * * Legacy Support Register (LEGSUP): *     bit13:  USB PIRQ Enable (USBPIRQDEN), *     bit4:   Trap/SMI On IRQ Enable (USBSMIEN). * * We mask out all r/wc bits, too. */static void __devinit quirk_piix3_usb(struct pci_dev *dev){	u16 legsup;	pci_read_config_word(dev, 0xc0, &legsup);	legsup &= 0x50ef;	pci_write_config_word(dev, 0xc0, legsup);}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371SB_2,	quirk_piix3_usb );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82371AB_2,	quirk_piix3_usb );/* * VIA VT82C598 has its device ID settable and many BIOSes * set it to the ID of VT82C597 for backward compatibility. * We need to switch it off to be able to recognize the real * type of the chip. */static void __devinit quirk_vt82c598_id(struct pci_dev *dev){	pci_write_config_byte(dev, 0xfc, 0);	pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_vt82c598_id );/* * CardBus controllers have a legacy base address that enables them * to respond as i82365 pcmcia controllers.  We don't want them to * do this even if the Linux CardBus driver is not loaded, because * the Linux i82365 driver does not (and should not) handle CardBus. */static void __devinit quirk_cardbus_legacy(struct pci_dev *dev){	if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)		return;	pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);}DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID,		PCI_ANY_ID,			quirk_cardbus_legacy );/* * Following the PCI ordering rules is optional on the AMD762. I'm not * sure what the designers were smoking but let's not inhale... * * To be fair to AMD, it follows the spec by default, its BIOS people * who turn it off! */static void __devinit quirk_amd_ordering(struct pci_dev *dev){	u32 pcic;	pci_read_config_dword(dev, 0x4C, &pcic);	if ((pcic&6)!=6) {		pcic |= 6;		printk(KERN_WARNING "BIOS failed to enable PCI standards compliance, fixing this error.\n");		pci_write_config_dword(dev, 0x4C, pcic);		pci_read_config_dword(dev, 0x84, &pcic);		pcic |= (1<<23);	/* Required in this mode */		pci_write_config_dword(dev, 0x84, pcic);	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );/* *	DreamWorks provided workaround for Dunord I-3000 problem * *	This card decodes and responds to addresses not apparently *	assigned to it. We force a larger allocation to ensure that *	nothing gets put too close to it. */static void __devinit quirk_dunord ( struct pci_dev * dev ){	struct resource *r = &dev->resource [1];	r->start = 0;	r->end = 0xffffff;}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD,	PCI_DEVICE_ID_DUNORD_I3000,	quirk_dunord );/* * i82380FB mobile docking controller: its PCI-to-PCI bridge * is subtractive decoding (transparent), and does indicate this * in the ProgIf. Unfortunately, the ProgIf value is wrong - 0x80 * instead of 0x01. */static void __devinit quirk_transparent_bridge(struct pci_dev *dev){	dev->transparent = 1;}DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82380FB,	quirk_transparent_bridge );DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA,	0x605,	quirk_transparent_bridge );/* * Common misconfiguration of the MediaGX/Geode PCI master that will * reduce PCI bandwidth from 70MB/s to 25MB/s.  See the GXM/GXLV/GX1 * datasheets found at http://www.national.com/ds/GX for info on what * these bits do.  <christer@weinigel.se> */static void __init quirk_mediagx_master(struct pci_dev *dev){	u8 reg;	pci_read_config_byte(dev, 0x41, &reg);	if (reg & 2) {		reg &= ~2;		printk(KERN_INFO "PCI: Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg);                pci_write_config_byte(dev, 0x41, reg);	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX,	PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );/* * As per PCI spec, ignore base address registers 0-3 of the IDE controllers * running in Compatible mode (bits 0 and 2 in the ProgIf for primary and * secondary channels respectively). If the device reports Compatible mode * but does use BAR0-3 for address decoding, we assume that firmware has * programmed these BARs with standard values (0x1f0,0x3f4 and 0x170,0x374). * Exceptions (if they exist) must be handled in chip/architecture specific * fixups. * * Note: for non x86 people. You may need an arch specific quirk to handle * moving IDE devices to native mode as well. Some plug in card devices power * up in compatible mode and assume the BIOS will adjust them. * * Q: should we load the 0x1f0,0x3f4 into the registers or zap them as * we do now ? We don't want is pci_enable_device to come along * and assign new resources. Both approaches work for that. */ static void __devinit quirk_ide_bases(struct pci_dev *dev){       struct resource *res;       int first_bar = 2, last_bar = 0;       if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)               return;       res = &dev->resource[0];       /* primary channel: ProgIf bit 0, BAR0, BAR1 */       if (!(dev->class & 1) && (res[0].flags || res[1].flags)) {                res[0].start = res[0].end = res[0].flags = 0;               res[1].start = res[1].end = res[1].flags = 0;               first_bar = 0;               last_bar = 1;       }       /* secondary channel: ProgIf bit 2, BAR2, BAR3 */       if (!(dev->class & 4) && (res[2].flags || res[3].flags)) {                res[2].start = res[2].end = res[2].flags = 0;               res[3].start = res[3].end = res[3].flags = 0;               last_bar = 3;       }       if (!last_bar)               return;       printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n",              first_bar, last_bar, pci_name(dev));}DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID,             PCI_ANY_ID,                     quirk_ide_bases );/* *	Ensure C0 rev restreaming is off. This is normally done by *	the BIOS but in the odd case it is not the results are corruption *	hence the presence of a Linux check */static void __init quirk_disable_pxb(struct pci_dev *pdev){	u16 config;	u8 rev;		pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);	if (rev != 0x04)		/* Only C0 requires this */		return;	pci_read_config_word(pdev, 0x40, &config);	if (config & (1<<6)) {		config &= ~(1<<6);		pci_write_config_word(pdev, 0x40, config);		printk(KERN_INFO "PCI: C0 revision 450NX. Disabling PCI restreaming.\n");	}}DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb );

⌨️ 快捷键说明

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