# This is a BitKeeper generated diff -Nru style patch.
#
# drivers/pci/hotplug/rpaphp_pci.c
#   2004/09/16 15:59:03+00:00 johnrose@austin.ibm.com +16 -9
#   PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
# 
# drivers/pci/hotplug/rpaphp_pci.c
#   2004/09/22 08:40:08+00:00 greg@press.kroah.org +0 -0
#   Auto merged
# 
# drivers/pci/hotplug/rpaphp_pci.c
#   2004/08/26 06:27:10-07:00 johnrose@austin.ibm.com +46 -9
#   PCI Hotplug: add host bridges to RPA hotplug subsystem
# 
# drivers/pci/hotplug/rpaphp_slot.c
#   2004/08/26 06:27:10-07:00 johnrose@austin.ibm.com +5 -6
#   PCI Hotplug: add host bridges to RPA hotplug subsystem
# 
# drivers/pci/hotplug/rpaphp_vio.c
#   2004/09/16 15:59:03+00:00 johnrose@austin.ibm.com +2 -2
#   PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
# 
# ChangeSet
#   2004/09/26 14:25:55-07:00 akpm@bix.(none) 
#   Merge
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/26 14:25:51-07:00 akpm@bix.(none) +90 -0
#   SCCS merged
# 
# drivers/char/applicom.c
#   2004/09/26 14:24:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc64/kernel/pci.c
#   2004/09/26 14:24:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ppc/kernel/pci.c
#   2004/09/26 14:24:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/pci/pci.c
#   2004/09/26 14:24:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/alpha/kernel/pci.c
#   2004/09/26 14:24:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/24 09:00:00-07:00 lcapitulino@conectiva.com.br 
#   [PATCH] PCI: add missing checks in drivers/pci/probe.c.
#   
#    I noticed drivers/pci/probe.c::pci_scan_bus_parented() has some functions which
#   the return value is not checked.
#   
#    The patch bellow adds the check for device_register(), class_device_register(),
#   class_device_create_file() and sysfs_create_link().
#   
#   (hope the error label names are not too ugly).
#   
#   
#   Signed-off-by: Luiz Capitulino <lcapitulino@conectiva.com.br>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/probe.c
#   2004/09/19 18:06:30-07:00 lcapitulino@conectiva.com.br +28 -8
#   PCI: add missing checks in drivers/pci/probe.c.
# 
# drivers/misc/ibmasm/uart.c
#   2004/09/22 17:02:06+00:00 greg@kroah.com +1 -1
#   ibmasm: fix __iomem warnings
# 
# drivers/misc/ibmasm/lowlevel.h
#   2004/09/22 17:02:06+00:00 greg@kroah.com +15 -15
#   ibmasm: fix __iomem warnings
# 
# drivers/misc/ibmasm/lowlevel.c
#   2004/09/22 17:02:06+00:00 greg@kroah.com +1 -1
#   ibmasm: fix __iomem warnings
# 
# drivers/misc/ibmasm/ibmasmfs.c
#   2004/09/22 17:02:06+00:00 greg@kroah.com +2 -2
#   ibmasm: fix __iomem warnings
# 
# drivers/misc/ibmasm/ibmasm.h
#   2004/09/22 17:02:06+00:00 greg@kroah.com +1 -1
#   ibmasm: fix __iomem warnings
# 
# drivers/pci/hotplug/shpchp_hpc.c
#   2004/09/22 14:56:32+00:00 dlsy@snoqualmie.dp.intel.com +1 -1
#   PCI Hotplug: quirk fix missed out in last patch
# 
# ChangeSet
#   2004/09/22 14:19:40+00:00 dlsy@snoqualmie.dp.intel.com 
#   [PATCH] PCI Hotplug: quirk fix missed out in last patch
#   
#   This patch contains a fix that was missed out in the last patch I sent
#   you regarding fixes for writing 1's to RsvdZ in Slot Status register
#   causing hot-plugging of PCI-X cards not working in some slots.
#   
#   Signed-off-by: Dely Sy <dely.l.sy@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/22 14:19:28+00:00 dlsy@snoqualmie.dp.intel.com 
#   [PATCH] PCI Hotplug: Quirk patch
#   
#   Here is a quirk patch.
#   
#   Problem: The E7520, E7320, and E7525 chipsets are potentially vulnerable to
#   attempts by software to enable ASPM (Active State Power Management) and LOs
#   specifically.  In a worse case, initiating L0s could cause loss of link.
#   
#   The attached patch provides a workaround for this issue by preventing
#   enabling of ASPM by SW on the affected chipsets.
#   
#   Signed-off-by: Dely Sy <dely.l.sy@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci_ids.h
#   2004/09/22 13:55:24+00:00 dlsy@snoqualmie.dp.intel.com +9 -1
#   PCI Hotplug: Quirk patch
# 
# drivers/pci/quirks.c
#   2004/09/22 14:12:53+00:00 dlsy@snoqualmie.dp.intel.com +99 -5
#   PCI Hotplug: Quirk patch
# 
# drivers/pci/pci.h
#   2004/09/22 14:07:44+00:00 dlsy@snoqualmie.dp.intel.com +2 -1
#   PCI Hotplug: Quirk patch
# 
# drivers/pci/hotplug/pciehp_pci.c
#   2004/09/22 14:13:47+00:00 dlsy@snoqualmie.dp.intel.com +7 -0
#   PCI Hotplug: Quirk patch
# 
# drivers/pci/hotplug/pciehp_hpc.c
#   2004/09/22 13:55:24+00:00 dlsy@snoqualmie.dp.intel.com +2 -2
#   PCI Hotplug: Quirk patch
# 
# drivers/pci/hotplug/pciehp_ctrl.c
#   2004/09/22 14:13:25+00:00 dlsy@snoqualmie.dp.intel.com +5 -0
#   PCI Hotplug: Quirk patch
# 
# ChangeSet
#   2004/09/22 13:48:09+00:00 hannal@us.ibm.com 
#   [PATCH] PCI: Changed pci_find_device to pci_get_device for acpi.c
#   
#   Another simple patch to complete the /i386 conversion to pci_get_device.
#   I was able to compile and boot this patch to verify it didn't break anything
#   (on my T22).
#   
#   Signed-off-by: Hanna Linder <hannal@us.ibm.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/acpi.c
#   2004/09/22 13:46:12+00:00 hannal@us.ibm.com +1 -1
#   PCI: Changed pci_find_device to pci_get_device for acpi.c
# 
# ChangeSet
#   2004/09/22 13:36:57+00:00 vernux@us.ibm.com 
#   [PATCH] PCI Hotplug: acpiphp extension fixes
#   
#   This patch fixes an off by one error that one of the IBM machines that
#   uses the acpiphp_ibm driver.  The slots were numbered starting at 0 in
#   BIOS instead of starting at 1 like the pci hotplug subsystem names
#   them.  So this patch provides a lookup to translate the Linux slot
#   numbers to the internal ACPI numbers.
#   
#   Signed-off-by: Vernon Mauery <vernux@us.ibm.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/acpiphp_ibm.c
#   2004/09/17 14:55:35+00:00 vernux@us.ibm.com +63 -38
#   PCI Hotplug: acpiphp extension fixes
# 
# ChangeSet
#   2004/09/22 11:27:42+00:00 johnrose@austin.ibm.com 
#   [PATCH] PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
#   
#   The following patch implements the RPA PCI Hotplug and DLPAR driver changes for
#   the dynamic addition/removal of PCI Host bridges (PHBs).  These operations are
#   initiated in the same way as existing slot DLPAR operations, which is by
#   writing the firmware (drc) name of the PHB to:
#   /sys/bus/pci/slots/control/[add,remove]_slot
#   
#   The "kernel" entry points for these operations are:
#   pcibios_remove_root_bus()
#   	ppc64-specific, submitted to ppc64 list on 8/19, not yet accepted
#   	http://ozlabs.org/ppc64-patches/patch.pl?id=241
#   init_phb_dynamic()
#   	ppc64-specific, submitted to ppc64 list on 9/16, not yet accepted
#   	http://ozlabs.org/ppc64-patches/patch.pl?id=292
#   pci_remove_bus()
#   	generic, submitted and accepted by Greg
#   	http://www.uwsg.iu.edu/hypermail/linux/kernel/0408.3/0595.html
#   
#   Signed-off-by: John Rose <johnrose@austin.ibm.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/rpaphp_core.c
#   2004/09/16 15:59:03+00:00 johnrose@austin.ibm.com +83 -56
#   PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
# 
# drivers/pci/hotplug/rpaphp.h
#   2004/09/16 15:59:03+00:00 johnrose@austin.ibm.com +2 -1
#   PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
# 
# drivers/pci/hotplug/rpadlpar_core.c
#   2004/09/16 15:59:03+00:00 johnrose@austin.ibm.com +136 -26
#   PCI Hotplug: RPA dynamic addition/removal of PCI Host Bridges
# 
# ChangeSet
#   2004/09/22 10:12:18+00:00 greg@kroah.com 
#   [PATCH] ibmasm: fix __iomem warnings
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/22 08:40:11+00:00 greg@press.kroah.org 
#   Merge gregkh@kernel.bkbits.net:linux/pci-2.6
#   into press.kroah.org:/home/greg/linux/BK/pci-2.6
# 
# drivers/pci/hotplug/rpaphp_core.c
#   2004/09/22 08:40:08+00:00 greg@press.kroah.org +0 -0
#   Auto merged
# 
# drivers/acpi/processor.c
#   2004/09/22 08:40:08+00:00 greg@press.kroah.org +0 -0
#   Auto merged
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/22 08:40:08+00:00 greg@press.kroah.org +0 -0
#   Auto merged
# 
# arch/ia64/sn/io/machvec/pci_bus_cvlink.c
#   2004/09/22 08:40:07+00:00 greg@press.kroah.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/15 15:12:20-07:00 hannal@us.ibm.com 
#   [PATCH] PCI: Fix one missed pci_find_device
#   
#   Just noticed this in my update to the latest mm kernel...
#   
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/cpu/cyrix.c
#   2004/09/14 16:35:14-07:00 hannal@us.ibm.com +1 -1
#   PCI: Fix one missed pci_find_device
# 
# ChangeSet
#   2004/09/15 15:11:17-07:00 akpm@osdl.org 
#   [PATCH] ppc64: fix pseries build in -mm
#   
#   From: Anton Blanchard <anton@samba.org>
#   
#   Looks like a list macro cleanup patch went in, resulting in two definitions
#   of *dev.  Remove one.
#   
#   (akpm: the breakage is in bk-pci.patch)
#   
#   Signed-off-by: Anton Blanchard <anton@samba.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/14 08:45:29-07:00 akpm@osdl.org +0 -1
#   ppc64: fix pseries build in -mm
# 
# ChangeSet
#   2004/09/14 15:30:37-07:00 greg@kroah.com 
#   PCI Hotplug: fix the rest of the drivers for __iomem and other sparse issues.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchp_hpc.c
#   2004/09/14 15:30:02-07:00 greg@kroah.com +1 -2
#   PCI Hotplug: fix the rest of the drivers for __iomem and other sparse issues.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchp_ctrl.c
#   2004/09/14 15:30:02-07:00 greg@kroah.com +1 -1
#   PCI Hotplug: fix the rest of the drivers for __iomem and other sparse issues.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchp.h
#   2004/09/14 15:30:02-07:00 greg@kroah.com +1 -1
#   PCI Hotplug: fix the rest of the drivers for __iomem and other sparse issues.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpcihp_zt5550.c
#   2004/09/14 15:30:02-07:00 greg@kroah.com +5 -5
#   PCI Hotplug: fix the rest of the drivers for __iomem and other sparse issues.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/14 15:14:13-07:00 dlsy@snoqualmie.dp.intel.com 
#   [PATCH] PCI Hotplug: Bug fixes for shpchp driver
#   
#   Can you please apply the following patch that has bug fixes for shpchp
#   driver? One bug was writing 1's to RsvdZ in Slot Status register
#   causing hot-plugging of PCI-X cards not working in some slots.  The
#   other fix is for getting the correct bus number.
#   
#   
#   Signed-off-by: Dely Sy <dely.l.sy@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchprm_acpi.c
#   2004/08/23 09:55:16-07:00 dlsy@snoqualmie.dp.intel.com +4 -2
#   PCI Hotplug: Bug fixes for shpchp driver
# 
# drivers/pci/hotplug/shpchp_hpc.c
#   2004/09/09 15:22:02-07:00 dlsy@snoqualmie.dp.intel.com +2 -2
#   PCI Hotplug: Bug fixes for shpchp driver
# 
# ChangeSet
#   2004/09/14 15:04:35-07:00 greg@kroah.com 
#   PCI Hotplug: fix __iomem warnings in the ibm pci hotplug driver
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/ibmphp_hpc.c
#   2004/09/14 15:03:07-07:00 greg@kroah.com +14 -14
#   PCI Hotplug: fix __iomem warnings in the ibm pci hotplug driver
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/ibmphp_ebda.c
#   2004/09/14 15:03:07-07:00 greg@kroah.com +1 -1
#   PCI Hotplug: fix __iomem warnings in the ibm pci hotplug driver
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/14 14:52:37-07:00 greg@kroah.com 
#   PCI Hotplug: fix __iomem warnings in the compaq pci hotplug driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpqphp_pci.c
#   2004/09/14 14:51:42-07:00 greg@kroah.com +6 -6
#   PCI Hotplug: fix __iomem warnings in the compaq pci hotplug driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpqphp_nvram.h
#   2004/09/14 14:51:42-07:00 greg@kroah.com +6 -6
#   PCI Hotplug: fix __iomem warnings in the compaq pci hotplug driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpqphp_core.c
#   2004/09/14 14:51:42-07:00 greg@kroah.com +19 -15
#   PCI Hotplug: fix __iomem warnings in the compaq pci hotplug driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpqphp.h
#   2004/09/14 14:51:42-07:00 greg@kroah.com +3 -3
#   PCI Hotplug: fix __iomem warnings in the compaq pci hotplug driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/14 14:23:06-07:00 greg@kroah.com 
#   PCI: fix up __iomem mess in the PCI rom code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/09/14 14:21:59-07:00 greg@kroah.com +3 -3
#   PCI: fix up __iomem mess in the PCI rom code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/rom.c
#   2004/09/14 14:21:59-07:00 greg@kroah.com +10 -11
#   PCI: fix up __iomem mess in the PCI rom code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/pci-sysfs.c
#   2004/09/14 14:21:59-07:00 greg@kroah.com +1 -1
#   PCI: fix up __iomem mess in the PCI rom code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/14 14:05:32-07:00 greg@kroah.com 
#   PCI: fix __iomem * warnings for PCI msi core code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/msi.h
#   2004/09/14 14:04:18-07:00 greg@kroah.com +1 -1
#   PCI: fix __iomem * warnings for PCI msi core code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/msi.c
#   2004/09/14 14:04:18-07:00 greg@kroah.com +10 -10
#   PCI: fix __iomem * warnings for PCI msi core code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/14 13:45:48-07:00 dlsy@snoqualmie.dp.intel.com 
#   [PATCH] PCI Hotplug: change bus speed patch
#   
#   Greg,
#   
#   
#   Here is a patch (against 2.6.8-rc2) that fixes the following things:
#   1) adds code to lower bus speed if the adapter card added run at a
#   lower speed that the current bus speed; 2) checks for any devices on
#   the same bus - not just those that sit on slots controlled by the same
#   shpc; 3) cleans up the code in the check bus speed area in board_added()
#   by creating two functions to handle common code.
#   
#   Signed-off-by: Dely Sy <dely.l.sy@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchp_ctrl.c
#   2004/07/30 17:29:39-07:00 dlsy@snoqualmie.dp.intel.com +110 -339
#   PCI Hotplug: change bus speed patch
# 
# ChangeSet
#   2004/09/14 13:44:49-07:00 kaneshige.kenji@jp.fujitsu.com 
#   [PATCH] PCI: warn of missing pci_disable_device()
#   
#   As mentioned in Documentaion/pci.txt, pci device driver should call
#   pci_disable_device() when it decides to stop using the device. But
#   there are some drivers that don't use pci_disable_device() so far.
#   
#   This patch adds warning messages that are displayed if the device is
#   removed without properly calling pci_disable_device().
#   
#   'WARN_ON(1)' is commented out for now because I guess many people
#   (including some distros) enables 'CONFIG_DEBUG_KERNEL'. People might
#   be surprised if many stack dumps are displayed on their console.
#   
#   Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/pci-driver.c
#   2004/09/12 20:41:24-07:00 kaneshige.kenji@jp.fujitsu.com +13 -0
#   PCI: warn of missing pci_disable_device()
# 
# ChangeSet
#   2004/09/13 11:04:10-07:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/pci-2.6
# 
# drivers/pci/quirks.c
#   2004/09/13 11:03:51-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/13 11:03:51-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/09 15:23:09-07:00 greg@kroah.com 
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/09 15:05:16-07:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/pci-2.6
# 
# drivers/pci/setup-irq.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/quirks.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +9 -7
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/proc.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/pci.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/pci-sysfs.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/ibmphp_core.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/cpcihp_zt5550.c
#   2004/09/09 15:21:57-07:00 greg@kroah.com +2 -1
#   PCI: remove pci_find_device() usages from drivers/pci/*
#   
#   yeah, I ignored the ppc64 hotplug pci driver, they can fix it up themselves...
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/asm-generic/vmlinux.lds.h
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# drivers/media/video/bttv-cards.c
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_fops.h
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# drivers/acpi/processor.c
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# arch/sparc64/kernel/pci_sabre.c
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -4
#   Auto merged
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# arch/ia64/sn/io/machvec/pci_bus_cvlink.c
#   2004/09/09 15:05:09-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# arch/ia64/pci/pci.c
#   2004/09/09 15:05:08-07:00 greg@kroah.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/09 14:42:20-07:00 greg@kroah.com 
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/irq.c
#   2004/09/09 14:40:57-07:00 greg@kroah.com +13 -7
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/i386.c
#   2004/09/09 14:40:57-07:00 greg@kroah.com +2 -2
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/acpi.c
#   2004/09/09 14:40:57-07:00 greg@kroah.com +1 -1
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/cpu/cyrix.c
#   2004/09/09 14:40:57-07:00 greg@kroah.com +10 -2
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
#   2004/09/09 14:40:57-07:00 greg@kroah.com +2 -1
#   PCI: get rid of pci_find_device() from arch/i386/*
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/09 10:28:35-07:00 akpm@osdl.org 
#   [PATCH] add-pci_fixup_enable-pass.patch
#   
#   From: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   
#   Nick Piggin's USB driver stopped working when I removed the unconditional
#   PCI ACPI IRQ routing stuff.  He has verified that the attached patch fixes
#   it.  I sort of hate to add another pass of PCI fixups, so I'm open to
#   alternate solutions if anybody suggests one.
#   
#   Add a "pci_fixup_enable" pass of PCI fixups.  These are run at the end of
#   pci_enable_device() to fix up things like IRQs that are not set up until
#   then.  Some VIA boards require a fixup after the IRQ is set up.  Found by
#   Nick Piggin, initial patch by Bjorn Helgaas, reworked to fit into current
#   -mm by Nick.
#   
#   Signed-off-by: Nick Piggin <nickpiggin@yahoo.com.au>
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/08/09 22:02:21-07:00 akpm@osdl.org +7 -0
#   add-pci_fixup_enable-pass.patch
# 
# include/asm-generic/vmlinux.lds.h
#   2004/08/09 22:02:21-07:00 akpm@osdl.org +3 -0
#   add-pci_fixup_enable-pass.patch
# 
# drivers/pci/quirks.c
#   2004/08/09 22:02:21-07:00 akpm@osdl.org +12 -3
#   add-pci_fixup_enable-pass.patch
# 
# drivers/pci/pci.c
#   2004/08/09 22:02:21-07:00 akpm@osdl.org +6 -1
#   add-pci_fixup_enable-pass.patch
# 
# ChangeSet
#   2004/09/08 23:37:24-07:00 janitor@sternwelten.at 
#   [PATCH] PCI pci_dev_b to list_for_each_entry: drivers-pci-setup-bus.c
#   
#   list_for_each & pci_(dev|bus)_[bg] replaced by list_for_each_entry.
#   
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/setup-bus.c
#   2004/09/01 10:38:29-07:00 janitor@sternwelten.at +6 -6
#   PCI pci_dev_b to list_for_each_entry: drivers-pci-setup-bus.c
# 
# ChangeSet
#   2004/09/08 23:36:38-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ppc64-kernel-pSeries_pci.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc64/kernel/pSeries_pci.c
#   2004/09/01 10:38:07-07:00 janitor@sternwelten.at +2 -3
#   PCI list_for_each: arch-ppc64-kernel-pSeries_pci.c
# 
# ChangeSet
#   2004/09/08 23:36:10-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-sparc-kernel-pcic.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/sparc/kernel/pcic.c
#   2004/09/01 10:38:15-07:00 janitor@sternwelten.at +2 -4
#   PCI list_for_each: arch-sparc-kernel-pcic.c
# 
# ChangeSet
#   2004/09/08 23:35:38-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-sparc64-kernel-pci_sabre.c
#   
#   s/for/list_for_each//
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/sparc64/kernel/pci_sabre.c
#   2004/09/01 10:38:15-07:00 janitor@sternwelten.at +4 -8
#   PCI list_for_each: arch-sparc64-kernel-pci_sabre.c
# 
# ChangeSet
#   2004/09/08 23:35:09-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ppc-kernel-pci.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc/kernel/pci.c
#   2004/09/01 10:38:14-07:00 janitor@sternwelten.at +9 -19
#   PCI list_for_each: arch-ppc-kernel-pci.c
# 
# ChangeSet
#   2004/09/08 23:34:38-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ppc64-kernel-pci_dn.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc64/kernel/pci_dn.c
#   2004/09/01 10:38:14-07:00 janitor@sternwelten.at +1 -3
#   PCI list_for_each: arch-ppc64-kernel-pci_dn.c
# 
# ChangeSet
#   2004/09/08 23:34:08-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ppc64-kernel-pci.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc64/kernel/pci.c
#   2004/09/01 10:38:07-07:00 janitor@sternwelten.at +4 -7
#   PCI list_for_each: arch-ppc64-kernel-pci.c
# 
# ChangeSet
#   2004/09/08 23:33:37-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ia64-sn-io-machvec-pci_bus_cvlink.c
#   
#   s/for/list_for_each/
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ia64/sn/io/machvec/pci_bus_cvlink.c
#   2004/09/01 10:38:06-07:00 janitor@sternwelten.at +1 -3
#   PCI list_for_each: arch-ia64-sn-io-machvec-pci_bus_cvlink.c
# 
# ChangeSet
#   2004/09/08 23:33:07-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-ia64-pci-pci.c
#   
#   Change for loops with list_for_each_entry().
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ia64/pci/pci.c
#   2004/09/01 10:38:06-07:00 janitor@sternwelten.at +3 -3
#   PCI list_for_each: arch-ia64-pci-pci.c
# 
# ChangeSet
#   2004/09/08 23:32:33-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-alpha-kernel-pci.c
#   
#   Change for loops with list_for_each().
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/alpha/kernel/pci.c
#   2004/09/01 10:36:10-07:00 janitor@sternwelten.at +5 -11
#   PCI list_for_each: arch-alpha-kernel-pci.c
# 
# ChangeSet
#   2004/09/08 23:32:03-07:00 janitor@sternwelten.at 
#   [PATCH] PCI list_for_each: arch-i386-pci-i386.c
#   
#   Replace for with more readable list_for_each.
#   Compile tested.
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/i386.c
#   2004/09/01 10:38:06-07:00 janitor@sternwelten.at +1 -3
#   PCI list_for_each: arch-i386-pci-i386.c
# 
# ChangeSet
#   2004/09/08 22:50:05-07:00 shaohua.li@intel.com 
#   [PATCH] PCI: Reorder some initialization code to allow resources to be proper allocated.
#   
#   On Tuesday, August 31, 2004, Linus Torvalds wrote:
#   > That list per se obviously looks ok by me, although I'd worry that some
#   > other fs_initcall depends on the ACPI stuff having been run (ie while the
#   > abover ordering is great, I worry that some _other_ part doesn't fit in
#   > the above ordering). Doing a quick check finds "chr_dev_init()", for
#   > example, which will do fbmem_init(), which might depend on the ACPI/PnP
#   > stuff having run already.
#   >
#   > So it _might_ be safer to make this ordering more explicit, rather than
#   
#   Yes, I agree. The problem is there isn't a straightforward method for
#   it. It possibly is hard to get it.
#   
#   > depending on the different phases of the initcalls. But I'd happily be
#   > proven wrogn with some simple argument for why this is guaranteed to be
#   > ok.. For example, maybe ACPI and PnP is linked before chr/mem.c, in which
#   > case it should all be ok.
#   
#   Original PCI assign resources code is the last 'subsys_initcall'
#   according to the makefile, so move some code of it to 'fs_initcall'
#   (just below 'subsystem_initcall') should be ok. As you said, ACPI and
#   PnP is linked before chr/mem.c. The method requires all other
#   'fs_initcall' don't touch PCI resources, since
#   'pcibios_assign_resources' is a 'fs_initcall' and maybe don't run, but
#   it looks ok currently. Again, I will be appreciated if we can find a
#   solution to make the ordering explicit.
#   
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pnp/system.c
#   2004/08/30 20:29:35-07:00 shaohua.li@intel.com +5 -1
#   PCI: Reorder some initialization code to allow resources to be proper allocated.
# 
# drivers/acpi/motherboard.c
#   2004/08/30 20:28:27-07:00 shaohua.li@intel.com +5 -1
#   PCI: Reorder some initialization code to allow resources to be proper allocated.
# 
# arch/i386/pci/i386.c
#   2004/08/30 20:34:29-07:00 shaohua.li@intel.com +8 -2
#   PCI: Reorder some initialization code to allow resources to be proper allocated.
# 
# ChangeSet
#   2004/09/08 22:11:47-07:00 johnrose@austin.ibm.com 
#   [PATCH] PCI Hotplug: add host bridges to RPA hotplug subsystem
#   
#   The following patch implements the registration of PCI Host Bridges as hotplug
#   slots.  Only host bridges that are dynamically removable will be registered.
#   The hotplug slots directory goes from looking like this:
#   
#   # ls /sys/bus/pci/slots
#   .             0000:00:02.2  0001:00:02.4  0002:00:02.2  30000000
#   ..            0000:00:02.4  0001:00:02.6  0002:00:02.4  control
#   0000:00:02.0  0001:00:02.2  0002:00:02.0  0002:00:02.6
#   
#   to this:
#   
#   # ls /sys/bus/pci/slots
#   .             0000:00:02.0  0001:00:00.0  0001:00:02.6  0002:00:02.2  30000000
#   ..            0000:00:02.2  0001:00:02.2  0002:00:00.0  0002:00:02.4  control
#   0000:00:00.0  0000:00:02.4  0001:00:02.4  0002:00:02.0  0002:00:02.6
#   
#   This work is precursory to the DLPAR module changes that implement
#   addition/removal of these bridges.  Please apply if there are no objections.
#   
#   Signed-off-by: John Rose <johnrose@austin.ibm.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/rpaphp_core.c
#   2004/08/26 06:27:10-07:00 johnrose@austin.ibm.com +13 -7
#   PCI Hotplug: add host bridges to RPA hotplug subsystem
# 
# drivers/pci/hotplug/rpaphp.h
#   2004/08/26 06:27:10-07:00 johnrose@austin.ibm.com +1 -0
#   PCI Hotplug: add host bridges to RPA hotplug subsystem
# 
# ChangeSet
#   2004/09/08 16:55:27-07:00 david-b@pacbell.net 
#   [PATCH] PCI: update Documentation/power/pci.txt
#   
#   That document was wrong on some things, misleading on others; this
#   fixes some of the issues I noticed.
#   
#   However it probably needs to say that drivers for devices that implement
#   the PCI PM spec "should" always use pci_set_power_state() to reduce the
#   power usage.  If I get ambitions I might submit a patch to the PCI core
#   to print a nag message for drivers that don't do that.
#   
#   
#   Updates the PCI PM docs, better matching the specs and code.
#   
#     - List both D3 states (D3hot, D3cold) up front.
#   
#     - Clarify that suspend() methods should disable I/0 (including DMA)
#       and IRQs; it's not optional.
#   
#     - More accurately describe resume(); there are common cases where
#       device re-initialization isn't appropriate.  The previous text said
#       re-init was always required; that's false.
#   
#   Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# Documentation/power/pci.txt
#   2004/09/08 02:41:05-07:00 david-b@pacbell.net +35 -16
#   PCI: update Documentation/power/pci.txt
# 
# ChangeSet
#   2004/09/08 16:54:00-07:00 hch@lst.de 
#   [PATCH] PCI: mark proc_bus_pci_dir static
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/proc.c
#   2004/09/07 05:57:36-07:00 hch@lst.de +1 -2
#   PCI: mark proc_bus_pci_dir static
# 
# ChangeSet
#   2004/09/08 16:50:45-07:00 davej@redhat.com 
#   [PATCH] PCI Hotplug: Use before NULL check in shpchp_ctrl
#   
#   More fun found with the coverity checker.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/hotplug/shpchp_ctrl.c
#   2004/09/03 14:09:41-07:00 davej@redhat.com +3 -1
#   PCI Hotplug: Use before NULL check in shpchp_ctrl
# 
# ChangeSet
#   2004/09/08 16:49:33-07:00 johnpol@2ka.mipt.ru 
#   [PATCH] scx200: pci_find_device() removal.
#   
#   Remove pci_find_device() in arch/i386/kernel/scx200.c.
#   
#   Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/scx200.c
#   2004/09/01 22:30:04-07:00 johnpol@2ka.mipt.ru +40 -27
#   scx200: pci_find_device() removal.
# 
# ChangeSet
#   2004/09/08 16:48:14-07:00 jonsmirl@yahoo.com 
#   [PATCH] PCI: add PCI ROMs to sysfs
#   
#   Exposes PCI ROMs via sysfs. Four new routines for drivers to use when
#   accessing ROMs: pci_map_rom, pci_map_rom_copy, pci_unmap_rom, pci_remove_rom.
#   Handles shadow ROMs for laptops that compress actual ROMs.
#   
#   Signed-off-by: "Jon Smirl" <jonsmirl@yahoo.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +7 -0
#   PCI: add PCI ROMs to sysfs
# 
# include/linux/ioport.h
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +5 -0
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/setup-res.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +1 -1
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/remove.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +2 -0
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/probe.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +1 -1
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/pci.h
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +3 -1
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/pci-sysfs.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +93 -1
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/Makefile
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +2 -1
#   PCI: add PCI ROMs to sysfs
# 
# arch/i386/pci/fixup.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +38 -0
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/rom.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +226 -0
#   PCI: add PCI ROMs to sysfs
# 
# drivers/pci/rom.c
#   2004/08/28 17:22:21-07:00 jonsmirl@yahoo.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/rom.c
# 
# ChangeSet
#   2004/09/05 05:41:03+02:00 greg@kroah.com 
#   PCI: fix improper pr_debug() statement
#   
#   Thanks to Joe Perches for pointing this out.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/quirks.c
#   2004/09/05 05:40:39+02:00 greg@kroah.com +1 -1
#   PCI: fix improper pr_debug() statement
#   
#   Thanks to Joe Perches for pointing this out.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 15:27:59-07:00 greg@kroah.com 
#   PCI: delete the pci_find_class() function as it's unsafe in hotpluggable systems.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/08/26 15:26:34-07:00 greg@kroah.com +0 -4
#   PCI: delete the pci_find_class() function as it's unsafe in hotpluggable systems.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2004/08/26 15:26:34-07:00 greg@kroah.com +0 -40
#   PCI: delete the pci_find_class() function as it's unsafe in hotpluggable systems.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 15:26:14-07:00 greg@kroah.com 
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/scsi/eata.c
#   2004/08/26 15:23:42-07:00 greg@kroah.com +9 -3
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/net/wan/sbni.c
#   2004/08/26 15:23:43-07:00 greg@kroah.com +5 -1
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/media/video/bttv-cards.c
#   2004/08/26 15:23:43-07:00 greg@kroah.com +3 -3
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/char/ipmi/ipmi_si_intf.c
#   2004/08/26 15:23:43-07:00 greg@kroah.com +10 -4
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/char/drm/drm_fops.h
#   2004/08/26 15:23:43-07:00 greg@kroah.com +5 -2
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/char/applicom.c
#   2004/08/26 15:23:43-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_class() usage from all drivers/ files
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 15:21:14-07:00 greg@kroah.com 
#   PCI: remove pci_find_class() usage from arch specific files.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/ppc64/kernel/pci.c
#   2004/08/26 15:18:07-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_class() usage from arch specific files.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/cpu/mtrr/main.c
#   2004/08/26 15:18:07-07:00 greg@kroah.com +5 -3
#   PCI: remove pci_find_class() usage from arch specific files.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/alpha/kernel/console.c
#   2004/08/26 15:18:07-07:00 greg@kroah.com +1 -1
#   PCI: remove pci_find_class() usage from arch specific files.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 14:12:40-07:00 greg@kroah.com 
#   PCI: clean up the comments in search.c to be correct.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2004/08/26 14:11:30-07:00 greg@kroah.com +8 -10
#   PCI: clean up the comments in search.c to be correct.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 14:09:38-07:00 greg@kroah.com 
#   PCI: add pci_get_class() to make a safe pci_find_class() like call.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/08/26 14:08:25-07:00 greg@kroah.com +4 -0
#   PCI: add pci_get_class() to make a safe pci_find_class() like call.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2004/08/26 14:08:26-07:00 greg@kroah.com +38 -0
#   PCI: add pci_get_class() to make a safe pci_find_class() like call.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# Documentation/pci.txt
#   2004/08/26 14:08:25-07:00 greg@kroah.com +3 -2
#   PCI: add pci_get_class() to make a safe pci_find_class() like call.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 14:06:36-07:00 greg@kroah.com 
#   PCI: make pci_find_class() warn if in interrupt like all other find/get functions do.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2004/08/26 14:04:59-07:00 greg@kroah.com +1 -0
#   PCI: make pci_find_class() warn if in interrupt like all other find/get functions do.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 11:14:09-07:00 greg@kroah.com 
#   PCI: update the pci.txt documentation about pci_find_device and pci_find_subsys going away
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# Documentation/pci.txt
#   2004/08/26 11:13:38-07:00 greg@kroah.com +4 -4
#   PCI: update the pci.txt documentation about pci_find_device and pci_find_subsys going away
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 11:10:23-07:00 greg@kroah.com 
#   PCI: make pci_find_subsys() static, as it should not be used anymore
#   
#   Use pci_get_subsys() if you want this functionality.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci.h
#   2004/08/26 11:09:53-07:00 greg@kroah.com +0 -7
#   PCI: make pci_find_subsys() static, as it should not be used anymore
#   
#   Use pci_get_subsys() if you want this functionality.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2004/08/26 11:09:53-07:00 greg@kroah.com +5 -5
#   PCI: make pci_find_subsys() static, as it should not be used anymore
#   
#   Use pci_get_subsys() if you want this functionality.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 11:09:24-07:00 greg@kroah.com 
#   PCI: remove pci_find_subsys() calls from acpi code.
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/acpi/processor.c
#   2004/08/26 11:08:27-07:00 greg@kroah.com +10 -5
#   PCI: remove pci_find_subsys() calls from acpi code.
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/08/26 11:04:58-07:00 greg@kroah.com 
#   PCI: remove pci_find_subsys() calls from cpufreq code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
#   2004/08/26 11:01:25-07:00 greg@kroah.com +10 -5
#   PCI: remove pci_find_subsys() calls from cpufreq code.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
diff -Nru a/Documentation/pci.txt b/Documentation/pci.txt
--- a/Documentation/pci.txt	2004-09-26 14:30:27 -07:00
+++ b/Documentation/pci.txt	2004-09-26 14:30:27 -07:00
@@ -141,16 +141,16 @@
 Searching by vendor and device ID:
 
 	struct pci_dev *dev = NULL;
