Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6: (64 commits)
  PCI: make pci_bus a struct device
  PCI: fix codingstyle issues in include/linux/pci.h
  PCI: fix codingstyle issues in drivers/pci/pci.h
  PCI: PCIE ASPM support
  PCI: Fix fakephp deadlock
  PCI: modify SB700 SATA MSI quirk
  PCI: Run ACPI _OSC method on root bridges only
  PCI ACPI: AER driver should only register PCIe devices with _OSC
  PCI ACPI: Added a function to register _OSC with only PCIe devices.
  PCI: constify function pointer tables
  PCI: Convert drivers/pci/proc.c to use unlocked_ioctl
  pciehp: block new requests from the device before power off
  pciehp: workaround against Bad DLLP during power off
  pciehp: wait for 1000ms before LED operation after power off
  PCI: Remove pci_enable_device_bars() from documentation
  PCI: Remove pci_enable_device_bars()
  PCI: Remove users of pci_enable_device_bars()
  PCI: Add pci_enable_device_{io,mem} intefaces
  PCI: avoid save the same type of cap multiple times
  PCI: correctly initialize a structure for pcie_save_pcix_state()
  ...
This commit is contained in:
Linus Torvalds 2008-02-02 14:29:33 +11:00
commit 215e871aaa
63 changed files with 2101 additions and 897 deletions

View file

@ -274,8 +274,6 @@ the PCI device by calling pci_enable_device(). This will:
o allocate an IRQ (if BIOS did not). o allocate an IRQ (if BIOS did not).
NOTE: pci_enable_device() can fail! Check the return value. NOTE: pci_enable_device() can fail! Check the return value.
NOTE2: Also see pci_enable_device_bars() below. Drivers can
attempt to enable only a subset of BARs they need.
[ OS BUG: we don't check resource allocations before enabling those [ OS BUG: we don't check resource allocations before enabling those
resources. The sequence would make more sense if we called resources. The sequence would make more sense if we called
@ -605,40 +603,7 @@ device lists. This is still possible but discouraged.
10. pci_enable_device_bars() and Legacy I/O Port space 10. MMIO Space and "Write Posting"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Large servers may not be able to provide I/O port resources to all PCI
devices. I/O Port space is only 64KB on Intel Architecture[1] and is
likely also fragmented since the I/O base register of PCI-to-PCI
bridge will usually be aligned to a 4KB boundary[2]. On such systems,
pci_enable_device() and pci_request_region() will fail when
attempting to enable I/O Port regions that don't have I/O Port
resources assigned.
Fortunately, many PCI devices which request I/O Port resources also
provide access to the same registers via MMIO BARs. These devices can
be handled without using I/O port space and the drivers typically
offer a CONFIG_ option to only use MMIO regions
(e.g. CONFIG_TULIP_MMIO). PCI devices typically provide I/O port
interface for legacy OSes and will work when I/O port resources are not
assigned. The "PCI Local Bus Specification Revision 3.0" discusses
this on p.44, "IMPLEMENTATION NOTE".
If your PCI device driver doesn't need I/O port resources assigned to
I/O Port BARs, you should use pci_enable_device_bars() instead of
pci_enable_device() in order not to enable I/O port regions for the
corresponding devices. In addition, you should use
pci_request_selected_regions() and pci_release_selected_regions()
instead of pci_request_regions()/pci_release_regions() in order not to
request/release I/O port regions for the corresponding devices.
[1] Some systems support 64KB I/O port space per PCI segment.
[2] Some PCI-to-PCI bridges support optional 1KB aligned I/O base.
11. MMIO Space and "Write Posting"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converting a driver from using I/O Port space to using MMIO space Converting a driver from using I/O Port space to using MMIO space

View file

@ -318,11 +318,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config PCI_DOMAINS config PCI_DOMAINS
bool bool
default y default y

View file

@ -577,11 +577,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config PCI_SYSCALL config PCI_SYSCALL
def_bool PCI def_bool PCI

View file

@ -322,11 +322,6 @@ config PCI
onboard. If you have one of these boards and you wish to use the PCI onboard. If you have one of these boards and you wish to use the PCI
facilities, say Y here. facilities, say Y here.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config RESERVE_DMA_COHERENT config RESERVE_DMA_COHERENT
bool "Reserve DMA coherent memory" bool "Reserve DMA coherent memory"
depends on PCI && !MMU depends on PCI && !MMU

View file

@ -359,11 +359,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
choice choice
prompt "PCI access mode" prompt "PCI access mode"
depends on PCI depends on PCI

View file

@ -145,11 +145,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config MAC config MAC
bool "Macintosh support" bool "Macintosh support"
depends on !MMU_SUN3 depends on !MMU_SUN3

View file

@ -1961,11 +1961,6 @@ config PCI
your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, your box. Other bus systems are ISA, EISA, or VESA. If you have PCI,
say Y, otherwise N. say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config PCI_DOMAINS config PCI_DOMAINS
bool bool

View file

@ -6,11 +6,6 @@ config PCI
bus system, i.e. the way the CPU talks to the other stuff inside bus system, i.e. the way the CPU talks to the other stuff inside
your box. If you have PCI, say Y, otherwise N. your box. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config SH_PCIDMA_NONCOHERENT config SH_PCIDMA_NONCOHERENT
bool "Cache and PCI noncoherent" bool "Cache and PCI noncoherent"
depends on PCI depends on PCI

View file

@ -351,11 +351,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
config PCI_DOMAINS config PCI_DOMAINS
def_bool PCI def_bool PCI

View file

@ -1369,11 +1369,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't.
choice choice
prompt "PCI access mode" prompt "PCI access mode"
depends on X86_32 && PCI && !X86_VISWS depends on X86_32 && PCI && !X86_VISWS

View file

@ -30,8 +30,8 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
if (!(word & (1 << 13))) { if (!(word & (1 << 13))) {
printk(KERN_INFO "Intel E7520/7320/7525 detected. " dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
"Disabling irq balancing and affinity\n"); "disabling irq balancing and affinity\n");
#ifdef CONFIG_IRQBALANCE #ifdef CONFIG_IRQBALANCE
irqbalance_disable(""); irqbalance_disable("");
#endif #endif
@ -104,14 +104,16 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0xF0, &rcba); pci_read_config_dword(dev, 0xF0, &rcba);
rcba &= 0xFFFFC000; rcba &= 0xFFFFC000;
if (rcba == 0) { if (rcba == 0) {
printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n"); dev_printk(KERN_DEBUG, &dev->dev, "RCBA disabled; "
"cannot force enable HPET\n");
return; return;
} }
/* use bits 31:14, 16 kB aligned */ /* use bits 31:14, 16 kB aligned */
rcba_base = ioremap_nocache(rcba, 0x4000); rcba_base = ioremap_nocache(rcba, 0x4000);
if (rcba_base == NULL) { if (rcba_base == NULL) {
printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n"); dev_printk(KERN_DEBUG, &dev->dev, "ioremap failed; "
"cannot force enable HPET\n");
return; return;
} }
@ -122,8 +124,8 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
/* HPET is enabled in HPTC. Just not reported by BIOS */ /* HPET is enabled in HPTC. Just not reported by BIOS */
val = val & 0x3; val = val & 0x3;
force_hpet_address = 0xFED00000 | (val << 12); force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
force_hpet_address); "0x%lx\n", force_hpet_address);
iounmap(rcba_base); iounmap(rcba_base);
return; return;
} }
@ -142,11 +144,12 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
if (err) { if (err) {
force_hpet_address = 0; force_hpet_address = 0;
iounmap(rcba_base); iounmap(rcba_base);
printk(KERN_DEBUG "Failed to force enable HPET\n"); dev_printk(KERN_DEBUG, &dev->dev,
"Failed to force enable HPET\n");
} else { } else {
force_hpet_resume_type = ICH_FORCE_HPET_RESUME; force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
force_hpet_address); "0x%lx\n", force_hpet_address);
} }
} }
@ -208,8 +211,8 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
if (val & 0x4) { if (val & 0x4) {
val &= 0x3; val &= 0x3;
force_hpet_address = 0xFED00000 | (val << 12); force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
force_hpet_address); force_hpet_address);
return; return;
} }
@ -229,14 +232,14 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
/* HPET is enabled in HPTC. Just not reported by BIOS */ /* HPET is enabled in HPTC. Just not reported by BIOS */
val &= 0x3; val &= 0x3;
force_hpet_address = 0xFED00000 | (val << 12); force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
force_hpet_address); "0x%lx\n", force_hpet_address);
cached_dev = dev; cached_dev = dev;
force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME; force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
return; return;
} }
printk(KERN_DEBUG "Failed to force enable HPET\n"); dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
} }
/* /*
@ -294,8 +297,8 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev)
*/ */
if (val & 0x80) { if (val & 0x80) {
force_hpet_address = (val & ~0x3ff); force_hpet_address = (val & ~0x3ff);
printk(KERN_DEBUG "HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
force_hpet_address); force_hpet_address);
return; return;
} }
@ -309,14 +312,14 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0x68, &val); pci_read_config_dword(dev, 0x68, &val);
if (val & 0x80) { if (val & 0x80) {
force_hpet_address = (val & ~0x3ff); force_hpet_address = (val & ~0x3ff);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
force_hpet_address); "0x%lx\n", force_hpet_address);
cached_dev = dev; cached_dev = dev;
force_hpet_resume_type = VT8237_FORCE_HPET_RESUME; force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
return; return;
} }
printk(KERN_DEBUG "Failed to force enable HPET\n"); dev_printk(KERN_DEBUG, &dev->dev, "Failed to force enable HPET\n");
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
@ -344,7 +347,7 @@ static void nvidia_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0x44, &val); pci_read_config_dword(dev, 0x44, &val);
force_hpet_address = val & 0xfffffffe; force_hpet_address = val & 0xfffffffe;
force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME; force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME;
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n",
force_hpet_address); force_hpet_address);
cached_dev = dev; cached_dev = dev;
return; return;

View file

@ -17,7 +17,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
int pxb, reg; int pxb, reg;
u8 busno, suba, subb; u8 busno, suba, subb;
printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", pci_name(d)); dev_warn(&d->dev, "Searching for i450NX host bridges\n");
reg = 0xd0; reg = 0xd0;
for(pxb = 0; pxb < 2; pxb++) { for(pxb = 0; pxb < 2; pxb++) {
pci_read_config_byte(d, reg++, &busno); pci_read_config_byte(d, reg++, &busno);
@ -41,7 +41,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d)
*/ */
u8 busno; u8 busno;
pci_read_config_byte(d, 0x4a, &busno); pci_read_config_byte(d, 0x4a, &busno);
printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno); dev_info(&d->dev, "i440KX/GX host bridge; secondary bus %02x\n", busno);
pci_scan_bus_with_sysdata(busno); pci_scan_bus_with_sysdata(busno);
pcibios_last_bus = -1; pcibios_last_bus = -1;
} }
@ -55,7 +55,7 @@ static void __devinit pci_fixup_umc_ide(struct pci_dev *d)
*/ */
int i; int i;
printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", pci_name(d)); dev_warn(&d->dev, "Fixing base address flags\n");
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO; d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
} }
@ -68,7 +68,7 @@ static void __devinit pci_fixup_ncr53c810(struct pci_dev *d)
* Fix class to be PCI_CLASS_STORAGE_SCSI * Fix class to be PCI_CLASS_STORAGE_SCSI
*/ */
if (!d->class) { if (!d->class) {
printk(KERN_WARNING "PCI: fixing NCR 53C810 class code for %s\n", pci_name(d)); dev_warn(&d->dev, "Fixing NCR 53C810 class code\n");
d->class = PCI_CLASS_STORAGE_SCSI << 8; d->class = PCI_CLASS_STORAGE_SCSI << 8;
} }
} }
@ -80,7 +80,7 @@ static void __devinit pci_fixup_latency(struct pci_dev *d)
* SiS 5597 and 5598 chipsets require latency timer set to * SiS 5597 and 5598 chipsets require latency timer set to
* at most 32 to avoid lockups. * at most 32 to avoid lockups.
*/ */
DBG("PCI: Setting max latency to 32\n"); dev_dbg(&d->dev, "Setting max latency to 32\n");
pcibios_max_latency = 32; pcibios_max_latency = 32;
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency);
@ -138,7 +138,7 @@ static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
pci_read_config_byte(d, where, &v); pci_read_config_byte(d, where, &v);
if (v & ~mask) { if (v & ~mask) {
printk(KERN_WARNING "Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \ dev_warn(&d->dev, "Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \
d->device, d->revision, where, v, mask, v & mask); d->device, d->revision, where, v, mask, v & mask);
v &= mask; v &= mask;
pci_write_config_byte(d, where, v); pci_write_config_byte(d, where, v);
@ -200,7 +200,7 @@ static void pci_fixup_nforce2(struct pci_dev *dev)
* Apply fixup if needed, but don't touch disconnect state * Apply fixup if needed, but don't touch disconnect state
*/ */
if ((val & 0x00FF0000) != 0x00010000) { if ((val & 0x00FF0000) != 0x00010000) {
printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n"); dev_warn(&dev->dev, "nForce2 C1 Halt Disconnect fixup\n");
pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000); pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000);
} }
} }
@ -348,7 +348,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
pci_read_config_word(pdev, PCI_COMMAND, &config); pci_read_config_word(pdev, PCI_COMMAND, &config);
if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n");
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
@ -388,11 +388,11 @@ static void __devinit pci_fixup_msi_k8t_onboard_sound(struct pci_dev *dev)
/* verify the change for status output */ /* verify the change for status output */
pci_read_config_byte(dev, 0x50, &val); pci_read_config_byte(dev, 0x50, &val);
if (val & 0x40) if (val & 0x40)
printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " dev_info(&dev->dev, "Detected MSI K8T Neo2-FIR; "
"can't enable onboard soundcard!\n"); "can't enable onboard soundcard!\n");
else else
printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, " dev_info(&dev->dev, "Detected MSI K8T Neo2-FIR; "
"enabled onboard soundcard.\n"); "enabled onboard soundcard\n");
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,

View file

@ -174,11 +174,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
VESA. If you have PCI, say Y, otherwise N. VESA. If you have PCI, say Y, otherwise N.
The PCI-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>, contains valuable
information about which PCI hardware does work under Linux and which
doesn't
source "drivers/pci/Kconfig" source "drivers/pci/Kconfig"
config HOTPLUG config HOTPLUG

View file

@ -229,7 +229,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
return -ENOMEM; return -ENOMEM;
/* Perform set up for DMA */ /* Perform set up for DMA */
if (pci_enable_device_bars(pdev, 1<<2)) { if (pci_enable_device_io(pdev)) {
printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
return -ENODEV; return -ENODEV;
} }

View file

@ -492,7 +492,7 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev,
iface->pdev = pdev; iface->pdev = pdev;
iface->bar = bar; iface->bar = bar;
rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); rc = pci_enable_device_io(iface->pdev);
if (rc) if (rc)
goto errout_free; goto errout_free;

View file

@ -156,8 +156,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
ide_setup_pci_noise(dev, d); ide_setup_pci_noise(dev, d);
/* We must not grab the entire device, it has 'ISA' space in its /* We must not grab the entire device, it has 'ISA' space in its
BARS too and we will freak out other bits of the kernel */ * BARS too and we will freak out other bits of the kernel
if (pci_enable_device_bars(dev, 1<<2)) { *
* pci_enable_device_bars() is going away. I replaced it with
* IO only enable for now but I'll need confirmation this is
* allright for that device. If not, it will need some kind of
* quirk. --BenH.
*/
if (pci_enable_device_io(dev)) {
printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
return -ENODEV; return -ENODEV;
} }

View file

@ -228,7 +228,9 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
* @d: IDE port info * @d: IDE port info
* *
* Enable the IDE PCI device. We attempt to enable the device in full * Enable the IDE PCI device. We attempt to enable the device in full
* but if that fails then we only need BAR4 so we will enable that. * but if that fails then we only need IO space. The PCI code should
* have setup the proper resources for us already for controllers in
* legacy mode.
* *
* Returns zero on success or an error code * Returns zero on success or an error code
*/ */
@ -238,7 +240,7 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
int ret; int ret;
if (pci_enable_device(dev)) { if (pci_enable_device(dev)) {
ret = pci_enable_device_bars(dev, 1 << 4); ret = pci_enable_device_io(dev);
if (ret < 0) { if (ret < 0) {
printk(KERN_WARNING "%s: (ide_setup_pci_device:) " printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
"Could not enable device.\n", d->name); "Could not enable device.\n", d->name);

View file

@ -108,6 +108,7 @@ int pci_bus_add_device(struct pci_dev *dev)
void pci_bus_add_devices(struct pci_bus *bus) void pci_bus_add_devices(struct pci_bus *bus)
{ {
struct pci_dev *dev; struct pci_dev *dev;
struct pci_bus *child_bus;
int retval; int retval;
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
@ -138,11 +139,19 @@ void pci_bus_add_devices(struct pci_bus *bus)
up_write(&pci_bus_sem); up_write(&pci_bus_sem);
} }
pci_bus_add_devices(dev->subordinate); pci_bus_add_devices(dev->subordinate);
retval = sysfs_create_link(&dev->subordinate->class_dev.kobj,
&dev->dev.kobj, "bridge"); /* register the bus with sysfs as the parent is now
* properly registered. */
child_bus = dev->subordinate;
child_bus->dev.parent = child_bus->bridge;
retval = device_register(&child_bus->dev);
if (!retval)
retval = device_create_file(&child_bus->dev,
&dev_attr_cpuaffinity);
if (retval) if (retval)
dev_err(&dev->dev, "Error creating sysfs " dev_err(&dev->dev, "Error registering pci_bus"
"bridge symlink, continuing...\n"); " device bridge symlink,"
" continuing...\n");
} }
} }
} }
@ -204,7 +213,6 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
} }
up_read(&pci_bus_sem); up_read(&pci_bus_sem);
} }
EXPORT_SYMBOL_GPL(pci_walk_bus);
EXPORT_SYMBOL(pci_bus_alloc_resource); EXPORT_SYMBOL(pci_bus_alloc_resource);
EXPORT_SYMBOL_GPL(pci_bus_add_device); EXPORT_SYMBOL_GPL(pci_bus_add_device);

View file

@ -25,6 +25,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/dmar.h> #include <linux/dmar.h>
#include "iova.h"
#undef PREFIX #undef PREFIX
#define PREFIX "DMAR:" #define PREFIX "DMAR:"
@ -263,8 +264,8 @@ parse_dmar_table(void)
if (!dmar) if (!dmar)
return -ENODEV; return -ENODEV;
if (!dmar->width) { if (dmar->width < PAGE_SHIFT_4K - 1) {
printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n"); printk(KERN_WARNING PREFIX "Invalid DMAR haw\n");
return -EINVAL; return -EINVAL;
} }
@ -301,11 +302,24 @@ parse_dmar_table(void)
int __init dmar_table_init(void) int __init dmar_table_init(void)
{ {
parse_dmar_table(); int ret;
ret = parse_dmar_table();
if (ret) {
printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
return ret;
}
if (list_empty(&dmar_drhd_units)) { if (list_empty(&dmar_drhd_units)) {
printk(KERN_INFO PREFIX "No DMAR devices found\n"); printk(KERN_INFO PREFIX "No DMAR devices found\n");
return -ENODEV; return -ENODEV;
} }
if (list_empty(&dmar_rmrr_units)) {
printk(KERN_INFO PREFIX "No RMRR found\n");
return -ENODEV;
}
return 0; return 0;
} }

View file

@ -3,8 +3,8 @@
# #
menuconfig HOTPLUG_PCI menuconfig HOTPLUG_PCI
tristate "Support for PCI Hotplug (EXPERIMENTAL)" tristate "Support for PCI Hotplug"
depends on PCI && EXPERIMENTAL && HOTPLUG depends on PCI && HOTPLUG
---help--- ---help---
Say Y here if you have a motherboard with a PCI Hotplug controller. Say Y here if you have a motherboard with a PCI Hotplug controller.
This allows you to add and remove PCI cards while the machine is This allows you to add and remove PCI cards while the machine is

View file

@ -3,7 +3,6 @@
# #
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
@ -16,6 +15,9 @@ obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o
# Link this last so it doesn't claim devices that have a real hotplug driver
obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
pci_hotplug-objs := pci_hotplug_core.o pci_hotplug-objs := pci_hotplug_core.o
ifdef CONFIG_HOTPLUG_PCI_CPCI ifdef CONFIG_HOTPLUG_PCI_CPCI

View file

@ -113,7 +113,6 @@ struct acpiphp_slot {
u8 device; /* pci device# */ u8 device; /* pci device# */
u32 sun; /* ACPI _SUN (slot unique number) */ u32 sun; /* ACPI _SUN (slot unique number) */
u32 slotno; /* slot number relative to bridge */
u32 flags; /* see below */ u32 flags; /* see below */
}; };

View file

