提交 215e871a 编写于 作者: L Linus Torvalds

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()
  ...
......@@ -274,8 +274,6 @@ the PCI device by calling pci_enable_device(). This will:
o allocate an IRQ (if BIOS did not).
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
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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"
10. MMIO Space and "Write Posting"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Converting a driver from using I/O Port space to using MMIO space
......
......@@ -318,11 +318,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
bool
default y
......
......@@ -577,11 +577,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
def_bool PCI
......
......@@ -322,11 +322,6 @@ config PCI
onboard. If you have one of these boards and you wish to use the PCI
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
bool "Reserve DMA coherent memory"
depends on PCI && !MMU
......
......@@ -359,11 +359,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
prompt "PCI access mode"
depends on PCI
......
......@@ -145,11 +145,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
bool "Macintosh support"
depends on !MMU_SUN3
......
......@@ -1961,11 +1961,6 @@ config PCI
your box. Other bus systems are ISA, EISA, or 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
bool
......
......@@ -6,11 +6,6 @@ config PCI
bus system, i.e. the way the CPU talks to the other stuff inside
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
bool "Cache and PCI noncoherent"
depends on PCI
......
......@@ -351,11 +351,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
def_bool PCI
......
......@@ -1369,11 +1369,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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
prompt "PCI access mode"
depends on X86_32 && PCI && !X86_VISWS
......
......@@ -30,8 +30,8 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
if (!(word & (1 << 13))) {
printk(KERN_INFO "Intel E7520/7320/7525 detected. "
"Disabling irq balancing and affinity\n");
dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
"disabling irq balancing and affinity\n");
#ifdef CONFIG_IRQBALANCE
irqbalance_disable("");
#endif
......@@ -104,14 +104,16 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0xF0, &rcba);
rcba &= 0xFFFFC000;
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;
}
/* use bits 31:14, 16 kB aligned */
rcba_base = ioremap_nocache(rcba, 0x4000);
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;
}
......@@ -122,8 +124,8 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
/* HPET is enabled in HPTC. Just not reported by BIOS */
val = val & 0x3;
force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
"0x%lx\n", force_hpet_address);
iounmap(rcba_base);
return;
}
......@@ -142,11 +144,12 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
if (err) {
force_hpet_address = 0;
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 {
force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
"0x%lx\n", force_hpet_address);
}
}
......@@ -208,8 +211,8 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
if (val & 0x4) {
val &= 0x3;
force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
force_hpet_address);
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 */
val &= 0x3;
force_hpet_address = 0xFED00000 | (val << 12);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
"0x%lx\n", force_hpet_address);
cached_dev = dev;
force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
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) {
force_hpet_address = (val & ~0x3ff);
printk(KERN_DEBUG "HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "HPET at 0x%lx\n",
force_hpet_address);
return;
}
......@@ -309,14 +312,14 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0x68, &val);
if (val & 0x80) {
force_hpet_address = (val & ~0x3ff);
printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
force_hpet_address);
dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at "
"0x%lx\n", force_hpet_address);
cached_dev = dev;
force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
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,
......@@ -344,7 +347,7 @@ static void nvidia_force_enable_hpet(struct pci_dev *dev)
pci_read_config_dword(dev, 0x44, &val);
force_hpet_address = val & 0xfffffffe;
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);
cached_dev = dev;
return;
......
......@@ -17,7 +17,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
int pxb, reg;
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;
for(pxb = 0; pxb < 2; pxb++) {
pci_read_config_byte(d, reg++, &busno);
......@@ -41,7 +41,7 @@ static void __devinit pci_fixup_i450gx(struct pci_dev *d)
*/
u8 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);
pcibios_last_bus = -1;
}
......@@ -55,7 +55,7 @@ static void __devinit pci_fixup_umc_ide(struct pci_dev *d)
*/
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++)
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
*/
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;
}
}
......@@ -80,7 +80,7 @@ static void __devinit pci_fixup_latency(struct pci_dev *d)
* SiS 5597 and 5598 chipsets require latency timer set to
* 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;
}
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);
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);
v &= mask;
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
*/
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);
}
}
......@@ -348,7 +348,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
pci_read_config_word(pdev, PCI_COMMAND, &config);
if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
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);
......@@ -388,11 +388,11 @@ static void __devinit pci_fixup_msi_k8t_onboard_sound(struct pci_dev *dev)
/* verify the change for status output */
pci_read_config_byte(dev, 0x50, &val);
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");
else
printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, "
"enabled onboard soundcard.\n");
dev_info(&dev->dev, "Detected MSI K8T Neo2-FIR; "
"enabled onboard soundcard\n");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
......
......@@ -174,11 +174,6 @@ config PCI
your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
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"
config HOTPLUG
......
......@@ -229,7 +229,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
return -ENOMEM;
/* 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");
return -ENODEV;
}
......
......@@ -492,7 +492,7 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev,
iface->pdev = pdev;
iface->bar = bar;
rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar);
rc = pci_enable_device_io(iface->pdev);
if (rc)
goto errout_free;
......
......@@ -156,8 +156,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
ide_setup_pci_noise(dev, d);
/* 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 */
if (pci_enable_device_bars(dev, 1<<2)) {
* BARS too and we will freak out other bits of the kernel
*
* 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);
return -ENODEV;
}
......
......@@ -228,7 +228,9 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
* @d: IDE port info
*
* 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
*/
......@@ -238,7 +240,7 @@ static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
int ret;
if (pci_enable_device(dev)) {
ret = pci_enable_device_bars(dev, 1 << 4);
ret = pci_enable_device_io(dev);
if (ret < 0) {
printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
"Could not enable device.\n", d->name);
......
......@@ -108,6 +108,7 @@ int pci_bus_add_device(struct pci_dev *dev)
void pci_bus_add_devices(struct pci_bus *bus)
{
struct pci_dev *dev;
struct pci_bus *child_bus;
int retval;
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);
}
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)
dev_err(&dev->dev, "Error creating sysfs "
"bridge symlink, continuing...\n");
dev_err(&dev->dev, "Error registering pci_bus"
" 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);
}
EXPORT_SYMBOL_GPL(pci_walk_bus);
EXPORT_SYMBOL(pci_bus_alloc_resource);
EXPORT_SYMBOL_GPL(pci_bus_add_device);
......
......@@ -25,6 +25,7 @@
#include <linux/pci.h>
#include <linux/dmar.h>
#include "iova.h"
#undef PREFIX
#define PREFIX "DMAR:"
......@@ -263,8 +264,8 @@ parse_dmar_table(void)
if (!dmar)
return -ENODEV;
if (!dmar->width) {
printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
if (dmar->width < PAGE_SHIFT_4K - 1) {
printk(KERN_WARNING PREFIX "Invalid DMAR haw\n");
return -EINVAL;
}
......@@ -301,11 +302,24 @@ parse_dmar_table(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)) {
printk(KERN_INFO PREFIX "No DMAR devices found\n");
return -ENODEV;
}
if (list_empty(&dmar_rmrr_units)) {
printk(KERN_INFO PREFIX "No RMRR found\n");
return -ENODEV;
}
return 0;
}
......
......@@ -3,8 +3,8 @@
#
menuconfig HOTPLUG_PCI
tristate "Support for PCI Hotplug (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL && HOTPLUG
tristate "Support for PCI Hotplug"
depends on PCI && HOTPLUG
---help---
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
......
......@@ -3,7 +3,6 @@
#
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_IBM) += ibmphp.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_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
ifdef CONFIG_HOTPLUG_PCI_CPCI
......
......@@ -113,7 +113,6 @@ struct acpiphp_slot {
u8 device; /* pci device# */
u32 sun; /* ACPI _SUN (slot unique number) */
u32 slotno; /* slot number relative to bridge */
u32 flags; /* see below */
};
......
......@@ -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
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
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);
dbg("%s: re-enumerating slots under %s\n",
__FUNCTION__, objname);
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
acpiphp_check_bridge(bridge);
}
return AE_OK ;
......
......@@ -39,6 +39,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "../pci.h"
#if !defined(MODULE)
......@@ -63,10 +64,16 @@ struct dummy_slot {
struct list_head node;
struct hotplug_slot *slot;
struct pci_dev *dev;
struct work_struct remove_work;
unsigned long removed;
};
static int debug;
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 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];
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)
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);
}
/* 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
* @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);
}
/* 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)
{
/* 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;
}
......@@ -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");
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 */
if (!(dslot->dev->devfn & 7)) {
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 */
pci_remove_bus_device(dslot->dev);
/* blow away this sysfs entry and other parts. */
remove_slot(dslot);
/* queue work item to blow away this sysfs entry and other parts. */
INIT_WORK(&dslot->remove_work, remove_slot_worker);
queue_work(dummyphp_wq, &dslot->remove_work);
return 0;
}
......@@ -340,6 +366,7 @@ static void cleanup_slots (void)
struct list_head *next;
struct dummy_slot *dslot;
destroy_workqueue(dummyphp_wq);
list_for_each_safe (tmp, next, &slot_list) {
dslot = list_entry (tmp, struct dummy_slot, node);
remove_slot(dslot);
......@@ -351,6 +378,10 @@ static int __init dummyphp_init(void)
{
info(DRIVER_DESC "\n");
dummyphp_wq = create_singlethread_workqueue(MY_NAME);
if (!dummyphp_wq)
return -ENOMEM;
return pci_scan_buses();
}
......
......@@ -761,10 +761,13 @@ static void ibm_unconfigure_device(struct pci_func *func)
debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
for (j = 0; j < 0x08; j++) {
temp = pci_find_slot(func->busno, (func->device << 3) | j);
if (temp)
temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
if (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)))
flag = 1;
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));
if (func->dev == NULL) {
......@@ -836,7 +839,7 @@ static int ibm_configure_device(struct pci_func *func)
if (num)
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));
if (func->dev == NULL) {
err("ERROR... : pci_dev still NULL\n");
......
......@@ -137,7 +137,7 @@ static int get_##name (struct hotplug_slot *slot, type *value) \
int retval = 0; \
if (try_module_get(ops->owner)) { \
if (ops->get_##name) \
retval = ops->get_##name (slot, value); \
retval = ops->get_##name(slot, value); \
else \
*value = slot->info->name; \
module_put(ops->owner); \
......@@ -625,7 +625,7 @@ int pci_hp_register (struct hotplug_slot *slot)
if ((slot->info == NULL) || (slot->ops == NULL))
return -EINVAL;
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");
return -EINVAL;
}
......
......@@ -82,24 +82,18 @@ struct event_info {
};
struct controller {
struct controller *next;
struct mutex crit_sect; /* critical section mutex */
struct mutex ctrl_lock; /* controller lock */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct list_head slot_list;
struct slot *slot;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 bus;
u8 device;
u8 function;
u8 slot_device_offset;
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 ctrlcap;
u16 vendor_id;
u8 cap_base;
struct timer_list poll_timer;
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 void pciehp_queue_pushbutton_work(struct work_struct *work);
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)
{
......
......@@ -453,13 +453,9 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
pci_set_drvdata(pdev, ctrl);
ctrl->bus = pdev->bus->number; /* ctrl bus */
ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
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);
dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
__FUNCTION__, pdev->bus->number, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn), pdev->irq);
/* Setup the slot information structures */
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->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) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
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)
{
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;
}
#endif
......
......@@ -37,8 +37,6 @@
#include "pciehp.h"
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)
{
......@@ -197,12 +195,6 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
__FUNCTION__);
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)
{
u8 hp_slot;
int retval = 0;
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",
__FUNCTION__, p_slot->device,
ctrl->slot_device_offset, hp_slot);
ctrl->slot_device_offset, p_slot->hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) {
/* Power on slot */
......@@ -281,8 +270,6 @@ static int board_added(struct slot *p_slot)
*/
static int remove_board(struct slot *p_slot)
{
u8 device;
u8 hp_slot;
int retval = 0;
struct controller *ctrl = p_slot->ctrl;
......@@ -290,11 +277,7 @@ static int remove_board(struct slot *p_slot)
if (retval)
return retval;
device = p_slot->device;
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);
dbg("In %s, hp_slot = %d\n", __FUNCTION__, p_slot->hp_slot);
if (POWER_CTRL(ctrl->ctrlcap)) {
/* power off slot */
......@@ -621,12 +604,6 @@ int pciehp_disable_slot(struct slot *p_slot)
mutex_unlock(&p_slot->ctrl->crit_sect);
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);
......
......@@ -636,15 +636,57 @@ static int hpc_power_on_slot(struct slot * slot)
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)
{
struct controller *ctrl = slot->ctrl;
u16 slot_cmd;
u16 cmd_mask;
int retval = 0;
int changed;
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;
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",
__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;
}
......@@ -1067,13 +1119,143 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
}
#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;
u16 temp_word;
u16 cap_reg;
u16 intr_enable = 0;
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;
u16 slot_status, slot_ctrl;
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",
__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__);
goto abort_free_ctlr;
goto abort;
}
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);
if (rc) {
err("%s: Cannot read CAPREG register\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: CAPREG offset %x cap_reg %x\n",
__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))) {
dbg("%s : This is not a root port or the port is not "
"connected to a slot\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
if (rc) {
err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: SLOTCAP offset %x slot_cap %x\n",
__FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap);
if (!(slot_cap & HP_CAP)) {
dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
/* For debugging purpose */
rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (rc) {
err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: SLOTSTATUS offset %x slot_status %x\n",
__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);
if (rc) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
__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->ctrlcap = slot_cap & 0x0000007f;
/* Mask Hot-plug Interrupt Enable */
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (rc) {
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;
}
rc = pcie_init_hardware_part1(ctrl, dev);
if (rc)
goto abort;
if (pciehp_poll_mode) {
/* 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) {
err("Can't get irq %d for the hotplug controller\n",
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,
......@@ -1224,82 +1380,16 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
}
}
rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
if (rc) {
err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
goto abort_free_irq;
rc = pcie_init_hardware_part2(ctrl, dev);
if (rc == 0) {
ctrl->hpc_ops = &pciehp_hpc_ops;
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:
if (pciehp_poll_mode)
del_timer_sync(&ctrl->poll_timer);
else
free_irq(ctrl->pci_dev->irq, ctrl);
abort_free_ctlr:
abort:
return -1;
}
......@@ -105,12 +105,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
}
/* Find Advanced Error Reporting Enhanced Capability */
pos = 256;
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)));
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return;
......@@ -248,11 +243,15 @@ int pciehp_unconfigure_device(struct slot *p_slot)
u8 bctl = 0;
u8 presence = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
u16 command;
dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
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,
(p_slot->device << 3) | j);
if (!temp)
......@@ -263,21 +262,26 @@ int pciehp_unconfigure_device(struct slot *p_slot)
pci_dev_put(temp);
continue;
}
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot,
&presence);
if (!ret && presence) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL,
&bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) {
err("Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
continue;
}
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) {
err("Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
continue;
}
}
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);
}
/*
......@@ -288,4 +292,3 @@ int pciehp_unconfigure_device(struct slot *p_slot)
return rc;
}
......@@ -74,7 +74,6 @@ struct slot {
u32 type;
u32 power_domain;
char *name;
char *location;
struct device_node *dn;
struct pci_bus *bus;
struct list_head *pci_devs;
......
......@@ -64,19 +64,6 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state)
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
* @slot: target &slot
......@@ -115,7 +102,6 @@ int rpaphp_enable_slot(struct slot *slot)
info->adapter_status = EMPTY;
slot->bus = bus;
slot->pci_devs = &bus->devices;
set_slot_name(slot);
/* if there's an adapter in the slot, go add the pci devices */
if (state == PRESENT) {
......
......@@ -33,23 +33,31 @@
#include <asm/rtas.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 = -ENOENT;
int retval;
struct slot *slot = (struct slot *)php_slot->private;
struct pci_bus *bus;
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;
}
static struct hotplug_slot_attribute php_attr_location = {
.attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
.show = location_read_file,
static struct hotplug_slot_attribute php_attr_address = {
.attr = {.name = "address", .mode = S_IFREG | S_IRUGO},
.show = address_read_file,
};
/* 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->name);
kfree(slot->hotplug_slot);
kfree(slot->location);
kfree(slot);
}
......@@ -83,16 +90,13 @@ struct slot *alloc_slot_struct(struct device_node *dn,
GFP_KERNEL);
if (!slot->hotplug_slot->info)
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)
goto error_info;
slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL);
if (!slot->location)
goto error_name;
slot->name = slot->hotplug_slot->name;
strcpy(slot->name, drc_name);
slot->dn = dn;
slot->index = drc_index;
strcpy(slot->location, drc_name);
slot->power_domain = power_domain;
slot->hotplug_slot->private = slot;
slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops;
......@@ -100,8 +104,6 @@ struct slot *alloc_slot_struct(struct device_node *dn,
return (slot);
error_name:
kfree(slot->hotplug_slot->name);
error_info:
kfree(slot->hotplug_slot->info);
error_hpslot:
......@@ -133,8 +135,8 @@ int rpaphp_deregister_slot(struct slot *slot)
list_del(&slot->rpaphp_slot_list);
/* remove "phy_location" file */
sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr);
/* remove "address" file */
sysfs_remove_file(&php_slot->kobj, &php_attr_address.attr);
retval = pci_hp_deregister(php_slot);
if (retval)
......@@ -166,8 +168,8 @@ int rpaphp_register_slot(struct slot *slot)
return retval;
}
/* create "phy_location" file */
retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr);
/* create "address" file */
retval = sysfs_create_file(&php_slot->kobj, &php_attr_address.attr);
if (retval) {
err("sysfs_create_file failed with error %d\n", retval);
goto sysfs_fail;
......@@ -175,8 +177,7 @@ int rpaphp_register_slot(struct slot *slot)
/* add slot to our internal list */
list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
info("Slot [%s](PCI location=%s) registered\n", slot->name,
slot->location);
info("Slot [%s] registered\n", slot->name);
return 0;
sysfs_fail:
......
......@@ -597,7 +597,7 @@ static void hpc_release_ctlr(struct controller *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 |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
......
......@@ -1781,7 +1781,7 @@ __intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
/*
* First try to allocate an io virtual address in
* 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);
if (!iova)
......
......@@ -25,6 +25,51 @@
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)
{
int pos;
......@@ -230,7 +275,6 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable)
pci_intx(dev, enable);
}
#ifdef CONFIG_PM
static void __pci_restore_msi_state(struct pci_dev *dev)
{
int pos;
......@@ -288,7 +332,7 @@ void pci_restore_msi_state(struct pci_dev *dev)
__pci_restore_msi_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
......@@ -683,49 +727,3 @@ void pci_msi_init_pci_dev(struct pci_dev *dev)
{
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);
}
}
......@@ -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
*
* Update OS support fields and doing a _OSC Query to obtain an update
* 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;
acpi_status retval;
......@@ -176,7 +176,7 @@ acpi_status pci_osc_support_set(u32 flags)
temp = ctrlset_buf[OSC_CONTROL_TYPE];
ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
acpi_get_devices ( PCI_ROOT_HID_STRING,
acpi_get_devices(hid,
acpi_query_osc,
ctrlset_buf,
(void **) &retval );
......@@ -188,7 +188,6 @@ acpi_status pci_osc_support_set(u32 flags)
}
return AE_OK;
}
EXPORT_SYMBOL(pci_osc_support_set);
/**
* pci_osc_control_set - commit requested control to Firmware
......
......@@ -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));
/* And set default memory allocation policy */
oldpol = current->mempolicy;
current->mempolicy = &default_policy;
mpol_get(current->mempolicy);
current->mempolicy = NULL; /* fall back to system default policy */
#endif
error = drv->probe(dev, id);
#ifdef CONFIG_NUMA
set_cpus_allowed(current, oldmask);
mpol_free(current->mempolicy);
current->mempolicy = oldpol;
#endif
return error;
......
......@@ -21,6 +21,7 @@
#include <linux/topology.h>
#include <linux/mm.h>
#include <linux/capability.h>
#include <linux/aspm.h>
#include "pci.h"
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)
{
struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device,
struct device,
kobj));
/* 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)
{
struct pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device,
struct device,
kobj));
/* Only support 1, 2 or 4 byte accesses */
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 pci_bus *bus = to_pci_bus(container_of(kobj,
struct class_device,
struct device,
kobj));
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))
goto err_rom_file;
pcie_aspm_create_sysfs_dev_files(pdev);
return 0;
err_rom_file:
......@@ -679,6 +682,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
if (!sysfs_initialized)
return;
pcie_aspm_remove_sysfs_dev_files(pdev);
if (pdev->cfg_size < 4096)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
......
......@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/log2.h>
#include <linux/aspm.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#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);
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
* @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
* accessible by its driver.
*/
void
static void
pci_restore_bars(struct pci_dev *dev)
{
int i, numres;
......@@ -501,6 +520,9 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (need_restore)
pci_restore_bars(dev);
if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0;
}
......@@ -551,6 +573,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
int pos, i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
int found = 0;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
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);
if (!save_state)
save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL);
else
found = 1;
if (!save_state) {
dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
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_SLTCTL, &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;
}
......@@ -597,14 +624,17 @@ static int pci_save_pcix_state(struct pci_dev *dev)
int pos, i = 0;
struct pci_cap_saved_state *save_state;
u16 *cap;
int found = 0;
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (pos <= 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)
save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL);
else
found = 1;
if (!save_state) {
dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
return -ENOMEM;
......@@ -612,7 +642,9 @@ static int pci_save_pcix_state(struct pci_dev *dev)
cap = (u16 *)&save_state->data[0];
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;
}
......@@ -713,29 +745,51 @@ int pci_reenable_device(struct pci_dev *dev)
return 0;
}
/**
* pci_enable_device_bars - Initialize some of a device for use
* @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)
static int __pci_enable_device_flags(struct pci_dev *dev,
resource_size_t flags)
{
int err;
int i, bars = 0;
if (atomic_add_return(1, &dev->enable_cnt) > 1)
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);
if (err < 0)
atomic_dec(&dev->enable_cnt);
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.
* @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)
{
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)
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);
if (pci_command & PCI_COMMAND_MASTER) {
pci_command &= ~PCI_COMMAND_MASTER;
......@@ -1619,9 +1676,9 @@ early_param("pci", pci_setup);
device_initcall(pci_init);
EXPORT_SYMBOL_GPL(pci_restore_bars);
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(pcim_enable_device);
EXPORT_SYMBOL(pcim_pin_device);
......
......@@ -6,8 +6,10 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev,
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_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) { }
#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
void pci_no_aer(void);
#else
......@@ -68,14 +64,14 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
}
extern int pcie_mch_quirk;
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 device id structure
* @id: single PCI device id structure to match
* @dev: the PCI device structure to match against
*
*
* Returns the matching pci_device_id structure or %NULL if there is no match.
*/
static inline const struct pci_device_id *
......
......@@ -26,3 +26,23 @@ config HOTPLUG_PCI_PCIE
When in doubt, say N.
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.
......@@ -2,6 +2,9 @@
# 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
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
......
......@@ -31,26 +31,16 @@ int aer_osc_setup(struct pcie_device *pciedev)
{
acpi_status status = AE_NOT_FOUND;
struct pci_dev *pdev = pciedev->port;
acpi_handle handle = DEVICE_ACPI_HANDLE(&pdev->dev);
struct pci_bus *parent;
acpi_handle handle = 0;
while (!handle) {
if (!pdev || !pdev->bus->parent)
break;
parent = pdev->bus->parent;
if (!parent->self)
/* 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;
}
/* Find root host bridge */
while (pdev->bus && pdev->bus->self)
pdev = pdev->bus->self;
handle = acpi_get_pci_rootbridge_handle(
pci_domain_nr(pdev->bus), pdev->bus->number);
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,
OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
......
此差异已折叠。
......@@ -192,9 +192,8 @@ static int get_port_device_capability(struct pci_dev *dev)
if (reg32 & SLOT_HP_CAPABLE_MASK)
services |= PCIE_PORT_SERVICE_HP;
}
/* PME Capable */
pos = pci_find_capability(dev, PCI_CAP_ID_PME);
if (pos)
/* PME Capable - root port capability */
if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
services |= PCIE_PORT_SERVICE_PME;
pos = PCI_CFG_SPACE_SIZE;
......
......@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/cpumask.h>
#include <linux/aspm.h>
#include "pci.h"
#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->read = pci_read_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 */
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->attr.mode = S_IRUSR | S_IWUSR;
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)
{
if (b->legacy_io) {
class_device_remove_bin_file(&b->class_dev, b->legacy_io);
class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
device_remove_bin_file(&b->dev, b->legacy_io);
device_remove_bin_file(&b->dev, b->legacy_mem);
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
*/
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)
{
int ret;
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);
if (ret < PAGE_SIZE)
buf[ret++] = '\n';
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
*/
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)
put_device(pci_bus->bridge);
......@@ -109,7 +111,7 @@ static void release_pcibus_dev(struct class_device *class_dev)
static struct class pcibus_class = {
.name = "pci_bus",
.release = &release_pcibus_dev,
.dev_release = &release_pcibus_dev,
};
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;
int i;
int retval;
/*
* 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->bridge = get_device(&bridge->dev);
child->class_dev.class = &pcibus_class;
sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr);
retval = class_device_register(&child->class_dev);
if (retval)
goto error_register;
retval = class_device_create_file(&child->class_dev,
&class_device_attr_cpuaffinity);
if (retval)
goto error_file_create;
/* initialize some portions of the bus device, but don't register it
* now as the parent is not properly set up yet. This device will get
* registered later in pci_bus_add_devices()
*/
child->dev.class = &pcibus_class;
sprintf(child->dev.bus_id, "%04x:%02x", pci_domain_nr(child), busnr);
/*
* 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;
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)
......@@ -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.
* 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->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",
child->number, child->subordinate,
(bus->number > child->subordinate &&
bus->subordinate < child->number) ?
"wholly " : " partially",
bus->self->transparent ? " transparent" : " ",
"wholly" : "partially",
bus->self->transparent ? " transparent" : "",
bus->number, bus->subordinate);
}
bus = bus->parent;
......@@ -971,6 +961,7 @@ struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn)
return dev;
}
EXPORT_SYMBOL(pci_scan_single_device);
/**
* 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;
}
}
if (bus->self)
pcie_aspm_init_link_state(bus->self);
return nr;
}
......@@ -1103,32 +1098,27 @@ struct pci_bus * pci_create_bus(struct device *parent,
goto dev_reg_err;
b->bridge = get_device(dev);
b->class_dev.class = &pcibus_class;
sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus);
error = class_device_register(&b->class_dev);
b->dev.class = &pcibus_class;
b->dev.parent = b->bridge;
sprintf(b->dev.bus_id, "%04x:%02x", pci_domain_nr(b), bus);
error = device_register(&b->dev);
if (error)
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)
goto class_dev_create_file_err;
goto dev_create_file_err;
/* Create legacy_io and legacy_mem files for this bus */
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->resource[0] = &ioport_resource;
b->resource[1] = &iomem_resource;
return b;
sys_create_link_err:
class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity);
class_dev_create_file_err:
class_device_unregister(&b->class_dev);
dev_create_file_err:
device_unregister(&b->dev);
class_dev_reg_err:
device_unregister(dev);
dev_reg_err:
......@@ -1140,7 +1130,6 @@ struct pci_bus * pci_create_bus(struct device *parent,
kfree(b);
return NULL;
}
EXPORT_SYMBOL_GPL(pci_create_bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent,
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_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL(pci_scan_single_device);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
#endif
......
......@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
......@@ -202,15 +203,18 @@ struct pci_filp_private {
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;
#ifdef HAVE_PCI_MMAP
struct pci_filp_private *fpriv = file->private_data;
#endif /* HAVE_PCI_MMAP */
int ret = 0;
lock_kernel();
switch (cmd) {
case PCIIOC_CONTROLLER:
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;
};
unlock_kernel();
return ret;
}
......@@ -291,7 +296,7 @@ static const struct file_operations proc_bus_pci_operations = {
.llseek = proc_bus_pci_lseek,
.read = proc_bus_pci_read,
.write = proc_bus_pci_write,
.ioctl = proc_bus_pci_ioctl,
.unlocked_ioctl = proc_bus_pci_ioctl,
#ifdef HAVE_PCI_MMAP
.open = proc_bus_pci_open,
.release = proc_bus_pci_release,
......@@ -370,7 +375,7 @@ static int show_device(struct seq_file *m, void *v)
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,
.next = pci_seq_next,
.stop = pci_seq_stop,
......@@ -480,7 +485,3 @@ static int __init pci_proc_init(void)
__initcall(pci_proc_init);
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_proc_detach_bus);
#endif
此差异已折叠。
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/aspm.h>
#include "pci.h"
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;
up_write(&pci_bus_sem);
}
if (dev->bus->self)
pcie_aspm_exit_link_state(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);
up_write(&pci_bus_sem);
pci_remove_legacy_files(pci_bus);
class_device_remove_file(&pci_bus->class_dev,
&class_device_attr_cpuaffinity);
sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
class_device_unregister(&pci_bus->class_dev);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
device_unregister(&pci_bus->dev);
}
EXPORT_SYMBOL(pci_remove_bus);
......
......@@ -162,6 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
return rom;
}
#if 0
/**
* pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
* @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;
}
#endif /* 0 */
/**
* 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);
}
#if 0
/**
* pci_remove_rom - disable the ROM and remove its sysfs attribute
* @pdev: pointer to pci device struct
......@@ -236,6 +239,7 @@ void pci_remove_rom(struct pci_dev *pdev)
IORESOURCE_ROM_COPY)))
pci_disable_rom(pdev);
}
#endif /* 0 */
/**
* 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_copy);
EXPORT_SYMBOL(pci_unmap_rom);
EXPORT_SYMBOL(pci_remove_rom);
......@@ -89,8 +89,9 @@ void pci_setup_cardbus(struct pci_bus *bus)
* The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs.
*/
printk(" IO window: %08lx-%08lx\n",
region.start, region.end);
printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
(unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
region.start);
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]);
if (bus->resource[1]->flags & IORESOURCE_IO) {
printk(" IO window: %08lx-%08lx\n",
region.start, region.end);
printk(KERN_INFO " IO window: 0x%08lx-0x%08lx\n",
(unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start);
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]);
if (bus->resource[2]->flags & IORESOURCE_MEM) {
printk(" PREFETCH window: %08lx-%08lx\n",
region.start, region.end);
printk(KERN_INFO " PREFETCH window: 0x%08lx-0x%08lx\n",
(unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start);
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]);
if (bus->resource[3]->flags & IORESOURCE_MEM) {
printk(" MEM window: %08lx-%08lx\n",
region.start, region.end);
printk(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
(unsigned long)region.start,
(unsigned long)region.end);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start);
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_bus_region region;
u32 l, io_upper16;
u32 l, bu, lu, io_upper16;
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. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
DBG(KERN_INFO " IO window: %04lx-%04lx\n",
region.start, region.end);
(unsigned long)region.start,
(unsigned long)region.end);
}
else {
/* 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) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
DBG(KERN_INFO " MEM window: %08lx-%08lx\n",
region.start, region.end);
DBG(KERN_INFO " MEM window: 0x%08lx-0x%08lx\n",
(unsigned long)region.start,
(unsigned long)region.end);
}
else {
l = 0x0000fff0;
......@@ -195,12 +201,18 @@ pci_setup_bridge(struct pci_bus *bus)
pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
/* Set up PREF base/limit. */
bu = lu = 0;
pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n",
region.start, region.end);
#ifdef CONFIG_RESOURCES_64BIT
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 {
l = 0x0000fff0;
......@@ -208,8 +220,9 @@ pci_setup_bridge(struct pci_bus *bus)
}
pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
/* Clear out the upper 32 bits of PREF base. */
pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
/* Set the upper 32 bits of PREF base & limit. */
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);
}
......@@ -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)
{
struct pci_dev *dev;
unsigned long min_align, align, size;
unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
resource_size_t min_align, align, size;
resource_size_t aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order;
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++) {
struct resource *r = &dev->resource[i];
unsigned long r_size;
resource_size_t r_size;
if (r->parent || (r->flags & mask) != type)
continue;
......@@ -350,10 +363,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
order = __ffs(align) - 20;
if (order > 11) {
printk(KERN_WARNING "PCI: region %s/%d "
"too large: %llx-%llx\n",
"too large: 0x%016llx-0x%016llx\n",
pci_name(dev), i,
(unsigned long long)r->start,
(unsigned long long)r->end);
(unsigned long long)r->start,
(unsigned long long)r->end);
r->flags = 0;
continue;
}
......@@ -372,8 +385,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
align = 0;
min_align = 0;
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)
min_align = align1;
else if (ALIGN(align + min_align, min_align) < align1)
......
......@@ -51,10 +51,12 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
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,
(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);
if (res->flags & IORESOURCE_IO)
......@@ -125,7 +127,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
return err;
}
EXPORT_SYMBOL_GPL(pci_claim_resource);
int pci_assign_resource(struct pci_dev *dev, int resno)
{
......
......@@ -34,7 +34,6 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
if (!dev)
goto error;
lock_kernel();
switch (len) {
case 1:
cfg_ret = pci_user_read_config_byte(dev, off, &byte);
......@@ -47,10 +46,8 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn,
break;
default:
err = -EINVAL;
unlock_kernel();
goto error;
};
unlock_kernel();
err = -EIO;
if (cfg_ret != PCIBIOS_SUCCESSFUL)
......@@ -107,7 +104,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
if (!dev)
return -ENODEV;
lock_kernel();
switch(len) {
case 1:
err = get_user(byte, (u8 __user *)buf);
......@@ -140,7 +136,6 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
err = -EINVAL;
break;
}
unlock_kernel();
pci_dev_put(dev);
return err;
}
......@@ -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 lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
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");
if (pci_enable_device_bars(pdev, bars)) {
if (pci_enable_device_mem(pdev)) {
printk(KERN_ERR "lpfc: Cannot re-enable "
"PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
......
......@@ -2268,6 +2268,7 @@ typedef struct scsi_qla_host {
spinlock_t hardware_lock ____cacheline_aligned;
int bars;
int mem_only;
device_reg_t __iomem *iobase; /* Base I/O address */
resource_size_t pio_address;
#define MIN_IOBASE_LEN 0x100
......
......@@ -1564,7 +1564,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
char pci_info[30];
char fw_str[30];
struct scsi_host_template *sht;
int bars;
int bars, mem_only = 0;
bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
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) {
bars = pci_select_bars(pdev, IORESOURCE_MEM);
sht = &qla24xx_driver_template;
mem_only = 1;
}
if (pci_enable_device_bars(pdev, bars))
goto probe_out;
if (mem_only) {
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_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);
ha->parent = NULL;
ha->bars = bars;
ha->mem_only = mem_only;
/* Set ISP-type information. */
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;
scsi_qla_host_t *ha = pci_get_drvdata(pdev);
int rc;
if (ha->mem_only)
rc = pci_enable_device_mem(pdev);
else
rc = pci_enable_device(pdev);
if (pci_enable_device_bars(pdev, ha->bars)) {
if (rc) {
qla_printk(KERN_WARNING, ha,
"Can't re-enable PCI device after reset.\n");
......
......@@ -190,9 +190,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
msleep(10);
}
if (wait_time <= 0)
printk(KERN_WARNING "%s %s: BIOS handoff "
"failed (BIOS bug ?) %08x\n",
pdev->dev.bus_id, "OHCI",
dev_warn(&pdev->dev, "OHCI: BIOS handoff failed"
" (BIOS bug?) %08x\n",
readl(base + OHCI_CONTROL));
/* reset controller, preserving RWC */
......@@ -243,8 +242,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
switch (cap & 0xff) {
case 1: /* BIOS/SMM/... handoff support */
if ((cap & EHCI_USBLEGSUP_BIOS)) {
pr_debug("%s %s: BIOS handoff\n",
pdev->dev.bus_id, "EHCI");
dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n");
#if 0
/* 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
* it down, and hope nothing goes too wrong
*/
printk(KERN_WARNING "%s %s: BIOS handoff "
"failed (BIOS bug ?) %08x\n",
pdev->dev.bus_id, "EHCI", cap);
dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
" (BIOS bug?) %08x\n", cap);
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;
/* FALLTHROUGH */
default:
printk(KERN_WARNING "%s %s: unrecognized "
"capability %02x\n",
pdev->dev.bus_id, "EHCI",
cap & 0xff);
dev_warn(&pdev->dev, "EHCI: unrecognized capability "
"%02x\n", cap & 0xff);
break;
}
offset = (cap >> 8) & 0xff;
}
if (!count)
printk(KERN_DEBUG "%s %s: capability loop?\n",
pdev->dev.bus_id, "EHCI");
dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n");
/*
* halt EHCI & disable its interrupts in any case
......
/*
* 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 */
......@@ -48,7 +48,15 @@
#ifdef CONFIG_ACPI
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
#if !defined(AE_ERROR)
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)
{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 /* _PCI_ACPI_H_ */
此差异已折叠。
......@@ -395,9 +395,17 @@
#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#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_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_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_SLTCTL 24 /* Slot Control */
#define PCI_EXP_SLTSTA 26 /* Slot Status */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册