-	while (dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev))
+	while (dev = pci_get_device(VENDOR_ID, DEVICE_ID, dev))
 		configure_device(dev);
 
 Searching by class ID (iterate in a similar way):
 
-	pci_find_class(CLASS_ID, dev)
+	pci_get_class(CLASS_ID, dev)
 
 Searching by both vendor/device and subsystem vendor/device ID:
 
-	pci_find_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).
+	pci_get_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).
 
    You can use the constant PCI_ANY_ID as a wildcard replacement for
 VENDOR_ID or DEVICE_ID.  This allows searching for any device from a
@@ -275,11 +275,12 @@
 				devices just return NULL.
 pcibios_(read|write)_*		Superseded by their pci_(read|write)_*
 				counterparts.
-pcibios_find_*			Superseded by their pci_find_* counterparts.
-pci_for_each_dev()		Superseded by pci_find_device()
+pcibios_find_*			Superseded by their pci_get_* counterparts.
+pci_for_each_dev()		Superseded by pci_get_device()
 pci_for_each_dev_reverse()	Superseded by pci_find_device_reverse()
 pci_for_each_bus()		Superseded by pci_find_next_bus()
 pci_find_device()		Superseded by pci_get_device()
 pci_find_subsys()		Superseded by pci_get_subsys()
-pcibios_find_class()		Superseded by pci_find_class()
+pcibios_find_class()		Superseded by pci_get_class()
+pci_find_class()		Superseded by pci_get_class()
 pci_(read|write)_*_nodev()	Superseded by pci_bus_(read|write)_*()
diff -Nru a/Documentation/power/pci.txt b/Documentation/power/pci.txt
--- a/Documentation/power/pci.txt	2004-09-26 14:30:27 -07:00
+++ b/Documentation/power/pci.txt	2004-09-26 14:30:27 -07:00
@@ -5,6 +5,7 @@
 An overview of the concepts and the related functions in the Linux kernel
 
 Patrick Mochel <mochel@transmeta.com>
+(and others)
 
 ---------------------------------------------------------------------------
 
@@ -31,10 +32,15 @@
 the higher the number, the longer the latency is for the device to return to 
 an operational state (D0).
 
+There are actually two D3 states.  When someone talks about D3, they usually
+mean D3hot, which corresponds to an ACPI D2 state (power is reduced, the
+device may lose some context).  But they may also mean D3cold, which is an
+ACPI D3 state (power is fully off, all state was discarded); or both.
+
 Bus power management is not covered in this version of this document.
 
-Note that all PCI devices support D0 and D3 by default, regardless of whether or
-not they implement any of the PCI PM spec.
+Note that all PCI devices support D0 and D3cold by default, regardless of
+whether or not they implement any of the PCI PM spec.
 
 The possible state transitions that a device can undergo are:
 