@ -102,7 +102,7 @@ static int is_ejectable(acpi_handle handle)
} }
/* callback routine to check the existence of ejectable slots */ /* callback routine to check for the existence of ejectable slots */
static acpi_status static acpi_status
is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv) is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
@ -117,7 +117,7 @@ is_ejectable_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
} }
} }
/* callback routine to check for the existance of a pci dock device */ /* callback routine to check for the existence of a pci dock device */
static acpi_status static acpi_status
is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
@ -1528,7 +1528,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
dbg("%s: re-enumerating slots under %s\n", dbg("%s: re-enumerating slots under %s\n",
__FUNCTION__, objname); __FUNCTION__, objname);
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
acpiphp_check_bridge(bridge); acpiphp_check_bridge(bridge);
} }
return AE_OK ; return AE_OK ;

View file

@ -39,6 +39,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/workqueue.h>
#include "../pci.h" #include "../pci.h"
#if !defined(MODULE) #if !defined(MODULE)
@ -63,10 +64,16 @@ struct dummy_slot {
struct list_head node; struct list_head node;
struct hotplug_slot *slot; struct hotplug_slot *slot;
struct pci_dev *dev; struct pci_dev *dev;
struct work_struct remove_work;
unsigned long removed;
}; };
static int debug; static int debug;
static LIST_HEAD(slot_list); static LIST_HEAD(slot_list);
static struct workqueue_struct *dummyphp_wq;
static void pci_rescan_worker(struct work_struct *work);
static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
static int enable_slot (struct hotplug_slot *slot); static int enable_slot (struct hotplug_slot *slot);
static int disable_slot (struct hotplug_slot *slot); static int disable_slot (struct hotplug_slot *slot);
@ -109,7 +116,7 @@ static int add_slot(struct pci_dev *dev)
slot->name = &dev->dev.bus_id[0]; slot->name = &dev->dev.bus_id[0];
dbg("slot->name = %s\n", slot->name); dbg("slot->name = %s\n", slot->name);
dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL); dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
if (!dslot) if (!dslot)
goto error_info; goto error_info;
@ -164,6 +171,14 @@ static void remove_slot(struct dummy_slot *dslot)
err("Problem unregistering a slot %s\n", dslot->slot->name); err("Problem unregistering a slot %s\n", dslot->slot->name);
} }
/* called from the single-threaded workqueue handler to remove a slot */
static void remove_slot_worker(struct work_struct *work)
{
struct dummy_slot *dslot =
container_of(work, struct dummy_slot, remove_work);
remove_slot(dslot);
}
/** /**
* pci_rescan_slot - Rescan slot * pci_rescan_slot - Rescan slot
* @temp: Device template. Should be set: bus and devfn. * @temp: Device template. Should be set: bus and devfn.
@ -267,11 +282,17 @@ static inline void pci_rescan(void) {
pci_rescan_buses(&pci_root_buses); pci_rescan_buses(&pci_root_buses);
} }
/* called from the single-threaded workqueue handler to rescan all pci buses */
static void pci_rescan_worker(struct work_struct *work)
{
pci_rescan();
}
static int enable_slot(struct hotplug_slot *hotplug_slot) static int enable_slot(struct hotplug_slot *hotplug_slot)
{ {
/* mis-use enable_slot for rescanning of the pci bus */ /* mis-use enable_slot for rescanning of the pci bus */
pci_rescan(); cancel_work_sync(&pci_rescan_work);
queue_work(dummyphp_wq, &pci_rescan_work);
return -ENODEV; return -ENODEV;
} }
@ -306,6 +327,10 @@ static int disable_slot(struct hotplug_slot *slot)
err("Can't remove PCI devices with other PCI devices behind it yet.\n"); err("Can't remove PCI devices with other PCI devices behind it yet.\n");
return -ENODEV; return -ENODEV;
} }
if (test_and_set_bit(0, &dslot->removed)) {
dbg("Slot already scheduled for removal\n");
return -ENODEV;
}
/* search for subfunctions and disable them first */ /* search for subfunctions and disable them first */
if (!(dslot->dev->devfn & 7)) { if (!(dslot->dev->devfn & 7)) {
for (func = 1; func < 8; func++) { for (func = 1; func < 8; func++) {
@ -328,8 +353,9 @@ static int disable_slot(struct hotplug_slot *slot)
/* remove the device from the pci core */ /* remove the device from the pci core */
pci_remove_bus_device(dslot->dev); pci_remove_bus_device(dslot->dev);
/* blow away this sysfs entry and other parts. */ /* queue work item to blow away this sysfs entry and other parts. */
remove_slot(dslot); INIT_WORK(&dslot->remove_work, remove_slot_worker);
queue_work(dummyphp_wq, &dslot->remove_work);
return 0; return 0;
} }
@ -340,6 +366,7 @@ static void cleanup_slots (void)
struct list_head *next; struct list_head *next;
struct dummy_slot *dslot; struct dummy_slot *dslot;
destroy_workqueue(dummyphp_wq);
list_for_each_safe (tmp, next, &slot_list) { list_for_each_safe (tmp, next, &slot_list) {
dslot = list_entry (tmp, struct dummy_slot, node); dslot = list_entry (tmp, struct dummy_slot, node);
remove_slot(dslot); remove_slot(dslot);
@ -351,6 +378,10 @@ static int __init dummyphp_init(void)
{ {
info(DRIVER_DESC "\n"); info(DRIVER_DESC "\n");
dummyphp_wq = create_singlethread_workqueue(MY_NAME);
if (!dummyphp_wq)
return -ENOMEM;
return pci_scan_buses(); return pci_scan_buses();
} }

View file

@ -761,10 +761,13 @@ static void ibm_unconfigure_device(struct pci_func *func)
debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
for (j = 0; j < 0x08; j++) { for (j = 0; j < 0x08; j++) {
temp = pci_find_slot(func->busno, (func->device << 3) | j); temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
if (temp) if (temp) {
pci_remove_bus_device(temp); pci_remove_bus_device(temp);
pci_dev_put(temp);
}
} }
pci_dev_put(func->dev);
} }
/* /*
@ -823,7 +826,7 @@ static int ibm_configure_device(struct pci_func *func)
if (!(bus_structure_fixup(func->busno))) if (!(bus_structure_fixup(func->busno)))
flag = 1; flag = 1;
if (func->dev == NULL) if (func->dev == NULL)
func->dev = pci_find_slot(func->busno, func->dev = pci_get_bus_and_slot(func->busno,
PCI_DEVFN(func->device, func->function)); PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) { if (func->dev == NULL) {
@ -836,7 +839,7 @@ static int ibm_configure_device(struct pci_func *func)
if (num) if (num)
pci_bus_add_devices(bus); pci_bus_add_devices(bus);
func->dev = pci_find_slot(func->busno, func->dev = pci_get_bus_and_slot(func->busno,
PCI_DEVFN(func->device, func->function)); PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) { if (func->dev == NULL) {
err("ERROR... : pci_dev still NULL\n"); err("ERROR... : pci_dev still NULL\n");

View file

@ -137,7 +137,7 @@ static int get_##name (struct hotplug_slot *slot, type *value) \
int retval = 0; \ int retval = 0; \
if (try_module_get(ops->owner)) { \ if (try_module_get(ops->owner)) { \
if (ops->get_##name) \ if (ops->get_##name) \
retval = ops->get_##name (slot, value); \ retval = ops->get_##name(slot, value); \
else \ else \
*value = slot->info->name; \ *value = slot->info->name; \
module_put(ops->owner); \ module_put(ops->owner); \
@ -625,7 +625,7 @@ int pci_hp_register (struct hotplug_slot *slot)
if ((slot->info == NULL) || (slot->ops == NULL)) if ((slot->info == NULL) || (slot->ops == NULL))
return -EINVAL; return -EINVAL;
if (slot->release == NULL) { if (slot->release == NULL) {
dbg("Why are you trying to register a hotplug slot" dbg("Why are you trying to register a hotplug slot "
"without a proper release function?\n"); "without a proper release function?\n");
return -EINVAL; return -EINVAL;
} }

View file

@ -82,24 +82,18 @@ struct event_info {
}; };
struct controller { struct controller {
struct controller *next;
struct mutex crit_sect; /* critical section mutex */ struct mutex crit_sect; /* critical section mutex */
struct mutex ctrl_lock; /* controller lock */ struct mutex ctrl_lock; /* controller lock */
int num_slots; /* Number of slots on ctlr */ int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */ int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct list_head slot_list; struct list_head slot_list;
struct slot *slot;
struct hpc_ops *hpc_ops; struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */ wait_queue_head_t queue; /* sleep & wake process */
u8 bus;
u8 device;
u8 function;
u8 slot_device_offset; u8 slot_device_offset;
u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
u8 slot_bus; /* Bus where the slots handled by this controller sit */ u8 slot_bus; /* Bus where the slots handled by this controller sit */
u8 ctrlcap; u8 ctrlcap;
u16 vendor_id;
u8 cap_base; u8 cap_base;
struct timer_list poll_timer; struct timer_list poll_timer;
volatile int cmd_busy; volatile int cmd_busy;
@ -161,6 +155,9 @@ extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_unconfigure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void pciehp_queue_pushbutton_work(struct work_struct *work); extern void pciehp_queue_pushbutton_work(struct work_struct *work);
int pcie_init(struct controller *ctrl, struct pcie_device *dev); int pcie_init(struct controller *ctrl, struct pcie_device *dev);
int pciehp_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot);
int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev);
static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
{ {

View file

@ -453,13 +453,9 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
pci_set_drvdata(pdev, ctrl); pci_set_drvdata(pdev, ctrl);
ctrl->bus = pdev->bus->number; /* ctrl bus */ dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ __FUNCTION__, pdev->bus->number, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn), pdev->irq);
ctrl->device = PCI_SLOT(pdev->devfn);
ctrl->function = PCI_FUNC(pdev->devfn);
dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__,
ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
/* Setup the slot information structures */ /* Setup the slot information structures */
rc = init_slots(ctrl); rc = init_slots(ctrl);
@ -471,6 +467,11 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
if (value) {
rc = pciehp_enable_slot(t_slot);
if (rc) /* -ENODEV: shouldn't happen, but deal with it */
value = 0;
}
if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
if (rc) if (rc)
@ -509,6 +510,24 @@ static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
static int pciehp_resume (struct pcie_device *dev) static int pciehp_resume (struct pcie_device *dev)
{ {
printk("%s ENTRY\n", __FUNCTION__); printk("%s ENTRY\n", __FUNCTION__);
if (pciehp_force) {
struct pci_dev *pdev = dev->port;
struct controller *ctrl = pci_get_drvdata(pdev);
struct slot *t_slot;
u8 status;
/* reinitialize the chipset's event detection logic */
pcie_init_hardware_part2(ctrl, dev);
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
/* Check if slot is occupied */
t_slot->hpc_ops->get_adapter_status(t_slot, &status);
if (status)
pciehp_enable_slot(t_slot);
else
pciehp_disable_slot(t_slot);
}
return 0; return 0;
} }
#endif #endif

View file

@ -37,8 +37,6 @@
#include "pciehp.h" #include "pciehp.h"
static void interrupt_event_handler(struct work_struct *work); static void interrupt_event_handler(struct work_struct *work);
static int pciehp_enable_slot(struct slot *p_slot);
static int pciehp_disable_slot(struct slot *p_slot);
static int queue_interrupt_event(struct slot *p_slot, u32 event_type) static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
{ {
@ -197,12 +195,6 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
__FUNCTION__); __FUNCTION__);
return; return;
} }
/*
* After turning power off, we must wait for at least
* 1 second before taking any action that relies on
* power having been removed from the slot/adapter.
*/
msleep(1000);
} }
} }
@ -215,15 +207,12 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
*/ */
static int board_added(struct slot *p_slot) static int board_added(struct slot *p_slot)
{ {
u8 hp_slot;
int retval = 0; int retval = 0;
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
hp_slot = p_slot->device - ctrl->slot_device_offset;
dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n", dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
__FUNCTION__, p_slot->device, __FUNCTION__, p_slot->device,
ctrl->slot_device_offset, hp_slot); ctrl->slot_device_offset, p_slot->hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) { if (POWER_CTRL(ctrl->ctrlcap)) {
/* Power on slot */ /* Power on slot */
@ -281,8 +270,6 @@ static int board_added(struct slot *p_slot)
*/ */
static int remove_board(struct slot *p_slot) static int remove_board(struct slot *p_slot)
{ {
u8 device;
u8 hp_slot;
int retval = 0; int retval = 0;
struct controller *ctrl = p_slot->ctrl; struct controller *ctrl = p_slot->ctrl;
@ -290,11 +277,7 @@ static int remove_board(struct slot *p_slot)
if (retval) if (retval)
return retval; return retval;
device = p_slot->device; dbg("In %s, hp_slot = %d\n", __FUNCTION__, p_slot->hp_slot);
hp_slot = p_slot->device - ctrl->slot_device_offset;
p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) { if (POWER_CTRL(ctrl->ctrlcap)) {
/* power off slot */ /* power off slot */
@ -621,12 +604,6 @@ int pciehp_disable_slot(struct slot *p_slot)
mutex_unlock(&p_slot->ctrl->crit_sect); mutex_unlock(&p_slot->ctrl->crit_sect);
return -EINVAL; return -EINVAL;
} }
/*
* After turning power off, we must wait for at least
* 1 second before taking any action that relies on
* power having been removed from the slot/adapter.
*/
msleep(1000);
} }
ret = remove_board(p_slot); ret = remove_board(p_slot);

View file

@ -636,15 +636,57 @@ static int hpc_power_on_slot(struct slot * slot)
return retval; return retval;
} }
static inline int pcie_mask_bad_dllp(struct controller *ctrl)
{
struct pci_dev *dev = ctrl->pci_dev;
int pos;
u32 reg;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return 0;
pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
if (reg & PCI_ERR_COR_BAD_DLLP)
return 0;
reg |= PCI_ERR_COR_BAD_DLLP;
pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
return 1;
}
static inline void pcie_unmask_bad_dllp(struct controller *ctrl)
{
struct pci_dev *dev = ctrl->pci_dev;
u32 reg;
int pos;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return;
pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
if (!(reg & PCI_ERR_COR_BAD_DLLP))
return;
reg &= ~PCI_ERR_COR_BAD_DLLP;
pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
}
static int hpc_power_off_slot(struct slot * slot) static int hpc_power_off_slot(struct slot * slot)
{ {
struct controller *ctrl = slot->ctrl; struct controller *ctrl = slot->ctrl;
u16 slot_cmd; u16 slot_cmd;
u16 cmd_mask; u16 cmd_mask;
int retval = 0; int retval = 0;
int changed;
dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
/*
* Set Bad DLLP Mask bit in Correctable Error Mask
* Register. This is the workaround against Bad DLLP error
* that sometimes happens during turning power off the slot
* which conforms to PCI Express 1.0a spec.
*/
changed = pcie_mask_bad_dllp(ctrl);
slot_cmd = POWER_OFF; slot_cmd = POWER_OFF;
cmd_mask = PWR_CTRL; cmd_mask = PWR_CTRL;
/* /*
@ -674,6 +716,16 @@ static int hpc_power_off_slot(struct slot * slot)
dbg("%s: SLOTCTRL %x write cmd %x\n", dbg("%s: SLOTCTRL %x write cmd %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
/*
* After turning power off, we must wait for at least 1 second
* before taking any action that relies on power having been
* removed from the slot/adapter.
*/
msleep(1000);
if (changed)
pcie_unmask_bad_dllp(ctrl);
return retval; return retval;
} }
@ -1067,13 +1119,143 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
} }
#endif #endif
int pcie_init(struct controller * ctrl, struct pcie_device *dev) static int pcie_init_hardware_part1(struct controller *ctrl,
struct pcie_device *dev)
{
int rc;
u16 temp_word;
u32 slot_cap;
u16 slot_status;
rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
if (rc) {
err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
return -1;
}
/* Mask Hot-plug Interrupt Enable */
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (rc) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
return -1;
}
dbg("%s: SLOTCTRL %x value read %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) |
0x00;
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
if (rc) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
return -1;
}
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
return -1;
}
temp_word = 0x1F; /* Clear all events */
rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
if (rc) {
err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
return -1;
}
return 0;
}
int pcie_init_hardware_part2(struct controller *ctrl, struct pcie_device *dev)
{ {
int rc; int rc;
u16 temp_word; u16 temp_word;
u16 cap_reg;
u16 intr_enable = 0; u16 intr_enable = 0;
u32 slot_cap; u32 slot_cap;
u16 slot_status;
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (rc) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
goto abort;
}
intr_enable = intr_enable | PRSN_DETECT_ENABLE;
rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
if (rc) {
err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
goto abort;
}
if (ATTN_BUTTN(slot_cap))
intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
if (POWER_CTRL(slot_cap))
intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
if (MRL_SENS(slot_cap))
intr_enable = intr_enable | MRL_DETECT_ENABLE;
temp_word = (temp_word & ~intr_enable) | intr_enable;
if (pciehp_poll_mode) {
temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0;
} else {
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
}
/*
* Unmask Hot-plug Interrupt Enable for the interrupt
* notification mechanism case.
*/
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
if (rc) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
goto abort;
}
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
goto abort_disable_intr;
}
temp_word = 0x1F; /* Clear all events */
rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
if (rc) {
err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
goto abort_disable_intr;
}
if (pciehp_force) {
dbg("Bypassing BIOS check for pciehp use on %s\n",
pci_name(ctrl->pci_dev));
} else {
rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
if (rc)
goto abort_disable_intr;
}
return 0;
/* We end up here for the many possible ways to fail this API. */
abort_disable_intr:
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (!rc) {
temp_word &= ~(intr_enable | HP_INTR_ENABLE);
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
}
if (rc)
err("%s : disabling interrupts failed\n", __FUNCTION__);
abort:
return -1;
}
int pcie_init(struct controller *ctrl, struct pcie_device *dev)
{
int rc;
u16 cap_reg;
u32 slot_cap;
int cap_base; int cap_base;
u16 slot_status, slot_ctrl; u16 slot_status, slot_ctrl;
struct pci_dev *pdev; struct pci_dev *pdev;
@ -1084,9 +1266,10 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
__FUNCTION__, pdev->vendor, pdev->device); __FUNCTION__, pdev->vendor, pdev->device);
if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (cap_base == 0) {
dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
ctrl->cap_base = cap_base; ctrl->cap_base = cap_base;
@ -1096,7 +1279,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
rc = pciehp_readw(ctrl, CAPREG, &cap_reg); rc = pciehp_readw(ctrl, CAPREG, &cap_reg);
if (rc) { if (rc) {
err("%s: Cannot read CAPREG register\n", __FUNCTION__); err("%s: Cannot read CAPREG register\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
dbg("%s: CAPREG offset %x cap_reg %x\n", dbg("%s: CAPREG offset %x cap_reg %x\n",
__FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg);
@ -1106,26 +1289,26 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
&& ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
dbg("%s : This is not a root port or the port is not " dbg("%s : This is not a root port or the port is not "
"connected to a slot\n", __FUNCTION__); "connected to a slot\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
if (rc) { if (rc) {
err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
dbg("%s: SLOTCAP offset %x slot_cap %x\n", dbg("%s: SLOTCAP offset %x slot_cap %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap);
if (!(slot_cap & HP_CAP)) { if (!(slot_cap & HP_CAP)) {
dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
/* For debugging purpose */ /* For debugging purpose */
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) { if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
dbg("%s: SLOTSTATUS offset %x slot_status %x\n", dbg("%s: SLOTSTATUS offset %x slot_status %x\n",
__FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status);
@ -1133,7 +1316,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (rc) { if (rc) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
goto abort_free_ctlr; goto abort;
} }
dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
@ -1161,36 +1344,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
ctrl->first_slot = slot_cap >> 19; ctrl->first_slot = slot_cap >> 19;
ctrl->ctrlcap = slot_cap & 0x0000007f; ctrl->ctrlcap = slot_cap & 0x0000007f;
/* Mask Hot-plug Interrupt Enable */ rc = pcie_init_hardware_part1(ctrl, dev);
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc)
if (rc) { goto abort;
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
goto abort_free_ctlr;
}
dbg("%s: SLOTCTRL %x value read %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) |
0x00;
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
if (rc) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
goto abort_free_ctlr;
}
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
goto abort_free_ctlr;
}
temp_word = 0x1F; /* Clear all events */
rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
if (rc) {
err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
goto abort_free_ctlr;
}
if (pciehp_poll_mode) { if (pciehp_poll_mode) {
/* Install interrupt polling timer. Start with 10 sec delay */ /* Install interrupt polling timer. Start with 10 sec delay */
@ -1206,7 +1362,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
if (rc) { if (rc) {
err("Can't get irq %d for the hotplug controller\n", err("Can't get irq %d for the hotplug controller\n",
ctrl->pci_dev->irq); ctrl->pci_dev->irq);
goto abort_free_ctlr; goto abort;
} }
} }
dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
@ -1224,82 +1380,16 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
} }
} }
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); rc = pcie_init_hardware_part2(ctrl, dev);
if (rc) { if (rc == 0) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); ctrl->hpc_ops = &pciehp_hpc_ops;
goto abort_free_irq; return 0;
} }
intr_enable = intr_enable | PRSN_DETECT_ENABLE;
if (ATTN_BUTTN(slot_cap))
intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
if (POWER_CTRL(slot_cap))
intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
if (MRL_SENS(slot_cap))
intr_enable = intr_enable | MRL_DETECT_ENABLE;
temp_word = (temp_word & ~intr_enable) | intr_enable;
if (pciehp_poll_mode) {
temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0;
} else {
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
}
/*
* Unmask Hot-plug Interrupt Enable for the interrupt
* notification mechanism case.
*/
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
if (rc) {
err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
goto abort_free_irq;
}
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
goto abort_disable_intr;
}
temp_word = 0x1F; /* Clear all events */
rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
if (rc) {
err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
goto abort_disable_intr;
}
if (pciehp_force) {
dbg("Bypassing BIOS check for pciehp use on %s\n",
pci_name(ctrl->pci_dev));
} else {
rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
if (rc)
goto abort_disable_intr;
}
ctrl->hpc_ops = &pciehp_hpc_ops;
return 0;
/* We end up here for the many possible ways to fail this API. */
abort_disable_intr:
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (!rc) {
temp_word &= ~(intr_enable | HP_INTR_ENABLE);
rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
}
if (rc)
err("%s : disabling interrupts failed\n", __FUNCTION__);
abort_free_irq: abort_free_irq:
if (pciehp_poll_mode) if (pciehp_poll_mode)
del_timer_sync(&ctrl->poll_timer); del_timer_sync(&ctrl->poll_timer);
else else
free_irq(ctrl->pci_dev->irq, ctrl); free_irq(ctrl->pci_dev->irq, ctrl);
abort:
abort_free_ctlr:
return -1; return -1;
} }

