Browse Source

Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (74 commits)
  PCI: make msi_free_irqs() to use msix_mask_irq() instead of open coded write
  PCI: Fix the NIU MSI-X problem in a better way
  PCI ASPM: remove get_root_port_link
  PCI ASPM: cleanup pcie_aspm_sanity_check
  PCI ASPM: remove has_switch field
  PCI ASPM: cleanup calc_Lx_latency
  PCI ASPM: cleanup pcie_aspm_get_cap_device
  PCI ASPM: cleanup clkpm checks
  PCI ASPM: cleanup __pcie_aspm_check_state_one
  PCI ASPM: cleanup initialization
  PCI ASPM: cleanup change input argument of aspm functions
  PCI ASPM: cleanup misc in struct pcie_link_state
  PCI ASPM: cleanup clkpm state in struct pcie_link_state
  PCI ASPM: cleanup latency field in struct pcie_link_state
  PCI ASPM: cleanup aspm state field in struct pcie_link_state
  PCI ASPM: fix typo in struct pcie_link_state
  PCI: drivers/pci/slot.c should depend on CONFIG_SYSFS
  PCI: remove redundant __msi_set_enable()
  PCI PM: consistently use type bool for wake enable variable
  x86/ACPI: Correct maximum allowed _CRS returned resources and warn if exceeded
  ...
Linus Torvalds 16 năm trước cách đây
mục cha
commit
59ef7a83f1
55 tập tin đã thay đổi với 3038 bổ sung2201 xóa
  1. 7 0
      Documentation/ABI/testing/sysfs-bus-pci
  2. 25 0
      Documentation/PCI/pcieaer-howto.txt
  3. 10 1
      Documentation/kernel-parameters.txt
  4. 24 14
      arch/powerpc/platforms/pseries/eeh_driver.c
  5. 1 0
      arch/x86/include/asm/pci.h
  6. 1 1
      arch/x86/include/asm/pci_x86.h
  7. 28 7
      arch/x86/pci/acpi.c
  8. 1 1
      arch/x86/pci/amd_bus.c
  9. 2 2
      arch/x86/pci/common.c
  10. 1 0
      drivers/acpi/Kconfig
  11. 2 1
      drivers/pci/Makefile
  12. 19 0
      drivers/pci/access.c
  13. 15 3
      drivers/pci/bus.c
  14. 2 2
      drivers/pci/hotplug/Kconfig
  15. 0 1
      drivers/pci/hotplug/acpiphp_core.c
  16. 0 1
      drivers/pci/hotplug/cpci_hotplug_core.c
  17. 95 72
      drivers/pci/hotplug/cpqphp.h
  18. 560 608
      drivers/pci/hotplug/cpqphp_core.c
  19. 191 180
      drivers/pci/hotplug/cpqphp_ctrl.c
  20. 51 46
      drivers/pci/hotplug/cpqphp_nvram.c
  21. 297 302
      drivers/pci/hotplug/cpqphp_pci.c
  22. 1 1
      drivers/pci/hotplug/ibmphp_core.c
  23. 84 71
      drivers/pci/hotplug/pci_hotplug_core.c
  24. 0 3
      drivers/pci/hotplug/pciehp.h
  25. 1 111
      drivers/pci/hotplug/pciehp_core.c
  26. 0 31
      drivers/pci/hotplug/pciehp_hpc.c
  27. 0 1
      drivers/pci/hotplug/pcihp_skeleton.c
  28. 0 1
      drivers/pci/hotplug/rpaphp_core.c
  29. 0 1
      drivers/pci/hotplug/sgi_hotplug.c
  30. 0 1
      drivers/pci/hotplug/shpchp_core.c
  31. 4 2
      drivers/pci/iov.c
  32. 51 49
      drivers/pci/msi.c
  33. 4 10
      drivers/pci/msi.h
  34. 158 88
      drivers/pci/pci.c
  35. 15 0
      drivers/pci/pcie/aer/Kconfig
  36. 18 0
      drivers/pci/pcie/aer/Kconfig.debug
  37. 3 0
      drivers/pci/pcie/aer/Makefile
  38. 473 0
      drivers/pci/pcie/aer/aer_inject.c
  39. 2 1
      drivers/pci/pcie/aer/aerdrv.c
  40. 6 0
      drivers/pci/pcie/aer/aerdrv.h
  41. 191 87
      drivers/pci/pcie/aer/aerdrv_core.c
  42. 131 0
      drivers/pci/pcie/aer/ecrc.c
  43. 371 416
      drivers/pci/pcie/aspm.c
  44. 8 3
      drivers/pci/probe.c
  45. 24 0
      drivers/pci/quirks.c
  46. 0 2
      drivers/pci/remove.c
  47. 1 31
      drivers/pci/search.c
  48. 42 11
      drivers/pci/setup-bus.c
  49. 36 13
      drivers/pci/setup-res.c
  50. 39 0
      drivers/pci/slot.c
  51. 2 0
      include/linux/ioport.h
  52. 2 2
      include/linux/pci-acpi.h
  53. 24 11
      include/linux/pci.h
  54. 13 10
      include/linux/pci_hotplug.h
  55. 2 2
      include/linux/pci_regs.h

+ 7 - 0
Documentation/ABI/testing/sysfs-bus-pci

@@ -122,3 +122,10 @@ Description:
 		This symbolic link appears when a device is a Virtual Function.
 		This symbolic link appears when a device is a Virtual Function.
 		The symbolic link points to the PCI device sysfs entry of the
 		The symbolic link points to the PCI device sysfs entry of the
 		Physical Function this device associates with.
 		Physical Function this device associates with.
+
+What:		/sys/bus/pci/slots/.../module
+Date:		June 2009
+Contact:	linux-pci@vger.kernel.org
+Description:
+		This symbolic link points to the PCI hotplug controller driver
+		module that manages the hotplug slot.

+ 25 - 0
Documentation/PCI/pcieaer-howto.txt

@@ -61,6 +61,10 @@ be initiated although firmwares have no _OSC support. To enable the
 walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line
 walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line
 when booting kernel. Note that forceload=n by default.
 when booting kernel. Note that forceload=n by default.
 
 
+nosourceid, another parameter of type bool, can be used when broken
+hardware (mostly chipsets) has root ports that cannot obtain the reporting
+source ID. nosourceid=n by default.
+
 2.3 AER error output
 2.3 AER error output
 When a PCI-E AER error is captured, an error message will be outputed to
 When a PCI-E AER error is captured, an error message will be outputed to
 console. If it's a correctable error, it is outputed as a warning.
 console. If it's a correctable error, it is outputed as a warning.
@@ -246,3 +250,24 @@ with the PCI Express AER Root driver?
 A: It could call the helper functions to enable AER in devices and
 A: It could call the helper functions to enable AER in devices and
 cleanup uncorrectable status register. Pls. refer to section 3.3.
 cleanup uncorrectable status register. Pls. refer to section 3.3.
 
 
+
+4. Software error injection
+
+Debugging PCIE AER error recovery code is quite difficult because it
+is hard to trigger real hardware errors. Software based error
+injection can be used to fake various kinds of PCIE errors.
+
+First you should enable PCIE AER software error injection in kernel
+configuration, that is, following item should be in your .config.
+
+CONFIG_PCIEAER_INJECT=y or CONFIG_PCIEAER_INJECT=m
+
+After reboot with new kernel or insert the module, a device file named
+/dev/aer_inject should be created.
+
+Then, you need a user space tool named aer-inject, which can be gotten
+from:
+    http://www.kernel.org/pub/linux/utils/pci/aer-inject/
+
+More information about aer-inject can be found in the document comes
+with its source code.

+ 10 - 1
Documentation/kernel-parameters.txt

@@ -1776,6 +1776,9 @@ and is between 256 and 4096 characters. It is defined in the file
 				root domains (aka PCI segments, in ACPI-speak).
 				root domains (aka PCI segments, in ACPI-speak).
 		nommconf	[X86] Disable use of MMCONFIG for PCI
 		nommconf	[X86] Disable use of MMCONFIG for PCI
 				Configuration
 				Configuration
+		check_enable_amd_mmconf [X86] check for and enable
+				properly configured MMIO access to PCI
+				config space on AMD family 10h CPU
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 				enabled, this kernel boot option can be used to
 				enabled, this kernel boot option can be used to
 				disable the use of MSI interrupts system-wide.
 				disable the use of MSI interrupts system-wide.
@@ -1828,7 +1831,7 @@ and is between 256 and 4096 characters. It is defined in the file
 				IRQ routing is enabled.
 				IRQ routing is enabled.
 		noacpi		[X86] Do not use ACPI for IRQ routing
 		noacpi		[X86] Do not use ACPI for IRQ routing
 				or for PCI scanning.
 				or for PCI scanning.
-		use_crs		[X86] Use _CRS for PCI resource
+		nocrs		[X86] Don't use _CRS for PCI resource
 				allocation.
 				allocation.
 		routeirq	Do IRQ routing for all PCI devices.
 		routeirq	Do IRQ routing for all PCI devices.
 				This is normally done in pci_enable_device(),
 				This is normally done in pci_enable_device(),
@@ -1865,6 +1868,12 @@ and is between 256 and 4096 characters. It is defined in the file
 				PAGE_SIZE is used as alignment.
 				PAGE_SIZE is used as alignment.
 				PCI-PCI bridge can be specified, if resource
 				PCI-PCI bridge can be specified, if resource
 				windows need to be expanded.
 				windows need to be expanded.
+		ecrc=		Enable/disable PCIe ECRC (transaction layer
+				end-to-end CRC checking).
+				bios: Use BIOS/firmware settings. This is the
+				the default.
+				off: Turn ECRC off
+				on: Turn ECRC on.
 
 
 	pcie_aspm=	[PCIE] Forcibly enable or disable PCIe Active State Power
 	pcie_aspm=	[PCIE] Forcibly enable or disable PCIe Active State Power
 			Management.
 			Management.

+ 24 - 14
arch/powerpc/platforms/pseries/eeh_driver.c

@@ -122,7 +122,7 @@ static void eeh_enable_irq(struct pci_dev *dev)
  * passed back in "userdata".
  * passed back in "userdata".
  */
  */
 
 
-static void eeh_report_error(struct pci_dev *dev, void *userdata)
+static int eeh_report_error(struct pci_dev *dev, void *userdata)
 {
 {
 	enum pci_ers_result rc, *res = userdata;
 	enum pci_ers_result rc, *res = userdata;
 	struct pci_driver *driver = dev->driver;
 	struct pci_driver *driver = dev->driver;
@@ -130,19 +130,21 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
 	dev->error_state = pci_channel_io_frozen;
 	dev->error_state = pci_channel_io_frozen;
 
 
 	if (!driver)
 	if (!driver)
-		return;
+		return 0;
 
 
 	eeh_disable_irq(dev);
 	eeh_disable_irq(dev);
 
 
 	if (!driver->err_handler ||
 	if (!driver->err_handler ||
 	    !driver->err_handler->error_detected)
 	    !driver->err_handler->error_detected)
-		return;
+		return 0;
 
 
 	rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
 	rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
 
 
 	/* A driver that needs a reset trumps all others */
 	/* A driver that needs a reset trumps all others */
 	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
 	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -153,7 +155,7 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
  * Cumulative response passed back in "userdata".
  * Cumulative response passed back in "userdata".
  */
  */
 
 
-static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
+static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
 {
 {
 	enum pci_ers_result rc, *res = userdata;
 	enum pci_ers_result rc, *res = userdata;
 	struct pci_driver *driver = dev->driver;
 	struct pci_driver *driver = dev->driver;
@@ -161,26 +163,28 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
 	if (!driver ||
 	if (!driver ||
 	    !driver->err_handler ||
 	    !driver->err_handler ||
 	    !driver->err_handler->mmio_enabled)
 	    !driver->err_handler->mmio_enabled)
-		return;
+		return 0;
 
 
 	rc = driver->err_handler->mmio_enabled (dev);
 	rc = driver->err_handler->mmio_enabled (dev);
 
 
 	/* A driver that needs a reset trumps all others */
 	/* A driver that needs a reset trumps all others */
 	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
 	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+	return 0;
 }
 }
 
 
 /**
 /**
  * eeh_report_reset - tell device that slot has been reset
  * eeh_report_reset - tell device that slot has been reset
  */
  */
 
 
-static void eeh_report_reset(struct pci_dev *dev, void *userdata)
+static int eeh_report_reset(struct pci_dev *dev, void *userdata)
 {
 {
 	enum pci_ers_result rc, *res = userdata;
 	enum pci_ers_result rc, *res = userdata;
 	struct pci_driver *driver = dev->driver;
 	struct pci_driver *driver = dev->driver;
 
 
 	if (!driver)
 	if (!driver)
-		return;
+		return 0;
 
 
 	dev->error_state = pci_channel_io_normal;
 	dev->error_state = pci_channel_io_normal;
 
 
@@ -188,35 +192,39 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
 
 
 	if (!driver->err_handler ||
 	if (!driver->err_handler ||
 	    !driver->err_handler->slot_reset)
 	    !driver->err_handler->slot_reset)
-		return;
+		return 0;
 
 
 	rc = driver->err_handler->slot_reset(dev);
 	rc = driver->err_handler->slot_reset(dev);
 	if ((*res == PCI_ERS_RESULT_NONE) ||
 	if ((*res == PCI_ERS_RESULT_NONE) ||
 	    (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
 	    (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
 	if (*res == PCI_ERS_RESULT_DISCONNECT &&
 	if (*res == PCI_ERS_RESULT_DISCONNECT &&
 	     rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
 	     rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+
+	return 0;
 }
 }
 
 
 /**
 /**
  * eeh_report_resume - tell device to resume normal operations
  * eeh_report_resume - tell device to resume normal operations
  */
  */
 
 
-static void eeh_report_resume(struct pci_dev *dev, void *userdata)
+static int eeh_report_resume(struct pci_dev *dev, void *userdata)
 {
 {
 	struct pci_driver *driver = dev->driver;
 	struct pci_driver *driver = dev->driver;
 
 
 	dev->error_state = pci_channel_io_normal;
 	dev->error_state = pci_channel_io_normal;
 
 
 	if (!driver)
 	if (!driver)
-		return;
+		return 0;
 
 
 	eeh_enable_irq(dev);
 	eeh_enable_irq(dev);
 
 
 	if (!driver->err_handler ||
 	if (!driver->err_handler ||
 	    !driver->err_handler->resume)
 	    !driver->err_handler->resume)
-		return;
+		return 0;
 
 
 	driver->err_handler->resume(dev);
 	driver->err_handler->resume(dev);
+
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -226,22 +234,24 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata)
  * dead, and that no further recovery attempts will be made on it.
  * dead, and that no further recovery attempts will be made on it.
  */
  */
 
 
-static void eeh_report_failure(struct pci_dev *dev, void *userdata)
+static int eeh_report_failure(struct pci_dev *dev, void *userdata)
 {
 {
 	struct pci_driver *driver = dev->driver;
 	struct pci_driver *driver = dev->driver;
 
 
 	dev->error_state = pci_channel_io_perm_failure;
 	dev->error_state = pci_channel_io_perm_failure;
 
 
 	if (!driver)
 	if (!driver)
-		return;
+		return 0;
 
 
 	eeh_disable_irq(dev);
 	eeh_disable_irq(dev);
 
 
 	if (!driver->err_handler ||
 	if (!driver->err_handler ||
 	    !driver->err_handler->error_detected)
 	    !driver->err_handler->error_detected)
-		return;
+		return 0;
 
 
 	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
 	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
+
+	return 0;
 }
 }
 
 
 /* ------------------------------------------------------- */
 /* ------------------------------------------------------- */

+ 1 - 0
arch/x86/include/asm/pci.h

@@ -130,6 +130,7 @@ extern void pci_iommu_alloc(void);
 
 
 /* generic pci stuff */
 /* generic pci stuff */
 #include <asm-generic/pci.h>
 #include <asm-generic/pci.h>
+#define PCIBIOS_MAX_MEM_32 0xffffffff
 
 
 #ifdef CONFIG_NUMA
 #ifdef CONFIG_NUMA
 /* Returns the node based on pci bus */
 /* Returns the node based on pci bus */

+ 1 - 1
arch/x86/include/asm/pci_x86.h

@@ -25,7 +25,7 @@
 #define PCI_BIOS_IRQ_SCAN	0x2000
 #define PCI_BIOS_IRQ_SCAN	0x2000
 #define PCI_ASSIGN_ALL_BUSSES	0x4000
 #define PCI_ASSIGN_ALL_BUSSES	0x4000
 #define PCI_CAN_SKIP_ISA_ALIGN	0x8000
 #define PCI_CAN_SKIP_ISA_ALIGN	0x8000
-#define PCI_USE__CRS		0x10000
+#define PCI_NO_ROOT_CRS		0x10000
 #define PCI_CHECK_ENABLE_AMD_MMCONF	0x20000
 #define PCI_CHECK_ENABLE_AMD_MMCONF	0x20000
 #define PCI_HAS_IO_ECS		0x40000
 #define PCI_HAS_IO_ECS		0x40000
 #define PCI_NOASSIGN_ROMS	0x80000
 #define PCI_NOASSIGN_ROMS	0x80000

+ 28 - 7
arch/x86/pci/acpi.c

@@ -38,15 +38,26 @@ count_resource(struct acpi_resource *acpi_res, void *data)
 	struct acpi_resource_address64 addr;
 	struct acpi_resource_address64 addr;
 	acpi_status status;
 	acpi_status status;
 
 
-	if (info->res_num >= PCI_BUS_NUM_RESOURCES)
-		return AE_OK;
-
 	status = resource_to_addr(acpi_res, &addr);
 	status = resource_to_addr(acpi_res, &addr);
 	if (ACPI_SUCCESS(status))
 	if (ACPI_SUCCESS(status))
 		info->res_num++;
 		info->res_num++;
 	return AE_OK;
 	return AE_OK;
 }
 }
 
 
+static int
+bus_has_transparent_bridge(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		u16 class = dev->class >> 8;
+
+		if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent)
+			return true;
+	}
+	return false;
+}
+
 static acpi_status
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
 {
@@ -56,9 +67,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	acpi_status status;
 	acpi_status status;
 	unsigned long flags;
 	unsigned long flags;
 	struct resource *root;
 	struct resource *root;
-
-	if (info->res_num >= PCI_BUS_NUM_RESOURCES)
-		return AE_OK;
+	int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
 
 
 	status = resource_to_addr(acpi_res, &addr);
 	status = resource_to_addr(acpi_res, &addr);
 	if (!ACPI_SUCCESS(status))
 	if (!ACPI_SUCCESS(status))
@@ -82,6 +91,18 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
 	res->end = res->start + addr.address_length - 1;
 	res->end = res->start + addr.address_length - 1;
 	res->child = NULL;
 	res->child = NULL;
 
 
+	if (bus_has_transparent_bridge(info->bus))
+		max_root_bus_resources -= 3;
+	if (info->res_num >= max_root_bus_resources) {
+		printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
+			"from %s for %s due to _CRS returning more than "
+			"%d resource descriptors\n", (unsigned long) res->start,
+			(unsigned long) res->end, root->name, info->name,
+			max_root_bus_resources);
+		info->res_num++;
+		return AE_OK;
+	}
+
 	if (insert_resource(root, res)) {
 	if (insert_resource(root, res)) {
 		printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
 		printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
 			"from %s for %s\n", (unsigned long) res->start,
 			"from %s for %s\n", (unsigned long) res->start,
@@ -217,7 +238,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
 #endif
 #endif
 	}
 	}
 
 
-	if (bus && (pci_probe & PCI_USE__CRS))
+	if (bus && !(pci_probe & PCI_NO_ROOT_CRS))
 		get_current_resources(device, busnum, domain, bus);
 		get_current_resources(device, busnum, domain, bus);
 	return bus;
 	return bus;
 }
 }

+ 1 - 1
arch/x86/pci/amd_bus.c

@@ -101,7 +101,7 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b)
 	struct pci_root_info *info;
 	struct pci_root_info *info;
 
 
 	/* don't go for it if _CRS is used */
 	/* don't go for it if _CRS is used */
-	if (pci_probe & PCI_USE__CRS)
+	if (!(pci_probe & PCI_NO_ROOT_CRS))
 		return;
 		return;
 
 
 	/* if only one root bus, don't need to anything */
 	/* if only one root bus, don't need to anything */

+ 2 - 2
arch/x86/pci/common.c

@@ -515,8 +515,8 @@ char * __devinit  pcibios_setup(char *str)
 	} else if (!strcmp(str, "assign-busses")) {
 	} else if (!strcmp(str, "assign-busses")) {
 		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
 		return NULL;
 		return NULL;
-	} else if (!strcmp(str, "use_crs")) {
-		pci_probe |= PCI_USE__CRS;
+	} else if (!strcmp(str, "nocrs")) {
+		pci_probe |= PCI_NO_ROOT_CRS;
 		return NULL;
 		return NULL;
 	} else if (!strcmp(str, "earlydump")) {
 	} else if (!strcmp(str, "earlydump")) {
 		pci_early_dump_regs = 1;
 		pci_early_dump_regs = 1;

+ 1 - 0
drivers/acpi/Kconfig

@@ -266,6 +266,7 @@ config ACPI_DEBUG_FUNC_TRACE
 
 
 config ACPI_PCI_SLOT
 config ACPI_PCI_SLOT
 	tristate "PCI slot detection driver"
 	tristate "PCI slot detection driver"
+	depends on SYSFS
 	default n
 	default n
 	help
 	help
 	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
 	  This driver creates entries in /sys/bus/pci/slots/ for all PCI

+ 2 - 1
drivers/pci/Makefile

@@ -2,10 +2,11 @@
 # Makefile for the PCI bus specific drivers.
 # Makefile for the PCI bus specific drivers.
 #
 #
 
 
-obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o slot.o \
+obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
 			irq.o
 			irq.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_PROC_FS) += proc.o
+obj-$(CONFIG_SYSFS) += slot.o
 
 
 # Build PCI Express stuff if needed
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
 obj-$(CONFIG_PCIEPORTBUS) += pcie/

+ 19 - 0
drivers/pci/access.c

@@ -66,6 +66,25 @@ EXPORT_SYMBOL(pci_bus_write_config_byte);
 EXPORT_SYMBOL(pci_bus_write_config_word);
 EXPORT_SYMBOL(pci_bus_write_config_word);
 EXPORT_SYMBOL(pci_bus_write_config_dword);
 EXPORT_SYMBOL(pci_bus_write_config_dword);
 
 
+/**
+ * pci_bus_set_ops - Set raw operations of pci bus
+ * @bus:	pci bus struct
+ * @ops:	new raw operations
+ *
+ * Return previous raw operations
+ */
+struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops)
+{
+	struct pci_ops *old_ops;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pci_lock, flags);
+	old_ops = bus->ops;
+	bus->ops = ops;
+	spin_unlock_irqrestore(&pci_lock, flags);
+	return old_ops;
+}
+EXPORT_SYMBOL(pci_bus_set_ops);
 
 
 /**
 /**
  * pci_read_vpd - Read one entry from Vital Product Data
  * pci_read_vpd - Read one entry from Vital Product Data

+ 15 - 3
drivers/pci/bus.c

@@ -41,9 +41,14 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 		void *alignf_data)
 		void *alignf_data)
 {
 {
 	int i, ret = -ENOMEM;
 	int i, ret = -ENOMEM;
+	resource_size_t max = -1;
 
 
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 
 
+	/* don't allocate too high if the pref mem doesn't support 64bit*/
+	if (!(res->flags & IORESOURCE_MEM_64))
+		max = PCIBIOS_MAX_MEM_32;
+
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		struct resource *r = bus->resource[i];
 		struct resource *r = bus->resource[i];
 		if (!r)
 		if (!r)
@@ -62,7 +67,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 		/* Ok, try it out.. */
 		/* Ok, try it out.. */
 		ret = allocate_resource(r, res, size,
 		ret = allocate_resource(r, res, size,
 					r->start ? : min,
 					r->start ? : min,
-					-1, align,
+					max, align,
 					alignf, alignf_data);
 					alignf, alignf_data);
 		if (ret == 0)
 		if (ret == 0)
 			break;
 			break;
@@ -201,13 +206,18 @@ void pci_enable_bridges(struct pci_bus *bus)
  *  Walk the given bus, including any bridged devices
  *  Walk the given bus, including any bridged devices
  *  on buses under this bus.  Call the provided callback
  *  on buses under this bus.  Call the provided callback
  *  on each device found.
  *  on each device found.
+ *
+ *  We check the return of @cb each time. If it returns anything
+ *  other than 0, we break out.
+ *
  */
  */
-void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
 		  void *userdata)
 		  void *userdata)
 {
 {
 	struct pci_dev *dev;
 	struct pci_dev *dev;
 	struct pci_bus *bus;
 	struct pci_bus *bus;
 	struct list_head *next;
 	struct list_head *next;
+	int retval;
 
 
 	bus = top;
 	bus = top;
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
@@ -231,8 +241,10 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
 
 
 		/* Run device routines with the device locked */
 		/* Run device routines with the device locked */
 		down(&dev->dev.sem);
 		down(&dev->dev.sem);
-		cb(dev, userdata);
+		retval = cb(dev, userdata);
 		up(&dev->dev.sem);
 		up(&dev->dev.sem);
+		if (retval)
+			break;
 	}
 	}
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
 }
 }

+ 2 - 2
drivers/pci/hotplug/Kconfig

@@ -4,7 +4,7 @@
 
 
 menuconfig HOTPLUG_PCI
 menuconfig HOTPLUG_PCI
 	tristate "Support for PCI Hotplug"
 	tristate "Support for PCI Hotplug"
-	depends on PCI && HOTPLUG
+	depends on PCI && HOTPLUG && SYSFS
 	---help---
 	---help---
 	  Say Y here if you have a motherboard with a PCI Hotplug controller.
 	  Say Y here if you have a motherboard with a PCI Hotplug controller.
 	  This allows you to add and remove PCI cards while the machine is
 	  This allows you to add and remove PCI cards while the machine is
@@ -41,7 +41,7 @@ config HOTPLUG_PCI_FAKE
 
 
 config HOTPLUG_PCI_COMPAQ
 config HOTPLUG_PCI_COMPAQ
 	tristate "Compaq PCI Hotplug driver"
 	tristate "Compaq PCI Hotplug driver"
-	depends on X86 && PCI_BIOS && PCI_LEGACY
+	depends on X86 && PCI_BIOS
 	help
 	help
 	  Say Y here if you have a motherboard with a Compaq PCI Hotplug
 	  Say Y here if you have a motherboard with a Compaq PCI Hotplug
 	  controller.
 	  controller.

+ 0 - 1
drivers/pci/hotplug/acpiphp_core.c

@@ -77,7 +77,6 @@ static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 
 
 static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
 static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
-	.owner			= THIS_MODULE,
 	.enable_slot		= enable_slot,
 	.enable_slot		= enable_slot,
 	.disable_slot		= disable_slot,
 	.disable_slot		= disable_slot,
 	.set_attention_status	= set_attention_status,
 	.set_attention_status	= set_attention_status,

+ 0 - 1
drivers/pci/hotplug/cpci_hotplug_core.c

@@ -72,7 +72,6 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
 static int get_latch_status(struct hotplug_slot *slot, u8 * value);
 static int get_latch_status(struct hotplug_slot *slot, u8 * value);
 
 
 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
-	.owner = THIS_MODULE,
 	.enable_slot = enable_slot,
 	.enable_slot = enable_slot,
 	.disable_slot = disable_slot,
 	.disable_slot = disable_slot,
 	.set_attention_status = set_attention_status,
 	.set_attention_status = set_attention_status,

+ 95 - 72
drivers/pci/hotplug/cpqphp.h

@@ -150,25 +150,25 @@ struct ctrl_reg {			/* offset */
 
 
 /* offsets to the controller registers based on the above structure layout */
 /* offsets to the controller registers based on the above structure layout */
 enum ctrl_offsets {
 enum ctrl_offsets {
-	SLOT_RST = 		offsetof(struct ctrl_reg, slot_RST),
+	SLOT_RST =		offsetof(struct ctrl_reg, slot_RST),
 	SLOT_ENABLE =		offsetof(struct ctrl_reg, slot_enable),
 	SLOT_ENABLE =		offsetof(struct ctrl_reg, slot_enable),
 	MISC =			offsetof(struct ctrl_reg, misc),
 	MISC =			offsetof(struct ctrl_reg, misc),
 	LED_CONTROL =		offsetof(struct ctrl_reg, led_control),
 	LED_CONTROL =		offsetof(struct ctrl_reg, led_control),
 	INT_INPUT_CLEAR =	offsetof(struct ctrl_reg, int_input_clear),
 	INT_INPUT_CLEAR =	offsetof(struct ctrl_reg, int_input_clear),
-	INT_MASK = 		offsetof(struct ctrl_reg, int_mask),
-	CTRL_RESERVED0 = 	offsetof(struct ctrl_reg, reserved0),
+	INT_MASK =		offsetof(struct ctrl_reg, int_mask),
+	CTRL_RESERVED0 =	offsetof(struct ctrl_reg, reserved0),
 	CTRL_RESERVED1 =	offsetof(struct ctrl_reg, reserved1),
 	CTRL_RESERVED1 =	offsetof(struct ctrl_reg, reserved1),
 	CTRL_RESERVED2 =	offsetof(struct ctrl_reg, reserved1),
 	CTRL_RESERVED2 =	offsetof(struct ctrl_reg, reserved1),
-	GEN_OUTPUT_AB = 	offsetof(struct ctrl_reg, gen_output_AB),
-	NON_INT_INPUT = 	offsetof(struct ctrl_reg, non_int_input),
+	GEN_OUTPUT_AB =		offsetof(struct ctrl_reg, gen_output_AB),
+	NON_INT_INPUT =		offsetof(struct ctrl_reg, non_int_input),
 	CTRL_RESERVED3 =	offsetof(struct ctrl_reg, reserved3),
 	CTRL_RESERVED3 =	offsetof(struct ctrl_reg, reserved3),
 	CTRL_RESERVED4 =	offsetof(struct ctrl_reg, reserved4),
 	CTRL_RESERVED4 =	offsetof(struct ctrl_reg, reserved4),
 	CTRL_RESERVED5 =	offsetof(struct ctrl_reg, reserved5),
 	CTRL_RESERVED5 =	offsetof(struct ctrl_reg, reserved5),
 	CTRL_RESERVED6 =	offsetof(struct ctrl_reg, reserved6),
 	CTRL_RESERVED6 =	offsetof(struct ctrl_reg, reserved6),
 	CTRL_RESERVED7 =	offsetof(struct ctrl_reg, reserved7),
 	CTRL_RESERVED7 =	offsetof(struct ctrl_reg, reserved7),
 	CTRL_RESERVED8 =	offsetof(struct ctrl_reg, reserved8),
 	CTRL_RESERVED8 =	offsetof(struct ctrl_reg, reserved8),
-	SLOT_MASK = 		offsetof(struct ctrl_reg, slot_mask),
-	CTRL_RESERVED9 = 	offsetof(struct ctrl_reg, reserved9),
+	SLOT_MASK =		offsetof(struct ctrl_reg, slot_mask),
+	CTRL_RESERVED9 =	offsetof(struct ctrl_reg, reserved9),
 	CTRL_RESERVED10 =	offsetof(struct ctrl_reg, reserved10),
 	CTRL_RESERVED10 =	offsetof(struct ctrl_reg, reserved10),
 	CTRL_RESERVED11 =	offsetof(struct ctrl_reg, reserved11),
 	CTRL_RESERVED11 =	offsetof(struct ctrl_reg, reserved11),
 	SLOT_SERR =		offsetof(struct ctrl_reg, slot_SERR),
 	SLOT_SERR =		offsetof(struct ctrl_reg, slot_SERR),
@@ -190,7 +190,9 @@ struct hrt {
 	u32 reserved2;
 	u32 reserved2;
 } __attribute__ ((packed));
 } __attribute__ ((packed));
 
 
-/* offsets to the hotplug resource table registers based on the above structure layout */
+/* offsets to the hotplug resource table registers based on the above
+ * structure layout
+ */
 enum hrt_offsets {
 enum hrt_offsets {
 	SIG0 =			offsetof(struct hrt, sig0),
 	SIG0 =			offsetof(struct hrt, sig0),
 	SIG1 =			offsetof(struct hrt, sig1),
 	SIG1 =			offsetof(struct hrt, sig1),
@@ -217,18 +219,20 @@ struct slot_rt {
 	u16 pre_mem_length;
 	u16 pre_mem_length;
 } __attribute__ ((packed));
 } __attribute__ ((packed));
 
 
-/* offsets to the hotplug slot resource table registers based on the above structure layout */
+/* offsets to the hotplug slot resource table registers based on the above
+ * structure layout
+ */
 enum slot_rt_offsets {
 enum slot_rt_offsets {
 	DEV_FUNC =		offsetof(struct slot_rt, dev_func),
 	DEV_FUNC =		offsetof(struct slot_rt, dev_func),
-	PRIMARY_BUS = 		offsetof(struct slot_rt, primary_bus),
-	SECONDARY_BUS = 	offsetof(struct slot_rt, secondary_bus),
-	MAX_BUS = 		offsetof(struct slot_rt, max_bus),
-	IO_BASE = 		offsetof(struct slot_rt, io_base),
-	IO_LENGTH = 		offsetof(struct slot_rt, io_length),
-	MEM_BASE = 		offsetof(struct slot_rt, mem_base),
-	MEM_LENGTH = 		offsetof(struct slot_rt, mem_length),
-	PRE_MEM_BASE = 		offsetof(struct slot_rt, pre_mem_base),
-	PRE_MEM_LENGTH = 	offsetof(struct slot_rt, pre_mem_length),
+	PRIMARY_BUS =		offsetof(struct slot_rt, primary_bus),
+	SECONDARY_BUS =		offsetof(struct slot_rt, secondary_bus),
+	MAX_BUS =		offsetof(struct slot_rt, max_bus),
+	IO_BASE =		offsetof(struct slot_rt, io_base),
+	IO_LENGTH =		offsetof(struct slot_rt, io_length),
+	MEM_BASE =		offsetof(struct slot_rt, mem_base),
+	MEM_LENGTH =		offsetof(struct slot_rt, mem_length),
+	PRE_MEM_BASE =		offsetof(struct slot_rt, pre_mem_base),
+	PRE_MEM_LENGTH =	offsetof(struct slot_rt, pre_mem_length),
 };
 };
 
 
 struct pci_func {
 struct pci_func {
@@ -286,8 +290,8 @@ struct event_info {
 struct controller {
 struct controller {
 	struct controller *next;
 	struct controller *next;
 	u32 ctrl_int_comp;
 	u32 ctrl_int_comp;
-	struct mutex crit_sect;		/* critical section mutex */
-	void __iomem *hpc_reg;		/* cookie for our pci controller location */
+	struct mutex crit_sect;	/* critical section mutex */
+	void __iomem *hpc_reg;	/* cookie for our pci controller location */
 	struct pci_resource *mem_head;
 	struct pci_resource *mem_head;
 	struct pci_resource *p_mem_head;
 	struct pci_resource *p_mem_head;
 	struct pci_resource *io_head;
 	struct pci_resource *io_head;
@@ -299,7 +303,7 @@ struct controller {
 	u8 next_event;
 	u8 next_event;
 	u8 interrupt;
 	u8 interrupt;
 	u8 cfgspc_irq;
 	u8 cfgspc_irq;
-	u8 bus;				/* bus number for the pci hotplug controller */
+	u8 bus;			/* bus number for the pci hotplug controller */
 	u8 rev;
 	u8 rev;
 	u8 slot_device_offset;
 	u8 slot_device_offset;
 	u8 first_slot;
 	u8 first_slot;
@@ -401,46 +405,57 @@ struct resource_lists {
 
 
 
 
 /* debugfs functions for the hotplug controller info */
 /* debugfs functions for the hotplug controller info */
-extern void cpqhp_initialize_debugfs		(void);
-extern void cpqhp_shutdown_debugfs		(void);
-extern void cpqhp_create_debugfs_files		(struct controller *ctrl);
-extern void cpqhp_remove_debugfs_files		(struct controller *ctrl);
+extern void cpqhp_initialize_debugfs(void);
+extern void cpqhp_shutdown_debugfs(void);
+extern void cpqhp_create_debugfs_files(struct controller *ctrl);
+extern void cpqhp_remove_debugfs_files(struct controller *ctrl);
 
 
 /* controller functions */
 /* controller functions */
-extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
-extern irqreturn_t cpqhp_ctrl_intr		(int IRQ, void *data);
-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);
-extern struct pci_func *cpqhp_slot_find		(unsigned char bus, unsigned char device, unsigned char index);
-extern int	cpqhp_process_SI		(struct controller *ctrl, struct pci_func *func);
-extern int	cpqhp_process_SS		(struct controller *ctrl, struct pci_func *func);
-extern int	cpqhp_hardware_test		(struct controller *ctrl, int test_num);
+extern void cpqhp_pushbutton_thread(unsigned long event_pointer);
+extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data);
+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);
+extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device,
+					unsigned char index);
+extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func);
+extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);
+extern int cpqhp_hardware_test(struct controller *ctrl, int test_num);
 
 
 /* resource functions */
 /* resource functions */
 extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);
 extern int	cpqhp_resource_sort_and_combine	(struct pci_resource **head);
 
 
 /* pci functions */
 /* pci functions */
-extern int	cpqhp_set_irq			(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
-extern int	cpqhp_get_bus_dev		(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot);
-extern int	cpqhp_save_config		(struct controller *ctrl, int busnumber, int is_hot_plug);
-extern int	cpqhp_save_base_addr_length	(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_save_used_resources	(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_configure_board		(struct controller *ctrl, struct pci_func * func);
-extern int	cpqhp_save_slot_config		(struct controller *ctrl, struct pci_func * new_slot);
-extern int	cpqhp_valid_replace		(struct controller *ctrl, struct pci_func * func);
-extern void	cpqhp_destroy_board_resources	(struct pci_func * func);
-extern int	cpqhp_return_board_resources	(struct pci_func * func, struct resource_lists * resources);
-extern void	cpqhp_destroy_resource_list	(struct resource_lists * resources);
-extern int	cpqhp_configure_device		(struct controller* ctrl, struct pci_func* func);
-extern int	cpqhp_unconfigure_device	(struct pci_func* func);
+extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
+extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num,
+			     u8 slot);
+extern int cpqhp_save_config(struct controller *ctrl, int busnumber,
+			     int is_hot_plug);
+extern int cpqhp_save_base_addr_length(struct controller *ctrl,
+				       struct pci_func *func);
+extern int cpqhp_save_used_resources(struct controller *ctrl,
+				     struct pci_func *func);
+extern int cpqhp_configure_board(struct controller *ctrl,
+				 struct pci_func *func);
+extern int cpqhp_save_slot_config(struct controller *ctrl,
+				  struct pci_func *new_slot);
+extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func);
+extern void cpqhp_destroy_board_resources(struct pci_func *func);
+extern int cpqhp_return_board_resources	(struct pci_func *func,
+					 struct resource_lists *resources);
+extern void cpqhp_destroy_resource_list(struct resource_lists *resources);
+extern int cpqhp_configure_device(struct controller *ctrl,
+				  struct pci_func *func);
+extern int cpqhp_unconfigure_device(struct pci_func *func);
 
 
 /* Global variables */
 /* Global variables */
 extern int cpqhp_debug;
 extern int cpqhp_debug;
 extern int cpqhp_legacy_mode;
 extern int cpqhp_legacy_mode;
 extern struct controller *cpqhp_ctrl_list;
 extern struct controller *cpqhp_ctrl_list;
 extern struct pci_func *cpqhp_slot_list[256];
 extern struct pci_func *cpqhp_slot_list[256];
+extern struct irq_routing_table *cpqhp_routing_table;
 
 
 /* these can be gotten rid of, but for debugging they are purty */
 /* these can be gotten rid of, but for debugging they are purty */
 extern u8 cpqhp_nic_irq;
 extern u8 cpqhp_nic_irq;
@@ -449,7 +464,7 @@ extern u8 cpqhp_disk_irq;
 
 
 /* inline functions */
 /* inline functions */
 
 
-static inline char *slot_name(struct slot *slot)
+static inline const char *slot_name(struct slot *slot)
 {
 {
 	return hotplug_slot_name(slot->hotplug_slot);
 	return hotplug_slot_name(slot->hotplug_slot);
 }
 }
@@ -458,9 +473,9 @@ static inline char *slot_name(struct slot *slot)
  * return_resource
  * return_resource
  *
  *
  * Puts node back in the resource list pointed to by head
  * Puts node back in the resource list pointed to by head
- *
  */
  */
-static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
+static inline void return_resource(struct pci_resource **head,
+				   struct pci_resource *node)
 {
 {
 	if (!node || !head)
 	if (!node || !head)
 		return;
 		return;
@@ -471,7 +486,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour
 static inline void set_SOGO(struct controller *ctrl)
 static inline void set_SOGO(struct controller *ctrl)
 {
 {
 	u16 misc;
 	u16 misc;
-	
+
 	misc = readw(ctrl->hpc_reg + MISC);
 	misc = readw(ctrl->hpc_reg + MISC);
 	misc = (misc | 0x0001) & 0xFFFB;
 	misc = (misc | 0x0001) & 0xFFFB;
 	writew(misc, ctrl->hpc_reg + MISC);
 	writew(misc, ctrl->hpc_reg + MISC);
@@ -481,7 +496,7 @@ static inline void set_SOGO(struct controller *ctrl)
 static inline void amber_LED_on(struct controller *ctrl, u8 slot)
 static inline void amber_LED_on(struct controller *ctrl, u8 slot)
 {
 {
 	u32 led_control;
 	u32 led_control;
-	
+
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control |= (0x01010000L << slot);
 	led_control |= (0x01010000L << slot);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -491,7 +506,7 @@ static inline void amber_LED_on(struct controller *ctrl, u8 slot)
 static inline void amber_LED_off(struct controller *ctrl, u8 slot)
 static inline void amber_LED_off(struct controller *ctrl, u8 slot)
 {
 {
 	u32 led_control;
 	u32 led_control;
-	
+
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control &= ~(0x01010000L << slot);
 	led_control &= ~(0x01010000L << slot);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -504,7 +519,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot)
 
 
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control &= (0x01010000L << slot);
 	led_control &= (0x01010000L << slot);
-	
+
 	return led_control ? 1 : 0;
 	return led_control ? 1 : 0;
 }
 }
 
 
@@ -512,7 +527,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot)
 static inline void green_LED_on(struct controller *ctrl, u8 slot)
 static inline void green_LED_on(struct controller *ctrl, u8 slot)
 {
 {
 	u32 led_control;
 	u32 led_control;
-	
+
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control |= 0x0101L << slot;
 	led_control |= 0x0101L << slot;
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -521,7 +536,7 @@ static inline void green_LED_on(struct controller *ctrl, u8 slot)
 static inline void green_LED_off(struct controller *ctrl, u8 slot)
 static inline void green_LED_off(struct controller *ctrl, u8 slot)
 {
 {
 	u32 led_control;
 	u32 led_control;
-	
+
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control &= ~(0x0101L << slot);
 	led_control &= ~(0x0101L << slot);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
 	writel(led_control, ctrl->hpc_reg + LED_CONTROL);
@@ -531,7 +546,7 @@ static inline void green_LED_off(struct controller *ctrl, u8 slot)
 static inline void green_LED_blink(struct controller *ctrl, u8 slot)
 static inline void green_LED_blink(struct controller *ctrl, u8 slot)
 {
 {
 	u32 led_control;
 	u32 led_control;
-	
+
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control = readl(ctrl->hpc_reg + LED_CONTROL);
 	led_control &= ~(0x0101L << slot);
 	led_control &= ~(0x0101L << slot);
 	led_control |= (0x0001L << slot);
 	led_control |= (0x0001L << slot);
@@ -575,22 +590,21 @@ static inline u8 read_slot_enable(struct controller *ctrl)
 }
 }
 
 
 
 
-/*
+/**
  * get_controller_speed - find the current frequency/mode of controller.
  * get_controller_speed - find the current frequency/mode of controller.
  *
  *
  * @ctrl: controller to get frequency/mode for.
  * @ctrl: controller to get frequency/mode for.
  *
  *
  * Returns controller speed.
  * Returns controller speed.
- *
  */
  */
 static inline u8 get_controller_speed(struct controller *ctrl)
 static inline u8 get_controller_speed(struct controller *ctrl)
 {
 {
 	u8 curr_freq;
 	u8 curr_freq;
- 	u16 misc;
- 	
+	u16 misc;
+
 	if (ctrl->pcix_support) {
 	if (ctrl->pcix_support) {
 		curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
 		curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
-		if ((curr_freq & 0xB0) == 0xB0) 
+		if ((curr_freq & 0xB0) == 0xB0)
 			return PCI_SPEED_133MHz_PCIX;
 			return PCI_SPEED_133MHz_PCIX;
 		if ((curr_freq & 0xA0) == 0xA0)
 		if ((curr_freq & 0xA0) == 0xA0)
 			return PCI_SPEED_100MHz_PCIX;
 			return PCI_SPEED_100MHz_PCIX;
@@ -602,19 +616,18 @@ static inline u8 get_controller_speed(struct controller *ctrl)
 		return PCI_SPEED_33MHz;
 		return PCI_SPEED_33MHz;
 	}
 	}
 
 
- 	misc = readw(ctrl->hpc_reg + MISC);
- 	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
+	misc = readw(ctrl->hpc_reg + MISC);
+	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
 }
 }
- 
 
 
-/*
+
+/**
  * get_adapter_speed - find the max supported frequency/mode of adapter.
  * get_adapter_speed - find the max supported frequency/mode of adapter.
  *
  *
  * @ctrl: hotplug controller.
  * @ctrl: hotplug controller.
  * @hp_slot: hotplug slot where adapter is installed.
  * @hp_slot: hotplug slot where adapter is installed.
  *
  *
  * Returns adapter speed.
  * Returns adapter speed.
- *
  */
  */
 static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
 static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
 {
 {
@@ -672,7 +685,8 @@ static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
 }
 }
 
 
 
 
-static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slot)
+static inline int cpq_get_latch_status(struct controller *ctrl,
+				       struct slot *slot)
 {
 {
 	u32 status;
 	u32 status;
 	u8 hp_slot;
 	u8 hp_slot;
@@ -687,7 +701,8 @@ static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slo
 }
 }
 
 
 
 
-static inline int get_presence_status(struct controller *ctrl, struct slot *slot)
+static inline int get_presence_status(struct controller *ctrl,
+				      struct slot *slot)
 {
 {
 	int presence_save = 0;
 	int presence_save = 0;
 	u8 hp_slot;
 	u8 hp_slot;
@@ -696,7 +711,8 @@ static inline int get_presence_status(struct controller *ctrl, struct slot *slot
 	hp_slot = slot->device - ctrl->slot_device_offset;
 	hp_slot = slot->device - ctrl->slot_device_offset;
 
 
 	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
 	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-	presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02;
+	presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15))
+				>> hp_slot) & 0x02;
 
 
 	return presence_save;
 	return presence_save;
 }
 }
@@ -718,5 +734,12 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
 	return retval;
 	return retval;
 }
 }
 
 
-#endif
+#include <asm/pci_x86.h>
+static inline int cpqhp_routing_table_length(void)
+{
+	BUG_ON(cpqhp_routing_table == NULL);
+	return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
+		sizeof(struct irq_info));
+}
 
 
+#endif

+ 560 - 608
drivers/pci/hotplug/cpqphp_core.c

@@ -25,8 +25,7 @@
  * Send feedback to <greg@kroah.com>
  * Send feedback to <greg@kroah.com>
  *
  *
  * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support,
  * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support,
- * 			Torben Mathiasen <torben.mathiasen@hp.com>
- *
+ *			Torben Mathiasen <torben.mathiasen@hp.com>
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
@@ -45,7 +44,6 @@
 
 
 #include "cpqphp.h"
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
 #include "cpqphp_nvram.h"
-#include <asm/pci_x86.h>
 
 
 
 
 /* Global variables */
 /* Global variables */
@@ -53,6 +51,7 @@ int cpqhp_debug;
 int cpqhp_legacy_mode;
 int cpqhp_legacy_mode;
 struct controller *cpqhp_ctrl_list;	/* = NULL */
 struct controller *cpqhp_ctrl_list;	/* = NULL */
 struct pci_func *cpqhp_slot_list[256];
 struct pci_func *cpqhp_slot_list[256];
+struct irq_routing_table *cpqhp_routing_table;
 
 
 /* local variables */
 /* local variables */
 static void __iomem *smbios_table;
 static void __iomem *smbios_table;
@@ -78,33 +77,6 @@ MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
 
 
 #define CPQHPC_MODULE_MINOR 208
 #define CPQHPC_MODULE_MINOR 208
 
 
-static int one_time_init	(void);
-static int set_attention_status	(struct hotplug_slot *slot, u8 value);
-static int process_SI		(struct hotplug_slot *slot);
-static int process_SS		(struct hotplug_slot *slot);
-static int hardware_test	(struct hotplug_slot *slot, u32 value);
-static int get_power_status	(struct hotplug_slot *slot, u8 *value);
-static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
-static int get_latch_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 *slot, enum pci_bus_speed *value);
-static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
-
-static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
-	.set_attention_status =	set_attention_status,
-	.enable_slot =		process_SI,
-	.disable_slot =		process_SS,
-	.hardware_test =	hardware_test,
-	.get_power_status =	get_power_status,
-	.get_attention_status =	get_attention_status,
-	.get_latch_status =	get_latch_status,
-	.get_adapter_status =	get_adapter_status,
-  	.get_max_bus_speed =	get_max_bus_speed,
-  	.get_cur_bus_speed =	get_cur_bus_speed,
-};
-
-
 static inline int is_slot64bit(struct slot *slot)
 static inline int is_slot64bit(struct slot *slot)
 {
 {
 	return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
 	return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0;
@@ -144,7 +116,7 @@ static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *e
 			break;
 			break;
 		}
 		}
 	}
 	}
-	
+
 	if (!status)
 	if (!status)
 		fp = NULL;
 		fp = NULL;
 
 
@@ -171,7 +143,7 @@ static int init_SERR(struct controller * ctrl)
 	tempdword = ctrl->first_slot;
 	tempdword = ctrl->first_slot;
 
 
 	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
-	// Loop through slots
+	/* Loop through slots */
 	while (number_of_slots) {
 	while (number_of_slots) {
 		physical_slot = tempdword;
 		physical_slot = tempdword;
 		writeb(0, ctrl->hpc_reg + SLOT_SERR);
 		writeb(0, ctrl->hpc_reg + SLOT_SERR);
@@ -182,41 +154,42 @@ static int init_SERR(struct controller * ctrl)
 	return 0;
 	return 0;
 }
 }
 
 
-
-/* nice debugging output */
-static int pci_print_IRQ_route (void)
+static int init_cpqhp_routing_table(void)
 {
 {
-	struct irq_routing_table *routing_table;
 	int len;
 	int len;
-	int loop;
-
-	u8 tbus, tdevice, tslot;
 
 
-	routing_table = pcibios_get_irq_routing_table();
-	if (routing_table == NULL) {
-		err("No BIOS Routing Table??? Not good\n");
+	cpqhp_routing_table = pcibios_get_irq_routing_table();
+	if (cpqhp_routing_table == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
-	len = (routing_table->size - sizeof(struct irq_routing_table)) /
-			sizeof(struct irq_info);
-	// Make sure I got at least one entry
+	len = cpqhp_routing_table_length();
 	if (len == 0) {
 	if (len == 0) {
-		kfree(routing_table);
+		kfree(cpqhp_routing_table);
+		cpqhp_routing_table = NULL;
 		return -1;
 		return -1;
 	}
 	}
 
 
-	dbg("bus dev func slot\n");
+	return 0;
+}
 
 
+/* nice debugging output */
+static void pci_print_IRQ_route(void)
+{
+	int len;
+	int loop;
+	u8 tbus, tdevice, tslot;
+
+	len = cpqhp_routing_table_length();
+
+	dbg("bus dev func slot\n");
 	for (loop = 0; loop < len; ++loop) {
 	for (loop = 0; loop < len; ++loop) {
-		tbus = routing_table->slots[loop].bus;
-		tdevice = routing_table->slots[loop].devfn;
-		tslot = routing_table->slots[loop].slot;
+		tbus = cpqhp_routing_table->slots[loop].bus;
+		tdevice = cpqhp_routing_table->slots[loop].devfn;
+		tslot = cpqhp_routing_table->slots[loop].slot;
 		dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
 		dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
 
 
 	}
 	}
-	kfree(routing_table);
-	return 0;
+	return;
 }
 }
 
 
 
 
@@ -242,9 +215,9 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
 	void __iomem *p_max;
 	void __iomem *p_max;
 
 
 	if (!smbios_table || !curr)
 	if (!smbios_table || !curr)
-		return(NULL);
+		return NULL;
 
 
-	// set p_max to the end of the table
+	/* set p_max to the end of the table */
 	p_max = smbios_start + readw(smbios_table + ST_LENGTH);
 	p_max = smbios_start + readw(smbios_table + ST_LENGTH);
 
 
 	p_temp = curr;
 	p_temp = curr;
@@ -253,20 +226,19 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
 	while ((p_temp < p_max) && !bail) {
 	while ((p_temp < p_max) && !bail) {
 		/* Look for the double NULL terminator
 		/* Look for the double NULL terminator
 		 * The first condition is the previous byte
 		 * The first condition is the previous byte
-		 * and the second is the curr */
-		if (!previous_byte && !(readb(p_temp))) {
+		 * and the second is the curr
+		 */
+		if (!previous_byte && !(readb(p_temp)))
 			bail = 1;
 			bail = 1;
-		}
 
 
 		previous_byte = readb(p_temp);
 		previous_byte = readb(p_temp);
 		p_temp++;
 		p_temp++;
 	}
 	}
 
 
-	if (p_temp < p_max) {
+	if (p_temp < p_max)
 		return p_temp;
 		return p_temp;
-	} else {
+	else
 		return NULL;
 		return NULL;
-	}
 }
 }
 
 
 
 
@@ -292,21 +264,18 @@ static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
 	if (!smbios_table)
 	if (!smbios_table)
 		return NULL;
 		return NULL;
 
 
-	if (!previous) {		  
+	if (!previous)
 		previous = smbios_start;
 		previous = smbios_start;
-	} else {
+	else
 		previous = get_subsequent_smbios_entry(smbios_start,
 		previous = get_subsequent_smbios_entry(smbios_start,
 					smbios_table, previous);
 					smbios_table, previous);
-	}
 
 
-	while (previous) {
-	       	if (readb(previous + SMBIOS_GENERIC_TYPE) != type) {
+	while (previous)
+		if (readb(previous + SMBIOS_GENERIC_TYPE) != type)
 			previous = get_subsequent_smbios_entry(smbios_start,
 			previous = get_subsequent_smbios_entry(smbios_start,
 						smbios_table, previous);
 						smbios_table, previous);
-		} else {
+		else
 			break;
 			break;
-		}
-	}
 
 
 	return previous;
 	return previous;
 }
 }
@@ -322,144 +291,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 	kfree(slot);
 	kfree(slot);
 }
 }
 
 
-#define SLOT_NAME_SIZE 10
-
-static int ctrl_slot_setup(struct controller *ctrl,
-			void __iomem *smbios_start,
-			void __iomem *smbios_table)
-{
-	struct slot *slot;
-	struct hotplug_slot *hotplug_slot;
-	struct hotplug_slot_info *hotplug_slot_info;
-	u8 number_of_slots;
-	u8 slot_device;
-	u8 slot_number;
-	u8 ctrl_slot;
-	u32 tempdword;
-	char name[SLOT_NAME_SIZE];
-	void __iomem *slot_entry= NULL;
-	int result = -ENOMEM;
-
-	dbg("%s\n", __func__);
-
-	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
-
-	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
-	slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
-	slot_number = ctrl->first_slot;
-
-	while (number_of_slots) {
-		slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-		if (!slot)
-			goto error;
-
-		slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
-						GFP_KERNEL);
-		if (!slot->hotplug_slot)
-			goto error_slot;
-		hotplug_slot = slot->hotplug_slot;
-
-		hotplug_slot->info =
-				kzalloc(sizeof(*(hotplug_slot->info)),
-							GFP_KERNEL);
-		if (!hotplug_slot->info)
-			goto error_hpslot;
-		hotplug_slot_info = hotplug_slot->info;
-
-		slot->ctrl = ctrl;
-		slot->bus = ctrl->bus;
-		slot->device = slot_device;
-		slot->number = slot_number;
-		dbg("slot->number = %u\n", slot->number);
-
-		slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
-					slot_entry);
-
-		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
-				slot->number)) {
-			slot_entry = get_SMBIOS_entry(smbios_start,
-						smbios_table, 9, slot_entry);
-		}
-
-		slot->p_sm_slot = slot_entry;
-
-		init_timer(&slot->task_event);
-		slot->task_event.expires = jiffies + 5 * HZ;
-		slot->task_event.function = cpqhp_pushbutton_thread;
-
-		//FIXME: these capabilities aren't used but if they are
-		//       they need to be correctly implemented
-		slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
-		slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
-
-		if (is_slot64bit(slot))
-			slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
-		if (is_slot66mhz(slot))
-			slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
-		if (ctrl->speed == PCI_SPEED_66MHz)
-			slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
-
-		ctrl_slot =
-			slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
-
-		// Check presence
-		slot->capabilities |=
-			((((~tempdword) >> 23) |
-			 ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
-		// Check the switch state
-		slot->capabilities |=
-			((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
-		// Check the slot enable
-		slot->capabilities |=
-			((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
-
-		/* register this slot with the hotplug pci core */
-		hotplug_slot->release = &release_slot;
-		hotplug_slot->private = slot;
-		snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
-		hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
-
-		hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
-		hotplug_slot_info->attention_status =
-			cpq_get_attention_status(ctrl, slot);
-		hotplug_slot_info->latch_status =
-			cpq_get_latch_status(ctrl, slot);
-		hotplug_slot_info->adapter_status =
-			get_presence_status(ctrl, slot);
-		
-		dbg("registering bus %d, dev %d, number %d, "
-				"ctrl->slot_device_offset %d, slot %d\n",
-				slot->bus, slot->device,
-				slot->number, ctrl->slot_device_offset,
-				slot_number);
-		result = pci_hp_register(hotplug_slot,
-					 ctrl->pci_dev->bus,
-					 slot->device,
-					 name);
-		if (result) {
-			err("pci_hp_register failed with error %d\n", result);
-			goto error_info;
-		}
-		
-		slot->next = ctrl->slot;
-		ctrl->slot = slot;
-
-		number_of_slots--;
-		slot_device++;
-		slot_number++;
-	}
-
-	return 0;
-error_info:
-	kfree(hotplug_slot_info);
-error_hpslot:
-	kfree(hotplug_slot);
-error_slot:
-	kfree(slot);
-error:
-	return result;
-}
-
 static int ctrl_slot_cleanup (struct controller * ctrl)
 static int ctrl_slot_cleanup (struct controller * ctrl)
 {
 {
 	struct slot *old_slot, *next_slot;
 	struct slot *old_slot, *next_slot;
@@ -476,36 +307,32 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
 
 
 	cpqhp_remove_debugfs_files(ctrl);
 	cpqhp_remove_debugfs_files(ctrl);
 
 
-	//Free IRQ associated with hot plug device
+	/* Free IRQ associated with hot plug device */
 	free_irq(ctrl->interrupt, ctrl);
 	free_irq(ctrl->interrupt, ctrl);
-	//Unmap the memory
+	/* Unmap the memory */
 	iounmap(ctrl->hpc_reg);
 	iounmap(ctrl->hpc_reg);
-	//Finally reclaim PCI mem
+	/* Finally reclaim PCI mem */
 	release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
 	release_mem_region(pci_resource_start(ctrl->pci_dev, 0),
 			   pci_resource_len(ctrl->pci_dev, 0));
 			   pci_resource_len(ctrl->pci_dev, 0));
 
 
-	return(0);
+	return 0;
 }
 }
 
 
 
 
-//============================================================================
-// function:	get_slot_mapping
-//
-// Description: Attempts to determine a logical slot mapping for a PCI
-//		device.  Won't work for more than one PCI-PCI bridge
-//		in a slot.
-//
-// Input:	u8 bus_num - bus number of PCI device
-//		u8 dev_num - device number of PCI device
-//		u8 *slot - Pointer to u8 where slot number will
-//			be returned
-//
-// Output:	SUCCESS or FAILURE
-//=============================================================================
+/**
+ * get_slot_mapping - determine logical slot mapping for PCI device
+ *
+ * Won't work for more than one PCI-PCI bridge in a slot.
+ *
+ * @bus_num - bus number of PCI device
+ * @dev_num - device number of PCI device
+ * @slot - Pointer to u8 where slot number will	be returned
+ *
+ * Output:	SUCCESS or FAILURE
+ */
 static int
 static int
 get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
 get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
 {
 {
-	struct irq_routing_table *PCIIRQRoutingInfoLength;
 	u32 work;
 	u32 work;
 	long len;
 	long len;
 	long loop;
 	long loop;
@@ -516,36 +343,25 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
 
 
 	bridgeSlot = 0xFF;
 	bridgeSlot = 0xFF;
 
 
-	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
-	if (!PCIIRQRoutingInfoLength)
-		return -1;
-
-	len = (PCIIRQRoutingInfoLength->size -
-	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	// Make sure I got at least one entry
-	if (len == 0) {
-		kfree(PCIIRQRoutingInfoLength);
-		return -1;
-	}
-
+	len = cpqhp_routing_table_length();
 	for (loop = 0; loop < len; ++loop) {
 	for (loop = 0; loop < len; ++loop) {
-		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
-		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
-		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+		tbus = cpqhp_routing_table->slots[loop].bus;
+		tdevice = cpqhp_routing_table->slots[loop].devfn >> 3;
+		tslot = cpqhp_routing_table->slots[loop].slot;
 
 
 		if ((tbus == bus_num) && (tdevice == dev_num)) {
 		if ((tbus == bus_num) && (tdevice == dev_num)) {
 			*slot = tslot;
 			*slot = tslot;
-			kfree(PCIIRQRoutingInfoLength);
 			return 0;
 			return 0;
 		} else {
 		} else {
 			/* Did not get a match on the target PCI device. Check
 			/* Did not get a match on the target PCI device. Check
-			 * if the current IRQ table entry is a PCI-to-PCI bridge
-			 * device.  If so, and it's secondary bus matches the
-			 * bus number for the target device, I need to save the
-			 * bridge's slot number.  If I can not find an entry for
-			 * the target device, I will have to assume it's on the
-			 * other side of the bridge, and assign it the bridge's
-			 * slot. */
+			 * if the current IRQ table entry is a PCI-to-PCI
+			 * bridge device.  If so, and it's secondary bus
+			 * matches the bus number for the target device, I need
+			 * to save the bridge's slot number.  If I can not find
+			 * an entry for the target device, I will have to
+			 * assume it's on the other side of the bridge, and
+			 * assign it the bridge's slot.
+			 */
 			bus->number = tbus;
 			bus->number = tbus;
 			pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
 			pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0),
 						PCI_CLASS_REVISION, &work);
 						PCI_CLASS_REVISION, &work);
@@ -555,25 +371,23 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
 							PCI_DEVFN(tdevice, 0),
 							PCI_DEVFN(tdevice, 0),
 							PCI_PRIMARY_BUS, &work);
 							PCI_PRIMARY_BUS, &work);
 				// See if bridge's secondary bus matches target bus.
 				// See if bridge's secondary bus matches target bus.
-				if (((work >> 8) & 0x000000FF) == (long) bus_num) {
+				if (((work >> 8) & 0x000000FF) == (long) bus_num)
 					bridgeSlot = tslot;
 					bridgeSlot = tslot;
-				}
 			}
 			}
 		}
 		}
 
 
 	}
 	}
 
 
-	// If we got here, we didn't find an entry in the IRQ mapping table 
-	// for the target PCI device.  If we did determine that the target 
-	// device is on the other side of a PCI-to-PCI bridge, return the 
-	// slot number for the bridge.
+	/* If we got here, we didn't find an entry in the IRQ mapping table for
+	 * the target PCI device.  If we did determine that the target device
+	 * is on the other side of a PCI-to-PCI bridge, return the slot number
+	 * for the bridge.
+	 */
 	if (bridgeSlot != 0xFF) {
 	if (bridgeSlot != 0xFF) {
 		*slot = bridgeSlot;
 		*slot = bridgeSlot;
-		kfree(PCIIRQRoutingInfoLength);
 		return 0;
 		return 0;
 	}
 	}
-	kfree(PCIIRQRoutingInfoLength);
-	// Couldn't find an entry in the routing table for this PCI device
+	/* Couldn't find an entry in the routing table for this PCI device */
 	return -1;
 	return -1;
 }
 }
 
 
@@ -591,32 +405,32 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
 	u8 hp_slot;
 	u8 hp_slot;
 
 
 	if (func == NULL)
 	if (func == NULL)
-		return(1);
+		return 1;
 
 
 	hp_slot = func->device - ctrl->slot_device_offset;
 	hp_slot = func->device - ctrl->slot_device_offset;
 
 
-	// Wait for exclusive access to hardware
+	/* Wait for exclusive access to hardware */
 	mutex_lock(&ctrl->crit_sect);
 	mutex_lock(&ctrl->crit_sect);
 
 
-	if (status == 1) {
+	if (status == 1)
 		amber_LED_on (ctrl, hp_slot);
 		amber_LED_on (ctrl, hp_slot);
-	} else if (status == 0) {
+	else if (status == 0)
 		amber_LED_off (ctrl, hp_slot);
 		amber_LED_off (ctrl, hp_slot);
-	} else {
-		// Done with exclusive hardware access
+	else {
+		/* Done with exclusive hardware access */
 		mutex_unlock(&ctrl->crit_sect);
 		mutex_unlock(&ctrl->crit_sect);
-		return(1);
+		return 1;
 	}
 	}
 
 
 	set_SOGO(ctrl);
 	set_SOGO(ctrl);
 
 
-	// Wait for SOBS to be unset
+	/* Wait for SOBS to be unset */
 	wait_for_ctrl_irq (ctrl);
 	wait_for_ctrl_irq (ctrl);
 
 
-	// Done with exclusive hardware access
+	/* Done with exclusive hardware access */
 	mutex_unlock(&ctrl->crit_sect);
 	mutex_unlock(&ctrl->crit_sect);
 
 
-	return(0);
+	return 0;
 }
 }
 
 
 
 
@@ -719,7 +533,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value)
 
 
 	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
 
-	return cpqhp_hardware_test(ctrl, value);	
+	return cpqhp_hardware_test(ctrl, value);
 }
 }
 
 
 
 
@@ -738,7 +552,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
 {
 	struct slot *slot = hotplug_slot->private;
 	struct slot *slot = hotplug_slot->private;
 	struct controller *ctrl = slot->ctrl;
 	struct controller *ctrl = slot->ctrl;
-	
+
 	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 	dbg("%s - physical_slot = %s\n", __func__, slot_name(slot));
 
 
 	*value = cpq_get_attention_status(ctrl, slot);
 	*value = cpq_get_attention_status(ctrl, slot);
@@ -793,256 +607,474 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
 	return 0;
 	return 0;
 }
 }
 
 
-static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
+	.set_attention_status =	set_attention_status,
+	.enable_slot =		process_SI,
+	.disable_slot =		process_SS,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
+	.get_max_bus_speed =	get_max_bus_speed,
+	.get_cur_bus_speed =	get_cur_bus_speed,
+};
+
+#define SLOT_NAME_SIZE 10
+
+static int ctrl_slot_setup(struct controller *ctrl,
+			void __iomem *smbios_start,
+			void __iomem *smbios_table)
 {
 {
-	u8 num_of_slots = 0;
-	u8 hp_slot = 0;
-	u8 device;
-	u8 bus_cap;
-	u16 temp_word;
-	u16 vendor_id;
-	u16 subsystem_vid;
-	u16 subsystem_deviceid;
-	u32 rc;
-	struct controller *ctrl;
-	struct pci_func *func;
-	int err;
+	struct slot *slot;
+	struct hotplug_slot *hotplug_slot;
+	struct hotplug_slot_info *hotplug_slot_info;
+	u8 number_of_slots;
+	u8 slot_device;
+	u8 slot_number;
+	u8 ctrl_slot;
+	u32 tempdword;
+	char name[SLOT_NAME_SIZE];
+	void __iomem *slot_entry= NULL;
+	int result = -ENOMEM;
 
 
-	err = pci_enable_device(pdev);
-	if (err) {
-		printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
-			pci_name(pdev), err);
-		return err;
-	}
+	dbg("%s\n", __func__);
 
 
-	// Need to read VID early b/c it's used to differentiate CPQ and INTC discovery
-	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
-	if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
-		err(msg_HPC_non_compaq_or_intel);
-		rc = -ENODEV;
-		goto err_disable_device;
-	}
-	dbg("Vendor ID: %x\n", vendor_id);
+	tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
 
 
-	dbg("revision: %d\n", pdev->revision);
-	if ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!pdev->revision)) {
-		err(msg_HPC_rev_error);
-		rc = -ENODEV;
-		goto err_disable_device;
-	}
+	number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
+	slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
+	slot_number = ctrl->first_slot;
 
 
-	/* Check for the proper subsytem ID's
-	 * Intel uses a different SSID programming model than Compaq.  
-	 * For Intel, each SSID bit identifies a PHP capability.
-	 * Also Intel HPC's may have RID=0.
-	 */
-	if ((pdev->revision > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) {
-		// TODO: This code can be made to support non-Compaq or Intel subsystem IDs
-		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
-		if (rc) {
-			err("%s : pci_read_config_word failed\n", __func__);
-			goto err_disable_device;
-		}
-		dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
-		if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
-			err(msg_HPC_non_compaq_or_intel);
-			rc = -ENODEV;
-			goto err_disable_device;
-		}
+	while (number_of_slots) {
+		slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+		if (!slot)
+			goto error;
+
+		slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
+						GFP_KERNEL);
+		if (!slot->hotplug_slot)
+			goto error_slot;
+		hotplug_slot = slot->hotplug_slot;
 
 
-		ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
-		if (!ctrl) {
-			err("%s : out of memory\n", __func__);
-			rc = -ENOMEM;
-			goto err_disable_device;
+		hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)),
+							GFP_KERNEL);
+		if (!hotplug_slot->info)
+			goto error_hpslot;
+		hotplug_slot_info = hotplug_slot->info;
+
+		slot->ctrl = ctrl;
+		slot->bus = ctrl->bus;
+		slot->device = slot_device;
+		slot->number = slot_number;
+		dbg("slot->number = %u\n", slot->number);
+
+		slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
+					slot_entry);
+
+		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
+				slot->number)) {
+			slot_entry = get_SMBIOS_entry(smbios_start,
+						smbios_table, 9, slot_entry);
 		}
 		}
 
 
-		rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
-		if (rc) {
-			err("%s : pci_read_config_word failed\n", __func__);
-			goto err_free_ctrl;
+		slot->p_sm_slot = slot_entry;
+
+		init_timer(&slot->task_event);
+		slot->task_event.expires = jiffies + 5 * HZ;
+		slot->task_event.function = cpqhp_pushbutton_thread;
+
+		/*FIXME: these capabilities aren't used but if they are
+		 *	 they need to be correctly implemented
+		 */
+		slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
+		slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
+
+		if (is_slot64bit(slot))
+			slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
+		if (is_slot66mhz(slot))
+			slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
+		if (ctrl->speed == PCI_SPEED_66MHz)
+			slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
+
+		ctrl_slot =
+			slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
+
+		/* Check presence */
+		slot->capabilities |=
+			((((~tempdword) >> 23) |
+			 ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
+		/* Check the switch state */
+		slot->capabilities |=
+			((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
+		/* Check the slot enable */
+		slot->capabilities |=
+			((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
+
+		/* register this slot with the hotplug pci core */
+		hotplug_slot->release = &release_slot;
+		hotplug_slot->private = slot;
+		snprintf(name, SLOT_NAME_SIZE, "%u", slot->number);
+		hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
+
+		hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
+		hotplug_slot_info->attention_status =
+			cpq_get_attention_status(ctrl, slot);
+		hotplug_slot_info->latch_status =
+			cpq_get_latch_status(ctrl, slot);
+		hotplug_slot_info->adapter_status =
+			get_presence_status(ctrl, slot);
+
+		dbg("registering bus %d, dev %d, number %d, "
+				"ctrl->slot_device_offset %d, slot %d\n",
+				slot->bus, slot->device,
+				slot->number, ctrl->slot_device_offset,
+				slot_number);
+		result = pci_hp_register(hotplug_slot,
+					 ctrl->pci_dev->bus,
+					 slot->device,
+					 name);
+		if (result) {
+			err("pci_hp_register failed with error %d\n", result);
+			goto error_info;
 		}
 		}
 
 
-		info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
-
-		/* Set Vendor ID, so it can be accessed later from other functions */
-		ctrl->vendor_id = vendor_id;
-
-		switch (subsystem_vid) {
-			case PCI_VENDOR_ID_COMPAQ:
-				if (pdev->revision >= 0x13) { /* CIOBX */
-					ctrl->push_flag = 1;
-					ctrl->slot_switch_type = 1;
-					ctrl->push_button = 1;
-					ctrl->pci_config_space = 1;
-					ctrl->defeature_PHP = 1;
-					ctrl->pcix_support = 1;
-					ctrl->pcix_speed_capability = 1;
-					pci_read_config_byte(pdev, 0x41, &bus_cap);
-					if (bus_cap & 0x80) {
-						dbg("bus max supports 133MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 0x40) {
-						dbg("bus max supports 100MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 20) {
-						dbg("bus max supports 66MHz PCI-X\n");
-						ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
-						break;
-					}
-					if (bus_cap & 10) {
-						dbg("bus max supports 66MHz PCI\n");
-						ctrl->speed_capability = PCI_SPEED_66MHz;
-						break;
-					}
-
-					break;
-				}
-
-				switch (subsystem_deviceid) {
-					case PCI_SUB_HPC_ID:
-						/* Original 6500/7000 implementation */
-						ctrl->slot_switch_type = 1;
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 0;
-						ctrl->pci_config_space = 1;
-						ctrl->defeature_PHP = 1;
-						ctrl->pcix_support = 0;
-						ctrl->pcix_speed_capability = 0;
-						break;
-					case PCI_SUB_HPC_ID2:
-						/* First Pushbutton implementation */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 1;
-						ctrl->pci_config_space = 1;
-						ctrl->defeature_PHP = 1;
-						ctrl->pcix_support = 0;
-						ctrl->pcix_speed_capability = 0;
-						break;
-					case PCI_SUB_HPC_ID_INTC:
-						/* Third party (6500/7000) */
-						ctrl->slot_switch_type = 1;
-						ctrl->speed_capability = PCI_SPEED_33MHz;
-						ctrl->push_button = 0;
-						ctrl->pci_config_space = 1;
-						ctrl->defeature_PHP = 1;
-						ctrl->pcix_support = 0;
-						ctrl->pcix_speed_capability = 0;
-						break;
-					case PCI_SUB_HPC_ID3:
-						/* First 66 Mhz implementation */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;
-						ctrl->speed_capability = PCI_SPEED_66MHz;
-						ctrl->push_button = 1;
-						ctrl->pci_config_space = 1;
-						ctrl->defeature_PHP = 1;
-						ctrl->pcix_support = 0;
-						ctrl->pcix_speed_capability = 0;
-						break;
-					case PCI_SUB_HPC_ID4:
-						/* First PCI-X implementation, 100MHz */
-						ctrl->push_flag = 1;
-						ctrl->slot_switch_type = 1;
-						ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
-						ctrl->push_button = 1;
-						ctrl->pci_config_space = 1;
-						ctrl->defeature_PHP = 1;
-						ctrl->pcix_support = 1;
-						ctrl->pcix_speed_capability = 0;	
-						break;
-					default:
-						err(msg_HPC_not_supported);
-						rc = -ENODEV;
-						goto err_free_ctrl;
-				}
-				break;
+		slot->next = ctrl->slot;
+		ctrl->slot = slot;
+
+		number_of_slots--;
+		slot_device++;
+		slot_number++;
+	}
+
+	return 0;
+error_info:
+	kfree(hotplug_slot_info);
+error_hpslot:
+	kfree(hotplug_slot);
+error_slot:
+	kfree(slot);
+error:
+	return result;
+}
+
+static int one_time_init(void)
+{
+	int loop;
+	int retval = 0;
+
+	if (initialized)
+		return 0;
+
+	power_mode = 0;
+
+	retval = init_cpqhp_routing_table();
+	if (retval)
+		goto error;
+
+	if (cpqhp_debug)
+		pci_print_IRQ_route();
+
+	dbg("Initialize + Start the notification mechanism \n");
+
+	retval = cpqhp_event_start_thread();
+	if (retval)
+		goto error;
+
+	dbg("Initialize slot lists\n");
+	for (loop = 0; loop < 256; loop++)
+		cpqhp_slot_list[loop] = NULL;
+
+	/* FIXME: We also need to hook the NMI handler eventually.
+	 * this also needs to be worked with Christoph
+	 * register_NMI_handler();
+	 */
+	/* Map rom address */
+	cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
+	if (!cpqhp_rom_start) {
+		err ("Could not ioremap memory region for ROM\n");
+		retval = -EIO;
+		goto error;
+	}
+
+	/* Now, map the int15 entry point if we are on compaq specific
+	 * hardware
+	 */
+	compaq_nvram_init(cpqhp_rom_start);
+
+	/* Map smbios table entry point structure */
+	smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
+					cpqhp_rom_start + ROM_PHY_LEN);
+	if (!smbios_table) {
+		err ("Could not find the SMBIOS pointer in memory\n");
+		retval = -EIO;
+		goto error_rom_start;
+	}
+
+	smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
+					readw(smbios_table + ST_LENGTH));
+	if (!smbios_start) {
+		err ("Could not ioremap memory region taken from SMBIOS values\n");
+		retval = -EIO;
+		goto error_smbios_start;
+	}
+
+	initialized = 1;
+
+	return retval;
+
+error_smbios_start:
+	iounmap(smbios_start);
+error_rom_start:
+	iounmap(cpqhp_rom_start);
+error:
+	return retval;
+}
+
+static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	u8 num_of_slots = 0;
+	u8 hp_slot = 0;
+	u8 device;
+	u8 bus_cap;
+	u16 temp_word;
+	u16 vendor_id;
+	u16 subsystem_vid;
+	u16 subsystem_deviceid;
+	u32 rc;
+	struct controller *ctrl;
+	struct pci_func *func;
+	int err;
 
 
-			case PCI_VENDOR_ID_INTEL:
-				/* Check for speed capability (0=33, 1=66) */
-				if (subsystem_deviceid & 0x0001) {
-					ctrl->speed_capability = PCI_SPEED_66MHz;
-				} else {
-					ctrl->speed_capability = PCI_SPEED_33MHz;
-				}
-
-				/* Check for push button */
-				if (subsystem_deviceid & 0x0002) {
-					/* no push button */
-					ctrl->push_button = 0;
-				} else {
-					/* push button supported */
-					ctrl->push_button = 1;
-				}
-
-				/* Check for slot switch type (0=mechanical, 1=not mechanical) */
-				if (subsystem_deviceid & 0x0004) {
-					/* no switch */
-					ctrl->slot_switch_type = 0;
-				} else {
-					/* switch */
-					ctrl->slot_switch_type = 1;
-				}
-
-				/* PHP Status (0=De-feature PHP, 1=Normal operation) */
-				if (subsystem_deviceid & 0x0008) {
-					ctrl->defeature_PHP = 1;	// PHP supported
-				} else {
-					ctrl->defeature_PHP = 0;	// PHP not supported
-				}
-
-				/* Alternate Base Address Register Interface (0=not supported, 1=supported) */
-				if (subsystem_deviceid & 0x0010) {
-					ctrl->alternate_base_address = 1;	// supported
-				} else {
-					ctrl->alternate_base_address = 0;	// not supported
-				}
-
-				/* PCI Config Space Index (0=not supported, 1=supported) */
-				if (subsystem_deviceid & 0x0020) {
-					ctrl->pci_config_space = 1;		// supported
-				} else {
-					ctrl->pci_config_space = 0;		// not supported
-				}
-
-				/* PCI-X support */
-				if (subsystem_deviceid & 0x0080) {
-					/* PCI-X capable */
-					ctrl->pcix_support = 1;
-					/* Frequency of operation in PCI-X mode */
-					if (subsystem_deviceid & 0x0040) {
-						/* 133MHz PCI-X if bit 7 is 1 */
-						ctrl->pcix_speed_capability = 1;
-					} else {
-						/* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
-						/* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
-						ctrl->pcix_speed_capability = 0;
-					}
-				} else {
-					/* Conventional PCI */
-					ctrl->pcix_support = 0;
-					ctrl->pcix_speed_capability = 0;
-				}
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR MY_NAME ": cannot enable PCI device %s (%d)\n",
+			pci_name(pdev), err);
+		return err;
+	}
+
+	/* Need to read VID early b/c it's used to differentiate CPQ and INTC
+	 * discovery
+	 */
+	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
+	if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) {
+		err(msg_HPC_non_compaq_or_intel);
+		rc = -ENODEV;
+		goto err_disable_device;
+	}
+	dbg("Vendor ID: %x\n", vendor_id);
+
+	dbg("revision: %d\n", pdev->revision);
+	if ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!pdev->revision)) {
+		err(msg_HPC_rev_error);
+		rc = -ENODEV;
+		goto err_disable_device;
+	}
+
+	/* Check for the proper subsytem ID's
+	 * Intel uses a different SSID programming model than Compaq.
+	 * For Intel, each SSID bit identifies a PHP capability.
+	 * Also Intel HPC's may have RID=0.
+	 */
+	if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) {
+		err(msg_HPC_not_supported);
+		return -ENODEV;
+	}
+
+	/* TODO: This code can be made to support non-Compaq or Intel
+	 * subsystem IDs
+	 */
+	rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
+	if (rc) {
+		err("%s : pci_read_config_word failed\n", __func__);
+		goto err_disable_device;
+	}
+	dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
+	if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) {
+		err(msg_HPC_non_compaq_or_intel);
+		rc = -ENODEV;
+		goto err_disable_device;
+	}
+
+	ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
+	if (!ctrl) {
+		err("%s : out of memory\n", __func__);
+		rc = -ENOMEM;
+		goto err_disable_device;
+	}
+
+	rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
+	if (rc) {
+		err("%s : pci_read_config_word failed\n", __func__);
+		goto err_free_ctrl;
+	}
+
+	info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid);
+
+	/* Set Vendor ID, so it can be accessed later from other
+	 * functions
+	 */
+	ctrl->vendor_id = vendor_id;
+
+	switch (subsystem_vid) {
+	case PCI_VENDOR_ID_COMPAQ:
+		if (pdev->revision >= 0x13) { /* CIOBX */
+			ctrl->push_flag = 1;
+			ctrl->slot_switch_type = 1;
+			ctrl->push_button = 1;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 1;
+			ctrl->pcix_speed_capability = 1;
+			pci_read_config_byte(pdev, 0x41, &bus_cap);
+			if (bus_cap & 0x80) {
+				dbg("bus max supports 133MHz PCI-X\n");
+				ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
+				break;
+			}
+			if (bus_cap & 0x40) {
+				dbg("bus max supports 100MHz PCI-X\n");
+				ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+				break;
+			}
+			if (bus_cap & 20) {
+				dbg("bus max supports 66MHz PCI-X\n");
+				ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
 				break;
 				break;
+			}
+			if (bus_cap & 10) {
+				dbg("bus max supports 66MHz PCI\n");
+				ctrl->speed_capability = PCI_SPEED_66MHz;
+				break;
+			}
 
 
-			default:
-				err(msg_HPC_not_supported);
-				rc = -ENODEV;
-				goto err_free_ctrl;
+			break;
 		}
 		}
 
 
-	} else {
+		switch (subsystem_deviceid) {
+		case PCI_SUB_HPC_ID:
+			/* Original 6500/7000 implementation */
+			ctrl->slot_switch_type = 1;
+			ctrl->speed_capability = PCI_SPEED_33MHz;
+			ctrl->push_button = 0;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 0;
+			ctrl->pcix_speed_capability = 0;
+			break;
+		case PCI_SUB_HPC_ID2:
+			/* First Pushbutton implementation */
+			ctrl->push_flag = 1;
+			ctrl->slot_switch_type = 1;
+			ctrl->speed_capability = PCI_SPEED_33MHz;
+			ctrl->push_button = 1;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 0;
+			ctrl->pcix_speed_capability = 0;
+			break;
+		case PCI_SUB_HPC_ID_INTC:
+			/* Third party (6500/7000) */
+			ctrl->slot_switch_type = 1;
+			ctrl->speed_capability = PCI_SPEED_33MHz;
+			ctrl->push_button = 0;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 0;
+			ctrl->pcix_speed_capability = 0;
+			break;
+		case PCI_SUB_HPC_ID3:
+			/* First 66 Mhz implementation */
+			ctrl->push_flag = 1;
+			ctrl->slot_switch_type = 1;
+			ctrl->speed_capability = PCI_SPEED_66MHz;
+			ctrl->push_button = 1;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 0;
+			ctrl->pcix_speed_capability = 0;
+			break;
+		case PCI_SUB_HPC_ID4:
+			/* First PCI-X implementation, 100MHz */
+			ctrl->push_flag = 1;
+			ctrl->slot_switch_type = 1;
+			ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
+			ctrl->push_button = 1;
+			ctrl->pci_config_space = 1;
+			ctrl->defeature_PHP = 1;
+			ctrl->pcix_support = 1;
+			ctrl->pcix_speed_capability = 0;
+			break;
+		default:
+			err(msg_HPC_not_supported);
+			rc = -ENODEV;
+			goto err_free_ctrl;
+		}
+		break;
+
+	case PCI_VENDOR_ID_INTEL:
+		/* Check for speed capability (0=33, 1=66) */
+		if (subsystem_deviceid & 0x0001)
+			ctrl->speed_capability = PCI_SPEED_66MHz;
+		else
+			ctrl->speed_capability = PCI_SPEED_33MHz;
+
+		/* Check for push button */
+		if (subsystem_deviceid & 0x0002)
+			ctrl->push_button = 0;
+		else
+			ctrl->push_button = 1;
+
+		/* Check for slot switch type (0=mechanical, 1=not mechanical) */
+		if (subsystem_deviceid & 0x0004)
+			ctrl->slot_switch_type = 0;
+		else
+			ctrl->slot_switch_type = 1;
+
+		/* PHP Status (0=De-feature PHP, 1=Normal operation) */
+		if (subsystem_deviceid & 0x0008)
+			ctrl->defeature_PHP = 1;	/* PHP supported */
+		else
+			ctrl->defeature_PHP = 0;	/* PHP not supported */
+
+		/* Alternate Base Address Register Interface
+		 * (0=not supported, 1=supported)
+		 */
+		if (subsystem_deviceid & 0x0010)
+			ctrl->alternate_base_address = 1;
+		else
+			ctrl->alternate_base_address = 0;
+
+		/* PCI Config Space Index (0=not supported, 1=supported) */
+		if (subsystem_deviceid & 0x0020)
+			ctrl->pci_config_space = 1;
+		else
+			ctrl->pci_config_space = 0;
+
+		/* PCI-X support */
+		if (subsystem_deviceid & 0x0080) {
+			ctrl->pcix_support = 1;
+			if (subsystem_deviceid & 0x0040)
+				/* 133MHz PCI-X if bit 7 is 1 */
+				ctrl->pcix_speed_capability = 1;
+			else
+				/* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */
+				/* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */
+				ctrl->pcix_speed_capability = 0;
+		} else {
+			/* Conventional PCI */
+			ctrl->pcix_support = 0;
+			ctrl->pcix_speed_capability = 0;
+		}
+		break;
+
+	default:
 		err(msg_HPC_not_supported);
 		err(msg_HPC_not_supported);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto err_free_ctrl;
 	}
 	}
 
 
-	// Tell the user that we found one.
+	/* Tell the user that we found one. */
 	info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
 	info("Initializing the PCI hot plug controller residing on PCI bus %d\n",
 					pdev->bus->number);
 					pdev->bus->number);
 
 
@@ -1087,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc) {
 	if (rc) {
 		goto err_free_bus;
 		goto err_free_bus;
 	}
 	}
-	
+
 	dbg("pdev = %p\n", pdev);
 	dbg("pdev = %p\n", pdev);
 	dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0));
 	dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0));
 	dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0));
 	dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0));
@@ -1109,7 +1141,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_free_mem_region;
 		goto err_free_mem_region;
 	}
 	}
 
 
-	// Check for 66Mhz operation
+	/* Check for 66Mhz operation */
 	ctrl->speed = get_controller_speed(ctrl);
 	ctrl->speed = get_controller_speed(ctrl);
 
 
 
 
@@ -1120,7 +1152,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 *
 	 *
 	 ********************************************************/
 	 ********************************************************/
 
 
-	// find the physical slot number of the first hot plug slot
+	/* find the physical slot number of the first hot plug slot */
 
 
 	/* Get slot won't work for devices behind bridges, but
 	/* Get slot won't work for devices behind bridges, but
 	 * in this case it will always be called for the "base"
 	 * in this case it will always be called for the "base"
@@ -1137,7 +1169,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_iounmap;
 		goto err_iounmap;
 	}
 	}
 
 
-	// Store PCI Config Space for all devices on this bus
+	/* Store PCI Config Space for all devices on this bus */
 	rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
 	rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
 	if (rc) {
 	if (rc) {
 		err("%s: unable to save PCI configuration data, error %d\n",
 		err("%s: unable to save PCI configuration data, error %d\n",
@@ -1148,7 +1180,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/*
 	/*
 	 * Get IO, memory, and IRQ resources for new devices
 	 * Get IO, memory, and IRQ resources for new devices
 	 */
 	 */
-	// The next line is required for cpqhp_find_available_resources
+	/* The next line is required for cpqhp_find_available_resources */
 	ctrl->interrupt = pdev->irq;
 	ctrl->interrupt = pdev->irq;
 	if (ctrl->interrupt < 0x10) {
 	if (ctrl->interrupt < 0x10) {
 		cpqhp_legacy_mode = 1;
 		cpqhp_legacy_mode = 1;
@@ -1182,7 +1214,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			__func__, rc);
 			__func__, rc);
 		goto err_iounmap;
 		goto err_iounmap;
 	}
 	}
-	
+
 	/* Mask all general input interrupts */
 	/* Mask all general input interrupts */
 	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
 	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
 
 
@@ -1196,12 +1228,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_iounmap;
 		goto err_iounmap;
 	}
 	}
 
 
-	/* Enable Shift Out interrupt and clear it, also enable SERR on power fault */
+	/* Enable Shift Out interrupt and clear it, also enable SERR on power
+	 * fault
+	 */
 	temp_word = readw(ctrl->hpc_reg + MISC);
 	temp_word = readw(ctrl->hpc_reg + MISC);
 	temp_word |= 0x4006;
 	temp_word |= 0x4006;
 	writew(temp_word, ctrl->hpc_reg + MISC);
 	writew(temp_word, ctrl->hpc_reg + MISC);
 
 
-	// Changed 05/05/97 to clear all interrupts at start
+	/* Changed 05/05/97 to clear all interrupts at start */
 	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
 	writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR);
 
 
 	ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
 	ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
@@ -1216,13 +1250,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		cpqhp_ctrl_list = ctrl;
 		cpqhp_ctrl_list = ctrl;
 	}
 	}
 
 
-	// turn off empty slots here unless command line option "ON" set
-	// Wait for exclusive access to hardware
+	/* turn off empty slots here unless command line option "ON" set
+	 * Wait for exclusive access to hardware
+	 */
 	mutex_lock(&ctrl->crit_sect);
 	mutex_lock(&ctrl->crit_sect);
 
 
 	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 
 
-	// find first device number for the ctrl
+	/* find first device number for the ctrl */
 	device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
 	device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4;
 
 
 	while (num_of_slots) {
 	while (num_of_slots) {
@@ -1234,23 +1269,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		hp_slot = func->device - ctrl->slot_device_offset;
 		hp_slot = func->device - ctrl->slot_device_offset;
 		dbg("hp_slot: %d\n", hp_slot);
 		dbg("hp_slot: %d\n", hp_slot);
 
 
-		// We have to save the presence info for these slots
+		/* We have to save the presence info for these slots */
 		temp_word = ctrl->ctrl_int_comp >> 16;
 		temp_word = ctrl->ctrl_int_comp >> 16;
 		func->presence_save = (temp_word >> hp_slot) & 0x01;
 		func->presence_save = (temp_word >> hp_slot) & 0x01;
 		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
 		func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
 
 
-		if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
+		if (ctrl->ctrl_int_comp & (0x1L << hp_slot))
 			func->switch_save = 0;
 			func->switch_save = 0;
-		} else {
+		else
 			func->switch_save = 0x10;
 			func->switch_save = 0x10;
-		}
 
 
-		if (!power_mode) {
+		if (!power_mode)
 			if (!func->is_a_board) {
 			if (!func->is_a_board) {
 				green_LED_off(ctrl, hp_slot);
 				green_LED_off(ctrl, hp_slot);
 				slot_disable(ctrl, hp_slot);
 				slot_disable(ctrl, hp_slot);
 			}
 			}
-		}
 
 
 		device++;
 		device++;
 		num_of_slots--;
 		num_of_slots--;
@@ -1258,7 +1291,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 
 	if (!power_mode) {
 	if (!power_mode) {
 		set_SOGO(ctrl);
 		set_SOGO(ctrl);
-		// Wait for SOBS to be unset
+		/* Wait for SOBS to be unset */
 		wait_for_ctrl_irq(ctrl);
 		wait_for_ctrl_irq(ctrl);
 	}
 	}
 
 
@@ -1269,7 +1302,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_free_irq;
 		goto err_free_irq;
 	}
 	}
 
 
-	// Done with exclusive hardware access
+	/* Done with exclusive hardware access */
 	mutex_unlock(&ctrl->crit_sect);
 	mutex_unlock(&ctrl->crit_sect);
 
 
 	cpqhp_create_debugfs_files(ctrl);
 	cpqhp_create_debugfs_files(ctrl);
@@ -1291,77 +1324,6 @@ err_disable_device:
 	return rc;
 	return rc;
 }
 }
 
 
-
-static int one_time_init(void)
-{
-	int loop;
-	int retval = 0;
-
-	if (initialized)
-		return 0;
-
-	power_mode = 0;
-
-	retval = pci_print_IRQ_route();
-	if (retval)
-		goto error;
-
-	dbg("Initialize + Start the notification mechanism \n");
-
-	retval = cpqhp_event_start_thread();
-	if (retval)
-		goto error;
-
-	dbg("Initialize slot lists\n");
-	for (loop = 0; loop < 256; loop++) {
-		cpqhp_slot_list[loop] = NULL;
-	}
-
-	// FIXME: We also need to hook the NMI handler eventually.
-	// this also needs to be worked with Christoph
-	// register_NMI_handler();
-
-	// Map rom address
-	cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN);
-	if (!cpqhp_rom_start) {
-		err ("Could not ioremap memory region for ROM\n");
-		retval = -EIO;
-		goto error;
-	}
-	
-	/* Now, map the int15 entry point if we are on compaq specific hardware */
-	compaq_nvram_init(cpqhp_rom_start);
-	
-	/* Map smbios table entry point structure */
-	smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start,
-					cpqhp_rom_start + ROM_PHY_LEN);
-	if (!smbios_table) {
-		err ("Could not find the SMBIOS pointer in memory\n");
-		retval = -EIO;
-		goto error_rom_start;
-	}
-
-	smbios_start = ioremap(readl(smbios_table + ST_ADDRESS),
-					readw(smbios_table + ST_LENGTH));
-	if (!smbios_start) {
-		err ("Could not ioremap memory region taken from SMBIOS values\n");
-		retval = -EIO;
-		goto error_smbios_start;
-	}
-
-	initialized = 1;
-
-	return retval;
-
-error_smbios_start:
-	iounmap(smbios_start);
-error_rom_start:
-	iounmap(cpqhp_rom_start);
-error:
-	return retval;
-}
-
-
 static void __exit unload_cpqphpd(void)
 static void __exit unload_cpqphpd(void)
 {
 {
 	struct pci_func *next;
 	struct pci_func *next;
@@ -1381,10 +1343,10 @@ static void __exit unload_cpqphpd(void)
 		if (ctrl->hpc_reg) {
 		if (ctrl->hpc_reg) {
 			u16 misc;
 			u16 misc;
 			rc = read_slot_enable (ctrl);
 			rc = read_slot_enable (ctrl);
-			
+
 			writeb(0, ctrl->hpc_reg + SLOT_SERR);
 			writeb(0, ctrl->hpc_reg + SLOT_SERR);
 			writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
 			writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK);
-			
+
 			misc = readw(ctrl->hpc_reg + MISC);
 			misc = readw(ctrl->hpc_reg + MISC);
 			misc &= 0xFFFD;
 			misc &= 0xFFFD;
 			writew(misc, ctrl->hpc_reg + MISC);
 			writew(misc, ctrl->hpc_reg + MISC);
@@ -1464,38 +1426,34 @@ static void __exit unload_cpqphpd(void)
 		}
 		}
 	}
 	}
 
 
-	// Stop the notification mechanism
+	/* Stop the notification mechanism */
 	if (initialized)
 	if (initialized)
 		cpqhp_event_stop_thread();
 		cpqhp_event_stop_thread();
 
 
-	//unmap the rom address
+	/* unmap the rom address */
 	if (cpqhp_rom_start)
 	if (cpqhp_rom_start)
 		iounmap(cpqhp_rom_start);
 		iounmap(cpqhp_rom_start);
 	if (smbios_start)
 	if (smbios_start)
 		iounmap(smbios_start);
 		iounmap(smbios_start);
 }
 }
 
 
-
-
 static struct pci_device_id hpcd_pci_tbl[] = {
 static struct pci_device_id hpcd_pci_tbl[] = {
 	{
 	{
 	/* handle any PCI Hotplug controller */
 	/* handle any PCI Hotplug controller */
 	.class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
 	.class =        ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
 	.class_mask =   ~0,
 	.class_mask =   ~0,
-	
+
 	/* no matter who makes it */
 	/* no matter who makes it */
 	.vendor =       PCI_ANY_ID,
 	.vendor =       PCI_ANY_ID,
 	.device =       PCI_ANY_ID,
 	.device =       PCI_ANY_ID,
 	.subvendor =    PCI_ANY_ID,
 	.subvendor =    PCI_ANY_ID,
 	.subdevice =    PCI_ANY_ID,
 	.subdevice =    PCI_ANY_ID,
-	
+
 	}, { /* end: all zeroes */ }
 	}, { /* end: all zeroes */ }
 };
 };
 
 
 MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
 MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl);
 
 
-
-
 static struct pci_driver cpqhpc_driver = {
 static struct pci_driver cpqhpc_driver = {
 	.name =		"compaq_pci_hotplug",
 	.name =		"compaq_pci_hotplug",
 	.id_table =	hpcd_pci_tbl,
 	.id_table =	hpcd_pci_tbl,
@@ -1503,8 +1461,6 @@ static struct pci_driver cpqhpc_driver = {
 	/* remove:	cpqhpc_remove_one, */
 	/* remove:	cpqhpc_remove_one, */
 };
 };
 
 
-
-
 static int __init cpqhpc_init(void)
 static int __init cpqhpc_init(void)
 {
 {
 	int result;
 	int result;
@@ -1518,7 +1474,6 @@ static int __init cpqhpc_init(void)
 	return result;
 	return result;
 }
 }
 
 
-
 static void __exit cpqhpc_cleanup(void)
 static void __exit cpqhpc_cleanup(void)
 {
 {
 	dbg("unload_cpqphpd()\n");
 	dbg("unload_cpqphpd()\n");
@@ -1529,8 +1484,5 @@ static void __exit cpqhpc_cleanup(void)
 	cpqhp_shutdown_debugfs();
 	cpqhp_shutdown_debugfs();
 }
 }
 
 
-
 module_init(cpqhpc_init);
 module_init(cpqhpc_init);
 module_exit(cpqhpc_cleanup);
 module_exit(cpqhpc_cleanup);
-
-

+ 191 - 180
drivers/pci/hotplug/cpqphp_ctrl.c

@@ -81,14 +81,15 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
 
 
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 		if (change & (0x1L << hp_slot)) {
 		if (change & (0x1L << hp_slot)) {
-			/**********************************
+			/*
 			 * this one changed.
 			 * this one changed.
-			 **********************************/
+			 */
 			func = cpqhp_slot_find(ctrl->bus,
 			func = cpqhp_slot_find(ctrl->bus,
 				(hp_slot + ctrl->slot_device_offset), 0);
 				(hp_slot + ctrl->slot_device_offset), 0);
 
 
 			/* this is the structure that tells the worker thread
 			/* this is the structure that tells the worker thread
-			 *what to do */
+			 * what to do
+			 */
 			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
 			taskInfo = &(ctrl->event_queue[ctrl->next_event]);
 			ctrl->next_event = (ctrl->next_event + 1) % 10;
 			ctrl->next_event = (ctrl->next_event + 1) % 10;
 			taskInfo->hp_slot = hp_slot;
 			taskInfo->hp_slot = hp_slot;
@@ -100,17 +101,17 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
 			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
 			func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
 
 
 			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
 			if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
-				/**********************************
+				/*
 				 * Switch opened
 				 * Switch opened
-				 **********************************/
+				 */
 
 
 				func->switch_save = 0;
 				func->switch_save = 0;
 
 
 				taskInfo->event_type = INT_SWITCH_OPEN;
 				taskInfo->event_type = INT_SWITCH_OPEN;
 			} else {
 			} else {
-				/**********************************
+				/*
 				 * Switch closed
 				 * Switch closed
-				 **********************************/
+				 */
 
 
 				func->switch_save = 0x10;
 				func->switch_save = 0x10;
 
 
@@ -131,9 +132,8 @@ static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device)
 {
 {
 	struct slot *slot = ctrl->slot;
 	struct slot *slot = ctrl->slot;
 
 
-	while (slot && (slot->device != device)) {
+	while (slot && (slot->device != device))
 		slot = slot->next;
 		slot = slot->next;
-	}
 
 
 	return slot;
 	return slot;
 }
 }
@@ -152,17 +152,17 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
 	if (!change)
 	if (!change)
 		return 0;
 		return 0;
 
 
-	/**********************************
+	/*
 	 * Presence Change
 	 * Presence Change
-	 **********************************/
+	 */
 	dbg("cpqsbd:  Presence/Notify input change.\n");
 	dbg("cpqsbd:  Presence/Notify input change.\n");
 	dbg("         Changed bits are 0x%4.4x\n", change );
 	dbg("         Changed bits are 0x%4.4x\n", change );
 
 
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 		if (change & (0x0101 << hp_slot)) {
 		if (change & (0x0101 << hp_slot)) {
-			/**********************************
+			/*
 			 * this one changed.
 			 * this one changed.
-			 **********************************/
+			 */
 			func = cpqhp_slot_find(ctrl->bus,
 			func = cpqhp_slot_find(ctrl->bus,
 				(hp_slot + ctrl->slot_device_offset), 0);
 				(hp_slot + ctrl->slot_device_offset), 0);
 
 
@@ -177,22 +177,23 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
 				return 0;
 				return 0;
 
 
 			/* If the switch closed, must be a button
 			/* If the switch closed, must be a button
-			 * If not in button mode, nevermind */
+			 * If not in button mode, nevermind
+			 */
 			if (func->switch_save && (ctrl->push_button == 1)) {
 			if (func->switch_save && (ctrl->push_button == 1)) {
 				temp_word = ctrl->ctrl_int_comp >> 16;
 				temp_word = ctrl->ctrl_int_comp >> 16;
 				temp_byte = (temp_word >> hp_slot) & 0x01;
 				temp_byte = (temp_word >> hp_slot) & 0x01;
 				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
 				temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
 
 
 				if (temp_byte != func->presence_save) {
 				if (temp_byte != func->presence_save) {
-					/**************************************
+					/*
 					 * button Pressed (doesn't do anything)
 					 * button Pressed (doesn't do anything)
-					 **************************************/
+					 */
 					dbg("hp_slot %d button pressed\n", hp_slot);
 					dbg("hp_slot %d button pressed\n", hp_slot);
 					taskInfo->event_type = INT_BUTTON_PRESS;
 					taskInfo->event_type = INT_BUTTON_PRESS;
 				} else {
 				} else {
-					/**********************************
+					/*
 					 * button Released - TAKE ACTION!!!!
 					 * button Released - TAKE ACTION!!!!
-					 **********************************/
+					 */
 					dbg("hp_slot %d button released\n", hp_slot);
 					dbg("hp_slot %d button released\n", hp_slot);
 					taskInfo->event_type = INT_BUTTON_RELEASE;
 					taskInfo->event_type = INT_BUTTON_RELEASE;
 
 
@@ -210,7 +211,8 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
 				}
 				}
 			} else {
 			} else {
 				/* Switch is open, assume a presence change
 				/* Switch is open, assume a presence change
-				 * Save the presence state */
+				 * Save the presence state
+				 */
 				temp_word = ctrl->ctrl_int_comp >> 16;
 				temp_word = ctrl->ctrl_int_comp >> 16;
 				func->presence_save = (temp_word >> hp_slot) & 0x01;
 				func->presence_save = (temp_word >> hp_slot) & 0x01;
 				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
 				func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
@@ -241,17 +243,17 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl)
 	if (!change)
 	if (!change)
 		return 0;
 		return 0;
 
 
-	/**********************************
+	/*
 	 * power fault
 	 * power fault
-	 **********************************/
+	 */
 
 
 	info("power fault interrupt\n");
 	info("power fault interrupt\n");
 
 
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 	for (hp_slot = 0; hp_slot < 6; hp_slot++) {
 		if (change & (0x01 << hp_slot)) {
 		if (change & (0x01 << hp_slot)) {
-			/**********************************
+			/*
 			 * this one changed.
 			 * this one changed.
-			 **********************************/
+			 */
 			func = cpqhp_slot_find(ctrl->bus,
 			func = cpqhp_slot_find(ctrl->bus,
 				(hp_slot + ctrl->slot_device_offset), 0);
 				(hp_slot + ctrl->slot_device_offset), 0);
 
 
@@ -262,16 +264,16 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl)
 			rc++;
 			rc++;
 
 
 			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
 			if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
-				/**********************************
+				/*
 				 * power fault Cleared
 				 * power fault Cleared
-				 **********************************/
+				 */
 				func->status = 0x00;
 				func->status = 0x00;
 
 
 				taskInfo->event_type = INT_POWER_FAULT_CLEAR;
 				taskInfo->event_type = INT_POWER_FAULT_CLEAR;
 			} else {
 			} else {
-				/**********************************
+				/*
 				 * power fault
 				 * power fault
-				 **********************************/
+				 */
 				taskInfo->event_type = INT_POWER_FAULT;
 				taskInfo->event_type = INT_POWER_FAULT;
 
 
 				if (ctrl->rev < 4) {
 				if (ctrl->rev < 4) {
@@ -432,13 +434,15 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h
 
 
 
 
 	/* If we got here, there the bridge requires some of the resource, but
 	/* If we got here, there the bridge requires some of the resource, but
-	 * we may be able to split some off of the front */
+	 * we may be able to split some off of the front
+	 */
 
 
 	node = *head;
 	node = *head;
 
 
 	if (node->length & (alignment -1)) {
 	if (node->length & (alignment -1)) {
 		/* this one isn't an aligned length, so we'll make a new entry
 		/* this one isn't an aligned length, so we'll make a new entry
-		 * and split it up. */
+		 * and split it up.
+		 */
 		split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 		split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 
 
 		if (!split_node)
 		if (!split_node)
@@ -544,10 +548,10 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
 	if (!(*head))
 	if (!(*head))
 		return NULL;
 		return NULL;
 
 
-	if ( cpqhp_resource_sort_and_combine(head) )
+	if (cpqhp_resource_sort_and_combine(head))
 		return NULL;
 		return NULL;
 
 
-	if ( sort_by_size(head) )
+	if (sort_by_size(head))
 		return NULL;
 		return NULL;
 
 
 	for (node = *head; node; node = node->next) {
 	for (node = *head; node; node = node->next) {
@@ -556,7 +560,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
 
 
 		if (node->base & (size - 1)) {
 		if (node->base & (size - 1)) {
 			/* this one isn't base aligned properly
 			/* this one isn't base aligned properly
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			temp_dword = (node->base | (size-1)) + 1;
 			temp_dword = (node->base | (size-1)) + 1;
 
 
 			/* Short circuit if adjusted size is too small */
 			/* Short circuit if adjusted size is too small */
@@ -581,7 +586,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
 		/* Don't need to check if too small since we already did */
 		/* Don't need to check if too small since we already did */
 		if (node->length > size) {
 		if (node->length > size) {
 			/* this one is longer than we need
 			/* this one is longer than we need
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 
 
 			if (!split_node)
 			if (!split_node)
@@ -601,7 +607,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size
 			continue;
 			continue;
 
 
 		/* If we got here, then it is the right size
 		/* If we got here, then it is the right size
-		 * Now take it out of the list and break */
+		 * Now take it out of the list and break
+		 */
 		if (*head == node) {
 		if (*head == node) {
 			*head = node->next;
 			*head = node->next;
 		} else {
 		} else {
@@ -642,14 +649,16 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz
 		return NULL;
 		return NULL;
 
 
 	for (max = *head; max; max = max->next) {
 	for (max = *head; max; max = max->next) {
-		/* If not big enough we could probably just bail, 
-		 * instead we'll continue to the next. */
+		/* If not big enough we could probably just bail,
+		 * instead we'll continue to the next.
+		 */
 		if (max->length < size)
 		if (max->length < size)
 			continue;
 			continue;
 
 
 		if (max->base & (size - 1)) {
 		if (max->base & (size - 1)) {
 			/* this one isn't base aligned properly
 			/* this one isn't base aligned properly
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			temp_dword = (max->base | (size-1)) + 1;
 			temp_dword = (max->base | (size-1)) + 1;
 
 
 			/* Short circuit if adjusted size is too small */
 			/* Short circuit if adjusted size is too small */
@@ -672,7 +681,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz
 
 
 		if ((max->base + max->length) & (size - 1)) {
 		if ((max->base + max->length) & (size - 1)) {
 			/* this one isn't end aligned properly at the top
 			/* this one isn't end aligned properly at the top
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 
 
 			if (!split_node)
 			if (!split_node)
@@ -744,7 +754,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
 		if (node->base & (size - 1)) {
 		if (node->base & (size - 1)) {
 			dbg("%s: not aligned\n", __func__);
 			dbg("%s: not aligned\n", __func__);
 			/* this one isn't base aligned properly
 			/* this one isn't base aligned properly
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			temp_dword = (node->base | (size-1)) + 1;
 			temp_dword = (node->base | (size-1)) + 1;
 
 
 			/* Short circuit if adjusted size is too small */
 			/* Short circuit if adjusted size is too small */
@@ -769,7 +780,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
 		if (node->length > size) {
 		if (node->length > size) {
 			dbg("%s: too big\n", __func__);
 			dbg("%s: too big\n", __func__);
 			/* this one is longer than we need
 			/* this one is longer than we need
-			 * so we'll make a new entry and split it up */
+			 * so we'll make a new entry and split it up
+			 */
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 			split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
 
 
 			if (!split_node)
 			if (!split_node)
@@ -886,19 +898,19 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)
 	u32 Diff;
 	u32 Diff;
 	u32 temp_dword;
 	u32 temp_dword;
 
 
-	
+
 	misc = readw(ctrl->hpc_reg + MISC);
 	misc = readw(ctrl->hpc_reg + MISC);
-	/***************************************
+	/*
 	 * Check to see if it was our interrupt
 	 * Check to see if it was our interrupt
-	 ***************************************/
+	 */
 	if (!(misc & 0x000C)) {
 	if (!(misc & 0x000C)) {
 		return IRQ_NONE;
 		return IRQ_NONE;
 	}
 	}
 
 
 	if (misc & 0x0004) {
 	if (misc & 0x0004) {
-		/**********************************
+		/*
 		 * Serial Output interrupt Pending
 		 * Serial Output interrupt Pending
-		 **********************************/
+		 */
 
 
 		/* Clear the interrupt */
 		/* Clear the interrupt */
 		misc |= 0x0004;
 		misc |= 0x0004;
@@ -961,11 +973,8 @@ struct pci_func *cpqhp_slot_create(u8 busnumber)
 	struct pci_func *next;
 	struct pci_func *next;
 
 
 	new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL);
 	new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL);
-	if (new_slot == NULL) {
-		/* I'm not dead yet!
-		 * You will be. */
+	if (new_slot == NULL)
 		return new_slot;
 		return new_slot;
-	}
 
 
 	new_slot->next = NULL;
 	new_slot->next = NULL;
 	new_slot->configured = 1;
 	new_slot->configured = 1;
@@ -996,10 +1005,8 @@ static int slot_remove(struct pci_func * old_slot)
 		return 1;
 		return 1;
 
 
 	next = cpqhp_slot_list[old_slot->bus];
 	next = cpqhp_slot_list[old_slot->bus];
-
-	if (next == NULL) {
+	if (next == NULL)
 		return 1;
 		return 1;
-	}
 
 
 	if (next == old_slot) {
 	if (next == old_slot) {
 		cpqhp_slot_list[old_slot->bus] = old_slot->next;
 		cpqhp_slot_list[old_slot->bus] = old_slot->next;
@@ -1008,9 +1015,8 @@ static int slot_remove(struct pci_func * old_slot)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	while ((next->next != old_slot) && (next->next != NULL)) {
+	while ((next->next != old_slot) && (next->next != NULL))
 		next = next->next;
 		next = next->next;
-	}
 
 
 	if (next->next == old_slot) {
 	if (next->next == old_slot) {
 		next->next = old_slot->next;
 		next->next = old_slot->next;
@@ -1040,9 +1046,8 @@ static int bridge_slot_remove(struct pci_func *bridge)
 	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
 	for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
 		next = cpqhp_slot_list[tempBus];
 		next = cpqhp_slot_list[tempBus];
 
 
-		while (!slot_remove(next)) {
+		while (!slot_remove(next))
 			next = cpqhp_slot_list[tempBus];
 			next = cpqhp_slot_list[tempBus];
-		}
 	}
 	}
 
 
 	next = cpqhp_slot_list[bridge->bus];
 	next = cpqhp_slot_list[bridge->bus];
@@ -1130,39 +1135,43 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
 	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
 	u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
 	u16 reg16;
 	u16 reg16;
 	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
 	u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
-	
+
 	if (ctrl->speed == adapter_speed)
 	if (ctrl->speed == adapter_speed)
 		return 0;
 		return 0;
-	
+
 	/* We don't allow freq/mode changes if we find another adapter running
 	/* We don't allow freq/mode changes if we find another adapter running
-	 * in another slot on this controller */
+	 * in another slot on this controller
+	 */
 	for(slot = ctrl->slot; slot; slot = slot->next) {
 	for(slot = ctrl->slot; slot; slot = slot->next) {
-		if (slot->device == (hp_slot + ctrl->slot_device_offset)) 
+		if (slot->device == (hp_slot + ctrl->slot_device_offset))
 			continue;
 			continue;
 		if (!slot->hotplug_slot || !slot->hotplug_slot->info)
 		if (!slot->hotplug_slot || !slot->hotplug_slot->info)
 			continue;
 			continue;
-		if (slot->hotplug_slot->info->adapter_status == 0) 
+		if (slot->hotplug_slot->info->adapter_status == 0)
 			continue;
 			continue;
 		/* If another adapter is running on the same segment but at a
 		/* If another adapter is running on the same segment but at a
 		 * lower speed/mode, we allow the new adapter to function at
 		 * lower speed/mode, we allow the new adapter to function at
-		 * this rate if supported */
-		if (ctrl->speed < adapter_speed) 
+		 * this rate if supported
+		 */
+		if (ctrl->speed < adapter_speed)
 			return 0;
 			return 0;
 
 
 		return 1;
 		return 1;
 	}
 	}
-	
+
 	/* If the controller doesn't support freq/mode changes and the
 	/* If the controller doesn't support freq/mode changes and the
-	 * controller is running at a higher mode, we bail */
+	 * controller is running at a higher mode, we bail
+	 */
 	if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
 	if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
 		return 1;
 		return 1;
-	
+
 	/* But we allow the adapter to run at a lower rate if possible */
 	/* But we allow the adapter to run at a lower rate if possible */
 	if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
 	if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
 		return 0;
 		return 0;
 
 
 	/* We try to set the max speed supported by both the adapter and
 	/* We try to set the max speed supported by both the adapter and
-	 * controller */
+	 * controller
+	 */
 	if (ctrl->speed_capability < adapter_speed) {
 	if (ctrl->speed_capability < adapter_speed) {
 		if (ctrl->speed == ctrl->speed_capability)
 		if (ctrl->speed == ctrl->speed_capability)
 			return 0;
 			return 0;
@@ -1171,22 +1180,22 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
 
 
 	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
 	writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
 	writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
 	writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
-	
-	set_SOGO(ctrl); 
+
+	set_SOGO(ctrl);
 	wait_for_ctrl_irq(ctrl);
 	wait_for_ctrl_irq(ctrl);
-	
+
 	if (adapter_speed != PCI_SPEED_133MHz_PCIX)
 	if (adapter_speed != PCI_SPEED_133MHz_PCIX)
 		reg = 0xF5;
 		reg = 0xF5;
 	else
 	else
-		reg = 0xF4;	
+		reg = 0xF4;
 	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
 	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
-	
+
 	reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
 	reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
 	reg16 &= ~0x000F;
 	reg16 &= ~0x000F;
 	switch(adapter_speed) {
 	switch(adapter_speed) {
-		case(PCI_SPEED_133MHz_PCIX): 
+		case(PCI_SPEED_133MHz_PCIX):
 			reg = 0x75;
 			reg = 0x75;
-			reg16 |= 0xB; 
+			reg16 |= 0xB;
 			break;
 			break;
 		case(PCI_SPEED_100MHz_PCIX):
 		case(PCI_SPEED_100MHz_PCIX):
 			reg = 0x74;
 			reg = 0x74;
@@ -1203,48 +1212,48 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_
 		default: /* 33MHz PCI 2.2 */
 		default: /* 33MHz PCI 2.2 */
 			reg = 0x71;
 			reg = 0x71;
 			break;
 			break;
-			
+
 	}
 	}
 	reg16 |= 0xB << 12;
 	reg16 |= 0xB << 12;
 	writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
 	writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
-	
-	mdelay(5); 
-	
+
+	mdelay(5);
+
 	/* Reenable interrupts */
 	/* Reenable interrupts */
 	writel(0, ctrl->hpc_reg + INT_MASK);
 	writel(0, ctrl->hpc_reg + INT_MASK);
 
 
-	pci_write_config_byte(ctrl->pci_dev, 0x41, reg); 
-	
+	pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
+
 	/* Restart state machine */
 	/* Restart state machine */
 	reg = ~0xF;
 	reg = ~0xF;
 	pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
 	pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
 	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
 	pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
-	
+
 	/* Only if mode change...*/
 	/* Only if mode change...*/
 	if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
 	if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
 		((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
 		((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) 
 			set_SOGO(ctrl);
 			set_SOGO(ctrl);
-	
+
 	wait_for_ctrl_irq(ctrl);
 	wait_for_ctrl_irq(ctrl);
 	mdelay(1100);
 	mdelay(1100);
-	
+
 	/* Restore LED/Slot state */
 	/* Restore LED/Slot state */
 	writel(leds, ctrl->hpc_reg + LED_CONTROL);
 	writel(leds, ctrl->hpc_reg + LED_CONTROL);
 	writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
 	writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
-	
+
 	set_SOGO(ctrl);
 	set_SOGO(ctrl);
 	wait_for_ctrl_irq(ctrl);
 	wait_for_ctrl_irq(ctrl);
 
 
 	ctrl->speed = adapter_speed;
 	ctrl->speed = adapter_speed;
 	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 	slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
 
-	info("Successfully changed frequency/mode for adapter in slot %d\n", 
+	info("Successfully changed frequency/mode for adapter in slot %d\n",
 			slot->number);
 			slot->number);
 	return 0;
 	return 0;
 }
 }
 
 
-/* the following routines constitute the bulk of the 
-   hotplug controller logic
+/* the following routines constitute the bulk of the
+ * hotplug controller logic
  */
  */
 
 
 
 
@@ -1268,17 +1277,17 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
 
 	hp_slot = func->device - ctrl->slot_device_offset;
 	hp_slot = func->device - ctrl->slot_device_offset;
 
 
-	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
-		/**********************************
-		 * The switch is open.
-		 **********************************/
+	/*
+	 * The switch is open.
+	 */
+	if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot))
 		rc = INTERLOCK_OPEN;
 		rc = INTERLOCK_OPEN;
-	} else if (is_slot_enabled (ctrl, hp_slot)) {
-		/**********************************
-		 * The board is already on
-		 **********************************/
+	/*
+	 * The board is already on
+	 */
+	else if (is_slot_enabled (ctrl, hp_slot))
 		rc = CARD_FUNCTIONING;
 		rc = CARD_FUNCTIONING;
-	} else {
+	else {
 		mutex_lock(&ctrl->crit_sect);
 		mutex_lock(&ctrl->crit_sect);
 
 
 		/* turn on board without attaching to the bus */
 		/* turn on board without attaching to the bus */
@@ -1299,7 +1308,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
 
 		/* Wait for SOBS to be unset */
 		/* Wait for SOBS to be unset */
 		wait_for_ctrl_irq (ctrl);
 		wait_for_ctrl_irq (ctrl);
-		
+
 		adapter_speed = get_adapter_speed(ctrl, hp_slot);
 		adapter_speed = get_adapter_speed(ctrl, hp_slot);
 		if (ctrl->speed != adapter_speed)
 		if (ctrl->speed != adapter_speed)
 			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 			if (set_controller_speed(ctrl, adapter_speed, hp_slot))
@@ -1352,7 +1361,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 			 * Get slot won't work for devices behind
 			 * Get slot won't work for devices behind
 			 * bridges, but in this case it will always be
 			 * bridges, but in this case it will always be
 			 * called for the "base" bus/dev/func of an
 			 * called for the "base" bus/dev/func of an
-			 * adapter. */
+			 * adapter.
+			 */
 
 
 			mutex_lock(&ctrl->crit_sect);
 			mutex_lock(&ctrl->crit_sect);
 
 
@@ -1377,7 +1387,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
 
 			 * Get slot won't work for devices behind bridges, but
 			 * Get slot won't work for devices behind bridges, but
 			 * in this case it will always be called for the "base"
 			 * in this case it will always be called for the "base"
-			 * bus/dev/func of an adapter. */
+			 * bus/dev/func of an adapter.
+			 */
 
 
 			mutex_lock(&ctrl->crit_sect);
 			mutex_lock(&ctrl->crit_sect);
 
 
@@ -1434,7 +1445,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 	wait_for_ctrl_irq (ctrl);
 	wait_for_ctrl_irq (ctrl);
 
 
 	/* Change bits in slot power register to force another shift out
 	/* Change bits in slot power register to force another shift out
-	 * NOTE: this is to work around the timer bug */
+	 * NOTE: this is to work around the timer bug
+	 */
 	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
 	temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
 	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
 	writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
 	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
 	writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
@@ -1443,12 +1455,12 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 
 
 	/* Wait for SOBS to be unset */
 	/* Wait for SOBS to be unset */
 	wait_for_ctrl_irq (ctrl);
 	wait_for_ctrl_irq (ctrl);
-	
+
 	adapter_speed = get_adapter_speed(ctrl, hp_slot);
 	adapter_speed = get_adapter_speed(ctrl, hp_slot);
 	if (ctrl->speed != adapter_speed)
 	if (ctrl->speed != adapter_speed)
 		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 		if (set_controller_speed(ctrl, adapter_speed, hp_slot))
 			rc = WRONG_BUS_FREQUENCY;
 			rc = WRONG_BUS_FREQUENCY;
-	
+
 	/* turn off board without attaching to the bus */
 	/* turn off board without attaching to the bus */
 	disable_slot_power (ctrl, hp_slot);
 	disable_slot_power (ctrl, hp_slot);
 
 
@@ -1461,7 +1473,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 
 
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
-	
+
 	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 	p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
 
 	/* turn on board and blink green LED */
 	/* turn on board and blink green LED */
@@ -1521,7 +1533,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 	}
 	}
 
 
 	/* All F's is an empty slot or an invalid board */
 	/* All F's is an empty slot or an invalid board */
-	if (temp_register != 0xFFFFFFFF) {	  /* Check for a board in the slot */
+	if (temp_register != 0xFFFFFFFF) {
 		res_lists.io_head = ctrl->io_head;
 		res_lists.io_head = ctrl->io_head;
 		res_lists.mem_head = ctrl->mem_head;
 		res_lists.mem_head = ctrl->mem_head;
 		res_lists.p_mem_head = ctrl->p_mem_head;
 		res_lists.p_mem_head = ctrl->p_mem_head;
@@ -1570,9 +1582,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
 		index = 0;
 		index = 0;
 		do {
 		do {
 			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
 			new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
-			if (new_slot && !new_slot->pci_dev) {
+			if (new_slot && !new_slot->pci_dev)
 				cpqhp_configure_device(ctrl, new_slot);
 				cpqhp_configure_device(ctrl, new_slot);
-			}
 		} while (new_slot);
 		} while (new_slot);
 
 
 		mutex_lock(&ctrl->crit_sect);
 		mutex_lock(&ctrl->crit_sect);
@@ -1859,12 +1870,12 @@ static void interrupt_event_handler(struct controller *ctrl)
 						info(msg_button_on, p_slot->number);
 						info(msg_button_on, p_slot->number);
 					}
 					}
 					mutex_lock(&ctrl->crit_sect);
 					mutex_lock(&ctrl->crit_sect);
-					
+
 					dbg("blink green LED and turn off amber\n");
 					dbg("blink green LED and turn off amber\n");
-					
+
 					amber_LED_off (ctrl, hp_slot);
 					amber_LED_off (ctrl, hp_slot);
 					green_LED_blink (ctrl, hp_slot);
 					green_LED_blink (ctrl, hp_slot);
-					
+
 					set_SOGO(ctrl);
 					set_SOGO(ctrl);
 
 
 					/* Wait for SOBS to be unset */
 					/* Wait for SOBS to be unset */
@@ -1958,7 +1969,7 @@ void cpqhp_pushbutton_thread(unsigned long slot)
 			if (cpqhp_process_SI(ctrl, func) != 0) {
 			if (cpqhp_process_SI(ctrl, func) != 0) {
 				amber_LED_on(ctrl, hp_slot);
 				amber_LED_on(ctrl, hp_slot);
 				green_LED_off(ctrl, hp_slot);
 				green_LED_off(ctrl, hp_slot);
-				
+
 				set_SOGO(ctrl);
 				set_SOGO(ctrl);
 
 
 				/* Wait for SOBS to be unset */
 				/* Wait for SOBS to be unset */
@@ -2079,7 +2090,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
 	struct pci_bus *pci_bus = ctrl->pci_bus;
 	struct pci_bus *pci_bus = ctrl->pci_bus;
 	int physical_slot=0;
 	int physical_slot=0;
 
 
-	device = func->device; 
+	device = func->device;
 	func = cpqhp_slot_find(ctrl->bus, device, index++);
 	func = cpqhp_slot_find(ctrl->bus, device, index++);
 	p_slot = cpqhp_find_slot(ctrl, device);
 	p_slot = cpqhp_find_slot(ctrl, device);
 	if (p_slot) {
 	if (p_slot) {
@@ -2113,9 +2124,8 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func)
 
 
 				/* If the VGA Enable bit is set, remove isn't
 				/* If the VGA Enable bit is set, remove isn't
 				 * supported */
 				 * supported */
-				if (BCR & PCI_BRIDGE_CTL_VGA) {
+				if (BCR & PCI_BRIDGE_CTL_VGA)
 					rc = REMOVE_NOT_SUPPORTED;
 					rc = REMOVE_NOT_SUPPORTED;
-				}
 			}
 			}
 		}
 		}
 
 
@@ -2183,67 +2193,67 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num)
 	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
 	num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
 
 
 	switch (test_num) {
 	switch (test_num) {
-		case 1:
-			/* Do stuff here! */
-
-			/* Do that funky LED thing */
-			/* so we can restore them later */
-			save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
-			work_LED = 0x01010101;
-			switch_leds(ctrl, num_of_slots, &work_LED, 0);
-			switch_leds(ctrl, num_of_slots, &work_LED, 1);
-			switch_leds(ctrl, num_of_slots, &work_LED, 0);
-			switch_leds(ctrl, num_of_slots, &work_LED, 1);
-
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			switch_leds(ctrl, num_of_slots, &work_LED, 0);
-			switch_leds(ctrl, num_of_slots, &work_LED, 1);
-			work_LED = 0x00000101;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			switch_leds(ctrl, num_of_slots, &work_LED, 0);
-			switch_leds(ctrl, num_of_slots, &work_LED, 1);
+	case 1:
+		/* Do stuff here! */
+
+		/* Do that funky LED thing */
+		/* so we can restore them later */
+		save_LED = readl(ctrl->hpc_reg + LED_CONTROL);
+		work_LED = 0x01010101;
+		switch_leds(ctrl, num_of_slots, &work_LED, 0);
+		switch_leds(ctrl, num_of_slots, &work_LED, 1);
+		switch_leds(ctrl, num_of_slots, &work_LED, 0);
+		switch_leds(ctrl, num_of_slots, &work_LED, 1);
+
+		work_LED = 0x01010000;
+		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+		switch_leds(ctrl, num_of_slots, &work_LED, 0);
+		switch_leds(ctrl, num_of_slots, &work_LED, 1);
+		work_LED = 0x00000101;
+		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+		switch_leds(ctrl, num_of_slots, &work_LED, 0);
+		switch_leds(ctrl, num_of_slots, &work_LED, 1);
+
+		work_LED = 0x01010000;
+		writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+		for (loop = 0; loop < num_of_slots; loop++) {
+			set_SOGO(ctrl);
 
 
-			work_LED = 0x01010000;
-			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			for (loop = 0; loop < num_of_slots; loop++) {
-				set_SOGO(ctrl);
+			/* Wait for SOGO interrupt */
+			wait_for_ctrl_irq (ctrl);
 
 
-				/* Wait for SOGO interrupt */
-				wait_for_ctrl_irq (ctrl);
+			/* Get ready for next iteration */
+			long_delay((3*HZ)/10);
+			work_LED = work_LED >> 16;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
 
 
-				/* Get ready for next iteration */
-				long_delay((3*HZ)/10);
-				work_LED = work_LED >> 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				
-				set_SOGO(ctrl);
+			set_SOGO(ctrl);
 
 
-				/* Wait for SOGO interrupt */
-				wait_for_ctrl_irq (ctrl);
+			/* Wait for SOGO interrupt */
+			wait_for_ctrl_irq (ctrl);
 
 
-				/* Get ready for next iteration */
-				long_delay((3*HZ)/10);
-				work_LED = work_LED << 16;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-				work_LED = work_LED << 1;
-				writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
-			}
+			/* Get ready for next iteration */
+			long_delay((3*HZ)/10);
+			work_LED = work_LED << 16;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+			work_LED = work_LED << 1;
+			writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
+		}
 
 
-			/* put it back the way it was */
-			writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
+		/* put it back the way it was */
+		writel(save_LED, ctrl->hpc_reg + LED_CONTROL);
 
 
-			set_SOGO(ctrl);
+		set_SOGO(ctrl);
 
 
-			/* Wait for SOBS to be unset */
-			wait_for_ctrl_irq (ctrl);
-			break;
-		case 2:
-			/* Do other stuff here! */
-			break;
-		case 3:
-			/* and more... */
-			break;
+		/* Wait for SOBS to be unset */
+		wait_for_ctrl_irq (ctrl);
+		break;
+	case 2:
+		/* Do other stuff here! */
+		break;
+	case 3:
+		/* and more... */
+		break;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -2312,9 +2322,9 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func
 		while ((function < max_functions) && (!stop_it)) {
 		while ((function < max_functions) && (!stop_it)) {
 			pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
 			pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
 
 
-			if (ID == 0xFFFFFFFF) {	  /* There's nothing there. */
+			if (ID == 0xFFFFFFFF) {
 				function++;
 				function++;
-			} else {  /* There's something there */
+			} else {
 				/* Setup slot structure. */
 				/* Setup slot structure. */
 				new_slot = cpqhp_slot_create(func->bus);
 				new_slot = cpqhp_slot_create(func->bus);
 
 
@@ -2339,8 +2349,8 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func
 
 
 
 
 /*
 /*
-  Configuration logic that involves the hotplug data structures and 
-  their bookkeeping
+ * Configuration logic that involves the hotplug data structures and
+ * their bookkeeping
  */
  */
 
 
 
 
@@ -2393,7 +2403,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
 
 
-	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
+	if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
 		/* set Primary bus */
 		/* set Primary bus */
 		dbg("set Primary bus = %d\n", func->bus);
 		dbg("set Primary bus = %d\n", func->bus);
 		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
 		rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
@@ -2484,7 +2494,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 		temp_resources.irqs = &irqs;
 		temp_resources.irqs = &irqs;
 
 
 		/* Make copies of the nodes we are going to pass down so that
 		/* Make copies of the nodes we are going to pass down so that
-		 * if there is a problem,we can just use these to free resources */
+		 * if there is a problem,we can just use these to free resources
+		 */
 		hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
 		hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
 		hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
 		hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
 		hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
 		hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
@@ -2556,7 +2567,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 		temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
 		temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
 		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
 
-		/* Adjust this to compensate for extra adjustment in first loop */
+		/* Adjust this to compensate for extra adjustment in first loop
+		 */
 		irqs.barber_pole--;
 		irqs.barber_pole--;
 
 
 		rc = 0;
 		rc = 0;
@@ -2917,27 +2929,26 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
 		}		/* End of base register loop */
 		}		/* End of base register loop */
 		if (cpqhp_legacy_mode) {
 		if (cpqhp_legacy_mode) {
 			/* Figure out which interrupt pin this function uses */
 			/* Figure out which interrupt pin this function uses */
-			rc = pci_bus_read_config_byte (pci_bus, devfn, 
+			rc = pci_bus_read_config_byte (pci_bus, devfn,
 				PCI_INTERRUPT_PIN, &temp_byte);
 				PCI_INTERRUPT_PIN, &temp_byte);
 
 
 			/* If this function needs an interrupt and we are behind
 			/* If this function needs an interrupt and we are behind
 			 * a bridge and the pin is tied to something that's
 			 * a bridge and the pin is tied to something that's
 			 * alread mapped, set this one the same */
 			 * alread mapped, set this one the same */
-			if (temp_byte && resources->irqs && 
-			    (resources->irqs->valid_INT & 
+			if (temp_byte && resources->irqs &&
+			    (resources->irqs->valid_INT &
 			     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
 			     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
 				/* We have to share with something already set up */
 				/* We have to share with something already set up */
-				IRQ = resources->irqs->interrupt[(temp_byte + 
+				IRQ = resources->irqs->interrupt[(temp_byte +
 					resources->irqs->barber_pole - 1) & 0x03];
 					resources->irqs->barber_pole - 1) & 0x03];
 			} else {
 			} else {
 				/* Program IRQ based on card type */
 				/* Program IRQ based on card type */
 				rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
 				rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
 
 
-				if (class_code == PCI_BASE_CLASS_STORAGE) {
+				if (class_code == PCI_BASE_CLASS_STORAGE)
 					IRQ = cpqhp_disk_irq;
 					IRQ = cpqhp_disk_irq;
-				} else {
+				else
 					IRQ = cpqhp_nic_irq;
 					IRQ = cpqhp_nic_irq;
-				}
 			}
 			}
 
 
 			/* IRQ Line */
 			/* IRQ Line */

+ 51 - 46
drivers/pci/hotplug/cpqphp_nvram.c

@@ -94,12 +94,13 @@ static u8 evbuffer[1024];
 
 
 static void __iomem *compaq_int15_entry_point;
 static void __iomem *compaq_int15_entry_point;
 
 
-static spinlock_t int15_lock;		/* lock for ordering int15_bios_call() */
+/* lock for ordering int15_bios_call() */
+static spinlock_t int15_lock;
 
 
 
 
 /* This is a series of function that deals with
 /* This is a series of function that deals with
-   setting & getting the hotplug resource table in some environment variable.
-*/
+ * setting & getting the hotplug resource table in some environment variable.
+ */
 
 
 /*
 /*
  * We really shouldn't be doing this unless there is a _very_ good reason to!!!
  * We really shouldn't be doing this unless there is a _very_ good reason to!!!
@@ -113,7 +114,7 @@ static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail)
 
 
 	if ((*used + 1) > *avail)
 	if ((*used + 1) > *avail)
 		return(1);
 		return(1);
-	
+
 	*((u8*)*p_buffer) = value;
 	*((u8*)*p_buffer) = value;
 	tByte = (u8**)p_buffer;
 	tByte = (u8**)p_buffer;
 	(*tByte)++;
 	(*tByte)++;
@@ -170,10 +171,10 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
 	unsigned long flags;
 	unsigned long flags;
 	int op = operation;
 	int op = operation;
 	int ret_val;
 	int ret_val;
-	
+
 	if (!compaq_int15_entry_point)
 	if (!compaq_int15_entry_point)
 		return -ENODEV;
 		return -ENODEV;
-	
+
 	spin_lock_irqsave(&int15_lock, flags);
 	spin_lock_irqsave(&int15_lock, flags);
 	__asm__ (
 	__asm__ (
 		"xorl   %%ebx,%%ebx\n" \
 		"xorl   %%ebx,%%ebx\n" \
@@ -187,7 +188,7 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
 		"D" (buffer), "m" (compaq_int15_entry_point)
 		"D" (buffer), "m" (compaq_int15_entry_point)
 		: "%ebx", "%edx");
 		: "%ebx", "%edx");
 	spin_unlock_irqrestore(&int15_lock, flags);
 	spin_unlock_irqrestore(&int15_lock, flags);
-	
+
 	return((ret_val & 0xFF00) >> 8);
 	return((ret_val & 0xFF00) >> 8);
 }
 }
 
 
@@ -210,14 +211,16 @@ static int load_HRT (void __iomem *rom_start)
 
 
 	available = 1024;
 	available = 1024;
 
 
-	// Now load the EV
+	/* Now load the EV */
 	temp_dword = available;
 	temp_dword = available;
 
 
 	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
 	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);
 
 
 	evbuffer_length = temp_dword;
 	evbuffer_length = temp_dword;
 
 
-	// We're maintaining the resource lists so write FF to invalidate old info
+	/* We're maintaining the resource lists so write FF to invalidate old
+	 * info
+	 */
 	temp_dword = 1;
 	temp_dword = 1;
 
 
 	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
 	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);
@@ -263,13 +266,13 @@ static u32 store_HRT (void __iomem *rom_start)
 	p_EV_header = (struct ev_hrt_header *) pFill;
 	p_EV_header = (struct ev_hrt_header *) pFill;
 
 
 	ctrl = cpqhp_ctrl_list;
 	ctrl = cpqhp_ctrl_list;
-	
-	// The revision of this structure
+
+	/* The revision of this structure */
 	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
 	rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available);
 	if (rc)
 	if (rc)
 		return(rc);
 		return(rc);
 
 
-	// The number of controllers
+	/* The number of controllers */
 	rc = add_byte( &pFill, 1, &usedbytes, &available);
 	rc = add_byte( &pFill, 1, &usedbytes, &available);
 	if (rc)
 	if (rc)
 		return(rc);
 		return(rc);
@@ -279,27 +282,27 @@ static u32 store_HRT (void __iomem *rom_start)
 
 
 		numCtrl++;
 		numCtrl++;
 
 
-		// The bus number
+		/* The bus number */
 		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
 		rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available);
 		if (rc)
 		if (rc)
 			return(rc);
 			return(rc);
 
 
-		// The device Number
+		/* The device Number */
 		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
 		rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
 		if (rc)
 		if (rc)
 			return(rc);
 			return(rc);
 
 
-		// The function Number
+		/* The function Number */
 		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
 		rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
 		if (rc)
 		if (rc)
 			return(rc);
 			return(rc);
 
 
-		// Skip the number of available entries
+		/* Skip the number of available entries */
 		rc = add_dword( &pFill, 0, &usedbytes, &available);
 		rc = add_dword( &pFill, 0, &usedbytes, &available);
 		if (rc)
 		if (rc)
 			return(rc);
 			return(rc);
 
 
-		// Figure out memory Available
+		/* Figure out memory Available */
 
 
 		resNode = ctrl->mem_head;
 		resNode = ctrl->mem_head;
 
 
@@ -308,12 +311,12 @@ static u32 store_HRT (void __iomem *rom_start)
 		while (resNode) {
 		while (resNode) {
 			loop ++;
 			loop ++;
 
 
-			// base
+			/* base */
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
 
 
-			// length
+			/* length */
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
@@ -321,10 +324,10 @@ static u32 store_HRT (void __iomem *rom_start)
 			resNode = resNode->next;
 			resNode = resNode->next;
 		}
 		}
 
 
-		// Fill in the number of entries
+		/* Fill in the number of entries */
 		p_ev_ctrl->mem_avail = loop;
 		p_ev_ctrl->mem_avail = loop;
 
 
-		// Figure out prefetchable memory Available
+		/* Figure out prefetchable memory Available */
 
 
 		resNode = ctrl->p_mem_head;
 		resNode = ctrl->p_mem_head;
 
 
@@ -333,12 +336,12 @@ static u32 store_HRT (void __iomem *rom_start)
 		while (resNode) {
 		while (resNode) {
 			loop ++;
 			loop ++;
 
 
-			// base
+			/* base */
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
 
 
-			// length
+			/* length */
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
@@ -346,10 +349,10 @@ static u32 store_HRT (void __iomem *rom_start)
 			resNode = resNode->next;
 			resNode = resNode->next;
 		}
 		}
 
 
-		// Fill in the number of entries
+		/* Fill in the number of entries */
 		p_ev_ctrl->p_mem_avail = loop;
 		p_ev_ctrl->p_mem_avail = loop;
 
 
-		// Figure out IO Available
+		/* Figure out IO Available */
 
 
 		resNode = ctrl->io_head;
 		resNode = ctrl->io_head;
 
 
@@ -358,12 +361,12 @@ static u32 store_HRT (void __iomem *rom_start)
 		while (resNode) {
 		while (resNode) {
 			loop ++;
 			loop ++;
 
 
-			// base
+			/* base */
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
 
 
-			// length
+			/* length */
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
@@ -371,10 +374,10 @@ static u32 store_HRT (void __iomem *rom_start)
 			resNode = resNode->next;
 			resNode = resNode->next;
 		}
 		}
 
 
-		// Fill in the number of entries
+		/* Fill in the number of entries */
 		p_ev_ctrl->io_avail = loop;
 		p_ev_ctrl->io_avail = loop;
 
 
-		// Figure out bus Available
+		/* Figure out bus Available */
 
 
 		resNode = ctrl->bus_head;
 		resNode = ctrl->bus_head;
 
 
@@ -383,12 +386,12 @@ static u32 store_HRT (void __iomem *rom_start)
 		while (resNode) {
 		while (resNode) {
 			loop ++;
 			loop ++;
 
 
-			// base
+			/* base */
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->base, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
 
 
-			// length
+			/* length */
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			rc = add_dword( &pFill, resNode->length, &usedbytes, &available);
 			if (rc)
 			if (rc)
 				return(rc);
 				return(rc);
@@ -396,15 +399,15 @@ static u32 store_HRT (void __iomem *rom_start)
 			resNode = resNode->next;
 			resNode = resNode->next;
 		}
 		}
 
 
-		// Fill in the number of entries
+		/* Fill in the number of entries */
 		p_ev_ctrl->bus_avail = loop;
 		p_ev_ctrl->bus_avail = loop;
 
 
 		ctrl = ctrl->next;
 		ctrl = ctrl->next;
 	}
 	}
-	
+
 	p_EV_header->num_of_ctrl = numCtrl;
 	p_EV_header->num_of_ctrl = numCtrl;
 
 
-	// Now store the EV
+	/* Now store the EV */
 
 
 	temp_dword = usedbytes;
 	temp_dword = usedbytes;
 
 
@@ -449,20 +452,21 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 	struct ev_hrt_header *p_EV_header;
 	struct ev_hrt_header *p_EV_header;
 
 
 	if (!evbuffer_init) {
 	if (!evbuffer_init) {
-		// Read the resource list information in from NVRAM
+		/* Read the resource list information in from NVRAM */
 		if (load_HRT(rom_start))
 		if (load_HRT(rom_start))
 			memset (evbuffer, 0, 1024);
 			memset (evbuffer, 0, 1024);
 
 
 		evbuffer_init = 1;
 		evbuffer_init = 1;
 	}
 	}
 
 
-	// If we saved information in NVRAM, use it now
+	/* If we saved information in NVRAM, use it now */
 	p_EV_header = (struct ev_hrt_header *) evbuffer;
 	p_EV_header = (struct ev_hrt_header *) evbuffer;
 
 
-	// The following code is for systems where version 1.0 of this
-	// driver has been loaded, but doesn't support the hardware.
-	// In that case, the driver would incorrectly store something
-	// in NVRAM.
+	/* The following code is for systems where version 1.0 of this
+	 * driver has been loaded, but doesn't support the hardware.
+	 * In that case, the driver would incorrectly store something
+	 * in NVRAM.
+	 */
 	if ((p_EV_header->Version == 2) ||
 	if ((p_EV_header->Version == 2) ||
 	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
 	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
 		p_byte = &(p_EV_header->next);
 		p_byte = &(p_EV_header->next);
@@ -479,7 +483,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 		function = p_ev_ctrl->function;
 		function = p_ev_ctrl->function;
 
 
 		while ((bus != ctrl->bus) ||
 		while ((bus != ctrl->bus) ||
-		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) || 
+		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
 		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
 		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
 			nummem = p_ev_ctrl->mem_avail;
 			nummem = p_ev_ctrl->mem_avail;
 			numpmem = p_ev_ctrl->p_mem_avail;
 			numpmem = p_ev_ctrl->p_mem_avail;
@@ -491,7 +495,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
 				return 2;
 				return 2;
 
 
-			// Skip forward to the next entry
+			/* Skip forward to the next entry */
 			p_byte += (nummem + numpmem + numio + numbus) * 8;
 			p_byte += (nummem + numpmem + numio + numbus) * 8;
 
 
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
 			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
@@ -629,8 +633,9 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 			ctrl->bus_head = bus_node;
 			ctrl->bus_head = bus_node;
 		}
 		}
 
 
-		// If all of the following fail, we don't have any resources for
-		// hot plug add
+		/* If all of the following fail, we don't have any resources for
+		 * hot plug add
+		 */
 		rc = 1;
 		rc = 1;
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
 		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
@@ -640,14 +645,14 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 		if (rc)
 		if (rc)
 			return(rc);
 			return(rc);
 	} else {
 	} else {
-		if ((evbuffer[0] != 0) && (!ctrl->push_flag)) 
+		if ((evbuffer[0] != 0) && (!ctrl->push_flag))
 			return 1;
 			return 1;
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-	
+
 int compaq_nvram_store (void __iomem *rom_start)
 int compaq_nvram_store (void __iomem *rom_start)
 {
 {
 	int rc = 1;
 	int rc = 1;

+ 297 - 302
drivers/pci/hotplug/cpqphp_pci.c

@@ -37,7 +37,6 @@
 #include "../pci.h"
 #include "../pci.h"
 #include "cpqphp.h"
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
 #include "cpqphp_nvram.h"
-#include <asm/pci_x86.h>
 
 
 
 
 u8 cpqhp_nic_irq;
 u8 cpqhp_nic_irq;
@@ -82,14 +81,14 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
 }
 }
 
 
 
 
-int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
+int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
 {
 {
 	unsigned char bus;
 	unsigned char bus;
 	struct pci_bus *child;
 	struct pci_bus *child;
 	int num;
 	int num;
 
 
 	if (func->pci_dev == NULL)
 	if (func->pci_dev == NULL)
-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+		func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function));
 
 
 	/* No pci device, we need to create it then */
 	/* No pci device, we need to create it then */
 	if (func->pci_dev == NULL) {
 	if (func->pci_dev == NULL) {
@@ -99,7 +98,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
 		if (num)
 		if (num)
 			pci_bus_add_devices(ctrl->pci_dev->bus);
 			pci_bus_add_devices(ctrl->pci_dev->bus);
 
 
-		func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
+		func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
 		if (func->pci_dev == NULL) {
 		if (func->pci_dev == NULL) {
 			dbg("ERROR: pci_dev still null\n");
 			dbg("ERROR: pci_dev still null\n");
 			return 0;
 			return 0;
@@ -112,20 +111,24 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
 		pci_do_scan_bus(child);
 		pci_do_scan_bus(child);
 	}
 	}
 
 
+	pci_dev_put(func->pci_dev);
+
 	return 0;
 	return 0;
 }
 }
 
 
 
 
-int cpqhp_unconfigure_device(struct pci_func* func) 
+int cpqhp_unconfigure_device(struct pci_func* func)
 {
 {
 	int j;
 	int j;
-	
+
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);
 
 
 	for (j=0; j<8 ; j++) {
 	for (j=0; j<8 ; j++) {
-		struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j));
-		if (temp)
+		struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
+		if (temp) {
+			pci_dev_put(temp);
 			pci_remove_bus_device(temp);
 			pci_remove_bus_device(temp);
+		}
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -178,32 +181,22 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 		if (!rc)
 		if (!rc)
 			return !rc;
 			return !rc;
 
 
-		// set the Edge Level Control Register (ELCR)
+		/* set the Edge Level Control Register (ELCR) */
 		temp_word = inb(0x4d0);
 		temp_word = inb(0x4d0);
 		temp_word |= inb(0x4d1) << 8;
 		temp_word |= inb(0x4d1) << 8;
 
 
 		temp_word |= 0x01 << irq_num;
 		temp_word |= 0x01 << irq_num;
 
 
-		// This should only be for x86 as it sets the Edge Level Control Register
-		outb((u8) (temp_word & 0xFF), 0x4d0);
-		outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
-		rc = 0;
-	}
+		/* This should only be for x86 as it sets the Edge Level
+		 * Control Register
+		 */
+		outb((u8) (temp_word & 0xFF), 0x4d0); outb((u8) ((temp_word &
+		0xFF00) >> 8), 0x4d1); rc = 0; }
 
 
 	return rc;
 	return rc;
 }
 }
 
 
 
 
-/*
- * WTF??? This function isn't in the code, yet a function calls it, but the 
- * compiler optimizes it away?  strange.  Here as a placeholder to keep the 
- * compiler happy.
- */
-static int PCI_ScanBusNonBridge (u8 bus, u8 device)
-{
-	return 0;
-}
-
 static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
 static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
 {
 {
 	u16 tdevice;
 	u16 tdevice;
@@ -213,11 +206,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
 	ctrl->pci_bus->number = bus_num;
 	ctrl->pci_bus->number = bus_num;
 
 
 	for (tdevice = 0; tdevice < 0xFF; tdevice++) {
 	for (tdevice = 0; tdevice < 0xFF; tdevice++) {
-		//Scan for access first
+		/* Scan for access first */
 		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
 		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
 			continue;
 			continue;
 		dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
 		dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
-		//Yep we got one. Not a bridge ?
+		/* Yep we got one. Not a bridge ? */
 		if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
 		if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
 			*dev_num = tdevice;
 			*dev_num = tdevice;
 			dbg("found it !\n");
 			dbg("found it !\n");
@@ -225,16 +218,16 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
 		}
 		}
 	}
 	}
 	for (tdevice = 0; tdevice < 0xFF; tdevice++) {
 	for (tdevice = 0; tdevice < 0xFF; tdevice++) {
-		//Scan for access first
+		/* Scan for access first */
 		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
 		if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
 			continue;
 			continue;
 		dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
 		dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
-		//Yep we got one. bridge ?
+		/* Yep we got one. bridge ? */
 		if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
 		if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
 			pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
 			pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
+			/* XXX: no recursion, wtf? */
 			dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
 			dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
-			if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
-				return 0;
+			return 0;
 		}
 		}
 	}
 	}
 
 
@@ -244,39 +237,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
 
 
 static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
 static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
 {
 {
-	struct irq_routing_table *PCIIRQRoutingInfoLength;
-	long len;
-	long loop;
+	int loop, len;
 	u32 work;
 	u32 work;
-
 	u8 tbus, tdevice, tslot;
 	u8 tbus, tdevice, tslot;
 
 
-	PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
-	if (!PCIIRQRoutingInfoLength)
-		return -1;
-
-	len = (PCIIRQRoutingInfoLength->size -
-	       sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	// Make sure I got at least one entry
-	if (len == 0) {
-		kfree(PCIIRQRoutingInfoLength );
-		return -1;
-	}
-
+	len = cpqhp_routing_table_length();
 	for (loop = 0; loop < len; ++loop) {
 	for (loop = 0; loop < len; ++loop) {
-		tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
-		tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
-		tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
+		tbus = cpqhp_routing_table->slots[loop].bus;
+		tdevice = cpqhp_routing_table->slots[loop].devfn;
+		tslot = cpqhp_routing_table->slots[loop].slot;
 
 
 		if (tslot == slot) {
 		if (tslot == slot) {
 			*bus_num = tbus;
 			*bus_num = tbus;
 			*dev_num = tdevice;
 			*dev_num = tdevice;
 			ctrl->pci_bus->number = tbus;
 			ctrl->pci_bus->number = tbus;
 			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
 			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
-			if (!nobridge || (work == 0xffffffff)) {
-				kfree(PCIIRQRoutingInfoLength );
+			if (!nobridge || (work == 0xffffffff))
 				return 0;
 				return 0;
-			}
 
 
 			dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
 			dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
 			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
 			pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
@@ -287,28 +264,26 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
 				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
 				dbg("Scan bus for Non Bridge: bus %d\n", tbus);
 				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
 				if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
 					*bus_num = tbus;
 					*bus_num = tbus;
-					kfree(PCIIRQRoutingInfoLength );
 					return 0;
 					return 0;
 				}
 				}
-			} else {
-				kfree(PCIIRQRoutingInfoLength );
+			} else
 				return 0;
 				return 0;
-			}
-
 		}
 		}
 	}
 	}
-	kfree(PCIIRQRoutingInfoLength );
 	return -1;
 	return -1;
 }
 }
 
 
 
 
 int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
 int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
 {
 {
-	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);	//plain (bridges allowed)
+	/* plain (bridges allowed) */
+	return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);
 }
 }
 
 
 
 
-/* More PCI configuration routines; this time centered around hotplug controller */
+/* More PCI configuration routines; this time centered around hotplug
+ * controller
+ */
 
 
 
 
 /*
 /*
@@ -339,12 +314,12 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
 	int stop_it;
 	int stop_it;
 	int index;
 	int index;
 
 
-	//              Decide which slots are supported
+	/* Decide which slots are supported */
 
 
 	if (is_hot_plug) {
 	if (is_hot_plug) {
-		//*********************************
-		// is_hot_plug is the slot mask
-		//*********************************
+		/*
+		 * is_hot_plug is the slot mask
+		 */
 		FirstSupported = is_hot_plug >> 4;
 		FirstSupported = is_hot_plug >> 4;
 		LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
 		LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
 	} else {
 	} else {
@@ -352,123 +327,127 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
 		LastSupported = 0x1F;
 		LastSupported = 0x1F;
 	}
 	}
 
 
-	//     Save PCI configuration space for all devices in supported slots
+	/* Save PCI configuration space for all devices in supported slots */
 	ctrl->pci_bus->number = busnumber;
 	ctrl->pci_bus->number = busnumber;
 	for (device = FirstSupported; device <= LastSupported; device++) {
 	for (device = FirstSupported; device <= LastSupported; device++) {
 		ID = 0xFFFFFFFF;
 		ID = 0xFFFFFFFF;
-		rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+		rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+
+		if (ID == 0xFFFFFFFF) {
+			if (is_hot_plug) {
+				/* Setup slot structure with entry for empty
+				 * slot
+				 */
+				new_slot = cpqhp_slot_create(busnumber);
+				if (new_slot == NULL)
+					return 1;
 
 
-		if (ID != 0xFFFFFFFF) {	  //  device in slot
-			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
-			if (rc)
-				return rc;
+				new_slot->bus = (u8) busnumber;
+				new_slot->device = (u8) device;
+				new_slot->function = 0;
+				new_slot->is_a_board = 0;
+				new_slot->presence_save = 0;
+				new_slot->switch_save = 0;
+			}
+			continue;
+		}
 
 
-			rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
-			if (rc)
-				return rc;
+		rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
+		if (rc)
+			return rc;
 
 
-			// If multi-function device, set max_functions to 8
-			if (header_type & 0x80)
-				max_functions = 8;
-			else
-				max_functions = 1;
+		rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
+		if (rc)
+			return rc;
 
 
-			function = 0;
+		/* If multi-function device, set max_functions to 8 */
+		if (header_type & 0x80)
+			max_functions = 8;
+		else
+			max_functions = 1;
 
 
-			do {
-				DevError = 0;
+		function = 0;
 
 
-				if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   // P-P Bridge
-					//  Recurse the subordinate bus
-					//  get the subordinate bus number
-					rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
-					if (rc) {
+		do {
+			DevError = 0;
+			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+				/* Recurse the subordinate bus
+				 * get the subordinate bus number
+				 */
+				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
+				if (rc) {
+					return rc;
+				} else {
+					sub_bus = (int) secondary_bus;
+
+					/* Save secondary bus cfg spc
+					 * with this recursive call.
+					 */
+					rc = cpqhp_save_config(ctrl, sub_bus, 0);
+					if (rc)
 						return rc;
 						return rc;
-					} else {
-						sub_bus = (int) secondary_bus;
-
-						// Save secondary bus cfg spc
-						// with this recursive call.
-						rc = cpqhp_save_config(ctrl, sub_bus, 0);
-						if (rc)
-							return rc;
-						ctrl->pci_bus->number = busnumber;
-					}
+					ctrl->pci_bus->number = busnumber;
 				}
 				}
+			}
 
 
-				index = 0;
+			index = 0;
+			new_slot = cpqhp_slot_find(busnumber, device, index++);
+			while (new_slot &&
+			       (new_slot->function != (u8) function))
 				new_slot = cpqhp_slot_find(busnumber, device, index++);
 				new_slot = cpqhp_slot_find(busnumber, device, index++);
-				while (new_slot && 
-				       (new_slot->function != (u8) function))
-					new_slot = cpqhp_slot_find(busnumber, device, index++);
 
 
-				if (!new_slot) {
-					// Setup slot structure.
-					new_slot = cpqhp_slot_create(busnumber);
-
-					if (new_slot == NULL)
-						return(1);
-				}
-
-				new_slot->bus = (u8) busnumber;
-				new_slot->device = (u8) device;
-				new_slot->function = (u8) function;
-				new_slot->is_a_board = 1;
-				new_slot->switch_save = 0x10;
-				// In case of unsupported board
-				new_slot->status = DevError;
-				new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
-
-				for (cloop = 0; cloop < 0x20; cloop++) {
-					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
-					if (rc)
-						return rc;
-				}
+			if (!new_slot) {
+				/* Setup slot structure. */
+				new_slot = cpqhp_slot_create(busnumber);
+				if (new_slot == NULL)
+					return 1;
+			}
 
 
-				function++;
+			new_slot->bus = (u8) busnumber;
+			new_slot->device = (u8) device;
+			new_slot->function = (u8) function;
+			new_slot->is_a_board = 1;
+			new_slot->switch_save = 0x10;
+			/* In case of unsupported board */
+			new_slot->status = DevError;
+			new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
 
 
-				stop_it = 0;
+			for (cloop = 0; cloop < 0x20; cloop++) {
+				rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
+				if (rc)
+					return rc;
+			}
 
 
-				//  this loop skips to the next present function
-				//  reading in Class Code and Header type.
+			pci_dev_put(new_slot->pci_dev);
 
 
-				while ((function < max_functions)&&(!stop_it)) {
-					rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
-					if (ID == 0xFFFFFFFF) {	 // nothing there.
-						function++;
-					} else {  // Something there
-						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
-						if (rc)
-							return rc;
+			function++;
 
 
-						rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
-						if (rc)
-							return rc;
+			stop_it = 0;
 
 
-						stop_it++;
-					}
+			/* this loop skips to the next present function
+			 * reading in Class Code and Header type.
+			 */
+			while ((function < max_functions) && (!stop_it)) {
+				rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
+				if (ID == 0xFFFFFFFF) {
+					function++;
+					continue;
 				}
 				}
+				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
+				if (rc)
+					return rc;
 
 
-			} while (function < max_functions);
-		}		// End of IF (device in slot?)
-		else if (is_hot_plug) {
-			// Setup slot structure with entry for empty slot
-			new_slot = cpqhp_slot_create(busnumber);
+				rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
+				if (rc)
+					return rc;
 
 
-			if (new_slot == NULL) {
-				return(1);
+				stop_it++;
 			}
 			}
 
 
-			new_slot->bus = (u8) busnumber;
-			new_slot->device = (u8) device;
-			new_slot->function = 0;
-			new_slot->is_a_board = 0;
-			new_slot->presence_save = 0;
-			new_slot->switch_save = 0;
-		}
-	}			// End of FOR loop
+		} while (function < max_functions);
+	}			/* End of FOR loop */
 
 
-	return(0);
+	return 0;
 }
 }
 
 
 
 
@@ -489,7 +468,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
 	u8 secondary_bus;
 	u8 secondary_bus;
 	int sub_bus;
 	int sub_bus;
 	int max_functions;
 	int max_functions;
-	int function;
+	int function = 0;
 	int cloop = 0;
 	int cloop = 0;
 	int stop_it;
 	int stop_it;
 
 
@@ -498,63 +477,58 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
 	ctrl->pci_bus->number = new_slot->bus;
 	ctrl->pci_bus->number = new_slot->bus;
 	pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
 	pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
 
 
-	if (ID != 0xFFFFFFFF) {	  //  device in slot
-		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
-		pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
-
-		if (header_type & 0x80)	// Multi-function device
-			max_functions = 8;
-		else
-			max_functions = 1;
-
-		function = 0;
-
-		do {
-			if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-				//  Recurse the subordinate bus
-				pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
+	if (ID == 0xFFFFFFFF)
+		return 2;
 
 
-				sub_bus = (int) secondary_bus;
+	pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
+	pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
 
 
-				// Save the config headers for the secondary bus.
-				rc = cpqhp_save_config(ctrl, sub_bus, 0);
-				if (rc)
-					return(rc);
-				ctrl->pci_bus->number = new_slot->bus;
+	if (header_type & 0x80)	/* Multi-function device */
+		max_functions = 8;
+	else
+		max_functions = 1;
 
 
-			}	// End of IF
+	while (function < max_functions) {
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+			/*  Recurse the subordinate bus */
+			pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
 
 
-			new_slot->status = 0;
+			sub_bus = (int) secondary_bus;
 
 
-			for (cloop = 0; cloop < 0x20; cloop++) {
-				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
-			}
+			/* Save the config headers for the secondary
+			 * bus.
+			 */
+			rc = cpqhp_save_config(ctrl, sub_bus, 0);
+			if (rc)
+				return(rc);
+			ctrl->pci_bus->number = new_slot->bus;
 
 
-			function++;
+		}
 
 
-			stop_it = 0;
+		new_slot->status = 0;
 
 
-			//  this loop skips to the next present function
-			//  reading in the Class Code and the Header type.
+		for (cloop = 0; cloop < 0x20; cloop++)
+			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
 
 
-			while ((function < max_functions) && (!stop_it)) {
-				pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
+		function++;
 
 
-				if (ID == 0xFFFFFFFF) {	 // nothing there.
-					function++;
-				} else {  // Something there
-					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
+		stop_it = 0;
 
 
-					pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
+		/* this loop skips to the next present function
+		 * reading in the Class Code and the Header type.
+		 */
+		while ((function < max_functions) && (!stop_it)) {
+			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
 
 
-					stop_it++;
-				}
+			if (ID == 0xFFFFFFFF)
+				function++;
+			else {
+				pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
+				pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
+				stop_it++;
 			}
 			}
+		}
 
 
-		} while (function < max_functions);
-	}			// End of IF (device in slot?)
-	else {
-		return 2;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -590,11 +564,10 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
 		pci_bus->number = func->bus;
 		pci_bus->number = func->bus;
 		devfn = PCI_DEVFN(func->device, func->function);
 		devfn = PCI_DEVFN(func->device, func->function);
 
 
-		// Check for Bridge
+		/* Check for Bridge */
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
 
 		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
 		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
-			// PCI-PCI Bridge
 			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 
 
 			sub_bus = (int) secondary_bus;
 			sub_bus = (int) secondary_bus;
@@ -610,23 +583,27 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
 			}
 			}
 			pci_bus->number = func->bus;
 			pci_bus->number = func->bus;
 
 
-			//FIXME: this loop is duplicated in the non-bridge case.  The two could be rolled together
-			// Figure out IO and memory base lengths
+			/* FIXME: this loop is duplicated in the non-bridge
+			 * case.  The two could be rolled together Figure out
+			 * IO and memory base lengths
+			 */
 			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
 			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
 				temp_register = 0xFFFFFFFF;
 				temp_register = 0xFFFFFFFF;
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-
-				if (base) {  // If this register is implemented
+				/* If this register is implemented */
+				if (base) {
 					if (base & 0x01L) {
 					if (base & 0x01L) {
-						// IO base
-						// set base = amount of IO space requested
+						/* IO base
+						 * set base = amount of IO space
+						 * requested
+						 */
 						base = base & 0xFFFFFFFE;
 						base = base & 0xFFFFFFFE;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
 						type = 1;
 						type = 1;
 					} else {
 					} else {
-						// memory base
+						/* memory base */
 						base = base & 0xFFFFFFF0;
 						base = base & 0xFFFFFFF0;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
@@ -637,32 +614,36 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
 					type = 0;
 					type = 0;
 				}
 				}
 
 
-				// Save information in slot structure
+				/* Save information in slot structure */
 				func->base_length[(cloop - 0x10) >> 2] =
 				func->base_length[(cloop - 0x10) >> 2] =
 				base;
 				base;
 				func->base_type[(cloop - 0x10) >> 2] = type;
 				func->base_type[(cloop - 0x10) >> 2] = type;
 
 
-			}	// End of base register loop
+			}	/* End of base register loop */
 
 
-
-		} else if ((header_type & 0x7F) == 0x00) {	  // PCI-PCI Bridge
-			// Figure out IO and memory base lengths
+		} else if ((header_type & 0x7F) == 0x00) {
+			/* Figure out IO and memory base lengths */
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 				temp_register = 0xFFFFFFFF;
 				temp_register = 0xFFFFFFFF;
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
 
 
-				if (base) {  // If this register is implemented
+				/* If this register is implemented */
+				if (base) {
 					if (base & 0x01L) {
 					if (base & 0x01L) {
-						// IO base
-						// base = amount of IO space requested
+						/* IO base
+						 * base = amount of IO space
+						 * requested
+						 */
 						base = base & 0xFFFFFFFE;
 						base = base & 0xFFFFFFFE;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
 						type = 1;
 						type = 1;
 					} else {
 					} else {
-						// memory base
-						// base = amount of memory space requested
+						/* memory base
+						 * base = amount of memory
+						 * space requested
+						 */
 						base = base & 0xFFFFFFF0;
 						base = base & 0xFFFFFFF0;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
@@ -673,16 +654,16 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
 					type = 0;
 					type = 0;
 				}
 				}
 
 
-				// Save information in slot structure
+				/* Save information in slot structure */
 				func->base_length[(cloop - 0x10) >> 2] = base;
 				func->base_length[(cloop - 0x10) >> 2] = base;
 				func->base_type[(cloop - 0x10) >> 2] = type;
 				func->base_type[(cloop - 0x10) >> 2] = type;
 
 
-			}	// End of base register loop
+			}	/* End of base register loop */
 
 
-		} else {	  // Some other unknown header type
+		} else {	  /* Some other unknown header type */
 		}
 		}
 
 
-		// find the next device in this slot
+		/* find the next device in this slot */
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 	}
 	}
 
 
@@ -728,18 +709,18 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 		pci_bus->number = func->bus;
 		pci_bus->number = func->bus;
 		devfn = PCI_DEVFN(func->device, func->function);
 		devfn = PCI_DEVFN(func->device, func->function);
 
 
-		// Save the command register
+		/* Save the command register */
 		pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
 		pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
 
 
-		// disable card
+		/* disable card */
 		command = 0x00;
 		command = 0x00;
 		pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
 		pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
 
 
-		// Check for Bridge
+		/* Check for Bridge */
 		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 		pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
 
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-			// Clear Bridge Control Register
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+			/* Clear Bridge Control Register */
 			command = 0x00;
 			command = 0x00;
 			pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
 			pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
@@ -755,7 +736,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 			bus_node->next = func->bus_head;
 			bus_node->next = func->bus_head;
 			func->bus_head = bus_node;
 			func->bus_head = bus_node;
 
 
-			// Save IO base and Limit registers
+			/* Save IO base and Limit registers */
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base);
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);
 			pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length);
 
 
@@ -771,7 +752,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 				func->io_head = io_node;
 				func->io_head = io_node;
 			}
 			}
 
 
-			// Save memory base and Limit registers
+			/* Save memory base and Limit registers */
 			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
 
 
@@ -787,7 +768,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 				func->mem_head = mem_node;
 				func->mem_head = mem_node;
 			}
 			}
 
 
-			// Save prefetchable memory base and Limit registers
+			/* Save prefetchable memory base and Limit registers */
 			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
 			pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
 
 
@@ -802,7 +783,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 				p_mem_node->next = func->p_mem_head;
 				p_mem_node->next = func->p_mem_head;
 				func->p_mem_head = p_mem_node;
 				func->p_mem_head = p_mem_node;
 			}
 			}
-			// Figure out IO and memory base lengths
+			/* Figure out IO and memory base lengths */
 			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
 			for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
 
 
@@ -812,11 +793,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 
 
 				temp_register = base;
 				temp_register = base;
 
 
-				if (base) {  // If this register is implemented
+				/* If this register is implemented */
+				if (base) {
 					if (((base & 0x03L) == 0x01)
 					if (((base & 0x03L) == 0x01)
 					    && (save_command & 0x01)) {
 					    && (save_command & 0x01)) {
-						// IO base
-						// set temp_register = amount of IO space requested
+						/* IO base
+						 * set temp_register = amount
+						 * of IO space requested
+						 */
 						temp_register = base & 0xFFFFFFFE;
 						temp_register = base & 0xFFFFFFFE;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -834,7 +818,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						if (((base & 0x0BL) == 0x08)
 						if (((base & 0x0BL) == 0x08)
 						    && (save_command & 0x02)) {
 						    && (save_command & 0x02)) {
-						// prefetchable memory base
+						/* prefetchable memory base */
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -851,7 +835,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						if (((base & 0x0BL) == 0x00)
 						if (((base & 0x0BL) == 0x00)
 						    && (save_command & 0x02)) {
 						    && (save_command & 0x02)) {
-						// prefetchable memory base
+						/* prefetchable memory base */
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -868,9 +852,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						return(1);
 						return(1);
 				}
 				}
-			}	// End of base register loop
-		} else if ((header_type & 0x7F) == 0x00) {	  // Standard header
-			// Figure out IO and memory base lengths
+			}	/* End of base register loop */
+		/* Standard header */
+		} else if ((header_type & 0x7F) == 0x00) {
+			/* Figure out IO and memory base lengths */
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 				pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
 				pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
 
 
@@ -880,11 +865,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 
 
 				temp_register = base;
 				temp_register = base;
 
 
-				if (base) {	  // If this register is implemented
+				/* If this register is implemented */
+				if (base) {
 					if (((base & 0x03L) == 0x01)
 					if (((base & 0x03L) == 0x01)
 					    && (save_command & 0x01)) {
 					    && (save_command & 0x01)) {
-						// IO base
-						// set temp_register = amount of IO space requested
+						/* IO base
+						 * set temp_register = amount
+						 * of IO space requested
+						 */
 						temp_register = base & 0xFFFFFFFE;
 						temp_register = base & 0xFFFFFFFE;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -901,7 +889,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						if (((base & 0x0BL) == 0x08)
 						if (((base & 0x0BL) == 0x08)
 						    && (save_command & 0x02)) {
 						    && (save_command & 0x02)) {
-						// prefetchable memory base
+						/* prefetchable memory base */
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -918,7 +906,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						if (((base & 0x0BL) == 0x00)
 						if (((base & 0x0BL) == 0x00)
 						    && (save_command & 0x02)) {
 						    && (save_command & 0x02)) {
-						// prefetchable memory base
+						/* prefetchable memory base */
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = base & 0xFFFFFFF0;
 						temp_register = (~temp_register) + 1;
 						temp_register = (~temp_register) + 1;
 
 
@@ -935,15 +923,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
 					} else
 					} else
 						return(1);
 						return(1);
 				}
 				}
-			}	// End of base register loop
-		} else {	  // Some other unknown header type
+			}	/* End of base register loop */
 		}
 		}
 
 
-		// find the next device in this slot
+		/* find the next device in this slot */
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 	}
 	}
 
 
-	return(0);
+	return 0;
 }
 }
 
 
 
 
@@ -975,16 +962,16 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
 		pci_bus->number = func->bus;
 		pci_bus->number = func->bus;
 		devfn = PCI_DEVFN(func->device, func->function);
 		devfn = PCI_DEVFN(func->device, func->function);
 
 
-		// Start at the top of config space so that the control
-		// registers are programmed last
-		for (cloop = 0x3C; cloop > 0; cloop -= 4) {
+		/* Start at the top of config space so that the control
+		 * registers are programmed last
+		 */
+		for (cloop = 0x3C; cloop > 0; cloop -= 4)
 			pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
 			pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
-		}
 
 
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
 
-		// If this is a bridge device, restore subordinate devices
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
+		/* If this is a bridge device, restore subordinate devices */
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
 			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 			pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 
 
 			sub_bus = (int) secondary_bus;
 			sub_bus = (int) secondary_bus;
@@ -1000,8 +987,9 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
 			}
 			}
 		} else {
 		} else {
 
 
-			// Check all the base Address Registers to make sure
-			// they are the same.  If not, the board is different.
+			/* Check all the base Address Registers to make sure
+			 * they are the same.  If not, the board is different.
+			 */
 
 
 			for (cloop = 16; cloop < 40; cloop += 4) {
 			for (cloop = 16; cloop < 40; cloop += 4) {
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
@@ -1058,27 +1046,28 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
 
 
 		pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
 		pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
 
 
-		// No adapter present
+		/* No adapter present */
 		if (temp_register == 0xFFFFFFFF)
 		if (temp_register == 0xFFFFFFFF)
 			return(NO_ADAPTER_PRESENT);
 			return(NO_ADAPTER_PRESENT);
 
 
 		if (temp_register != func->config_space[0])
 		if (temp_register != func->config_space[0])
 			return(ADAPTER_NOT_SAME);
 			return(ADAPTER_NOT_SAME);
 
 
-		// Check for same revision number and class code
+		/* Check for same revision number and class code */
 		pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
 		pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
 
 
-		// Adapter not the same
+		/* Adapter not the same */
 		if (temp_register != func->config_space[0x08 >> 2])
 		if (temp_register != func->config_space[0x08 >> 2])
 			return(ADAPTER_NOT_SAME);
 			return(ADAPTER_NOT_SAME);
 
 
-		// Check for Bridge
+		/* Check for Bridge */
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 		pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 
 
-		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {	  // PCI-PCI Bridge
-			// In order to continue checking, we must program the
-			// bus registers in the bridge to respond to accesses
-			// for it's subordinate bus(es)
+		if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
+			/* In order to continue checking, we must program the
+			 * bus registers in the bridge to respond to accesses
+			 * for its subordinate bus(es)
+			 */
 
 
 			temp_register = func->config_space[0x18 >> 2];
 			temp_register = func->config_space[0x18 >> 2];
 			pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
 			pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
@@ -1096,35 +1085,39 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
 			}
 			}
 
 
 		}
 		}
-		// Check to see if it is a standard config header
+		/* Check to see if it is a standard config header */
 		else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
 		else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
-			// Check subsystem vendor and ID
+			/* Check subsystem vendor and ID */
 			pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
 			pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
 
 
 			if (temp_register != func->config_space[0x2C >> 2]) {
 			if (temp_register != func->config_space[0x2C >> 2]) {
-				// If it's a SMART-2 and the register isn't filled
-				// in, ignore the difference because
-				// they just have an old rev of the firmware
-
+				/* If it's a SMART-2 and the register isn't
+				 * filled in, ignore the difference because
+				 * they just have an old rev of the firmware
+				 */
 				if (!((func->config_space[0] == 0xAE100E11)
 				if (!((func->config_space[0] == 0xAE100E11)
 				      && (temp_register == 0x00L)))
 				      && (temp_register == 0x00L)))
 					return(ADAPTER_NOT_SAME);
 					return(ADAPTER_NOT_SAME);
 			}
 			}
-			// Figure out IO and memory base lengths
+			/* Figure out IO and memory base lengths */
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 			for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
 				temp_register = 0xFFFFFFFF;
 				temp_register = 0xFFFFFFFF;
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
 				pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
-				if (base) {	  // If this register is implemented
+
+				/* If this register is implemented */
+				if (base) {
 					if (base & 0x01L) {
 					if (base & 0x01L) {
-						// IO base
-						// set base = amount of IO space requested
+						/* IO base
+						 * set base = amount of IO
+						 * space requested
+						 */
 						base = base & 0xFFFFFFFE;
 						base = base & 0xFFFFFFFE;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
 						type = 1;
 						type = 1;
 					} else {
 					} else {
-						// memory base
+						/* memory base */
 						base = base & 0xFFFFFFF0;
 						base = base & 0xFFFFFFF0;
 						base = (~base) + 1;
 						base = (~base) + 1;
 
 
@@ -1135,23 +1128,24 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
 					type = 0;
 					type = 0;
 				}
 				}
 
 
-				// Check information in slot structure
+				/* Check information in slot structure */
 				if (func->base_length[(cloop - 0x10) >> 2] != base)
 				if (func->base_length[(cloop - 0x10) >> 2] != base)
 					return(ADAPTER_NOT_SAME);
 					return(ADAPTER_NOT_SAME);
 
 
 				if (func->base_type[(cloop - 0x10) >> 2] != type)
 				if (func->base_type[(cloop - 0x10) >> 2] != type)
 					return(ADAPTER_NOT_SAME);
 					return(ADAPTER_NOT_SAME);
 
 
-			}	// End of base register loop
+			}	/* End of base register loop */
 
 
-		}		// End of (type 0 config space) else
+		}		/* End of (type 0 config space) else */
 		else {
 		else {
-			// this is not a type 0 or 1 config space header so
-			// we don't know how to do it
+			/* this is not a type 0 or 1 config space header so
+			 * we don't know how to do it
+			 */
 			return(DEVICE_TYPE_NOT_SUPPORTED);
 			return(DEVICE_TYPE_NOT_SUPPORTED);
 		}
 		}
 
 
-		// Get the next function
+		/* Get the next function */
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 		func = cpqhp_slot_find(func->bus, func->device, index++);
 	}
 	}
 
 
@@ -1168,7 +1162,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
  * this function is for hot plug ADD!
  * this function is for hot plug ADD!
  *
  *
  * returns 0 if success
  * returns 0 if success
- */  
+ */
 int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
 int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
 {
 {
 	u8 temp;
 	u8 temp;
@@ -1187,10 +1181,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
 	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
 	dbg("rom_resource_table = %p\n", rom_resource_table);
 	dbg("rom_resource_table = %p\n", rom_resource_table);
 
 
-	if (rom_resource_table == NULL) {
+	if (rom_resource_table == NULL)
 		return -ENODEV;
 		return -ENODEV;
-	}
-	// Sum all resources and setup resource maps
+
+	/* Sum all resources and setup resource maps */
 	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
 	unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
 	dbg("unused_IRQ = %x\n", unused_IRQ);
 	dbg("unused_IRQ = %x\n", unused_IRQ);
 
 
@@ -1222,13 +1216,11 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 
 
 	temp = 0;
 	temp = 0;
 
 
-	if (!cpqhp_nic_irq) {
+	if (!cpqhp_nic_irq)
 		cpqhp_nic_irq = ctrl->cfgspc_irq;
 		cpqhp_nic_irq = ctrl->cfgspc_irq;
-	}
 
 
-	if (!cpqhp_disk_irq) {
+	if (!cpqhp_disk_irq)
 		cpqhp_disk_irq = ctrl->cfgspc_irq;
 		cpqhp_disk_irq = ctrl->cfgspc_irq;
-	}
 
 
 	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
 	dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
 
 
@@ -1262,13 +1254,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
 		    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
 		    primary_bus, secondary_bus, max_bus);
 		    primary_bus, secondary_bus, max_bus);
 
 
-		// If this entry isn't for our controller's bus, ignore it
+		/* If this entry isn't for our controller's bus, ignore it */
 		if (primary_bus != ctrl->bus) {
 		if (primary_bus != ctrl->bus) {
 			i--;
 			i--;
 			one_slot += sizeof (struct slot_rt);
 			one_slot += sizeof (struct slot_rt);
 			continue;
 			continue;
 		}
 		}
-		// find out if this entry is for an occupied slot
+		/* find out if this entry is for an occupied slot */
 		ctrl->pci_bus->number = primary_bus;
 		ctrl->pci_bus->number = primary_bus;
 		pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
 		pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
 		dbg("temp_D_word = %x\n", temp_dword);
 		dbg("temp_D_word = %x\n", temp_dword);
@@ -1282,13 +1274,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
 				func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
 			}
 			}
 
 
-			// If we can't find a match, skip this table entry
+			/* If we can't find a match, skip this table entry */
 			if (!func) {
 			if (!func) {
 				i--;
 				i--;
 				one_slot += sizeof (struct slot_rt);
 				one_slot += sizeof (struct slot_rt);
 				continue;
 				continue;
 			}
 			}
-			// this may not work and shouldn't be used
+			/* this may not work and shouldn't be used */
 			if (secondary_bus != primary_bus)
 			if (secondary_bus != primary_bus)
 				bridged_slot = 1;
 				bridged_slot = 1;
 			else
 			else
@@ -1301,7 +1293,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 		}
 		}
 
 
 
 
-		// If we've got a valid IO base, use it
+		/* If we've got a valid IO base, use it */
 
 
 		temp_dword = io_base + io_length;
 		temp_dword = io_base + io_length;
 
 
@@ -1325,7 +1317,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 			}
 			}
 		}
 		}
 
 
-		// If we've got a valid memory base, use it
+		/* If we've got a valid memory base, use it */
 		temp_dword = mem_base + mem_length;
 		temp_dword = mem_base + mem_length;
 		if ((mem_base) && (temp_dword < 0x10000)) {
 		if ((mem_base) && (temp_dword < 0x10000)) {
 			mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
 			mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL);
@@ -1348,8 +1340,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 			}
 			}
 		}
 		}
 
 
-		// If we've got a valid prefetchable memory base, and
-		// the base + length isn't greater than 0xFFFF
+		/* If we've got a valid prefetchable memory base, and
+		 * the base + length isn't greater than 0xFFFF
+		 */
 		temp_dword = pre_mem_base + pre_mem_length;
 		temp_dword = pre_mem_base + pre_mem_length;
 		if ((pre_mem_base) && (temp_dword < 0x10000)) {
 		if ((pre_mem_base) && (temp_dword < 0x10000)) {
 			p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
 			p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL);
@@ -1372,9 +1365,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 			}
 			}
 		}
 		}
 
 
-		// If we've got a valid bus number, use it
-		// The second condition is to ignore bus numbers on
-		// populated slots that don't have PCI-PCI bridges
+		/* If we've got a valid bus number, use it
+		 * The second condition is to ignore bus numbers on
+		 * populated slots that don't have PCI-PCI bridges
+		 */
 		if (secondary_bus && (secondary_bus != primary_bus)) {
 		if (secondary_bus && (secondary_bus != primary_bus)) {
 			bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
 			bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL);
 			if (!bus_node)
 			if (!bus_node)
@@ -1398,8 +1392,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
 		one_slot += sizeof (struct slot_rt);
 		one_slot += sizeof (struct slot_rt);
 	}
 	}
 
 
-	// If all of the following fail, we don't have any resources for
-	// hot plug add
+	/* If all of the following fail, we don't have any resources for
+	 * hot plug add
+	 */
 	rc = 1;
 	rc = 1;
 	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
 	rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
 	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
 	rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));

+ 1 - 1
drivers/pci/hotplug/ibmphp_core.c

@@ -1318,7 +1318,6 @@ error:
 }
 }
 
 
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
-	.owner =			THIS_MODULE,
 	.set_attention_status =		set_attention_status,
 	.set_attention_status =		set_attention_status,
 	.enable_slot =			enable_slot,
 	.enable_slot =			enable_slot,
 	.disable_slot =			ibmphp_disable_slot,
 	.disable_slot =			ibmphp_disable_slot,
@@ -1421,3 +1420,4 @@ static void __exit ibmphp_exit(void)
 }
 }
 
 
 module_init(ibmphp_init);
 module_init(ibmphp_init);
+module_exit(ibmphp_exit);

+ 84 - 71
drivers/pci/hotplug/pci_hotplug_core.c

@@ -347,125 +347,129 @@ static struct pci_slot_attribute hotplug_slot_attr_test = {
 	.store = test_write_file
 	.store = test_write_file
 };
 };
 
 
-static int has_power_file(struct pci_slot *pci_slot)
+static bool has_power_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if ((slot->ops->enable_slot) ||
 	if ((slot->ops->enable_slot) ||
 	    (slot->ops->disable_slot) ||
 	    (slot->ops->disable_slot) ||
 	    (slot->ops->get_power_status))
 	    (slot->ops->get_power_status))
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_attention_file(struct pci_slot *pci_slot)
+static bool has_attention_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if ((slot->ops->set_attention_status) ||
 	if ((slot->ops->set_attention_status) ||
 	    (slot->ops->get_attention_status))
 	    (slot->ops->get_attention_status))
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_latch_file(struct pci_slot *pci_slot)
+static bool has_latch_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if (slot->ops->get_latch_status)
 	if (slot->ops->get_latch_status)
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_adapter_file(struct pci_slot *pci_slot)
+static bool has_adapter_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if (slot->ops->get_adapter_status)
 	if (slot->ops->get_adapter_status)
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_max_bus_speed_file(struct pci_slot *pci_slot)
+static bool has_max_bus_speed_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if (slot->ops->get_max_bus_speed)
 	if (slot->ops->get_max_bus_speed)
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_cur_bus_speed_file(struct pci_slot *pci_slot)
+static bool has_cur_bus_speed_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if (slot->ops->get_cur_bus_speed)
 	if (slot->ops->get_cur_bus_speed)
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
-static int has_test_file(struct pci_slot *pci_slot)
+static bool has_test_file(struct pci_slot *pci_slot)
 {
 {
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	struct hotplug_slot *slot = pci_slot->hotplug;
 	if ((!slot) || (!slot->ops))
 	if ((!slot) || (!slot->ops))
-		return -ENODEV;
+		return false;
 	if (slot->ops->hardware_test)
 	if (slot->ops->hardware_test)
-		return 0;
-	return -ENOENT;
+		return true;
+	return false;
 }
 }
 
 
 static int fs_add_slot(struct pci_slot *slot)
 static int fs_add_slot(struct pci_slot *slot)
 {
 {
 	int retval = 0;
 	int retval = 0;
 
 
-	if (has_power_file(slot) == 0) {
-		retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+	/* Create symbolic link to the hotplug driver module */
+	pci_hp_create_module_link(slot);
+
+	if (has_power_file(slot)) {
+		retval = sysfs_create_file(&slot->kobj,
+					   &hotplug_slot_attr_power.attr);
 		if (retval)
 		if (retval)
 			goto exit_power;
 			goto exit_power;
 	}
 	}
 
 
-	if (has_attention_file(slot) == 0) {
+	if (has_attention_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
 					   &hotplug_slot_attr_attention.attr);
 					   &hotplug_slot_attr_attention.attr);
 		if (retval)
 		if (retval)
 			goto exit_attention;
 			goto exit_attention;
 	}
 	}
 
 
-	if (has_latch_file(slot) == 0) {
+	if (has_latch_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
 					   &hotplug_slot_attr_latch.attr);
 					   &hotplug_slot_attr_latch.attr);
 		if (retval)
 		if (retval)
 			goto exit_latch;
 			goto exit_latch;
 	}
 	}
 
 
-	if (has_adapter_file(slot) == 0) {
+	if (has_adapter_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
 					   &hotplug_slot_attr_presence.attr);
 					   &hotplug_slot_attr_presence.attr);
 		if (retval)
 		if (retval)
 			goto exit_adapter;
 			goto exit_adapter;
 	}
 	}
 
 
-	if (has_max_bus_speed_file(slot) == 0) {
+	if (has_max_bus_speed_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
-					   &hotplug_slot_attr_max_bus_speed.attr);
+					&hotplug_slot_attr_max_bus_speed.attr);
 		if (retval)
 		if (retval)
 			goto exit_max_speed;
 			goto exit_max_speed;
 	}
 	}
 
 
-	if (has_cur_bus_speed_file(slot) == 0) {
+	if (has_cur_bus_speed_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
-					   &hotplug_slot_attr_cur_bus_speed.attr);
+					&hotplug_slot_attr_cur_bus_speed.attr);
 		if (retval)
 		if (retval)
 			goto exit_cur_speed;
 			goto exit_cur_speed;
 	}
 	}
 
 
-	if (has_test_file(slot) == 0) {
+	if (has_test_file(slot)) {
 		retval = sysfs_create_file(&slot->kobj,
 		retval = sysfs_create_file(&slot->kobj,
 					   &hotplug_slot_attr_test.attr);
 					   &hotplug_slot_attr_test.attr);
 		if (retval)
 		if (retval)
@@ -475,55 +479,61 @@ static int fs_add_slot(struct pci_slot *slot)
 	goto exit;
 	goto exit;
 
 
 exit_test:
 exit_test:
-	if (has_cur_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
-
+	if (has_cur_bus_speed_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_cur_bus_speed.attr);
 exit_cur_speed:
 exit_cur_speed:
-	if (has_max_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
-
+	if (has_max_bus_speed_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_max_bus_speed.attr);
 exit_max_speed:
 exit_max_speed:
-	if (has_adapter_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
-
+	if (has_adapter_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_presence.attr);
 exit_adapter:
 exit_adapter:
-	if (has_latch_file(slot) == 0)
+	if (has_latch_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
-
 exit_latch:
 exit_latch:
-	if (has_attention_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
-
+	if (has_attention_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_attention.attr);
 exit_attention:
 exit_attention:
-	if (has_power_file(slot) == 0)
+	if (has_power_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
 exit_power:
 exit_power:
+	pci_hp_remove_module_link(slot);
 exit:
 exit:
 	return retval;
 	return retval;
 }
 }
 
 
 static void fs_remove_slot(struct pci_slot *slot)
 static void fs_remove_slot(struct pci_slot *slot)
 {
 {
-	if (has_power_file(slot) == 0)
+	if (has_power_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
 
 
-	if (has_attention_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+	if (has_attention_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_attention.attr);
 
 
-	if (has_latch_file(slot) == 0)
+	if (has_latch_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
 
-	if (has_adapter_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+	if (has_adapter_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_presence.attr);
 
 
-	if (has_max_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+	if (has_max_bus_speed_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_max_bus_speed.attr);
 
 
-	if (has_cur_bus_speed_file(slot) == 0)
-		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+	if (has_cur_bus_speed_file(slot))
+		sysfs_remove_file(&slot->kobj,
+				  &hotplug_slot_attr_cur_bus_speed.attr);
 
 
-	if (has_test_file(slot) == 0)
+	if (has_test_file(slot))
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
+
+	pci_hp_remove_module_link(slot);
 }
 }
 
 
 static struct hotplug_slot *get_slot_from_name (const char *name)
 static struct hotplug_slot *get_slot_from_name (const char *name)
@@ -540,10 +550,10 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
 }
 }
 
 
 /**
 /**
- * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
+ * __pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
  * @bus: bus this slot is on
  * @bus: bus this slot is on
  * @slot: pointer to the &struct hotplug_slot to register
  * @slot: pointer to the &struct hotplug_slot to register
- * @slot_nr: slot number
+ * @devnr: device number
  * @name: name registered with kobject core
  * @name: name registered with kobject core
  *
  *
  * Registers a hotplug slot with the pci hotplug subsystem, which will allow
  * Registers a hotplug slot with the pci hotplug subsystem, which will allow
@@ -551,8 +561,9 @@ static struct hotplug_slot *get_slot_from_name (const char *name)
  *
  *
  * Returns 0 if successful, anything else for an error.
  * Returns 0 if successful, anything else for an error.
  */
  */
-int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
-			const char *name)
+int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus,
+		      int devnr, const char *name,
+		      struct module *owner, const char *mod_name)
 {
 {
 	int result;
 	int result;
 	struct pci_slot *pci_slot;
 	struct pci_slot *pci_slot;
@@ -567,14 +578,16 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	mutex_lock(&pci_hp_mutex);
+	slot->ops->owner = owner;
+	slot->ops->mod_name = mod_name;
 
 
+	mutex_lock(&pci_hp_mutex);
 	/*
 	/*
 	 * No problems if we call this interface from both ACPI_PCI_SLOT
 	 * No problems if we call this interface from both ACPI_PCI_SLOT
 	 * driver and call it here again. If we've already created the
 	 * driver and call it here again. If we've already created the
 	 * pci_slot, the interface will simply bump the refcount.
 	 * pci_slot, the interface will simply bump the refcount.
 	 */
 	 */
-	pci_slot = pci_create_slot(bus, slot_nr, name, slot);
+	pci_slot = pci_create_slot(bus, devnr, name, slot);
 	if (IS_ERR(pci_slot)) {
 	if (IS_ERR(pci_slot)) {
 		result = PTR_ERR(pci_slot);
 		result = PTR_ERR(pci_slot);
 		goto out;
 		goto out;
@@ -684,6 +697,6 @@ MODULE_LICENSE("GPL");
 module_param(debug, bool, 0644);
 module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
 
 
-EXPORT_SYMBOL_GPL(pci_hp_register);
+EXPORT_SYMBOL_GPL(__pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);

+ 0 - 3
drivers/pci/hotplug/pciehp.h

@@ -81,7 +81,6 @@ struct slot {
 	struct hpc_ops *hpc_ops;
 	struct hpc_ops *hpc_ops;
 	struct hotplug_slot *hotplug_slot;
 	struct hotplug_slot *hotplug_slot;
 	struct list_head	slot_list;
 	struct list_head	slot_list;
-	unsigned long last_emi_toggle;
 	struct delayed_work work;	/* work for button event */
 	struct delayed_work work;	/* work for button event */
 	struct mutex lock;
 	struct mutex lock;
 };
 };
@@ -203,8 +202,6 @@ struct hpc_ops {
 	int (*set_attention_status)(struct slot *slot, u8 status);
 	int (*set_attention_status)(struct slot *slot, u8 status);
 	int (*get_latch_status)(struct slot *slot, u8 *status);
 	int (*get_latch_status)(struct slot *slot, u8 *status);
 	int (*get_adapter_status)(struct slot *slot, u8 *status);
 	int (*get_adapter_status)(struct slot *slot, u8 *status);
-	int (*get_emi_status)(struct slot *slot, u8 *status);
-	int (*toggle_emi)(struct slot *slot);
 	int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
 	int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val);
 	int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val);

+ 1 - 111
drivers/pci/hotplug/pciehp_core.c

@@ -73,7 +73,6 @@ static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *val
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
 
 static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
 static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
 	.set_attention_status =	set_attention_status,
 	.set_attention_status =	set_attention_status,
 	.enable_slot =		enable_slot,
 	.enable_slot =		enable_slot,
 	.disable_slot =		disable_slot,
 	.disable_slot =		disable_slot,
@@ -85,99 +84,6 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
   	.get_cur_bus_speed =	get_cur_bus_speed,
   	.get_cur_bus_speed =	get_cur_bus_speed,
 };
 };
 
 
-/*
- * Check the status of the Electro Mechanical Interlock (EMI)
- */
-static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value)
-{
-	struct slot *slot = hotplug_slot->private;
-	return (slot->hpc_ops->get_emi_status(slot, value));
-}
-
-/*
- * sysfs interface for the Electro Mechanical Interlock (EMI)
- * 1 == locked, 0 == unlocked
- */
-static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf)
-{
-	int retval;
-	u8 value;
-
-	retval = get_lock_status(slot, &value);
-	if (retval)
-		goto lock_read_exit;
-	retval = sprintf (buf, "%d\n", value);
-
-lock_read_exit:
-	return retval;
-}
-
-/*
- * Change the status of the Electro Mechanical Interlock (EMI)
- * This is a toggle - in addition there must be at least 1 second
- * in between toggles.
- */
-static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
-{
-	struct slot *slot = hotplug_slot->private;
-	int retval;
-	u8 value;
-
-	mutex_lock(&slot->ctrl->crit_sect);
-
-	/* has it been >1 sec since our last toggle? */
-	if ((get_seconds() - slot->last_emi_toggle) < 1) {
-		mutex_unlock(&slot->ctrl->crit_sect);
-		return -EINVAL;
-	}
-
-	/* see what our current state is */
-	retval = get_lock_status(hotplug_slot, &value);
-	if (retval || (value == status))
-		goto set_lock_exit;
-
-	slot->hpc_ops->toggle_emi(slot);
-set_lock_exit:
-	mutex_unlock(&slot->ctrl->crit_sect);
-	return 0;
-}
-
-/*
- * sysfs interface which allows the user to toggle the Electro Mechanical
- * Interlock.  Valid values are either 0 or 1.  0 == unlock, 1 == lock
- */
-static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot,
-		const char *buf, size_t count)
-{
-	struct slot *slot = hotplug_slot->private;
-	unsigned long llock;
-	u8 lock;
-	int retval = 0;
-
-	llock = simple_strtoul(buf, NULL, 10);
-	lock = (u8)(llock & 0xff);
-
-	switch (lock) {
-		case 0:
-		case 1:
-			retval = set_lock_status(hotplug_slot, lock);
-			break;
-		default:
-			ctrl_err(slot->ctrl, "%d is an invalid lock value\n",
-				 lock);
-			retval = -EINVAL;
-	}
-	if (retval)
-		return retval;
-	return count;
-}
-
-static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
-	.attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR},
-	.show = lock_read_file,
-	.store = lock_write_file
-};
-
 /**
 /**
  * release_slot - free up the memory used by a slot
  * release_slot - free up the memory used by a slot
  * @hotplug_slot: slot to free
  * @hotplug_slot: slot to free
@@ -236,17 +142,6 @@ static int init_slots(struct controller *ctrl)
 		get_attention_status(hotplug_slot, &info->attention_status);
 		get_attention_status(hotplug_slot, &info->attention_status);
 		get_latch_status(hotplug_slot, &info->latch_status);
 		get_latch_status(hotplug_slot, &info->latch_status);
 		get_adapter_status(hotplug_slot, &info->adapter_status);
 		get_adapter_status(hotplug_slot, &info->adapter_status);
-		/* create additional sysfs entries */
-		if (EMI(ctrl)) {
-			retval = sysfs_create_file(&hotplug_slot->pci_slot->kobj,
-				&hotplug_slot_attr_lock.attr);
-			if (retval) {
-				pci_hp_deregister(hotplug_slot);
-				ctrl_err(ctrl, "Cannot create additional sysfs "
-					 "entries\n");
-				goto error_info;
-			}
-		}
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -261,13 +156,8 @@ error:
 static void cleanup_slots(struct controller *ctrl)
 static void cleanup_slots(struct controller *ctrl)
 {
 {
 	struct slot *slot;
 	struct slot *slot;
-
-	list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
-		if (EMI(ctrl))
-			sysfs_remove_file(&slot->hotplug_slot->pci_slot->kobj,
-				&hotplug_slot_attr_lock.attr);
+	list_for_each_entry(slot, &ctrl->slot_list, slot_list)
 		pci_hp_deregister(slot->hotplug_slot);
 		pci_hp_deregister(slot->hotplug_slot);
-	}
 }
 }
 
 
 /*
 /*

+ 0 - 31
drivers/pci/hotplug/pciehp_hpc.c

@@ -422,35 +422,6 @@ static int hpc_query_power_fault(struct slot *slot)
 	return !!(slot_status & PCI_EXP_SLTSTA_PFD);
 	return !!(slot_status & PCI_EXP_SLTSTA_PFD);
 }
 }
 
 
-static int hpc_get_emi_status(struct slot *slot, u8 *status)
-{
-	struct controller *ctrl = slot->ctrl;
-	u16 slot_status;
-	int retval;
-
-	retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status);
-	if (retval) {
-		ctrl_err(ctrl, "Cannot check EMI status\n");
-		return retval;
-	}
-	*status = !!(slot_status & PCI_EXP_SLTSTA_EIS);
-	return retval;
-}
-
-static int hpc_toggle_emi(struct slot *slot)
-{
-	u16 slot_cmd;
-	u16 cmd_mask;
-	int rc;
-
-	slot_cmd = PCI_EXP_SLTCTL_EIC;
-	cmd_mask = PCI_EXP_SLTCTL_EIC;
-	rc = pcie_write_cmd(slot->ctrl, slot_cmd, cmd_mask);
-	slot->last_emi_toggle = get_seconds();
-
-	return rc;
-}
-
 static int hpc_set_attention_status(struct slot *slot, u8 value)
 static int hpc_set_attention_status(struct slot *slot, u8 value)
 {
 {
 	struct controller *ctrl = slot->ctrl;
 	struct controller *ctrl = slot->ctrl;
@@ -874,8 +845,6 @@ static struct hpc_ops pciehp_hpc_ops = {
 	.get_attention_status		= hpc_get_attention_status,
 	.get_attention_status		= hpc_get_attention_status,
 	.get_latch_status		= hpc_get_latch_status,
 	.get_latch_status		= hpc_get_latch_status,
 	.get_adapter_status		= hpc_get_adapter_status,
 	.get_adapter_status		= hpc_get_adapter_status,
-	.get_emi_status			= hpc_get_emi_status,
-	.toggle_emi			= hpc_toggle_emi,
 
 
 	.get_max_bus_speed		= hpc_get_max_lnk_speed,
 	.get_max_bus_speed		= hpc_get_max_lnk_speed,
 	.get_cur_bus_speed		= hpc_get_cur_lnk_speed,
 	.get_cur_bus_speed		= hpc_get_cur_lnk_speed,

+ 0 - 1
drivers/pci/hotplug/pcihp_skeleton.c

@@ -82,7 +82,6 @@ static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
 
 
 static struct hotplug_slot_ops skel_hotplug_slot_ops = {
 static struct hotplug_slot_ops skel_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
 	.enable_slot =		enable_slot,
 	.enable_slot =		enable_slot,
 	.disable_slot =		disable_slot,
 	.disable_slot =		disable_slot,
 	.set_attention_status =	set_attention_status,
 	.set_attention_status =	set_attention_status,

+ 0 - 1
drivers/pci/hotplug/rpaphp_core.c

@@ -423,7 +423,6 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
 }
 }
 
 
 struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
 struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
-	.owner = THIS_MODULE,
 	.enable_slot = enable_slot,
 	.enable_slot = enable_slot,
 	.disable_slot = disable_slot,
 	.disable_slot = disable_slot,
 	.set_attention_status = set_attention_status,
 	.set_attention_status = set_attention_status,

+ 0 - 1
drivers/pci/hotplug/sgi_hotplug.c

@@ -83,7 +83,6 @@ static int disable_slot(struct hotplug_slot *slot);
 static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
 static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
 
 
 static struct hotplug_slot_ops sn_hotplug_slot_ops = {
 static struct hotplug_slot_ops sn_hotplug_slot_ops = {
-	.owner                  = THIS_MODULE,
 	.enable_slot            = enable_slot,
 	.enable_slot            = enable_slot,
 	.disable_slot           = disable_slot,
 	.disable_slot           = disable_slot,
 	.get_power_status       = get_power_status,
 	.get_power_status       = get_power_status,

+ 0 - 1
drivers/pci/hotplug/shpchp_core.c

@@ -69,7 +69,6 @@ static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *val
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
 
 static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
 static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
-	.owner =		THIS_MODULE,
 	.set_attention_status =	set_attention_status,
 	.set_attention_status =	set_attention_status,
 	.enable_slot =		enable_slot,
 	.enable_slot =		enable_slot,
 	.disable_slot =		disable_slot,
 	.disable_slot =		disable_slot,

+ 4 - 2
drivers/pci/iov.c

@@ -110,7 +110,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
 	}
 	}
 
 
 	if (reset)
 	if (reset)
-		pci_execute_reset_function(virtfn);
+		__pci_reset_function(virtfn);
 
 
 	pci_device_add(virtfn, virtfn->bus);
 	pci_device_add(virtfn, virtfn->bus);
 	mutex_unlock(&iov->dev->sriov->lock);
 	mutex_unlock(&iov->dev->sriov->lock);
@@ -164,7 +164,7 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
 
 
 	if (reset) {
 	if (reset) {
 		device_release_driver(&virtfn->dev);
 		device_release_driver(&virtfn->dev);
-		pci_execute_reset_function(virtfn);
+		__pci_reset_function(virtfn);
 	}
 	}
 
 
 	sprintf(buf, "virtfn%u", id);
 	sprintf(buf, "virtfn%u", id);
@@ -487,6 +487,8 @@ found:
 	iov->self = dev;
 	iov->self = dev;
 	pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
 	pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
 	pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
 	pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
+	if (dev->pcie_type == PCI_EXP_TYPE_RC_END)
+		iov->link = PCI_DEVFN(PCI_SLOT(dev->devfn), iov->link);
 
 
 	if (pdev)
 	if (pdev)
 		iov->dev = pci_dev_get(pdev);
 		iov->dev = pci_dev_get(pdev);

+ 51 - 49
drivers/pci/msi.c

@@ -75,22 +75,17 @@ void arch_teardown_msi_irqs(struct pci_dev *dev)
 }
 }
 #endif
 #endif
 
 
-static void __msi_set_enable(struct pci_dev *dev, int pos, int enable)
+static void msi_set_enable(struct pci_dev *dev, int pos, int enable)
 {
 {
 	u16 control;
 	u16 control;
 
 
-	if (pos) {
-		pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
-		control &= ~PCI_MSI_FLAGS_ENABLE;
-		if (enable)
-			control |= PCI_MSI_FLAGS_ENABLE;
-		pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
-	}
-}
+	BUG_ON(!pos);
 
 
-static void msi_set_enable(struct pci_dev *dev, int enable)
-{
-	__msi_set_enable(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), enable);
+	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+	control &= ~PCI_MSI_FLAGS_ENABLE;
+	if (enable)
+		control |= PCI_MSI_FLAGS_ENABLE;
+	pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
 }
 }
 
 
 static void msix_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
@@ -131,9 +126,6 @@ static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
  * mask all MSI interrupts by clearing the MSI enable bit does not work
  * mask all MSI interrupts by clearing the MSI enable bit does not work
  * reliably as devices without an INTx disable bit will then generate a
  * reliably as devices without an INTx disable bit will then generate a
  * level IRQ which will never be cleared.
  * level IRQ which will never be cleared.
- *
- * Returns 1 if it succeeded in masking the interrupt and 0 if the device
- * doesn't support MSI masking.
  */
  */
 static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
 static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
 {
 {
@@ -303,7 +295,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
 	pos = entry->msi_attrib.pos;
 	pos = entry->msi_attrib.pos;
 
 
 	pci_intx_for_msi(dev, 0);
 	pci_intx_for_msi(dev, 0);
-	msi_set_enable(dev, 0);
+	msi_set_enable(dev, pos, 0);
 	write_msi_msg(dev->irq, &entry->msg);
 	write_msi_msg(dev->irq, &entry->msg);
 
 
 	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
 	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
@@ -321,22 +313,22 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
 
 
 	if (!dev->msix_enabled)
 	if (!dev->msix_enabled)
 		return;
 		return;
+	BUG_ON(list_empty(&dev->msi_list));
+	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
+	pos = entry->msi_attrib.pos;
+	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
 
 
 	/* route the table */
 	/* route the table */
 	pci_intx_for_msi(dev, 0);
 	pci_intx_for_msi(dev, 0);
-	msix_set_enable(dev, 0);
+	control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
 	list_for_each_entry(entry, &dev->msi_list, list) {
 		write_msi_msg(entry->irq, &entry->msg);
 		write_msi_msg(entry->irq, &entry->msg);
 		msix_mask_irq(entry, entry->masked);
 		msix_mask_irq(entry, entry->masked);
 	}
 	}
 
 
-	BUG_ON(list_empty(&dev->msi_list));
-	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
-	pos = entry->msi_attrib.pos;
-	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
 	control &= ~PCI_MSIX_FLAGS_MASKALL;
 	control &= ~PCI_MSIX_FLAGS_MASKALL;
-	control |= PCI_MSIX_FLAGS_ENABLE;
 	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 }
 }
 
 
@@ -365,9 +357,9 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	u16 control;
 	u16 control;
 	unsigned mask;
 	unsigned mask;
 
 
-	msi_set_enable(dev, 0);	/* Ensure msi is disabled as I set it up */
-
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+	msi_set_enable(dev, pos, 0);	/* Disable MSI during set up */
+
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
 	/* MSI Entry Initialization */
 	/* MSI Entry Initialization */
 	entry = alloc_msi_entry(dev);
 	entry = alloc_msi_entry(dev);
@@ -381,7 +373,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
 	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
 	entry->msi_attrib.pos = pos;
 	entry->msi_attrib.pos = pos;
 
 
-	entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+	entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64);
 	/* All MSIs are unmasked by default, Mask them all */
 	/* All MSIs are unmasked by default, Mask them all */
 	if (entry->msi_attrib.maskbit)
 	if (entry->msi_attrib.maskbit)
 		pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
 		pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
@@ -399,7 +391,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 
 
 	/* Set MSI enabled bits	 */
 	/* Set MSI enabled bits	 */
 	pci_intx_for_msi(dev, 0);
 	pci_intx_for_msi(dev, 0);
-	msi_set_enable(dev, 1);
+	msi_set_enable(dev, pos, 1);
 	dev->msi_enabled = 1;
 	dev->msi_enabled = 1;
 
 
 	dev->irq = entry->irq;
 	dev->irq = entry->irq;
@@ -427,11 +419,14 @@ static int msix_capability_init(struct pci_dev *dev,
 	u8 bir;
 	u8 bir;
 	void __iomem *base;
 	void __iomem *base;
 
 
-	msix_set_enable(dev, 0);/* Ensure msix is disabled as I set it up */
-
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
+
+	/* Ensure MSI-X is disabled while it is set up */
+	control &= ~PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
+
 	/* Request & Map MSI-X table region */
 	/* Request & Map MSI-X table region */
- 	pci_read_config_word(dev, msi_control_reg(pos), &control);
 	nr_entries = multi_msix_capable(control);
 	nr_entries = multi_msix_capable(control);
 
 
  	pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
  	pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
@@ -442,7 +437,6 @@ static int msix_capability_init(struct pci_dev *dev,
 	if (base == NULL)
 	if (base == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	/* MSI-X Table Initialization */
 	for (i = 0; i < nvec; i++) {
 	for (i = 0; i < nvec; i++) {
 		entry = alloc_msi_entry(dev);
 		entry = alloc_msi_entry(dev);
 		if (!entry)
 		if (!entry)
@@ -455,7 +449,6 @@ static int msix_capability_init(struct pci_dev *dev,
 		entry->msi_attrib.default_irq = dev->irq;
 		entry->msi_attrib.default_irq = dev->irq;
 		entry->msi_attrib.pos = pos;
 		entry->msi_attrib.pos = pos;
 		entry->mask_base = base;
 		entry->mask_base = base;
-		msix_mask_irq(entry, 1);
 
 
 		list_add_tail(&entry->list, &dev->msi_list);
 		list_add_tail(&entry->list, &dev->msi_list);
 	}
 	}
@@ -480,22 +473,31 @@ static int msix_capability_init(struct pci_dev *dev,
 		return ret;
 		return ret;
 	}
 	}
 
 
+	/*
+	 * Some devices require MSI-X to be enabled before we can touch the
+	 * MSI-X registers.  We need to mask all the vectors to prevent
+	 * interrupts coming in before they're fully set up.
+	 */
+	control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
+
 	i = 0;
 	i = 0;
 	list_for_each_entry(entry, &dev->msi_list, list) {
 	list_for_each_entry(entry, &dev->msi_list, list) {
 		entries[i].vector = entry->irq;
 		entries[i].vector = entry->irq;
 		set_irq_msi(entry->irq, entry);
 		set_irq_msi(entry->irq, entry);
+		j = entries[i].entry;
+		entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
+					PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+		msix_mask_irq(entry, 1);
 		i++;
 		i++;
 	}
 	}
-	/* Set MSI-X enabled bits */
+
+	/* Set MSI-X enabled bits and unmask the function */
 	pci_intx_for_msi(dev, 0);
 	pci_intx_for_msi(dev, 0);
-	msix_set_enable(dev, 1);
 	dev->msix_enabled = 1;
 	dev->msix_enabled = 1;
 
 
-	list_for_each_entry(entry, &dev->msi_list, list) {
-		int vector = entry->msi_attrib.entry_nr;
-		entry->masked = readl(base + vector * PCI_MSIX_ENTRY_SIZE +
-					PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
-	}
+	control &= ~PCI_MSIX_FLAGS_MASKALL;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -596,17 +598,20 @@ void pci_msi_shutdown(struct pci_dev *dev)
 	struct msi_desc *desc;
 	struct msi_desc *desc;
 	u32 mask;
 	u32 mask;
 	u16 ctrl;
 	u16 ctrl;
+	unsigned pos;
 
 
 	if (!pci_msi_enable || !dev || !dev->msi_enabled)
 	if (!pci_msi_enable || !dev || !dev->msi_enabled)
 		return;
 		return;
 
 
-	msi_set_enable(dev, 0);
+	BUG_ON(list_empty(&dev->msi_list));
+	desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+	pos = desc->msi_attrib.pos;
+
+	msi_set_enable(dev, pos, 0);
 	pci_intx_for_msi(dev, 1);
 	pci_intx_for_msi(dev, 1);
 	dev->msi_enabled = 0;
 	dev->msi_enabled = 0;
 
 
-	BUG_ON(list_empty(&dev->msi_list));
-	desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
-	pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl);
+	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl);
 	mask = msi_capable_mask(ctrl);
 	mask = msi_capable_mask(ctrl);
 	msi_mask_irq(desc, mask, ~mask);
 	msi_mask_irq(desc, mask, ~mask);
 
 
@@ -648,10 +653,7 @@ static int msi_free_irqs(struct pci_dev* dev)
 
 
 	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
 	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
 		if (entry->msi_attrib.is_msix) {
 		if (entry->msi_attrib.is_msix) {
-			writel(1, entry->mask_base + entry->msi_attrib.entry_nr
-				  * PCI_MSIX_ENTRY_SIZE
-				  + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
-
+			msix_mask_irq(entry, 1);
 			if (list_is_last(&entry->list, &dev->msi_list))
 			if (list_is_last(&entry->list, &dev->msi_list))
 				iounmap(entry->mask_base);
 				iounmap(entry->mask_base);
 		}
 		}
@@ -691,8 +693,8 @@ int pci_msix_table_size(struct pci_dev *dev)
  * indicates the successful configuration of MSI-X capability structure
  * indicates the successful configuration of MSI-X capability structure
  * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
  * with new allocated MSI-X irqs. A return of < 0 indicates a failure.
  * Or a return of > 0 indicates that driver request is exceeding the number
  * Or a return of > 0 indicates that driver request is exceeding the number
- * of irqs available. Driver should use the returned value to re-send
- * its request.
+ * of irqs or MSI-X vectors available. Driver should use the returned value to
+ * re-send its request.
  **/
  **/
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
 {
@@ -708,7 +710,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 
 
 	nr_entries = pci_msix_table_size(dev);
 	nr_entries = pci_msix_table_size(dev);
 	if (nvec > nr_entries)
 	if (nvec > nr_entries)
-		return -EINVAL;
+		return nr_entries;
 
 
 	/* Check for any invalid entries */
 	/* Check for any invalid entries */
 	for (i = 0; i < nvec; i++) {
 	for (i = 0; i < nvec; i++) {

+ 4 - 10
drivers/pci/msi.h

@@ -16,21 +16,15 @@
 #define msi_lower_address_reg(base)	(base + PCI_MSI_ADDRESS_LO)
 #define msi_lower_address_reg(base)	(base + PCI_MSI_ADDRESS_LO)
 #define msi_upper_address_reg(base)	(base + PCI_MSI_ADDRESS_HI)
 #define msi_upper_address_reg(base)	(base + PCI_MSI_ADDRESS_HI)
 #define msi_data_reg(base, is64bit)	\
 #define msi_data_reg(base, is64bit)	\
-	( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
-#define msi_mask_bits_reg(base, is64bit) \
-	( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
-#define msi_disable(control)		control &= ~PCI_MSI_FLAGS_ENABLE
+	(base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32))
+#define msi_mask_reg(base, is64bit)	\
+	(base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32))
 #define is_64bit_address(control)	(!!(control & PCI_MSI_FLAGS_64BIT))
 #define is_64bit_address(control)	(!!(control & PCI_MSI_FLAGS_64BIT))
 #define is_mask_bit_support(control)	(!!(control & PCI_MSI_FLAGS_MASKBIT))
 #define is_mask_bit_support(control)	(!!(control & PCI_MSI_FLAGS_MASKBIT))
 
 
 #define msix_table_offset_reg(base)	(base + 0x04)
 #define msix_table_offset_reg(base)	(base + 0x04)
 #define msix_pba_offset_reg(base)	(base + 0x08)
 #define msix_pba_offset_reg(base)	(base + 0x08)
-#define msix_enable(control)	 	control |= PCI_MSIX_FLAGS_ENABLE
-#define msix_disable(control)	 	control &= ~PCI_MSIX_FLAGS_ENABLE
 #define msix_table_size(control) 	((control & PCI_MSIX_FLAGS_QSIZE)+1)
 #define msix_table_size(control) 	((control & PCI_MSIX_FLAGS_QSIZE)+1)
-#define multi_msix_capable		msix_table_size
-#define msix_unmask(address)	 	(address & ~PCI_MSIX_FLAGS_BITMASK)
-#define msix_mask(address)		(address | PCI_MSIX_FLAGS_BITMASK)
-#define msix_is_pending(address) 	(address & PCI_MSIX_FLAGS_PENDMASK)
+#define multi_msix_capable(control)	msix_table_size((control))
 
 
 #endif /* MSI_H */
 #endif /* MSI_H */

+ 158 - 88
drivers/pci/pci.c

@@ -485,6 +485,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= state;
 		pmcsr |= state;
 		break;
 		break;
+	case PCI_D3hot:
+	case PCI_D3cold:
 	case PCI_UNKNOWN: /* Boot-up */
 	case PCI_UNKNOWN: /* Boot-up */
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
@@ -1208,7 +1210,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
  * Error code depending on the platform is returned if both the platform and
  * Error code depending on the platform is returned if both the platform and
  * the native mechanism fail to enable the generation of wake-up events
  * the native mechanism fail to enable the generation of wake-up events
  */
  */
-int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
 {
 {
 	int error = 0;
 	int error = 0;
 	bool pme_done = false;
 	bool pme_done = false;
@@ -1287,15 +1289,14 @@ pci_power_t pci_target_state(struct pci_dev *dev)
 		default:
 		default:
 			target_state = state;
 			target_state = state;
 		}
 		}
+	} else if (!dev->pm_cap) {
+		target_state = PCI_D0;
 	} else if (device_may_wakeup(&dev->dev)) {
 	} else if (device_may_wakeup(&dev->dev)) {
 		/*
 		/*
 		 * Find the deepest state from which the device can generate
 		 * Find the deepest state from which the device can generate
 		 * wake-up events, make it the target state and enable device
 		 * wake-up events, make it the target state and enable device
 		 * to generate PME#.
 		 * to generate PME#.
 		 */
 		 */
-		if (!dev->pm_cap)
-			return PCI_POWER_ERROR;
-
 		if (dev->pme_support) {
 		if (dev->pme_support) {
 			while (target_state
 			while (target_state
 			      && !(dev->pme_support & (1 << target_state)))
 			      && !(dev->pme_support & (1 << target_state)))
@@ -1532,7 +1533,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 	if (!pin)
 	if (!pin)
 		return -1;
 		return -1;
 
 
-	while (dev->bus->parent) {
+	while (!pci_is_root_bus(dev->bus)) {
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		dev = dev->bus->self;
 		dev = dev->bus->self;
 	}
 	}
@@ -1552,7 +1553,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
 {
 {
 	u8 pin = *pinp;
 	u8 pin = *pinp;
 
 
-	while (dev->bus->parent) {
+	while (!pci_is_root_bus(dev->bus)) {
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		pin = pci_swizzle_interrupt_pin(dev, pin);
 		dev = dev->bus->self;
 		dev = dev->bus->self;
 	}
 	}
@@ -2058,111 +2059,177 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 EXPORT_SYMBOL(pci_set_dma_seg_boundary);
 #endif
 #endif
 
 
-static int __pcie_flr(struct pci_dev *dev, int probe)
+static int pcie_flr(struct pci_dev *dev, int probe)
 {
 {
-	u16 status;
+	int i;
+	int pos;
 	u32 cap;
 	u32 cap;
-	int exppos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	u16 status;
 
 
-	if (!exppos)
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos)
 		return -ENOTTY;
 		return -ENOTTY;
-	pci_read_config_dword(dev, exppos + PCI_EXP_DEVCAP, &cap);
+
+	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap);
 	if (!(cap & PCI_EXP_DEVCAP_FLR))
 	if (!(cap & PCI_EXP_DEVCAP_FLR))
 		return -ENOTTY;
 		return -ENOTTY;
 
 
 	if (probe)
 	if (probe)
 		return 0;
 		return 0;
 
 
-	pci_block_user_cfg_access(dev);
-
 	/* Wait for Transaction Pending bit clean */
 	/* Wait for Transaction Pending bit clean */
-	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-	if (!(status & PCI_EXP_DEVSTA_TRPND))
-		goto transaction_done;
+	for (i = 0; i < 4; i++) {
+		if (i)
+			msleep((1 << (i - 1)) * 100);
 
 
-	msleep(100);
-	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-	if (!(status & PCI_EXP_DEVSTA_TRPND))
-		goto transaction_done;
-
-	dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
-			"sleeping for 1 second\n");
-	ssleep(1);
-	pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
-	if (status & PCI_EXP_DEVSTA_TRPND)
-		dev_info(&dev->dev, "Still busy after 1s; "
-				"proceeding with reset anyway\n");
-
-transaction_done:
-	pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
+		pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status);
+		if (!(status & PCI_EXP_DEVSTA_TRPND))
+			goto clear;
+	}
+
+	dev_err(&dev->dev, "transaction is not cleared; "
+			"proceeding with reset anyway\n");
+
+clear:
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
 				PCI_EXP_DEVCTL_BCR_FLR);
 				PCI_EXP_DEVCTL_BCR_FLR);
-	mdelay(100);
+	msleep(100);
 
 
-	pci_unblock_user_cfg_access(dev);
 	return 0;
 	return 0;
 }
 }
 
 
-static int __pci_af_flr(struct pci_dev *dev, int probe)
+static int pci_af_flr(struct pci_dev *dev, int probe)
 {
 {
-	int cappos = pci_find_capability(dev, PCI_CAP_ID_AF);
-	u8 status;
+	int i;
+	int pos;
 	u8 cap;
 	u8 cap;
+	u8 status;
 
 
-	if (!cappos)
+	pos = pci_find_capability(dev, PCI_CAP_ID_AF);
+	if (!pos)
 		return -ENOTTY;
 		return -ENOTTY;
-	pci_read_config_byte(dev, cappos + PCI_AF_CAP, &cap);
+
+	pci_read_config_byte(dev, pos + PCI_AF_CAP, &cap);
 	if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
 	if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
 		return -ENOTTY;
 		return -ENOTTY;
 
 
 	if (probe)
 	if (probe)
 		return 0;
 		return 0;
 
 
-	pci_block_user_cfg_access(dev);
-
 	/* Wait for Transaction Pending bit clean */
 	/* Wait for Transaction Pending bit clean */
-	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-	if (!(status & PCI_AF_STATUS_TP))
-		goto transaction_done;
+	for (i = 0; i < 4; i++) {
+		if (i)
+			msleep((1 << (i - 1)) * 100);
+
+		pci_read_config_byte(dev, pos + PCI_AF_STATUS, &status);
+		if (!(status & PCI_AF_STATUS_TP))
+			goto clear;
+	}
 
 
+	dev_err(&dev->dev, "transaction is not cleared; "
+			"proceeding with reset anyway\n");
+
+clear:
+	pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
 	msleep(100);
 	msleep(100);
-	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-	if (!(status & PCI_AF_STATUS_TP))
-		goto transaction_done;
-
-	dev_info(&dev->dev, "Busy after 100ms while trying to"
-			" reset; sleeping for 1 second\n");
-	ssleep(1);
-	pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
-	if (status & PCI_AF_STATUS_TP)
-		dev_info(&dev->dev, "Still busy after 1s; "
-				"proceeding with reset anyway\n");
-
-transaction_done:
-	pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
-	mdelay(100);
-
-	pci_unblock_user_cfg_access(dev);
+
 	return 0;
 	return 0;
 }
 }
 
 
-static int __pci_reset_function(struct pci_dev *pdev, int probe)
+static int pci_pm_reset(struct pci_dev *dev, int probe)
 {
 {
-	int res;
+	u16 csr;
+
+	if (!dev->pm_cap)
+		return -ENOTTY;
 
 
-	res = __pcie_flr(pdev, probe);
-	if (res != -ENOTTY)
-		return res;
+	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &csr);
+	if (csr & PCI_PM_CTRL_NO_SOFT_RESET)
+		return -ENOTTY;
 
 
-	res = __pci_af_flr(pdev, probe);
-	if (res != -ENOTTY)
-		return res;
+	if (probe)
+		return 0;
 
 
-	return res;
+	if (dev->current_state != PCI_D0)
+		return -EINVAL;
+
+	csr &= ~PCI_PM_CTRL_STATE_MASK;
+	csr |= PCI_D3hot;
+	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
+	msleep(pci_pm_d3_delay);
+
+	csr &= ~PCI_PM_CTRL_STATE_MASK;
+	csr |= PCI_D0;
+	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
+	msleep(pci_pm_d3_delay);
+
+	return 0;
+}
+
+static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
+{
+	u16 ctrl;
+	struct pci_dev *pdev;
+
+	if (dev->subordinate)
+		return -ENOTTY;
+
+	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
+		if (pdev != dev)
+			return -ENOTTY;
+
+	if (probe)
+		return 0;
+
+	pci_read_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, &ctrl);
+	ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
+	pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
+	msleep(100);
+
+	ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+	pci_write_config_word(dev->bus->self, PCI_BRIDGE_CONTROL, ctrl);
+	msleep(100);
+
+	return 0;
+}
+
+static int pci_dev_reset(struct pci_dev *dev, int probe)
+{
+	int rc;
+
+	might_sleep();
+
+	if (!probe) {
+		pci_block_user_cfg_access(dev);
+		/* block PM suspend, driver probe, etc. */
+		down(&dev->dev.sem);
+	}
+
+	rc = pcie_flr(dev, probe);
+	if (rc != -ENOTTY)
+		goto done;
+
+	rc = pci_af_flr(dev, probe);
+	if (rc != -ENOTTY)
+		goto done;
+
+	rc = pci_pm_reset(dev, probe);
+	if (rc != -ENOTTY)
+		goto done;
+
+	rc = pci_parent_bus_reset(dev, probe);
+done:
+	if (!probe) {
+		up(&dev->dev.sem);
+		pci_unblock_user_cfg_access(dev);
+	}
+
+	return rc;
 }
 }
 
 
 /**
 /**
- * pci_execute_reset_function() - Reset a PCI device function
- * @dev: Device function to reset
+ * __pci_reset_function - reset a PCI device function
+ * @dev: PCI device to reset
  *
  *
  * Some devices allow an individual function to be reset without affecting
  * Some devices allow an individual function to be reset without affecting
  * other functions in the same device.  The PCI device must be responsive
  * other functions in the same device.  The PCI device must be responsive
@@ -2174,18 +2241,18 @@ static int __pci_reset_function(struct pci_dev *pdev, int probe)
  * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
  * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
  * etc.
  * etc.
  *
  *
- * Returns 0 if the device function was successfully reset or -ENOTTY if the
+ * Returns 0 if the device function was successfully reset or negative if the
  * device doesn't support resetting a single function.
  * device doesn't support resetting a single function.
  */
  */
-int pci_execute_reset_function(struct pci_dev *dev)
+int __pci_reset_function(struct pci_dev *dev)
 {
 {
-	return __pci_reset_function(dev, 0);
+	return pci_dev_reset(dev, 0);
 }
 }
-EXPORT_SYMBOL_GPL(pci_execute_reset_function);
+EXPORT_SYMBOL_GPL(__pci_reset_function);
 
 
 /**
 /**
- * pci_reset_function() - quiesce and reset a PCI device function
- * @dev: Device function to reset
+ * pci_reset_function - quiesce and reset a PCI device function
+ * @dev: PCI device to reset
  *
  *
  * Some devices allow an individual function to be reset without affecting
  * Some devices allow an individual function to be reset without affecting
  * other functions in the same device.  The PCI device must be responsive
  * other functions in the same device.  The PCI device must be responsive
@@ -2193,32 +2260,33 @@ EXPORT_SYMBOL_GPL(pci_execute_reset_function);
  *
  *
  * This function does not just reset the PCI portion of a device, but
  * This function does not just reset the PCI portion of a device, but
  * clears all the state associated with the device.  This function differs
  * clears all the state associated with the device.  This function differs
- * from pci_execute_reset_function in that it saves and restores device state
+ * from __pci_reset_function in that it saves and restores device state
  * over the reset.
  * over the reset.
  *
  *
- * Returns 0 if the device function was successfully reset or -ENOTTY if the
+ * Returns 0 if the device function was successfully reset or negative if the
  * device doesn't support resetting a single function.
  * device doesn't support resetting a single function.
  */
  */
 int pci_reset_function(struct pci_dev *dev)
 int pci_reset_function(struct pci_dev *dev)
 {
 {
-	int r = __pci_reset_function(dev, 1);
+	int rc;
 
 
-	if (r < 0)
-		return r;
+	rc = pci_dev_reset(dev, 1);
+	if (rc)
+		return rc;
 
 
-	if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
-		disable_irq(dev->irq);
 	pci_save_state(dev);
 	pci_save_state(dev);
 
 
+	/*
+	 * both INTx and MSI are disabled after the Interrupt Disable bit
+	 * is set and the Bus Master bit is cleared.
+	 */
 	pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
 	pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
 
 
-	r = pci_execute_reset_function(dev);
+	rc = pci_dev_reset(dev, 0);
 
 
 	pci_restore_state(dev);
 	pci_restore_state(dev);
-	if (!dev->msi_enabled && !dev->msix_enabled && dev->irq != 0)
-		enable_irq(dev->irq);
 
 
-	return r;
+	return rc;
 }
 }
 EXPORT_SYMBOL_GPL(pci_reset_function);
 EXPORT_SYMBOL_GPL(pci_reset_function);
 
 
@@ -2591,6 +2659,8 @@ static int __init pci_setup(char *str)
 			} else if (!strncmp(str, "resource_alignment=", 19)) {
 			} else if (!strncmp(str, "resource_alignment=", 19)) {
 				pci_set_resource_alignment_param(str + 19,
 				pci_set_resource_alignment_param(str + 19,
 							strlen(str + 19));
 							strlen(str + 19));
+			} else if (!strncmp(str, "ecrc=", 5)) {
+				pcie_ecrc_get_policy(str + 5);
 			} else {
 			} else {
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 						str);
 						str);

+ 15 - 0
drivers/pci/pcie/aer/Kconfig

@@ -10,3 +10,18 @@ config PCIEAER
 	  This enables PCI Express Root Port Advanced Error Reporting
 	  This enables PCI Express Root Port Advanced Error Reporting
 	  (AER) driver support. Error reporting messages sent to Root
 	  (AER) driver support. Error reporting messages sent to Root
 	  Port will be handled by PCI Express AER driver.
 	  Port will be handled by PCI Express AER driver.
+
+
+#
+# PCI Express ECRC
+#
+config PCIE_ECRC
+	bool "PCI Express ECRC settings control"
+	depends on PCIEAER
+	help
+	  Used to override firmware/bios settings for PCI Express ECRC
+	  (transaction layer end-to-end CRC checking).
+
+	  When in doubt, say N.
+
+source "drivers/pci/pcie/aer/Kconfig.debug"

+ 18 - 0
drivers/pci/pcie/aer/Kconfig.debug

@@ -0,0 +1,18 @@
+#
+# PCI Express Root Port Device AER Debug Configuration
+#
+
+config PCIEAER_INJECT
+	tristate "PCIE AER error injector support"
+	depends on PCIEAER
+	default n
+	help
+	  This enables PCI Express Root Port Advanced Error Reporting
+	  (AER) software error injector.
+
+	  Debuging PCIE AER code is quite difficult because it is hard
+	  to trigger various real hardware errors. Software based
+	  error injection can fake almost all kinds of errors with the
+	  help of a user space helper tool aer-inject, which can be
+	  gotten from:
+	     http://www.kernel.org/pub/linux/utils/pci/aer-inject/

+ 3 - 0
drivers/pci/pcie/aer/Makefile

@@ -4,6 +4,9 @@
 
 
 obj-$(CONFIG_PCIEAER) += aerdriver.o
 obj-$(CONFIG_PCIEAER) += aerdriver.o
 
 
+obj-$(CONFIG_PCIE_ECRC)	+= ecrc.o
+
 aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o
 aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o
 aerdriver-$(CONFIG_ACPI) += aerdrv_acpi.o
 aerdriver-$(CONFIG_ACPI) += aerdrv_acpi.o
 
 
+obj-$(CONFIG_PCIEAER_INJECT) += aer_inject.o

+ 473 - 0
drivers/pci/pcie/aer/aer_inject.c

@@ -0,0 +1,473 @@
+/*
+ * PCIE AER software error injection support.
+ *
+ * Debuging PCIE AER code is quite difficult because it is hard to
+ * trigger various real hardware errors. Software based error
+ * injection can fake almost all kinds of errors with the help of a
+ * user space helper tool aer-inject, which can be gotten from:
+ *   http://www.kernel.org/pub/linux/utils/pci/aer-inject/
+ *
+ * Copyright 2009 Intel Corporation.
+ *     Huang Ying <ying.huang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include "aerdrv.h"
+
+struct aer_error_inj
+{
+	u8 bus;
+	u8 dev;
+	u8 fn;
+	u32 uncor_status;
+	u32 cor_status;
+	u32 header_log0;
+	u32 header_log1;
+	u32 header_log2;
+	u32 header_log3;
+};
+
+struct aer_error
+{
+	struct list_head list;
+	unsigned int bus;
+	unsigned int devfn;
+	int pos_cap_err;
+
+	u32 uncor_status;
+	u32 cor_status;
+	u32 header_log0;
+	u32 header_log1;
+	u32 header_log2;
+	u32 header_log3;
+	u32 root_status;
+	u32 source_id;
+};
+
+struct pci_bus_ops
+{
+	struct list_head list;
+	struct pci_bus *bus;
+	struct pci_ops *ops;
+};
+
+static LIST_HEAD(einjected);
+
+static LIST_HEAD(pci_bus_ops_list);
+
+/* Protect einjected and pci_bus_ops_list */
+static DEFINE_SPINLOCK(inject_lock);
+
+static void aer_error_init(struct aer_error *err, unsigned int bus,
+			   unsigned int devfn, int pos_cap_err)
+{
+	INIT_LIST_HEAD(&err->list);
+	err->bus = bus;
+	err->devfn = devfn;
+	err->pos_cap_err = pos_cap_err;
+}
+
+/* inject_lock must be held before calling */
+static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn)
+{
+	struct aer_error *err;
+
+	list_for_each_entry(err, &einjected, list) {
+		if (bus == err->bus && devfn == err->devfn)
+			return err;
+	}
+	return NULL;
+}
+
+/* inject_lock must be held before calling */
+static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev)
+{
+	return __find_aer_error(dev->bus->number, dev->devfn);
+}
+
+/* inject_lock must be held before calling */
+static struct pci_ops *__find_pci_bus_ops(struct pci_bus *bus)
+{
+	struct pci_bus_ops *bus_ops;
+
+	list_for_each_entry(bus_ops, &pci_bus_ops_list, list) {
+		if (bus_ops->bus == bus)
+			return bus_ops->ops;
+	}
+	return NULL;
+}
+
+static struct pci_bus_ops *pci_bus_ops_pop(void)
+{
+	unsigned long flags;
+	struct pci_bus_ops *bus_ops = NULL;
+
+	spin_lock_irqsave(&inject_lock, flags);
+	if (list_empty(&pci_bus_ops_list))
+		bus_ops = NULL;
+	else {
+		struct list_head *lh = pci_bus_ops_list.next;
+		list_del(lh);
+		bus_ops = list_entry(lh, struct pci_bus_ops, list);
+	}
+	spin_unlock_irqrestore(&inject_lock, flags);
+	return bus_ops;
+}
+
+static u32 *find_pci_config_dword(struct aer_error *err, int where,
+				  int *prw1cs)
+{
+	int rw1cs = 0;
+	u32 *target = NULL;
+
+	if (err->pos_cap_err == -1)
+		return NULL;
+
+	switch (where - err->pos_cap_err) {
+	case PCI_ERR_UNCOR_STATUS:
+		target = &err->uncor_status;
+		rw1cs = 1;
+		break;
+	case PCI_ERR_COR_STATUS:
+		target = &err->cor_status;
+		rw1cs = 1;
+		break;
+	case PCI_ERR_HEADER_LOG:
+		target = &err->header_log0;
+		break;
+	case PCI_ERR_HEADER_LOG+4:
+		target = &err->header_log1;
+		break;
+	case PCI_ERR_HEADER_LOG+8:
+	        target = &err->header_log2;
+		break;
+	case PCI_ERR_HEADER_LOG+12:
+		target = &err->header_log3;
+		break;
+	case PCI_ERR_ROOT_STATUS:
+		target = &err->root_status;
+		rw1cs = 1;
+		break;
+	case PCI_ERR_ROOT_COR_SRC:
+		target = &err->source_id;
+		break;
+	}
+	if (prw1cs)
+		*prw1cs = rw1cs;
+	return target;
+}
+
+static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where,
+			int size, u32 *val)
+{
+	u32 *sim;
+	struct aer_error *err;
+	unsigned long flags;
+	struct pci_ops *ops;
+
+	spin_lock_irqsave(&inject_lock, flags);
+	if (size != sizeof(u32))
+		goto out;
+	err = __find_aer_error(bus->number, devfn);
+	if (!err)
+		goto out;
+
+	sim = find_pci_config_dword(err, where, NULL);
+	if (sim) {
+		*val = *sim;
+		spin_unlock_irqrestore(&inject_lock, flags);
+		return 0;
+	}
+out:
+	ops = __find_pci_bus_ops(bus);
+	spin_unlock_irqrestore(&inject_lock, flags);
+	return ops->read(bus, devfn, where, size, val);
+}
+
+int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size,
+		  u32 val)
+{
+	u32 *sim;
+	struct aer_error *err;
+	unsigned long flags;
+	int rw1cs;
+	struct pci_ops *ops;
+
+	spin_lock_irqsave(&inject_lock, flags);
+	if (size != sizeof(u32))
+		goto out;
+	err = __find_aer_error(bus->number, devfn);
+	if (!err)
+		goto out;
+
+	sim = find_pci_config_dword(err, where, &rw1cs);
+	if (sim) {
+		if (rw1cs)
+			*sim ^= val;
+		else
+			*sim = val;
+		spin_unlock_irqrestore(&inject_lock, flags);
+		return 0;
+	}
+out:
+	ops = __find_pci_bus_ops(bus);
+	spin_unlock_irqrestore(&inject_lock, flags);
+	return ops->write(bus, devfn, where, size, val);
+}
+
+static struct pci_ops pci_ops_aer = {
+	.read = pci_read_aer,
+	.write = pci_write_aer,
+};
+
+static void pci_bus_ops_init(struct pci_bus_ops *bus_ops,
+			     struct pci_bus *bus,
+			     struct pci_ops *ops)
+{
+	INIT_LIST_HEAD(&bus_ops->list);
+	bus_ops->bus = bus;
+	bus_ops->ops = ops;
+}
+
+static int pci_bus_set_aer_ops(struct pci_bus *bus)
+{
+	struct pci_ops *ops;
+	struct pci_bus_ops *bus_ops;
+	unsigned long flags;
+
+	bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL);
+	if (!bus_ops)
+		return -ENOMEM;
+	ops = pci_bus_set_ops(bus, &pci_ops_aer);
+	spin_lock_irqsave(&inject_lock, flags);
+	if (ops == &pci_ops_aer)
+		goto out;
+	pci_bus_ops_init(bus_ops, bus, ops);
+	list_add(&bus_ops->list, &pci_bus_ops_list);
+	bus_ops = NULL;
+out:
+	spin_unlock_irqrestore(&inject_lock, flags);
+	if (bus_ops)
+		kfree(bus_ops);
+	return 0;
+}
+
+static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+{
+	while (1) {
+		if (!dev->is_pcie)
+			break;
+		if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+			return dev;
+		if (!dev->bus->self)
+			break;
+		dev = dev->bus->self;
+	}
+	return NULL;
+}
+
+static int find_aer_device_iter(struct device *device, void *data)
+{
+	struct pcie_device **result = data;
+	struct pcie_device *pcie_dev;
+
+	if (device->bus == &pcie_port_bus_type) {
+		pcie_dev = to_pcie_device(device);
+		if (pcie_dev->service & PCIE_PORT_SERVICE_AER) {
+			*result = pcie_dev;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int find_aer_device(struct pci_dev *dev, struct pcie_device **result)
+{
+	return device_for_each_child(&dev->dev, result, find_aer_device_iter);
+}
+
+static int aer_inject(struct aer_error_inj *einj)
+{
+	struct aer_error *err, *rperr;
+	struct aer_error *err_alloc = NULL, *rperr_alloc = NULL;
+	struct pci_dev *dev, *rpdev;
+	struct pcie_device *edev;
+	unsigned long flags;
+	unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
+	int pos_cap_err, rp_pos_cap_err;
+	u32 sever;
+	int ret = 0;
+
+	dev = pci_get_bus_and_slot(einj->bus, devfn);
+	if (!dev)
+		return -EINVAL;
+	rpdev = pcie_find_root_port(dev);
+	if (!rpdev) {
+		ret = -EINVAL;
+		goto out_put;
+	}
+
+	pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos_cap_err) {
+		ret = -EIO;
+		goto out_put;
+	}
+	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
+
+	rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
+	if (!rp_pos_cap_err) {
+		ret = -EIO;
+		goto out_put;
+	}
+
+	err_alloc =  kzalloc(sizeof(struct aer_error), GFP_KERNEL);
+	if (!err_alloc) {
+		ret = -ENOMEM;
+		goto out_put;
+	}
+	rperr_alloc =  kzalloc(sizeof(struct aer_error), GFP_KERNEL);
+	if (!rperr_alloc) {
+		ret = -ENOMEM;
+		goto out_put;
+	}
+
+	spin_lock_irqsave(&inject_lock, flags);
+
+	err = __find_aer_error_by_dev(dev);
+	if (!err) {
+		err = err_alloc;
+		err_alloc = NULL;
+		aer_error_init(err, einj->bus, devfn, pos_cap_err);
+		list_add(&err->list, &einjected);
+	}
+	err->uncor_status |= einj->uncor_status;
+	err->cor_status |= einj->cor_status;
+	err->header_log0 = einj->header_log0;
+	err->header_log1 = einj->header_log1;
+	err->header_log2 = einj->header_log2;
+	err->header_log3 = einj->header_log3;
+
+	rperr = __find_aer_error_by_dev(rpdev);
+	if (!rperr) {
+		rperr = rperr_alloc;
+		rperr_alloc = NULL;
+		aer_error_init(rperr, rpdev->bus->number, rpdev->devfn,
+			       rp_pos_cap_err);
+		list_add(&rperr->list, &einjected);
+	}
+	if (einj->cor_status) {
+		if (rperr->root_status & PCI_ERR_ROOT_COR_RCV)
+			rperr->root_status |= PCI_ERR_ROOT_MULTI_COR_RCV;
+		else
+			rperr->root_status |= PCI_ERR_ROOT_COR_RCV;
+		rperr->source_id &= 0xffff0000;
+		rperr->source_id |= (einj->bus << 8) | devfn;
+	}
+	if (einj->uncor_status) {
+		if (rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV)
+			rperr->root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV;
+		if (sever & einj->uncor_status) {
+			rperr->root_status |= PCI_ERR_ROOT_FATAL_RCV;
+			if (!(rperr->root_status & PCI_ERR_ROOT_UNCOR_RCV))
+				rperr->root_status |= PCI_ERR_ROOT_FIRST_FATAL;
+		} else
+			rperr->root_status |= PCI_ERR_ROOT_NONFATAL_RCV;
+		rperr->root_status |= PCI_ERR_ROOT_UNCOR_RCV;
+		rperr->source_id &= 0x0000ffff;
+		rperr->source_id |= ((einj->bus << 8) | devfn) << 16;
+	}
+	spin_unlock_irqrestore(&inject_lock, flags);
+
+	ret = pci_bus_set_aer_ops(dev->bus);
+	if (ret)
+		goto out_put;
+	ret = pci_bus_set_aer_ops(rpdev->bus);
+	if (ret)
+		goto out_put;
+
+	if (find_aer_device(rpdev, &edev))
+		aer_irq(-1, edev);
+	else
+		ret = -EINVAL;
+out_put:
+	if (err_alloc)
+		kfree(err_alloc);
+	if (rperr_alloc)
+		kfree(rperr_alloc);
+	pci_dev_put(dev);
+	return ret;
+}
+
+static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf,
+				size_t usize, loff_t *off)
+{
+	struct aer_error_inj einj;
+	int ret;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (usize != sizeof(struct aer_error_inj))
+		return -EINVAL;
+
+	if (copy_from_user(&einj, ubuf, usize))
+		return -EFAULT;
+
+	ret = aer_inject(&einj);
+	return ret ? ret : usize;
+}
+
+static const struct file_operations aer_inject_fops = {
+	.write = aer_inject_write,
+	.owner = THIS_MODULE,
+};
+
+static struct miscdevice aer_inject_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "aer_inject",
+	.fops = &aer_inject_fops,
+};
+
+static int __init aer_inject_init(void)
+{
+	return misc_register(&aer_inject_device);
+}
+
+static void __exit aer_inject_exit(void)
+{
+	struct aer_error *err, *err_next;
+	unsigned long flags;
+	struct pci_bus_ops *bus_ops;
+
+	misc_deregister(&aer_inject_device);
+
+	while ((bus_ops = pci_bus_ops_pop())) {
+		pci_bus_set_ops(bus_ops->bus, bus_ops->ops);
+		kfree(bus_ops);
+	}
+
+	spin_lock_irqsave(&inject_lock, flags);
+	list_for_each_entry_safe(err, err_next,
+				 &pci_bus_ops_list, list) {
+		list_del(&err->list);
+		kfree(err);
+	}
+	spin_unlock_irqrestore(&inject_lock, flags);
+}
+
+module_init(aer_inject_init);
+module_exit(aer_inject_exit);
+
+MODULE_DESCRIPTION("PCIE AER software error injector");
+MODULE_LICENSE("GPL");

+ 2 - 1
drivers/pci/pcie/aer/aerdrv.c

@@ -77,7 +77,7 @@ void pci_no_aer(void)
  *
  *
  * Invoked when Root Port detects AER messages.
  * Invoked when Root Port detects AER messages.
  **/
  **/
-static irqreturn_t aer_irq(int irq, void *context)
+irqreturn_t aer_irq(int irq, void *context)
 {
 {
 	unsigned int status, id;
 	unsigned int status, id;
 	struct pcie_device *pdev = (struct pcie_device *)context;
 	struct pcie_device *pdev = (struct pcie_device *)context;
@@ -126,6 +126,7 @@ static irqreturn_t aer_irq(int irq, void *context)
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
+EXPORT_SYMBOL_GPL(aer_irq);
 
 
 /**
 /**
  * aer_alloc_rpc - allocate Root Port data structure
  * aer_alloc_rpc - allocate Root Port data structure

+ 6 - 0
drivers/pci/pcie/aer/aerdrv.h

@@ -11,6 +11,7 @@
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
 #include <linux/pcieport_if.h>
 #include <linux/pcieport_if.h>
 #include <linux/aer.h>
 #include <linux/aer.h>
+#include <linux/interrupt.h>
 
 
 #define AER_NONFATAL			0
 #define AER_NONFATAL			0
 #define AER_FATAL			1
 #define AER_FATAL			1
@@ -56,7 +57,11 @@ struct header_log_regs {
 	unsigned int dw3;
 	unsigned int dw3;
 };
 };
 
 
+#define AER_MAX_MULTI_ERR_DEVICES	5	/* Not likely to have more */
 struct aer_err_info {
 struct aer_err_info {
+	struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
+	int error_dev_num;
+	u16 id;
 	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
 	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
 	int flags;
 	int flags;
 	unsigned int status;		/* COR/UNCOR Error Status */
 	unsigned int status;		/* COR/UNCOR Error Status */
@@ -120,6 +125,7 @@ extern void aer_delete_rootport(struct aer_rpc *rpc);
 extern int aer_init(struct pcie_device *dev);
 extern int aer_init(struct pcie_device *dev);
 extern void aer_isr(struct work_struct *work);
 extern void aer_isr(struct work_struct *work);
 extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
+extern irqreturn_t aer_irq(int irq, void *context);
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 extern int aer_osc_setup(struct pcie_device *pciedev);
 extern int aer_osc_setup(struct pcie_device *pciedev);

+ 191 - 87
drivers/pci/pcie/aer/aerdrv_core.c

@@ -26,7 +26,9 @@
 #include "aerdrv.h"
 #include "aerdrv.h"
 
 
 static int forceload;
 static int forceload;
+static int nosourceid;
 module_param(forceload, bool, 0);
 module_param(forceload, bool, 0);
+module_param(nosourceid, bool, 0);
 
 
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
 {
@@ -109,19 +111,23 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
 #endif  /*  0  */
 #endif  /*  0  */
 
 
 
 
-static void set_device_error_reporting(struct pci_dev *dev, void *data)
+static int set_device_error_reporting(struct pci_dev *dev, void *data)
 {
 {
 	bool enable = *((bool *)data);
 	bool enable = *((bool *)data);
 
 
-	if (dev->pcie_type != PCIE_RC_PORT &&
-	    dev->pcie_type != PCIE_SW_UPSTREAM_PORT &&
-	    dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT)
-		return;
+	if (dev->pcie_type == PCIE_RC_PORT ||
+	    dev->pcie_type == PCIE_SW_UPSTREAM_PORT ||
+	    dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) {
+		if (enable)
+			pci_enable_pcie_error_reporting(dev);
+		else
+			pci_disable_pcie_error_reporting(dev);
+	}
 
 
 	if (enable)
 	if (enable)
-		pci_enable_pcie_error_reporting(dev);
-	else
-		pci_disable_pcie_error_reporting(dev);
+		pcie_set_ecrc_checking(dev);
+
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -139,73 +145,148 @@ static void set_downstream_devices_error_reporting(struct pci_dev *dev,
 	pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
 	pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
 }
 }
 
 
-static int find_device_iter(struct device *device, void *data)
+static inline int compare_device_id(struct pci_dev *dev,
+			struct aer_err_info *e_info)
 {
 {
-	struct pci_dev *dev;
-	u16 id = *(unsigned long *)data;
-	u8 secondary, subordinate, d_bus = id >> 8;
+	if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) {
+		/*
+		 * Device ID match
+		 */
+		return 1;
+	}
 
 
-	if (device->bus == &pci_bus_type) {
-		dev = to_pci_dev(device);
-		if (id == ((dev->bus->number << 8) | dev->devfn)) {
-			/*
-			 * Device ID match
-			 */
-			*(unsigned long*)data = (unsigned long)device;
-			return 1;
-		}
+	return 0;
+}
+
+static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)
+{
+	if (e_info->error_dev_num < AER_MAX_MULTI_ERR_DEVICES) {
+		e_info->dev[e_info->error_dev_num] = dev;
+		e_info->error_dev_num++;
+		return 1;
+	} else
+		return 0;
+}
+
+
+#define	PCI_BUS(x)	(((x) >> 8) & 0xff)
+
+static int find_device_iter(struct pci_dev *dev, void *data)
+{
+	int pos;
+	u32 status;
+	u32 mask;
+	u16 reg16;
+	int result;
+	struct aer_err_info *e_info = (struct aer_err_info *)data;
+
+	/*
+	 * When bus id is equal to 0, it might be a bad id
+	 * reported by root port.
+	 */
+	if (!nosourceid && (PCI_BUS(e_info->id) != 0)) {
+		result = compare_device_id(dev, e_info);
+		if (result)
+			add_error_device(e_info, dev);
 
 
 		/*
 		/*
-		 * If device is P2P, check if it is an upstream?
+		 * If there is no multiple error, we stop
+		 * or continue based on the id comparing.
 		 */
 		 */
-		if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
-			pci_read_config_byte(dev, PCI_SECONDARY_BUS,
-				&secondary);
-			pci_read_config_byte(dev, PCI_SUBORDINATE_BUS,
-				&subordinate);
-			if (d_bus >= secondary && d_bus <= subordinate) {
-				*(unsigned long*)data = (unsigned long)device;
-				return 1;
-			}
+		if (!(e_info->flags & AER_MULTI_ERROR_VALID_FLAG))
+			return result;
+
+		/*
+		 * If there are multiple errors and id does match,
+		 * We need continue to search other devices under
+		 * the root port. Return 0 means that.
+		 */
+		if (result)
+			return 0;
+	}
+
+	/*
+	 * When either
+	 *      1) nosourceid==y;
+	 *      2) bus id is equal to 0. Some ports might lose the bus
+	 *              id of error source id;
+	 *      3) There are multiple errors and prior id comparing fails;
+	 * We check AER status registers to find the initial reporter.
+	 */
+	if (atomic_read(&dev->enable_cnt) == 0)
+		return 0;
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return 0;
+	/* Check if AER is enabled */
+	pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16);
+	if (!(reg16 & (
+		PCI_EXP_DEVCTL_CERE |
+		PCI_EXP_DEVCTL_NFERE |
+		PCI_EXP_DEVCTL_FERE |
+		PCI_EXP_DEVCTL_URRE)))
+		return 0;
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos)
+		return 0;
+
+	status = 0;
+	mask = 0;
+	if (e_info->severity == AER_CORRECTABLE) {
+		pci_read_config_dword(dev,
+				pos + PCI_ERR_COR_STATUS,
+				&status);
+		pci_read_config_dword(dev,
+				pos + PCI_ERR_COR_MASK,
+				&mask);
+		if (status & ERR_CORRECTABLE_ERROR_MASK & ~mask) {
+			add_error_device(e_info, dev);
+			goto added;
+		}
+	} else {
+		pci_read_config_dword(dev,
+				pos + PCI_ERR_UNCOR_STATUS,
+				&status);
+		pci_read_config_dword(dev,
+				pos + PCI_ERR_UNCOR_MASK,
+				&mask);
+		if (status & ERR_UNCORRECTABLE_ERROR_MASK & ~mask) {
+			add_error_device(e_info, dev);
+			goto added;
 		}
 		}
 	}
 	}
 
 
 	return 0;
 	return 0;
+
+added:
+	if (e_info->flags & AER_MULTI_ERROR_VALID_FLAG)
+		return 0;
+	else
+		return 1;
 }
 }
 
 
 /**
 /**
  * find_source_device - search through device hierarchy for source device
  * find_source_device - search through device hierarchy for source device
  * @parent: pointer to Root Port pci_dev data structure
  * @parent: pointer to Root Port pci_dev data structure
- * @id: device ID of agent who sends an error message to this Root Port
+ * @err_info: including detailed error information such like id
  *
  *
  * Invoked when error is detected at the Root Port.
  * Invoked when error is detected at the Root Port.
  */
  */
-static struct device* find_source_device(struct pci_dev *parent, u16 id)
+static void find_source_device(struct pci_dev *parent,
+		struct aer_err_info *e_info)
 {
 {
 	struct pci_dev *dev = parent;
 	struct pci_dev *dev = parent;
-	struct device *device;
-	unsigned long device_addr;
-	int status;
+	int result;
 
 
 	/* Is Root Port an agent that sends error message? */
 	/* Is Root Port an agent that sends error message? */
-	if (id == ((dev->bus->number << 8) | dev->devfn))
-		return &dev->dev;
-
-	do {
-		device_addr = id;
- 		if ((status = device_for_each_child(&dev->dev,
-			&device_addr, find_device_iter))) {
-			device = (struct device*)device_addr;
-			dev = to_pci_dev(device);
-			if (id == ((dev->bus->number << 8) | dev->devfn))
-				return device;
-		}
- 	}while (status);
+	result = find_device_iter(dev, e_info);
+	if (result)
+		return;
 
 
-	return NULL;
+	pci_walk_bus(parent->subordinate, find_device_iter, e_info);
 }
 }
 
 
-static void report_error_detected(struct pci_dev *dev, void *data)
+static int report_error_detected(struct pci_dev *dev, void *data)
 {
 {
 	pci_ers_result_t vote;
 	pci_ers_result_t vote;
 	struct pci_error_handlers *err_handler;
 	struct pci_error_handlers *err_handler;
@@ -230,16 +311,16 @@ static void report_error_detected(struct pci_dev *dev, void *data)
 				   dev->driver ?
 				   dev->driver ?
 				   "no AER-aware driver" : "no driver");
 				   "no AER-aware driver" : "no driver");
 		}
 		}
-		return;
+		return 0;
 	}
 	}
 
 
 	err_handler = dev->driver->err_handler;
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->error_detected(dev, result_data->state);
 	vote = err_handler->error_detected(dev, result_data->state);
 	result_data->result = merge_result(result_data->result, vote);
 	result_data->result = merge_result(result_data->result, vote);
-	return;
+	return 0;
 }
 }
 
 
-static void report_mmio_enabled(struct pci_dev *dev, void *data)
+static int report_mmio_enabled(struct pci_dev *dev, void *data)
 {
 {
 	pci_ers_result_t vote;
 	pci_ers_result_t vote;
 	struct pci_error_handlers *err_handler;
 	struct pci_error_handlers *err_handler;
@@ -249,15 +330,15 @@ static void report_mmio_enabled(struct pci_dev *dev, void *data)
 	if (!dev->driver ||
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->mmio_enabled)
 		!dev->driver->err_handler->mmio_enabled)
-		return;
+		return 0;
 
 
 	err_handler = dev->driver->err_handler;
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->mmio_enabled(dev);
 	vote = err_handler->mmio_enabled(dev);
 	result_data->result = merge_result(result_data->result, vote);
 	result_data->result = merge_result(result_data->result, vote);
-	return;
+	return 0;
 }
 }
 
 
-static void report_slot_reset(struct pci_dev *dev, void *data)
+static int report_slot_reset(struct pci_dev *dev, void *data)
 {
 {
 	pci_ers_result_t vote;
 	pci_ers_result_t vote;
 	struct pci_error_handlers *err_handler;
 	struct pci_error_handlers *err_handler;
@@ -267,15 +348,15 @@ static void report_slot_reset(struct pci_dev *dev, void *data)
 	if (!dev->driver ||
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->slot_reset)
 		!dev->driver->err_handler->slot_reset)
-		return;
+		return 0;
 
 
 	err_handler = dev->driver->err_handler;
 	err_handler = dev->driver->err_handler;
 	vote = err_handler->slot_reset(dev);
 	vote = err_handler->slot_reset(dev);
 	result_data->result = merge_result(result_data->result, vote);
 	result_data->result = merge_result(result_data->result, vote);
-	return;
+	return 0;
 }
 }
 
 
-static void report_resume(struct pci_dev *dev, void *data)
+static int report_resume(struct pci_dev *dev, void *data)
 {
 {
 	struct pci_error_handlers *err_handler;
 	struct pci_error_handlers *err_handler;
 
 
@@ -284,11 +365,11 @@ static void report_resume(struct pci_dev *dev, void *data)
 	if (!dev->driver ||
 	if (!dev->driver ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler ||
 		!dev->driver->err_handler->resume)
 		!dev->driver->err_handler->resume)
-		return;
+		return 0;
 
 
 	err_handler = dev->driver->err_handler;
 	err_handler = dev->driver->err_handler;
 	err_handler->resume(dev);
 	err_handler->resume(dev);
-	return;
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -305,7 +386,7 @@ static void report_resume(struct pci_dev *dev, void *data)
 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
 static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
 	enum pci_channel_state state,
 	enum pci_channel_state state,
 	char *error_mesg,
 	char *error_mesg,
-	void (*cb)(struct pci_dev *, void *))
+	int (*cb)(struct pci_dev *, void *))
 {
 {
 	struct aer_broadcast_data result_data;
 	struct aer_broadcast_data result_data;
 
 
@@ -497,12 +578,12 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
  */
  */
 static void handle_error_source(struct pcie_device * aerdev,
 static void handle_error_source(struct pcie_device * aerdev,
 	struct pci_dev *dev,
 	struct pci_dev *dev,
-	struct aer_err_info info)
+	struct aer_err_info *info)
 {
 {
 	pci_ers_result_t status = 0;
 	pci_ers_result_t status = 0;
 	int pos;
 	int pos;
 
 
-	if (info.severity == AER_CORRECTABLE) {
+	if (info->severity == AER_CORRECTABLE) {
 		/*
 		/*
 		 * Correctable error does not need software intevention.
 		 * Correctable error does not need software intevention.
 		 * No need to go through error recovery process.
 		 * No need to go through error recovery process.
@@ -510,9 +591,9 @@ static void handle_error_source(struct pcie_device * aerdev,
 		pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 		pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 		if (pos)
 		if (pos)
 			pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
 			pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
-					info.status);
+					info->status);
 	} else {
 	} else {
-		status = do_recovery(aerdev, dev, info.severity);
+		status = do_recovery(aerdev, dev, info->severity);
 		if (status == PCI_ERS_RESULT_RECOVERED) {
 		if (status == PCI_ERS_RESULT_RECOVERED) {
 			dev_printk(KERN_DEBUG, &dev->dev, "AER driver "
 			dev_printk(KERN_DEBUG, &dev->dev, "AER driver "
 				   "successfully recovered\n");
 				   "successfully recovered\n");
@@ -661,6 +742,28 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 	return AER_SUCCESS;
 	return AER_SUCCESS;
 }
 }
 
 
+static inline void aer_process_err_devices(struct pcie_device *p_device,
+			struct aer_err_info *e_info)
+{
+	int i;
+
+	if (!e_info->dev[0]) {
+		dev_printk(KERN_DEBUG, &p_device->port->dev,
+				"can't find device of ID%04x\n",
+				e_info->id);
+	}
+
+	for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) {
+		if (get_device_error_info(e_info->dev[i], e_info) ==
+				AER_SUCCESS) {
+			aer_print_error(e_info->dev[i], e_info);
+			handle_error_source(p_device,
+					e_info->dev[i],
+					e_info);
+		}
+	}
+}
+
 /**
 /**
  * aer_isr_one_error - consume an error detected by root port
  * aer_isr_one_error - consume an error detected by root port
  * @p_device: pointer to error root port service device
  * @p_device: pointer to error root port service device
@@ -669,10 +772,16 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 static void aer_isr_one_error(struct pcie_device *p_device,
 static void aer_isr_one_error(struct pcie_device *p_device,
 		struct aer_err_source *e_src)
 		struct aer_err_source *e_src)
 {
 {
-	struct device *s_device;
-	struct aer_err_info e_info = {0, 0, 0,};
+	struct aer_err_info *e_info;
 	int i;
 	int i;
-	u16 id;
+
+	/* struct aer_err_info might be big, so we allocate it with slab */
+	e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
+	if (e_info == NULL) {
+		dev_printk(KERN_DEBUG, &p_device->port->dev,
+			"Can't allocate mem when processing AER errors\n");
+		return;
+	}
 
 
 	/*
 	/*
 	 * There is a possibility that both correctable error and
 	 * There is a possibility that both correctable error and
@@ -684,31 +793,26 @@ static void aer_isr_one_error(struct pcie_device *p_device,
 		if (!(e_src->status & i))
 		if (!(e_src->status & i))
 			continue;
 			continue;
 
 
+		memset(e_info, 0, sizeof(struct aer_err_info));
+
 		/* Init comprehensive error information */
 		/* Init comprehensive error information */
 		if (i & PCI_ERR_ROOT_COR_RCV) {
 		if (i & PCI_ERR_ROOT_COR_RCV) {
-			id = ERR_COR_ID(e_src->id);
-			e_info.severity = AER_CORRECTABLE;
+			e_info->id = ERR_COR_ID(e_src->id);
+			e_info->severity = AER_CORRECTABLE;
 		} else {
 		} else {
-			id = ERR_UNCOR_ID(e_src->id);
-			e_info.severity = ((e_src->status >> 6) & 1);
+			e_info->id = ERR_UNCOR_ID(e_src->id);
+			e_info->severity = ((e_src->status >> 6) & 1);
 		}
 		}
 		if (e_src->status &
 		if (e_src->status &
 			(PCI_ERR_ROOT_MULTI_COR_RCV |
 			(PCI_ERR_ROOT_MULTI_COR_RCV |
 			 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
 			 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
-			e_info.flags |= AER_MULTI_ERROR_VALID_FLAG;
-		if (!(s_device = find_source_device(p_device->port, id))) {
-			printk(KERN_DEBUG "%s->can't find device of ID%04x\n",
-				__func__, id);
-			continue;
-		}
-		if (get_device_error_info(to_pci_dev(s_device), &e_info) ==
-				AER_SUCCESS) {
-			aer_print_error(to_pci_dev(s_device), &e_info);
-			handle_error_source(p_device,
-				to_pci_dev(s_device),
-				e_info);
-		}
+			e_info->flags |= AER_MULTI_ERROR_VALID_FLAG;
+
+		find_source_device(p_device->port, e_info);
+		aer_process_err_devices(p_device, e_info);
 	}
 	}
+
+	kfree(e_info);
 }
 }
 
 
 /**
 /**

+ 131 - 0
drivers/pci/pcie/aer/ecrc.c

@@ -0,0 +1,131 @@
+/*
+ *    Enables/disables PCIe ECRC checking.
+ *
+ *    (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
+ *    Andrew Patterson <andrew.patterson@hp.com>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; version 2 of the License.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *    General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *    02111-1307, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+#include <linux/pci_regs.h>
+#include <linux/errno.h>
+#include "../../pci.h"
+
+#define ECRC_POLICY_DEFAULT 0		/* ECRC set by BIOS */
+#define ECRC_POLICY_OFF     1		/* ECRC off for performance */
+#define ECRC_POLICY_ON      2		/* ECRC on for data integrity */
+
+static int ecrc_policy = ECRC_POLICY_DEFAULT;
+
+static const char *ecrc_policy_str[] = {
+	[ECRC_POLICY_DEFAULT] = "bios",
+	[ECRC_POLICY_OFF] = "off",
+	[ECRC_POLICY_ON] = "on"
+};
+
+/**
+ * enable_ercr_checking - enable PCIe ECRC checking for a device
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+static int enable_ecrc_checking(struct pci_dev *dev)
+{
+	int pos;
+	u32 reg32;
+
+	if (!dev->is_pcie)
+		return -ENODEV;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos)
+		return -ENODEV;
+
+	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
+	if (reg32 & PCI_ERR_CAP_ECRC_GENC)
+		reg32 |= PCI_ERR_CAP_ECRC_GENE;
+	if (reg32 & PCI_ERR_CAP_ECRC_CHKC)
+		reg32 |= PCI_ERR_CAP_ECRC_CHKE;
+	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+
+	return 0;
+}
+
+/**
+ * disable_ercr_checking - disables PCIe ECRC checking for a device
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+static int disable_ecrc_checking(struct pci_dev *dev)
+{
+	int pos;
+	u32 reg32;
+
+	if (!dev->is_pcie)
+		return -ENODEV;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos)
+		return -ENODEV;
+
+	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
+	reg32 &= ~(PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE);
+	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+
+	return 0;
+}
+
+/**
+ * pcie_set_ecrc_checking - set/unset PCIe ECRC checking for a device based on global policy
+ * @dev: the PCI device
+ */
+void pcie_set_ecrc_checking(struct pci_dev *dev)
+{
+	switch (ecrc_policy) {
+	case ECRC_POLICY_DEFAULT:
+		return;
+	case ECRC_POLICY_OFF:
+		disable_ecrc_checking(dev);
+		break;
+	case ECRC_POLICY_ON:
+		enable_ecrc_checking(dev);;
+		break;
+	default:
+		return;
+	}
+}
+
+/**
+ * pcie_ecrc_get_policy - parse kernel command-line ecrc option
+ */
+void pcie_ecrc_get_policy(char *str)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ecrc_policy_str); i++)
+		if (!strncmp(str, ecrc_policy_str[i],
+			     strlen(ecrc_policy_str[i])))
+			break;
+	if (i >= ARRAY_SIZE(ecrc_policy_str))
+		return;
+
+	ecrc_policy = i;
+}

+ 371 - 416
drivers/pci/pcie/aspm.c

@@ -26,40 +26,36 @@
 #endif
 #endif
 #define MODULE_PARAM_PREFIX "pcie_aspm."
 #define MODULE_PARAM_PREFIX "pcie_aspm."
 
 
-struct endpoint_state {
-	unsigned int l0s_acceptable_latency;
-	unsigned int l1_acceptable_latency;
+struct aspm_latency {
+	u32 l0s;			/* L0s latency (nsec) */
+	u32 l1;				/* L1 latency (nsec) */
 };
 };
 
 
 struct pcie_link_state {
 struct pcie_link_state {
-	struct list_head sibiling;
-	struct pci_dev *pdev;
-	bool downstream_has_switch;
-
-	struct pcie_link_state *parent;
-	struct list_head children;
-	struct list_head link;
+	struct pci_dev *pdev;		/* Upstream component of the Link */
+	struct pcie_link_state *root;	/* pointer to the root port link */
+	struct pcie_link_state *parent;	/* pointer to the parent Link state */
+	struct list_head sibling;	/* node in link_list */
+	struct list_head children;	/* list of child link states */
+	struct list_head link;		/* node in parent's children list */
 
 
 	/* ASPM state */
 	/* ASPM state */
-	unsigned int support_state;
-	unsigned int enabled_state;
-	unsigned int bios_aspm_state;
-	/* upstream component */
-	unsigned int l0s_upper_latency;
-	unsigned int l1_upper_latency;
-	/* downstream component */
-	unsigned int l0s_down_latency;
-	unsigned int l1_down_latency;
-	/* Clock PM state*/
-	unsigned int clk_pm_capable;
-	unsigned int clk_pm_enabled;
-	unsigned int bios_clk_state;
+	u32 aspm_support:2;		/* Supported ASPM state */
+	u32 aspm_enabled:2;		/* Enabled ASPM state */
+	u32 aspm_default:2;		/* Default ASPM state by BIOS */
+
+	/* Clock PM state */
+	u32 clkpm_capable:1;		/* Clock PM capable? */
+	u32 clkpm_enabled:1;		/* Current Clock PM state */
+	u32 clkpm_default:1;		/* Default Clock PM state by BIOS */
 
 
+	/* Latencies */
+	struct aspm_latency latency;	/* Exit latency */
 	/*
 	/*
-	 * A pcie downstream port only has one slot under it, so at most there
-	 * are 8 functions
+	 * Endpoint acceptable latencies. A pcie downstream port only
+	 * has one slot under it, so at most there are 8 functions.
 	 */
 	 */
-	struct endpoint_state endpoints[8];
+	struct aspm_latency acceptable[8];
 };
 };
 
 
 static int aspm_disabled, aspm_force;
 static int aspm_disabled, aspm_force;
@@ -78,27 +74,23 @@ static const char *policy_str[] = {
 
 
 #define LINK_RETRAIN_TIMEOUT HZ
 #define LINK_RETRAIN_TIMEOUT HZ
 
 
-static int policy_to_aspm_state(struct pci_dev *pdev)
+static int policy_to_aspm_state(struct pcie_link_state *link)
 {
 {
-	struct pcie_link_state *link_state = pdev->link_state;
-
 	switch (aspm_policy) {
 	switch (aspm_policy) {
 	case POLICY_PERFORMANCE:
 	case POLICY_PERFORMANCE:
 		/* Disable ASPM and Clock PM */
 		/* Disable ASPM and Clock PM */
 		return 0;
 		return 0;
 	case POLICY_POWERSAVE:
 	case POLICY_POWERSAVE:
 		/* Enable ASPM L0s/L1 */
 		/* Enable ASPM L0s/L1 */
-		return PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
+		return PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
 	case POLICY_DEFAULT:
 	case POLICY_DEFAULT:
-		return link_state->bios_aspm_state;
+		return link->aspm_default;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-static int policy_to_clkpm_state(struct pci_dev *pdev)
+static int policy_to_clkpm_state(struct pcie_link_state *link)
 {
 {
-	struct pcie_link_state *link_state = pdev->link_state;
-
 	switch (aspm_policy) {
 	switch (aspm_policy) {
 	case POLICY_PERFORMANCE:
 	case POLICY_PERFORMANCE:
 		/* Disable ASPM and Clock PM */
 		/* Disable ASPM and Clock PM */
@@ -107,73 +99,78 @@ static int policy_to_clkpm_state(struct pci_dev *pdev)
 		/* Disable Clock PM */
 		/* Disable Clock PM */
 		return 1;
 		return 1;
 	case POLICY_DEFAULT:
 	case POLICY_DEFAULT:
-		return link_state->bios_clk_state;
+		return link->clkpm_default;
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-static void pcie_set_clock_pm(struct pci_dev *pdev, int enable)
+static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
 {
 {
-	struct pci_dev *child_dev;
 	int pos;
 	int pos;
 	u16 reg16;
 	u16 reg16;
-	struct pcie_link_state *link_state = pdev->link_state;
+	struct pci_dev *child;
+	struct pci_bus *linkbus = link->pdev->subordinate;
 
 
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
 		if (!pos)
 		if (!pos)
 			return;
 			return;
-		pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16);
+		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
 		if (enable)
 		if (enable)
 			reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
 			reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN;
 		else
 		else
 			reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
 			reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
-		pci_write_config_word(child_dev, pos + PCI_EXP_LNKCTL, reg16);
+		pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16);
 	}
 	}
-	link_state->clk_pm_enabled = !!enable;
+	link->clkpm_enabled = !!enable;
 }
 }
 
 
-static void pcie_check_clock_pm(struct pci_dev *pdev, int blacklist)
+static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
 {
 {
-	int pos;
+	/* Don't enable Clock PM if the link is not Clock PM capable */
+	if (!link->clkpm_capable && enable)
+		return;
+	/* Need nothing if the specified equals to current state */
+	if (link->clkpm_enabled == enable)
+		return;
+	pcie_set_clkpm_nocheck(link, enable);
+}
+
+static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
+{
+	int pos, capable = 1, enabled = 1;
 	u32 reg32;
 	u32 reg32;
 	u16 reg16;
 	u16 reg16;
-	int capable = 1, enabled = 1;
-	struct pci_dev *child_dev;
-	struct pcie_link_state *link_state = pdev->link_state;
+	struct pci_dev *child;
+	struct pci_bus *linkbus = link->pdev->subordinate;
 
 
 	/* All functions should have the same cap and state, take the worst */
 	/* All functions should have the same cap and state, take the worst */
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
 		if (!pos)
 		if (!pos)
 			return;
 			return;
-		pci_read_config_dword(child_dev, pos + PCI_EXP_LNKCAP, &reg32);
+		pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, &reg32);
 		if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
 		if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) {
 			capable = 0;
 			capable = 0;
 			enabled = 0;
 			enabled = 0;
 			break;
 			break;
 		}
 		}
-		pci_read_config_word(child_dev, pos + PCI_EXP_LNKCTL, &reg16);
+		pci_read_config_word(child, pos + PCI_EXP_LNKCTL, &reg16);
 		if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
 		if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN))
 			enabled = 0;
 			enabled = 0;
 	}
 	}
-	link_state->clk_pm_enabled = enabled;
-	link_state->bios_clk_state = enabled;
-	if (!blacklist) {
-		link_state->clk_pm_capable = capable;
-		pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev));
-	} else {
-		link_state->clk_pm_capable = 0;
-		pcie_set_clock_pm(pdev, 0);
-	}
+	link->clkpm_enabled = enabled;
+	link->clkpm_default = enabled;
+	link->clkpm_capable = (blacklist) ? 0 : capable;
 }
 }
 
 
-static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev)
+static bool pcie_aspm_downstream_has_switch(struct pcie_link_state *link)
 {
 {
-	struct pci_dev *child_dev;
+	struct pci_dev *child;
+	struct pci_bus *linkbus = link->pdev->subordinate;
 
 
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		if (child_dev->pcie_type == PCI_EXP_TYPE_UPSTREAM)
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		if (child->pcie_type == PCI_EXP_TYPE_UPSTREAM)
 			return true;
 			return true;
 	}
 	}
 	return false;
 	return false;
@@ -184,289 +181,263 @@ static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev)
  *   could use common clock. If they are, configure them to use the
  *   could use common clock. If they are, configure them to use the
  *   common clock. That will reduce the ASPM state exit latency.
  *   common clock. That will reduce the ASPM state exit latency.
  */
  */
-static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
+static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
 {
 {
-	int pos, child_pos, i = 0;
-	u16 reg16 = 0;
-	struct pci_dev *child_dev;
-	int same_clock = 1;
+	int ppos, cpos, same_clock = 1;
+	u16 reg16, parent_reg, child_reg[8];
 	unsigned long start_jiffies;
 	unsigned long start_jiffies;
-	u16 child_regs[8], parent_reg;
+	struct pci_dev *child, *parent = link->pdev;
+	struct pci_bus *linkbus = parent->subordinate;
 	/*
 	/*
-	 * all functions of a slot should have the same Slot Clock
+	 * All functions of a slot should have the same Slot Clock
 	 * Configuration, so just check one function
 	 * Configuration, so just check one function
-	 * */
-	child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev,
-		bus_list);
-	BUG_ON(!child_dev->is_pcie);
+	 */
+	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
+	BUG_ON(!child->is_pcie);
 
 
 	/* Check downstream component if bit Slot Clock Configuration is 1 */
 	/* Check downstream component if bit Slot Clock Configuration is 1 */
-	child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
-	pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKSTA, &reg16);
+	cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+	pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 		same_clock = 0;
 
 
 	/* Check upstream component if bit Slot Clock Configuration is 1 */
 	/* Check upstream component if bit Slot Clock Configuration is 1 */
-	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-	pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
+	ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
+	pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 	if (!(reg16 & PCI_EXP_LNKSTA_SLC))
 		same_clock = 0;
 		same_clock = 0;
 
 
 	/* Configure downstream component, all functions */
 	/* Configure downstream component, all functions */
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
-		pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
-			&reg16);
-		child_regs[i] = reg16;
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, &reg16);
+		child_reg[PCI_FUNC(child->devfn)] = reg16;
 		if (same_clock)
 		if (same_clock)
 			reg16 |= PCI_EXP_LNKCTL_CCC;
 			reg16 |= PCI_EXP_LNKCTL_CCC;
 		else
 		else
 			reg16 &= ~PCI_EXP_LNKCTL_CCC;
 			reg16 &= ~PCI_EXP_LNKCTL_CCC;
-		pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
-			reg16);
-		i++;
+		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16);
 	}
 	}
 
 
 	/* Configure upstream component */
 	/* Configure upstream component */
-	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+	pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, &reg16);
 	parent_reg = reg16;
 	parent_reg = reg16;
 	if (same_clock)
 	if (same_clock)
 		reg16 |= PCI_EXP_LNKCTL_CCC;
 		reg16 |= PCI_EXP_LNKCTL_CCC;
 	else
 	else
 		reg16 &= ~PCI_EXP_LNKCTL_CCC;
 		reg16 &= ~PCI_EXP_LNKCTL_CCC;
-	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
 
 
-	/* retrain link */
+	/* Retrain link */
 	reg16 |= PCI_EXP_LNKCTL_RL;
 	reg16 |= PCI_EXP_LNKCTL_RL;
-	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16);
 
 
-	/* Wait for link training end */
-	/* break out after waiting for timeout */
+	/* Wait for link training end. Break out after waiting for timeout */
 	start_jiffies = jiffies;
 	start_jiffies = jiffies;
 	for (;;) {
 	for (;;) {
-		pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
+		pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, &reg16);
 		if (!(reg16 & PCI_EXP_LNKSTA_LT))
 		if (!(reg16 & PCI_EXP_LNKSTA_LT))
 			break;
 			break;
 		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
 		if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT))
 			break;
 			break;
 		msleep(1);
 		msleep(1);
 	}
 	}
-	/* training failed -> recover */
-	if (reg16 & PCI_EXP_LNKSTA_LT) {
-		dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure"
-			    " common clock\n");
-		i = 0;
-		list_for_each_entry(child_dev, &pdev->subordinate->devices,
-				    bus_list) {
-			child_pos = pci_find_capability(child_dev,
-							PCI_CAP_ID_EXP);
-			pci_write_config_word(child_dev,
-					      child_pos + PCI_EXP_LNKCTL,
-					      child_regs[i]);
-			i++;
-		}
-		pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, parent_reg);
+	if (!(reg16 & PCI_EXP_LNKSTA_LT))
+		return;
+
+	/* Training failed. Restore common clock configurations */
+	dev_printk(KERN_ERR, &parent->dev,
+		   "ASPM: Could not configure common clock\n");
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		cpos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pci_write_config_word(child, cpos + PCI_EXP_LNKCTL,
+				      child_reg[PCI_FUNC(child->devfn)]);
 	}
 	}
+	pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg);
 }
 }
 
 
-/*
- * calc_L0S_latency: Convert L0s latency encoding to ns
- */
-static unsigned int calc_L0S_latency(unsigned int latency_encoding, int ac)
+/* Convert L0s latency encoding to ns */
+static u32 calc_l0s_latency(u32 encoding)
 {
 {
-	unsigned int ns = 64;
+	if (encoding == 0x7)
+		return (5 * 1000);	/* > 4us */
+	return (64 << encoding);
+}
 
 
-	if (latency_encoding == 0x7) {
-		if (ac)
-			ns = -1U;
-		else
-			ns = 5*1000; /* > 4us */
-	} else
-		ns *= (1 << latency_encoding);
-	return ns;
+/* Convert L0s acceptable latency encoding to ns */
+static u32 calc_l0s_acceptable(u32 encoding)
+{
+	if (encoding == 0x7)
+		return -1U;
+	return (64 << encoding);
 }
 }
 
 
-/*
- * calc_L1_latency: Convert L1 latency encoding to ns
- */
-static unsigned int calc_L1_latency(unsigned int latency_encoding, int ac)
+/* Convert L1 latency encoding to ns */
+static u32 calc_l1_latency(u32 encoding)
 {
 {
-	unsigned int ns = 1000;
+	if (encoding == 0x7)
+		return (65 * 1000);	/* > 64us */
+	return (1000 << encoding);
+}
 
 
-	if (latency_encoding == 0x7) {
-		if (ac)
-			ns = -1U;
-		else
-			ns = 65*1000; /* > 64us */
-	} else
-		ns *= (1 << latency_encoding);
-	return ns;
+/* Convert L1 acceptable latency encoding to ns */
+static u32 calc_l1_acceptable(u32 encoding)
+{
+	if (encoding == 0x7)
+		return -1U;
+	return (1000 << encoding);
 }
 }
 
 
 static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
 static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
-	unsigned int *l0s, unsigned int *l1, unsigned int *enabled)
+				     u32 *l0s, u32 *l1, u32 *enabled)
 {
 {
 	int pos;
 	int pos;
 	u16 reg16;
 	u16 reg16;
-	u32 reg32;
-	unsigned int latency;
+	u32 reg32, encoding;
 
 
+	*l0s = *l1 = *enabled = 0;
 	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
 	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
 	*state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
 	*state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
 	if (*state != PCIE_LINK_STATE_L0S &&
 	if (*state != PCIE_LINK_STATE_L0S &&
-		*state != (PCIE_LINK_STATE_L1|PCIE_LINK_STATE_L0S))
+	    *state != (PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L0S))
 		*state = 0;
 		*state = 0;
 	if (*state == 0)
 	if (*state == 0)
 		return;
 		return;
 
 
-	latency = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
-	*l0s = calc_L0S_latency(latency, 0);
+	encoding = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
+	*l0s = calc_l0s_latency(encoding);
 	if (*state & PCIE_LINK_STATE_L1) {
 	if (*state & PCIE_LINK_STATE_L1) {
-		latency = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
-		*l1 = calc_L1_latency(latency, 0);
+		encoding = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
+		*l1 = calc_l1_latency(encoding);
 	}
 	}
 	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
 	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
-	*enabled = reg16 & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1);
+	*enabled = reg16 & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
 }
 }
 
 
-static void pcie_aspm_cap_init(struct pci_dev *pdev)
+static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
 {
-	struct pci_dev *child_dev;
-	u32 state, tmp;
-	struct pcie_link_state *link_state = pdev->link_state;
+	u32 support, l0s, l1, enabled;
+	struct pci_dev *child, *parent = link->pdev;
+	struct pci_bus *linkbus = parent->subordinate;
+
+	if (blacklist) {
+		/* Set support state to 0, so we will disable ASPM later */
+		link->aspm_support = 0;
+		link->aspm_default = 0;
+		link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
+		return;
+	}
+
+	/* Configure common clock before checking latencies */
+	pcie_aspm_configure_common_clock(link);
 
 
 	/* upstream component states */
 	/* upstream component states */
-	pcie_aspm_get_cap_device(pdev, &link_state->support_state,
-		&link_state->l0s_upper_latency,
-		&link_state->l1_upper_latency,
-		&link_state->enabled_state);
+	pcie_aspm_get_cap_device(parent, &support, &l0s, &l1, &enabled);
+	link->aspm_support = support;
+	link->latency.l0s = l0s;
+	link->latency.l1 = l1;
+	link->aspm_enabled = enabled;
+
 	/* downstream component states, all functions have the same setting */
 	/* downstream component states, all functions have the same setting */
-	child_dev = list_entry(pdev->subordinate->devices.next, struct pci_dev,
-		bus_list);
-	pcie_aspm_get_cap_device(child_dev, &state,
-		&link_state->l0s_down_latency,
-		&link_state->l1_down_latency,
-		&tmp);
-	link_state->support_state &= state;
-	if (!link_state->support_state)
+	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
+	pcie_aspm_get_cap_device(child, &support, &l0s, &l1, &enabled);
+	link->aspm_support &= support;
+	link->latency.l0s = max_t(u32, link->latency.l0s, l0s);
+	link->latency.l1 = max_t(u32, link->latency.l1, l1);
+
+	if (!link->aspm_support)
 		return;
 		return;
-	link_state->enabled_state &= link_state->support_state;
-	link_state->bios_aspm_state = link_state->enabled_state;
+
+	link->aspm_enabled &= link->aspm_support;
+	link->aspm_default = link->aspm_enabled;
 
 
 	/* ENDPOINT states*/
 	/* ENDPOINT states*/
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
 		int pos;
 		int pos;
-		u32 reg32;
-		unsigned int latency;
-		struct endpoint_state *ep_state =
-			&link_state->endpoints[PCI_FUNC(child_dev->devfn)];
+		u32 reg32, encoding;
+		struct aspm_latency *acceptable =
+			&link->acceptable[PCI_FUNC(child->devfn)];
 
 
-		if (child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
-			child_dev->pcie_type != PCI_EXP_TYPE_LEG_END)
+		if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
+		    child->pcie_type != PCI_EXP_TYPE_LEG_END)
 			continue;
 			continue;
 
 
-		pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
-		pci_read_config_dword(child_dev, pos + PCI_EXP_DEVCAP, &reg32);
-		latency = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
-		latency = calc_L0S_latency(latency, 1);
-		ep_state->l0s_acceptable_latency = latency;
-		if (link_state->support_state & PCIE_LINK_STATE_L1) {
-			latency = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
-			latency = calc_L1_latency(latency, 1);
-			ep_state->l1_acceptable_latency = latency;
+		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
+		acceptable->l0s = calc_l0s_acceptable(encoding);
+		if (link->aspm_support & PCIE_LINK_STATE_L1) {
+			encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
+			acceptable->l1 = calc_l1_acceptable(encoding);
 		}
 		}
 	}
 	}
 }
 }
 
 
-static unsigned int __pcie_aspm_check_state_one(struct pci_dev *pdev,
-	unsigned int state)
-{
-	struct pci_dev *parent_dev, *tmp_dev;
-	unsigned int latency, l1_latency = 0;
-	struct pcie_link_state *link_state;
-	struct endpoint_state *ep_state;
-
-	parent_dev = pdev->bus->self;
-	link_state = parent_dev->link_state;
-	state &= link_state->support_state;
-	if (state == 0)
-		return 0;
-	ep_state = &link_state->endpoints[PCI_FUNC(pdev->devfn)];
-
-	/*
-	 * Check latency for endpoint device.
-	 * TBD: The latency from the endpoint to root complex vary per
-	 * switch's upstream link state above the device. Here we just do a
-	 * simple check which assumes all links above the device can be in L1
-	 * state, that is we just consider the worst case. If switch's upstream
-	 * link can't be put into L0S/L1, then our check is too strictly.
-	 */
-	tmp_dev = pdev;
-	while (state & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
-		parent_dev = tmp_dev->bus->self;
-		link_state = parent_dev->link_state;
-		if (state & PCIE_LINK_STATE_L0S) {
-			latency = max_t(unsigned int,
-					link_state->l0s_upper_latency,
-					link_state->l0s_down_latency);
-			if (latency > ep_state->l0s_acceptable_latency)
-				state &= ~PCIE_LINK_STATE_L0S;
-		}
-		if (state & PCIE_LINK_STATE_L1) {
-			latency = max_t(unsigned int,
-					link_state->l1_upper_latency,
-					link_state->l1_down_latency);
-			if (latency + l1_latency >
-					ep_state->l1_acceptable_latency)
-				state &= ~PCIE_LINK_STATE_L1;
-		}
-		if (!parent_dev->bus->self) /* parent_dev is a root port */
-			break;
-		else {
-			/*
-			 * parent_dev is the downstream port of a switch, make
-			 * tmp_dev the upstream port of the switch
-			 */
-			tmp_dev = parent_dev->bus->self;
-			/*
-			 * every switch on the path to root complex need 1 more
-			 * microsecond for L1. Spec doesn't mention L0S.
-			 */
-			if (state & PCIE_LINK_STATE_L1)
-				l1_latency += 1000;
-		}
+/**
+ * __pcie_aspm_check_state_one - check latency for endpoint device.
+ * @endpoint: pointer to the struct pci_dev of endpoint device
+ *
+ * TBD: The latency from the endpoint to root complex vary per switch's
+ * upstream link state above the device. Here we just do a simple check
+ * which assumes all links above the device can be in L1 state, that
+ * is we just consider the worst case. If switch's upstream link can't
+ * be put into L0S/L1, then our check is too strictly.
+ */
+static u32 __pcie_aspm_check_state_one(struct pci_dev *endpoint, u32 state)
+{
+	u32 l1_switch_latency = 0;
+	struct aspm_latency *acceptable;
+	struct pcie_link_state *link;
+
+	link = endpoint->bus->self->link_state;
+	state &= link->aspm_support;
+	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
+
+	while (link && state) {
+		if ((state & PCIE_LINK_STATE_L0S) &&
+		    (link->latency.l0s > acceptable->l0s))
+			state &= ~PCIE_LINK_STATE_L0S;
+		if ((state & PCIE_LINK_STATE_L1) &&
+		    (link->latency.l1 + l1_switch_latency > acceptable->l1))
+			state &= ~PCIE_LINK_STATE_L1;
+		link = link->parent;
+		/*
+		 * Every switch on the path to root complex need 1
+		 * more microsecond for L1. Spec doesn't mention L0s.
+		 */
+		l1_switch_latency += 1000;
 	}
 	}
 	return state;
 	return state;
 }
 }
 
 
-static unsigned int pcie_aspm_check_state(struct pci_dev *pdev,
-	unsigned int state)
+static u32 pcie_aspm_check_state(struct pcie_link_state *link, u32 state)
 {
 {
-	struct pci_dev *child_dev;
+	pci_power_t power_state;
+	struct pci_dev *child;
+	struct pci_bus *linkbus = link->pdev->subordinate;
 
 
 	/* If no child, ignore the link */
 	/* If no child, ignore the link */
-	if (list_empty(&pdev->subordinate->devices))
+	if (list_empty(&linkbus->devices))
 		return state;
 		return state;
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
-			/*
-			 * If downstream component of a link is pci bridge, we
-			 * disable ASPM for now for the link
-			 * */
-			state = 0;
-			break;
-		}
-		if ((child_dev->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
-			child_dev->pcie_type != PCI_EXP_TYPE_LEG_END))
+
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		/*
+		 * If downstream component of a link is pci bridge, we
+		 * disable ASPM for now for the link
+		 */
+		if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+			return 0;
+
+		if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
+		     child->pcie_type != PCI_EXP_TYPE_LEG_END))
 			continue;
 			continue;
 		/* Device not in D0 doesn't need check latency */
 		/* Device not in D0 doesn't need check latency */
-		if (child_dev->current_state == PCI_D1 ||
-			child_dev->current_state == PCI_D2 ||
-			child_dev->current_state == PCI_D3hot ||
-			child_dev->current_state == PCI_D3cold)
+		power_state = child->current_state;
+		if (power_state == PCI_D1 || power_state == PCI_D2 ||
+		    power_state == PCI_D3hot || power_state == PCI_D3cold)
 			continue;
 			continue;
-		state = __pcie_aspm_check_state_one(child_dev, state);
+		state = __pcie_aspm_check_state_one(child, state);
 	}
 	}
 	return state;
 	return state;
 }
 }
@@ -482,90 +453,71 @@ static void __pcie_aspm_config_one_dev(struct pci_dev *pdev, unsigned int state)
 	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
 	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
 }
 }
 
 
-static void __pcie_aspm_config_link(struct pci_dev *pdev, unsigned int state)
+static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
 {
 {
-	struct pci_dev *child_dev;
-	int valid = 1;
-	struct pcie_link_state *link_state = pdev->link_state;
+	struct pci_dev *child, *parent = link->pdev;
+	struct pci_bus *linkbus = parent->subordinate;
 
 
 	/* If no child, disable the link */
 	/* If no child, disable the link */
-	if (list_empty(&pdev->subordinate->devices))
+	if (list_empty(&linkbus->devices))
 		state = 0;
 		state = 0;
 	/*
 	/*
-	 * if the downstream component has pci bridge function, don't do ASPM
-	 * now
+	 * If the downstream component has pci bridge function, don't
+	 * do ASPM now.
 	 */
 	 */
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
-			valid = 0;
-			break;
-		}
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+			return;
 	}
 	}
-	if (!valid)
-		return;
-
 	/*
 	/*
-	 * spec 2.0 suggests all functions should be configured the same
-	 * setting for ASPM. Enabling ASPM L1 should be done in upstream
-	 * component first and then downstream, and vice versa for disabling
-	 * ASPM L1. Spec doesn't mention L0S.
+	 * Spec 2.0 suggests all functions should be configured the
+	 * same setting for ASPM. Enabling ASPM L1 should be done in
+	 * upstream component first and then downstream, and vice
+	 * versa for disabling ASPM L1. Spec doesn't mention L0S.
 	 */
 	 */
 	if (state & PCIE_LINK_STATE_L1)
 	if (state & PCIE_LINK_STATE_L1)
-		__pcie_aspm_config_one_dev(pdev, state);
+		__pcie_aspm_config_one_dev(parent, state);
 
 
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list)
-		__pcie_aspm_config_one_dev(child_dev, state);
+	list_for_each_entry(child, &linkbus->devices, bus_list)
+		__pcie_aspm_config_one_dev(child, state);
 
 
 	if (!(state & PCIE_LINK_STATE_L1))
 	if (!(state & PCIE_LINK_STATE_L1))
-		__pcie_aspm_config_one_dev(pdev, state);
+		__pcie_aspm_config_one_dev(parent, state);
 
 
-	link_state->enabled_state = state;
+	link->aspm_enabled = state;
 }
 }
 
 
-static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link)
+/* Check the whole hierarchy, and configure each link in the hierarchy */
+static void __pcie_aspm_configure_link_state(struct pcie_link_state *link,
+					     u32 state)
 {
 {
-	struct pcie_link_state *root_port_link = link;
-	while (root_port_link->parent)
-		root_port_link = root_port_link->parent;
-	return root_port_link;
-}
+	struct pcie_link_state *leaf, *root = link->root;
 
 
-/* check the whole hierarchy, and configure each link in the hierarchy */
-static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
-	unsigned int state)
-{
-	struct pcie_link_state *link_state = pdev->link_state;
-	struct pcie_link_state *root_port_link = get_root_port_link(link_state);
-	struct pcie_link_state *leaf;
+	state &= (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
 
 
-	state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
-
-	/* check all links who have specific root port link */
-	list_for_each_entry(leaf, &link_list, sibiling) {
-		if (!list_empty(&leaf->children) ||
-			get_root_port_link(leaf) != root_port_link)
+	/* Check all links who have specific root port link */
+	list_for_each_entry(leaf, &link_list, sibling) {
+		if (!list_empty(&leaf->children) || (leaf->root != root))
 			continue;
 			continue;
-		state = pcie_aspm_check_state(leaf->pdev, state);
+		state = pcie_aspm_check_state(leaf, state);
 	}
 	}
-	/* check root port link too in case it hasn't children */
-	state = pcie_aspm_check_state(root_port_link->pdev, state);
-
-	if (link_state->enabled_state == state)
+	/* Check root port link too in case it hasn't children */
+	state = pcie_aspm_check_state(root, state);
+	if (link->aspm_enabled == state)
 		return;
 		return;
-
 	/*
 	/*
-	 * we must change the hierarchy. See comments in
+	 * We must change the hierarchy. See comments in
 	 * __pcie_aspm_config_link for the order
 	 * __pcie_aspm_config_link for the order
 	 **/
 	 **/
 	if (state & PCIE_LINK_STATE_L1) {
 	if (state & PCIE_LINK_STATE_L1) {
-		list_for_each_entry(leaf, &link_list, sibiling) {
-			if (get_root_port_link(leaf) == root_port_link)
-				__pcie_aspm_config_link(leaf->pdev, state);
+		list_for_each_entry(leaf, &link_list, sibling) {
+			if (leaf->root == root)
+				__pcie_aspm_config_link(leaf, state);
 		}
 		}
 	} else {
 	} else {
-		list_for_each_entry_reverse(leaf, &link_list, sibiling) {
-			if (get_root_port_link(leaf) == root_port_link)
-				__pcie_aspm_config_link(leaf->pdev, state);
+		list_for_each_entry_reverse(leaf, &link_list, sibling) {
+			if (leaf->root == root)
+				__pcie_aspm_config_link(leaf, state);
 		}
 		}
 	}
 	}
 }
 }
@@ -574,45 +526,42 @@ static void __pcie_aspm_configure_link_state(struct pci_dev *pdev,
  * pcie_aspm_configure_link_state: enable/disable PCI express link state
  * pcie_aspm_configure_link_state: enable/disable PCI express link state
  * @pdev: the root port or switch downstream port
  * @pdev: the root port or switch downstream port
  */
  */
-static void pcie_aspm_configure_link_state(struct pci_dev *pdev,
-	unsigned int state)
+static void pcie_aspm_configure_link_state(struct pcie_link_state *link,
+					   u32 state)
 {
 {
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	mutex_lock(&aspm_lock);
-	__pcie_aspm_configure_link_state(pdev, state);
+	__pcie_aspm_configure_link_state(link, state);
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
 }
 }
 
 
-static void free_link_state(struct pci_dev *pdev)
+static void free_link_state(struct pcie_link_state *link)
 {
 {
-	kfree(pdev->link_state);
-	pdev->link_state = NULL;
+	link->pdev->link_state = NULL;
+	kfree(link);
 }
 }
 
 
 static int pcie_aspm_sanity_check(struct pci_dev *pdev)
 static int pcie_aspm_sanity_check(struct pci_dev *pdev)
 {
 {
-	struct pci_dev *child_dev;
-	int child_pos;
+	struct pci_dev *child;
+	int pos;
 	u32 reg32;
 	u32 reg32;
-
 	/*
 	/*
-	 * Some functions in a slot might not all be PCIE functions, very
-	 * strange. Disable ASPM for the whole slot
+	 * Some functions in a slot might not all be PCIE functions,
+	 * very strange. Disable ASPM for the whole slot
 	 */
 	 */
-	list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
-		child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
-		if (!child_pos)
+	list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
+		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
+		if (!pos)
 			return -EINVAL;
 			return -EINVAL;
-
 		/*
 		/*
 		 * Disable ASPM for pre-1.1 PCIe device, we follow MS to use
 		 * Disable ASPM for pre-1.1 PCIe device, we follow MS to use
 		 * RBER bit to determine if a function is 1.1 version device
 		 * RBER bit to determine if a function is 1.1 version device
 		 */
 		 */
-		pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
-			&reg32);
+		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
 		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
 		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
-			dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM"
+			dev_printk(KERN_INFO, &child->dev, "disabling ASPM"
 				" on pre-1.1 PCIe device.  You can enable it"
 				" on pre-1.1 PCIe device.  You can enable it"
 				" with 'pcie_aspm=force'\n");
 				" with 'pcie_aspm=force'\n");
 			return -EINVAL;
 			return -EINVAL;
@@ -621,6 +570,47 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
+static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev)
+{
+	struct pcie_link_state *link;
+	int blacklist = !!pcie_aspm_sanity_check(pdev);
+
+	link = kzalloc(sizeof(*link), GFP_KERNEL);
+	if (!link)
+		return NULL;
+	INIT_LIST_HEAD(&link->sibling);
+	INIT_LIST_HEAD(&link->children);
+	INIT_LIST_HEAD(&link->link);
+	link->pdev = pdev;
+	if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
+		struct pcie_link_state *parent;
+		parent = pdev->bus->parent->self->link_state;
+		if (!parent) {
+			kfree(link);
+			return NULL;
+		}
+		link->parent = parent;
+		list_add(&link->link, &parent->children);
+	}
+	/* Setup a pointer to the root port link */
+	if (!link->parent)
+		link->root = link;
+	else
+		link->root = link->parent->root;
+
+	list_add(&link->sibling, &link_list);
+
+	pdev->link_state = link;
+
+	/* Check ASPM capability */
+	pcie_aspm_cap_init(link, blacklist);
+
+	/* Check Clock PM capability */
+	pcie_clkpm_cap_init(link, blacklist);
+
+	return link;
+}
+
 /*
 /*
  * pcie_aspm_init_link_state: Initiate PCI express link state.
  * pcie_aspm_init_link_state: Initiate PCI express link state.
  * It is called after the pcie and its children devices are scaned.
  * It is called after the pcie and its children devices are scaned.
@@ -628,75 +618,47 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
  */
  */
 void pcie_aspm_init_link_state(struct pci_dev *pdev)
 void pcie_aspm_init_link_state(struct pci_dev *pdev)
 {
 {
-	unsigned int state;
-	struct pcie_link_state *link_state;
-	int error = 0;
-	int blacklist;
+	u32 state;
+	struct pcie_link_state *link;
 
 
 	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
 	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
 		return;
 		return;
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+	    pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+		return;
+
+	/* VIA has a strange chipset, root port is under a bridge */
+	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
+	    pdev->bus->self)
 		return;
 		return;
+
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
 	if (list_empty(&pdev->subordinate->devices))
 	if (list_empty(&pdev->subordinate->devices))
 		goto out;
 		goto out;
 
 
-	blacklist = !!pcie_aspm_sanity_check(pdev);
-
 	mutex_lock(&aspm_lock);
 	mutex_lock(&aspm_lock);
-
-	link_state = kzalloc(sizeof(*link_state), GFP_KERNEL);
-	if (!link_state)
-		goto unlock_out;
-
-	link_state->downstream_has_switch = pcie_aspm_downstream_has_switch(pdev);
-	INIT_LIST_HEAD(&link_state->children);
-	INIT_LIST_HEAD(&link_state->link);
-	if (pdev->bus->self) {/* this is a switch */
-		struct pcie_link_state *parent_link_state;
-
-		parent_link_state = pdev->bus->parent->self->link_state;
-		if (!parent_link_state) {
-			kfree(link_state);
-			goto unlock_out;
-		}
-		list_add(&link_state->link, &parent_link_state->children);
-		link_state->parent = parent_link_state;
-	}
-
-	pdev->link_state = link_state;
-
-	if (!blacklist) {
-		pcie_aspm_configure_common_clock(pdev);
-		pcie_aspm_cap_init(pdev);
+	link = pcie_aspm_setup_link_state(pdev);
+	if (!link)
+		goto unlock;
+	/*
+	 * Setup initial ASPM state
+	 *
+	 * If link has switch, delay the link config. The leaf link
+	 * initialization will config the whole hierarchy. But we must
+	 * make sure BIOS doesn't set unsupported link state.
+	 */
+	if (pcie_aspm_downstream_has_switch(link)) {
+		state = pcie_aspm_check_state(link, link->aspm_default);
+		__pcie_aspm_config_link(link, state);
 	} else {
 	} else {
-		link_state->enabled_state = PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1;
-		link_state->bios_aspm_state = 0;
-		/* Set support state to 0, so we will disable ASPM later */
-		link_state->support_state = 0;
+		state = policy_to_aspm_state(link);
+		__pcie_aspm_configure_link_state(link, state);
 	}
 	}
 
 
-	link_state->pdev = pdev;
-	list_add(&link_state->sibiling, &link_list);
-
-	if (link_state->downstream_has_switch) {
-		/*
-		 * If link has switch, delay the link config. The leaf link
-		 * initialization will config the whole hierarchy. but we must
-		 * make sure BIOS doesn't set unsupported link state
-		 **/
-		state = pcie_aspm_check_state(pdev, link_state->bios_aspm_state);
-		__pcie_aspm_config_link(pdev, state);
-	} else
-		__pcie_aspm_configure_link_state(pdev,
-			policy_to_aspm_state(pdev));
-
-	pcie_check_clock_pm(pdev, blacklist);
-
-unlock_out:
-	if (error)
-		free_link_state(pdev);
+	/* Setup initial Clock PM state */
+	state = (link->clkpm_capable) ? policy_to_clkpm_state(link) : 0;
+	pcie_set_clkpm(link, state);
+unlock:
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 out:
 out:
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
@@ -725,11 +687,11 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 
 
 	/* All functions are removed, so just disable ASPM for the link */
 	/* All functions are removed, so just disable ASPM for the link */
 	__pcie_aspm_config_one_dev(parent, 0);
 	__pcie_aspm_config_one_dev(parent, 0);
-	list_del(&link_state->sibiling);
+	list_del(&link_state->sibling);
 	list_del(&link_state->link);
 	list_del(&link_state->link);
 	/* Clock PM is for endpoint device */
 	/* Clock PM is for endpoint device */
 
 
-	free_link_state(parent);
+	free_link_state(link_state);
 out:
 out:
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
@@ -749,7 +711,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
 	 * devices changed PM state, we should recheck if latency meets all
 	 * devices changed PM state, we should recheck if latency meets all
 	 * functions' requirement
 	 * functions' requirement
 	 */
 	 */
-	pcie_aspm_configure_link_state(pdev, link_state->enabled_state);
+	pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
 }
 }
 
 
 /*
 /*
@@ -772,14 +734,12 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	mutex_lock(&aspm_lock);
 	link_state = parent->link_state;
 	link_state = parent->link_state;
-	link_state->support_state &=
-		~(state & (PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1));
-	if (state & PCIE_LINK_STATE_CLKPM)
-		link_state->clk_pm_capable = 0;
-
-	__pcie_aspm_configure_link_state(parent, link_state->enabled_state);
-	if (!link_state->clk_pm_capable && link_state->clk_pm_enabled)
-		pcie_set_clock_pm(parent, 0);
+	link_state->aspm_support &= ~state;
+	__pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
+	if (state & PCIE_LINK_STATE_CLKPM) {
+		link_state->clkpm_capable = 0;
+		pcie_set_clkpm(link_state, 0);
+	}
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
 }
 }
@@ -788,7 +748,6 @@ EXPORT_SYMBOL(pci_disable_link_state);
 static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
 static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
 {
 {
 	int i;
 	int i;
-	struct pci_dev *pdev;
 	struct pcie_link_state *link_state;
 	struct pcie_link_state *link_state;
 
 
 	for (i = 0; i < ARRAY_SIZE(policy_str); i++)
 	for (i = 0; i < ARRAY_SIZE(policy_str); i++)
@@ -802,14 +761,10 @@ static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	mutex_lock(&aspm_lock);
 	aspm_policy = i;
 	aspm_policy = i;
-	list_for_each_entry(link_state, &link_list, sibiling) {
-		pdev = link_state->pdev;
-		__pcie_aspm_configure_link_state(pdev,
-			policy_to_aspm_state(pdev));
-		if (link_state->clk_pm_capable &&
-		    link_state->clk_pm_enabled != policy_to_clkpm_state(pdev))
-			pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev));
-
+	list_for_each_entry(link_state, &link_list, sibling) {
+		__pcie_aspm_configure_link_state(link_state,
+			policy_to_aspm_state(link_state));
+		pcie_set_clkpm(link_state, policy_to_clkpm_state(link_state));
 	}
 	}
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
@@ -838,7 +793,7 @@ static ssize_t link_state_show(struct device *dev,
 	struct pci_dev *pci_device = to_pci_dev(dev);
 	struct pci_dev *pci_device = to_pci_dev(dev);
 	struct pcie_link_state *link_state = pci_device->link_state;
 	struct pcie_link_state *link_state = pci_device->link_state;
 
 
-	return sprintf(buf, "%d\n", link_state->enabled_state);
+	return sprintf(buf, "%d\n", link_state->aspm_enabled);
 }
 }
 
 
 static ssize_t link_state_store(struct device *dev,
 static ssize_t link_state_store(struct device *dev,
@@ -846,7 +801,7 @@ static ssize_t link_state_store(struct device *dev,
 		const char *buf,
 		const char *buf,
 		size_t n)
 		size_t n)
 {
 {
-	struct pci_dev *pci_device = to_pci_dev(dev);
+	struct pci_dev *pdev = to_pci_dev(dev);
 	int state;
 	int state;
 
 
 	if (n < 1)
 	if (n < 1)
@@ -854,7 +809,7 @@ static ssize_t link_state_store(struct device *dev,
 	state = buf[0]-'0';
 	state = buf[0]-'0';
 	if (state >= 0 && state <= 3) {
 	if (state >= 0 && state <= 3) {
 		/* setup link aspm state */
 		/* setup link aspm state */
-		pcie_aspm_configure_link_state(pci_device, state);
+		pcie_aspm_configure_link_state(pdev->link_state, state);
 		return n;
 		return n;
 	}
 	}
 
 
@@ -868,7 +823,7 @@ static ssize_t clk_ctl_show(struct device *dev,
 	struct pci_dev *pci_device = to_pci_dev(dev);
 	struct pci_dev *pci_device = to_pci_dev(dev);
 	struct pcie_link_state *link_state = pci_device->link_state;
 	struct pcie_link_state *link_state = pci_device->link_state;
 
 
-	return sprintf(buf, "%d\n", link_state->clk_pm_enabled);
+	return sprintf(buf, "%d\n", link_state->clkpm_enabled);
 }
 }
 
 
 static ssize_t clk_ctl_store(struct device *dev,
 static ssize_t clk_ctl_store(struct device *dev,
@@ -876,7 +831,7 @@ static ssize_t clk_ctl_store(struct device *dev,
 		const char *buf,
 		const char *buf,
 		size_t n)
 		size_t n)
 {
 {
-	struct pci_dev *pci_device = to_pci_dev(dev);
+	struct pci_dev *pdev = to_pci_dev(dev);
 	int state;
 	int state;
 
 
 	if (n < 1)
 	if (n < 1)
@@ -885,7 +840,7 @@ static ssize_t clk_ctl_store(struct device *dev,
 
 
 	down_read(&pci_bus_sem);
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	mutex_lock(&aspm_lock);
-	pcie_set_clock_pm(pci_device, !!state);
+	pcie_set_clkpm_nocheck(pdev->link_state, !!state);
 	mutex_unlock(&aspm_lock);
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
 	up_read(&pci_bus_sem);
 
 
@@ -904,10 +859,10 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 		return;
 
 
-	if (link_state->support_state)
+	if (link_state->aspm_support)
 		sysfs_add_file_to_group(&pdev->dev.kobj,
 		sysfs_add_file_to_group(&pdev->dev.kobj,
 			&dev_attr_link_state.attr, power_group);
 			&dev_attr_link_state.attr, power_group);
-	if (link_state->clk_pm_capable)
+	if (link_state->clkpm_capable)
 		sysfs_add_file_to_group(&pdev->dev.kobj,
 		sysfs_add_file_to_group(&pdev->dev.kobj,
 			&dev_attr_clk_ctl.attr, power_group);
 			&dev_attr_clk_ctl.attr, power_group);
 }
 }
@@ -920,10 +875,10 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state)
 		return;
 		return;
 
 
-	if (link_state->support_state)
+	if (link_state->aspm_support)
 		sysfs_remove_file_from_group(&pdev->dev.kobj,
 		sysfs_remove_file_from_group(&pdev->dev.kobj,
 			&dev_attr_link_state.attr, power_group);
 			&dev_attr_link_state.attr, power_group);
-	if (link_state->clk_pm_capable)
+	if (link_state->clkpm_capable)
 		sysfs_remove_file_from_group(&pdev->dev.kobj,
 		sysfs_remove_file_from_group(&pdev->dev.kobj,
 			&dev_attr_clk_ctl.attr, power_group);
 			&dev_attr_clk_ctl.attr, power_group);
 }
 }

+ 8 - 3
drivers/pci/probe.c

@@ -193,7 +193,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
 		res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
 		if (type == pci_bar_io) {
 		if (type == pci_bar_io) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
 			l &= PCI_BASE_ADDRESS_IO_MASK;
-			mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
+			mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT;
 		} else {
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
@@ -237,6 +237,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			dev_printk(KERN_DEBUG, &dev->dev,
 			dev_printk(KERN_DEBUG, &dev->dev,
 				"reg %x 64bit mmio: %pR\n", pos, res);
 				"reg %x 64bit mmio: %pR\n", pos, res);
 		}
 		}
+
+		res->flags |= IORESOURCE_MEM_64;
 	} else {
 	} else {
 		sz = pci_size(l, sz, mask);
 		sz = pci_size(l, sz, mask);
 
 
@@ -287,7 +289,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
 	struct resource *res;
 	struct resource *res;
 	int i;
 	int i;
 
 
-	if (!child->parent)	/* It's a host bus, nothing to read */
+	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
 		return;
 		return;
 
 
 	if (dev->transparent) {
 	if (dev->transparent) {
@@ -362,7 +364,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
 		}
 		}
 	}
 	}
 	if (base <= limit) {
 	if (base <= limit) {
-		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) |
+					 IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		if (res->flags & PCI_PREF_RANGE_TYPE_64)
+			res->flags |= IORESOURCE_MEM_64;
 		res->start = base;
 		res->start = base;
 		res->end = limit + 0xfffff;
 		res->end = limit + 0xfffff;
 		dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
 		dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",

+ 24 - 0
drivers/pci/quirks.c

@@ -1133,6 +1133,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 			switch (dev->subsystem_device) {
 			switch (dev->subsystem_device) {
 			case 0x1751: /* M2N notebook */
 			case 0x1751: /* M2N notebook */
 			case 0x1821: /* M5N notebook */
 			case 0x1821: /* M5N notebook */
+			case 0x1897: /* A6L notebook */
 				asus_hides_smbus = 1;
 				asus_hides_smbus = 1;
 			}
 			}
 		else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
 		else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
@@ -1163,6 +1164,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 			switch (dev->subsystem_device) {
 			switch (dev->subsystem_device) {
 			case 0x12bc: /* HP D330L */
 			case 0x12bc: /* HP D330L */
 			case 0x12bd: /* HP D530 */
 			case 0x12bd: /* HP D530 */
+			case 0x006a: /* HP Compaq nx9500 */
 				asus_hides_smbus = 1;
 				asus_hides_smbus = 1;
 			}
 			}
 		else if (dev->device == PCI_DEVICE_ID_INTEL_82875_HB)
 		else if (dev->device == PCI_DEVICE_ID_INTEL_82875_HB)
@@ -2016,6 +2018,28 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
 			PCI_DEVICE_ID_NX2_5709S,
 			PCI_DEVICE_ID_NX2_5709S,
 			quirk_brcm_570x_limit_vpd);
 			quirk_brcm_570x_limit_vpd);
 
 
+/* Originally in EDAC sources for i82875P:
+ * Intel tells BIOS developers to hide device 6 which
+ * configures the overflow device access containing
+ * the DRBs - this is where we expose device 6.
+ * http://www.x86-secret.com/articles/tweak/pat/patsecrets-2.htm
+ */
+static void __devinit quirk_unhide_mch_dev6(struct pci_dev *dev)
+{
+	u8 reg;
+
+	if (pci_read_config_byte(dev, 0xF4, &reg) == 0 && !(reg & 0x02)) {
+		dev_info(&dev->dev, "Enabling MCH 'Overflow' Device\n");
+		pci_write_config_byte(dev, 0xF4, reg | 0x02);
+	}
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
+			quirk_unhide_mch_dev6);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
+			quirk_unhide_mch_dev6);
+
+
 #ifdef CONFIG_PCI_MSI
 #ifdef CONFIG_PCI_MSI
 /* Some chipsets do not support MSI. We cannot easily rely on setting
 /* Some chipsets do not support MSI. We cannot easily rely on setting
  * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
  * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually

+ 0 - 2
drivers/pci/remove.c

@@ -32,8 +32,6 @@ static void pci_stop_dev(struct pci_dev *dev)
 
 
 static void pci_destroy_dev(struct pci_dev *dev)
 static void pci_destroy_dev(struct pci_dev *dev)
 {
 {
-	pci_stop_dev(dev);
-
 	/* Remove the device from the device lists, and prevent any further
 	/* Remove the device from the device lists, and prevent any further
 	 * list accesses from this device */
 	 * list accesses from this device */
 	down_write(&pci_bus_sem);
 	down_write(&pci_bus_sem);

+ 1 - 31
drivers/pci/search.c

@@ -29,7 +29,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
 	if (pdev->is_pcie)
 	if (pdev->is_pcie)
 		return NULL;
 		return NULL;
 	while (1) {
 	while (1) {
-		if (!pdev->bus->parent)
+		if (pci_is_root_bus(pdev->bus))
 			break;
 			break;
 		pdev = pdev->bus->self;
 		pdev = pdev->bus->self;
 		/* a p2p bridge */
 		/* a p2p bridge */
@@ -114,36 +114,6 @@ pci_find_next_bus(const struct pci_bus *from)
 }
 }
 
 
 #ifdef CONFIG_PCI_LEGACY
 #ifdef CONFIG_PCI_LEGACY
-/**
- * pci_find_slot - locate PCI device from a given PCI slot
- * @bus: number of PCI bus on which desired PCI device resides
- * @devfn: encodes number of PCI slot in which the desired PCI
- * device resides and the logical device number within that slot
- * in case of multi-function devices.
- *
- * Given a PCI bus and slot/function number, the desired PCI device
- * is located in system global list of PCI devices.  If the device
- * is found, a pointer to its data structure is returned.  If no
- * device is found, %NULL is returned.
- *
- * NOTE: Do not use this function any more; use pci_get_slot() instead, as
- * the PCI device returned by this function can disappear at any moment in
- * time.
- */
-struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
-{
-	struct pci_dev *dev = NULL;
-
-	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (dev->bus->number == bus && dev->devfn == devfn) {
-			pci_dev_put(dev);
-			return dev;
-		}
-	}
-	return NULL;
-}
-EXPORT_SYMBOL(pci_find_slot);
-
 /**
 /**
  * pci_find_device - begin or continue searching for a PCI device by vendor/device id
  * pci_find_device - begin or continue searching for a PCI device by vendor/device id
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids

+ 42 - 11
drivers/pci/setup-bus.c

@@ -58,7 +58,6 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
 		res = list->res;
 		res = list->res;
 		idx = res - &list->dev->resource[0];
 		idx = res - &list->dev->resource[0];
 		if (pci_assign_resource(list->dev, idx)) {
 		if (pci_assign_resource(list->dev, idx)) {
-			/* FIXME: get rid of this */
 			res->start = 0;
 			res->start = 0;
 			res->end = 0;
 			res->end = 0;
 			res->flags = 0;
 			res->flags = 0;
@@ -143,6 +142,7 @@ static void pci_setup_bridge(struct pci_bus *bus)
 	struct pci_dev *bridge = bus->self;
 	struct pci_dev *bridge = bus->self;
 	struct pci_bus_region region;
 	struct pci_bus_region region;
 	u32 l, bu, lu, io_upper16;
 	u32 l, bu, lu, io_upper16;
+	int pref_mem64;
 
 
 	if (pci_is_enabled(bridge))
 	if (pci_is_enabled(bridge))
 		return;
 		return;
@@ -198,16 +198,22 @@ static void pci_setup_bridge(struct pci_bus *bus)
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 
 	/* Set up PREF base/limit. */
 	/* Set up PREF base/limit. */
+	pref_mem64 = 0;
 	bu = lu = 0;
 	bu = lu = 0;
 	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
 	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
 	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
 	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+		int width = 8;
 		l = (region.start >> 16) & 0xfff0;
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
 		l |= region.end & 0xfff00000;
-		bu = upper_32_bits(region.start);
-		lu = upper_32_bits(region.end);
-		dev_info(&bridge->dev, "  PREFETCH window: %#016llx-%#016llx\n",
-		    (unsigned long long)region.start,
-		    (unsigned long long)region.end);
+		if (bus->resource[2]->flags & IORESOURCE_MEM_64) {
+			pref_mem64 = 1;
+			bu = upper_32_bits(region.start);
+			lu = upper_32_bits(region.end);
+			width = 16;
+		}
+		dev_info(&bridge->dev, "  PREFETCH window: %#0*llx-%#0*llx\n",
+				width, (unsigned long long)region.start,
+				width, (unsigned long long)region.end);
 	}
 	}
 	else {
 	else {
 		l = 0x0000fff0;
 		l = 0x0000fff0;
@@ -215,9 +221,11 @@ static void pci_setup_bridge(struct pci_bus *bus)
 	}
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 
 
-	/* Set the upper 32 bits of PREF base & limit. */
-	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
-	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+	if (pref_mem64) {
+		/* Set the upper 32 bits of PREF base & limit. */
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu);
+		pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu);
+	}
 
 
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl);
 }
 }
@@ -255,8 +263,25 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
 		pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
 		pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
 		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
 		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
 	}
 	}
-	if (pmem)
+	if (pmem) {
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64)
+			b_res[2].flags |= IORESOURCE_MEM_64;
+	}
+
+	/* double check if bridge does support 64 bit pref */
+	if (b_res[2].flags & IORESOURCE_MEM_64) {
+		u32 mem_base_hi, tmp;
+		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+					 &mem_base_hi);
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+					       0xffffffff);
+		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
+		if (!tmp)
+			b_res[2].flags &= ~IORESOURCE_MEM_64;
+		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+				       mem_base_hi);
+	}
 }
 }
 
 
 /* Helper function for sizing routines: find first available
 /* Helper function for sizing routines: find first available
@@ -336,6 +361,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 	resource_size_t aligns[12];	/* Alignments from 1Mb to 2Gb */
 	resource_size_t aligns[12];	/* Alignments from 1Mb to 2Gb */
 	int order, max_order;
 	int order, max_order;
 	struct resource *b_res = find_free_bus_resource(bus, type);
 	struct resource *b_res = find_free_bus_resource(bus, type);
+	unsigned int mem64_mask = 0;
 
 
 	if (!b_res)
 	if (!b_res)
 		return 0;
 		return 0;
@@ -344,9 +370,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 	max_order = 0;
 	max_order = 0;
 	size = 0;
 	size = 0;
 
 
+	mem64_mask = b_res->flags & IORESOURCE_MEM_64;
+	b_res->flags &= ~IORESOURCE_MEM_64;
+
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
 		int i;
-		
+
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *r = &dev->resource[i];
 			struct resource *r = &dev->resource[i];
 			resource_size_t r_size;
 			resource_size_t r_size;
@@ -372,6 +401,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 				aligns[order] += align;
 				aligns[order] += align;
 			if (order > max_order)
 			if (order > max_order)
 				max_order = order;
 				max_order = order;
+			mem64_mask &= r->flags & IORESOURCE_MEM_64;
 		}
 		}
 	}
 	}
 
 
@@ -396,6 +426,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 	b_res->start = min_align;
 	b_res->start = min_align;
 	b_res->end = size + min_align - 1;
 	b_res->end = size + min_align - 1;
 	b_res->flags |= IORESOURCE_STARTALIGN;
 	b_res->flags |= IORESOURCE_STARTALIGN;
+	b_res->flags |= mem64_mask;
 	return 1;
 	return 1;
 }
 }
 
 

+ 36 - 13
drivers/pci/setup-res.c

@@ -135,23 +135,16 @@ void pci_disable_bridge_window(struct pci_dev *dev)
 }
 }
 #endif	/* CONFIG_PCI_QUIRKS */
 #endif	/* CONFIG_PCI_QUIRKS */
 
 
-int pci_assign_resource(struct pci_dev *dev, int resno)
+static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
+				 int resno)
 {
 {
-	struct pci_bus *bus = dev->bus;
 	struct resource *res = dev->resource + resno;
 	struct resource *res = dev->resource + resno;
 	resource_size_t size, min, align;
 	resource_size_t size, min, align;
 	int ret;
 	int ret;
 
 
 	size = resource_size(res);
 	size = resource_size(res);
 	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-
 	align = resource_alignment(res);
 	align = resource_alignment(res);
-	if (!align) {
-		dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
-			"alignment) %pR flags %#lx\n",
-			resno, res, res->flags);
-		return -EINVAL;
-	}
 
 
 	/* First, try exact prefetching match.. */
 	/* First, try exact prefetching match.. */
 	ret = pci_bus_alloc_resource(bus, res, size, align, min,
 	ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -169,10 +162,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 					     pcibios_align_resource, dev);
 					     pcibios_align_resource, dev);
 	}
 	}
 
 
-	if (ret) {
-		dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
-			resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
-	} else {
+	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
 		res->flags &= ~IORESOURCE_STARTALIGN;
 		if (resno < PCI_BRIDGE_RESOURCES)
 		if (resno < PCI_BRIDGE_RESOURCES)
 			pci_update_resource(dev, resno);
 			pci_update_resource(dev, resno);
@@ -181,6 +171,39 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	return ret;
 	return ret;
 }
 }
 
 
+int pci_assign_resource(struct pci_dev *dev, int resno)
+{
+	struct resource *res = dev->resource + resno;
+	resource_size_t align;
+	struct pci_bus *bus;
+	int ret;
+
+	align = resource_alignment(res);
+	if (!align) {
+		dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
+			"alignment) %pR flags %#lx\n",
+			resno, res, res->flags);
+		return -EINVAL;
+	}
+
+	bus = dev->bus;
+	while ((ret = __pci_assign_resource(bus, dev, resno))) {
+		if (bus->parent && bus->self->transparent)
+			bus = bus->parent;
+		else
+			bus = NULL;
+		if (bus)
+			continue;
+		break;
+	}
+
+	if (ret)
+		dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
+			resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
+
+	return ret;
+}
+
 #if 0
 #if 0
 int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
 int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
 {
 {

+ 39 - 0
drivers/pci/slot.c

@@ -307,6 +307,45 @@ void pci_destroy_slot(struct pci_slot *slot)
 }
 }
 EXPORT_SYMBOL_GPL(pci_destroy_slot);
 EXPORT_SYMBOL_GPL(pci_destroy_slot);
 
 
+#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
+#include <linux/pci_hotplug.h>
+/**
+ * pci_hp_create_link - create symbolic link to the hotplug driver module.
+ * @slot: struct pci_slot
+ *
+ * Helper function for pci_hotplug_core.c to create symbolic link to
+ * the hotplug driver module.
+ */
+void pci_hp_create_module_link(struct pci_slot *pci_slot)
+{
+	struct hotplug_slot *slot = pci_slot->hotplug;
+	struct kobject *kobj = NULL;
+	int no_warn;
+
+	if (!slot || !slot->ops)
+		return;
+	kobj = kset_find_obj(module_kset, slot->ops->mod_name);
+	if (!kobj)
+		return;
+	no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module");
+	kobject_put(kobj);
+}
+EXPORT_SYMBOL_GPL(pci_hp_create_module_link);
+
+/**
+ * pci_hp_remove_link - remove symbolic link to the hotplug driver module.
+ * @slot: struct pci_slot
+ *
+ * Helper function for pci_hotplug_core.c to remove symbolic link to
+ * the hotplug driver module.
+ */
+void pci_hp_remove_module_link(struct pci_slot *pci_slot)
+{
+	sysfs_remove_link(&pci_slot->kobj, "module");
+}
+EXPORT_SYMBOL_GPL(pci_hp_remove_module_link);
+#endif
+
 static int pci_slot_init(void)
 static int pci_slot_init(void)
 {
 {
 	struct kset *pci_bus_kset;
 	struct kset *pci_bus_kset;

+ 2 - 0
include/linux/ioport.h

@@ -49,6 +49,8 @@ struct resource_list {
 #define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
 #define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
 #define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
 #define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
 
 
+#define IORESOURCE_MEM_64	0x00100000
+
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
 #define IORESOURCE_DISABLED	0x10000000
 #define IORESOURCE_UNSET	0x20000000
 #define IORESOURCE_UNSET	0x20000000

+ 2 - 2
include/linux/pci-acpi.h

@@ -15,7 +15,7 @@ static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
 {
 {
 	struct pci_bus *pbus = pdev->bus;
 	struct pci_bus *pbus = pdev->bus;
 	/* Find a PCI root bus */
 	/* Find a PCI root bus */
-	while (pbus->parent)
+	while (!pci_is_root_bus(pbus))
 		pbus = pbus->parent;
 		pbus = pbus->parent;
 	return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
 	return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
 					      pbus->number);
 					      pbus->number);
@@ -23,7 +23,7 @@ static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
 
 
 static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
 static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
 {
 {
-	if (pbus->parent)
+	if (!pci_is_root_bus(pbus))
 		return DEVICE_ACPI_HANDLE(&(pbus->self->dev));
 		return DEVICE_ACPI_HANDLE(&(pbus->self->dev));
 	return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
 	return acpi_get_pci_rootbridge_handle(pci_domain_nr(pbus),
 					      pbus->number);
 					      pbus->number);

+ 24 - 11
include/linux/pci.h

@@ -607,8 +607,6 @@ extern void pci_sort_breadthfirst(void);
 struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
 struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
 					     unsigned int device,
 					     unsigned int device,
 					     struct pci_dev *from);
 					     struct pci_dev *from);
-struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
-					   unsigned int devfn);
 #endif /* CONFIG_PCI_LEGACY */
 #endif /* CONFIG_PCI_LEGACY */
 
 
 enum pci_lost_interrupt_reason {
 enum pci_lost_interrupt_reason {
@@ -647,6 +645,7 @@ int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn,
 			      int where, u16 val);
 			      int where, u16 val);
 int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
 int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
 			       int where, u32 val);
 			       int where, u32 val);
+struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops);
 
 
 static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
 static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
 {
 {
@@ -711,8 +710,8 @@ int pcix_get_mmrbc(struct pci_dev *dev);
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
 int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
 int pcie_get_readrq(struct pci_dev *dev);
 int pcie_get_readrq(struct pci_dev *dev);
 int pcie_set_readrq(struct pci_dev *dev, int rq);
 int pcie_set_readrq(struct pci_dev *dev, int rq);
+int __pci_reset_function(struct pci_dev *dev);
 int pci_reset_function(struct pci_dev *dev);
 int pci_reset_function(struct pci_dev *dev);
-int pci_execute_reset_function(struct pci_dev *dev);
 void pci_update_resource(struct pci_dev *dev, int resno);
 void pci_update_resource(struct pci_dev *dev, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
 int pci_select_bars(struct pci_dev *dev, unsigned long flags);
 int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@ -732,7 +731,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 void pci_pme_active(struct pci_dev *dev, bool enable);
 void pci_pme_active(struct pci_dev *dev, bool enable);
-int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable);
 int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 pci_power_t pci_target_state(struct pci_dev *dev);
 pci_power_t pci_target_state(struct pci_dev *dev);
 int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_prepare_to_sleep(struct pci_dev *dev);
@@ -798,7 +797,7 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
 		    int pass);
 		    int pass);
 
 
-void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
 		  void *userdata);
 		  void *userdata);
 int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
@@ -888,6 +887,17 @@ static inline int pcie_aspm_enabled(void)
 extern int pcie_aspm_enabled(void);
 extern int pcie_aspm_enabled(void);
 #endif
 #endif
 
 
+#ifndef CONFIG_PCIE_ECRC
+static inline void pcie_set_ecrc_checking(struct pci_dev *dev)
+{
+	return;
+}
+static inline void pcie_ecrc_get_policy(char *str) {};
+#else
+extern void pcie_set_ecrc_checking(struct pci_dev *dev);
+extern void pcie_ecrc_get_policy(char *str);
+#endif
+
 #define pci_enable_msi(pdev)	pci_enable_msi_block(pdev, 1)
 #define pci_enable_msi(pdev)	pci_enable_msi_block(pdev, 1)
 
 
 #ifdef CONFIG_HT_IRQ
 #ifdef CONFIG_HT_IRQ
@@ -944,12 +954,6 @@ static inline struct pci_dev *pci_find_device(unsigned int vendor,
 	return NULL;
 	return NULL;
 }
 }
 
 
-static inline struct pci_dev *pci_find_slot(unsigned int bus,
-					    unsigned int devfn)
-{
-	return NULL;
-}
-
 static inline struct pci_dev *pci_get_device(unsigned int vendor,
 static inline struct pci_dev *pci_get_device(unsigned int vendor,
 					     unsigned int device,
 					     unsigned int device,
 					     struct pci_dev *from)
 					     struct pci_dev *from)
@@ -1105,6 +1109,10 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
 
 
 #include <asm/pci.h>
 #include <asm/pci.h>
 
 
+#ifndef PCIBIOS_MAX_MEM_32
+#define PCIBIOS_MAX_MEM_32 (-1)
+#endif
+
 /* these helpers provide future and backwards compatibility
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)
 #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)
@@ -1261,5 +1269,10 @@ static inline irqreturn_t pci_sriov_migration(struct pci_dev *dev)
 }
 }
 #endif
 #endif
 
 
+#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
+extern void pci_hp_create_module_link(struct pci_slot *pci_slot);
+extern void pci_hp_remove_module_link(struct pci_slot *pci_slot);
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */
 #endif /* LINUX_PCI_H */
 #endif /* LINUX_PCI_H */

+ 13 - 10
include/linux/pci_hotplug.h

@@ -66,17 +66,10 @@ enum pcie_link_speed {
 	PCIE_LNK_SPEED_UNKNOWN	= 0xFF,
 	PCIE_LNK_SPEED_UNKNOWN	= 0xFF,
 };
 };
 
 
-struct hotplug_slot;
-struct hotplug_slot_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct hotplug_slot *, char *);
-	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
-};
-#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr);
-
 /**
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
  * @owner: The module owner of this structure
+ * @mod_name: The module name (KBUILD_MODNAME) of this structure
  * @enable_slot: Called when the user wants to enable a specific pci slot
  * @enable_slot: Called when the user wants to enable a specific pci slot
  * @disable_slot: Called when the user wants to disable a specific pci slot
  * @disable_slot: Called when the user wants to disable a specific pci slot
  * @set_attention_status: Called to set the specific slot's attention LED to
  * @set_attention_status: Called to set the specific slot's attention LED to
@@ -109,6 +102,7 @@ struct hotplug_slot_attribute {
  */
  */
 struct hotplug_slot_ops {
 struct hotplug_slot_ops {
 	struct module *owner;
 	struct module *owner;
+	const char *mod_name;
 	int (*enable_slot)		(struct hotplug_slot *slot);
 	int (*enable_slot)		(struct hotplug_slot *slot);
 	int (*disable_slot)		(struct hotplug_slot *slot);
 	int (*disable_slot)		(struct hotplug_slot *slot);
 	int (*set_attention_status)	(struct hotplug_slot *slot, u8 value);
 	int (*set_attention_status)	(struct hotplug_slot *slot, u8 value);
@@ -167,12 +161,21 @@ static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)
 	return pci_slot_name(slot->pci_slot);
 	return pci_slot_name(slot->pci_slot);
 }
 }
 
 
-extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr,
-			   const char *name);
+extern int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus,
+			     int nr, const char *name,
+			     struct module *owner, const char *mod_name);
 extern int pci_hp_deregister(struct hotplug_slot *slot);
 extern int pci_hp_deregister(struct hotplug_slot *slot);
 extern int __must_check pci_hp_change_slot_info	(struct hotplug_slot *slot,
 extern int __must_check pci_hp_change_slot_info	(struct hotplug_slot *slot,
 						 struct hotplug_slot_info *info);
 						 struct hotplug_slot_info *info);
 
 
+static inline int pci_hp_register(struct hotplug_slot *slot,
+				  struct pci_bus *pbus,
+				  int devnr, const char *name)
+{
+	return __pci_hp_register(slot, pbus, devnr, name,
+				 THIS_MODULE, KBUILD_MODNAME);
+}
+
 /* PCI Setting Record (Type 0) */
 /* PCI Setting Record (Type 0) */
 struct hpp_type0 {
 struct hpp_type0 {
 	u32 revision;
 	u32 revision;

+ 2 - 2
include/linux/pci_regs.h

@@ -295,8 +295,9 @@
 #define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
 #define PCI_MSI_ADDRESS_LO	4	/* Lower 32 bits */
 #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
 #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
+#define PCI_MSI_MASK_32		12	/* Mask bits register for 32-bit devices */
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
-#define PCI_MSI_MASK_BIT	16	/* Mask bits register */
+#define PCI_MSI_MASK_64		16	/* Mask bits register for 64-bit devices */
 
 
 /* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
 /* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
 #define PCI_MSIX_FLAGS		2
 #define PCI_MSIX_FLAGS		2
@@ -304,7 +305,6 @@
 #define  PCI_MSIX_FLAGS_ENABLE	(1 << 15)
 #define  PCI_MSIX_FLAGS_ENABLE	(1 << 15)
 #define  PCI_MSIX_FLAGS_MASKALL	(1 << 14)
 #define  PCI_MSIX_FLAGS_MASKALL	(1 << 14)
 #define PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
 #define PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
-#define PCI_MSIX_FLAGS_BITMASK	(1 << 0)
 
 
 /* CompactPCI Hotswap Register */
 /* CompactPCI Hotswap Register */