@@ -204,15 +210,16 @@
 	dev->driver->suspend(dev,state);
 
 A driver uses this function to actually transition the device into a low power
-state. This may include disabling I/O, memory and bus-mastering, as well as
-physically transitioning the device to a lower power state.
+state. This should include disabling I/O, IRQs, and bus-mastering, as well as
+physically transitioning the device to a lower power state; it may also include
+calls to pci_enable_wake().
 
 Bus mastering may be disabled by doing:
 
 pci_disable_device(dev);
 
 For devices that support the PCI PM Spec, this may be used to set the device's
-power state:
+power state to match the suspend() parameter:
 
 pci_set_power_state(dev,state);
 
@@ -223,7 +230,7 @@
 obviate the need for some operations.
 
 The driver should update the current_state field in its pci_dev structure in
-this function.
+this function, except for PM-capable devices when pci_set_power_state is used.
 
 resume
 ------
@@ -237,16 +244,28 @@
 transition the device to the D0 state. 
 
 The driver is responsible for reenabling any features of the device that had
-been disabled during previous suspend calls and restoring all state that was
-saved in previous save_state calls.
+been disabled during previous suspend calls, such as IRQs and bus mastering,
+as well as calling pci_restore_state().
+
+If the device is currently in D3, it may need to be reinitialized in resume().
 
-If the device is currently in D3, it must be completely reinitialized, as it
-must be assumed that the device has lost all of its context (even that of its
-PCI config space). For almost all current drivers, this means that the
-initialization code that the driver does at boot must be separated out and
-called again from the resume callback. Note that some values for the device may
-not have to be probed for this time around if they are saved before entering the
-low power state.
+  * Some types of devices, like bus controllers, will preserve context in D3hot
+    (using Vcc power).  Their drivers will often want to avoid re-initializing
+    them after re-entering D0 (perhaps to avoid resetting downstream devices).
+
+  * Other kinds of devices in D3hot will discard device context as part of a
+    soft reset when re-entering the D0 state.
+    
+  * Devices resuming from D3cold always go through a power-on reset.  Some
+    device context can also be preserved using Vaux power.
+
+  * Some systems hide D3cold resume paths from drivers.  For example, on PCs
+    the resume path for suspend-to-disk often runs BIOS powerup code, which
+    will sometimes re-initialize the device.
+
+To handle resets during D3 to D0 transitions, it may be convenient to share
+device initialization code between probe() and resume().  Device parameters
+can also be saved before the driver suspends into D3, avoiding re-probe.
 
 If the device supports the PCI PM Spec, it can use this to physically transition
 the device to D0:
@@ -263,7 +282,7 @@
 ensure correct (and speedy) operation.
 
 The driver should update the current_state field in its pci_dev structure in
-this function.
+this function, except for PM-capable devices when pci_set_power_state is used.
 
 
 enable_wake
diff -Nru a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
--- a/arch/alpha/kernel/console.c	2004-09-26 14:30:27 -07:00
+++ b/arch/alpha/kernel/console.c	2004-09-26 14:30:27 -07:00
@@ -47,7 +47,7 @@
 
 	if (!sel_func) sel_func = (void *)default_vga_hose_select;
 
-	for(dev=NULL; (dev=pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
+	for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
 		if (!hose) hose = dev->sysdata;
 		else hose = sel_func(hose, dev->sysdata);
 	}
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	2004-09-26 14:30:27 -07:00
+++ b/arch/alpha/kernel/pci.c	2004-09-26 14:30:27 -07:00
@@ -280,7 +280,6 @@
 	/* Propagate hose info into the subordinate devices.  */
 
 	struct pci_controller *hose = bus->sysdata;
-	struct list_head *ln;
 	struct pci_dev *dev = bus->self;
 
 	if (!dev) {
@@ -304,9 +303,7 @@
  		pcibios_fixup_device_resources(dev, bus);
 	} 
 
-	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		struct pci_dev *dev = pci_dev_b(ln);
-
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 		pdev_save_srm_config(dev);
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			pcibios_fixup_device_resources(dev, bus);
@@ -403,11 +400,10 @@
 static void __init
 pcibios_claim_one_bus(struct pci_bus *b)
 {
-	struct list_head *ld;
+	struct pci_dev *dev;
 	struct pci_bus *child_bus;
 
-	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
-		struct pci_dev *dev = pci_dev_b(ld);
+	list_for_each_entry(dev, &b->devices, bus_list) {
 		int i;
 
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -426,12 +422,10 @@
 static void __init
 pcibios_claim_console_setup(void)
 {
-	struct list_head *lb;
+	struct pci_bus *b;
 
-	for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
-		struct pci_bus *b = pci_bus_b(lb);
+	list_for_each_entry(b, &pci_root_buses, node)
 		pcibios_claim_one_bus(b);
-	}
 }
 
 void __init
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2004-09-26 14:30:27 -07:00
@@ -199,7 +199,7 @@
 	}
 
 	/* detect which companion chip is used */
-	while ((gx_pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
+	while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
 		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
 			return gx_pci;
 		}
@@ -499,6 +499,7 @@
 static void __exit cpufreq_gx_exit(void)
 {
 	cpufreq_unregister_driver(&gx_suspmod_driver);
+	pci_dev_put(gx_params->cs55x0);
 	kfree(gx_params);
 }
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2004-09-26 14:30:27 -07:00
@@ -171,7 +171,7 @@
  */
 static unsigned int speedstep_detect_chipset (void)
 {
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801DB_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -179,7 +179,7 @@
 	if (speedstep_chipset_dev)
 		return 4; /* 4-M */
 
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801CA_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -188,7 +188,7 @@
 		return 3; /* 3-M */
 
 
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801BA_10,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -201,7 +201,7 @@
 		static struct pci_dev *hostbridge;
 		u8 rev = 0;
 
-		hostbridge  = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+		hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82815_MC,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -214,9 +214,11 @@
 		if (rev < 5) {
 			dprintk(KERN_INFO "cpufreq: hostbridge does not support speedstep\n");
 			speedstep_chipset_dev = NULL;
+			pci_dev_put(hostbridge);
 			return 0;
 		}
 
+		pci_dev_put(hostbridge);
 		return 2; /* 2-M */
 	}
 
@@ -411,8 +413,10 @@
 	}
 
 	/* activate speedstep support */
-	if (speedstep_activate())
+	if (speedstep_activate()) {
+		pci_dev_put(speedstep_chipset_dev);
 		return -EINVAL;
+	}
 
 	return cpufreq_register_driver(&speedstep_driver);
 }
@@ -425,6 +429,7 @@
  */
 static void __exit speedstep_exit(void)
 {
+	pci_dev_put(speedstep_chipset_dev);
 	cpufreq_unregister_driver(&speedstep_driver);
 }
 
diff -Nru a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
--- a/arch/i386/kernel/cpu/cyrix.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/kernel/cpu/cyrix.c	2004-09-26 14:30:27 -07:00
@@ -192,6 +192,7 @@
 	unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
 	char *buf = c->x86_model_id;
 	const char *p = NULL;
+	struct pci_dev *dev;
 
 	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
 	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
@@ -274,9 +275,16 @@
 		/*
 		 *  The 5510/5520 companion chips have a funky PIT.
 		 */  
-		if (pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||
-		    pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))
+		dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL);
+		if (dev) {
+			pci_dev_put(dev);
 			pit_latch_buggy = 1;
+		}
+		dev =  pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL);
+		if (dev) {
+			pci_dev_put(dev);
+			pit_latch_buggy = 1;
+		}
 
 		/* GXm supports extended cpuid levels 'ala' AMD */
 		if (c->cpuid_level == 2) {
diff -Nru a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
--- a/arch/i386/kernel/cpu/mtrr/main.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/kernel/cpu/mtrr/main.c	2004-09-26 14:30:27 -07:00
@@ -77,22 +77,24 @@
 {
 	struct pci_dev *dev;
 	
-	if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
+	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
 		/* ServerWorks LE chipsets have problems with write-combining 
 		   Don't allow it and leave room for other chipsets to be tagged */
 		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
 		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
 			printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
+			pci_dev_put(dev);
 			return 0;
 		}
 		/* Intel 450NX errata # 23. Non ascending cachline evictions to
 		   write combining memory may resulting in data corruption */
 		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
-		    dev->device == PCI_DEVICE_ID_INTEL_82451NX)
-		{
+		    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
 			printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
+			pci_dev_put(dev);
 			return 0;
 		}
+		pci_dev_put(dev);
 	}		
 	return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
 }
diff -Nru a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
--- a/arch/i386/kernel/scx200.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/kernel/scx200.c	2004-09-26 14:30:27 -07:00
@@ -22,9 +22,47 @@
 unsigned scx200_gpio_base = 0;
 long scx200_gpio_shadow[2];
 
+static struct pci_device_id scx200_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci,scx200_tbl);
+
+static int __devinit scx200_probe(struct pci_dev *, const struct pci_device_id *);
+
+static struct pci_driver scx200_pci_driver = {
+	.name = "scx200",
+	.id_table = scx200_tbl,
+	.probe = scx200_probe,
+};
+
 spinlock_t scx200_gpio_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t scx200_gpio_config_lock = SPIN_LOCK_UNLOCKED;
 
+static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int bank;
+	unsigned base;
+
+	base = pci_resource_start(pdev, 0);
+	printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
+
+	if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) {
+		printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
+		return -EBUSY;
+	}
+
+	scx200_gpio_base = base;
+
+	/* read the current values driven on the GPIO signals */
+	for (bank = 0; bank < 2; ++bank)
+		scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
+
+	return 0;
+
+}
+
 u32 scx200_gpio_configure(int index, u32 mask, u32 bits)
 {
 	u32 config, new_config;
@@ -77,39 +115,14 @@
 
 int __init scx200_init(void)
 {
-	struct pci_dev *bridge;
-	int bank;
-	unsigned base;
-
 	printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n");
 
-	if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 
-				      PCI_DEVICE_ID_NS_SCx200_BRIDGE,
-				      NULL)) == NULL
-	    && (bridge = pci_find_device(PCI_VENDOR_ID_NS,
-					 PCI_DEVICE_ID_NS_SC1100_BRIDGE,
-					 NULL)) == NULL)
-		return -ENODEV;
-
-	base = pci_resource_start(bridge, 0);
-	printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
-
-	if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) {
-		printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
-		return -EBUSY;
-	}
-
-	scx200_gpio_base = base;
-
-	/* read the current values driven on the GPIO signals */
-	for (bank = 0; bank < 2; ++bank)
-		scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
-
-	return 0;
+	return pci_module_init(&scx200_pci_driver);
 }
 
 void __exit scx200_cleanup(void)
 {
+	pci_unregister_driver(&scx200_pci_driver);
 	release_region(scx200_gpio_base, SCx200_GPIO_SIZE);
 }
 
diff -Nru a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
--- a/arch/i386/pci/fixup.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/pci/fixup.c	2004-09-26 14:30:27 -07:00
@@ -255,3 +255,41 @@
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
 
+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@yahoo.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video 
+ * card will have it's BIOS copied to C0000 in system RAM. 
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ *
+ */static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+	struct pci_dev *bridge;
+	struct pci_bus *bus;
+	u16 l;
+
+	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+		return;
+
+	/* Is VGA routed to us? */
+	bus = pdev->bus;
+	while (bus) {
+		bridge = bus->self;
+		if (bridge) {
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &l);
+			if (!(l & PCI_BRIDGE_CTL_VGA))
+				return;
+		}
+		bus = bus->parent;
+	}
+	pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
diff -Nru a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
--- a/arch/i386/pci/i386.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/pci/i386.c	2004-09-26 14:30:27 -07:00
@@ -96,15 +96,13 @@
 
 static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	int idx;
 	struct resource *r, *pr;
 
 	/* Depth-First Search on bus tree */
-	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		if ((dev = bus->self)) {
 			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
 				r = &dev->resource[idx];
@@ -126,7 +124,7 @@
 	u16 command;
 	struct resource *r, *pr;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -164,13 +162,13 @@
 	}
 }
 
-static void __init pcibios_assign_resources(void)
+static int __init pcibios_assign_resources(void)
 {
 	struct pci_dev *dev = NULL;
 	int idx;
 	struct resource *r;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
@@ -204,6 +202,7 @@
 				pci_assign_resource(dev, PCI_ROM_RESOURCE);
 		}
 	}
+	return 0;
 }
 
 void __init pcibios_resource_survey(void)
@@ -212,8 +211,13 @@
 	pcibios_allocate_bus_resources(&pci_root_buses);
 	pcibios_allocate_resources(0);
 	pcibios_allocate_resources(1);
-	pcibios_assign_resources();
 }
+
+/**
+ * called in fs_initcall (one below subsys_initcall),
+ * give a chance for motherboard reserve resources
+ */
+fs_initcall(pcibios_assign_resources);
 
 int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c	2004-09-26 14:30:27 -07:00
+++ b/arch/i386/pci/irq.c	2004-09-26 14:30:27 -07:00
@@ -455,12 +455,18 @@
 
 static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
 {
+	struct pci_dev *dev1, *dev2;
+
 	/* 440GX has a proprietary PIRQ router -- don't use it */
-	if (	pci_find_device(PCI_VENDOR_ID_INTEL,
-				PCI_DEVICE_ID_INTEL_82443GX_0, NULL) ||
-		pci_find_device(PCI_VENDOR_ID_INTEL,
-				PCI_DEVICE_ID_INTEL_82443GX_2, NULL))
+	dev1 = pci_get_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82443GX_0, NULL);
+	dev2 = pci_get_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82443GX_2, NULL);
+	if ((dev1 != NULL) || (dev2 != NULL)) {
+		pci_dev_put(dev1);
+		pci_dev_put(dev2);
 		return 0;
+	}
 
 	switch(device)
 	{
@@ -804,7 +810,7 @@
 	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
 
 	/* Update IRQ for all devices with the same pirq value */
-	while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
+	while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
 		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
 		if (!pin)
 			continue;
@@ -838,7 +844,7 @@
 	u8 pin;
 
 	DBG("PCI: IRQ fixup\n");
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * If the BIOS has set an out of range IRQ number, just ignore it.
 		 * Also keep track of which IRQ's are already in use.
@@ -854,7 +860,7 @@
 	}
 
 	dev = NULL;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef CONFIG_X86_IO_APIC
 		/*
diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ia64/pci/pci.c	2004-09-26 14:30:27 -07:00
@@ -365,10 +365,10 @@
 void __devinit
 pcibios_fixup_bus (struct pci_bus *b)
 {
-	struct list_head *ln;
+	struct pci_dev *dev;
 
-	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
-		pcibios_fixup_device_resources(pci_dev_b(ln), b);
+	list_for_each_entry(dev, &b->devices, bus_list)
+		pcibios_fixup_device_resources(dev, b);
 
 	return;
 }
diff -Nru a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2004-09-26 14:30:27 -07:00
@@ -832,7 +832,6 @@
 {
 	int i = 0;
 	struct pci_controller *controller;
-	struct list_head *ln;
 	struct pci_bus *pci_bus = NULL;
 	struct pci_dev *pci_dev = NULL;
 	int ret;
@@ -879,8 +878,7 @@
 	/*
 	 * Initialize the pci bus vertex in the pci_bus struct.
 	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
+	list_for_each_entry(pci_bus, &pci_root_buses, node) {
 		ret = sn_pci_fixup_bus(pci_bus);
 		if ( ret ) {
 			printk(KERN_WARNING
diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
--- a/arch/ppc/kernel/pci.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ppc/kernel/pci.c	2004-09-26 14:30:27 -07:00
@@ -231,14 +231,12 @@
 static void __init
 pcibios_allocate_bus_resources(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 	int i;
 	struct resource *res, *pr;
 
 	/* Depth-First Search on bus tree */
-	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		for (i = 0; i < 4; ++i) {
 			if ((res = bus->resource[i]) == NULL || !res->flags
 			    || res->start > res->end)
@@ -381,7 +379,6 @@
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	struct resource *r;
-	struct list_head *ln;
 	int i;
 
 	for (r = pr->child; r != NULL; r = r->sibling) {
@@ -390,9 +387,7 @@
 			return 1;
 		}
 	}
-	for (ln = parent->children.next; ln != &parent->children;
-	     ln = ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, &parent->children, node) {
 		for (i = 0; i < 4; ++i) {
 			if ((r = bus->resource[i]) == NULL)
 				continue;
@@ -406,8 +401,7 @@
 			}
 		}
 	}