View file

@ -105,12 +105,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
} }
/* Find Advanced Error Reporting Enhanced Capability */ /* Find Advanced Error Reporting Enhanced Capability */
pos = 256; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
do {
pci_read_config_dword(dev, pos, &reg32);
if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
break;
} while ((pos = PCI_EXT_CAP_NEXT(reg32)));
if (!pos) if (!pos)
return; return;
@ -248,11 +243,15 @@ int pciehp_unconfigure_device(struct slot *p_slot)
u8 bctl = 0; u8 bctl = 0;
u8 presence = 0; u8 presence = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
u16 command;
dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
p_slot->device); p_slot->device);
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence);
if (ret)
presence = 0;
for (j=0; j<8 ; j++) { for (j = 0; j < 8; j++) {
struct pci_dev* temp = pci_get_slot(parent, struct pci_dev* temp = pci_get_slot(parent,
(p_slot->device << 3) | j); (p_slot->device << 3) | j);
if (!temp) if (!temp)
@ -263,21 +262,26 @@ int pciehp_unconfigure_device(struct slot *p_slot)
pci_dev_put(temp); pci_dev_put(temp);
continue; continue;
} }
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot, pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
&presence); if (bctl & PCI_BRIDGE_CTL_VGA) {
if (!ret && presence) { err("Cannot remove display device %s\n",
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, pci_name(temp));
&bctl); pci_dev_put(temp);
if (bctl & PCI_BRIDGE_CTL_VGA) { continue;
err("Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
continue;
}
} }
} }
pci_remove_bus_device(temp); pci_remove_bus_device(temp);
/*
* Ensure that no new Requests will be generated from
* the device.
*/
if (presence) {
pci_read_config_word(temp, PCI_COMMAND, &command);
command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
command |= PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(temp, PCI_COMMAND, command);
}
pci_dev_put(temp); pci_dev_put(temp);
} }
/* /*
@ -288,4 +292,3 @@ int pciehp_unconfigure_device(struct slot *p_slot)
return rc; return rc;
} }

View file

@ -74,7 +74,6 @@ struct slot {
u32 type; u32 type;
u32 power_domain; u32 power_domain;
char *name; char *name;
char *location;
struct device_node *dn; struct device_node *dn;
struct pci_bus *bus; struct pci_bus *bus;
struct list_head *pci_devs; struct list_head *pci_devs;

View file

@ -64,19 +64,6 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state)
return rc; return rc;
} }
static void set_slot_name(struct slot *slot)
{
struct pci_bus *bus = slot->bus;
struct pci_dev *bridge;
bridge = bus->self;
if (bridge)
strcpy(slot->name, pci_name(bridge));
else
sprintf(slot->name, "%04x:%02x:00.0", pci_domain_nr(bus),
bus->number);
}
/** /**
* rpaphp_enable_slot - record slot state, config pci device * rpaphp_enable_slot - record slot state, config pci device
* @slot: target &slot * @slot: target &slot
@ -115,7 +102,6 @@ int rpaphp_enable_slot(struct slot *slot)
info->adapter_status = EMPTY; info->adapter_status = EMPTY;
slot->bus = bus; slot->bus = bus;
slot->pci_devs = &bus->devices; slot->pci_devs = &bus->devices;
set_slot_name(slot);
/* if there's an adapter in the slot, go add the pci devices */ /* if there's an adapter in the slot, go add the pci devices */
if (state == PRESENT) { if (state == PRESENT) {

View file

@ -33,23 +33,31 @@
#include <asm/rtas.h> #include <asm/rtas.h>
#include "rpaphp.h" #include "rpaphp.h"
static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) static ssize_t address_read_file (struct hotplug_slot *php_slot, char *buf)
{ {
char *value; int retval;
int retval = -ENOENT;
struct slot *slot = (struct slot *)php_slot->private; struct slot *slot = (struct slot *)php_slot->private;
struct pci_bus *bus;
if (!slot) if (!slot)
return retval; return -ENOENT;
bus = slot->bus;
if (!bus)
return -ENOENT;
if (bus->self)
retval = sprintf(buf, pci_name(bus->self));
else
retval = sprintf(buf, "%04x:%02x:00.0",
pci_domain_nr(bus), bus->number);
value = slot->location;
retval = sprintf (buf, "%s\n", value);
return retval; return retval;
} }
static struct hotplug_slot_attribute php_attr_location = { static struct hotplug_slot_attribute php_attr_address = {
.attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, .attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
.show = location_read_file, .show = address_read_file,
}; };
/* free up the memory used by a slot */ /* free up the memory used by a slot */
@ -64,7 +72,6 @@ void dealloc_slot_struct(struct slot *slot)
kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->info);
kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot->name);
kfree(slot->hotplug_slot); kfree(slot->hotplug_slot);
kfree(slot->location);
kfree(slot); kfree(slot);
} }
@ -83,16 +90,13 @@ struct slot *alloc_slot_struct(struct device_node *dn,
GFP_KERNEL); GFP_KERNEL);
if (!slot->hotplug_slot->info) if (!slot->hotplug_slot->info)
goto error_hpslot; goto error_hpslot;
slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
if (!slot->hotplug_slot->name) if (!slot->hotplug_slot->name)
goto error_info; goto error_info;
slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
if (!slot->location)
goto error_name;
slot->name = slot->hotplug_slot->name; slot->name = slot->hotplug_slot->name;
strcpy(slot->name, drc_name);
slot->dn = dn; slot->dn = dn;
slot->index = drc_index; slot->index = drc_index;
strcpy(slot->location, drc_name);
slot->power_domain = power_domain; slot->power_domain = power_domain;
slot->hotplug_slot->private = slot; slot->hotplug_slot->private = slot;
slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
@ -100,8 +104,6 @@ struct slot *alloc_slot_struct(struct device_node *dn,
return (slot); return (slot);
error_name:
kfree(slot->hotplug_slot->name);
error_info: error_info:
kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->info);
error_hpslot: error_hpslot:
@ -133,8 +135,8 @@ int rpaphp_deregister_slot(struct slot *slot)
list_del(&slot->rpaphp_slot_list); list_del(&slot->rpaphp_slot_list);
/* remove "phy_location" file */ /* remove "address" file */
sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr); sysfs_remove_file(&php_slot->kobj, &php_attr_address.attr);
retval = pci_hp_deregister(php_slot); retval = pci_hp_deregister(php_slot);
if (retval) if (retval)
@ -166,8 +168,8 @@ int rpaphp_register_slot(struct slot *slot)
return retval; return retval;
} }
/* create "phy_location" file */ /* create "address" file */
retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr); retval = sysfs_create_file(&php_slot->kobj, &php_attr_address.attr);
if (retval) { if (retval) {
err("sysfs_create_file failed with error %d\n", retval); err("sysfs_create_file failed with error %d\n", retval);
goto sysfs_fail; goto sysfs_fail;
@ -175,8 +177,7 @@ int rpaphp_register_slot(struct slot *slot)
/* add slot to our internal list */ /* add slot to our internal list */
list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
info("Slot [%s](PCI location=%s) registered\n", slot->name, info("Slot [%s] registered\n", slot->name);
slot->location);
return 0; return 0;
sysfs_fail: sysfs_fail:

View file

@ -597,7 +597,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
cleanup_slots(ctrl); cleanup_slots(ctrl);
/* /*
* Mask SERR and System Interrut generation * Mask SERR and System Interrupt generation
*/ */
serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE); serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK | serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |

View file

@ -1781,7 +1781,7 @@ __intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
/* /*
* First try to allocate an io virtual address in * First try to allocate an io virtual address in
* DMA_32BIT_MASK and if that fails then try allocating * DMA_32BIT_MASK and if that fails then try allocating
* from higer range * from higher range
*/ */
iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK); iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
if (!iova) if (!iova)

View file

@ -25,6 +25,51 @@
static int pci_msi_enable = 1; static int pci_msi_enable = 1;
/* Arch hooks */
int __attribute__ ((weak))
arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
{
return 0;
}
int __attribute__ ((weak))
arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
{
return 0;
}
int __attribute__ ((weak))
arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
list_for_each_entry(entry, &dev->msi_list, list) {
ret = arch_setup_msi_irq(dev, entry);
if (ret)
return ret;
}
return 0;
}
void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
{
return;
}
void __attribute__ ((weak))
arch_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
list_for_each_entry(entry, &dev->msi_list, list) {
if (entry->irq != 0)
arch_teardown_msi_irq(entry->irq);
}
}
static void msi_set_enable(struct pci_dev *dev, int enable) static void msi_set_enable(struct pci_dev *dev, int enable)
{ {
int pos; int pos;
@ -230,7 +275,6 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable)
pci_intx(dev, enable); pci_intx(dev, enable);
} }
#ifdef CONFIG_PM
static void __pci_restore_msi_state(struct pci_dev *dev) static void __pci_restore_msi_state(struct pci_dev *dev)
{ {
int pos; int pos;
@ -288,7 +332,7 @@ void pci_restore_msi_state(struct pci_dev *dev)
__pci_restore_msi_state(dev); __pci_restore_msi_state(dev);
__pci_restore_msix_state(dev); __pci_restore_msix_state(dev);
} }
#endif /* CONFIG_PM */ EXPORT_SYMBOL_GPL(pci_restore_msi_state);
/** /**
* msi_capability_init - configure device's MSI capability structure * msi_capability_init - configure device's MSI capability structure
@ -683,49 +727,3 @@ void pci_msi_init_pci_dev(struct pci_dev *dev)
{ {
INIT_LIST_HEAD(&dev->msi_list); INIT_LIST_HEAD(&dev->msi_list);
} }
/* Arch hooks */
int __attribute__ ((weak))
arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
{
return 0;
}
int __attribute__ ((weak))
arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
{
return 0;
}
int __attribute__ ((weak))
arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
list_for_each_entry(entry, &dev->msi_list, list) {
ret = arch_setup_msi_irq(dev, entry);
if (ret)
return ret;
}
return 0;
}
void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
{
return;
}
void __attribute__ ((weak))
arch_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
list_for_each_entry(entry, &dev->msi_list, list) {
if (entry->irq != 0)
arch_teardown_msi_irq(entry->irq);
}
}

View file

@ -156,13 +156,13 @@ acpi_run_osc (
} }
/** /**
* pci_osc_support_set - register OS support to Firmware * __pci_osc_support_set - register OS support to Firmware
* @flags: OS support bits * @flags: OS support bits
* *
* Update OS support fields and doing a _OSC Query to obtain an update * Update OS support fields and doing a _OSC Query to obtain an update
* from Firmware on supported control bits. * from Firmware on supported control bits.
**/ **/
acpi_status pci_osc_support_set(u32 flags) acpi_status __pci_osc_support_set(u32 flags, const char *hid)
{ {
u32 temp; u32 temp;
acpi_status retval; acpi_status retval;
@ -176,7 +176,7 @@ acpi_status pci_osc_support_set(u32 flags)
temp = ctrlset_buf[OSC_CONTROL_TYPE]; temp = ctrlset_buf[OSC_CONTROL_TYPE];
ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
acpi_get_devices ( PCI_ROOT_HID_STRING, acpi_get_devices(hid,
acpi_query_osc, acpi_query_osc,
ctrlset_buf, ctrlset_buf,
(void **) &retval ); (void **) &retval );
@ -188,7 +188,6 @@ acpi_status pci_osc_support_set(u32 flags)
} }
return AE_OK; return AE_OK;
} }
EXPORT_SYMBOL(pci_osc_support_set);
/** /**
* pci_osc_control_set - commit requested control to Firmware * pci_osc_control_set - commit requested control to Firmware

View file

@ -186,13 +186,11 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
set_cpus_allowed(current, node_to_cpumask(node)); set_cpus_allowed(current, node_to_cpumask(node));
/* And set default memory allocation policy */ /* And set default memory allocation policy */
oldpol = current->mempolicy; oldpol = current->mempolicy;
current->mempolicy = &default_policy; current->mempolicy = NULL; /* fall back to system default policy */
mpol_get(current->mempolicy);
#endif #endif
error = drv->probe(dev, id); error = drv->probe(dev, id);
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
set_cpus_allowed(current, oldmask); set_cpus_allowed(current, oldmask);
mpol_free(current->mempolicy);
current->mempolicy = oldpol; current->mempolicy = oldpol;
#endif #endif
return error; return error;

View file

@ -21,6 +21,7 @@
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/aspm.h>
#include "pci.h" #include "pci.h"
static int sysfs_initialized; /* = 0 */ static int sysfs_initialized; /* = 0 */
@ -358,7 +359,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct pci_bus *bus = to_pci_bus(container_of(kobj, struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device, struct device,
kobj)); kobj));
/* Only support 1, 2 or 4 byte accesses */ /* Only support 1, 2 or 4 byte accesses */
@ -383,7 +384,7 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct pci_bus *bus = to_pci_bus(container_of(kobj, struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device, struct device,
kobj)); kobj));
/* Only support 1, 2 or 4 byte accesses */ /* Only support 1, 2 or 4 byte accesses */
if (count != 1 && count != 2 && count != 4) if (count != 1 && count != 2 && count != 4)
@ -407,7 +408,7 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma) struct vm_area_struct *vma)
{ {
struct pci_bus *bus = to_pci_bus(container_of(kobj, struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device, struct device,
kobj)); kobj));
return pci_mmap_legacy_page_range(bus, vma); return pci_mmap_legacy_page_range(bus, vma);
@ -650,6 +651,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
if (pcibios_add_platform_entries(pdev)) if (pcibios_add_platform_entries(pdev))
goto err_rom_file; goto err_rom_file;
pcie_aspm_create_sysfs_dev_files(pdev);
return 0; return 0;
err_rom_file: err_rom_file:
@ -679,6 +682,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
if (!sysfs_initialized) if (!sysfs_initialized)
return; return;
pcie_aspm_remove_sysfs_dev_files(pdev);
if (pdev->cfg_size < 4096) if (pdev->cfg_size < 4096)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else else

View file

@ -18,6 +18,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/log2.h> #include <linux/log2.h>
#include <linux/aspm.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */ #include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h" #include "pci.h"
@ -314,6 +315,24 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
} }
EXPORT_SYMBOL_GPL(pci_find_ht_capability); EXPORT_SYMBOL_GPL(pci_find_ht_capability);
void pcie_wait_pending_transaction(struct pci_dev *dev)
{
int pos;
u16 reg16;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return;
while (1) {
pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
if (!(reg16 & PCI_EXP_DEVSTA_TRPND))
break;
cpu_relax();
}
}
EXPORT_SYMBOL_GPL(pcie_wait_pending_transaction);
/** /**
* pci_find_parent_resource - return resource region of parent bus of given region * pci_find_parent_resource - return resource region of parent bus of given region
* @dev: PCI device structure contains resources to be searched * @dev: PCI device structure contains resources to be searched
@ -353,7 +372,7 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
* Restore the BAR values for a given device, so as to make it * Restore the BAR values for a given device, so as to make it
* accessible by its driver. * accessible by its driver.
*/ */
void static void
pci_restore_bars(struct pci_dev *dev) pci_restore_bars(struct pci_dev *dev)
{ {
int i, numres; int i, numres;
@ -501,6 +520,9 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (need_restore) if (need_restore)
pci_restore_bars(dev); pci_restore_bars(dev);
if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0; return 0;
} }
@ -551,6 +573,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
int pos, i = 0; int pos, i = 0;
struct pci_cap_saved_state *save_state; struct pci_cap_saved_state *save_state;
u16 *cap; u16 *cap;
int found = 0;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP); pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (pos <= 0) if (pos <= 0)
@ -559,6 +582,8 @@ static int pci_save_pcie_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) if (!save_state)
save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL);
else
found = 1;
if (!save_state) { if (!save_state) {
dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
return -ENOMEM; return -ENOMEM;
@ -569,7 +594,9 @@ static int pci_save_pcie_state(struct pci_dev *dev)
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
pci_add_saved_cap(dev, save_state); save_state->cap_nr = PCI_CAP_ID_EXP;
if (!found)
pci_add_saved_cap(dev, save_state);
return 0; return 0;
} }
@ -597,14 +624,17 @@ static int pci_save_pcix_state(struct pci_dev *dev)
int pos, i = 0; int pos, i = 0;
struct pci_cap_saved_state *save_state; struct pci_cap_saved_state *save_state;
u16 *cap; u16 *cap;
int found = 0;
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (pos <= 0) if (pos <= 0)
return 0; return 0;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
if (!save_state) if (!save_state)
save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL);
else
found = 1;
if (!save_state) { if (!save_state) {
dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
return -ENOMEM; return -ENOMEM;
@ -612,7 +642,9 @@ static int pci_save_pcix_state(struct pci_dev *dev)
cap = (u16 *)&save_state->data[0]; cap = (u16 *)&save_state->data[0];
pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]); pci_read_config_word(dev, pos + PCI_X_CMD, &cap[i++]);
pci_add_saved_cap(dev, save_state); save_state->cap_nr = PCI_CAP_ID_PCIX;
if (!found)
pci_add_saved_cap(dev, save_state);
return 0; return 0;
} }
@ -713,29 +745,51 @@ int pci_reenable_device(struct pci_dev *dev)
return 0; return 0;
} }
/** static int __pci_enable_device_flags(struct pci_dev *dev,
* pci_enable_device_bars - Initialize some of a device for use resource_size_t flags)
* @dev: PCI device to be initialized
* @bars: bitmask of BAR's that must be configured
*
* Initialize device before it's used by a driver. Ask low-level code
* to enable selected I/O and memory resources. Wake up the device if it
* was suspended. Beware, this function can fail.
*/
int
pci_enable_device_bars(struct pci_dev *dev, int bars)
{ {
int err; int err;
int i, bars = 0;
if (atomic_add_return(1, &dev->enable_cnt) > 1) if (atomic_add_return(1, &dev->enable_cnt) > 1)
return 0; /* already enabled */ return 0; /* already enabled */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
if (dev->resource[i].flags & flags)
bars |= (1 << i);
err = do_pci_enable_device(dev, bars); err = do_pci_enable_device(dev, bars);
if (err < 0) if (err < 0)
atomic_dec(&dev->enable_cnt); atomic_dec(&dev->enable_cnt);
return err; return err;
} }
/**
* pci_enable_device_io - Initialize a device for use with IO space
* @dev: PCI device to be initialized
*
* Initialize device before it's used by a driver. Ask low-level code
* to enable I/O resources. Wake up the device if it was suspended.
* Beware, this function can fail.
*/
int pci_enable_device_io(struct pci_dev *dev)
{
return __pci_enable_device_flags(dev, IORESOURCE_IO);
}
/**
* pci_enable_device_mem - Initialize a device for use with Memory space
* @dev: PCI device to be initialized
*
* Initialize device before it's used by a driver. Ask low-level code
* to enable Memory resources. Wake up the device if it was suspended.
* Beware, this function can fail.
*/
int pci_enable_device_mem(struct pci_dev *dev)
{
return __pci_enable_device_flags(dev, IORESOURCE_MEM);
}
/** /**
* pci_enable_device - Initialize device before it's used by a driver. * pci_enable_device - Initialize device before it's used by a driver.
* @dev: PCI device to be initialized * @dev: PCI device to be initialized
@ -749,7 +803,7 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
*/ */
int pci_enable_device(struct pci_dev *dev) int pci_enable_device(struct pci_dev *dev)
{ {
return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO);
} }
/* /*
@ -885,6 +939,9 @@ pci_disable_device(struct pci_dev *dev)
if (atomic_sub_return(1, &dev->enable_cnt) != 0) if (atomic_sub_return(1, &dev->enable_cnt) != 0)
return; return;
/* Wait for all transactions are finished before disabling the device */
pcie_wait_pending_transaction(dev);
pci_read_config_word(dev, PCI_COMMAND, &pci_command); pci_read_config_word(dev, PCI_COMMAND, &pci_command);
if (pci_command & PCI_COMMAND_MASTER) { if (pci_command & PCI_COMMAND_MASTER) {
pci_command &= ~PCI_COMMAND_MASTER; pci_command &= ~PCI_COMMAND_MASTER;
@ -1619,9 +1676,9 @@ early_param("pci", pci_setup);
device_initcall(pci_init); device_initcall(pci_init);
EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(pci_reenable_device); EXPORT_SYMBOL(pci_reenable_device);
EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device_io);
EXPORT_SYMBOL(pci_enable_device_mem);
EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pcim_enable_device); EXPORT_SYMBOL(pcim_enable_device);
EXPORT_SYMBOL(pcim_pin_device); EXPORT_SYMBOL(pcim_pin_device);

