Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 22 Jun 2009 18:59:51 +0000 (11:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 22 Jun 2009 18:59:51 +0000 (11:59 -0700)
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (74 commits)
  PCI: make msi_free_irqs() to use msix_mask_irq() instead of open coded write
  PCI: Fix the NIU MSI-X problem in a better way
  PCI ASPM: remove get_root_port_link
  PCI ASPM: cleanup pcie_aspm_sanity_check
  PCI ASPM: remove has_switch field
  PCI ASPM: cleanup calc_Lx_latency
  PCI ASPM: cleanup pcie_aspm_get_cap_device
  PCI ASPM: cleanup clkpm checks
  PCI ASPM: cleanup __pcie_aspm_check_state_one
  PCI ASPM: cleanup initialization
  PCI ASPM: cleanup change input argument of aspm functions
  PCI ASPM: cleanup misc in struct pcie_link_state
  PCI ASPM: cleanup clkpm state in struct pcie_link_state
  PCI ASPM: cleanup latency field in struct pcie_link_state
  PCI ASPM: cleanup aspm state field in struct pcie_link_state
  PCI ASPM: fix typo in struct pcie_link_state
  PCI: drivers/pci/slot.c should depend on CONFIG_SYSFS
  PCI: remove redundant __msi_set_enable()
  PCI PM: consistently use type bool for wake enable variable
  x86/ACPI: Correct maximum allowed _CRS returned resources and warn if exceeded
  ...

1  2 
Documentation/kernel-parameters.txt
drivers/pci/Makefile
drivers/pci/hotplug/ibmphp_core.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/pci.c
drivers/pci/quirks.c
drivers/pci/setup-res.c
include/linux/pci.h

@@@ -48,7 -48,6 +48,7 @@@ parameter is applicable
        EFI     EFI Partitioning (GPT) is enabled
        EIDE    EIDE/ATAPI support is enabled.
        FB      The frame buffer device is enabled.
 +      GCOV    GCOV profiling is enabled.
        HW      Appropriate hardware is enabled.
        IA-64   IA-64 architecture is enabled.
        IMA     Integrity measurement architecture is enabled.
@@@ -57,6 -56,7 +57,6 @@@
        ISAPNP  ISA PnP code is enabled.
        ISDN    Appropriate ISDN support is enabled.
        JOY     Appropriate joystick support is enabled.
 -      KMEMTRACE kmemtrace is enabled.
        LIBATA  Libata driver is enabled
        LP      Printer support is enabled.
        LOOP    Loopback device support is enabled.
@@@ -329,6 -329,11 +329,6 @@@ and is between 256 and 4096 characters
                                    flushed before they will be reused, which
                                    is a lot of faster
  
 -      amd_iommu_size= [HW,X86-64]
 -                      Define the size of the aperture for the AMD IOMMU
 -                      driver. Possible values are:
 -                      '32M', '64M' (default), '128M', '256M', '512M', '1G'
 -
        amijoy.map=     [HW,JOY] Amiga joystick support
                        Map of devices attached to JOY0DAT and JOY1DAT
                        Format: <a>,<b>
                        Also note the kernel might malfunction if you disable
                        some critical bits.
  
 +      cmo_free_hint=  [PPC] Format: { yes | no }
 +                      Specify whether pages are marked as being inactive
 +                      when they are freed.  This is used in CMO environments
 +                      to determine OS memory pressure for page stealing by
 +                      a hypervisor.
 +                      Default: yes
 +
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
                        console=brl,ttyS0
                For now, only VisioBraille is supported.
  
 +      consoleblank=   [KNL] The console blank (screen saver) timeout in
 +                      seconds. Defaults to 10*60 = 10mins. A value of 0
 +                      disables the blank timer.
 +
        coredump_filter=
                        [KNL] Change the default value for
                        /proc/<pid>/coredump_filter.
                        DMA-API debugging code disables itself because the
                        architectural default is too low.
  
 +      dma_debug_driver=<driver_name>
 +                      With this option the DMA-API debugging driver
 +                      filter feature can be enabled at boot time. Just
 +                      pass the driver to filter for as the parameter.
 +                      The filter can be disabled or changed to another
 +                      driver later using sysfs.
 +
        dscc4.setup=    [NET]
  
        dtc3181e=       [HW,SCSI]
                        ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
  
        ftrace=[tracer]
 -                      [ftrace] will set and start the specified tracer
 +                      [FTRACE] will set and start the specified tracer
                        as early as possible in order to facilitate early
                        boot debugging.
  
        ftrace_dump_on_oops
 -                      [ftrace] will dump the trace buffers on oops.
 +                      [FTRACE] will dump the trace buffers on oops.
 +
 +      ftrace_filter=[function-list]
 +                      [FTRACE] Limit the functions traced by the function
 +                      tracer at boot up. function-list is a comma separated
 +                      list of functions. This list can be changed at run
 +                      time by the set_ftrace_filter file in the debugfs
 +                      tracing directory. 
 +
 +      ftrace_notrace=[function-list]
 +                      [FTRACE] Do not trace the functions specified in
 +                      function-list. This list can be changed at run time
 +                      by the set_ftrace_notrace file in the debugfs
 +                      tracing directory.
  
        gamecon.map[2|3]=
                        [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
                        Format: off | on
                        default: on
  
 +      gcov_persist=   [GCOV] When non-zero (default), profiling data for
 +                      kernel modules is saved and remains accessible via
 +                      debugfs, even when the module is unloaded/reloaded.
 +                      When zero, profiling data is discarded and associated
 +                      debugfs files are removed at module unload time.
 +
        gdth=           [HW,SCSI]
                        See header of drivers/scsi/gdth.c.
  
  
        ide-core.nodma= [HW] (E)IDE subsystem
                        Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
 -                      .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
 -                      .chs .ignore_cable are additional options
 -                      See Documentation/ide/ide.txt.
 -
 -      idebus=         [HW] (E)IDE subsystem - VLB/PCI bus speed
 +                      .vlb_clock .pci_clock .noflush .nohpa .noprobe .nowerr
 +                      .cdrom .chs .ignore_cable are additional options
                        See Documentation/ide/ide.txt.
  
        ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
                        Formt: { "sha1" | "md5" }
                        default: "sha1"
  
 +      ima_tcb         [IMA]
 +                      Load a policy which meets the needs of the Trusted
 +                      Computing Base.  This means IMA will measure all
 +                      programs exec'd, files mmap'd for exec, and all files
 +                      opened for read by uid=0.
 +
        in2000=         [HW,SCSI]
                        See header of drivers/scsi/in2000.c.
  
                        use the HighMem zone if it exists, and the Normal
                        zone if it does not.
  
 -      kmemtrace.enable=       [KNL,KMEMTRACE] Format: { yes | no }
 -                              Controls whether kmemtrace is enabled
 -                              at boot-time.
 -
 -      kmemtrace.subbufs=n     [KNL,KMEMTRACE] Overrides the number of
 -                      subbufs kmemtrace's relay channel has. Set this
 -                      higher than default (KMEMTRACE_N_SUBBUFS in code) if
 -                      you experience buffer overruns.
 -
        kgdboc=         [HW] kgdb over consoles.
                        Requires a tty driver that supports console polling.
 -                      (only serial suported for now)
 +                      (only serial supported for now)
                        Format: <serial_device>[,baud]
  
        kmac=           [MIPS] korina ethernet MAC address.
                        Configure the RouterBoard 532 series on-chip
                        Ethernet adapter MAC address.
  
 +      kmemleak=       [KNL] Boot-time kmemleak enable/disable
 +                      Valid arguments: on, off
 +                      Default: on
 +
        kstack=N        [X86] Print N words from the kernel stack
                        in oops dumps.
  
                        ('y', default) or cooked coordinates ('n')
  
        mtrr_chunk_size=nn[KMG] [X86]
 -                      used for mtrr cleanup. It is largest continous chunk
 +                      used for mtrr cleanup. It is largest continuous chunk
                        that could hold holes aka. UC entries.
  
        mtrr_gran_size=nn[KMG] [X86]
        noinitrd        [RAM] Tells the kernel not to load any configured
                        initial RAM disk.
  
 +      nointremap      [X86-64, Intel-IOMMU] Do not enable interrupt
 +                      remapping.
 +
        nointroute      [IA-64]
  
        nojitter        [IA64] Disables jitter checking for ITC timers.
        oprofile.timer= [HW]
                        Use timer interrupt instead of performance counters
  
 +      oprofile.cpu_type=      Force an oprofile cpu type
 +                      This might be useful if you have an older oprofile
 +                      userland or if you want common events.
 +                      Format: { archperfmon }
 +                      archperfmon: [X86] Force use of architectural
 +                              perfmon on Intel CPUs instead of the
 +                              CPU specific event set.
 +
        osst=           [HW,SCSI] SCSI Tape Driver
                        Format: <buffer_size>,<write_threshold>
                        See also Documentation/scsi/st.txt.
                                root domains (aka PCI segments, in ACPI-speak).
                nommconf        [X86] Disable use of MMCONFIG for PCI
                                Configuration
+               check_enable_amd_mmconf [X86] check for and enable
+                               properly configured MMIO access to PCI
+                               config space on AMD family 10h CPU
                nomsi           [MSI] If the PCI_MSI kernel config parameter is
                                enabled, this kernel boot option can be used to
                                disable the use of MSI interrupts system-wide.
                                IRQ routing is enabled.
                noacpi          [X86] Do not use ACPI for IRQ routing
                                or for PCI scanning.
-               use_crs         [X86] Use _CRS for PCI resource
+               nocrs           [X86] Don't use _CRS for PCI resource
                                allocation.
                routeirq        Do IRQ routing for all PCI devices.
                                This is normally done in pci_enable_device(),
                                PAGE_SIZE is used as alignment.
                                PCI-PCI bridge can be specified, if resource
                                windows need to be expanded.
+               ecrc=           Enable/disable PCIe ECRC (transaction layer
+                               end-to-end CRC checking).
+                               bios: Use BIOS/firmware settings. This is the
+                               the default.
+                               off: Turn ECRC off
+                               on: Turn ECRC on.
  
        pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
                        Management.
diff --combined drivers/pci/Makefile
@@@ -2,10 -2,11 +2,11 @@@
  # Makefile for the PCI bus specific drivers.
  #
  
- obj-y         += access.o bus.o probe.o remove.o pci.o quirks.o slot.o \
+ obj-y         += access.o bus.o probe.o remove.o pci.o quirks.o \
                        pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
                        irq.o
  obj-$(CONFIG_PROC_FS) += proc.o
+ obj-$(CONFIG_SYSFS) += slot.o
  
  # Build PCI Express stuff if needed
  obj-$(CONFIG_PCIEPORTBUS) += pcie/
@@@ -39,6 -40,7 +40,6 @@@ obj-$(CONFIG_ALPHA) += setup-bus.o setu
  obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
  obj-$(CONFIG_PARISC) += setup-bus.o
  obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
 -obj-$(CONFIG_PPC32) += setup-irq.o
  obj-$(CONFIG_PPC) += setup-bus.o
  obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
  obj-$(CONFIG_X86_VISWS) += setup-irq.o
@@@ -153,47 -153,45 +153,47 @@@ int ibmphp_init_devno(struct slot **cur
                return -1;
        }
        for (loop = 0; loop < len; loop++) {
 -              if ((*cur_slot)->number == rtable->slots[loop].slot) {
 -              if ((*cur_slot)->bus == rtable->slots[loop].bus) {
 +              if ((*cur_slot)->number == rtable->slots[loop].slot &&
 +                  (*cur_slot)->bus == rtable->slots[loop].bus) {
 +                      struct io_apic_irq_attr irq_attr;
 +
                        (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
                        for (i = 0; i < 4; i++)
                                (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
 -                                              (int) (*cur_slot)->device, i);
 -
 -                              debug("(*cur_slot)->irq[0] = %x\n",
 -                                              (*cur_slot)->irq[0]);
 -                              debug("(*cur_slot)->irq[1] = %x\n",
 -                                              (*cur_slot)->irq[1]);
 -                              debug("(*cur_slot)->irq[2] = %x\n",
 -                                              (*cur_slot)->irq[2]);
 -                              debug("(*cur_slot)->irq[3] = %x\n",
 -                                              (*cur_slot)->irq[3]);
 -
 -                              debug("rtable->exlusive_irqs = %x\n",
 +                                              (int) (*cur_slot)->device, i,
 +                                              &irq_attr);
 +
 +                      debug("(*cur_slot)->irq[0] = %x\n",
 +                                      (*cur_slot)->irq[0]);
 +                      debug("(*cur_slot)->irq[1] = %x\n",
 +                                      (*cur_slot)->irq[1]);
 +                      debug("(*cur_slot)->irq[2] = %x\n",
 +                                      (*cur_slot)->irq[2]);
 +                      debug("(*cur_slot)->irq[3] = %x\n",
 +                                      (*cur_slot)->irq[3]);
 +
 +                      debug("rtable->exlusive_irqs = %x\n",
                                        rtable->exclusive_irqs);
 -                              debug("rtable->slots[loop].irq[0].bitmap = %x\n",
 +                      debug("rtable->slots[loop].irq[0].bitmap = %x\n",
                                        rtable->slots[loop].irq[0].bitmap);
 -                              debug("rtable->slots[loop].irq[1].bitmap = %x\n",
 +                      debug("rtable->slots[loop].irq[1].bitmap = %x\n",
                                        rtable->slots[loop].irq[1].bitmap);
 -                              debug("rtable->slots[loop].irq[2].bitmap = %x\n",
 +                      debug("rtable->slots[loop].irq[2].bitmap = %x\n",
                                        rtable->slots[loop].irq[2].bitmap);
 -                              debug("rtable->slots[loop].irq[3].bitmap = %x\n",
 +                      debug("rtable->slots[loop].irq[3].bitmap = %x\n",
                                        rtable->slots[loop].irq[3].bitmap);
  
 -                              debug("rtable->slots[loop].irq[0].link = %x\n",
 +                      debug("rtable->slots[loop].irq[0].link = %x\n",
                                        rtable->slots[loop].irq[0].link);
 -                              debug("rtable->slots[loop].irq[1].link = %x\n",
 +                      debug("rtable->slots[loop].irq[1].link = %x\n",
                                        rtable->slots[loop].irq[1].link);
 -                              debug("rtable->slots[loop].irq[2].link = %x\n",
 +                      debug("rtable->slots[loop].irq[2].link = %x\n",
                                        rtable->slots[loop].irq[2].link);
 -                              debug("rtable->slots[loop].irq[3].link = %x\n",
 +                      debug("rtable->slots[loop].irq[3].link = %x\n",
                                        rtable->slots[loop].irq[3].link);
 -                              debug("end of init_devno\n");
 -                              kfree(rtable);
 -                              return 0;
 -                      }
 +                      debug("end of init_devno\n");
 +                      kfree(rtable);
 +                      return 0;
                }
        }
  
@@@ -1318,7 -1316,6 +1318,6 @@@ error
  }
  
  struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
-       .owner =                        THIS_MODULE,
        .set_attention_status =         set_attention_status,
        .enable_slot =                  enable_slot,
        .disable_slot =                 ibmphp_disable_slot,
@@@ -1421,3 -1418,4 +1420,4 @@@ static void __exit ibmphp_exit(void
  }
  
  module_init(ibmphp_init);
+ module_exit(ibmphp_exit);
@@@ -83,7 -83,6 +83,6 @@@ static int disable_slot(struct hotplug_
  static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
  
  static struct hotplug_slot_ops sn_hotplug_slot_ops = {
-       .owner                  = THIS_MODULE,
        .enable_slot            = enable_slot,
        .disable_slot           = disable_slot,
        .get_power_status       = get_power_status,
@@@ -679,7 -678,7 +678,7 @@@ alloc_err
        return rc;
  }
  
 -static int sn_pci_hotplug_init(void)
 +static int __init sn_pci_hotplug_init(void)
  {
        struct pci_bus *pci_bus = NULL;
        int rc;
        return registered == 1 ? 0 : -ENODEV;
  }
  
 -static void sn_pci_hotplug_exit(void)
 +static void __exit sn_pci_hotplug_exit(void)
  {
        struct hotplug_slot *bss_hotplug_slot;
  
diff --combined drivers/pci/pci.c
  #include <asm/setup.h>
  #include "pci.h"
  
 +const char *pci_power_names[] = {
 +      "error", "D0", "D1", "D2", "D3hot", "D3cold", "unknown",
 +};
 +EXPORT_SYMBOL_GPL(pci_power_names);
 +
  unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
  
  #ifdef CONFIG_PCI_DOMAINS
@@@ -485,6 -480,8 +485,8 @@@ static int pci_raw_set_power_state(stru
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
                pmcsr |= state;
                break;
+       case PCI_D3hot:
+       case PCI_D3cold:
        case PCI_UNKNOWN: /* Boot-up */
                if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
                 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
@@@ -1208,7 -1205,7 +1210,7 @@@ void pci_pme_active(struct pci_dev *dev
   * Error code depending on the platform is returned if both the platform and
   * the native mechanism fail to enable the generation of wake-up events
   */
- 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, bool enable)
  {
        int error = 0;
        bool pme_done = false;
@@@ -1287,15 -1284,14 +1289,14 @@@ pci_power_t pci_target_state(struct pci
                default:
                        target_state = state;
                }
+       } else if (!dev->pm_cap) {
+               target_state = PCI_D0;
        } else if (device_may_wakeup(&dev->dev)) {
                /*
                 * Find the deepest state from which the device can generate
                 * wake-up events, make it the target state and enable device
                 * to generate PME#.
                 */
-               if (!dev->pm_cap)
-                       return PCI_POWER_ERROR;
                if (dev->pme_support) {
                        while (target_state
                              && !(dev->pme_support & (1 << target_state)))
@@@ -1532,7 -1528,7 +1533,7 @@@ pci_get_interrupt_pin(struct pci_dev *d
        if (!pin)
                return -1;
  
-       while (dev->bus->parent) {
+       while (!pci_is_root_bus(dev->bus)) {
                pin = pci_swizzle_interrupt_pin(dev, pin);
                dev = dev->bus->self;
        }
@@@ -1552,7 -1548,7 +1553,7 @@@ u8 pci_common_swizzle(struct pci_dev *d
  {
        u8 pin = *pinp;
  
-       while (dev->bus->parent) {
+       while (!pci_is_root_bus(dev->bus)) {
                pin = pci_swizzle_interrupt_pin(dev, pin);
                dev = dev->bus->self;
        }
@@@ -2058,111 -2054,177 +2059,177 @@@ int pci_set_dma_seg_boundary(struct pci
  EXPORT_SYMBOL(pci_set_dma_seg_boundary);
  #endif
  
- static int __pcie_flr(struct pci_dev *dev, int probe)
+ static int pcie_flr(struct pci_dev *dev, int probe)
  {
-       u16 status;
+       int i;
+       int pos;
        u32 cap;
-       int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       u16 status;
  
-       if (!exppos)
+       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!pos)
                return -ENOTTY;
-       pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
+       pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
        if (!(cap & PCI_EXP_DEVCAP_FLR))
                return -ENOTTY;
  
        if (probe)
                return 0;
  
-       pci_block_user_cfg_access(dev);
        /* Wait for Transaction Pending bit clean */
-       pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-       if (!(status & PCI_EXP_DEVSTA_TRPND))
-               goto transaction_done;
+       for (i = 0; i < 4; i++) {
+               if (i)
+                       msleep((1 << (i - 1)) * 100);
  
-       msleep(100);
-       pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-       if (!(status & PCI_EXP_DEVSTA_TRPND))
-               goto transaction_done;
-       dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
-                       "sleeping for 1 second\n");
-       ssleep(1);
-       pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-       if (status & PCI_EXP_DEVSTA_TRPND)
-               dev_info(&dev->dev, "Still busy after 1s; "
-                               "proceeding with reset anyway\n");
- transaction_done:
-       pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
+               pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+               if (!(status & PCI_EXP_DEVSTA_TRPND))
+                       goto clear;
+       }
+       dev_err(&dev->dev, "transaction is not cleared; "
+                       "proceeding with reset anyway\n");
+ clear:
+       pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
                                PCI_EXP_DEVCTL_BCR_FLR);
-       mdelay(100);
+       msleep(100);
  
-       pci_unblock_user_cfg_access(dev);
        return 0;
  }
  
- static int __pci_af_flr(struct pci_dev *dev, int probe)
+ static int pci_af_flr(struct pci_dev *dev, int probe)
  {
-       int cappos = pci_find_capability(dev, PCI_CAP_ID_AF);
-       u8 status;
+       int i;
+       int pos;
        u8 cap;
+       u8 status;
  
-       if (!cappos)
+       pos = pci_find_capability(dev, PCI_CAP_ID_AF);
+       if (!pos)
                return -ENOTTY;
-       pci_read_config_byte(dev, cappos + PCI_AF_CAP, &cap);
+       pci_read_config_byte(dev, pos + PCI_AF_CAP, &cap);
        if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
                return -ENOTTY;
  
        if (probe)
                return 0;
  
-       pci_block_user_cfg_access(dev);
        /* Wait for Transaction Pending bit clean */
-       pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-       if (!(status & PCI_AF_STATUS_TP))
-               goto transaction_done;
+       for (i = 0; i < 4; i++) {
+               if (i)
+                       msleep((1 << (i - 1)) * 100);
+               pci_read_config_byte(dev, pos + PCI_AF_STATUS, &status);
+               if (!(status & PCI_AF_STATUS_TP))
+                       goto clear;
+       }
  
+       dev_err(&dev->dev, "transaction is not cleared; "
+                       "proceeding with reset anyway\n");
+ clear:
+       pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
        msleep(100);
-       pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-       if (!(status & PCI_AF_STATUS_TP))
-               goto transaction_done;
-       dev_info(&dev->dev, "Busy after 100ms while trying to"
-                       " reset; sleeping for 1 second\n");
-       ssleep(1);
-       pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-       if (status & PCI_AF_STATUS_TP)
-               dev_info(&dev->dev, "Still busy after 1s; "
-                               "proceeding with reset anyway\n");
- transaction_done:
-       pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
-       mdelay(100);
-       pci_unblock_user_cfg_access(dev);
        return 0;
  }
  
- static int __pci_reset_function(struct pci_dev *pdev, int probe)
+ static int pci_pm_reset(struct pci_dev *dev, int probe)
  {
-       int res;
+       u16 csr;
+       if (!dev->pm_cap)
+               return -ENOTTY;
  
-       res = __pcie_flr(pdev, probe);
-       if (res != -ENOTTY)
-               return res;
+       pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
+       if (csr & PCI_PM_CTRL_NO_SOFT_RESET)
+               return -ENOTTY;
  
-       res = __pci_af_flr(pdev, probe);
-       if (res != -ENOTTY)
-               return res;
+       if (probe)
+               return 0;
  
-       return res;
+       if (dev->current_state != PCI_D0)
+               return -EINVAL;
+       csr &= ~PCI_PM_CTRL_STATE_MASK;
+       csr |= PCI_D3hot;
+       pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
+       msleep(pci_pm_d3_delay);
+       csr &= ~PCI_PM_CTRL_STATE_MASK;
+       csr |= PCI_D0;
+       pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
+       msleep(pci_pm_d3_delay);
+       return 0;
+ }
+ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
+ {
+       u16 ctrl;
+       struct pci_dev *pdev;
+       if (dev->subordinate)
+               return -ENOTTY;
+       list_for_each_entry(pdev, &dev->bus->devices, bus_list)
+               if (pdev != dev)
+                       return -ENOTTY;
+       if (probe)
+               return 0;
+       pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl);
+       ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
+       pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
+       msleep(100);
+       ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+       pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
+       msleep(100);
+       return 0;
+ }
+ static int pci_dev_reset(struct pci_dev *dev, int probe)
+ {
+       int rc;
+       might_sleep();
+       if (!probe) {
+               pci_block_user_cfg_access(dev);
+               /* block PM suspend, driver probe, etc. */
+               down(&dev->dev.sem);
+       }
+       rc = pcie_flr(dev, probe);
+       if (rc != -ENOTTY)
+               goto done;
+       rc = pci_af_flr(dev, probe);
+       if (rc != -ENOTTY)
+               goto done;
+       rc = pci_pm_reset(dev, probe);
+       if (rc != -ENOTTY)
+               goto done;
+       rc = pci_parent_bus_reset(dev, probe);
+ done:
+       if (!probe) {
+               up(&dev->dev.sem);
+               pci_unblock_user_cfg_access(dev);
+       }
+       return rc;
  }
  
  /**
-  * pci_execute_reset_function() - Reset a PCI device function
-  * @dev: Device function to reset
+  * __pci_reset_function - reset a PCI device function
+  * @dev: PCI device to reset
   *
   * Some devices allow an individual function to be reset without affecting
   * other functions in the same device.  The PCI device must be responsive
   * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
   * etc.
   *
-  * Returns 0 if the device function was successfully reset or -ENOTTY if the
+  * Returns 0 if the device function was successfully reset or negative if the
   * device doesn't support resetting a single function.
   */
- int pci_execute_reset_function(struct pci_dev *dev)
+ int __pci_reset_function(struct pci_dev *dev)
  {
-       return __pci_reset_function(dev, 0);
+       return pci_dev_reset(dev, 0);
  }
- EXPORT_SYMBOL_GPL(pci_execute_reset_function);
+ EXPORT_SYMBOL_GPL(__pci_reset_function);
  
  /**
-  * pci_reset_function() - quiesce and reset a PCI device function
-  * @dev: Device function to reset
+  * pci_reset_function - quiesce and reset a PCI device function
+  * @dev: PCI device to reset
   *
   * Some devices allow an individual function to be reset without affecting
   * other functions in the same device.  The PCI device must be responsive
   *
   * This function does not just reset the PCI portion of a device, but
   * clears all the state associated with the device.  This function differs
-  * from pci_execute_reset_function in that it saves and restores device state
+  * from __pci_reset_function in that it saves and restores device state
   * over the reset.
   *
-  * Returns 0 if the device function was successfully reset or -ENOTTY if the
+  * Returns 0 if the device function was successfully reset or negative if the
   * device doesn't support resetting a single function.
   */
  int pci_reset_function(struct pci_dev *dev)
  {
-       int r = __pci_reset_function(dev, 1);
+       int rc;
  
-       if (r < 0)
-               return r;
+       rc = pci_dev_reset(dev, 1);
+       if (rc)
+               return rc;
  
-       if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
-               disable_irq(dev->irq);
        pci_save_state(dev);
  
+       /*
+        * both INTx and MSI are disabled after the Interrupt Disable bit
+        * is set and the Bus Master bit is cleared.
+        */
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
  
-       r = pci_execute_reset_function(dev);
+       rc = pci_dev_reset(dev, 0);
  
        pci_restore_state(dev);
-       if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
-               enable_irq(dev->irq);
  
-       return r;
+       return rc;
  }
  EXPORT_SYMBOL_GPL(pci_reset_function);
  
@@@ -2591,6 -2654,8 +2659,8 @@@ static int __init pci_setup(char *str
                        } else if (!strncmp(str, "resource_alignment=", 19)) {
                                pci_set_resource_alignment_param(str + 19,
                                                        strlen(str + 19));
+                       } else if (!strncmp(str, "ecrc=", 5)) {
+                               pcie_ecrc_get_policy(str + 5);
                        } else {
                                printk(KERN_ERR "PCI: Unknown option `%s'\n",
                                                str);
diff --combined drivers/pci/quirks.c
@@@ -1133,6 -1133,7 +1133,7 @@@ static void __init asus_hides_smbus_hos
                        switch (dev->subsystem_device) {
                        case 0x1751: /* M2N notebook */
                        case 0x1821: /* M5N notebook */
+                       case 0x1897: /* A6L notebook */
                                asus_hides_smbus = 1;
                        }
                else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch (dev->subsystem_device) {
                        case 0x12bc: /* HP D330L */
                        case 0x12bd: /* HP D530 */
+                       case 0x006a: /* HP Compaq nx9500 */
                                asus_hides_smbus = 1;
                        }
                else if (dev->device == PCI_DEVICE_ID_INTEL_82875_HB)
@@@ -2016,6 -2018,28 +2018,28 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_B
                        PCI_DEVICE_ID_NX2_5709S,
                        quirk_brcm_570x_limit_vpd);
  
+ /* Originally in EDAC sources for i82875P:
+  * Intel tells BIOS developers to hide device 6 which
+  * configures the overflow device access containing
+  * the DRBs - this is where we expose device 6.
+  * http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm
+  */
+ static void __devinit quirk_unhide_mch_dev6(struct pci_dev *dev)
+ {
+       u8 reg;
+       if (pci_read_config_byte(dev, 0xF4, &reg) == 0 && !(reg & 0x02)) {
+               dev_info(&dev->dev, "Enabling MCH 'Overflow' Device\n");
+               pci_write_config_byte(dev, 0xF4, reg | 0x02);
+       }
+ }
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
+                       quirk_unhide_mch_dev6);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
+                       quirk_unhide_mch_dev6);
  #ifdef CONFIG_PCI_MSI
  /* 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
@@@ -2461,8 -2485,6 +2485,8 @@@ static void __devinit quirk_i82576_srio
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
 +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov);
 +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov);
  
  #endif        /* CONFIG_PCI_IOV */
  
diff --combined drivers/pci/setup-res.c
@@@ -99,11 -99,11 +99,11 @@@ void pci_update_resource(struct pci_de
  int pci_claim_resource(struct pci_dev *dev, int resource)
  {
        struct resource *res = &dev->resource[resource];
 -      struct resource *root = NULL;
 +      struct resource *root;
        char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
        int err;
  
 -      root = pcibios_select_root(dev, res);
 +      root = pci_find_parent_resource(dev, res);
  
        err = -EINVAL;
        if (root != NULL)
@@@ -135,23 -135,16 +135,16 @@@ void pci_disable_bridge_window(struct p
  }
  #endif        /* CONFIG_PCI_QUIRKS */
  
- int pci_assign_resource(struct pci_dev *dev, int resno)
+ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
+                                int resno)
  {
-       struct pci_bus *bus = dev->bus;
        struct resource *res = dev->resource + resno;
        resource_size_t size, min, align;
        int ret;
  
        size = resource_size(res);
        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
        align = resource_alignment(res);
-       if (!align) {
-               dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
-                       "alignment) %pR flags %#lx\n",
-                       resno, res, res->flags);
-               return -EINVAL;
-       }
  
        /* First, try exact prefetching match.. */
        ret = pci_bus_alloc_resource(bus, res, size, align, min,
                                             pcibios_align_resource, dev);
        }
  
-       if (ret) {
-               dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
-                       resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
-       } else {
+       if (!ret) {
                res->flags &= ~IORESOURCE_STARTALIGN;
                if (resno < PCI_BRIDGE_RESOURCES)
                        pci_update_resource(dev, resno);
        return ret;
  }
  
+ int pci_assign_resource(struct pci_dev *dev, int resno)
+ {
+       struct resource *res = dev->resource + resno;
+       resource_size_t align;
+       struct pci_bus *bus;
+       int ret;
+       align = resource_alignment(res);
+       if (!align) {
+               dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
+                       "alignment) %pR flags %#lx\n",
+                       resno, res, res->flags);
+               return -EINVAL;
+       }
+       bus = dev->bus;
+       while ((ret = __pci_assign_resource(bus, dev, resno))) {
+               if (bus->parent && bus->self->transparent)
+                       bus = bus->parent;
+               else
+                       bus = NULL;
+               if (bus)
+                       continue;
+               break;
+       }
+       if (ret)
+               dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
+                       resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
+       return ret;
+ }
  #if 0
  int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
  {
diff --combined include/linux/pci.h
@@@ -124,14 -124,6 +124,14 @@@ typedef int __bitwise pci_power_t
  #define PCI_UNKNOWN   ((pci_power_t __force) 5)
  #define PCI_POWER_ERROR       ((pci_power_t __force) -1)
  
 +/* Remember to update this when the list above changes! */
 +extern const char *pci_power_names[];
 +
 +static inline const char *pci_power_name(pci_power_t state)
 +{
 +      return pci_power_names[1 + (int) state];
 +}
 +
  #define PCI_PM_D2_DELAY       200
  #define PCI_PM_D3_WAIT        10
  #define PCI_PM_BUS_WAIT       50
@@@ -607,8 -599,6 +607,6 @@@ extern void pci_sort_breadthfirst(void)
  struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
                                             unsigned int device,
                                             struct pci_dev *from);
- struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
-                                          unsigned int devfn);
  #endif /* CONFIG_PCI_LEGACY */
  
  enum pci_lost_interrupt_reason {
@@@ -647,6 -637,7 +645,7 @@@ int pci_bus_write_config_word(struct pc
                              int where, u16 val);
  int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
                               int where, u32 val);
+ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
  
  static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
  {
@@@ -711,8 -702,8 +710,8 @@@ int pcix_get_mmrbc(struct pci_dev *dev)
  int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
  int pcie_get_readrq(struct pci_dev *dev);
  int pcie_set_readrq(struct pci_dev *dev, int rq);
+ int __pci_reset_function(struct pci_dev *dev);
  int pci_reset_function(struct pci_dev *dev);
- int pci_execute_reset_function(struct pci_dev *dev);
  void pci_update_resource(struct pci_dev *dev, int resno);
  int __must_check pci_assign_resource(struct pci_dev *dev, int i);
  int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@@ -732,7 -723,7 +731,7 @@@ int pci_set_power_state(struct pci_dev 
  pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
  bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
  void pci_pme_active(struct pci_dev *dev, bool enable);
- 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, bool enable);
  int pci_wake_from_d3(struct pci_dev *dev, bool enable);
  pci_power_t pci_target_state(struct pci_dev *dev);
  int pci_prepare_to_sleep(struct pci_dev *dev);
@@@ -798,7 -789,7 +797,7 @@@ const struct pci_device_id *pci_match_i
  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, int (*cb)(struct pci_dev *, void *),
                  void *userdata);
  int pci_cfg_space_size_ext(struct pci_dev *dev);
  int pci_cfg_space_size(struct pci_dev *dev);
@@@ -888,6 -879,17 +887,17 @@@ static inline int pcie_aspm_enabled(voi
  extern int pcie_aspm_enabled(void);
  #endif
  
+ #ifndef CONFIG_PCIE_ECRC
+ static inline void pcie_set_ecrc_checking(struct pci_dev *dev)
+ {
+       return;
+ }
+ static inline void pcie_ecrc_get_policy(char *str) {};
+ #else
+ extern void pcie_set_ecrc_checking(struct pci_dev *dev);
+ extern void pcie_ecrc_get_policy(char *str);
+ #endif
  #define pci_enable_msi(pdev)  pci_enable_msi_block(pdev, 1)
  
  #ifdef CONFIG_HT_IRQ
@@@ -944,12 -946,6 +954,6 @@@ static inline struct pci_dev *pci_find_
        return NULL;
  }
  
- static inline struct pci_dev *pci_find_slot(unsigned int bus,
-                                           unsigned int devfn)
- {
-       return NULL;
- }
  static inline struct pci_dev *pci_get_device(unsigned int vendor,
                                             unsigned int device,
                                             struct pci_dev *from)
@@@ -1105,6 -1101,10 +1109,10 @@@ static inline struct pci_dev *pci_get_b
  
  #include <asm/pci.h>
  
+ #ifndef PCIBIOS_MAX_MEM_32
+ #define PCIBIOS_MAX_MEM_32 (-1)
+ #endif
  /* these helpers provide future and backwards compatibility
   * for accessing popular PCI BAR info */
  #define pci_resource_start(dev, bar)  ((dev)->resource[(bar)].start)
@@@ -1261,5 -1261,10 +1269,10 @@@ static inline irqreturn_t pci_sriov_mig
  }
  #endif
  
+ #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
+ extern void pci_hp_create_module_link(struct pci_slot *pci_slot);
+ extern void pci_hp_remove_module_link(struct pci_slot *pci_slot);
+ #endif
  #endif /* __KERNEL__ */
  #endif /* LINUX_PCI_H */