-	for (ln = parent->devices.next; ln != &parent->devices; ln=ln->next) {
-		dev = pci_dev_b(ln);
+	list_for_each_entry(dev, &parent->devices, bus_list) {
 		for (i = 0; i < 6; ++i) {
 			r = &dev->resource[i];
 			if (!r->flags || (r->flags & IORESOURCE_UNSET))
@@ -1102,7 +1096,7 @@
 static int __init
 check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
 {
-	struct list_head *ln;
+	struct pci_dev *dev;
 	int	i;
 	int	rc = 0;
 
@@ -1110,8 +1104,7 @@
 	res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
     } while (0)
 
-	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-		struct pci_dev *dev = pci_dev_b(ln);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 class = dev->class >> 8;
 
 		if (class == PCI_CLASS_DISPLAY_VGA ||
@@ -1152,7 +1145,7 @@
 static void __init
 do_fixup_p2p_level(struct pci_bus *bus)
 {
-	struct list_head *ln;
+	struct pci_bus *b;
 	int i, parent_io;
 	int has_vga = 0;
 
@@ -1163,8 +1156,7 @@
 	if (parent_io >= 4)
 		return;
 
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
+	list_for_each_entry(b, &bus->children, node) {
 		struct pci_dev *d = b->self;
 		struct pci_controller* hose = (struct pci_controller *)d->sysdata;
 		struct resource *res = b->resource[0];
@@ -1237,12 +1229,10 @@
 static void
 pcibios_fixup_p2p_bridges(void)
 {
-	struct list_head *ln;
+	struct pci_bus *b;
 
-	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
+	list_for_each_entry(b, &pci_root_buses, node)
 		do_fixup_p2p_level(b);
-	}
 }
 
 #endif /* CONFIG_PPC_PMAC */
diff -Nru a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ppc64/kernel/pSeries_pci.c	2004-09-26 14:30:27 -07:00
@@ -372,6 +372,96 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
 #endif
 
+void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
+					   struct pci_bus *bus)
+{
+	/* Update device resources.  */
+	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (dev->resource[i].flags & IORESOURCE_IO) {
+			unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+                        unsigned long start, end, mask;
+
+                        start = dev->resource[i].start += offset;
+                        end = dev->resource[i].end += offset;
+
+                        /* Need to allow IO access to pages that are in the
+                           ISA range */
+                        if (start < MAX_ISA_PORT) {
+                                if (end > MAX_ISA_PORT)
+                                        end = MAX_ISA_PORT;
+
+                                start >>= PAGE_SHIFT;
+                                end >>= PAGE_SHIFT;
+
+                                /* get the range of pages for the map */
+                                mask = ((1 << (end+1))-1) ^ ((1 << start)-1);
+                                io_page_mask |= mask;
+                        }
+		}
+                else if (dev->resource[i].flags & IORESOURCE_MEM) {
+			dev->resource[i].start += hose->pci_mem_offset;
+			dev->resource[i].end += hose->pci_mem_offset;
+		}
+        }
+}
+EXPORT_SYMBOL(pcibios_fixup_device_resources);
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+	struct list_head *ln;
+
+	/* XXX or bus->parent? */
+	struct pci_dev *dev = bus->self;
+	struct resource *res;
+	int i;
+
+	if (!dev) {
+		/* Root bus. */
+
+		hose->bus = bus;
+		bus->resource[0] = res = &hose->io_resource;
+		if (!res->flags)
+			BUG();	/* No I/O resource for this PHB? */
+
+		if (request_resource(&ioport_resource, res))
+			printk(KERN_ERR "Failed to request IO on "
+					"PCI domain %d\n", pci_domain_nr(bus));
+
+
+		for (i = 0; i < 3; ++i) {
+			res = &hose->mem_resources[i];
+			if (!res->flags && i == 0)
+				BUG();	/* No memory resource for this PHB? */
+			bus->resource[i+1] = res;
+			if (res->flags && request_resource(&iomem_resource, res))
+				printk(KERN_ERR "Failed to request MEM on "
+						"PCI domain %d\n",
+						pci_domain_nr(bus));
+		}
+	} else if (pci_probe_only &&
+		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		/* This is a subordinate bridge */
+
+		pci_read_bridge_bases(bus);
+		pcibios_fixup_device_resources(dev, bus);
+	}
+
+	/* XXX Need to check why Alpha doesnt do this - Anton */
+	if (!pci_probe_only)
+		return;
+
+	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+			pcibios_fixup_device_resources(dev, bus);
+	}
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
 static void check_s7a(void)
 {
 	struct device_node *root;
diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ppc64/kernel/pci.c	2004-09-26 14:30:27 -07:00
@@ -236,11 +236,10 @@
 
 static void __init pcibios_claim_one_bus(struct pci_bus *b)
 {
-	struct list_head *ld;
+	struct pci_dev *dev;
 	struct pci_bus *child_bus;
 
-	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
-		struct pci_dev *dev = pci_dev_b(ld);
+	list_for_each_entry(dev, &b->devices, bus_list) {
 		int i;
 
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -259,12 +258,10 @@
 #ifndef CONFIG_PPC_ISERIES
 static void __init pcibios_claim_of_setup(void)
 {
-	struct list_head *lb;
+	struct pci_bus *b;
 
-	for (lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
-		struct pci_bus *b = pci_bus_b(lb);
+	list_for_each_entry(b, &pci_root_buses, node)
 		pcibios_claim_one_bus(b);
-	}
 }
 #endif
 
@@ -303,7 +300,7 @@
 		ppc_md.pcibios_fixup();
 
 	/* Cache the location of the ISA bridge (if we have one) */
-	ppc64_isabridge_dev = pci_find_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
 	if (ppc64_isabridge_dev != NULL)
 		printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
diff -Nru a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
--- a/arch/ppc64/kernel/pci_dn.c	2004-09-26 14:30:27 -07:00
+++ b/arch/ppc64/kernel/pci_dn.c	2004-09-26 14:30:27 -07:00
@@ -196,11 +196,9 @@
 
 static void __init pci_fixup_bus_sysdata_list(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 
-	for (ln = bus_list->next; ln != bus_list; ln = ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		if (bus->self)
 			bus->sysdata = bus->self->sysdata;
 		pci_fixup_bus_sysdata_list(&bus->children);
diff -Nru a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
--- a/arch/sparc/kernel/pcic.c	2004-09-26 14:30:27 -07:00
+++ b/arch/sparc/kernel/pcic.c	2004-09-26 14:30:27 -07:00
@@ -603,7 +603,7 @@
  */
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct list_head *walk;
+	struct pci_dev *dev;
 	int i, has_io, has_mem;
 	unsigned int cmd;
 	struct linux_pcic *pcic;
@@ -625,9 +625,7 @@
 		return;
 	}
 
-	walk = &bus->devices;
-	for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
-		struct pci_dev *dev = pci_dev_b(walk);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 
 		/*
 		 * Comment from i386 branch:
diff -Nru a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
--- a/drivers/acpi/motherboard.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/acpi/motherboard.c	2004-09-26 14:30:27 -07:00
@@ -170,4 +170,8 @@
 	return 0;
 }
 
-subsys_initcall(acpi_motherboard_init);
+/**
+ * Reserve motherboard resources after PCI claim BARs,
+ * but before PCI assign resources for uninitialized PCI devices
+ */
+fs_initcall(acpi_motherboard_init);
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/acpi/processor.c	2004-09-26 14:30:27 -07:00
@@ -213,11 +213,13 @@
 		 * each IDE controller's DMA status to make sure we catch all
 		 * DMA activity.
 		 */
-		dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 		           PCI_DEVICE_ID_INTEL_82371AB, 
                            PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev)
+		if (dev) {
 			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
 
 		/* 
 		 * Type-F DMA
@@ -228,7 +230,7 @@
 		 * disable C3 support if this is enabled, as some legacy 
 		 * devices won't operate well if fast DMA is disabled.
 		 */
-		dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, 
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
 			PCI_DEVICE_ID_INTEL_82371AB_0, 
 			PCI_ANY_ID, PCI_ANY_ID, NULL);
 		if (dev) {
@@ -236,6 +238,7 @@
 			pci_read_config_byte(dev, 0x77, &value2);
 			if ((value1 & 0x80) || (value2 & 0x80))
 				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
 		}
 
 		break;
@@ -267,10 +270,12 @@
 	/*
 	 * PIIX4
 	 */
-	dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, 
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
 		PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (dev)
+	if (dev) {
 		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
 
 	return_VALUE(result);
 }
diff -Nru a/drivers/char/applicom.c b/drivers/char/applicom.c
--- a/drivers/char/applicom.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/char/applicom.c	2004-09-26 14:30:27 -07:00
@@ -200,7 +200,7 @@
 
 	/* No mem and irq given - check for a PCI card */
 
-	while ( (dev = pci_find_class(PCI_CLASS_OTHERS << 16, dev))) {
+	while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {
 
 		if (dev->vendor != PCI_VENDOR_ID_APPLICOM)
 			continue;
diff -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h
--- a/drivers/char/drm/drm_fops.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/char/drm/drm_fops.h	2004-09-26 14:30:27 -07:00
@@ -99,8 +99,11 @@
 	 */
 	if (!dev->hose) {
 		struct pci_dev *pci_dev;
-		pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
-		if (pci_dev) dev->hose = pci_dev->sysdata;
+		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+		if (pci_dev) {
+			dev->hose = pci_dev->sysdata;
+			pci_dev_put(pci_dev);
+		}
 		if (!dev->hose) {
 			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
 			if (b) dev->hose = b->sysdata;
diff -Nru a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
--- a/drivers/char/ipmi/ipmi_si_intf.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/char/ipmi/ipmi_si_intf.c	2004-09-26 14:30:27 -07:00
@@ -1777,10 +1777,10 @@
 
 	pci_smic_checked = 1;
 
-	if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
+	if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
 				       NULL)))
 		;
-	else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) &&
+	else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) &&
 		 pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
 		fe_rmc = 1;
 	else
@@ -1789,6 +1789,7 @@
 	error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
 	if (error)
 	{
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR
 		       "ipmi_si: pci_read_config_word() failed (%d).\n",
 		       error);
@@ -1798,6 +1799,7 @@
 	/* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
 	if (!(base_addr & 0x0001))
 	{
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR
 		       "ipmi_si: memory mapped I/O not supported for PCI"
 		       " smic.\n");
@@ -1809,11 +1811,14 @@
 		/* Data register starts at base address + 1 in eRMC */
 		++base_addr;
 
-	if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr))
-	    return -ENODEV;
+	if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) {
+		pci_dev_put(pci_dev);
+		return -ENODEV;
+	}
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n");
 		return -ENOMEM;
 	}
@@ -1836,6 +1841,7 @@
 	printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n",
 		(long unsigned int) base_addr);
 
+	pci_dev_put(pci_dev);
 	return 0;
 }
 #endif /* CONFIG_PCI */
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/media/video/bttv-cards.c	2004-09-26 14:30:27 -07:00
@@ -4045,7 +4045,7 @@
 
 #if 0
 	/* print which chipset we have */
-	while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
+	while ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
 		printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
 #endif
 
@@ -4064,8 +4064,8 @@
 	if (UNSET != latency)
 		printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
 