View file

@ -6,8 +6,10 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev); extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */ /* Firmware callbacks */
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev,
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); pm_message_t state);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev,
pci_power_t state);
extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
@ -45,12 +47,6 @@ static inline void pci_no_msi(void) { }
static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
#endif #endif
#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
void pci_restore_msi_state(struct pci_dev *dev);
#else
static inline void pci_restore_msi_state(struct pci_dev *dev) {}
#endif
#ifdef CONFIG_PCIEAER #ifdef CONFIG_PCIEAER
void pci_no_aer(void); void pci_no_aer(void);
#else #else
@ -68,14 +64,14 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
} }
extern int pcie_mch_quirk; extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[]; extern struct device_attribute pci_dev_attrs[];
extern struct class_device_attribute class_device_attr_cpuaffinity; extern struct device_attribute dev_attr_cpuaffinity;
/** /**
* pci_match_one_device - Tell if a PCI device structure has a matching * pci_match_one_device - Tell if a PCI device structure has a matching
* PCI device id structure * PCI device id structure
* @id: single PCI device id structure to match * @id: single PCI device id structure to match
* @dev: the PCI device structure to match against * @dev: the PCI device structure to match against
* *
* Returns the matching pci_device_id structure or %NULL if there is no match. * Returns the matching pci_device_id structure or %NULL if there is no match.
*/ */
static inline const struct pci_device_id * static inline const struct pci_device_id *

View file

@ -26,3 +26,23 @@ config HOTPLUG_PCI_PCIE
When in doubt, say N. When in doubt, say N.
source "drivers/pci/pcie/aer/Kconfig" source "drivers/pci/pcie/aer/Kconfig"
#
# PCI Express ASPM
#
config PCIEASPM
bool "PCI Express ASPM support(Experimental)"
depends on PCI && EXPERIMENTAL
default y
help
This enables PCI Express ASPM (Active State Power Management) and
Clock Power Management. ASPM supports state L0/L0s/L1.
When in doubt, say N.
config PCIEASPM_DEBUG
bool "Debug PCI Express ASPM"
depends on PCIEASPM
default n
help
This enables PCI Express ASPM debug support. It will add per-device
interface to control ASPM.

View file

@ -2,6 +2,9 @@
# Makefile for PCI-Express PORT Driver # Makefile for PCI-Express PORT Driver
# #
# Build PCI Express ASPM if needed
obj-$(CONFIG_PCIEASPM) += aspm.o
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o

View file

@ -31,26 +31,16 @@ int aer_osc_setup(struct pcie_device *pciedev)
{ {
acpi_status status = AE_NOT_FOUND; acpi_status status = AE_NOT_FOUND;
struct pci_dev *pdev = pciedev->port; struct pci_dev *pdev = pciedev->port;
acpi_handle handle = DEVICE_ACPI_HANDLE(&pdev->dev); acpi_handle handle = 0;
struct pci_bus *parent;
while (!handle) { /* Find root host bridge */
if (!pdev || !pdev->bus->parent) while (pdev->bus && pdev->bus->self)
break; pdev = pdev->bus->self;
parent = pdev->bus->parent; handle = acpi_get_pci_rootbridge_handle(
if (!parent->self) pci_domain_nr(pdev->bus), pdev->bus->number);
/* Parent must be a host bridge */
handle = acpi_get_pci_rootbridge_handle(
pci_domain_nr(parent),
parent->number);
else
handle = DEVICE_ACPI_HANDLE(
&(parent->self->dev));
pdev = parent->self;
}
if (handle) { if (handle) {
pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
status = pci_osc_control_set(handle, status = pci_osc_control_set(handle,
OSC_PCI_EXPRESS_AER_CONTROL | OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);

802
drivers/pci/pcie/aspm.c Normal file
View file

@ -0,0 +1,802 @@
/*
* File: drivers/pci/pcie/aspm.c
* Enabling PCIE link L0s/L1 state and Clock Power Management
*
* Copyright (C) 2007 Intel
* Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com)
* Copyright (C) Shaohua Li (shaohua.li@intel.com)
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/aspm.h>
#include <acpi/acpi_bus.h>
#include <linux/pci-acpi.h>
#include "../pci.h"
#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX "pcie_aspm."
struct endpoint_state {
unsigned int l0s_acceptable_latency;
unsigned int l1_acceptable_latency;
};
struct pcie_link_state {
struct list_head sibiling;
struct pci_dev *pdev;
/* ASPM state */
unsigned int support_state;
unsigned int enabled_state;
unsigned int bios_aspm_state;
/* upstream component */
unsigned int l0s_upper_latency;
unsigned int l1_upper_latency;
/* downstream component */
unsigned int l0s_down_latency;
unsigned int l1_down_latency;
/* Clock PM state*/
unsigned int clk_pm_capable;
unsigned int clk_pm_enabled;
unsigned int bios_clk_state;
/*
* A pcie downstream port only has one slot under it, so at most there
* are 8 functions
*/
struct endpoint_state endpoints[8];
};
static int aspm_disabled;
static DEFINE_MUTEX(aspm_lock);
static LIST_HEAD(link_list);
#define POLICY_DEFAULT 0 /* BIOS default setting */
#define POLICY_PERFORMANCE 1 /* high performance */
#define POLICY_POWERSAVE 2 /* high power saving */
static int aspm_policy;
static const char *policy_str[] = {
[POLICY_DEFAULT] = "default",
[POLICY_PERFORMANCE] = "performance",
[POLICY_POWERSAVE] = "powersave"
};
static int policy_to_aspm_state(struct pci_dev *pdev)
{
struct pcie_link_state *link_state = pdev->link_state;
switch (aspm_policy) {
case POLICY_PERFORMANCE:
/* Disable ASPM and Clock PM */
return 0;
case POLICY_POWERSAVE:
/* Enable ASPM L0s/L1 */
return PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
case POLICY_DEFAULT:
return link_state->bios_aspm_state;
}
return 0;
}
static int policy_to_clkpm_state(struct pci_dev *pdev)
{
struct pcie_link_state *link_state = pdev->link_state;
switch (aspm_policy) {
case POLICY_PERFORMANCE:
/* Disable ASPM and Clock PM */
return 0;
case POLICY_POWERSAVE:
/* Disable Clock PM */
return 1;
case POLICY_DEFAULT:
return link_state->bios_clk_state;
}
return 0;
}
static void pcie_set_clock_pm(struct pci_dev *pdev, int enable)
{
struct pci_dev *child_dev;
int pos;
u16 reg16;
struct pcie_link_state *link_state = pdev->link_state;
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
if (!pos)
return;
pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16);
if (enable)
reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
else
reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
pci_write_config_word(child_dev, pos + PCI_EXP_LNKCTL, reg16);
}
link_state->clk_pm_enabled = !!enable;
}
static void pcie_check_clock_pm(struct pci_dev *pdev)
{
int pos;
u32 reg32;
u16 reg16;
int capable = 1, enabled = 1;
struct pci_dev *child_dev;
struct pcie_link_state *link_state = pdev->link_state;
/* All functions should have the same cap and state, take the worst */
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
if (!pos)
return;
pci_read_config_dword(child_dev, pos + PCI_EXP_LNKCAP, &reg32);
if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
capable = 0;
enabled = 0;
break;
}
pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16);
if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
enabled = 0;
}
link_state->clk_pm_capable = capable;
link_state->clk_pm_enabled = enabled;
link_state->bios_clk_state = enabled;
pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev));
}
/*
* pcie_aspm_configure_common_clock: check if the 2 ends of a link
* could use common clock. If they are, configure them to use the
* common clock. That will reduce the ASPM state exit latency.
*/
static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
{
int pos, child_pos;
u16 reg16 = 0;
struct pci_dev *child_dev;
int same_clock = 1;
/*
* all functions of a slot should have the same Slot Clock
* Configuration, so just check one function
* */
child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev,
bus_list);
BUG_ON(!child_dev->is_pcie);
/* Check downstream component if bit Slot Clock Configuration is 1 */
child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;
/* Check upstream component if bit Slot Clock Configuration is 1 */
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_SLC))
same_clock = 0;
/* Configure downstream component, all functions */
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
&reg16);
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
reg16);
}
/* Configure upstream component */
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
/* retrain link */
reg16 |= PCI_EXP_LNKCTL_RL;
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
/* Wait for link training end */
while (1) {
pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_LT))
break;
cpu_relax();
}
}
/*
* calc_L0S_latency: Convert L0s latency encoding to ns
*/
static unsigned int calc_L0S_latency(unsigned int latency_encoding, int ac)
{
unsigned int ns = 64;
if (latency_encoding == 0x7) {
if (ac)
ns = -1U;
else
ns = 5*1000; /* > 4us */
} else
ns *= (1 << latency_encoding);
return ns;
}
/*
* calc_L1_latency: Convert L1 latency encoding to ns
*/
static unsigned int calc_L1_latency(unsigned int latency_encoding, int ac)
{
unsigned int ns = 1000;
if (latency_encoding == 0x7) {
if (ac)
ns = -1U;
else
ns = 65*1000; /* > 64us */
} else
ns *= (1 << latency_encoding);
return ns;
}
static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
unsigned int *l0s, unsigned int *l1, unsigned int *enabled)
{
int pos;
u16 reg16;
u32 reg32;
unsigned int latency;
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
*state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
if (*state != PCIE_LINK_STATE_L0S &&
*state != (PCIE_LINK_STATE_L1|PCIE_LINK_STATE_L0S))
* state = 0;
if (*state == 0)
return;
latency = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
*l0s = calc_L0S_latency(latency, 0);
if (*state & PCIE_LINK_STATE_L1) {
latency = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
*l1 = calc_L1_latency(latency, 0);
}
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
*enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1);
}
static void pcie_aspm_cap_init(struct pci_dev *pdev)
{
struct pci_dev *child_dev;
u32 state, tmp;
struct pcie_link_state *link_state = pdev->link_state;
/* upstream component states */
pcie_aspm_get_cap_device(pdev, &link_state->support_state,
&link_state->l0s_upper_latency,
&link_state->l1_upper_latency,
&link_state->enabled_state);
/* downstream component states, all functions have the same setting */
child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev,
bus_list);
pcie_aspm_get_cap_device(child_dev, &state,
&link_state->l0s_down_latency,
&link_state->l1_down_latency,
&tmp);
link_state->support_state &= state;
if (!link_state->support_state)
return;
link_state->enabled_state &= link_state->support_state;
link_state->bios_aspm_state = link_state->enabled_state;
/* ENDPOINT states*/
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
int pos;
u32 reg32;
unsigned int latency;
struct endpoint_state *ep_state =
&link_state->endpoints[PCI_FUNC(child_dev->devfn)];
if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)
continue;
pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32);
latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
latency = calc_L0S_latency(latency, 1);
ep_state->l0s_acceptable_latency = latency;
if (link_state->support_state & PCIE_LINK_STATE_L1) {
latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
latency = calc_L1_latency(latency, 1);
ep_state->l1_acceptable_latency = latency;
}
}
}
static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
unsigned int state)
{
struct pci_dev *parent_dev, *tmp_dev;
unsigned int latency, l1_latency = 0;
struct pcie_link_state *link_state;
struct endpoint_state *ep_state;
parent_dev = pdev->bus->self;
link_state = parent_dev->link_state;
state &= link_state->support_state;
if (state == 0)
return 0;
ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)];
/*
* Check latency for endpoint device.
* TBD: The latency from the endpoint to root complex vary per
* switch's upstream link state above the device. Here we just do a
* simple check which assumes all links above the device can be in L1
* state, that is we just consider the worst case. If switch's upstream
* link can't be put into L0S/L1, then our check is too strictly.
*/
tmp_dev = pdev;
while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
parent_dev = tmp_dev->bus->self;
link_state = parent_dev->link_state;
if (state & PCIE_LINK_STATE_L0S) {
latency = max_t(unsigned int,
link_state->l0s_upper_latency,
link_state->l0s_down_latency);
if (latency > ep_state->l0s_acceptable_latency)
state &= ~PCIE_LINK_STATE_L0S;
}
if (state & PCIE_LINK_STATE_L1) {
latency = max_t(unsigned int,
link_state->l1_upper_latency,
link_state->l1_down_latency);
if (latency + l1_latency >
ep_state->l1_acceptable_latency)
state &= ~PCIE_LINK_STATE_L1;
}
if (!parent_dev->bus->self) /* parent_dev is a root port */
break;
else {
/*
* parent_dev is the downstream port of a switch, make
* tmp_dev the upstream port of the switch
*/
tmp_dev = parent_dev->bus->self;
/*
* every switch on the path to root complex need 1 more
* microsecond for L1. Spec doesn't mention L0S.
*/
if (state & PCIE_LINK_STATE_L1)
l1_latency += 1000;
}
}
return state;
}
static unsigned int pcie_aspm_check_state(struct pci_dev *pdev,
unsigned int state)
{
struct pci_dev *child_dev;
/* If no child, disable the link */
if (list_empty(&pdev->subordinate->devices))
return 0;
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
/*
* If downstream component of a link is pci bridge, we
* disable ASPM for now for the link
* */
state = 0;
break;
}
if ((child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
child_dev->pcie_type != PCI_EXP_TYPE_LEG_END))
continue;
/* Device not in D0 doesn't need check latency */
if (child_dev->current_state == PCI_D1 ||
child_dev->current_state == PCI_D2 ||
child_dev->current_state == PCI_D3hot ||
child_dev->current_state == PCI_D3cold)
continue;
state = __pcie_aspm_check_state_one(child_dev, state);
}
return state;
}
static void __pcie_aspm_config_one_dev(struct pci_dev *pdev, unsigned int state)
{
u16 reg16;
int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
reg16 &= ~0x3;
reg16 |= state;
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
}
static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state)
{
struct pci_dev *child_dev;
int valid = 1;
struct pcie_link_state *link_state = pdev->link_state;
/*
* if the downstream component has pci bridge function, don't do ASPM
* now
*/
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
valid = 0;
break;
}
}
if (!valid)
return;
/*
* spec 2.0 suggests all functions should be configured the same
* setting for ASPM. Enabling ASPM L1 should be done in upstream
* component first and then downstream, and vice versa for disabling
* ASPM L1. Spec doesn't mention L0S.
*/
if (state & PCIE_LINK_STATE_L1)
__pcie_aspm_config_one_dev(pdev, state);
list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list)
__pcie_aspm_config_one_dev(child_dev, state);
if (!(state & PCIE_LINK_STATE_L1))
__pcie_aspm_config_one_dev(pdev, state);
link_state->enabled_state = state;
}
static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
unsigned int state)
{
struct pcie_link_state *link_state = pdev->link_state;
if (link_state->support_state == 0)
return;
state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
/* state 0 means disabling aspm */
state = pcie_aspm_check_state(pdev, state);
if (link_state->enabled_state == state)
return;
__pcie_aspm_config_link(pdev, state);
}
/*
* pcie_aspm_configure_link_state: enable/disable PCI express link state
* @pdev: the root port or switch downstream port
*/
static void pcie_aspm_configure_link_state(struct pci_dev *pdev,
unsigned int state)
{
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
__pcie_aspm_configure_link_state(pdev, state);
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
}
static void free_link_state(struct pci_dev *pdev)
{
kfree(pdev->link_state);
pdev->link_state = NULL;
}
/*
* pcie_aspm_init_link_state: Initiate PCI express link state.
* It is called after the pcie and its children devices are scaned.
* @pdev: the root port or switch downstream port
*/
void pcie_aspm_init_link_state(struct pci_dev *pdev)
{
unsigned int state;
struct pcie_link_state *link_state;
int error = 0;
if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
return;
if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
return;
down_read(&pci_bus_sem);
if (list_empty(&pdev->subordinate->devices))
goto out;
mutex_lock(&aspm_lock);
link_state = kzalloc(sizeof(*link_state), GFP_KERNEL);
if (!link_state)
goto unlock_out;
pdev->link_state = link_state;
pcie_aspm_configure_common_clock(pdev);
pcie_aspm_cap_init(pdev);
/* config link state to avoid BIOS error */
state = pcie_aspm_check_state(pdev, policy_to_aspm_state(pdev));
__pcie_aspm_config_link(pdev, state);
pcie_check_clock_pm(pdev);
link_state->pdev = pdev;
list_add(&link_state->sibiling, &link_list);
unlock_out:
if (error)
free_link_state(pdev);
mutex_unlock(&aspm_lock);
out:
up_read(&pci_bus_sem);
}
/* @pdev: the endpoint device */
void pcie_aspm_exit_link_state(struct pci_dev *pdev)
{
struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link_state = parent->link_state;
if (aspm_disabled || !pdev->is_pcie || !parent || !link_state)
return;
if (parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
return;
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
/*
* All PCIe functions are in one slot, remove one function will remove
* the the whole slot, so just wait
*/
if (!list_empty(&parent->subordinate->devices))
goto out;
/* All functions are removed, so just disable ASPM for the link */
__pcie_aspm_config_one_dev(parent, 0);
list_del(&link_state->sibiling);
/* Clock PM is for endpoint device */
free_link_state(parent);
out:
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
}
/* @pdev: the root port or switch downstream port */
void pcie_aspm_pm_state_change(struct pci_dev *pdev)
{
struct pcie_link_state *link_state = pdev->link_state;
if (aspm_disabled || !pdev->is_pcie || !pdev->link_state)
return;
if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
return;
/*
* devices changed PM state, we should recheck if latency meets all
* functions' requirement
*/
pcie_aspm_configure_link_state(pdev, link_state->enabled_state);
}
/*
* pci_disable_link_state - disable pci device's link state, so the link will
* never enter specific states
*/
void pci_disable_link_state(struct pci_dev *pdev, int state)
{
struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link_state;
if (aspm_disabled || !pdev->is_pcie)
return;
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
parent = pdev;
if (!parent)
return;
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
link_state = parent->link_state;
link_state->support_state &=
~(state & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1));
if (state & PCIE_LINK_STATE_CLKPM)
link_state->clk_pm_capable = 0;
__pcie_aspm_configure_link_state(parent, link_state->enabled_state);
if (!link_state->clk_pm_capable && link_state->clk_pm_enabled)
pcie_set_clock_pm(parent, 0);
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
}
EXPORT_SYMBOL(pci_disable_link_state);
static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
{
int i;
struct pci_dev *pdev;
struct pcie_link_state *link_state;
for (i = 0; i < ARRAY_SIZE(policy_str); i++)
if (!strncmp(val, policy_str[i], strlen(policy_str[i])))
break;
if (i >= ARRAY_SIZE(policy_str))
return -EINVAL;
if (i == aspm_policy)
return 0;
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
aspm_policy = i;
list_for_each_entry(link_state, &link_list, sibiling) {
pdev = link_state->pdev;
__pcie_aspm_configure_link_state(pdev,
policy_to_aspm_state(pdev));
if (link_state->clk_pm_capable &&
link_state->clk_pm_enabled != policy_to_clkpm_state(pdev))
pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev));
}
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
return 0;
}
static int pcie_aspm_get_policy(char *buffer, struct kernel_param *kp)
{
int i, cnt = 0;
for (i = 0; i < ARRAY_SIZE(policy_str); i++)
if (i == aspm_policy)
cnt += sprintf(buffer + cnt, "[%s] ", policy_str[i]);
else
cnt += sprintf(buffer + cnt, "%s ", policy_str[i]);
return cnt;
}
module_param_call(policy, pcie_aspm_set_policy, pcie_aspm_get_policy,
NULL, 0644);
#ifdef CONFIG_PCIEASPM_DEBUG
static ssize_t link_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct pci_dev *pci_device = to_pci_dev(dev);
struct pcie_link_state *link_state = pci_device->link_state;
return sprintf(buf, "%d\n", link_state->enabled_state);
}
static ssize_t link_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t n)
{
struct pci_dev *pci_device = to_pci_dev(dev);
int state;
if (n < 1)
return -EINVAL;
state = buf[0]-'0';
if (state >= 0 && state <= 3) {
/* setup link aspm state */
pcie_aspm_configure_link_state(pci_device, state);
return n;
}
return -EINVAL;
}
static ssize_t clk_ctl_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct pci_dev *pci_device = to_pci_dev(dev);
struct pcie_link_state *link_state = pci_device->link_state;
return sprintf(buf, "%d\n", link_state->clk_pm_enabled);
}
static ssize_t clk_ctl_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t n)
{
struct pci_dev *pci_device = to_pci_dev(dev);
int state;
if (n < 1)
return -EINVAL;
state = buf[0]-'0';
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
pcie_set_clock_pm(pci_device, !!state);
mutex_unlock(&aspm_lock);
up_read(&pci_bus_sem);
return n;
}
static DEVICE_ATTR(link_state, 0644, link_state_show, link_state_store);
static DEVICE_ATTR(clk_ctl, 0644, clk_ctl_show, clk_ctl_store);
static char power_group[] = "power";
void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
{
struct pcie_link_state *link_state = pdev->link_state;
if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
return;
if (link_state->support_state)
sysfs_add_file_to_group(&pdev->dev.kobj,
&dev_attr_link_state.attr, power_group);
if (link_state->clk_pm_capable)
sysfs_add_file_to_group(&pdev->dev.kobj,
&dev_attr_clk_ctl.attr, power_group);
}
void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
{
struct pcie_link_state *link_state = pdev->link_state;
if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
return;
if (link_state->support_state)
sysfs_remove_file_from_group(&pdev->dev.kobj,
&dev_attr_link_state.attr, power_group);
if (link_state->clk_pm_capable)
sysfs_remove_file_from_group(&pdev->dev.kobj,
&dev_attr_clk_ctl.attr, power_group);
}
#endif
static int __init pcie_aspm_disable(char *str)
{
aspm_disabled = 1;
return 1;
}
__setup("pcie_noaspm", pcie_aspm_disable);
static int __init pcie_aspm_init(void)
{
if (aspm_disabled)
return 0;
pci_osc_support_set(OSC_ACTIVE_STATE_PWR_SUPPORT|
OSC_CLOCK_PWR_CAPABILITY_SUPPORT);
return 0;
}
fs_initcall(pcie_aspm_init);

View file

@ -192,9 +192,8 @@ static int get_port_device_capability(struct pci_dev *dev)
if (reg32 & SLOT_HP_CAPABLE_MASK) if (reg32 & SLOT_HP_CAPABLE_MASK)
services |= PCIE_PORT_SERVICE_HP; services |= PCIE_PORT_SERVICE_HP;
} }
/* PME Capable */ /* PME Capable - root port capability */
pos = pci_find_capability(dev, PCI_CAP_ID_PME); if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
if (pos)
services |= PCIE_PORT_SERVICE_PME; services |= PCIE_PORT_SERVICE_PME;
pos = PCI_CFG_SPACE_SIZE; pos = PCI_CFG_SPACE_SIZE;

View file

@ -9,6 +9,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/aspm.h>
#include "pci.h" #include "pci.h"
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
@ -53,7 +54,7 @@ static void pci_create_legacy_files(struct pci_bus *b)
b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_io->read = pci_read_legacy_io; b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io; b->legacy_io->write = pci_write_legacy_io;
class_device_create_bin_file(&b->class_dev, b->legacy_io); device_create_bin_file(&b->dev, b->legacy_io);
/* Allocated above after the legacy_io struct */ /* Allocated above after the legacy_io struct */
b->legacy_mem = b->legacy_io + 1; b->legacy_mem = b->legacy_io + 1;
@ -61,15 +62,15 @@ static void pci_create_legacy_files(struct pci_bus *b)
b->legacy_mem->size = 1024*1024; b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem; b->legacy_mem->mmap = pci_mmap_legacy_mem;
class_device_create_bin_file(&b->class_dev, b->legacy_mem); device_create_bin_file(&b->dev, b->legacy_mem);
} }
} }
void pci_remove_legacy_files(struct pci_bus *b) void pci_remove_legacy_files(struct pci_bus *b)
{ {
if (b->legacy_io) { if (b->legacy_io) {
class_device_remove_bin_file(&b->class_dev, b->legacy_io); device_remove_bin_file(&b->dev, b->legacy_io);
class_device_remove_bin_file(&b->class_dev, b->legacy_mem); device_remove_bin_file(&b->dev, b->legacy_mem);
kfree(b->legacy_io); /* both are allocated here */ kfree(b->legacy_io); /* both are allocated here */
} }
} }
@ -81,26 +82,27 @@ void pci_remove_legacy_files(struct pci_bus *bus) { return; }
/* /*
* PCI Bus Class Devices * PCI Bus Class Devices
*/ */
static ssize_t pci_bus_show_cpuaffinity(struct class_device *class_dev, static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
struct device_attribute *attr,
char *buf) char *buf)
{ {
int ret; int ret;
cpumask_t cpumask; cpumask_t cpumask;
cpumask = pcibus_to_cpumask(to_pci_bus(class_dev)); cpumask = pcibus_to_cpumask(to_pci_bus(dev));
ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask); ret = cpumask_scnprintf(buf, PAGE_SIZE, cpumask);
if (ret < PAGE_SIZE) if (ret < PAGE_SIZE)
buf[ret++] = '\n'; buf[ret++] = '\n';
return ret; return ret;
} }
CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL); DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
/* /*
* PCI Bus Class * PCI Bus Class
*/ */
static void release_pcibus_dev(struct class_device *class_dev) static void release_pcibus_dev(struct device *dev)
{ {
struct pci_bus *pci_bus = to_pci_bus(class_dev); struct pci_bus *pci_bus = to_pci_bus(dev);
if (pci_bus->bridge) if (pci_bus->bridge)
put_device(pci_bus->bridge); put_device(pci_bus->bridge);
@ -109,7 +111,7 @@ static void release_pcibus_dev(struct class_device *class_dev)
static struct class pcibus_class = { static struct class pcibus_class = {
.name = "pci_bus", .name = "pci_bus",
.release = &release_pcibus_dev, .dev_release = &release_pcibus_dev,
}; };
static int __init pcibus_class_init(void) static int __init pcibus_class_init(void)
@ -392,7 +394,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
{ {
struct pci_bus *child; struct pci_bus *child;
int i; int i;
int retval;
/* /*
* Allocate a new bus, and inherit stuff from the parent.. * Allocate a new bus, and inherit stuff from the parent..
@ -408,15 +409,12 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
child->bus_flags = parent->bus_flags; child->bus_flags = parent->bus_flags;
child->bridge = get_device(&bridge->dev); child->bridge = get_device(&bridge->dev);
child->class_dev.class = &pcibus_class; /* initialize some portions of the bus device, but don't register it
sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr); * now as the parent is not properly set up yet. This device will get
retval = class_device_register(&child->class_dev); * registered later in pci_bus_add_devices()
if (retval) */
goto error_register; child->dev.class = &pcibus_class;
retval = class_device_create_file(&child->class_dev, sprintf(child->dev.bus_id, "%04x:%02x", pci_domain_nr(child), busnr);
&class_device_attr_cpuaffinity);
if (retval)
goto error_file_create;
/* /*
* Set up the primary, secondary and subordinate * Set up the primary, secondary and subordinate
@ -434,12 +432,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
bridge->subordinate = child; bridge->subordinate = child;
return child; return child;
error_file_create:
class_device_unregister(&child->class_dev);
error_register:
kfree(child);
return NULL;
} }
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr)
@ -471,8 +463,6 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
} }
} }
unsigned int pci_scan_child_bus(struct pci_bus *bus);
/* /*
* If it's a bridge, configure it and scan the bus behind it. * If it's a bridge, configure it and scan the bus behind it.
* For CardBus bridges, we don't scan behind as the devices will * For CardBus bridges, we don't scan behind as the devices will
@ -641,13 +631,13 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass
(child->number > bus->subordinate) || (child->number > bus->subordinate) ||
(child->number < bus->number) || (child->number < bus->number) ||
(child->subordinate < bus->number)) { (child->subordinate < bus->number)) {
pr_debug("PCI: Bus #%02x (-#%02x) is %s" pr_debug("PCI: Bus #%02x (-#%02x) is %s "
"hidden behind%s bridge #%02x (-#%02x)\n", "hidden behind%s bridge #%02x (-#%02x)\n",
child->number, child->subordinate, child->number, child->subordinate,
(bus->number > child->subordinate && (bus->number > child->subordinate &&
bus->subordinate < child->number) ? bus->subordinate < child->number) ?
"wholly " : " partially", "wholly" : "partially",
bus->self->transparent ? " transparent" : " ", bus->self->transparent ? " transparent" : "",
bus->number, bus->subordinate); bus->number, bus->subordinate);
} }
bus = bus->parent; bus = bus->parent;
@ -971,6 +961,7 @@ struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn)
return dev; return dev;
} }
EXPORT_SYMBOL(pci_scan_single_device);
/** /**
* pci_scan_slot - scan a PCI slot on a bus for devices. * pci_scan_slot - scan a PCI slot on a bus for devices.
@ -1011,6 +1002,10 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
break; break;
} }
} }
if (bus->self)
pcie_aspm_init_link_state(bus->self);
return nr; return nr;
} }
@ -1103,32 +1098,27 @@ struct pci_bus * pci_create_bus(struct device *parent,
goto dev_reg_err; goto dev_reg_err;
b->bridge = get_device(dev); b->bridge = get_device(dev);
b->class_dev.class = &pcibus_class; b->dev.class = &pcibus_class;
sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus); b->dev.parent = b->bridge;
error = class_device_register(&b->class_dev); sprintf(b->dev.bus_id, "%04x:%02x", pci_domain_nr(b), bus);
error = device_register(&b->dev);
if (error) if (error)
goto class_dev_reg_err; goto class_dev_reg_err;
error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); error = device_create_file(&b->dev, &dev_attr_cpuaffinity);
if (error) if (error)
goto class_dev_create_file_err; goto dev_create_file_err;
/* Create legacy_io and legacy_mem files for this bus */ /* Create legacy_io and legacy_mem files for this bus */
pci_create_legacy_files(b); pci_create_legacy_files(b);
error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
if (error)
goto sys_create_link_err;
b->number = b->secondary = bus; b->number = b->secondary = bus;
b->resource[0] = &ioport_resource; b->resource[0] = &ioport_resource;
b->resource[1] = &iomem_resource; b->resource[1] = &iomem_resource;
return b; return b;
sys_create_link_err: dev_create_file_err:
class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity); device_unregister(&b->dev);
class_dev_create_file_err:
class_device_unregister(&b->class_dev);
class_dev_reg_err: class_dev_reg_err:
device_unregister(dev); device_unregister(dev);
dev_reg_err: dev_reg_err:
@ -1140,7 +1130,6 @@ struct pci_bus * pci_create_bus(struct device *parent,
kfree(b); kfree(b);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(pci_create_bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, struct pci_bus *pci_scan_bus_parented(struct device *parent,
int bus, struct pci_ops *ops, void *sysdata) int bus, struct pci_ops *ops, void *sysdata)
@ -1159,7 +1148,6 @@ EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge); EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL(pci_scan_single_device);
EXPORT_SYMBOL_GPL(pci_scan_child_bus); EXPORT_SYMBOL_GPL(pci_scan_child_bus);
#endif #endif

View file

@ -11,6 +11,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
@ -202,15 +203,18 @@ struct pci_filp_private {
int write_combine; int write_combine;
}; };
static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ {
const struct proc_dir_entry *dp = PDE(inode); const struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode);
struct pci_dev *dev = dp->data; struct pci_dev *dev = dp->data;
#ifdef HAVE_PCI_MMAP #ifdef HAVE_PCI_MMAP
struct pci_filp_private *fpriv = file->private_data; struct pci_filp_private *fpriv = file->private_data;
#endif /* HAVE_PCI_MMAP */ #endif /* HAVE_PCI_MMAP */
int ret = 0; int ret = 0;
lock_kernel();
switch (cmd) { switch (cmd) {
case PCIIOC_CONTROLLER: case PCIIOC_CONTROLLER:
ret = pci_domain_nr(dev->bus); ret = pci_domain_nr(dev->bus);
@ -239,6 +243,7 @@ static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned i
break; break;
}; };
unlock_kernel();
return ret; return ret;
} }
@ -291,7 +296,7 @@ static const struct file_operations proc_bus_pci_operations = {
.llseek = proc_bus_pci_lseek, .llseek = proc_bus_pci_lseek,
.read = proc_bus_pci_read, .read = proc_bus_pci_read,
.write = proc_bus_pci_write, .write = proc_bus_pci_write,
.ioctl = proc_bus_pci_ioctl, .unlocked_ioctl = proc_bus_pci_ioctl,
#ifdef HAVE_PCI_MMAP #ifdef HAVE_PCI_MMAP
.open = proc_bus_pci_open, .open = proc_bus_pci_open,
.release = proc_bus_pci_release, .release = proc_bus_pci_release,
@ -370,7 +375,7 @@ static int show_device(struct seq_file *m, void *v)
return 0; return 0;
} }
static struct seq_operations proc_bus_pci_devices_op = { static const struct seq_operations proc_bus_pci_devices_op = {
.start = pci_seq_start, .start = pci_seq_start,
.next = pci_seq_next, .next = pci_seq_next,
.stop = pci_seq_stop, .stop = pci_seq_stop,
@ -480,7 +485,3 @@ static int __init pci_proc_init(void)
__initcall(pci_proc_init); __initcall(pci_proc_init);
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_proc_detach_bus);
#endif

View file

@ -21,6 +21,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/kallsyms.h>
#include "pci.h" #include "pci.h"
/* The Mellanox Tavor device gives false positive parity errors /* The Mellanox Tavor device gives false positive parity errors
@ -46,14 +47,14 @@ static void quirk_passive_release(struct pci_dev *dev)
while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) { while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
pci_read_config_byte(d, 0x82, &dlc); pci_read_config_byte(d, 0x82, &dlc);
if (!(dlc & 1<<1)) { if (!(dlc & 1<<1)) {
printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d)); dev_err(&d->dev, "PIIX3: Enabling Passive Release\n");
dlc |= 1<<1; dlc |= 1<<1;
pci_write_config_byte(d, 0x82, dlc); 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_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 ); 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 /* 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 but VIA don't answer queries. If you happen to have good contacts at VIA
@ -68,20 +69,20 @@ static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
{ {
if (!isa_dma_bridge_buggy) { if (!isa_dma_bridge_buggy) {
isa_dma_bridge_buggy=1; isa_dma_bridge_buggy=1;
printk(KERN_INFO "Activating ISA DMA hang workarounds.\n"); dev_info(&dev->dev, "Activating ISA DMA hang workarounds\n");
} }
} }
/* /*
* Its not totally clear which chipsets are the problematic ones * Its not totally clear which chipsets are the problematic ones
* We know 82C586 and 82C596 variants are affected. * 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_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_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_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_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_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_2, quirk_isa_dma_hangs);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, 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; int pci_pci_problems;
EXPORT_SYMBOL(pci_pci_problems); EXPORT_SYMBOL(pci_pci_problems);
@ -92,12 +93,12 @@ EXPORT_SYMBOL(pci_pci_problems);
static void __devinit quirk_nopcipci(struct pci_dev *dev) static void __devinit quirk_nopcipci(struct pci_dev *dev)
{ {
if ((pci_pci_problems & PCIPCI_FAIL)==0) { if ((pci_pci_problems & PCIPCI_FAIL)==0) {
printk(KERN_INFO "Disabling direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Disabling direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_FAIL; 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_5597, quirk_nopcipci);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, 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) static void __devinit quirk_nopciamd(struct pci_dev *dev)
{ {
@ -105,11 +106,11 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev)
pci_read_config_byte(dev, 0x08, &rev); pci_read_config_byte(dev, 0x08, &rev);
if (rev == 0x13) { if (rev == 0x13) {
/* Erratum 24 */ /* Erratum 24 */
printk(KERN_INFO "Chipset erratum: Disabling direct PCI/AGP transfers.\n"); dev_info(&dev->dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n");
pci_pci_problems |= PCIAGP_FAIL; pci_pci_problems |= PCIAGP_FAIL;
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopciamd ); 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 * Triton requires workarounds to be used by the drivers
@ -117,14 +118,14 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopci
static void __devinit quirk_triton(struct pci_dev *dev) static void __devinit quirk_triton(struct pci_dev *dev)
{ {
if ((pci_pci_problems&PCIPCI_TRITON)==0) { if ((pci_pci_problems&PCIPCI_TRITON)==0) {
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_TRITON; 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_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_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_82439, quirk_triton);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_triton);
/* /*
* VIA Apollo KT133 needs PCI latency patch * VIA Apollo KT133 needs PCI latency patch
@ -139,25 +140,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir
static void quirk_vialatency(struct pci_dev *dev) static void quirk_vialatency(struct pci_dev *dev)
{ {
struct pci_dev *p; struct pci_dev *p;
u8 rev;
u8 busarb; u8 busarb;
/* Ok we have a potential problem chipset here. Now see if we have /* Ok we have a potential problem chipset here. Now see if we have
a buggy southbridge */ a buggy southbridge */
p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL); p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
if (p!=NULL) { if (p!=NULL) {
pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
/* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */ /* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */
/* Check for buggy part revisions */ /* Check for buggy part revisions */
if (rev < 0x40 || rev > 0x42) if (p->revision < 0x40 || p->revision > 0x42)
goto exit; goto exit;
} else { } else {
p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL); p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
if (p==NULL) /* No problem parts */ if (p==NULL) /* No problem parts */
goto exit; goto exit;
pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
/* Check for buggy part revisions */ /* Check for buggy part revisions */
if (rev < 0x10 || rev > 0x12) if (p->revision < 0x10 || p->revision > 0x12)
goto exit; goto exit;
} }
@ -180,17 +178,17 @@ static void quirk_vialatency(struct pci_dev *dev)
busarb &= ~(1<<5); busarb &= ~(1<<5);
busarb |= (1<<4); busarb |= (1<<4);
pci_write_config_byte(dev, 0x76, busarb); pci_write_config_byte(dev, 0x76, busarb);
printk(KERN_INFO "Applying VIA southbridge workaround.\n"); dev_info(&dev->dev, "Applying VIA southbridge workaround\n");
exit: exit:
pci_dev_put(p); 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_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_8371_1, quirk_vialatency);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, 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 */ /* 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_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_8371_1, quirk_vialatency);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, 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 * VIA Apollo VP3 needs ETBF on BT848/878
@ -198,20 +196,20 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_viala
static void __devinit quirk_viaetbf(struct pci_dev *dev) static void __devinit quirk_viaetbf(struct pci_dev *dev)
{ {
if ((pci_pci_problems&PCIPCI_VIAETBF)==0) { if ((pci_pci_problems&PCIPCI_VIAETBF)==0) {
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_VIAETBF; pci_pci_problems |= PCIPCI_VIAETBF;
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_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) static void __devinit quirk_vsfx(struct pci_dev *dev)
{ {
if ((pci_pci_problems&PCIPCI_VSFX)==0) { if ((pci_pci_problems&PCIPCI_VSFX)==0) {
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_VSFX; pci_pci_problems |= PCIPCI_VSFX;
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_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 * Ali Magik requires workarounds to be used by the drivers
@ -222,12 +220,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx
static void __init quirk_alimagik(struct pci_dev *dev) static void __init quirk_alimagik(struct pci_dev *dev)
{ {
if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) { if ((pci_pci_problems&PCIPCI_ALIMAGIK)==0) {
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON; 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_M1647, quirk_alimagik);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, 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 * Natoma has some interesting boundary conditions with Zoran stuff
@ -236,16 +234,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimag
static void __devinit quirk_natoma(struct pci_dev *dev) static void __devinit quirk_natoma(struct pci_dev *dev)
{ {
if ((pci_pci_problems&PCIPCI_NATOMA)==0) { if ((pci_pci_problems&PCIPCI_NATOMA)==0) {
printk(KERN_INFO "Limiting direct PCI/PCI transfers.\n"); dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_NATOMA; 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_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_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_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_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_1, quirk_natoma);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, 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 * This chip can cause PCI parity errors if config register 0xA0 is read
@ -255,7 +253,7 @@ static void __devinit quirk_citrine(struct pci_dev *dev)
{ {
dev->cfg_size = 0xA0; dev->cfg_size = 0xA0;
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, quirk_citrine ); 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. * S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
@ -270,8 +268,8 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev)
r->end = 0x3ffffff; 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_868, quirk_s3_64M);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, 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, static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
unsigned size, int nr, const char *name) unsigned size, int nr, const char *name)
@ -292,7 +290,7 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
pcibios_bus_to_resource(dev, res, &bus_region); pcibios_bus_to_resource(dev, res, &bus_region);
pci_claim_resource(dev, nr); pci_claim_resource(dev, nr);
printk("PCI quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name);
} }
} }
@ -302,12 +300,12 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
*/ */
static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev) static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev)
{ {
printk(KERN_INFO "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb.\n"); dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */ /* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
request_region(0x3b0, 0x0C, "RadeonIGP"); request_region(0x3b0, 0x0C, "RadeonIGP");
request_region(0x3d3, 0x01, "RadeonIGP"); request_region(0x3d3, 0x01, "RadeonIGP");
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_exploding_mce ); 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 * Let's make the southbridge information explicit instead
@ -329,7 +327,7 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
pci_read_config_word(dev, 0xE2, &region); pci_read_config_word(dev, 0xE2, &region);
quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); 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 ); 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) static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
{ {
@ -354,7 +352,7 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p
* let's get enough confirmation reports first. * let's get enough confirmation reports first.
*/ */
base &= -size; base &= -size;
printk("%s PIO at %04x-%04x\n", name, base, base + size - 1); dev_info(&dev->dev, "%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) static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
@ -379,7 +377,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
* reserve it, but let's get enough confirmation reports first. * reserve it, but let's get enough confirmation reports first.
*/ */
base &= -size; base &= -size;
printk("%s MMIO at %04x-%04x\n", name, base, base + size - 1); dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1);
} }
/* /*
@ -418,8 +416,8 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20); piix4_io_quirk(dev, "PIIX4 devres I", 0x78, 1 << 20);
piix4_io_quirk(dev, "PIIX4 devres J", 0x7c, 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_82371AB_3, quirk_piix4_acpi);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_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 * ICH4, ICH4-M, ICH5, ICH5-M ACPI: Three IO regions pointed to by longwords at
@ -436,16 +434,16 @@ static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
pci_read_config_dword(dev, 0x58, &region); pci_read_config_dword(dev, 0x58, &region);
quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH4 GPIO"); 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_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_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_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_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_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_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_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_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_82801EB_0, quirk_ich4_lpc_acpi);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, 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) static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
{ {
@ -457,20 +455,20 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
pci_read_config_dword(dev, 0x48, &region); pci_read_config_dword(dev, 0x48, &region);
quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO"); 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_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_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_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_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_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_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_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_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_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_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_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_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_7, quirk_ich6_lpc_acpi);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_8, 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 * VIA ACPI: One IO region pointed to by longword at
@ -486,7 +484,7 @@ static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev)
quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); 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 ); 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 * VIA VT82C686 ACPI: Three IO region pointed to by (long)words at
@ -509,7 +507,7 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
smb &= PCI_BASE_ADDRESS_IO_MASK; smb &= PCI_BASE_ADDRESS_IO_MASK;
quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); 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 ); 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 * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at
@ -551,14 +549,14 @@ static void quirk_via_ioapic(struct pci_dev *dev)
else else
tmp = 0x1f; /* all known bits (4-0) routed to external APIC */ tmp = 0x1f; /* all known bits (4-0) routed to external APIC */
printk(KERN_INFO "PCI: %sbling Via external APIC routing\n", dev_info(&dev->dev, "%sbling VIA external APIC routing\n",
tmp == 0 ? "Disa" : "Ena"); tmp == 0 ? "Disa" : "Ena");
/* Offset 0x58: External APIC IRQ output control */ /* Offset 0x58: External APIC IRQ output control */
pci_write_config_byte (dev, 0x58, tmp); 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_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 ); 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. * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@ -573,7 +571,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
pci_read_config_byte(dev, 0x5B, &misc_control2); pci_read_config_byte(dev, 0x5B, &misc_control2);
if (!(misc_control2 & BYPASS_APIC_DEASSERT)) { if (!(misc_control2 & BYPASS_APIC_DEASSERT)) {
printk(KERN_INFO "PCI: Bypassing VIA 8237 APIC De-Assert Message\n"); dev_info(&dev->dev, "Bypassing VIA 8237 APIC De-Assert Message\n");
pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT); pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT);
} }
} }
@ -592,18 +590,18 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_v
static void __devinit quirk_amd_ioapic(struct pci_dev *dev) static void __devinit quirk_amd_ioapic(struct pci_dev *dev)
{ {
if (dev->revision >= 0x02) { if (dev->revision >= 0x02) {
printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n"); dev_warn(&dev->dev, "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"); dev_warn(&dev->dev, " : booting with the \"noapic\" option\n");
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic ); 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) static void __init quirk_ioapic_rmw(struct pci_dev *dev)
{ {
if (dev->devfn == 0 && dev->bus->number == 0) if (dev->devfn == 0 && dev->bus->number == 0)
sis_apic_bug = 1; sis_apic_bug = 1;
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw);
#define AMD8131_revA0 0x01 #define AMD8131_revA0 0x01
#define AMD8131_revB0 0x11 #define AMD8131_revB0 0x11
@ -617,7 +615,7 @@ static void quirk_amd_8131_ioapic(struct pci_dev *dev)
return; return;
if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) { if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) {
printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n"); dev_info(&dev->dev, "Fixing up AMD8131 IOAPIC mode\n");
pci_read_config_byte( dev, AMD8131_MISC, &tmp); pci_read_config_byte( dev, AMD8131_MISC, &tmp);
tmp &= ~(1 << AMD8131_NIOAMODE_BIT); tmp &= ~(1 << AMD8131_NIOAMODE_BIT);
pci_write_config_byte( dev, AMD8131_MISC, tmp); pci_write_config_byte( dev, AMD8131_MISC, tmp);
@ -634,8 +632,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk
static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev)
{ {
if (dev->subordinate && dev->revision <= 0x12) { if (dev->subordinate && dev->revision <= 0x12) {
printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X " dev_info(&dev->dev, "AMD8131 rev %x detected; "
"MMRBC\n", dev->revision); "disabling PCI-X MMRBC\n", dev->revision);
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC; dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
} }
} }
@ -660,8 +658,8 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
if (irq && (irq != 2)) if (irq && (irq != 2))
d->irq = irq; 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_82C586_3, quirk_via_acpi);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi);
/* /*
@ -742,8 +740,8 @@ static void quirk_via_vlink(struct pci_dev *dev)
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
if (new_irq != irq) { if (new_irq != irq) {
printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n", dev_info(&dev->dev, "VIA VLink IRQ fixup, from %d to %d\n",
pci_name(dev), irq, new_irq); irq, new_irq);
udelay(15); /* unknown if delay really needed */ udelay(15); /* unknown if delay really needed */
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
} }
@ -761,7 +759,7 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev)
pci_write_config_byte(dev, 0xfc, 0); pci_write_config_byte(dev, 0xfc, 0);
pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device); 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 ); 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 * CardBus controllers have a legacy base address that enables them
@ -791,15 +789,15 @@ static void quirk_amd_ordering(struct pci_dev *dev)
pci_read_config_dword(dev, 0x4C, &pcic); pci_read_config_dword(dev, 0x4C, &pcic);
if ((pcic&6)!=6) { if ((pcic&6)!=6) {
pcic |= 6; pcic |= 6;
printk(KERN_WARNING "BIOS failed to enable PCI standards compliance, fixing this error.\n"); dev_warn(&dev->dev, "BIOS failed to enable PCI standards compliance; fixing this error\n");
pci_write_config_dword(dev, 0x4C, pcic); pci_write_config_dword(dev, 0x4C, pcic);
pci_read_config_dword(dev, 0x84, &pcic); pci_read_config_dword(dev, 0x84, &pcic);
pcic |= (1<<23); /* Required in this mode */ pcic |= (1<<23); /* Required in this mode */
pci_write_config_dword(dev, 0x84, pcic); 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 ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering);
/* /*
* DreamWorks provided workaround for Dunord I-3000 problem * DreamWorks provided workaround for Dunord I-3000 problem
@ -814,7 +812,7 @@ static void __devinit quirk_dunord ( struct pci_dev * dev )
r->start = 0; r->start = 0;
r->end = 0xffffff; r->end = 0xffffff;
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk_dunord ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DUNORD, PCI_DEVICE_ID_DUNORD_I3000, quirk_dunord);
/* /*
* i82380FB mobile docking controller: its PCI-to-PCI bridge * i82380FB mobile docking controller: its PCI-to-PCI bridge
@ -826,8 +824,8 @@ static void __devinit quirk_transparent_bridge(struct pci_dev *dev)
{ {
dev->transparent = 1; 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_INTEL, PCI_DEVICE_ID_INTEL_82380FB, quirk_transparent_bridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, 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 * Common misconfiguration of the MediaGX/Geode PCI master that will
@ -841,12 +839,12 @@ static void quirk_mediagx_master(struct pci_dev *dev)
pci_read_config_byte(dev, 0x41, &reg); pci_read_config_byte(dev, 0x41, &reg);
if (reg & 2) { if (reg & 2) {
reg &= ~2; reg &= ~2;
printk(KERN_INFO "PCI: Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg); dev_info(&dev->dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n", reg);
pci_write_config_byte(dev, 0x41, 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 ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master);
/* /*
* Ensure C0 rev restreaming is off. This is normally done by * Ensure C0 rev restreaming is off. This is normally done by
@ -863,11 +861,11 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
if (config & (1<<6)) { if (config & (1<<6)) {
config &= ~(1<<6); config &= ~(1<<6);
pci_write_config_word(pdev, 0x40, config); pci_write_config_word(pdev, 0x40, config);
printk(KERN_INFO "PCI: C0 revision 450NX. Disabling PCI restreaming.\n"); dev_info(&pdev->dev, "C0 revision 450NX. Disabling PCI restreaming\n");
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
static void __devinit quirk_sb600_sata(struct pci_dev *pdev) static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
@ -902,7 +900,7 @@ static void __devinit quirk_svwks_csb5ide(struct pci_dev *pdev)
/* PCI layer will sort out resources */ /* PCI layer will sort out resources */
} }
} }
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide ); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide);
/* /*
* Intel 82801CAM ICH3-M datasheet says IDE modes must be the same * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
@ -914,7 +912,7 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev)
pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) { if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) {
printk(KERN_INFO "PCI: IDE mode mismatch; forcing legacy mode\n"); dev_info(&pdev->dev, "IDE mode mismatch; forcing legacy mode\n");
prog &= ~5; prog &= ~5;
pdev->class &= ~5; pdev->class &= ~5;
pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
@ -929,7 +927,7 @@ static void __init quirk_eisa_bridge(struct pci_dev *dev)
{ {
dev->class = PCI_CLASS_BRIDGE_EISA << 8; dev->class = PCI_CLASS_BRIDGE_EISA << 8;
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge);
/* /*
@ -1022,6 +1020,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
case 0x12bd: /* HP D530 */ case 0x12bd: /* HP D530 */
asus_hides_smbus = 1; asus_hides_smbus = 1;
} }
else if (dev->device == PCI_DEVICE_ID_INTEL_82875_HB)
switch (dev->subsystem_device) {
case 0x12bf: /* HP xw4100 */
asus_hides_smbus = 1;
}
else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
switch (dev->subsystem_device) { switch (dev->subsystem_device) {
case 0x099c: /* HP Compaq nx6110 */ case 0x099c: /* HP Compaq nx6110 */
@ -1049,17 +1052,18 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
} }
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge);
static void asus_hides_smbus_lpc(struct pci_dev *dev) static void asus_hides_smbus_lpc(struct pci_dev *dev)
{ {
@ -1073,25 +1077,25 @@ static void asus_hides_smbus_lpc(struct pci_dev *dev)
pci_write_config_word(dev, 0xF2, val & (~0x8)); pci_write_config_word(dev, 0xF2, val & (~0x8));
pci_read_config_word(dev, 0xF2, &val); pci_read_config_word(dev, 0xF2, &val);
if (val & 0x8) if (val & 0x8)
printk(KERN_INFO "PCI: i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val); dev_info(&dev->dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n", val);
else else
printk(KERN_INFO "PCI: Enabled i801 SMBus device\n"); dev_info(&dev->dev, "Enabled i801 SMBus device\n");
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc);
static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
{ {
@ -1106,10 +1110,10 @@ static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */ val=readl(base + 0x3418); /* read the Function Disable register, dword mode only */
writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */ writel(val & 0xFFFFFFF7, base + 0x3418); /* enable the SMBus device */
iounmap(base); iounmap(base);
printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6);
/* /*
* SiS 96x south bridge: BIOS typically hides SMBus device... * SiS 96x south bridge: BIOS typically hides SMBus device...
@ -1119,18 +1123,18 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
u8 val = 0; u8 val = 0;
pci_read_config_byte(dev, 0x77, &val); pci_read_config_byte(dev, 0x77, &val);
if (val & 0x10) { if (val & 0x10) {
printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); dev_info(&dev->dev, "Enabling SiS 96x SMBus\n");
pci_write_config_byte(dev, 0x77, val & ~0x10); pci_write_config_byte(dev, 0x77, val & ~0x10);
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus);
/* /*
* ... This is further complicated by the fact that some SiS96x south * ... This is further complicated by the fact that some SiS96x south
@ -1163,8 +1167,8 @@ static void quirk_sis_503(struct pci_dev *dev)
dev->device = devid; dev->device = devid;
quirk_sis_96x_smbus(dev); quirk_sis_96x_smbus(dev);
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503);
/* /*
@ -1191,13 +1195,13 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
pci_write_config_byte(dev, 0x50, val & (~0xc0)); pci_write_config_byte(dev, 0x50, val & (~0xc0));
pci_read_config_byte(dev, 0x50, &val); pci_read_config_byte(dev, 0x50, &val);
if (val & 0xc0) if (val & 0xc0)
printk(KERN_INFO "PCI: onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val); dev_info(&dev->dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val);
else else
printk(KERN_INFO "PCI: enabled onboard AC97/MC97 devices\n"); dev_info(&dev->dev, "Enabled onboard AC97/MC97 devices\n");
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
@ -1292,7 +1296,7 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic);
#endif #endif
int pcie_mch_quirk; int pcie_mch_quirk;
@ -1302,9 +1306,9 @@ static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
{ {
pcie_mch_quirk = 1; pcie_mch_quirk = 1;
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch);
/* /*
@ -1314,11 +1318,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quir
static void __devinit quirk_pcie_pxh(struct pci_dev *dev) static void __devinit quirk_pcie_pxh(struct pci_dev *dev)
{ {
pci_msi_off(dev); pci_msi_off(dev);
dev->no_msi = 1; dev->no_msi = 1;
dev_warn(&dev->dev, "PXH quirk detected; SHPC device MSI disabled\n");
printk(KERN_WARNING "PCI: PXH quirk detected, "
"disabling MSI for SHPC device\n");
} }
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_0, quirk_pcie_pxh); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_0, quirk_pcie_pxh);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_1, quirk_pcie_pxh); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_1, quirk_pcie_pxh);
@ -1399,7 +1400,7 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
case PCI_DEVICE_ID_NETMOS_9855: case PCI_DEVICE_ID_NETMOS_9855:
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
num_parallel) { num_parallel) {
printk(KERN_INFO "PCI: Netmos %04x (%u parallel, " dev_info(&dev->dev, "Netmos %04x (%u parallel, "
"%u serial); changing class SERIAL to OTHER " "%u serial); changing class SERIAL to OTHER "
"(use parport_serial)\n", "(use parport_serial)\n",
dev->device, num_parallel, num_serial); dev->device, num_parallel, num_serial);
@ -1412,9 +1413,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
static void __devinit quirk_e100_interrupt(struct pci_dev *dev) static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
{ {
u16 command; u16 command, pmcsr;
u8 __iomem *csr; u8 __iomem *csr;
u8 cmd_hi; u8 cmd_hi;
int pm;
switch (dev->device) { switch (dev->device) {
/* PCI IDs taken from drivers/net/e100.c */ /* PCI IDs taken from drivers/net/e100.c */
@ -1448,18 +1450,28 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
if (!(command & PCI_COMMAND_MEMORY) || !pci_resource_start(dev, 0)) if (!(command & PCI_COMMAND_MEMORY) || !pci_resource_start(dev, 0))
return; return;
/*
* Check that the device is in the D0 power state. If it's not,
* there is no point to look any further.
*/
pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (pm) {
pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0)
return;
}
/* Convert from PCI bus to resource space. */ /* Convert from PCI bus to resource space. */
csr = ioremap(pci_resource_start(dev, 0), 8); csr = ioremap(pci_resource_start(dev, 0), 8);
if (!csr) { if (!csr) {
printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", dev_warn(&dev->dev, "Can't map e100 registers\n");
pci_name(dev));
return; return;
} }
cmd_hi = readb(csr + 3); cmd_hi = readb(csr + 3);
if (cmd_hi == 0) { if (cmd_hi == 0) {
printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " dev_warn(&dev->dev, "Firmware left e100 interrupts enabled; "
"enabled, disabling\n", pci_name(dev)); "disabling\n");
writeb(1, csr + 3); writeb(1, csr + 3);
} }
@ -1474,7 +1486,7 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
*/ */
if (dev->class == PCI_CLASS_NOT_DEFINED) { if (dev->class == PCI_CLASS_NOT_DEFINED) {
printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n"); dev_info(&dev->dev, "NCR 53c810 rev 1 detected; setting PCI class\n");
dev->class = PCI_CLASS_STORAGE_SCSI; dev->class = PCI_CLASS_STORAGE_SCSI;
} }
} }
@ -1485,7 +1497,11 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_f
while (f < end) { while (f < end) {
if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
(f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev)); #ifdef DEBUG
dev_dbg(&dev->dev, "calling quirk 0x%p", f->hook);
print_fn_descriptor_symbol(": %s()\n",
(unsigned long) f->hook);
#endif
f->hook(dev); f->hook(dev);
} }
f++; f++;
@ -1553,7 +1569,7 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
pci_read_config_word(dev, 0x40, &en1k); pci_read_config_word(dev, 0x40, &en1k);
if (en1k & 0x200) { if (en1k & 0x200) {
printk(KERN_INFO "PCI: Enable I/O Space to 1 KB Granularity\n"); dev_info(&dev->dev, "Enable I/O Space to 1KB granularity\n");
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
@ -1585,7 +1601,7 @@ static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00); iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00);
if (iobl_adr != iobl_adr_1k) { if (iobl_adr != iobl_adr_1k) {
printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n", dev_info(&dev->dev, "Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1KB granularity\n",
iobl_adr,iobl_adr_1k); iobl_adr,iobl_adr_1k);
pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k); pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k);
} }
@ -1603,9 +1619,8 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
if (pci_read_config_byte(dev, 0xf41, &b) == 0) { if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
if (!(b & 0x20)) { if (!(b & 0x20)) {
pci_write_config_byte(dev, 0xf41, b | 0x20); pci_write_config_byte(dev, 0xf41, b | 0x20);
printk(KERN_INFO dev_info(&dev->dev,
"PCI: Linking AER extended capability on %s\n", "Linking AER extended capability\n");
pci_name(dev));
} }
} }
} }
@ -1614,6 +1629,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap); quirk_nvidia_ck804_pcie_aer_ext_cap);
static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
{
/*
* Disable PCI Bus Parking and PCI Master read caching on CX700
* which causes unspecified timing errors with a VT6212L on the PCI
* bus leading to USB2.0 packet loss. The defaults are that these
* features are turned off but some BIOSes turn them on.
*/
uint8_t b;
if (pci_read_config_byte(dev, 0x76, &b) == 0) {
if (b & 0x40) {
/* Turn off PCI Bus Parking */
pci_write_config_byte(dev, 0x76, b ^ 0x40);
/* Turn off PCI Master read caching */
pci_write_config_byte(dev, 0x72, 0x0);
pci_write_config_byte(dev, 0x75, 0x1);
pci_write_config_byte(dev, 0x77, 0x0);
printk(KERN_INFO
"PCI: VIA CX700 PCI parking/caching fixup on %s\n",
pci_name(dev));
}
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching);
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting /* Some chipsets do not support MSI. We cannot easily rely on setting
* PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
@ -1624,7 +1667,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
static void __init quirk_disable_all_msi(struct pci_dev *dev) static void __init quirk_disable_all_msi(struct pci_dev *dev)
{ {
pci_no_msi(); pci_no_msi();
printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n"); dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n");
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
@ -1635,9 +1678,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disab
static void __devinit quirk_disable_msi(struct pci_dev *dev) static void __devinit quirk_disable_msi(struct pci_dev *dev)
{ {
if (dev->subordinate) { if (dev->subordinate) {
printk(KERN_WARNING "PCI: MSI quirk detected. " dev_warn(&dev->dev, "MSI quirk detected; "
"PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n", "subordinate MSI disabled\n");
pci_name(dev));
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
} }
} }
@ -1656,9 +1698,9 @@ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
&flags) == 0) &flags) == 0)
{ {
printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n", dev_info(&dev->dev, "Found %s HT MSI Mapping\n",
flags & HT_MSI_FLAGS_ENABLE ? flags & HT_MSI_FLAGS_ENABLE ?
"enabled" : "disabled", pci_name(dev)); "enabled" : "disabled");
return (flags & HT_MSI_FLAGS_ENABLE) != 0; return (flags & HT_MSI_FLAGS_ENABLE) != 0;
} }
@ -1672,17 +1714,40 @@ static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
{ {
if (dev->subordinate && !msi_ht_cap_enabled(dev)) { if (dev->subordinate && !msi_ht_cap_enabled(dev)) {
printk(KERN_WARNING "PCI: MSI quirk detected. " dev_warn(&dev->dev, "MSI quirk detected; "
"MSI disabled on chipset %s.\n", "subordinate MSI disabled\n");
pci_name(dev));
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
} }
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE,
quirk_msi_ht_cap); quirk_msi_ht_cap);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
quirk_msi_ht_cap); /*
* Force enable MSI mapping capability on HT bridges
*/
static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
{
int pos, ttl = 48;
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
while (pos && ttl--) {
u8 flags;
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) {
printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n",
pci_name(dev));
pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
flags | HT_MSI_FLAGS_ENABLE);
}
pos = pci_find_next_ht_capability(dev, pos,
HT_CAPTYPE_MSI_MAPPING);
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
quirk_msi_ht_cap_enable);
/* The nVidia CK804 chipset may have 2 HT MSI mappings. /* The nVidia CK804 chipset may have 2 HT MSI mappings.
* MSI are supported if the MSI capability set in any of these mappings. * MSI are supported if the MSI capability set in any of these mappings.
@ -1701,9 +1766,8 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
if (!pdev) if (!pdev)
return; return;
if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
printk(KERN_WARNING "PCI: MSI quirk detected. " dev_warn(&dev->dev, "MSI quirk detected; "
"MSI disabled on chipset %s.\n", "subordinate MSI disabled\n");
pci_name(dev));
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
} }
pci_dev_put(pdev); pci_dev_put(pdev);
@ -1715,6 +1779,23 @@ static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
{ {
dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
} }
static void __devinit quirk_msi_intx_disable_ati_bug(struct pci_dev *dev)
{
struct pci_dev *p;
/* SB700 MSI issue will be fixed at HW level from revision A21,
* we need check PCI REVISION ID of SMBus controller to get SB700
* revision.
*/
p = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
NULL);
if (!p)
return;
if ((p->revision < 0x3B) && (p->revision >= 0x30))
dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
pci_dev_put(p);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
PCI_DEVICE_ID_TIGON3_5780, PCI_DEVICE_ID_TIGON3_5780,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_bug);
@ -1735,17 +1816,15 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4390,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_ati_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4391,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_ati_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4392,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_ati_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4393,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_ati_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4394,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_ati_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4395,
quirk_msi_intx_disable_bug);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4373,
quirk_msi_intx_disable_bug); quirk_msi_intx_disable_bug);