-	while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-				      PCI_DEVICE_ID_INTEL_82441, dev))) {
+	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82441, dev))) {
                 unsigned char b;
 		pci_read_config_byte(dev, 0x53, &b);
 		if (bttv_debug)
diff -Nru a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
--- a/drivers/misc/ibmasm/ibmasm.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/misc/ibmasm/ibmasm.h	2004-09-26 14:30:27 -07:00
@@ -158,7 +158,7 @@
 struct service_processor {
 	struct list_head	node;
 	spinlock_t		lock;
-	void 			*base_address;
+	void __iomem		*base_address;
 	unsigned int		irq;
 	struct command		*current_command;
 	struct command		*heartbeat;
diff -Nru a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
--- a/drivers/misc/ibmasm/ibmasmfs.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/misc/ibmasm/ibmasmfs.c	2004-09-26 14:30:27 -07:00
@@ -520,7 +520,7 @@
 
 static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-	unsigned long address = (unsigned long)file->private_data;
+	void __iomem *address = (void __iomem *)file->private_data;
 	unsigned char *page;
 	int retval;
 	int len = 0;
@@ -554,7 +554,7 @@
 
 static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
 {
-	unsigned long address = (unsigned long)file->private_data;
+	void __iomem *address = (void __iomem *)file->private_data;
 	char *buff;
 	unsigned int value;
 
diff -Nru a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c
--- a/drivers/misc/ibmasm/lowlevel.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/misc/ibmasm/lowlevel.c	2004-09-26 14:30:27 -07:00
@@ -58,7 +58,7 @@
 {
 	u32	mfa;
 	struct service_processor *sp = (struct service_processor *)dev_id;
-	void *base_address = sp->base_address;
+	void __iomem *base_address = sp->base_address;
 
 	if (!sp_interrupt_pending(base_address))
 		return IRQ_NONE;
diff -Nru a/drivers/misc/ibmasm/lowlevel.h b/drivers/misc/ibmasm/lowlevel.h
--- a/drivers/misc/ibmasm/lowlevel.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/misc/ibmasm/lowlevel.h	2004-09-26 14:30:27 -07:00
@@ -52,51 +52,51 @@
 #define SCOUT_COM_C_BASE         0x0200   
 #define SCOUT_COM_D_BASE         0x0300   
 
-static inline int sp_interrupt_pending(void *base_address)
+static inline int sp_interrupt_pending(void __iomem *base_address)
 {
 	return SP_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
 }
 
-static inline int uart_interrupt_pending(void *base_address)
+static inline int uart_interrupt_pending(void __iomem *base_address)
 {
 	return UART_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
 }
 
-static inline void ibmasm_enable_interrupts(void *base_address, int mask)
+static inline void ibmasm_enable_interrupts(void __iomem *base_address, int mask)
 {
-	void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+	void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
 	writel( readl(ctrl_reg) & ~mask, ctrl_reg);
 }
 
-static inline void ibmasm_disable_interrupts(void *base_address, int mask)
+static inline void ibmasm_disable_interrupts(void __iomem *base_address, int mask)
 {
-	void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+	void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
 	writel( readl(ctrl_reg) | mask, ctrl_reg);
 }
 
-static inline void enable_sp_interrupts(void *base_address)
+static inline void enable_sp_interrupts(void __iomem *base_address)
 {
 	ibmasm_enable_interrupts(base_address, SP_INTR_MASK);
 }
 
-static inline void disable_sp_interrupts(void *base_address)
+static inline void disable_sp_interrupts(void __iomem *base_address)
 {
 	ibmasm_disable_interrupts(base_address, SP_INTR_MASK);
 }
 
-static inline void enable_uart_interrupts(void *base_address)
+static inline void enable_uart_interrupts(void __iomem *base_address)
 {
 	ibmasm_enable_interrupts(base_address, UART_INTR_MASK); 
 }
 
-static inline void disable_uart_interrupts(void *base_address)
+static inline void disable_uart_interrupts(void __iomem *base_address)
 {
 	ibmasm_disable_interrupts(base_address, UART_INTR_MASK); 
 }
 
 #define valid_mfa(mfa)	( (mfa) != NO_MFAS_AVAILABLE )
 
-static inline u32 get_mfa_outbound(void *base_address)
+static inline u32 get_mfa_outbound(void __iomem *base_address)
 {
 	int retry;
 	u32 mfa;
@@ -109,12 +109,12 @@
 	return mfa;
 }
 
-static inline void set_mfa_outbound(void *base_address, u32 mfa)
+static inline void set_mfa_outbound(void __iomem *base_address, u32 mfa)
 {
    	writel(mfa, base_address + OUTBOUND_QUEUE_PORT);
 }
 
-static inline u32 get_mfa_inbound(void *base_address)
+static inline u32 get_mfa_inbound(void __iomem *base_address)
 {
 	u32 mfa = readl(base_address + INBOUND_QUEUE_PORT);
 
@@ -124,12 +124,12 @@
 	return mfa;
 }
 
-static inline void set_mfa_inbound(void *base_address, u32 mfa)
+static inline void set_mfa_inbound(void __iomem *base_address, u32 mfa)
 {
    	writel(mfa, base_address + INBOUND_QUEUE_PORT);
 }
 
-static inline struct i2o_message *get_i2o_message(void *base_address, u32 mfa)
+static inline struct i2o_message *get_i2o_message(void __iomem *base_address, u32 mfa)
 {
 	return (struct i2o_message *)(GET_MFA_ADDR(mfa) + base_address);
 }
diff -Nru a/drivers/misc/ibmasm/uart.c b/drivers/misc/ibmasm/uart.c
--- a/drivers/misc/ibmasm/uart.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/misc/ibmasm/uart.c	2004-09-26 14:30:27 -07:00
@@ -34,7 +34,7 @@
 void ibmasm_register_uart(struct service_processor *sp)
 {
 	struct serial_struct serial;
-	unsigned char *iomem_base;
+	void __iomem *iomem_base;
 
 	iomem_base = sp->base_address + SCOUT_COM_B_BASE;
 
diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
--- a/drivers/net/wan/sbni.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/net/wan/sbni.c	2004-09-26 14:30:27 -07:00
@@ -294,7 +294,7 @@
 {
 	struct pci_dev  *pdev = NULL;
 
-	while( (pdev = pci_find_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
+	while( (pdev = pci_get_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
 	       != NULL ) {
 		int  pci_irq_line;
 		unsigned long  pci_ioaddr;
@@ -331,10 +331,14 @@
 		/* avoiding re-enable dual adapters */
 		if( (pci_ioaddr & 7) == 0  &&  pci_enable_device( pdev ) ) {
 			release_region( pci_ioaddr, SBNI_IO_EXTENT );
+			pci_dev_put( pdev );
 			return  -EIO;
 		}
 		if( sbni_probe1( dev, pci_ioaddr, pci_irq_line ) ) {
 			SET_NETDEV_DEV(dev, &pdev->dev);
+			/* not the best thing to do, but this is all messed up 
+			   for hotplug systems anyway... */
+			pci_dev_put( pdev );
 			return  0;
 		}
 	}
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/Makefile	2004-09-26 14:30:27 -07:00
@@ -3,7 +3,8 @@
 #
 
 obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o \
-			names.o pci-driver.o search.o pci-sysfs.o
+			names.o pci-driver.o search.o pci-sysfs.o \
+			rom.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
 ifndef CONFIG_SPARC64
diff -Nru a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
--- a/drivers/pci/hotplug/acpiphp_ibm.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/acpiphp_ibm.c	2004-09-26 14:30:27 -07:00
@@ -64,6 +64,8 @@
 #define IBM_HARDWARE_ID1 "IBM37D0"
 #define IBM_HARDWARE_ID2 "IBM37D4"
 
+#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun)
+
 /* union apci_descriptor - allows access to the
  * various device descriptors that are embedded in the
  * aPCI table
@@ -84,6 +86,7 @@
 		u8  attn;
 		u8  status[2];
 		u8  sun;
+		u8  res[3];
 	} slot;
 	struct {
 		u8 type;
@@ -128,6 +131,43 @@
 	.owner = THIS_MODULE,
 };
 
+/**
+ * ibm_slot_from_id - workaround for bad ibm hardware
+ * @id: the slot number that linux refers to the slot by
+ *
+ * Description: this method returns the aCPI slot descriptor
+ * corresponding to the Linux slot number.  This descriptor
+ * has info about the aPCI slot id and attention status.
+ * This descriptor must be freed using kfree when done.
+ **/
+static union apci_descriptor *ibm_slot_from_id(int id)
+{
+	int ind = 0, size;
+	union apci_descriptor *ret = NULL, *des;
+	char *table;
+
+	size = ibm_get_table_from_acpi(&table);
+	des = (union apci_descriptor *)table;
+	if (memcmp(des->header.sig, "aPCI", 4) != 0)
+		goto ibm_slot_done;
+
+	des = (union apci_descriptor *)&table[ind += des->header.len];
+	while (ind < size && (des->generic.type != 0x82 ||
+			des->slot.slot_num != id)) {
+		des = (union apci_descriptor *)&table[ind += des->generic.len];
+	}
+
+	if (ind < size && des->slot.slot_num == id)
+		ret = des;
+
+ibm_slot_done:
+	if (ret) {
+		ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
+		memcpy(ret, des, sizeof(union apci_descriptor));
+	}
+	kfree(table);
+	return ret;
+}
 
 /**
  * ibm_set_attention_status - callback method to set the attention LED
@@ -139,32 +179,34 @@
  **/
 static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 {
-	int retval = 0;
 	union acpi_object args[2]; 
 	struct acpi_object_list params = { .pointer = args, .count = 2 };
 	acpi_status stat; 
-	unsigned long rc = 0;
-	struct acpiphp_slot *acpi_slot;
+	unsigned long rc;
+	union apci_descriptor *ibm_slot;
 
-	acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
+	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
 
-	dbg("%s: set slot %d attention status to %d\n", __FUNCTION__,
-			acpi_slot->sun, (status ? 1 : 0));
+	dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__,
+			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
+			(status ? 1 : 0));
 
 	args[0].type = ACPI_TYPE_INTEGER;
-	args[0].integer.value = acpi_slot->sun;
+	args[0].integer.value = ibm_slot->slot.slot_id;
 	args[1].type = ACPI_TYPE_INTEGER;
 	args[1].integer.value = (status) ? 1 : 0;
 
+	kfree(ibm_slot);
+
 	stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", &params, &rc);
 	if (ACPI_FAILURE(stat)) {
-		retval = -ENODEV;
 		err("APLS evaluation failed:  0x%08x\n", stat);
+		return -ENODEV;
 	} else if (!rc) {
-		retval = -ERANGE;
 		err("APLS method failed:  0x%08lx\n", rc);
+		return -ERANGE;
 	}
-	return retval;
+	return 0;
 }
 
 /**
@@ -181,38 +223,21 @@
  **/
 static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
 {
-	int retval = -EINVAL, ind = 0, size;
-	char *table = NULL;
-	struct acpiphp_slot *acpi_slot;
-	union apci_descriptor *des;
+	union apci_descriptor *ibm_slot;
 
-	acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
+	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
 
-	size = ibm_get_table_from_acpi(&table);
-	if (size <= 0 || !table)
-		goto get_attn_done;
-	// read the header
-	des = (union apci_descriptor *)&table[ind];
-	if (memcmp(des->header.sig, "aPCI", 4) != 0)
-		goto get_attn_done;
-	des = (union apci_descriptor *)&table[ind += des->header.len];
-	while (ind < size && (des->generic.type != 0x82 ||
-			des->slot.slot_id != acpi_slot->sun))
-		des = (union apci_descriptor *)&table[ind += des->generic.len];
-	if (ind < size && des->slot.slot_id == acpi_slot->sun) {
-		retval = 0;
-		if (des->slot.attn & 0xa0 || des->slot.status[1] & 0x08)
-			*status = 1;
-		else
-			*status = 0;
-	}
+	if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
+		*status = 1;
+	else
+		*status = 0;
 
-	dbg("%s: get slot %d attention status is %d retval=%x\n",
-			__FUNCTION__, acpi_slot->sun, *status, retval);
+	dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__,
+			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
+			*status);
 
-get_attn_done:
-	kfree(table);
-	return retval;
+	kfree(ibm_slot);
+	return 0;
 }
 
 /**
diff -Nru a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
--- a/drivers/pci/hotplug/cpcihp_zt5550.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c	2004-09-26 14:30:27 -07:00
@@ -69,11 +69,11 @@
 static struct pci_dev *hc_dev;
 
 /* Host controller register addresses */
-static void *hc_registers;
-static void *csr_hc_index;
-static void *csr_hc_data;
-static void *csr_int_status;
-static void *csr_int_mask;
+static void __iomem *hc_registers;
+static void __iomem *csr_hc_index;
+static void __iomem *csr_hc_data;
+static void __iomem *csr_int_status;
+static void __iomem *csr_int_mask;
 
 
 static int zt5550_hc_config(struct pci_dev *pdev)
@@ -219,12 +219,13 @@
 	dbg("registered controller");
 
 	/* Look for first device matching cPCI bus's bridge vendor and device IDs */
-	if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC,
+	if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC,
 					 PCI_DEVICE_ID_DEC_21154, NULL))) {
 		status = -ENODEV;
 		goto init_register_error;
 	}
 	bus0 = bus0_dev->subordinate;
+	pci_dev_put(bus0_dev);
 
 	status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
 	if(status != 0) {
diff -Nru a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
--- a/drivers/pci/hotplug/cpqphp.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/cpqphp.h	2004-09-26 14:30:27 -07:00
@@ -268,7 +268,7 @@
 	struct timer_list task_event;
 	u8 hp_slot;
 	struct controller *ctrl;
-	void *p_sm_slot;
+	void __iomem *p_sm_slot;
 	struct hotplug_slot *hotplug_slot;
 };
 
@@ -287,7 +287,7 @@
 	struct controller *next;
 	u32 ctrl_int_comp;
 	struct semaphore crit_sect;	/* critical section semaphore */
-	void *hpc_reg;			/* cookie for our pci controller location */
+	void __iomem *hpc_reg;		/* cookie for our pci controller location */
 	struct pci_resource *mem_head;
 	struct pci_resource *p_mem_head;
 	struct pci_resource *io_head;
@@ -405,7 +405,7 @@
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
 extern irqreturn_t cpqhp_ctrl_intr		(int IRQ, void *data, struct pt_regs *regs);
-extern int	cpqhp_find_available_resources	(struct controller *ctrl, void *rom_start);
+extern int	cpqhp_find_available_resources	(struct controller *ctrl, void __iomem *rom_start);
 extern int	cpqhp_event_start_thread	(void);
 extern void	cpqhp_event_stop_thread		(void);
 extern struct pci_func *cpqhp_slot_create	(unsigned char busnumber);
diff -Nru a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
--- a/drivers/pci/hotplug/cpqphp_core.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/cpqphp_core.c	2004-09-26 14:30:27 -07:00
@@ -55,9 +55,9 @@
 struct pci_func *cpqhp_slot_list[256];
 
 /* local variables */
-static void *smbios_table;
-static void *smbios_start;
-static void *cpqhp_rom_start;
+static void __iomem *smbios_table;
+static void __iomem *smbios_start;
+static void __iomem *cpqhp_rom_start;
 static int power_mode;
 static int debug;
 
@@ -123,10 +123,10 @@
  * Returns pointer to the head of the SMBIOS tables (or NULL)
  *
  */
-static void * detect_SMBIOS_pointer(void *begin, void *end)
+static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
 {
-	void *fp;
-	void *endp;
+	void __iomem *fp;
+	void __iomem *endp;
 	u8 temp1, temp2, temp3, temp4;
 	int status = 0;
 
@@ -232,13 +232,14 @@
  *
  * returns a pointer to an SMBIOS structure or NULL if none found
  */
-static void *get_subsequent_smbios_entry(void *smbios_start,
-			void *smbios_table, void *curr)
+static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
+						void __iomem *smbios_table,
+						void __iomem *curr)
 {
 	u8 bail = 0;
 	u8 previous_byte = 1;
-	void *p_temp;
-	void *p_max;
+	void __iomem *p_temp;
+	void __iomem *p_max;
 
 	if (!smbios_table || !curr)
 		return(NULL);
@@ -282,8 +283,10 @@
  *
  * returns a pointer to an SMBIOS structure or %NULL if none found
  */
-static void *get_SMBIOS_entry(void *smbios_start, void *smbios_table, u8 type,
-			void * previous)
+static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
+					void __iomem *smbios_table,
+					u8 type,
+					void __iomem *previous)
 {
 	if (!smbios_table)
 		return NULL;
@@ -319,8 +322,9 @@
 	kfree(slot);
 }
 
-static int ctrl_slot_setup(struct controller * ctrl, void *smbios_start,
-			void *smbios_table)
+static int ctrl_slot_setup(struct controller *ctrl,
+			void __iomem *smbios_start,
+			void __iomem *smbios_table)
 {
 	struct slot *new_slot;
 	u8 number_of_slots;
@@ -328,7 +332,7 @@
 	u8 slot_number;
 	u8 ctrl_slot;
 	u32 tempdword;
-	void *slot_entry= NULL;
+	void __iomem *slot_entry= NULL;
 	int result = -ENOMEM;
 
 	dbg("%s\n", __FUNCTION__);
diff -Nru a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h
--- a/drivers/pci/hotplug/cpqphp_nvram.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/cpqphp_nvram.h	2004-09-26 14:30:27 -07:00
@@ -30,26 +30,26 @@
 
 #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
 
-static inline void compaq_nvram_init (void *rom_start)
+static inline void compaq_nvram_init (void __iomem *rom_start)
 {
 	return;
 }
 
-static inline int compaq_nvram_load (void *rom_start, struct controller *ctrl)
+static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 {
 	return 0;
 }
 
-static inline int compaq_nvram_store (void *rom_start)
+static inline int compaq_nvram_store (void __iomem *rom_start)
 {
 	return 0;
 }
 
 #else
 
-extern void compaq_nvram_init	(void *rom_start);
-extern int compaq_nvram_load	(void *rom_start, struct controller *ctrl);
-extern int compaq_nvram_store	(void *rom_start);
+extern void compaq_nvram_init	(void __iomem *rom_start);
+extern int compaq_nvram_load	(void __iomem *rom_start, struct controller *ctrl);
+extern int compaq_nvram_store	(void __iomem *rom_start);
 
 #endif
 
diff -Nru a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
--- a/drivers/pci/hotplug/cpqphp_pci.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/cpqphp_pci.c	2004-09-26 14:30:27 -07:00
@@ -51,10 +51,10 @@
  * find the Hot Plug Resource Table in the specified region of memory.
  *
  */
-static void *detect_HRT_floating_pointer(void *begin, void *end)
+static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
 {
-	void *fp;
-	void *endp;
+	void __iomem *fp;
+	void __iomem *endp;
 	u8 temp1, temp2, temp3, temp4;
 	int status = 0;
 
@@ -1162,12 +1162,13 @@
  *
  * returns 0 if success
  */  
-int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
+int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
 {
 	u8 temp;
 	u8 populated_slot;
 	u8 bridged_slot;
-	void *one_slot;
+	void __iomem *one_slot;
+	void __iomem *rom_resource_table;
 	struct pci_func *func = NULL;
 	int i = 10, index;
 	u32 temp_dword, rc;
@@ -1175,7 +1176,6 @@
 	struct pci_resource *p_mem_node;
 	struct pci_resource *io_node;
 	struct pci_resource *bus_node;
-	void *rom_resource_table;
 
 	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
 	dbg("rom_resource_table = %p\n", rom_resource_table);
diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
--- a/drivers/pci/hotplug/ibmphp_core.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/ibmphp_core.c	2004-09-26 14:30:27 -07:00
@@ -886,7 +886,7 @@
 				break;
 			case BUS_SPEED_133:
 				/* This is to take care of the bug in CIOBX chip */
-				while ((dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+				while ((dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
 							      0x0101, dev)) != NULL)
 					ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
 				cmd = HPC_BUS_133PCIXMODE;
diff -Nru a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
--- a/drivers/pci/hotplug/ibmphp_ebda.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/ibmphp_ebda.c	2004-09-26 14:30:27 -07:00
@@ -63,7 +63,7 @@
 static LIST_HEAD (rio_lo_head);
 static LIST_HEAD (opt_vg_head);
 static LIST_HEAD (opt_lo_head);
-static void *io_mem;
+static void __iomem *io_mem;
 
 /* Local functions */
 static int ebda_rsrc_controller (void);
diff -Nru a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
--- a/drivers/pci/hotplug/ibmphp_hpc.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/ibmphp_hpc.c	2004-09-26 14:30:27 -07:00
@@ -108,8 +108,8 @@
 //----------------------------------------------------------------------------
 // local function prototypes
 //----------------------------------------------------------------------------
-static u8 i2c_ctrl_read (struct controller *, void *, u8);
-static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
+static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
+static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
 static u8 hpc_writecmdtoindex (u8, u8);
 static u8 hpc_readcmdtoindex (u8, u8);
 static void get_hpc_access (void);
@@ -118,7 +118,7 @@
 static int process_changeinstatus (struct slot *, struct slot *);
 static int process_changeinlatch (u8, u8, struct controller *);
 static int hpc_poll_thread (void *);
-static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
+static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
 //----------------------------------------------------------------------------
 
 
@@ -147,11 +147,11 @@
 * Action:  read from HPC over I2C
 *
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
+static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
 {
 	u8 status;
 	int i;
-	void *wpg_addr;		// base addr + offset
+	void __iomem *wpg_addr;	// base addr + offset
 	unsigned long wpg_data;	// data to/from WPG LOHI format
 	unsigned long ultemp;
 	unsigned long data;	// actual data HILO format
@@ -255,10 +255,10 @@
 *
 * Return   0 or error codes
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
+static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
 {
 	u8 rc;
-	void *wpg_addr;		// base addr + offset
+	void __iomem *wpg_addr;	// base addr + offset
 	unsigned long wpg_data;	// data to/from WPG LOHI format 
 	unsigned long ultemp;
 	unsigned long data;	// actual data HILO format
@@ -399,7 +399,7 @@
 	return rc;
 }
 
-static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
+static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
 {
 	u8 rc;
 	switch (ctlr->ctlr_type) {
@@ -419,7 +419,7 @@
 	return rc;
 }
 
-static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
+static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 {
 	u8 rc = 0;
 	switch (ctlr->ctlr_type) {
@@ -536,7 +536,7 @@
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
 {
-	void *wpg_bbar = NULL;
+	void __iomem *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	struct list_head *pslotlist;
 	u8 index, status;
@@ -660,7 +660,7 @@
 	
 	// remove physical to logical address mapping
 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
+		iounmap (wpg_bbar);
 	
 	free_hpc_access ();
 
@@ -675,7 +675,7 @@
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
 {
-	void *wpg_bbar = NULL;
+	void __iomem *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	u8 index, status;
 	int busindex;
@@ -764,7 +764,7 @@
 
 	// remove physical to logical address mapping
 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
+		iounmap (wpg_bbar);
 	free_hpc_access ();
 
 	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -1130,7 +1130,7 @@
 * Return   0, HPC_ERROR
 * Value:
 *---------------------------------------------------------------------*/
-static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
+static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
 				    u8 * pstatus)
 {
 	int rc = 0;
diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
--- a/drivers/pci/hotplug/pciehp_ctrl.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/pciehp_ctrl.c	2004-09-26 14:30:27 -07:00
@@ -38,6 +38,7 @@
 #include <linux/wait.h>
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
+#include "../pci.h"
 #include "pciehp.h"
 #include "pciehprm.h"
 
@@ -1211,6 +1212,10 @@
 				pciehp_configure_device(ctrl, new_func);
 			}
 		} while (new_func);
+
+		/* Some PCI Express devices require ASPM fixup after hot-plug operation. */
+		if (pcie_mch_quirk)
+			pcie_rootport_aspm_quirk(ctrl->pci_dev);
 
 		/* Wait for exclusive access to hardware */
 		down(&ctrl->crit_sect);
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/pciehp_hpc.c	2004-09-26 14:30:27 -07:00
@@ -1402,8 +1402,8 @@
 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
 	} else {
 		/* Installs the interrupt handler */
-		dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk);
-		if (!pciehp_msi_quirk) {
+		dbg("%s: pcie_mch_quirk = %x\n", __FUNCTION__, pcie_mch_quirk);
+		if (!pcie_mch_quirk) {
 			rc = pci_enable_msi(pdev);
 			if (rc) {
 				info("Can't get msi for the hotplug controller\n");
diff -Nru a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
--- a/drivers/pci/hotplug/pciehp_pci.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/pciehp_pci.c	2004-09-26 14:30:27 -07:00
@@ -82,9 +82,11 @@
 {
 	int rc = 0;
 	int j;
+	struct pci_bus *pbus;
 
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus,
 				func->device, func->function);
+	pbus = func->pci_dev->bus;
 
 	for (j=0; j<8 ; j++) {
 		struct pci_dev* temp = pci_find_slot(func->bus,
@@ -93,6 +95,11 @@
 			pci_remove_bus_device(temp);
 		}
 	}
+
+	/* Some PCI Express devices require ASPM fixup after hot-plug operation. */
+	if (pcie_mch_quirk)
+		pcie_rootport_aspm_quirk(pbus->self);
+
 	return rc;
 }
 
diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
--- a/drivers/pci/hotplug/rpadlpar_core.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpadlpar_core.c	2004-09-26 14:30:27 -07:00
@@ -25,6 +25,10 @@
 
 static DECLARE_MUTEX(rpadlpar_sem);
 
+#define NODE_TYPE_VIO  1
+#define NODE_TYPE_SLOT 2
+#define NODE_TYPE_PHB  3
+
 static struct device_node *find_php_slot_vio_node(char *drc_name)
 {
 	struct device_node *child;
@@ -44,21 +48,50 @@
 	return NULL;
 }
 
-static struct device_node *find_php_slot_pci_node(char *drc_name)
+/* Find dlpar-capable pci node that contains the specified name and type */
+static struct device_node *find_php_slot_pci_node(char *drc_name,
+						  char *drc_type)
 {
 	struct device_node *np = NULL;
 	char *name;
+	char *type;
+	int rc;
 
-	while ((np = of_find_node_by_type(np, "pci")))
-		if (is_hotplug_capable(np)) {
-			name = rpaphp_get_drc_name(np);
-			if (name && (!strcmp(drc_name, name)))
+	while ((np = of_find_node_by_type(np, "pci"))) {
+		rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL);
+		if (rc == 0)
+			if (!strcmp(drc_name, name) && !strcmp(drc_type, type))
 				break;
-		}
+	}
 
 	return np;
 }
 
+static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
+{
+	struct device_node *dn;
+
+	dn = find_php_slot_pci_node(drc_name, "SLOT");
+	if (dn) {
+		*node_type = NODE_TYPE_SLOT;
+		return dn;
+	}
+
+	dn = find_php_slot_pci_node(drc_name, "PHB");
+	if (dn) {
+		*node_type = NODE_TYPE_PHB;
+		return dn;
+	}
+
+	dn = find_php_slot_vio_node(drc_name);
+	if (dn) {
+		*node_type = NODE_TYPE_VIO;
+		return dn;
+	}
+
+	return NULL;
+}
+
 static struct slot *find_slot(char *drc_name)
 {
 	struct list_head *tmp, *n;
@@ -205,6 +238,71 @@
 	return 0;
 }
 
+static int dlpar_remove_root_bus(struct pci_controller *phb)
+{
+	struct pci_bus *phb_bus;
+	int rc;
+
+	phb_bus = phb->bus;
+	if (!(list_empty(&phb_bus->children) &&
+	      list_empty(&phb_bus->devices))) {
+		return -EBUSY;
+	}
+
+	rc = pcibios_remove_root_bus(phb);
+	if (rc)
+		return -EIO;
+
+	device_unregister(phb_bus->bridge);
+	pci_remove_bus(phb_bus);
+
+	return 0;
+}
+
+static int dlpar_remove_phb(struct slot *slot)
+{
+	struct pci_controller *phb;
+	struct device_node *dn;
+	int rc = 0;
+
+	dn = slot->dn;
+	if (!dn) {
+		printk(KERN_ERR "%s: unexpected NULL slot device node\n",
+				__FUNCTION__);
+		return -EIO;
+	}
+
+	phb = dn->phb;
+	if (!phb) {
+		printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
+				__FUNCTION__);
+		return -EIO;
+	}
+
+	if (rpaphp_remove_slot(slot)) {
+		printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
+			__FUNCTION__, slot->location);
+		return -EIO;
+	}
+
+	rc = dlpar_remove_root_bus(phb);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+static int dlpar_add_phb(struct device_node *dn)
+{
+	struct pci_controller *phb;
+
+	phb = init_phb_dynamic(dn);
+	if (!phb)
+		return 1;
+
+	return 0;
+}
+
 /**
  * dlpar_add_slot - DLPAR add an I/O Slot
  * @drc_name: drc-name of newly added slot
@@ -220,7 +318,8 @@
  */
 int dlpar_add_slot(char *drc_name)
 {
-	struct device_node *dn;
+	struct device_node *dn = NULL;
+	int node_type;
 	int rc = 0;
 
 	if (down_interruptible(&rpadlpar_sem))
@@ -232,18 +331,27 @@
 		goto exit;
 	}
 
-	dn = find_php_slot_vio_node(drc_name);
+	dn = find_newly_added_node(drc_name, &node_type);
 	if (!dn) {
-		dn = find_php_slot_pci_node(drc_name);
-		if (dn)
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	switch (node_type) {
+		case NODE_TYPE_VIO:
+			/* Just add hotplug slot */
+			break;
+		case NODE_TYPE_SLOT:
 			rc = dlpar_add_pci_slot(drc_name, dn);
-		else {
-			rc = -ENODEV;
-			goto exit;
-		}
+			break;
+		case NODE_TYPE_PHB:
+			rc = dlpar_add_phb(dn);
+			break;
+		default:
+			printk("%s: unexpected node type\n", __FUNCTION__);
+			return -EIO;
 	}
 
-	/* Add hotplug slot for new VIOA or PCI */
 	if (!rc && rpaphp_add_slot(dn)) {
 		printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
 			__FUNCTION__, drc_name);
@@ -337,7 +445,8 @@
 		return -ERESTARTSYS;
 
 	if (!find_php_slot_vio_node(drc_name) &&
-	    !find_php_slot_pci_node(drc_name)) {
+	    !find_php_slot_pci_node(drc_name, "SLOT") &&
+	    !find_php_slot_pci_node(drc_name, "PHB")) {
 		rc = -ENODEV;
 		goto exit;
 	}
@@ -348,17 +457,18 @@
 		goto exit;
 	}
 	
-	switch (slot->dev_type) {
-		case PCI_DEV:
-			rc = dlpar_remove_pci_slot(slot, drc_name);
-			break;
-
-		case VIO_DEV:
-			rc = dlpar_remove_vio_slot(slot, drc_name);
-			break;
+	if (slot->type == PHB) {
+		rc = dlpar_remove_phb(slot);
+	} else {
+		switch (slot->dev_type) {
+			case PCI_DEV:
+				rc = dlpar_remove_pci_slot(slot, drc_name);
+				break;
 
-		default:
-			rc = -EIO;
+			case VIO_DEV:
+				rc = dlpar_remove_vio_slot(slot, drc_name);
+				break;
+		}
 	}
 exit:
 	up(&rpadlpar_sem);
diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
--- a/drivers/pci/hotplug/rpaphp.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpaphp.h	2004-09-26 14:30:27 -07:00
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include "pci_hotplug.h"
 
+#define	PHB     2
 #define	HOTPLUG	1
 #define	EMBEDDED 0
 
@@ -129,7 +130,8 @@
 /* rpaphp_core.c */
 extern int rpaphp_add_slot(struct device_node *dn);
 extern int rpaphp_remove_slot(struct slot *slot);
-extern char *rpaphp_get_drc_name(struct device_node *dn);
+extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
+		char **drc_name, char **drc_type, int *drc_power_domain);
 
 /* rpaphp_vio.c */
 extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
--- a/drivers/pci/hotplug/rpaphp_core.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpaphp_core.c	2004-09-26 14:30:27 -07:00
@@ -63,7 +63,6 @@
 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
 static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
-static int rpaphp_disable_slot(struct pci_dev *dev);
 
 struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
 	.owner = THIS_MODULE,
@@ -212,32 +211,91 @@
 	return deregister_slot(slot);
 }
 
-static int get_dn_properties(struct device_node *dn, int **indexes, int **names, 
-	int **types, int **power_domains)
+static int get_children_props(struct device_node *dn, int **drc_indexes,
+		int **drc_names, int **drc_types, int **drc_power_domains)
 {
-	*indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
+	int *indexes, *names;
+	int *types, *domains;
 
-	/* &names[1] contains NULL terminated slot names */
-	*names = (int *) get_property(dn, "ibm,drc-names", NULL);
+	indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
+	names = (int *) get_property(dn, "ibm,drc-names", NULL);
+	types = (int *) get_property(dn, "ibm,drc-types", NULL);
+	domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
+
+	if (!indexes || !names || !types || !domains) {
+		/* Slot does not have dynamically-removable children */
+		return 1;
+	}
+	if (drc_indexes)
+		*drc_indexes = indexes;
+	if (drc_names)
+		/* &drc_names[1] contains NULL terminated slot names */
+		*drc_names = names;
+	if (drc_types)
+		/* &drc_types[1] contains NULL terminated slot types */
+		*drc_types = types;
+	if (drc_power_domains)
+		*drc_power_domains = domains;
 
-	/* &types[1] contains NULL terminated slot types */
-	*types = (int *) get_property(dn, "ibm,drc-types", NULL);
-
-	/* power_domains[1...n] are the slot power domains */
-	*power_domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
-	
-	if (*indexes && *names && *types && *power_domains) 
-		return (1);
-	
-	return (0);
+	return 0;
+}
+
+/* To get the DRC props describing the current node, first obtain it's
+ * my-drc-index property.  Next obtain the DRC list from it's parent.  Use
+ * the my-drc-index for correlation, and obtain the requested properties.
+ */
+int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
+		char **drc_name, char **drc_type, int *drc_power_domain)
+{
+	int *indexes, *names;
+	int *types, *domains;
+	unsigned int *my_index;
+	char *name_tmp, *type_tmp;
+	int i, rc;
+
+	my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
+	if (!my_index) {
+		/* Node isn't DLPAR/hotplug capable */
+		return 1;
+	}
+
+	rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
+	if (rc) {
+		return 1;
+	}
+
+	name_tmp = (char *) &names[1];
+	type_tmp = (char *) &types[1];
+
+	/* Iterate through parent properties, looking for my-drc-index */
+	for (i = 0; i < indexes[0]; i++) {
+		if ((unsigned int) indexes[i + 1] == *my_index) {
+			if (drc_name)
+                		*drc_name = name_tmp;
+			if (drc_type)
+				*drc_type = type_tmp;
+			if (drc_index)
+				*drc_index = *my_index;
+			if (drc_power_domain)
+				*drc_power_domain = domains[i+1];
+			return 0;
+		}
+		name_tmp += (strlen(name_tmp) + 1);
+		type_tmp += (strlen(type_tmp) + 1);
+	}
+
+	return 1;
 }
 
 static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types,
 	  int **power_domains)
 {
+	int rc;
+
 	if (!is_hotplug_capable(dn))
 		return (0);
-	if (!get_dn_properties(dn, indexes, names, types, power_domains))
+	rc = get_children_props(dn, indexes, names, types, power_domains);
+	if (rc)
 		return (0);
 	return (1);
 }
@@ -245,8 +303,7 @@
 static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types,
 	  int **power_domains, int **my_drc_index)
 {
-	if (!is_hotplug_capable(dn))
-		return (0);
+	int rc;
 
 	*my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
 	if(!*my_drc_index) 		
@@ -255,7 +312,9 @@
 	if (!dn->parent)
 		return (0);
 
-	return get_dn_properties(dn->parent, indexes, names, types, power_domains);
+	rc = get_children_props(dn->parent, indexes, names, types,
+				power_domains);
+	return (rc == 0);
 }
 
 static inline int is_vdevice_root(struct device_node *dn)
@@ -263,34 +322,10 @@
 	return !strcmp(dn->name, "vdevice");
 }
 
-char *rpaphp_get_drc_name(struct device_node *dn)
+int is_dlpar_type(const char *type_str)
 {
-	char *name, *ptr = NULL;
-	int *drc_names, *drc_indexes, i;
-	struct device_node *parent = dn->parent;	
-	u32 *my_drc_index;
-
-	if (!parent)
-		return NULL;
-
-	my_drc_index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
-	if (!my_drc_index)
-		return NULL;	
-
-	drc_names = (int *) get_property(parent, "ibm,drc-names", NULL);
-	drc_indexes = (int *) get_property(parent, "ibm,drc-indexes", NULL);
-	if (!drc_names || !drc_indexes)
-		return NULL;
-
-	name = (char *) &drc_names[1];
-	for (i = 0; i < drc_indexes[0]; i++, name += (strlen(name) + 1)) {
-		if (drc_indexes[i + 1] == *my_drc_index) {
-			ptr = (char *) name;
-			break;
-		}
-	}
-
-	return ptr;
+	/* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
+	return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
 }
 
 /****************************************************************
@@ -329,15 +364,18 @@
 		for (i = 0; i < indexes[0]; i++,
 	     		name += (strlen(name) + 1), type += (strlen(type) + 1)) {
 
-			if ( slot_type == HOTPLUG || 
-				(slot_type == EMBEDDED && indexes[i + 1] == my_drc_index[0])) {
-				
+			if (slot_type == HOTPLUG ||
+			    (slot_type == EMBEDDED &&
+			     indexes[i + 1] == my_drc_index[0] &&
+			     is_dlpar_type(type))) {
 				if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
 					       power_domains[i + 1]))) {
 					retval = -ENOMEM;
 					goto exit;
 				}
-				if (slot_type == EMBEDDED)
+				if (!strcmp(type, "PHB"))
+					slot->type = PHB;
+				else if (slot_type == EMBEDDED)
 					slot->type = EMBEDDED;
 				else
 					slot->type = simple_strtoul(type, NULL, 10);
@@ -442,11 +480,6 @@
 	return retval;
 }
 
-static int rpaphp_disable_slot(struct pci_dev *dev)
-{
-	return disable_slot(rpaphp_find_hotplug_slot(dev));
-}
-
 static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
 	int retval = -EINVAL;
@@ -483,4 +516,4 @@
 EXPORT_SYMBOL_GPL(rpaphp_add_slot);
 EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
 EXPORT_SYMBOL_GPL(rpaphp_slot_head);
-EXPORT_SYMBOL_GPL(rpaphp_get_drc_name);
+EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);
diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
--- a/drivers/pci/hotplug/rpaphp_pci.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpaphp_pci.c	2004-09-26 14:30:27 -07:00
@@ -117,33 +117,40 @@
 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
 {
 	int state, rc;
-	*value = NOT_VALID;
+ 	struct device_node *child_dn;
+ 	struct pci_dev *child_dev;
 
+	*value = NOT_VALID;
 	rc = rpaphp_get_sensor_state(slot, &state);
 	if (rc)
 		goto exit;
-	if (state == PRESENT) {
+
+ 	if ((state == EMPTY) || (slot->type == PHB)) {
+ 		dbg("slot is empty\n");
+ 		*value = EMPTY;
+ 	}
+ 	else if (state == PRESENT) {
 		if (!is_init)
 			/* at run-time slot->state can be changed by */
 			/* config/unconfig adapter */
 			*value = slot->state;
 		else {
-			if (!slot->dn->child)
+ 			child_dn = slot->dn->child;
+ 			if (child_dn)
+ 				child_dev = rpaphp_find_pci_dev(child_dn);
+
+ 			if (child_dev)
+ 				*value = CONFIGURED;
+ 			else if (!child_dn)
 				dbg("%s: %s is not valid OFDT node\n",
 				    __FUNCTION__, slot->dn->full_name);
-			else if (rpaphp_find_pci_dev(slot->dn->child))
-				*value = CONFIGURED;
 			else {
 				err("%s: can't find pdev of adapter in slot[%s]\n", 
 					__FUNCTION__, slot->dn->full_name);
 				*value = NOT_CONFIGURED;
 			}
 		}
-	} else if (state == EMPTY) {
-		dbg("slot is empty\n");
-		*value = state;
 	}
-
 exit:
 	return rc;
 }
@@ -408,15 +415,52 @@
 	return 0;
 }
 
+static int set_phb_slot_name(struct slot *slot)
+{
+	struct device_node *dn;
+	struct pci_controller *phb;
+	struct pci_bus *bus;
+
+	dn = slot->dn;
+	if (!dn) {
+		return 1;
+	}
+	phb = dn->phb;
+	if (!phb) {
+		return 1;
+	}
+	bus = phb->bus;
+	if (!bus) {
+		return 1;
+	}
+
+	sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
+			bus->number, 0, 0);
+	return 0;
+}
+
 static int setup_pci_slot(struct slot *slot)
 {
-	slot->bridge = rpaphp_find_bridge_pdev(slot);
-	if (!slot->bridge) {	/* slot being added doesn't have pci_dev yet */
-		err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name);
-		goto exit_rc;
+	int rc;
+
+	if (slot->type == PHB) {
+		rc = set_phb_slot_name(slot);
+		if (rc) {
+			err("%s: failed to set phb slot name\n", __FUNCTION__);
+			goto exit_rc;
+		}
+	} else {
+		slot->bridge = rpaphp_find_bridge_pdev(slot);
+		if (!slot->bridge) {
+			/* slot being added doesn't have pci_dev yet */
+			err("%s: no pci_dev for bridge dn %s\n",
+					__FUNCTION__, slot->name);
+			goto exit_rc;
+		}
+		dbg("%s set slot->name to %s\n",  __FUNCTION__,
+				pci_name(slot->bridge));
+		strcpy(slot->name, pci_name(slot->bridge));
 	}
-	dbg("%s set slot->name to %s\n",  __FUNCTION__, pci_name(slot->bridge));
-	strcpy(slot->name, pci_name(slot->bridge));
 
 	/* find slot's pci_dev if it's not empty */
 	if (slot->hotplug_slot->info->adapter_status == EMPTY) {
@@ -470,10 +514,10 @@
 	int rc = 1;
 
 	slot->dev_type = PCI_DEV;
-	if (slot->type == EMBEDDED)
-		slot->removable = EMBEDDED;
+	if ((slot->type == EMBEDDED) || (slot->type == PHB))
+		slot->removable = 0;
 	else
-		slot->removable = HOTPLUG;
+		slot->removable = 1;
 	INIT_LIST_HEAD(&slot->dev.pci_funcs);
 	if (setup_pci_hotplug_slot_info(slot))
 		goto exit_rc;
diff -Nru a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
--- a/drivers/pci/hotplug/rpaphp_slot.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpaphp_slot.c	2004-09-26 14:30:27 -07:00
@@ -246,12 +246,7 @@
 {
 	int rc = 0, level;
 	
-	if (slot->type == EMBEDDED) {
-		dbg("%s set to POWER_ON for EMBEDDED slot %s\n",
-			__FUNCTION__, slot->location);
-		*value = POWER_ON;
-	}
-	else {
+	if (slot->type == HOTPLUG) {
 		rc = rtas_get_power_level(slot->power_domain, &level);
 		if (!rc) {
 			dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
@@ -260,6 +255,10 @@
 		} else
 			err("failed to get power-level for slot(%s), rc=0x%x\n",
 				slot->location, rc);
+	} else {
+		dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
+			__FUNCTION__, slot->location);
+		*value = (u8) POWER_ON;
 	}
 
 	return rc;
diff -Nru a/drivers/pci/hotplug/rpaphp_vio.c b/drivers/pci/hotplug/rpaphp_vio.c
--- a/drivers/pci/hotplug/rpaphp_vio.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/rpaphp_vio.c	2004-09-26 14:30:27 -07:00
@@ -74,8 +74,8 @@
 	int rc = 1;
 	struct slot *slot = NULL;
 	
-	name = rpaphp_get_drc_name(dn);
-	if (!name)
+	rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
+	if (rc)
 		goto exit_rc;
 	index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
 	if (!index)
diff -Nru a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
--- a/drivers/pci/hotplug/shpchp.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/shpchp.h	2004-09-26 14:30:27 -07:00
@@ -311,7 +311,7 @@
 	php_intr_callback_t presence_change_callback;
 	php_intr_callback_t power_fault_callback;
 	void *callback_instance_id;
-	void *creg;				/* Ptr to controller register space */
+	void __iomem *creg;			/* Ptr to controller register space */
 };
 /* Inline functions */
 
diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
--- a/drivers/pci/hotplug/shpchp_ctrl.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/shpchp_ctrl.c	2004-09-26 14:30:27 -07:00
@@ -1050,7 +1050,64 @@
 /* The following routines constitute the bulk of the 
    hotplug controller logic
  */
+static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
+{ 
+	u32 rc = 0;
 
+	dbg("%s: change to speed %d\n", __FUNCTION__, speed);
+	down(&ctrl->crit_sect);
+	if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
+		err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
+		up(&ctrl->crit_sect);
+		return WRONG_BUS_FREQUENCY;
+	}
+	wait_for_ctrl_irq (ctrl);
+		
+	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+		err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
+			  __FUNCTION__);
+		err("%s: Error code (%d)\n", __FUNCTION__, rc);
+		up(&ctrl->crit_sect);
+		return WRONG_BUS_FREQUENCY;
+	}
+	up(&ctrl->crit_sect);
+	return rc;
+}
+
+static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, 
+enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
+{ 
+	u32 rc = 0;
+	
+	if (flag != 0) { /* Other slots on the same bus are occupied */
+		if ( asp < bsp ) {
+			err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
+			return WRONG_BUS_FREQUENCY;
+		}
+	} else {
+		/* Other slots on the same bus are empty */
+		if (msp == bsp) {
+		/* if adapter_speed >= bus_speed, do nothing */
+			if (asp < bsp) {
+				/* 
+				* Try to lower bus speed to accommodate the adapter if other slots 
+				* on the same controller are empty
+				*/
+				if ((rc = change_bus_speed(ctrl, pslot, asp)))
+					return rc;
+			} 
+		} else {
+			if (asp < msp) {
+				if ((rc = change_bus_speed(ctrl, pslot, asp)))
+					return rc;
+			} else {
+				if ((rc = change_bus_speed(ctrl, pslot, msp)))
+					return rc;
+			}
+		}
+	}
+	return rc;
+}
 
 /**
  * board_added - Called after a board has been added to the system.
@@ -1061,14 +1118,13 @@
  */
 static u32 board_added(struct pci_func * func, struct controller * ctrl)
 {
-	u8 hp_slot, slot;
+	u8 hp_slot;
 	u8 slots_not_empty = 0;
 	int index;
 	u32 temp_register = 0xFFFFFFFF;
 	u32 retval, rc = 0;
 	struct pci_func *new_func = NULL;
-	struct pci_func *t_func = NULL;
-	struct slot *p_slot, *pslot;
+	struct slot *p_slot;
 	struct resource_lists res_lists;
 	enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
 	u8 pi, mode;
@@ -1132,258 +1188,72 @@
 	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
-	rc  = p_slot->hpc_ops->get_prog_int(p_slot, &pi);
-	if (rc) {
+	if ((rc  = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
 		err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
 		pi = 1;
 	}
+
+	/* Check if there are other slots or devices on the same bus */
+	if (!list_empty(&ctrl->pci_dev->subordinate->devices))
+		slots_not_empty = 1;
+
+	dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__, 
+		slots_not_empty, pi);
+	dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n", 
+		adapter_speed, bus_speed, max_bus_speed);
+
 	if (pi == 2) {
-		for ( slot = 0; slot < ctrl->num_slots; slot++) {
-			if (slot != hp_slot) {
-				pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
-				t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
-				slots_not_empty |= t_func->is_a_board;
-			}
+		dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+		if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
+			err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
+			mode = 0;
 		}
 
 		switch (adapter_speed) {
-		case PCI_SPEED_133MHz_PCIX_533:	
+		case PCI_SPEED_133MHz_PCIX_533:
 		case PCI_SPEED_133MHz_PCIX_266:
-			if ((( bus_speed < 0xa ) || (bus_speed < 0xd)) && (max_bus_speed > bus_speed) &&
-				((max_bus_speed <= 0xa) || (max_bus_speed <= 0xd)) && (!slots_not_empty)) {
-			
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-			}
-			break;
+			if ((bus_speed != adapter_speed) &&
+			   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+				return rc;
+			break;	
 		case PCI_SPEED_133MHz_PCIX_ECC:
 		case PCI_SPEED_133MHz_PCIX:
-
-			rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
-			if (rc) {
-				err("%s: PI is 1 \n", __FUNCTION__);
-				return WRONG_BUS_FREQUENCY;
-			}
-
 			if (mode) { /* Bus - Mode 1 ECC */
-
-				if (bus_speed > 0x7)  {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x7) && (max_bus_speed <= 0x7) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x7) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			} else {
-				if (bus_speed > 0x4) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x4) && (max_bus_speed <= 0x4) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x4) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			}
 			break;
 		case PCI_SPEED_66MHz_PCIX_ECC:
 		case PCI_SPEED_66MHz_PCIX:
-
-			rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
-			if (rc) {
-				err("%s: PI is 1 \n", __FUNCTION__);
-				return WRONG_BUS_FREQUENCY;
-			}
-
 			if (mode) { /* Bus - Mode 1 ECC */
-
-				if (bus_speed > 0x5)  {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x5) && (max_bus_speed <= 0x5) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x5) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			} else {
-				if (bus_speed > 0x2) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x2) && (max_bus_speed <= 0x2) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x2) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			}
 			break;
 		case PCI_SPEED_66MHz:
-			if (bus_speed > 0x1) {
-				err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-				return WRONG_BUS_FREQUENCY;
-			}
-			if (bus_speed == 0x1)
-				;
-			if ((bus_speed == 0x0) && ( max_bus_speed == 0x1))  {
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-			}
+			if ((bus_speed != 0x1) &&
+			   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+				return rc;
 			break;	
 		case PCI_SPEED_33MHz:
 			if (bus_speed > 0x0) {
-				err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-				return WRONG_BUS_FREQUENCY;
+				if (slots_not_empty == 0) {
+					if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
+						return rc;
+				} else {
+					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
+					return WRONG_BUS_FREQUENCY;
+				}
 			}
 			break;
 		default:
@@ -1391,133 +1261,34 @@
 			return WRONG_BUS_FREQUENCY;
 		}
 	} else {
-		/* if adpater_speed == bus_speed, nothing to do here */
-		if (adapter_speed != bus_speed) {
-			for ( slot = 0; slot < ctrl->num_slots; slot++) {
-				if (slot != hp_slot) {
-					pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
-					t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
-					slots_not_empty |= t_func->is_a_board;
-				}
-			}
-
-			if (slots_not_empty != 0) { /* Other slots on the same bus are occupied */
-				if ( adapter_speed < bus_speed ) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Do nothing if adapter_speed >= bus_speed */
-			}
-		}
-			
-		if ((adapter_speed != bus_speed) && (slots_not_empty == 0))  {
-			/* Other slots on the same bus are empty */
-			
-			rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
-			if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
-				err("%s: Can't get max bus operation speed\n", __FUNCTION__);
-				max_bus_speed = bus_speed;
-			}
-
-			if (max_bus_speed == bus_speed) {
-				/* if adapter_speed >= bus_speed, do nothing */
-				if (adapter_speed < bus_speed) {
-				/* 
-				 * Try to lower bus speed to accommodate the adapter if other slots 
-				 * on the same controller are empty
-				 */
-					
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						up(&ctrl->crit_sect);
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-								  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						up(&ctrl->crit_sect);
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-
-				} 
-			} else {
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				/* max_bus_speed != bus_speed. Note: max_bus_speed should be > than bus_speed */
-				if (adapter_speed < max_bus_speed) 
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
-				else  
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", 
-						__FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-
-			}
-		}
+		/* If adpater_speed == bus_speed, nothing to do here */
+		dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+		if ((adapter_speed != bus_speed) &&
+		   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+				return rc;
 	}
 