View file

@ -1,5 +1,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/aspm.h>
#include "pci.h" #include "pci.h"
static void pci_free_resources(struct pci_dev *dev) static void pci_free_resources(struct pci_dev *dev)
@ -30,6 +31,9 @@ static void pci_stop_dev(struct pci_dev *dev)
dev->global_list.next = dev->global_list.prev = NULL; dev->global_list.next = dev->global_list.prev = NULL;
up_write(&pci_bus_sem); up_write(&pci_bus_sem);
} }
if (dev->bus->self)
pcie_aspm_exit_link_state(dev);
} }
static void pci_destroy_dev(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev)
@ -74,10 +78,8 @@ void pci_remove_bus(struct pci_bus *pci_bus)
list_del(&pci_bus->node); list_del(&pci_bus->node);
up_write(&pci_bus_sem); up_write(&pci_bus_sem);
pci_remove_legacy_files(pci_bus); pci_remove_legacy_files(pci_bus);
class_device_remove_file(&pci_bus->class_dev, device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
&class_device_attr_cpuaffinity); device_unregister(&pci_bus->dev);
sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
class_device_unregister(&pci_bus->class_dev);
} }
EXPORT_SYMBOL(pci_remove_bus); EXPORT_SYMBOL(pci_remove_bus);

View file

@ -162,6 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
return rom; return rom;
} }
#if 0
/** /**
* pci_map_rom_copy - map a PCI ROM to kernel space, create a copy * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
* @pdev: pointer to pci device struct * @pdev: pointer to pci device struct
@ -196,6 +197,7 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
return (void __iomem *)(unsigned long)res->start; return (void __iomem *)(unsigned long)res->start;
} }
#endif /* 0 */
/** /**
* pci_unmap_rom - unmap the ROM from kernel space * pci_unmap_rom - unmap the ROM from kernel space
@ -218,6 +220,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
pci_disable_rom(pdev); pci_disable_rom(pdev);
} }
#if 0
/** /**
* pci_remove_rom - disable the ROM and remove its sysfs attribute * pci_remove_rom - disable the ROM and remove its sysfs attribute
* @pdev: pointer to pci device struct * @pdev: pointer to pci device struct
@ -236,6 +239,7 @@ void pci_remove_rom(struct pci_dev *pdev)
IORESOURCE_ROM_COPY))) IORESOURCE_ROM_COPY)))
pci_disable_rom(pdev); pci_disable_rom(pdev);
} }
#endif /* 0 */
/** /**
* pci_cleanup_rom - internal routine for freeing the ROM copy created * pci_cleanup_rom - internal routine for freeing the ROM copy created
@ -256,6 +260,4 @@ void pci_cleanup_rom(struct pci_dev *pdev)
} }
EXPORT_SYMBOL(pci_map_rom); EXPORT_SYMBOL(pci_map_rom);
EXPORT_SYMBOL(pci_map_rom_copy);
EXPORT_SYMBOL(pci_unmap_rom); EXPORT_SYMBOL(pci_unmap_rom);
EXPORT_SYMBOL(pci_remove_rom);

View file

@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
* The IO resource is allocated a range twice as large as it * The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs. * would normally need. This allows us to set both IO regs.
*/ */
printk(" IO window: %08lx-%08lx\n", printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
region.start); region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@ -99,8 +100,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
pcibios_resource_to_bus(bridge, &region, bus->resource[1]); pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
if (bus->resource[1]->flags & IORESOURCE_IO) { if (bus->resource[1]->flags & IORESOURCE_IO) {
printk(" IO window: %08lx-%08lx\n", printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start); region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@ -109,8 +111,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
pcibios_resource_to_bus(bridge, &region, bus->resource[2]); pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_MEM) { if (bus->resource[2]->flags & IORESOURCE_MEM) {
printk(" PREFETCH window: %08lx-%08lx\n", printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start); region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@ -119,8 +122,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
pcibios_resource_to_bus(bridge, &region, bus->resource[3]); pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
if (bus->resource[3]->flags & IORESOURCE_MEM) { if (bus->resource[3]->flags & IORESOURCE_MEM) {
printk(" MEM window: %08lx-%08lx\n", printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start); region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@ -145,7 +149,7 @@ pci_setup_bridge(struct pci_bus *bus)
{ {
struct pci_dev *bridge = bus->self; struct pci_dev *bridge = bus->self;
struct pci_bus_region region; struct pci_bus_region region;
u32 l, io_upper16; u32 l, bu, lu, io_upper16;
DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge)); DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge));
@ -159,7 +163,8 @@ pci_setup_bridge(struct pci_bus *bus)
/* Set up upper 16 bits of I/O base/limit. */ /* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
DBG(KERN_INFO " IO window: %04lx-%04lx\n", DBG(KERN_INFO " IO window: %04lx-%04lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
} }
else { else {
/* Clear upper 16 bits of I/O base/limit. */ /* Clear upper 16 bits of I/O base/limit. */
@ -180,8 +185,9 @@ pci_setup_bridge(struct pci_bus *bus)
if (bus->resource[1]->flags & IORESOURCE_MEM) { if (bus->resource[1]->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0; l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000; l |= region.end & 0xfff00000;
DBG(KERN_INFO " MEM window: %08lx-%08lx\n", DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
region.start, region.end); (unsigned long)region.start,
(unsigned long)region.end);
} }
else { else {
l = 0x0000fff0; l = 0x0000fff0;
@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
/* Set up PREF base/limit. */ /* Set up PREF base/limit. */
bu = lu = 0;
pcibios_resource_to_bus(bridge, &region, bus->resource[2]); pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0; l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000; l |= region.end & 0xfff00000;
DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n", #ifdef CONFIG_RESOURCES_64BIT
region.start, region.end); bu = region.start >> 32;
lu = region.end >> 32;
#endif
DBG(KERN_INFO " PREFETCH window: 0x%016llx-0x%016llx\n",
(unsigned long long)region.start,
(unsigned long long)region.end);
} }
else { else {
l = 0x0000fff0; l = 0x0000fff0;
@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
} }
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
/* Clear out the upper 32 bits of PREF base. */ /* Set the upper 32 bits of PREF base & limit. */
pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
} }
@ -323,8 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{ {
struct pci_dev *dev; struct pci_dev *dev;
unsigned long min_align, align, size; resource_size_t min_align, align, size;
unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */ resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order; int order, max_order;
struct resource *b_res = find_free_bus_resource(bus, type); struct resource *b_res = find_free_bus_resource(bus, type);
@ -340,7 +353,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
for (i = 0; i < PCI_NUM_RESOURCES; i++) { for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i]; struct resource *r = &dev->resource[i];
unsigned long r_size; resource_size_t r_size;
if (r->parent || (r->flags & mask) != type) if (r->parent || (r->flags & mask) != type)
continue; continue;
@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
order = __ffs(align) - 20; order = __ffs(align) - 20;
if (order > 11) { if (order > 11) {
printk(KERN_WARNING "PCI: region %s/%d " printk(KERN_WARNING "PCI: region %s/%d "
"too large: %llx-%llx\n", "too large: 0x%016llx-0x%016llx\n",
pci_name(dev), i, pci_name(dev), i,
(unsigned long long)r->start, (unsigned long long)r->start,
(unsigned long long)r->end); (unsigned long long)r->end);
r->flags = 0; r->flags = 0;
continue; continue;
} }
@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
align = 0; align = 0;
min_align = 0; min_align = 0;
for (order = 0; order <= max_order; order++) { for (order = 0; order <= max_order; order++) {
unsigned long align1 = 1UL << (order + 20); #ifdef CONFIG_RESOURCES_64BIT
resource_size_t align1 = 1ULL << (order + 20);
#else
resource_size_t align1 = 1U << (order + 20);
#endif
if (!align) if (!align)
min_align = align1; min_align = align1;
else if (ALIGN(align + min_align, min_align) < align1) else if (ALIGN(align + min_align, min_align) < align1)

View file

@ -51,10 +51,12 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
pcibios_resource_to_bus(dev, &region, res); pcibios_resource_to_bus(dev, &region, res);
pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " pr_debug(" got res [%llx:%llx] bus [%llx:%llx] flags %lx for "
"BAR %d of %s\n", (unsigned long long)res->start, "BAR %d of %s\n", (unsigned long long)res->start,
(unsigned long long)res->end, (unsigned long long)res->end,
region.start, region.end, res->flags, resno, pci_name(dev)); (unsigned long long)region.start,
(unsigned long long)region.end,
(unsigned long)res->flags, resno, pci_name(dev));
new = region.start | (res->flags & PCI_REGION_FLAG_MASK); new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
if (res->flags & IORESOURCE_IO) if (res->flags & IORESOURCE_IO)
@ -125,7 +127,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
return err; return err;
} }
EXPORT_SYMBOL_GPL(pci_claim_resource);
int pci_assign_resource(struct pci_dev *dev, int resno) int pci_assign_resource(struct pci_dev *dev, int resno)
{ {

View file

@ -34,7 +34,6 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
if (!dev) if (!dev)
goto error; goto error;
lock_kernel();
switch (len) { switch (len) {
case 1: case 1:
cfg_ret = pci_user_read_config_byte(dev, off, &byte); cfg_ret = pci_user_read_config_byte(dev, off, &byte);
@ -47,10 +46,8 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
break; break;
default: default:
err = -EINVAL; err = -EINVAL;
unlock_kernel();
goto error; goto error;
}; };
unlock_kernel();
err = -EIO; err = -EIO;
if (cfg_ret != PCIBIOS_SUCCESSFUL) if (cfg_ret != PCIBIOS_SUCCESSFUL)
@ -107,7 +104,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
lock_kernel();
switch(len) { switch(len) {
case 1: case 1:
err = get_user(byte, (u8 __user *)buf); err = get_user(byte, (u8 __user *)buf);
@ -140,7 +136,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err = -EINVAL; err = -EINVAL;
break; break;
} }
unlock_kernel();
pci_dev_put(dev); pci_dev_put(dev);
return err; return err;
} }

View file

@ -2296,10 +2296,9 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
struct Scsi_Host *shost = pci_get_drvdata(pdev); struct Scsi_Host *shost = pci_get_drvdata(pdev);
struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli *psli = &phba->sli;
int bars = pci_select_bars(pdev, IORESOURCE_MEM);
dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
if (pci_enable_device_bars(pdev, bars)) { if (pci_enable_device_mem(pdev)) {
printk(KERN_ERR "lpfc: Cannot re-enable " printk(KERN_ERR "lpfc: Cannot re-enable "
"PCI device after reset.\n"); "PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;

View file

@ -2268,6 +2268,7 @@ typedef struct scsi_qla_host {
spinlock_t hardware_lock ____cacheline_aligned; spinlock_t hardware_lock ____cacheline_aligned;
int bars; int bars;
int mem_only;
device_reg_t __iomem *iobase; /* Base I/O address */ device_reg_t __iomem *iobase; /* Base I/O address */
resource_size_t pio_address; resource_size_t pio_address;
#define MIN_IOBASE_LEN 0x100 #define MIN_IOBASE_LEN 0x100

View file

@ -1564,7 +1564,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
char pci_info[30]; char pci_info[30];
char fw_str[30]; char fw_str[30];
struct scsi_host_template *sht; struct scsi_host_template *sht;
int bars; int bars, mem_only = 0;
bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
sht = &qla2x00_driver_template; sht = &qla2x00_driver_template;
@ -1575,10 +1575,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
bars = pci_select_bars(pdev, IORESOURCE_MEM); bars = pci_select_bars(pdev, IORESOURCE_MEM);
sht = &qla24xx_driver_template; sht = &qla24xx_driver_template;
mem_only = 1;
} }
if (pci_enable_device_bars(pdev, bars)) if (mem_only) {
goto probe_out; if (pci_enable_device_mem(pdev))
goto probe_out;
} else {
if (pci_enable_device(pdev))
goto probe_out;
}
if (pci_find_aer_capability(pdev)) if (pci_find_aer_capability(pdev))
if (pci_enable_pcie_error_reporting(pdev)) if (pci_enable_pcie_error_reporting(pdev))
@ -1601,6 +1607,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no);
ha->parent = NULL; ha->parent = NULL;
ha->bars = bars; ha->bars = bars;
ha->mem_only = mem_only;
/* Set ISP-type information. */ /* Set ISP-type information. */
qla2x00_set_isp_flags(ha); qla2x00_set_isp_flags(ha);
@ -2875,8 +2882,14 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev)
{ {
pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;
scsi_qla_host_t *ha = pci_get_drvdata(pdev); scsi_qla_host_t *ha = pci_get_drvdata(pdev);
int rc;
if (pci_enable_device_bars(pdev, ha->bars)) { if (ha->mem_only)
rc = pci_enable_device_mem(pdev);
else
rc = pci_enable_device(pdev);
if (rc) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Can't re-enable PCI device after reset.\n"); "Can't re-enable PCI device after reset.\n");

View file

@ -190,9 +190,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
msleep(10); msleep(10);
} }
if (wait_time <= 0) if (wait_time <= 0)
printk(KERN_WARNING "%s %s: BIOS handoff " dev_warn(&pdev->dev, "OHCI: BIOS handoff failed"
"failed (BIOS bug ?) %08x\n", " (BIOS bug?) %08x\n",
pdev->dev.bus_id, "OHCI",
readl(base + OHCI_CONTROL)); readl(base + OHCI_CONTROL));
/* reset controller, preserving RWC */ /* reset controller, preserving RWC */
@ -243,8 +242,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
switch (cap & 0xff) { switch (cap & 0xff) {
case 1: /* BIOS/SMM/... handoff support */ case 1: /* BIOS/SMM/... handoff support */
if ((cap & EHCI_USBLEGSUP_BIOS)) { if ((cap & EHCI_USBLEGSUP_BIOS)) {
pr_debug("%s %s: BIOS handoff\n", dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
pdev->dev.bus_id, "EHCI");
#if 0 #if 0
/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on,
@ -285,9 +283,8 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
/* well, possibly buggy BIOS... try to shut /* well, possibly buggy BIOS... try to shut
* it down, and hope nothing goes too wrong * it down, and hope nothing goes too wrong
*/ */
printk(KERN_WARNING "%s %s: BIOS handoff " dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
"failed (BIOS bug ?) %08x\n", " (BIOS bug?) %08x\n", cap);
pdev->dev.bus_id, "EHCI", cap);
pci_write_config_byte(pdev, offset + 2, 0); pci_write_config_byte(pdev, offset + 2, 0);
} }
@ -306,17 +303,14 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
cap = 0; cap = 0;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
printk(KERN_WARNING "%s %s: unrecognized " dev_warn(&pdev->dev, "EHCI: unrecognized capability "
"capability %02x\n", "%02x\n", cap & 0xff);
pdev->dev.bus_id, "EHCI",
cap & 0xff);
break; break;
} }
offset = (cap >> 8) & 0xff; offset = (cap >> 8) & 0xff;
} }
if (!count) if (!count)
printk(KERN_DEBUG "%s %s: capability loop?\n", dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n");
pdev->dev.bus_id, "EHCI");
/* /*
* halt EHCI & disable its interrupts in any case * halt EHCI & disable its interrupts in any case

44
include/linux/aspm.h Normal file
View file

@ -0,0 +1,44 @@
/*
* aspm.h
*
* PCI Express ASPM defines and function prototypes
*
* Copyright (C) 2007 Intel Corp.
* Zhang Yanmin (yanmin.zhang@intel.com)
* Shaohua Li (shaohua.li@intel.com)
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
*
* PCI Express Specification
*/
#ifndef LINUX_ASPM_H
#define LINUX_ASPM_H
#include <linux/pci.h>
#define PCIE_LINK_STATE_L0S 1
#define PCIE_LINK_STATE_L1 2
#define PCIE_LINK_STATE_CLKPM 4
#ifdef CONFIG_PCIEASPM
extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
#else
#define pcie_aspm_init_link_state(pdev) do {} while (0)
#define pcie_aspm_exit_link_state(pdev) do {} while (0)
#define pcie_aspm_pm_state_change(pdev) do {} while (0)
#define pci_disable_link_state(pdev, state) do {} while (0)
#endif
#ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */
extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
#else
#define pcie_aspm_create_sysfs_dev_files(pdev) do {} while (0)
#define pcie_aspm_remove_sysfs_dev_files(pdev) do {} while (0)
#endif
#endif /* LINUX_ASPM_H */

View file

@ -48,7 +48,15 @@
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags);
extern acpi_status pci_osc_support_set(u32 flags); extern acpi_status __pci_osc_support_set(u32 flags, const char *hid);
static inline acpi_status pci_osc_support_set(u32 flags)
{
return __pci_osc_support_set(flags, PCI_ROOT_HID_STRING);
}
static inline acpi_status pcie_osc_support_set(u32 flags)
{
return __pci_osc_support_set(flags, PCI_EXPRESS_ROOT_HID_STRING);
}
#else #else
#if !defined(AE_ERROR) #if !defined(AE_ERROR)
typedef u32 acpi_status; typedef u32 acpi_status;
@ -57,6 +65,7 @@ typedef u32 acpi_status;
static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
{return AE_ERROR;} {return AE_ERROR;}
static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;}
static inline acpi_status pcie_osc_support_set(u32 flags) {return AE_ERROR;}
#endif #endif
#endif /* _PCI_ACPI_H_ */ #endif /* _PCI_ACPI_H_ */

View file