-	/* Wait for exclusive access to hardware */
 	down(&ctrl->crit_sect);
-
 	/* turn on board, blink green LED, turn off Amber LED */
-	rc = p_slot->hpc_ops->slot_enable(p_slot);
-	
-	if (rc) {
+	if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
 		err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
-		/* Done with exclusive hardware access */
 		up(&ctrl->crit_sect);
 		return rc;
 	}
-	/* Wait for the command to complete */
 	wait_for_ctrl_irq (ctrl);
 
-	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-	if (rc) {
+	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 		err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-		/* Done with exclusive hardware access */
 		up(&ctrl->crit_sect);
 		return rc;  
 	}
 
-	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
 	/* Wait for ~1 second */
 	dbg("%s: before long_delay\n", __FUNCTION__);
 	wait_for_ctrl_irq (ctrl);
-	dbg("%s: afterlong_delay\n", __FUNCTION__);
+	dbg("%s: after long_delay\n", __FUNCTION__);
 
 	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
 	/* Check for a power fault */
@@ -2163,11 +1934,13 @@
 	u32 rc = 0;
 	int ret = 0;
 	unsigned int devfn;
-	struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
+	struct pci_bus *pci_bus;
 	struct pci_func *func;
 
 	if (!p_slot->ctrl)
 		return 1;
+
+	pci_bus = p_slot->ctrl->pci_dev->subordinate;
 
 	/* Check to see if (latch closed, card present, power on) */
 	down(&p_slot->ctrl->crit_sect);
diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
--- a/drivers/pci/hotplug/shpchp_hpc.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/shpchp_hpc.c	2004-09-26 14:30:27 -07:00
@@ -1158,7 +1158,7 @@
 					hp_slot, php_ctlr->callback_instance_id);
 			
 			/* Clear all slot events */
-			temp_dword = 0xe01fffff;
+			temp_dword = 0xe01f3fff;
 			dbg("%s: Clearing slot events, temp_dword = %x\n",
 				__FUNCTION__, temp_dword); 
 			writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
@@ -1492,8 +1492,7 @@
 		goto abort_free_ctlr;
 	}
 
-	php_ctlr->creg = (struct ctrl_reg *)
-		ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
+	php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
 	if (!php_ctlr->creg) {
 		err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0), 
 			pci_resource_start(pdev, 0) + shpc_base_offset);
@@ -1539,7 +1538,7 @@
 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
-		tempdword = 0xffffffff;  
+		tempdword = 0xffff3fff;  
 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
 	}
 	
@@ -1592,7 +1591,7 @@
 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
-		tempdword = 0xe01fffff;  
+		tempdword = 0xe01f3fff;  
 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
 	}
 	if (!shpchp_poll_mode) {
diff -Nru a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
--- a/drivers/pci/hotplug/shpchprm_acpi.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/hotplug/shpchprm_acpi.c	2004-09-26 14:30:27 -07:00
@@ -1396,17 +1396,19 @@
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
 	struct pci_func *func, new_func;
-	int busn = ctrl->bus;
+	int busn = ctrl->slot_bus;
 	int devn, funn;
 	u32	vid;
 
 	for (devn = 0; devn < 32; devn++) {
 		for (funn = 0; funn < 8; funn++) {
+			/*
 			if (devn == ctrl->device && funn == ctrl->function)
 				continue;
+			*/
 			/* find out if this entry is for an occupied slot */
 			vid = 0xFFFFFFFF;
-			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
+			pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
 
 			if (vid != 0xFFFFFFFF) {
 				func = shpchp_slot_find(busn, devn, funn);
diff -Nru a/drivers/pci/msi.c b/drivers/pci/msi.c
--- a/drivers/pci/msi.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/msi.c	2004-09-26 14:30:27 -07:00
@@ -66,7 +66,7 @@
 		int		pos;
 		u32		mask_bits;
 
-		pos = entry->mask_base;
+		pos = (int)entry->mask_base;
 		pci_read_config_dword(entry->dev, pos, &mask_bits);
 		mask_bits &= ~(1);
 		mask_bits |= flag;
@@ -548,7 +548,7 @@
 	dev->irq = vector;
 	entry->dev = dev;
 	if (is_mask_bit_support(control)) {
-		entry->mask_base = msi_mask_bits_reg(pos,
+		entry->mask_base = (void __iomem *)msi_mask_bits_reg(pos,
 				is_64bit_address(control));
 	}
 	/* Replace with MSI handler */
@@ -606,7 +606,7 @@
 	u32 phys_addr, table_offset;
  	u16 control;
 	u8 bir;
-	void *base;
+	void __iomem *base;
 
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
 	/* Request & Map MSI-X table region */
@@ -642,7 +642,7 @@
 		entry->msi_attrib.maskbit = 1;
 		entry->msi_attrib.default_vector = dev->irq;
 		entry->dev = dev;
-		entry->mask_base = (unsigned long)base;
+		entry->mask_base = base;
 		if (!head) {
 			entry->link.head = vector;
 			entry->link.tail = vector;
@@ -806,7 +806,7 @@
 {
 	struct msi_desc *entry;
 	int head, entry_nr, type;
-	unsigned long base = 0L;
+	void __iomem *base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
@@ -857,7 +857,7 @@
 			phys_addr = pci_resource_start (dev, bir);
 			phys_addr += (u32)(table_offset &
 				~PCI_MSIX_FLAGS_BIRMASK);
-			iounmap((void*)base);
+			iounmap(base);
 			release_mem_region(phys_addr,
 				nr_entries * PCI_MSIX_ENTRY_SIZE);
 		}
@@ -869,8 +869,8 @@
 static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
 {
 	int vector = head, tail = 0;
-	int i = 0, j = 0, nr_entries = 0;
-	unsigned long base = 0L;
+	int i, j = 0, nr_entries = 0;
+	void __iomem *base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
@@ -1099,7 +1099,7 @@
    	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
 		int vector, head, tail = 0, warning = 0;
-		unsigned long base = 0L;
+		void __iomem *base = NULL;
 
 		vector = head = dev->irq;
 		while (head != tail) {
@@ -1129,7 +1129,7 @@
 			phys_addr = pci_resource_start (dev, bir);
 			phys_addr += (u32)(table_offset &
 				~PCI_MSIX_FLAGS_BIRMASK);
-			iounmap((void*)base);
+			iounmap(base);
 			release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE *
 				multi_msix_capable(control));
 			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
diff -Nru a/drivers/pci/msi.h b/drivers/pci/msi.h
--- a/drivers/pci/msi.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/msi.h	2004-09-26 14:30:27 -07:00
@@ -152,7 +152,7 @@
 		__u16	tail;
 	}link;
 
-	unsigned long mask_base;
+	void __iomem *mask_base;
 	struct pci_dev *dev;
 };
 
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/pci-driver.c	2004-09-26 14:30:27 -07:00
@@ -291,6 +291,19 @@
 			drv->remove(pci_dev);
 		pci_dev->driver = NULL;
 	}
+
+#ifdef CONFIG_DEBUG_KERNEL
+	/*
+	 * If the driver decides to stop using the device, it should
+	 * call pci_disable_device().
+	 */
+	if (pci_dev->is_enabled) {
+		dev_warn(&pci_dev->dev, "Device was removed without properly "
+			 "calling pci_disable_device(). This may need fixing.\n");
+		/* WARN_ON(1); */
+	}
+#endif /* CONFIG_DEBUG_KERNEL */
+
 	pci_dev_put(pci_dev);
 	return 0;
 }
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/pci-sysfs.c	2004-09-26 14:30:27 -07:00
@@ -5,6 +5,8 @@
  * (C) Copyright 2002-2004 IBM Corp.
  * (C) Copyright 2003 Matthew Wilcox
  * (C) Copyright 2003 Hewlett-Packard
+ * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
+ * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
  *
  * File attributes for PCI devices
  *
@@ -20,6 +22,8 @@
 
 #include "pci.h"
 
+static int sysfs_initialized;	/* = 0 */
+
 /* show configuration fields */
 #define pci_config_attr(field, format_string)				\
 static ssize_t								\
@@ -164,6 +168,40 @@
 	return count;
 }
 
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+static ssize_t
+pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
+	void __iomem *rom;
+	size_t size;
+	
+	rom = pci_map_rom(pdev, &size);	/* size starts out as PCI window size */
+	if (!rom)
+		return 0;
+		
+	if (off >= size)
+		count = 0;
+	else {
+		if (off + count > size)
+			count = size - off;
+		
+		memcpy_fromio(buf, rom + off, count);
+	}
+	pci_unmap_rom(pdev, rom);
+		
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +224,67 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+int pci_create_sysfs_dev_files (struct pci_dev *pdev)
 {
+	if (!sysfs_initialized)
+		return -EACCES;
+
 	if (pdev->cfg_size < 4096)
 		sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
 	else
 		sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
 
+	/* If the device has a ROM, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct bin_attribute *rom_attr;
+		
+		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+		if (rom_attr) {
+			pdev->rom_attr = rom_attr;
+			rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+			rom_attr->attr.name = "rom";
+			rom_attr->attr.mode = S_IRUSR;
+			rom_attr->attr.owner = THIS_MODULE;
+			rom_attr->read = pci_read_rom;
+			sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+		}
+	}
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+	
+	return 0;
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		if (pdev->rom_attr) {
+			sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+			kfree(pdev->rom_attr);
+		}
+	}
+}
+
+static int __init pci_sysfs_init(void)
+{
+	struct pci_dev *pdev = NULL;
+	
+	sysfs_initialized = 1;
+	while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL)
+		pci_create_sysfs_dev_files(pdev);
+
+	return 0;
 }
+
+__initcall(pci_sysfs_init);
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/pci.c	2004-09-26 14:30:27 -07:00
@@ -382,8 +382,13 @@
 int
 pci_enable_device(struct pci_dev *dev)
 {
+	int err;
+
 	dev->is_enabled = 1;
-	return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+	if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
+		return err;
+	pci_fixup_device(pci_fixup_enable, dev);
+	return 0;
 }
 
 /**
@@ -744,7 +749,7 @@
 {
 	struct pci_dev *dev = NULL;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_fixup_device(pci_fixup_final, dev);
 	}
 	return 0;
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/pci.h	2004-09-26 14:30:27 -07:00
@@ -2,7 +2,9 @@
 
 extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
 			 char *buffer, int buffer_size);
-extern void pci_create_sysfs_dev_files(struct pci_dev *pdev);
+extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
+extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
+extern void pci_cleanup_rom(struct pci_dev *dev);
 extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 				  unsigned long size, unsigned long align,
 				  unsigned long min, unsigned int type_mask,
@@ -61,5 +63,6 @@
 /* Lock for read/write access to pci device and bus lists */
 extern spinlock_t pci_bus_lock;
 
-extern int pciehp_msi_quirk;
+extern int pcie_mch_quirk;
+extern void pcie_rootport_aspm_quirk(struct pci_dev *pdev);
 extern struct device_attribute pci_dev_attrs[];
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/probe.c	2004-09-26 14:30:27 -07:00
@@ -170,7 +170,7 @@
 		if (sz && sz != 0xffffffff) {
 			sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
 			if (sz) {
-				res->flags = (l & PCI_ROM_ADDRESS_ENABLE) |
+				res->flags = (l & IORESOURCE_ROM_ENABLE) |
 				  IORESOURCE_MEM | IORESOURCE_PREFETCH |
 				  IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
 				res->start = l & PCI_ROM_ADDRESS_MASK;
@@ -750,6 +750,7 @@
 
 struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
 {
+	int error;
 	struct pci_bus *b;
 	struct device *dev;
 
@@ -769,9 +770,7 @@
 	if (pci_find_bus(pci_domain_nr(b), bus)) {
 		/* If we already got to this bus through a different bridge, ignore it */
 		DBG("PCI: Bus %02x already known\n", bus);
-		kfree(dev);
-		kfree(b);
-		return NULL;
+		goto err_out;
 	}
 	list_add_tail(&b->node, &pci_root_buses);
 
@@ -779,15 +778,23 @@
 	dev->parent = parent;
 	dev->release = pci_release_bus_bridge_dev;
 	sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus);
-	device_register(dev);
+	error = device_register(dev);
+	if (error)
+		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);
-	class_device_register(&b->class_dev);
-	class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
-
-	sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
+	error = class_device_register(&b->class_dev);
+	if (error)
+		goto class_dev_reg_err;
+	error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
+	if (error)
+		goto class_dev_create_file_err;
+
+	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;
@@ -798,6 +805,19 @@
 	pci_bus_add_devices(b);
 
 	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);
+class_dev_reg_err:
+	device_unregister(dev);
+dev_reg_err:
+	list_del(&b->node);
+err_out:
+	kfree(dev);
+	kfree(b);
+	return NULL;
 }
 EXPORT_SYMBOL(pci_scan_bus_parented);
 
diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c
--- a/drivers/pci/proc.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/proc.c	2004-09-26 14:30:27 -07:00
@@ -379,7 +379,7 @@
 	.show	= show_device
 };
 
-struct proc_dir_entry *proc_bus_pci_dir;
+static struct proc_dir_entry *proc_bus_pci_dir;
 
 int pci_proc_attach_device(struct pci_dev *dev)
 {
@@ -599,7 +599,7 @@
 	if (entry)
 		entry->proc_fops = &proc_bus_pci_dev_operations;
 	proc_initialized = 1;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_proc_attach_device(dev);
 	}
 	legacy_proc_init();
@@ -612,6 +612,5 @@
 EXPORT_SYMBOL(pci_proc_attach_device);
 EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
-EXPORT_SYMBOL(proc_bus_pci_dir);
 #endif
 
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/quirks.c	2004-09-26 14:30:27 -07:00
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include "pci.h"
 
 #undef DEBUG
 
@@ -30,7 +31,7 @@
 
 	/* We have to make sure a particular bit is set in the PIIX3
 	   ISA bridge, so we have to go out and find it. */
-	while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
+	while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
 		pci_read_config_byte(d, 0x82, &dlc);
 		if (!(dlc & 1<<1)) {
 			printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d));
@@ -116,21 +117,21 @@
 	/* Ok we have a potential problem chipset here. Now see if we have
 	   a buggy southbridge */
 	   
-	p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
+	p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
 	if (p!=NULL) {
 		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
 		/* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */
 		/* Check for buggy part revisions */
-		if (rev < 0x40 || rev > 0x42) 
-			return;
+		if (rev < 0x40 || rev > 0x42)
+			goto exit;
 	} else {
-		p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
+		p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
 		if (p==NULL)	/* No problem parts */
-			return;
+			goto exit;
 		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
 		/* Check for buggy part revisions */
 		if (rev < 0x10 || rev > 0x12) 
-			return;
+			goto exit;
 	}
 	
 	/*
@@ -153,6 +154,8 @@
 	busarb |= (1<<4);
 	pci_write_config_byte(dev, 0x76, busarb);
 	printk(KERN_INFO "Applying VIA southbridge workaround.\n");
+exit:
+	pci_dev_put(p);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );
@@ -491,9 +494,9 @@
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
 	}
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );
 
 
 /*
@@ -978,13 +981,105 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_ANY_ID,	  quirk_intel_ide_combined );
 #endif /* CONFIG_SCSI_SATA */
 
-int pciehp_msi_quirk;
+int pcie_mch_quirk;
 