@ -28,7 +28,7 @@
* 7:3 = slot * 7:3 = slot
* 2:0 = function * 2:0 = function
*/ */
#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07) #define PCI_FUNC(devfn) ((devfn) & 0x07)
@ -66,7 +66,6 @@ enum pci_mmap_state {
#define PCI_DMA_FROMDEVICE 2 #define PCI_DMA_FROMDEVICE 2
#define PCI_DMA_NONE 3 #define PCI_DMA_NONE 3
#define DEVICE_COUNT_COMPATIBLE 4
#define DEVICE_COUNT_RESOURCE 12 #define DEVICE_COUNT_RESOURCE 12
typedef int __bitwise pci_power_t; typedef int __bitwise pci_power_t;
@ -129,6 +128,7 @@ struct pci_cap_saved_state {
u32 data[0]; u32 data[0];
}; };
struct pcie_link_state;
/* /*
* The pci_dev structure is used to describe PCI devices. * The pci_dev structure is used to describe PCI devices.
*/ */
@ -164,13 +164,13 @@ struct pci_dev {
this is D0-D3, D0 being fully functional, this is D0-D3, D0 being fully functional,
and D3 being off. */ and D3 being off. */
#ifdef CONFIG_PCIEASPM
struct pcie_link_state *link_state; /* ASPM link state. */
#endif
pci_channel_state_t error_state; /* current connectivity state */ pci_channel_state_t error_state; /* current connectivity state */
struct device dev; /* Generic device interface */ struct device dev; /* Generic device interface */
/* device is compatible with these IDs */
unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];
int cfg_size; /* Size of configuration space */ int cfg_size; /* Size of configuration space */
/* /*
@ -219,7 +219,7 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
} }
static inline struct pci_cap_saved_state *pci_find_saved_cap( static inline struct pci_cap_saved_state *pci_find_saved_cap(
struct pci_dev *pci_dev,char cap) struct pci_dev *pci_dev, char cap)
{ {
struct pci_cap_saved_state *tmp; struct pci_cap_saved_state *tmp;
struct hlist_node *pos; struct hlist_node *pos;
@ -278,13 +278,13 @@ struct pci_bus {
unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */
pci_bus_flags_t bus_flags; /* Inherited by child busses */ pci_bus_flags_t bus_flags; /* Inherited by child busses */
struct device *bridge; struct device *bridge;
struct class_device class_dev; struct device dev;
struct bin_attribute *legacy_io; /* legacy I/O for this bus */ struct bin_attribute *legacy_io; /* legacy I/O for this bus */
struct bin_attribute *legacy_mem; /* legacy mem */ struct bin_attribute *legacy_mem; /* legacy mem */
}; };
#define pci_bus_b(n) list_entry(n, struct pci_bus, node) #define pci_bus_b(n) list_entry(n, struct pci_bus, node)
#define to_pci_bus(n) container_of(n, struct pci_bus, class_dev) #define to_pci_bus(n) container_of(n, struct pci_bus, dev)
/* /*
* Error values that may be returned by PCI functions. * Error values that may be returned by PCI functions.
@ -314,8 +314,8 @@ struct pci_raw_ops {
extern struct pci_raw_ops *raw_pci_ops; extern struct pci_raw_ops *raw_pci_ops;
struct pci_bus_region { struct pci_bus_region {
unsigned long start; resource_size_t start;
unsigned long end; resource_size_t end;
}; };
struct pci_dynids { struct pci_dynids {
@ -351,11 +351,10 @@ enum pci_ers_result {
}; };
/* PCI bus error event callbacks */ /* PCI bus error event callbacks */
struct pci_error_handlers struct pci_error_handlers {
{
/* PCI bus error detected on this device */ /* PCI bus error detected on this device */
pci_ers_result_t (*error_detected)(struct pci_dev *dev, pci_ers_result_t (*error_detected)(struct pci_dev *dev,
enum pci_channel_state error); enum pci_channel_state error);
/* MMIO has been re-enabled, but not DMA */ /* MMIO has been re-enabled, but not DMA */
pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev);
@ -390,7 +389,7 @@ struct pci_driver {
struct pci_dynids dynids; struct pci_dynids dynids;
}; };
#define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
/** /**
* PCI_DEVICE - macro used to describe a specific pci device * PCI_DEVICE - macro used to describe a specific pci device
@ -448,7 +447,7 @@ extern int no_pci_devices(void);
void pcibios_fixup_bus(struct pci_bus *); void pcibios_fixup_bus(struct pci_bus *);
int __must_check pcibios_enable_device(struct pci_dev *, int mask); int __must_check pcibios_enable_device(struct pci_dev *, int mask);
char *pcibios_setup (char *str); char *pcibios_setup(char *str);
/* Used only when drivers/pci/setup.c is used */ /* Used only when drivers/pci/setup.c is used */
void pcibios_align_resource(void *, struct resource *, resource_size_t, void pcibios_align_resource(void *, struct resource *, resource_size_t,
@ -459,8 +458,10 @@ void pcibios_update_irq(struct pci_dev *, int irq);
extern struct pci_bus *pci_find_bus(int domain, int busnr); extern struct pci_bus *pci_find_bus(int domain, int busnr);
void pci_bus_add_devices(struct pci_bus *bus); void pci_bus_add_devices(struct pci_bus *bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) struct pci_ops *ops, void *sysdata);
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
void *sysdata)
{ {
struct pci_bus *root_bus; struct pci_bus *root_bus;
root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
@ -468,15 +469,18 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s
pci_bus_add_devices(root_bus); pci_bus_add_devices(root_bus);
return root_bus; return root_bus;
} }
struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_bus(struct device *parent, int bus,
struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
int busnr);
int pci_scan_slot(struct pci_bus *bus, int devfn); int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn);
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
unsigned int pci_scan_child_bus(struct pci_bus *bus); unsigned int pci_scan_child_bus(struct pci_bus *bus);
int __must_check pci_bus_add_device(struct pci_dev *dev); int __must_check pci_bus_add_device(struct pci_dev *dev);
void pci_read_bridge_bases(struct pci_bus *child); void pci_read_bridge_bases(struct pci_bus *child);
struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); struct resource *pci_find_parent_resource(const struct pci_dev *dev,
struct resource *res);
int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
extern struct pci_dev *pci_dev_get(struct pci_dev *dev); extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
extern void pci_dev_put(struct pci_dev *dev); extern void pci_dev_put(struct pci_dev *dev);
@ -489,15 +493,19 @@ extern void pci_sort_breadthfirst(void);
/* Generic PCI functions exported to card drivers */ /* Generic PCI functions exported to card drivers */
#ifdef CONFIG_PCI_LEGACY #ifdef CONFIG_PCI_LEGACY
struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
struct pci_dev __deprecated *pci_find_slot (unsigned int bus, unsigned int devfn); unsigned int device,
const struct pci_dev *from);
struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
unsigned int devfn);
#endif /* CONFIG_PCI_LEGACY */ #endif /* CONFIG_PCI_LEGACY */
int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_capability(struct pci_dev *dev, int cap);
int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability (struct pci_dev *dev, int cap); int pci_find_ext_capability(struct pci_dev *dev, int cap);
int pci_find_ht_capability (struct pci_dev *dev, int ht_cap); int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap); int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
void pcie_wait_pending_transaction(struct pci_dev *dev);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from); struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
@ -505,49 +513,58 @@ struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device,
struct pci_dev *from); struct pci_dev *from);
struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device, unsigned int ss_vendor, unsigned int ss_device,
struct pci_dev *from); struct pci_dev *from);
struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from);
int pci_dev_present(const struct pci_device_id *ids); int pci_dev_present(const struct pci_device_id *ids);
const struct pci_device_id *pci_find_present(const struct pci_device_id *ids); const struct pci_device_id *pci_find_present(const struct pci_device_id *ids);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn,
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); int where, u8 *val);
int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val); int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn,
int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val); int where, u16 *val);
int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 val); int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn,
int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 val); int where, u32 *val);
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 val);
int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 val);
int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
int where, u32 val);
static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
{ {
return pci_bus_read_config_byte (dev->bus, dev->devfn, where, val); return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
} }
static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val) static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
{ {
return pci_bus_read_config_word (dev->bus, dev->devfn, where, val); return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
} }
static inline int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val) static inline int pci_read_config_dword(struct pci_dev *dev, int where,
u32 *val)
{ {
return pci_bus_read_config_dword (dev->bus, dev->devfn, where, val); return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
} }
static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val) static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
{ {
return pci_bus_write_config_byte (dev->bus, dev->devfn, where, val); return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
} }
static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val) static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val)
{ {
return pci_bus_write_config_word (dev->bus, dev->devfn, where, val); return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
} }
static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val) static inline int pci_write_config_dword(struct pci_dev *dev, int where,
u32 val)
{ {
return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val); return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
} }
int __must_check pci_enable_device(struct pci_dev *dev); int __must_check pci_enable_device(struct pci_dev *dev);
int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); int __must_check pci_enable_device_io(struct pci_dev *dev);
int __must_check pci_enable_device_mem(struct pci_dev *dev);
int __must_check pci_reenable_device(struct pci_dev *); int __must_check pci_reenable_device(struct pci_dev *);
int __must_check pcim_enable_device(struct pci_dev *pdev); int __must_check pcim_enable_device(struct pci_dev *pdev);
void pcim_pin_device(struct pci_dev *pdev); void pcim_pin_device(struct pci_dev *pdev);
@ -576,14 +593,11 @@ int pcie_set_readrq(struct pci_dev *dev, int rq);
void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_assign_resource(struct pci_dev *dev, int i);
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
void pci_restore_bars(struct pci_dev *dev);
int pci_select_bars(struct pci_dev *dev, unsigned long flags); int pci_select_bars(struct pci_dev *dev, unsigned long flags);
/* ROM control related routines */ /* ROM control related routines */
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
void pci_remove_rom(struct pci_dev *pdev);
size_t pci_get_rom_size(void __iomem *rom, size_t size); size_t pci_get_rom_size(void __iomem *rom, size_t size);
/* Power management related routines */ /* Power management related routines */
@ -594,7 +608,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
/* Functions for PCI Hotplug drivers to use */ /* Functions for PCI Hotplug drivers to use */
int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
void pci_bus_assign_resources(struct pci_bus *bus); void pci_bus_assign_resources(struct pci_bus *bus);
@ -631,16 +645,18 @@ static inline int __must_check pci_register_driver(struct pci_driver *driver)
return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
} }
void pci_unregister_driver(struct pci_driver *); void pci_unregister_driver(struct pci_driver *dev);
void pci_remove_behind_bridge(struct pci_dev *); void pci_remove_behind_bridge(struct pci_dev *dev);
struct pci_driver *pci_dev_driver(const struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); struct pci_dev *dev);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
int pass);
void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
void *userdata); void *userdata);
int pci_cfg_space_size(struct pci_dev *dev); int pci_cfg_space_size(struct pci_dev *dev);
unsigned char pci_bus_max_busnr(struct pci_bus* bus); unsigned char pci_bus_max_busnr(struct pci_bus *bus);
/* kmem_cache style wrapper around pci_alloc_consistent() */ /* kmem_cache style wrapper around pci_alloc_consistent() */
@ -669,19 +685,36 @@ struct msix_entry {
#ifndef CONFIG_PCI_MSI #ifndef CONFIG_PCI_MSI
static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} static inline int pci_enable_msi(struct pci_dev *dev)
static inline void pci_disable_msi(struct pci_dev *dev) {} {
static inline int pci_enable_msix(struct pci_dev* dev, return -1;
struct msix_entry *entries, int nvec) {return -1;} }
static inline void pci_disable_msix(struct pci_dev *dev) {}
static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} static inline void pci_disable_msi(struct pci_dev *dev)
{ }
static inline int pci_enable_msix(struct pci_dev *dev,
struct msix_entry *entries, int nvec)
{
return -1;
}
static inline void pci_disable_msix(struct pci_dev *dev)
{ }
static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev)
{ }
static inline void pci_restore_msi_state(struct pci_dev *dev)
{ }
#else #else
extern int pci_enable_msi(struct pci_dev *dev); extern int pci_enable_msi(struct pci_dev *dev);
extern void pci_disable_msi(struct pci_dev *dev); extern void pci_disable_msi(struct pci_dev *dev);
extern int pci_enable_msix(struct pci_dev* dev, extern int pci_enable_msix(struct pci_dev *dev,
struct msix_entry *entries, int nvec); struct msix_entry *entries, int nvec);
extern void pci_disable_msix(struct pci_dev *dev); extern void pci_disable_msix(struct pci_dev *dev);
extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
extern void pci_restore_msi_state(struct pci_dev *dev);
#endif #endif
#ifdef CONFIG_HT_IRQ #ifdef CONFIG_HT_IRQ
@ -702,7 +735,11 @@ extern void pci_unblock_user_cfg_access(struct pci_dev *dev);
extern int pci_domains_supported; extern int pci_domains_supported;
#else #else
enum { pci_domains_supported = 0 }; enum { pci_domains_supported = 0 };
static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } static inline int pci_domain_nr(struct pci_bus *bus)
{
return 0;
}
static inline int pci_proc_domain(struct pci_bus *bus) static inline int pci_proc_domain(struct pci_bus *bus)
{ {
return 0; return 0;
@ -716,67 +753,161 @@ static inline int pci_proc_domain(struct pci_bus *bus)
* these as simple inline functions to avoid hair in drivers. * these as simple inline functions to avoid hair in drivers.
*/ */
#define _PCI_NOP(o,s,t) \ #define _PCI_NOP(o, s, t) \
static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ static inline int pci_##o##_config_##s(struct pci_dev *dev, \
int where, t val) \
{ return PCIBIOS_FUNC_NOT_SUPPORTED; } { return PCIBIOS_FUNC_NOT_SUPPORTED; }
#define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \
_PCI_NOP(o,word,u16 x) \ #define _PCI_NOP_ALL(o, x) _PCI_NOP(o, byte, u8 x) \
_PCI_NOP(o,dword,u32 x) _PCI_NOP(o, word, u16 x) \
_PCI_NOP(o, dword, u32 x)
_PCI_NOP_ALL(read, *) _PCI_NOP_ALL(read, *)
_PCI_NOP_ALL(write,) _PCI_NOP_ALL(write,)
static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) static inline struct pci_dev *pci_find_device(unsigned int vendor,
{ return NULL; } unsigned int device,
const struct pci_dev *from)
{
return NULL;
}
static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) static inline struct pci_dev *pci_find_slot(unsigned int bus,
{ return NULL; } unsigned int devfn)
{
return NULL;
}
static inline struct pci_dev *pci_get_device(unsigned int vendor, static inline struct pci_dev *pci_get_device(unsigned int vendor,
unsigned int device, struct pci_dev *from) unsigned int device,
{ return NULL; } struct pci_dev *from)
{
return NULL;
}
static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor,
unsigned int device, struct pci_dev *from) unsigned int device,
{ return NULL; } struct pci_dev *from)
{
return NULL;
}
static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, static inline struct pci_dev *pci_get_subsys(unsigned int vendor,
unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) unsigned int device,
{ return NULL; } unsigned int ss_vendor,
unsigned int ss_device,
struct pci_dev *from)
{
return NULL;
}
static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) static inline struct pci_dev *pci_get_class(unsigned int class,
{ return NULL; } struct pci_dev *from)
{
return NULL;
}
#define pci_dev_present(ids) (0) #define pci_dev_present(ids) (0)
#define no_pci_devices() (1) #define no_pci_devices() (1)
#define pci_find_present(ids) (NULL) #define pci_find_present(ids) (NULL)
#define pci_dev_put(dev) do { } while (0) #define pci_dev_put(dev) do { } while (0)
static inline void pci_set_master(struct pci_dev *dev) { } static inline void pci_set_master(struct pci_dev *dev)
static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } { }
static inline void pci_disable_device(struct pci_dev *dev) { }
static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; } static inline int pci_enable_device(struct pci_dev *dev)
static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;} {
static inline int __pci_register_driver(struct pci_driver *drv, struct module *owner) { return 0;} return -EIO;
static inline int pci_register_driver(struct pci_driver *drv) { return 0;} }
static inline void pci_unregister_driver(struct pci_driver *drv) { }
static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } static inline void pci_disable_device(struct pci_dev *dev)
static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } { }
static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
{
return -EIO;
}
static inline int pci_assign_resource(struct pci_dev *dev, int i)
{
return -EBUSY;
}
static inline int __pci_register_driver(struct pci_driver *drv,
struct module *owner)
{
return 0;
}
static inline int pci_register_driver(struct pci_driver *drv)
{
return 0;
}
static inline void pci_unregister_driver(struct pci_driver *drv)
{ }
static inline int pci_find_capability(struct pci_dev *dev, int cap)
{
return 0;
}
static inline int pci_find_next_capability(struct pci_dev *dev, u8 post,
int cap)
{
return 0;
}
static inline int pci_find_ext_capability(struct pci_dev *dev, int cap)
{
return 0;
}
static inline void pcie_wait_pending_transaction(struct pci_dev *dev)
{ }
/* Power management related routines */ /* Power management related routines */
static inline int pci_save_state(struct pci_dev *dev) { return 0; } static inline int pci_save_state(struct pci_dev *dev)
static inline int pci_restore_state(struct pci_dev *dev) { return 0; } {
static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { return 0; } return 0;
static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } }
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; }
static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) { return -EIO; } static inline int pci_restore_state(struct pci_dev *dev)
static inline void pci_release_regions(struct pci_dev *dev) { } {
return 0;
}
static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
return 0;
}
static inline pci_power_t pci_choose_state(struct pci_dev *dev,
pm_message_t state)
{
return PCI_D0;
}
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
int enable)
{
return 0;
}
static inline int pci_request_regions(struct pci_dev *dev, const char *res_name)
{
return -EIO;
}
static inline void pci_release_regions(struct pci_dev *dev)
{ }
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } static inline void pci_block_user_cfg_access(struct pci_dev *dev)
static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } { }
static inline void pci_unblock_user_cfg_access(struct pci_dev *dev)
{ }
static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from) static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
{ return NULL; } { return NULL; }
@ -797,27 +928,27 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
/* these helpers provide future and backwards compatibility /* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */ * for accessing popular PCI BAR info */
#define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start) #define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
#define pci_resource_end(dev,bar) ((dev)->resource[(bar)].end) #define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
#define pci_resource_flags(dev,bar) ((dev)->resource[(bar)].flags) #define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
#define pci_resource_len(dev,bar) \ #define pci_resource_len(dev,bar) \
((pci_resource_start((dev),(bar)) == 0 && \ ((pci_resource_start((dev), (bar)) == 0 && \
pci_resource_end((dev),(bar)) == \ pci_resource_end((dev), (bar)) == \
pci_resource_start((dev),(bar))) ? 0 : \ pci_resource_start((dev), (bar))) ? 0 : \
\ \
(pci_resource_end((dev),(bar)) - \ (pci_resource_end((dev), (bar)) - \
pci_resource_start((dev),(bar)) + 1)) pci_resource_start((dev), (bar)) + 1))
/* Similar to the helpers above, these manipulate per-pci_dev /* Similar to the helpers above, these manipulate per-pci_dev
* driver-specific data. They are really just a wrapper around * driver-specific data. They are really just a wrapper around
* the generic device structure functions of these calls. * the generic device structure functions of these calls.
*/ */
static inline void *pci_get_drvdata (struct pci_dev *pdev) static inline void *pci_get_drvdata(struct pci_dev *pdev)
{ {
return dev_get_drvdata(&pdev->dev); return dev_get_drvdata(&pdev->dev);
} }
static inline void pci_set_drvdata (struct pci_dev *pdev, void *data) static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
{ {
dev_set_drvdata(&pdev->dev, data); dev_set_drvdata(&pdev->dev, data);
} }
@ -836,7 +967,7 @@ static inline char *pci_name(struct pci_dev *pdev)
*/ */
#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER #ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER
static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc, resource_size_t *start, const struct resource *rsrc, resource_size_t *start,
resource_size_t *end) resource_size_t *end)
{ {
*start = rsrc->start; *start = rsrc->start;
@ -888,9 +1019,9 @@ enum pci_fixup_pass {
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
void __iomem * const * pcim_iomap_table(struct pci_dev *pdev); void __iomem * const *pcim_iomap_table(struct pci_dev *pdev);
int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);

View file

@ -395,9 +395,17 @@
#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ #define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ #define PCI_EXP_LNKCAP 12 /* Link Capabilities */
#define PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */
#define PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */
#define PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */
#define PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */
#define PCI_EXP_LNKCTL 16 /* Link Control */ #define PCI_EXP_LNKCTL 16 /* Link Control */
#define PCI_EXP_LNKCTL_RL 0x20 /* Retrain Link */
#define PCI_EXP_LNKCTL_CCC 0x40 /* Common Clock COnfiguration */
#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ #define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */
#define PCI_EXP_LNKSTA 18 /* Link Status */ #define PCI_EXP_LNKSTA 18 /* Link Status */
#define PCI_EXP_LNKSTA_LT 0x800 /* Link Training */
#define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */
#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ #define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
#define PCI_EXP_SLTCTL 24 /* Slot Control */ #define PCI_EXP_SLTCTL 24 /* Slot Control */
#define PCI_EXP_SLTSTA 26 /* Slot Status */ #define PCI_EXP_SLTSTA 26 /* Slot Status */