-static void __devinit quirk_pciehp_msi(struct pci_dev *pdev)
+static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
 {
-	pciehp_msi_quirk = 1;
+	pcie_mch_quirk = 1;
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_SMCH,	quirk_pciehp_msi );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_pcie_mch );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_pcie_mch );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_pcie_mch );
+
+/* Max PCI Express root ports */
+#define MAX_PCIEROOT	6
+static int quirk_aspm_offset[MAX_PCIEROOT << 3];
+
+#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b)
+
+static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+{
+	return raw_pci_ops->read(0, bus->number, devfn, where, size, value);
+}
+
+/*
+ * Replace the original pci bus ops for write with a new one that will filter
+ * the request to insure ASPM cannot be enabled.
+ */
+static int quirk_pcie_aspm_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+{
+	u8 offset;
+
+	offset = quirk_aspm_offset[GET_INDEX(bus->self->device, devfn)];
+
+	if ((offset) && (where == offset))
+		value = value & 0xfffffffc;
+	return raw_pci_ops->write(0, bus->number, devfn, where, size, value);
+}
+
+struct pci_ops quirk_pcie_aspm_ops = {
+	.read = quirk_pcie_aspm_read,
+	.write = quirk_pcie_aspm_write,
+};
+
+/*
+ * Prevents PCI Express ASPM (Active State Power Management) being enabled.
+ *
+ * Save the register offset, where the ASPM control bits are located,
+ * for each PCI Express device that is in the device list of
+ * the root port in an array for fast indexing. Replace the bus ops
+ * with the modified one.
+ */
+void pcie_rootport_aspm_quirk(struct pci_dev *pdev)
+{
+	int cap_base, i;
+	struct pci_bus  *pbus;
+	struct pci_dev *dev;
+
+	if ((pbus = pdev->subordinate) == NULL)
+		return;
+
+	/*
+	 * Check if the DID of pdev matches one of the six root ports. This
+	 * check is needed in the case this function is called directly by the
+	 * hot-plug driver.
+	 */
+	if ((pdev->device < PCI_DEVICE_ID_INTEL_MCH_PA) ||
+	    (pdev->device > PCI_DEVICE_ID_INTEL_MCH_PC1))
+		return;
+
+	if (list_empty(&pbus->devices)) {
+		/*
+		 * If no device is attached to the root port at power-up or
+		 * after hot-remove, the pbus->devices is empty and this code
+		 * will set the offsets to zero and the bus ops to parent's bus
+		 * ops, which is unmodified.
+	 	 */
+		for (i= GET_INDEX(pdev->device, 0); i <= GET_INDEX(pdev->device, 7); ++i)
+			quirk_aspm_offset[i] = 0;
+
+		pbus->ops = pbus->parent->ops;
+	} else {
+		/*
+		 * If devices are attached to the root port at power-up or
+		 * after hot-add, the code loops through the device list of
+		 * each root port to save the register offsets and replace the
+		 * bus ops.
+		 */
+		list_for_each_entry(dev, &pbus->devices, bus_list) {
+			/* There are 0 to 8 devices attached to this bus */
+			cap_base = pci_bus_find_capability(pbus, dev->devfn, PCI_CAP_ID_EXP);
+			quirk_aspm_offset[GET_INDEX(pdev->device, dev->devfn)]= cap_base + 0x10;
+		}
+		pbus->ops = &quirk_pcie_aspm_ops;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PA,	pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PA1,	pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PB,	pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PB1,	pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PC,	pcie_rootport_aspm_quirk );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_MCH_PC1,	pcie_rootport_aspm_quirk );
 
 
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
@@ -992,7 +1087,7 @@
 	while (f < end) {
 		if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
  		    (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
-			pr_debug(KERN_INFO "PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
+			pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
 			f->hook(dev);
 		}
 		f++;
@@ -1003,6 +1098,9 @@
 extern struct pci_fixup __end_pci_fixups_header[];
 extern struct pci_fixup __start_pci_fixups_final[];
 extern struct pci_fixup __end_pci_fixups_final[];
+extern struct pci_fixup __start_pci_fixups_enable[];
+extern struct pci_fixup __end_pci_fixups_enable[];
+
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
 {
@@ -1018,6 +1116,12 @@
 		start = __start_pci_fixups_final;
 		end = __end_pci_fixups_final;
 		break;
+
+	case pci_fixup_enable:
+		start = __start_pci_fixups_enable;
+		end = __end_pci_fixups_enable;
+		break;
+
 	default:
 		/* stupid compiler warning, you would think with an enum... */
 		return;
@@ -1025,4 +1129,5 @@
 	pci_do_fixups(dev, start, end);
 }
 
-EXPORT_SYMBOL(pciehp_msi_quirk);
+EXPORT_SYMBOL(pcie_mch_quirk);
+EXPORT_SYMBOL(pcie_rootport_aspm_quirk);
diff -Nru a/drivers/pci/remove.c b/drivers/pci/remove.c
--- a/drivers/pci/remove.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/remove.c	2004-09-26 14:30:27 -07:00
@@ -16,6 +16,7 @@
 
  	msi_remove_pci_irq_vectors(dev);
 
+	pci_cleanup_rom(dev);
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		struct resource *res = dev->resource + i;
 		if (res->parent)
@@ -26,6 +27,7 @@
 static void pci_destroy_dev(struct pci_dev *dev)
 {
 	pci_proc_detach_device(dev);
+	pci_remove_sysfs_dev_files(dev);
 	device_unregister(&dev->dev);
 
 	/* Remove the device from the device lists, and prevent any further
diff -Nru a/drivers/pci/rom.c b/drivers/pci/rom.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/rom.c	2004-09-26 14:30:27 -07:00
@@ -0,0 +1,225 @@
+/*
+ * drivers/pci/rom.c
+ *
+ * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
+ * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
+ *
+ * PCI ROM access routines
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include "pci.h"
+
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *pdev)
+{
+	u32 rom_addr;
+	
+	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
+	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *pdev)
+{
+	u32 rom_addr;
+	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
+	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_map_rom - map a PCI ROM to kernel space
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
+{
+	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+	loff_t start;
+	void __iomem *rom;
+	void __iomem *image;
+	int last_image;
+	
+	if (res->flags & IORESOURCE_ROM_SHADOW) {	/* IORESOURCE_ROM_SHADOW only set on x86 */
+		start = (loff_t)0xC0000; 	/* primary video rom always starts here */
+		*size = 0x20000;		/* cover C000:0 through E000:0 */
+	} else {
+		if (res->flags & IORESOURCE_ROM_COPY) {
+			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+			return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE);
+		} else {
+			/* assign the ROM an address if it doesn't have one */
+			if (res->parent == NULL)
+				pci_assign_resource(pdev, PCI_ROM_RESOURCE);
+	
+			start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
+			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+			if (*size == 0)
+				return NULL;
+			
+			/* Enable ROM space decodes */
+			pci_enable_rom(pdev);
+		}
+	}
+	
+	rom = ioremap(start, *size);
+	if (!rom) {
+		/* restore enable if ioremap fails */
+		if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+			pci_disable_rom(pdev);
+		return NULL;
+	}		
+
+	/* Try to find the true size of the ROM since sometimes the PCI window */
+	/* size is much larger than the actual size of the ROM. */
+	/* True size is important if the ROM is going to be copied. */
+	image = rom;
+	do {
+		void __iomem *pds;
+		/* Standard PCI ROMs start out with these bytes 55 AA */
+		if (readb(image) != 0x55)
+			break;
+		if (readb(image + 1) != 0xAA)
+			break;
+		/* get the PCI data structure and check its signature */
+		pds = image + readw(image + 24);
+		if (readb(pds) != 'P')
+			break;
+		if (readb(pds + 1) != 'C')
+			break;
+		if (readb(pds + 2) != 'I')
+			break;
+		if (readb(pds + 3) != 'R')
+			break;
+		last_image = readb(pds + 21) & 0x80;
+		/* this length is reliable */
+		image += readw(pds + 16) * 512;
+	} while (!last_image);
+
+	*size = image - rom;
+
+	return rom;
+}
+
+/**
+ * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
+{
+	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+	void __iomem *rom;
+	
+	rom = pci_map_rom(pdev, size);
+	if (!rom)
+		return NULL;
+		
+	if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
+		return rom;
+		
+	res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
+	if (!res->start) 
+		return rom;
+
+	res->end = res->start + *size; 
+	memcpy_fromio((void*)res->start, rom, *size);
+	pci_unmap_rom(pdev, rom);
+	res->flags |= IORESOURCE_ROM_COPY;
+	
+	return (void __iomem *)res->start;
+}
+
+/**
+ * pci_unmap_rom - unmap the ROM from kernel space
+ * @dev: pointer to pci device struct
+ * @rom: virtual address of the previous mapping
+ *
+ * Remove a mapping of a previously mapped ROM
+ */
+void 
+pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
+{
+	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+
+	if (res->flags & IORESOURCE_ROM_COPY)
+		return;
+		
+	iounmap(rom);
+		
+	/* Disable again before continuing, leave enabled if pci=rom */
+	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
+		pci_disable_rom(pdev);
+}
+
+/**
+ * pci_remove_rom - disable the ROM and remove its sysfs attribute
+ * @dev: pointer to pci device struct
+ *
+ */
+void 
+pci_remove_rom(struct pci_dev *pdev) 
+{
+	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+	
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+		pci_disable_rom(pdev);
+}
+
+/**
+ * pci_cleanup_rom - internal routine for freeing the ROM copy created 
+ * by pci_map_rom_copy called from remove.c
+ * @dev: pointer to pci device struct
+ *
+ */
+void 
+pci_cleanup_rom(struct pci_dev *pdev) 
+{
+	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+	if (res->flags & IORESOURCE_ROM_COPY) {
+		kfree((void*)res->start);
+		res->flags &= ~IORESOURCE_ROM_COPY;
+		res->start = 0;
+		res->end = 0;
+	}
+}
+
+EXPORT_SYMBOL(pci_map_rom);
+EXPORT_SYMBOL(pci_map_rom_copy);
+EXPORT_SYMBOL(pci_unmap_rom);
+EXPORT_SYMBOL(pci_remove_rom);
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/search.c	2004-09-26 14:30:27 -07:00
@@ -1,10 +1,10 @@
 /*
  * 	PCI searching functions.
  *
- *	Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
- *				David Mosberger-Tang
- *	Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
- *	Copyright 2003 -- Greg Kroah-Hartman <greg@kroah.com>
+ *	Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
+ *					David Mosberger-Tang
+ *	Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz>
+ *	Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>
  */
 
 #include <linux/init.h>
@@ -156,10 +156,11 @@
  * the pci device returned by this function can disappear at any moment in
  * time.
  */
-struct pci_dev *
-pci_find_subsys(unsigned int vendor, unsigned int device,
-		unsigned int ss_vendor, unsigned int ss_device,
-		const struct pci_dev *from)
+static struct pci_dev * pci_find_subsys(unsigned int vendor,
+				        unsigned int device,
+					unsigned int ss_vendor,
+					unsigned int ss_device,
+					const struct pci_dev *from)
 {
 	struct list_head *n;
 	struct pci_dev *dev;
@@ -257,12 +258,6 @@
  * @from: Previous PCI device found in search, or %NULL for new search.
  *
  * Iterates through the list of known PCI devices.  If a PCI device is
- * found with a matching @vendor and @device, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device on the global list.
- *
- * Iterates through the list of known PCI devices.  If a PCI device is
  * found with a matching @vendor and @device, the reference count to the
  * device is incremented and a pointer to its device structure is returned.
  * Otherwise, %NULL is returned.  A new search is initiated by passing %NULL
@@ -312,25 +307,26 @@
 	return dev;
 }
 
-
 /**
- * pci_find_class - begin or continue searching for a PCI device by class
+ * pci_get_class - begin or continue searching for a PCI device by class
  * @class: search for a PCI device with this class designation
  * @from: Previous PCI device found in search, or %NULL for new search.
  *
  * Iterates through the list of known PCI devices.  If a PCI device is
- * found with a matching @class, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
+ * found with a matching @class, the reference count to the device is
+ * incremented and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned.
  * A new search is initiated by passing %NULL to the @from argument.
  * Otherwise if @from is not %NULL, searches continue from next device
- * on the global list.
+ * on the global list.  The reference count for @from is always decremented
+ * if it is not %NULL.
  */
-struct pci_dev *
-pci_find_class(unsigned int class, const struct pci_dev *from)
+struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
 {
 	struct list_head *n;
 	struct pci_dev *dev;
 
+	WARN_ON(in_interrupt());
 	spin_lock(&pci_bus_lock);
 	n = from ? from->global_list.next : pci_devices.next;
 
@@ -342,16 +338,17 @@
 	}
 	dev = NULL;
 exit:
+	pci_dev_put(from);
+	dev = pci_dev_get(dev);
 	spin_unlock(&pci_bus_lock);
 	return dev;
 }
 
 EXPORT_SYMBOL(pci_find_bus);
-EXPORT_SYMBOL(pci_find_class);
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
-EXPORT_SYMBOL(pci_find_subsys);
 EXPORT_SYMBOL(pci_get_device);
 EXPORT_SYMBOL(pci_get_subsys);
 EXPORT_SYMBOL(pci_get_slot);
+EXPORT_SYMBOL(pci_get_class);
diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/setup-bus.c	2004-09-26 14:30:27 -07:00
@@ -533,16 +533,16 @@
 void __init
 pci_assign_unassigned_resources(void)
 {
-	struct list_head *ln;
+	struct pci_bus *bus;
 
 	/* Depth first, calculate sizes and alignments of all
 	   subordinate buses. */
-	list_for_each(ln, &pci_root_buses) {
-		pci_bus_size_bridges(pci_bus_b(ln));
+	list_for_each_entry(bus, &pci_root_buses, node) {
+		pci_bus_size_bridges(bus);
 	}
 	/* Depth last, allocate resources and update the hardware. */
-	list_for_each(ln, &pci_root_buses) {
-		pci_bus_assign_resources(pci_bus_b(ln));
-		pci_enable_bridges(pci_bus_b(ln));
+	list_for_each_entry(bus, &pci_root_buses, node) {
+		pci_bus_assign_resources(bus);
+		pci_enable_bridges(bus);
 	}
 }
diff -Nru a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
--- a/drivers/pci/setup-irq.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/setup-irq.c	2004-09-26 14:30:27 -07:00
@@ -65,7 +65,7 @@
 	       int (*map_irq)(struct pci_dev *, u8, u8))
 {
 	struct pci_dev *dev = NULL;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pdev_fixup_irq(dev, swizzle, map_irq);
 	}
 }
diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pci/setup-res.c	2004-09-26 14:30:27 -07:00
@@ -56,7 +56,7 @@
 	if (resno < 6) {
 		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
 	} else if (resno == PCI_ROM_RESOURCE) {
-		new |= res->flags & PCI_ROM_ADDRESS_ENABLE;
+		new |= res->flags & IORESOURCE_ROM_ENABLE;
 		reg = dev->rom_base_reg;
 	} else {
 		/* Hmm, non-standard resource. */
diff -Nru a/drivers/pnp/system.c b/drivers/pnp/system.c
--- a/drivers/pnp/system.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/pnp/system.c	2004-09-26 14:30:27 -07:00
@@ -104,4 +104,8 @@
 	return pnp_register_driver(&system_pnp_driver);
 }
 
-subsys_initcall(pnp_system_init);
+/**
+ * Reserve motherboard resources after PCI claim BARs,
+ * but before PCI assign resources for uninitialized PCI devices
+ */
+fs_initcall(pnp_system_init);
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	2004-09-26 14:30:27 -07:00
+++ b/drivers/scsi/eata.c	2004-09-26 14:30:27 -07:00
@@ -1005,7 +1005,7 @@
    unsigned int addr;
    struct pci_dev *dev = NULL;
 
-   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
       addr = pci_resource_start (dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
@@ -1013,6 +1013,11 @@
              driver_name, dev->bus->number, dev->devfn, addr);
 #endif
 
+      /* we are in so much trouble for a pci hotplug system with this driver
+       * anyway, so doing this at least lets people unload the driver and not
+       * cause memory problems, but in general this is a bad thing to do (this
+       * driver needs to be converted to the proper PCI api someday... */
+      pci_dev_put(dev);
       if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev;
       }
 
@@ -1027,7 +1032,7 @@
 
    struct pci_dev *dev = NULL;
 
-   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
 
 #if defined(DEBUG_PCI_DETECT)
       printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
@@ -1454,7 +1459,7 @@
 
    for (k = 0; k < MAX_PCI; k++) {
 
-      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+      if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
 
       if (pci_enable_device (dev)) {
 
@@ -1478,6 +1483,7 @@
              addr + PCI_BASE_ADDRESS_0;
       }
 
+   pci_dev_put(dev);
 #endif /* end CONFIG_PCI */
 
    return;
diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h	2004-09-26 14:30:27 -07:00
+++ b/include/asm-generic/vmlinux.lds.h	2004-09-26 14:30:27 -07:00
@@ -24,6 +24,9 @@
 		VMLINUX_SYMBOL(__start_pci_fixups_final) = .;		\
 		*(.pci_fixup_final)					\
 		VMLINUX_SYMBOL(__end_pci_fixups_final) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_enable) = .;		\
+		*(.pci_fixup_enable)					\
+		VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: Normal symbols */			\
diff -Nru a/include/linux/ioport.h b/include/linux/ioport.h
--- a/include/linux/ioport.h	2004-09-26 14:30:27 -07:00
+++ b/include/linux/ioport.h	2004-09-26 14:30:27 -07:00
@@ -82,6 +82,11 @@
 #define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
 #define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
 
+/* PCI ROM control bits (IORESOURCE_BITS) */
+#define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
+#define IORESOURCE_ROM_SHADOW		(1<<1)	/* ROM is copy at C000:0 */
+#define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
+
 /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h	2004-09-26 14:30:27 -07:00
+++ b/include/linux/pci.h	2004-09-26 14:30:27 -07:00
@@ -537,6 +537,7 @@
 	unsigned int	is_busmaster:1; /* device is busmaster */
 	
 	u32		saved_config_space[16]; /* config space saved at suspend time */
+	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */
@@ -719,10 +720,6 @@
 
 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
 struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
-struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
-				 unsigned int ss_vendor, unsigned int ss_device,
-				 const struct pci_dev *from);
-struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
@@ -733,6 +730,7 @@
 				unsigned int ss_vendor, unsigned int ss_device,
 				struct pci_dev *from);
 struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
+struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
 
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -778,6 +776,12 @@
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_assign_resource(struct pci_dev *dev, int i);
 
+/* ROM control related routines */
+void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
+void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size);
+void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
+void pci_remove_rom(struct pci_dev *pdev);
+
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev, u32 *buffer);
 int pci_restore_state(struct pci_dev *dev, u32 *buffer);
@@ -882,16 +886,9 @@
 static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
 { return NULL; }
 
-static inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
-{ return NULL; }
-
 static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
 { return NULL; }
 
-static inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device,
-unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from)
-{ return NULL; }
-
 static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
 { return NULL; }
 
@@ -899,6 +896,9 @@
 unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from)
 { return NULL; }
 
+static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
+{ return NULL; }
+
 static inline void pci_set_master(struct pci_dev *dev) { }
 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
 static inline void pci_disable_device(struct pci_dev *dev) { }
@@ -1008,6 +1008,7 @@
 enum pci_fixup_pass {
 	pci_fixup_header,	/* Called immediately after reading configuration header */
 	pci_fixup_final,	/* Final phase of device fixups */
+	pci_fixup_enable,	/* pci_enable_device() time */
 };
 
 /* Anonymous variables would be nice... */
@@ -1020,6 +1021,12 @@
 	static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__	\
 	__attribute__((__section__(".pci_fixup_final"))) = {				\
 		vendor, device, hook };
+
+#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)				\
+	static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__	\
+	__attribute__((__section__(".pci_fixup_enable"))) = {				\
+		vendor, device, hook };
+
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
 
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2004-09-26 14:30:27 -07:00
+++ b/include/linux/pci_ids.h	2004-09-26 14:30:27 -07:00
@@ -2203,7 +2203,15 @@
 #define PCI_DEVICE_ID_INTEL_82830_CGC	0x3577
 #define PCI_DEVICE_ID_INTEL_82855GM_HB	0x3580
 #define PCI_DEVICE_ID_INTEL_82855GM_IG	0x3582
-#define PCI_DEVICE_ID_INTEL_SMCH	0x3590
+#define PCI_DEVICE_ID_INTEL_E7520_MCH	0x3590
+#define PCI_DEVICE_ID_INTEL_E7320_MCH	0x3592
+#define PCI_DEVICE_ID_INTEL_MCH_PA	0x3595
+#define PCI_DEVICE_ID_INTEL_MCH_PA1	0x3596
+#define PCI_DEVICE_ID_INTEL_MCH_PB	0x3597
+#define PCI_DEVICE_ID_INTEL_MCH_PB1	0x3598
+#define PCI_DEVICE_ID_INTEL_MCH_PC	0x3599
+#define PCI_DEVICE_ID_INTEL_MCH_PC1	0x359a
+#define PCI_DEVICE_ID_INTEL_E7525_MCH	0x359e
 #define PCI_DEVICE_ID_INTEL_80310	0x530d
 #define PCI_DEVICE_ID_INTEL_82371SB_0	0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1	0x7010