From b4b2c0411e25c8bd001c683be52a2a5996ea689a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 29 Dec 2005 20:07:25 +0100 Subject: [PATCH 01/23] [PATCH] PCI: schedule PCI_LEGACY_PROC for removal PCI_LEGACY_PROC is deprecated since 2.5.53 in favor of lspci(8). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- Documentation/feature-removal-schedule.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b4a1ea762698..b8143bda187f 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -148,3 +148,10 @@ Why: The 8250 serial driver now has the ability to deal with the differences brother on Alchemy SOCs. The loss of features is not considered an issue. Who: Ralf Baechle + +--------------------------- + +What: Legacy /proc/pci interface (PCI_LEGACY_PROC) +When: March 2006 +Why: deprecated since 2.5.53 in favor of lspci(8) +Who: Adrian Bunk From 051d9897731abfac62c4d1a2efcef83a89bd4482 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 3 Dec 2005 02:34:12 +0100 Subject: [PATCH 02/23] [PATCH] pci: Schedule removal of pci_module_init Scheduled the removal of pci_module_init. Signed-off-by: Richard Knutsson Signed-off-by: Greg Kroah-Hartman --- Documentation/feature-removal-schedule.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index b8143bda187f..4d4897c8ef96 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -155,3 +155,10 @@ What: Legacy /proc/pci interface (PCI_LEGACY_PROC) When: March 2006 Why: deprecated since 2.5.53 in favor of lspci(8) Who: Adrian Bunk + +--------------------------- + +What: pci_module_init(driver) +When: January 2007 +Why: Is replaced by pci_register_driver(pci_driver). +Who: Richard Knutsson and Greg Kroah-Hartman From b6ebb2659065b6e03605e7f0c69449bda382261a Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Mon, 9 Jan 2006 10:53:45 -0800 Subject: [PATCH 03/23] [PATCH] PCI: irq and pci_ids: patch for Intel ICH8 This patch adds the Intel ICH8 DID's to the irq.c and pci_ids.h files. Signed-off-by: Jason Gaston Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/irq.c | 5 +++++ include/linux/pci_ids.h | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e715aa930036..3ca59cad05f3 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -539,6 +539,11 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH7_30: case PCI_DEVICE_ID_INTEL_ICH7_31: case PCI_DEVICE_ID_INTEL_ESB2_0: + case PCI_DEVICE_ID_INTEL_ICH8_0: + case PCI_DEVICE_ID_INTEL_ICH8_1: + case PCI_DEVICE_ID_INTEL_ICH8_2: + case PCI_DEVICE_ID_INTEL_ICH8_3: + case PCI_DEVICE_ID_INTEL_ICH8_4: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4401a7e06057..9eb1983b8787 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2106,6 +2106,13 @@ #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de #define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df +#define PCI_DEVICE_ID_INTEL_ICH8_0 0x2810 +#define PCI_DEVICE_ID_INTEL_ICH8_1 0x2811 +#define PCI_DEVICE_ID_INTEL_ICH8_2 0x2812 +#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814 +#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 +#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e +#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 From f8d65713332cf6306889a3036142a17e01e3447e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 6 Jan 2006 03:25:37 +0100 Subject: [PATCH 04/23] [PATCH] PCI: drivers/pci/pci.c: #if 0 pci_find_ext_capability() This patch #if 0's the unused global function pci_find_ext_capability(). Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 2 ++ include/linux/pci.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d2a633efa10a..d2d187916643 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -163,6 +163,7 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap); } +#if 0 /** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query @@ -210,6 +211,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return 0; } +#endif /* 0 */ /** * pci_find_parent_resource - return resource region of parent bus of given region diff --git a/include/linux/pci.h b/include/linux/pci.h index 0a44072383ec..fe1a2b02fc55 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -406,7 +406,6 @@ struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int devic struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); -int pci_find_ext_capability (struct pci_dev *dev, int cap); struct pci_bus * pci_find_next_bus(const struct pci_bus *from); struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); @@ -626,7 +625,6 @@ static inline int pci_register_driver(struct pci_driver *drv) { return 0;} static inline void pci_unregister_driver(struct pci_driver *drv) { } static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } -static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } /* Power management related routines */ From 8169b5d2384a0acd9ea3bb86bf5988cd7d62d03a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Tue, 3 Jan 2006 18:51:46 -0800 Subject: [PATCH 05/23] [PATCH] PCI: make it easier to see that set_msi_affinity() is used I missed this usage in drivers/pci/msi.h: #ifdef CONFIG_SMP #define set_msi_irq_affinity set_msi_affinity #else #define set_msi_irq_affinity NULL #endif set_msi_affinity() is declared and exclusively used in msi.c. Here's a better way so (hopefully) history doesn't repeat itself. Signed-off-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 8 +++++--- drivers/pci/msi.h | 6 ------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 8e1ba0b7a8e4..48723d6fa60f 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -137,6 +137,8 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) break; } } +#else +#define set_msi_affinity NULL #endif /* CONFIG_SMP */ static void mask_MSI_irq(unsigned int vector) @@ -214,7 +216,7 @@ static struct hw_interrupt_type msix_irq_type = { .disable = mask_MSI_irq, .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; /* @@ -230,7 +232,7 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { .disable = mask_MSI_irq, .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; /* @@ -246,7 +248,7 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = { .disable = do_nothing, .ack = do_nothing, .end = end_msi_irq_wo_maskbit, - .set_affinity = set_msi_irq_affinity + .set_affinity = set_msi_affinity }; static void msi_data_init(struct msg_data *msi_data, diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 402136a5c9e4..4ac52d441e47 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -22,12 +22,6 @@ extern int vector_irq[NR_VECTORS]; extern void (*interrupt[NR_IRQS])(void); extern int pci_vector_resources(int last, int nr_released); -#ifdef CONFIG_SMP -#define set_msi_irq_affinity set_msi_affinity -#else -#define set_msi_irq_affinity NULL -#endif - /* * MSI-X Address Register */ From 072888fa60af86c3159f9f3ed4e34364861bab3a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 8 Jan 2006 20:11:59 +0100 Subject: [PATCH 06/23] [PATCH] PCI Hotplug: fix up coding style issues Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_ibm.c | 21 +++++++++------------ drivers/pci/hotplug/ibmphp_core.c | 4 ++-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 7e7f913ba7b9..317457dd4014 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -302,7 +302,7 @@ static int ibm_get_table_from_acpi(char **bufp) } package = (union acpi_object *) buffer.pointer; - if(!(package) || + if (!(package) || (package->type != ACPI_TYPE_PACKAGE) || !(package->package.elements)) { err("%s: Invalid APCI object\n", __FUNCTION__); @@ -405,7 +405,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, } info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; - if(info.current_status && (info.valid & ACPI_VALID_HID) && + if (info.current_status && (info.valid & ACPI_VALID_HID) && (!strcmp(info.hardware_id.value, IBM_HARDWARE_ID1) || !strcmp(info.hardware_id.value, IBM_HARDWARE_ID2))) { dbg("found hardware: %s, handle: %p\n", info.hardware_id.value, @@ -449,13 +449,11 @@ static int __init ibm_acpiphp_init(void) } ibm_note.device = device; - status = acpi_install_notify_handler( - ibm_acpi_handle, - ACPI_DEVICE_NOTIFY, - ibm_handle_events, + status = acpi_install_notify_handler(ibm_acpi_handle, + ACPI_DEVICE_NOTIFY, ibm_handle_events, &ibm_note); if (ACPI_FAILURE(status)) { - err("%s: Failed to register notification handler\n", + err("%s: Failed to register notification handler\n", __FUNCTION__); retval = -EBUSY; goto init_cleanup; @@ -482,14 +480,13 @@ static void __exit ibm_acpiphp_exit(void) if (acpiphp_unregister_attention(&ibm_attention_info)) err("%s: attention info deregistration failed", __FUNCTION__); - status = acpi_remove_notify_handler( + status = acpi_remove_notify_handler( ibm_acpi_handle, ACPI_DEVICE_NOTIFY, ibm_handle_events); - if (ACPI_FAILURE(status)) - err("%s: Notification handler removal failed\n", - __FUNCTION__); - // remove the /sys entries + if (ACPI_FAILURE(status)) + err("%s: Notification handler removal failed\n", __FUNCTION__); + /* remove the /sys entries */ if (sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr)) err("%s: removal of sysfs file apci_table failed\n", __FUNCTION__); diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index aabf1e70b528..dc59da675c08 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -235,12 +235,12 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { int rc = 0; struct slot *pslot; - u8 cmd; + u8 cmd = 0x00; /* avoid compiler warning */ debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n", (ulong) hotplug_slot, value); ibmphp_lock_operations(); - cmd = 0x00; // avoid compiler warning + if (hotplug_slot) { switch (value) { From 654143ee3a73b2793350b039a135d9cd3101147b Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 9 Jan 2006 16:16:00 +0100 Subject: [PATCH 07/23] [PATCH] PCI Hotplug: fix up Kconfig help text Remove reference to pcihpfs that no longer exists. Signed-off-by: Pavel Machek --- drivers/pci/hotplug/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 2f1289eebb3c..222a1cc4aa28 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -11,8 +11,7 @@ config HOTPLUG_PCI ---help--- Say Y here if you have a motherboard with a PCI Hotplug controller. This allows you to add and remove PCI cards while the machine is - powered up and running. The file system pcihpfs must be mounted - in order to interact with any PCI Hotplug controllers. + powered up and running. To compile this driver as a module, choose M here: the module will be called pci_hotplug. From 8cea8e9303d45556cb606cc8d9e41f889ff600c0 Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Thu, 5 Jan 2006 22:47:29 -0800 Subject: [PATCH 08/23] [PATCH] PCI: restore 2 missing pci ids Somewhere between 2.6.14 and 2.6.15-rc3, some PCI ids were apparently removed. The ecc.c module, which is not a part of the kernel.org tree, but included in some distributions, fails to compile. Signed-off-by: Mark Rustad Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9eb1983b8787..7868a8ed1906 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2065,6 +2065,7 @@ #define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 #define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db +#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd #define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 #define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 #define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 @@ -2156,6 +2157,7 @@ #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca #define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_DEVICE_ID_INTEL_84460GX 0x84ea From 2181c971952ec2af56cd9cc68453f7ad5a0a38d6 Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Sun, 15 Jan 2006 16:21:27 +1100 Subject: [PATCH 09/23] [PATCH] PCI: pci_ids: remove duplicates gathered during merge period pci_ids.h: remove duplicates. Compile tested allmodconfig. Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7868a8ed1906..b0b908f583c5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -394,14 +394,9 @@ #define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 #define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 #define PCI_DEVICE_ID_NS_87410 0xd001 -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d #define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028 #define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d -#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e -#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f -#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030 #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 @@ -511,8 +506,6 @@ #define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A -#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A - #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 From dd8c49966854a5245f3ed4769c9114e7afd819ef Mon Sep 17 00:00:00 2001 From: linas Date: Tue, 10 Jan 2006 15:15:47 -0600 Subject: [PATCH 10/23] [PATCH] PCI Hotplug/powerpc: module build break The RPAPHP hoplug driver will not build as a module, because it calls on pci_claim_resource(), which is not exported. This exports the symbol. Problem reported by Olaf Hering A grep indicates that building drivers/parisc/lba_pci.c would have trouble building as a module for the same reason. Signed-off-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman --- drivers/pci/setup-res.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 50d6685dcbcc..ea9277b7f899 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -112,6 +112,7 @@ pci_claim_resource(struct pci_dev *dev, int resource) return err; } +EXPORT_SYMBOL_GPL(pci_claim_resource); int pci_assign_resource(struct pci_dev *dev, int resno) { From 3c0c6441883be7676b795939e268b90d6acab360 Mon Sep 17 00:00:00 2001 From: linas Date: Thu, 12 Jan 2006 14:36:25 -0600 Subject: [PATCH 11/23] [PATCH] PCI Hotplug: PCI panic on dlpar add (add pci slot to running partition) Removing and then adding a PCI slot to a running partition results in a kernel panic. The current code attempts to add iospace for an entire root bus, which is inappropriate, and silently fails. When a pci device tries to use the iospace, a page fault is taken, as the iospace had not been mapped, and of course the page fault cannot be resolved. This only occurs for PCI adapters using pio, which may be why it hadn't been seen earlier (this seems to have been broken for a while). This patch has survived testing of dozens of slot add and removes. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7d93dbaf628d..7f504b380f26 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -152,7 +152,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) pcibios_claim_one_bus(dev->bus); /* ioremap() for child bus, which may or may not succeed */ - (void) remap_bus_range(dev->bus); + remap_bus_range(dev->subordinate); /* Add new devices to global lists. Register in proc, sysfs. */ pci_bus_add_devices(phb->bus); From 53044f357448693f218cc4f053affe92ed414f9d Mon Sep 17 00:00:00 2001 From: "Keck, David" Date: Mon, 16 Jan 2006 15:22:36 -0600 Subject: [PATCH 12/23] [PATCH] PCI Hotplug: shpchp: AMD POGO errata fix This patch fixes the AMD POGO errata on the hotplug controller where the platform will lock up or reboot if PERR/SERR generation is enabled and a slot is sent an enable command. This fix disables PERR/SERR generation before a slot is sent the enable command by first saving related registers, turning off SERR/PERR generation, enabling the slot, then restoring the registers. Signed-off-by: David Keck Cc: Kristen Accardi Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchp.h | 94 +++++++++++++++++++++++++++++++ drivers/pci/hotplug/shpchp_ctrl.c | 12 +++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index ce0e9b6ce833..7d6f521d02ea 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -95,6 +95,7 @@ struct controller { u8 function; u8 slot_device_offset; u8 add_support; + u32 pcix_misc2_reg; /* for amd pogo errata */ enum pci_bus_speed speed; u32 first_slot; /* First physical slot number */ u8 slot_bus; /* Bus where the slots handled by this controller sit */ @@ -113,6 +114,26 @@ struct hotplug_params { /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 +#define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 + +/* AMD PCIX bridge registers */ + +#define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C +#define PCIX_MISCII_OFFSET 0x48 +#define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 + +/* AMD PCIX_MISCII masks and offsets */ +#define PERRNONFATALENABLE_MASK 0x00040000 +#define PERRFATALENABLE_MASK 0x00080000 +#define PERRFLOODENABLE_MASK 0x00100000 +#define SERRNONFATALENABLE_MASK 0x00200000 +#define SERRFATALENABLE_MASK 0x00400000 + +/* AMD PCIX_MISC_BRIDGE_ERRORS masks and offsets */ +#define PERR_OBSERVED_MASK 0x00000001 + +/* AMD PCIX_MEM_BASE_LIMIT masks */ +#define RSE_MASK 0x40000000 #define INT_BUTTON_IGNORE 0 #define INT_PRESENCE_ON 1 @@ -333,6 +354,79 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) return retval; } +static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot) +{ + u32 pcix_misc2_temp; + + /* save MiscII register */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp); + + p_slot->ctrl->pcix_misc2_reg = pcix_misc2_temp; + + /* clear SERR/PERR enable bits */ + pcix_misc2_temp &= ~SERRFATALENABLE_MASK; + pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK; + pcix_misc2_temp &= ~PERRFLOODENABLE_MASK; + pcix_misc2_temp &= ~PERRFATALENABLE_MASK; + pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK; + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); +} + +static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) +{ + u32 pcix_misc2_temp; + u32 pcix_bridge_errors_reg; + u32 pcix_mem_base_reg; + u8 perr_set; + u8 rse_set; + + /* write-one-to-clear Bridge_Errors[ PERR_OBSERVED ] */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, &pcix_bridge_errors_reg); + perr_set = pcix_bridge_errors_reg & PERR_OBSERVED_MASK; + if (perr_set) { + dbg ("%s W1C: Bridge_Errors[ PERR_OBSERVED = %08X]\n",__FUNCTION__ , perr_set); + + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISC_BRIDGE_ERRORS_OFFSET, perr_set); + } + + /* write-one-to-clear Memory_Base_Limit[ RSE ] */ + pci_read_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, &pcix_mem_base_reg); + rse_set = pcix_mem_base_reg & RSE_MASK; + if (rse_set) { + dbg ("%s W1C: Memory_Base_Limit[ RSE ]\n",__FUNCTION__ ); + + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MEM_BASE_LIMIT_OFFSET, rse_set); + } + /* restore MiscII register */ + pci_read_config_dword( p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, &pcix_misc2_temp ); + + if (p_slot->ctrl->pcix_misc2_reg & SERRFATALENABLE_MASK) + pcix_misc2_temp |= SERRFATALENABLE_MASK; + else + pcix_misc2_temp &= ~SERRFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & SERRNONFATALENABLE_MASK) + pcix_misc2_temp |= SERRNONFATALENABLE_MASK; + else + pcix_misc2_temp &= ~SERRNONFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRFLOODENABLE_MASK) + pcix_misc2_temp |= PERRFLOODENABLE_MASK; + else + pcix_misc2_temp &= ~PERRFLOODENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRFATALENABLE_MASK) + pcix_misc2_temp |= PERRFATALENABLE_MASK; + else + pcix_misc2_temp &= ~PERRFATALENABLE_MASK; + + if (p_slot->ctrl->pcix_misc2_reg & PERRNONFATALENABLE_MASK) + pcix_misc2_temp |= PERRNONFATALENABLE_MASK; + else + pcix_misc2_temp &= ~PERRNONFATALENABLE_MASK; + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); +} + #define SLOT_NAME_SIZE 10 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 25ccb0e47593..643252d9bf3b 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -894,7 +894,17 @@ int shpchp_enable_slot (struct slot *p_slot) dbg("%s: p_slot->pwr_save %x\n", __FUNCTION__, p_slot->pwr_save); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - rc = board_added(p_slot); + if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) || + (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458)) + && p_slot->ctrl->num_slots == 1) { + /* handle amd pogo errata; this must be done before enable */ + amd_pogo_errata_save_misc_reg(p_slot); + rc = board_added(p_slot); + /* handle amd pogo errata; this must be done after enable */ + amd_pogo_errata_restore_misc_reg(p_slot); + } else + rc = board_added(p_slot); + if (rc) { p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); From 01657868be1c21b2b8b0e683ea24bdcc2331d522 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:18:26 -0600 Subject: [PATCH 13/23] [PATCH] powerpc/PCI hotplug: remove rpaphp_find_bus() The function rpaphp_find_pci_bus() has been migrated to pcibios_find_pci_bus() in arch/powerpc/platforms/pseries/pci_dlpar.c This patch removes the old version. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 6 ++--- drivers/pci/hotplug/rpaphp.h | 3 --- drivers/pci/hotplug/rpaphp_pci.c | 34 ++--------------------------- 3 files changed, 5 insertions(+), 38 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7f504b380f26..bc17a13fc82e 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -174,7 +174,7 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) { struct pci_dev *dev; - if (rpaphp_find_pci_bus(dn)) + if (pcibios_find_pci_bus(dn)) return -EINVAL; /* Add pci bus */ @@ -221,7 +221,7 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) struct pci_dn *pdn; int rc = 0; - if (!rpaphp_find_pci_bus(dn)) + if (!pcibios_find_pci_bus(dn)) return -EINVAL; slot = find_slot(dn); @@ -366,7 +366,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) struct pci_bus *bus; struct slot *slot; - bus = rpaphp_find_pci_bus(dn); + bus = pcibios_find_pci_bus(dn); if (!bus) return -EINVAL; diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 57ea71a7bda5..b333a35dd221 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -88,13 +88,10 @@ extern int num_slots; /* function prototypes */ /* rpaphp_pci.c */ -extern struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn); -extern int rpaphp_claim_resource(struct pci_dev *dev, int resource); extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern void rpaphp_init_new_devs(struct pci_bus *bus); -extern void rpaphp_eeh_init_nodes(struct device_node *dn); extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 396b54b0c847..f16d0f9240ee 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -32,36 +32,6 @@ #include "../pci.h" /* for pci_add_new_bus */ #include "rpaphp.h" -static struct pci_bus *find_bus_among_children(struct pci_bus *bus, - struct device_node *dn) -{ - struct pci_bus *child = NULL; - struct list_head *tmp; - struct device_node *busdn; - - busdn = pci_bus_to_OF_node(bus); - if (busdn == dn) - return bus; - - list_for_each(tmp, &bus->children) { - child = find_bus_among_children(pci_bus_b(tmp), dn); - if (child) - break; - } - return child; -} - -struct pci_bus *rpaphp_find_pci_bus(struct device_node *dn) -{ - struct pci_dn *pdn = dn->data; - - if (!pdn || !pdn->phb || !pdn->phb->bus) - return NULL; - - return find_bus_among_children(pdn->phb->bus, dn); -} -EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus); - static int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; @@ -120,7 +90,7 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) /* config/unconfig adapter */ *value = slot->state; } else { - bus = rpaphp_find_pci_bus(slot->dn); + bus = pcibios_find_pci_bus(slot->dn); if (bus && !list_empty(&bus->devices)) *value = CONFIGURED; else @@ -370,7 +340,7 @@ static int setup_pci_slot(struct slot *slot) struct pci_bus *bus; BUG_ON(!dn); - bus = rpaphp_find_pci_bus(dn); + bus = pcibios_find_pci_bus(dn); if (!bus) { err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); goto exit_rc; From eca845c71816669dace4bf1954d9ab276abb0002 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:20:26 -0600 Subject: [PATCH 14/23] [PATCH] powerpc/PCI hotplug: remove rpaphp_fixup_new_pci_devices() The function rpaphp_fixup_new_pci_devices() has been migrated to pcibios_fixup_new_pci_devices() in arch/powerpc/platforms/pseries/pci_dlpar.c This patch removes the old version. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 2 +- drivers/pci/hotplug/rpaphp.h | 1 - drivers/pci/hotplug/rpaphp_pci.c | 142 +--------------------------- 3 files changed, 2 insertions(+), 143 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index bc17a13fc82e..6c148106518e 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -146,7 +146,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) of_scan_pci_bridge(dn, dev); - rpaphp_init_new_devs(dev->subordinate); + pcibios_fixup_new_pci_devices(dev->subordinate,0); /* Claim new bus resources */ pcibios_claim_one_bus(dev->bus); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index b333a35dd221..6aa91ef5cd70 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,7 +91,6 @@ extern int num_slots; extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern void rpaphp_init_new_devs(struct pci_bus *bus); extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index f16d0f9240ee..1a12ebd10e34 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -101,140 +101,6 @@ int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) return rc; } -/* Must be called before pci_bus_add_devices */ -void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* - * Skip already-present devices (which are on the - * global device list.) - */ - if (list_empty(&dev->global_list)) { - int i; - - /* Need to setup IOMMU tables */ - ppc_md.iommu_dev_setup(dev); - - if(fix_bus) - pcibios_fixup_device_resources(dev, bus); - pci_read_irq_line(dev); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - - if (r->parent || !r->start || !r->flags) - continue; - pci_claim_resource(dev, i); - } - } - } -} - -static void rpaphp_eeh_add_bus_device(struct pci_bus *bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - eeh_add_device_late(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *subbus = dev->subordinate; - if (subbus) - rpaphp_eeh_add_bus_device (subbus); - } - } -} - -static int rpaphp_pci_config_bridge(struct pci_dev *dev) -{ - u8 sec_busno; - struct pci_bus *child_bus; - struct pci_dev *child_dev; - - dbg("Enter %s: BRIDGE dev=%s\n", __FUNCTION__, pci_name(dev)); - - /* get busno of downstream bus */ - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); - - /* add to children of PCI bridge dev->bus */ - child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); - if (!child_bus) { - err("%s: could not add second bus\n", __FUNCTION__); - return -EIO; - } - sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); - /* do pci_scan_child_bus */ - pci_scan_child_bus(child_bus); - - list_for_each_entry(child_dev, &child_bus->devices, bus_list) { - eeh_add_device_late(child_dev); - } - - /* fixup new pci devices without touching bus struct */ - rpaphp_fixup_new_pci_devices(child_bus, 0); - - /* Make the discovered devices available */ - pci_bus_add_devices(child_bus); - return 0; -} - -void rpaphp_init_new_devs(struct pci_bus *bus) -{ - rpaphp_fixup_new_pci_devices(bus, 0); - rpaphp_eeh_add_bus_device(bus); -} -EXPORT_SYMBOL_GPL(rpaphp_init_new_devs); - -/***************************************************************************** - rpaphp_pci_config_slot() will configure all devices under the - given slot->dn and return the the first pci_dev. - *****************************************************************************/ -static struct pci_dev * -rpaphp_pci_config_slot(struct pci_bus *bus) -{ - struct device_node *dn = pci_bus_to_OF_node(bus); - struct pci_dev *dev = NULL; - int slotno; - int num; - - dbg("Enter %s: dn=%s bus=%s\n", __FUNCTION__, dn->full_name, bus->name); - if (!dn || !dn->child) - return NULL; - - if (_machine == PLATFORM_PSERIES_LPAR) { - of_scan_bus(dn, bus); - if (list_empty(&bus->devices)) { - err("%s: No new device found\n", __FUNCTION__); - return NULL; - } - - rpaphp_init_new_devs(bus); - pci_bus_add_devices(bus); - dev = list_entry(&bus->devices, struct pci_dev, bus_list); - } else { - slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); - - /* pci_scan_slot should find all children */ - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (num) { - rpaphp_fixup_new_pci_devices(bus, 1); - pci_bus_add_devices(bus); - } - if (list_empty(&bus->devices)) { - err("%s: No new device found\n", __FUNCTION__); - return NULL; - } - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) - rpaphp_pci_config_bridge(dev); - - rpaphp_eeh_add_bus_device(bus); - } - } - - return dev; -} - static void print_slot_pci_funcs(struct pci_bus *bus) { struct device_node *dn; @@ -253,19 +119,13 @@ static void print_slot_pci_funcs(struct pci_bus *bus) int rpaphp_config_pci_adapter(struct pci_bus *bus) { struct device_node *dn = pci_bus_to_OF_node(bus); - struct pci_dev *dev; int rc = -ENODEV; dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); if (!dn) goto exit; - eeh_add_device_tree_early(dn); - dev = rpaphp_pci_config_slot(bus); - if (!dev) { - err("%s: can't find any devices.\n", __FUNCTION__); - goto exit; - } + pcibios_add_pci_devices(bus); print_slot_pci_funcs(bus); rc = 0; exit: From 7fec77e4793f307b30846a3d4015d329ffc0b685 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:22:07 -0600 Subject: [PATCH 15/23] [PATCH] powerpc/PCI hotplug: merge config_pci_adapter Remove general baroqueness. The function rpaphp_config_pci_adapter() is really just one line of code, once all the dbg printks are removed. And its called in only one place. So replace the call by the one line. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp.h | 1 - drivers/pci/hotplug/rpaphp_pci.c | 35 ++++---------------------------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 6aa91ef5cd70..89d705c7c502 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -92,7 +92,6 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern int rpaphp_config_pci_adapter(struct pci_bus *bus); extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); /* rpaphp_core.c */ diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 1a12ebd10e34..b93d9c964eea 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,24 +116,6 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -int rpaphp_config_pci_adapter(struct pci_bus *bus) -{ - struct device_node *dn = pci_bus_to_OF_node(bus); - int rc = -ENODEV; - - dbg("Entry %s: slot[%s]\n", __FUNCTION__, dn->full_name); - if (!dn) - goto exit; - - pcibios_add_pci_devices(bus); - print_slot_pci_funcs(bus); - rc = 0; -exit: - dbg("Exit %s: rc=%d\n", __FUNCTION__, rc); - return rc; -} -EXPORT_SYMBOL_GPL(rpaphp_config_pci_adapter); - static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) { eeh_remove_device(dev); @@ -225,10 +207,7 @@ static int setup_pci_slot(struct slot *slot) if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { dbg("%s CONFIGURING pci adapter in slot[%s]\n", __FUNCTION__, slot->name); - if (rpaphp_config_pci_adapter(slot->bus)) { - err("%s: CONFIG pci adapter failed\n", __FUNCTION__); - goto exit_rc; - } + pcibios_add_pci_devices(slot->bus); } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", @@ -274,16 +253,10 @@ int rpaphp_enable_pci_slot(struct slot *slot) /* if slot is not empty, enable the adapter */ if (state == PRESENT) { dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); - retval = rpaphp_config_pci_adapter(slot->bus); - if (!retval) { - slot->state = CONFIGURED; - info("%s: devices in slot[%s] configured\n", + pcibios_add_pci_devices(slot->bus); + slot->state = CONFIGURED; + info("%s: devices in slot[%s] configured\n", __FUNCTION__, slot->name); - } else { - slot->state = NOT_CONFIGURED; - dbg("%s: no pci_dev struct for adapter in slot[%s]\n", - __FUNCTION__, slot->name); - } } else if (state == EMPTY) { dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); slot->state = EMPTY; From 8a85a70db8c65fd1703b4597f72fe6ee25642234 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:24:27 -0600 Subject: [PATCH 16/23] [PATCH] powerpc/PCI hotplug: remove remove_bus_device() The function rpaphp_eeh_remove_bus_device() is a dupe of eeh_remove_bus_device(). Remove it. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp_pci.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index b93d9c964eea..1f5e73be47c7 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,30 +116,12 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev) -{ - eeh_remove_device(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *bus = dev->subordinate; - struct list_head *ln; - if (!bus) - return; - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *pdev = pci_dev_b(ln); - if (pdev) - rpaphp_eeh_remove_bus_device(pdev); - } - - } - return; -} - int rpaphp_unconfig_pci_adapter(struct pci_bus *bus) { struct pci_dev *dev, *tmp; list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - rpaphp_eeh_remove_bus_device(dev); + eeh_remove_bus_device(dev); pci_remove_bus_device(dev); } return 0; From 8fe64399cccf8dddcc4e5eaff270a12064f6fe9f Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:26:27 -0600 Subject: [PATCH 17/23] [PATCH] powerpc/PCI hotplug: de-convolute rpaphp_unconfig_pci_adap Remove general baroqueness. The function rpaphp_unconfig_pci_adapter() is really just three lines of code, once all the dbg printks are removed. And its called in only one place. So replace the call by the thre lines. Also, provide proper semaphore locking in the affected function disable_slot() Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 6 ++++- drivers/pci/hotplug/rpaphp.h | 2 -- drivers/pci/hotplug/rpaphp_core.c | 34 ++++++++++++++++------------- drivers/pci/hotplug/rpaphp_pci.c | 12 ---------- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 6c148106518e..15e853e5e689 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -380,7 +380,11 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) return -EIO; } } else { - rpaphp_unconfig_pci_adapter(bus); + struct pci_dev *dev, *tmp; + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); + } } if (unmap_bus_range(bus)) { diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 89d705c7c502..6e4f93ba6555 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -92,8 +92,6 @@ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); -extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); - /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); extern int rpaphp_remove_slot(struct slot *slot); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index cf075c34b578..acf17645fd8a 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -412,27 +412,31 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return retval; } -static int disable_slot(struct hotplug_slot *hotplug_slot) +static int __disable_slot(struct slot *slot) { - int retval = -EINVAL; - struct slot *slot = (struct slot *)hotplug_slot->private; + struct pci_dev *dev, *tmp; - dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); + if (slot->state == NOT_CONFIGURED) + return -EINVAL; - if (slot->state == NOT_CONFIGURED) { - dbg("%s: %s is already disabled\n", __FUNCTION__, slot->name); - goto exit; + list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); } - dbg("DISABLING SLOT %s\n", slot->name); - down(&rpaphp_sem); - retval = rpaphp_unconfig_pci_adapter(slot->bus); - up(&rpaphp_sem); slot->state = NOT_CONFIGURED; - info("%s: devices in slot[%s] unconfigured.\n", __FUNCTION__, - slot->name); -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return 0; +} + +static int disable_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = (struct slot *)hotplug_slot->private; + int retval; + + down(&rpaphp_sem); + retval = __disable_slot (slot); + up(&rpaphp_sem); + return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 1f5e73be47c7..ce7ebec05933 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,18 +116,6 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -int rpaphp_unconfig_pci_adapter(struct pci_bus *bus) -{ - struct pci_dev *dev, *tmp; - - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); - } - return 0; -} -EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter); - static int setup_pci_hotplug_slot_info(struct slot *slot) { struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; From e06b80b78db96ca272db4ec0b26ce1092a1a9704 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:28:22 -0600 Subject: [PATCH 18/23] [PATCH] powerpc/PCI hotplug: merge rpaphp_enable_pci_slot() Remove general baroqueness. The function rpaphp_enable_pci_slot() has a fairly simple logic structure, once all of the debug printk's are removed. Its called from only one place, and that place also has a very simple structure once he printk's are removed. Merge the two together. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp.h | 1 + drivers/pci/hotplug/rpaphp_core.c | 38 +++++++++++++++++++++++-------- drivers/pci/hotplug/rpaphp_pci.c | 30 +----------------------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 6e4f93ba6555..095c9aacaa16 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,6 +91,7 @@ extern int num_slots; extern int rpaphp_enable_pci_slot(struct slot *slot); extern int register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); +extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index acf17645fd8a..341fdd59090b 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -393,22 +393,40 @@ static void __exit rpaphp_exit(void) cleanup_slots(); } +static int __enable_slot(struct slot *slot) +{ + int state; + int retval; + + if (slot->state == CONFIGURED) + return 0; + + retval = rpaphp_get_sensor_state(slot, &state); + if (retval) + return retval; + + if (state == PRESENT) { + pcibios_add_pci_devices(slot->bus); + slot->state = CONFIGURED; + } else if (state == EMPTY) { + slot->state = EMPTY; + } else { + err("%s: slot[%s] is in invalid state\n", __FUNCTION__, slot->name); + slot->state = NOT_VALID; + return -EINVAL; + } + return 0; +} + static int enable_slot(struct hotplug_slot *hotplug_slot) { - int retval = 0; + int retval; struct slot *slot = (struct slot *)hotplug_slot->private; - if (slot->state == CONFIGURED) { - dbg("%s: %s is already enabled\n", __FUNCTION__, slot->name); - goto exit; - } - - dbg("ENABLING SLOT %s\n", slot->name); down(&rpaphp_sem); - retval = rpaphp_enable_pci_slot(slot); + retval = __enable_slot(slot); up(&rpaphp_sem); -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index ce7ebec05933..d1297d070a75 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -32,7 +32,7 @@ #include "../pci.h" /* for pci_add_new_bus */ #include "rpaphp.h" -static int rpaphp_get_sensor_state(struct slot *slot, int *state) +int rpaphp_get_sensor_state(struct slot *slot, int *state) { int rc; int setlevel; @@ -212,31 +212,3 @@ int register_pci_slot(struct slot *slot) return rc; } -int rpaphp_enable_pci_slot(struct slot *slot) -{ - int retval = 0, state; - - retval = rpaphp_get_sensor_state(slot, &state); - if (retval) - goto exit; - dbg("%s: sensor state[%d]\n", __FUNCTION__, state); - /* if slot is not empty, enable the adapter */ - if (state == PRESENT) { - dbg("%s : slot[%s] is occupied.\n", __FUNCTION__, slot->name); - pcibios_add_pci_devices(slot->bus); - slot->state = CONFIGURED; - info("%s: devices in slot[%s] configured\n", - __FUNCTION__, slot->name); - } else if (state == EMPTY) { - dbg("%s : slot[%s] is empty\n", __FUNCTION__, slot->name); - slot->state = EMPTY; - } else { - err("%s: slot[%s] is in invalid state\n", __FUNCTION__, - slot->name); - slot->state = NOT_VALID; - retval = -EINVAL; - } -exit: - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); - return retval; -} From f6afbad82c6b7bab0198442592b110341fb419ba Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:31:01 -0600 Subject: [PATCH 19/23] [PATCH] powerpc/PCI hotplug: cleanup: add prefix Minor cleanup. Add the prefix rpaphp_* to several generic-sounding routines. Remove rpaphp_remove_slot(), which is a one-liner. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 4 ++-- drivers/pci/hotplug/rpaphp.h | 6 +++--- drivers/pci/hotplug/rpaphp_core.c | 14 +++++--------- drivers/pci/hotplug/rpaphp_pci.c | 4 ++-- drivers/pci/hotplug/rpaphp_slot.c | 16 ++++++++-------- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 15e853e5e689..d3aa9df1acd4 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -227,7 +227,7 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) slot = find_slot(dn); if (slot) { /* Remove hotplug slot */ - if (rpaphp_remove_slot(slot)) { + if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", __FUNCTION__, drc_name); @@ -373,7 +373,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) slot = find_slot(dn); if (slot) { /* Remove hotplug slot */ - if (rpaphp_remove_slot(slot)) { + if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", __FUNCTION__, drc_name); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 095c9aacaa16..310b6186c0e5 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -89,7 +89,7 @@ extern int num_slots; /* rpaphp_pci.c */ extern int rpaphp_enable_pci_slot(struct slot *slot); -extern int register_pci_slot(struct slot *slot); +extern int rpaphp_register_pci_slot(struct slot *slot); extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern int rpaphp_get_sensor_state(struct slot *slot, int *state); @@ -102,8 +102,8 @@ extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, /* rpaphp_slot.c */ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); -extern int register_slot(struct slot *slot); -extern int deregister_slot(struct slot *slot); +extern int rpaphp_register_slot(struct slot *slot); +extern int rpaphp_deregister_slot(struct slot *slot); extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 341fdd59090b..c0e521c8f9ef 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -196,11 +196,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe return 0; } -int rpaphp_remove_slot(struct slot *slot) -{ - return deregister_slot(slot); -} - static int get_children_props(struct device_node *dn, int **drc_indexes, int **drc_names, int **drc_types, int **drc_power_domains) { @@ -307,13 +302,15 @@ static int is_php_dn(struct device_node *dn, int **indexes, int **names, return 0; } -/**************************************************************** +/** + * rpaphp_add_slot -- add hotplug or dlpar slot + * * rpaphp not only registers PCI hotplug slots(HOTPLUG), * but also logical DR slots(EMBEDDED). * HOTPLUG slot: An adapter can be physically added/removed. * EMBEDDED slot: An adapter can be logically removed/added * from/to a partition with the slot. - ***************************************************************/ + */ int rpaphp_add_slot(struct device_node *dn) { struct slot *slot; @@ -344,7 +341,7 @@ int rpaphp_add_slot(struct device_node *dn) dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", indexes[i + 1], name, type); - retval = register_pci_slot(slot); + retval = rpaphp_register_pci_slot(slot); } } exit: @@ -462,6 +459,5 @@ module_init(rpaphp_init); module_exit(rpaphp_exit); EXPORT_SYMBOL_GPL(rpaphp_add_slot); -EXPORT_SYMBOL_GPL(rpaphp_remove_slot); EXPORT_SYMBOL_GPL(rpaphp_slot_head); EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index d1297d070a75..6f6cbede5135 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -199,7 +199,7 @@ static int setup_pci_slot(struct slot *slot) return -EINVAL; } -int register_pci_slot(struct slot *slot) +int rpaphp_register_pci_slot(struct slot *slot) { int rc = -EINVAL; @@ -207,7 +207,7 @@ int register_pci_slot(struct slot *slot) goto exit_rc; if (setup_pci_slot(slot)) goto exit_rc; - rc = register_slot(slot); + rc = rpaphp_register_slot(slot); exit_rc: return rc; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index daa89ae57123..04cc1e7275ce 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -35,16 +35,16 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) { - char *value; - int retval = -ENOENT; + char *value; + int retval = -ENOENT; struct slot *slot = (struct slot *)php_slot->private; if (!slot) return retval; - value = slot->location; - retval = sprintf (buf, "%s\n", value); - return retval; + value = slot->location; + retval = sprintf (buf, "%s\n", value); + return retval; } static struct hotplug_slot_attribute hotplug_slot_attr_location = { @@ -137,7 +137,7 @@ static int is_registered(struct slot *slot) return 0; } -int deregister_slot(struct slot *slot) +int rpaphp_deregister_slot(struct slot *slot) { int retval = 0; struct hotplug_slot *php_slot = slot->hotplug_slot; @@ -160,7 +160,7 @@ int deregister_slot(struct slot *slot) return retval; } -int register_slot(struct slot *slot) +int rpaphp_register_slot(struct slot *slot) { int retval; @@ -169,7 +169,7 @@ int register_slot(struct slot *slot) slot->power_domain, slot->type); /* should not try to register the same slot twice */ if (is_registered(slot)) { /* should't be here */ - err("register_slot: slot[%s] is already registered\n", slot->name); + err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); rpaphp_release_slot(slot->hotplug_slot); return -EAGAIN; } From b64a71ab5c9098a79ccb463af968933483458a0f Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:32:58 -0600 Subject: [PATCH 20/23] [PATCH] powerpc/PCI hotplug: minor cleanup forward decls Minor cleanup. Move structure initializer to bottom of file, this allows elimination of eyeball-strain-inducing forward declarations. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpaphp_core.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c0e521c8f9ef..6e79f5675b0d 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -56,25 +56,6 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, 0644); -static int enable_slot(struct hotplug_slot *slot); -static int disable_slot(struct hotplug_slot *slot); -static int set_attention_status(struct hotplug_slot *slot, u8 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_adapter_status(struct hotplug_slot *slot, u8 * value); -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value); - -struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { - .owner = THIS_MODULE, - .enable_slot = enable_slot, - .disable_slot = disable_slot, - .set_attention_status = set_attention_status, - .get_power_status = get_power_status, - .get_attention_status = get_attention_status, - .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, -}; - static int rpaphp_get_attention_status(struct slot *slot) { return slot->hotplug_slot->info->attention_status; @@ -455,6 +436,17 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) return retval; } +struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { + .owner = THIS_MODULE, + .enable_slot = enable_slot, + .disable_slot = disable_slot, + .set_attention_status = set_attention_status, + .get_power_status = get_power_status, + .get_attention_status = get_attention_status, + .get_adapter_status = get_adapter_status, + .get_max_bus_speed = get_max_bus_speed, +}; + module_init(rpaphp_init); module_exit(rpaphp_exit); From 8737d6a90cd8b085c2ea9cb4c7443c87f86c3429 Mon Sep 17 00:00:00 2001 From: "linas@austin.ibm.com" Date: Thu, 12 Jan 2006 18:35:23 -0600 Subject: [PATCH 21/23] [PATCH] powerpc/PCI hotplug: shuffle error checking to better location. Error checking is scattered through various layers of the dlpar code, leading to a somewhat opaque code structure. This patch consolidates error checking in one routine, simplifying the code a tad. There's also some whitespace cleanup here too. Signed-off-by: Linas Vepstas Acked-by: John Rose Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/rpadlpar_core.c | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index d3aa9df1acd4..3eefe2cec72d 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -103,13 +103,13 @@ static struct slot *find_slot(struct device_node *dn) struct list_head *tmp, *n; struct slot *slot; - list_for_each_safe(tmp, n, &rpaphp_slot_head) { - slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->dn == dn) - return slot; - } + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + if (slot->dn == dn) + return slot; + } - return NULL; + return NULL; } static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, @@ -126,9 +126,9 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, return NULL; } -static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) +static void dlpar_pci_add_bus(struct device_node *dn) { - struct pci_dn *pdn = dn->data; + struct pci_dn *pdn = PCI_DN(dn); struct pci_controller *phb = pdn->phb; struct pci_dev *dev = NULL; @@ -139,7 +139,7 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) if (!dev) { printk(KERN_ERR "%s: failed to create pci dev for %s\n", __FUNCTION__, dn->full_name); - return NULL; + return; } if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || @@ -156,35 +156,35 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) /* Add new devices to global lists. Register in proc, sysfs. */ pci_bus_add_devices(phb->bus); - - /* Confirm new bridge dev was created */ - dev = dlpar_find_new_dev(phb->bus, dn); - if (dev) { - if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { - printk(KERN_ERR "%s: unexpected header type %d\n", - __FUNCTION__, dev->hdr_type); - return NULL; - } - } - - return dev; } static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) { struct pci_dev *dev; + struct pci_controller *phb; if (pcibios_find_pci_bus(dn)) return -EINVAL; /* Add pci bus */ - dev = dlpar_pci_add_bus(dn); + dlpar_pci_add_bus(dn); + + /* Confirm new bridge dev was created */ + phb = PCI_DN(dn)->phb; + dev = dlpar_find_new_dev(phb->bus, dn); + if (!dev) { printk(KERN_ERR "%s: unable to add bus %s\n", __FUNCTION__, drc_name); return -EIO; } + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { + printk(KERN_ERR "%s: unexpected header type %d, unable to add bus %s\n", + __FUNCTION__, dev->hdr_type, drc_name); + return -EIO; + } + /* Add hotplug slot */ if (rpaphp_add_slot(dn)) { printk(KERN_ERR "%s: unable to add hotplug slot %s\n", From 877be3f0304de16a77f11b2b47f1291b800d5479 Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Wed, 18 Jan 2006 21:12:57 -0500 Subject: [PATCH 22/23] [PATCH] PCI: cyblafb: remove pci_module_init() return, really. Richard Knutsson did the original pci_module_init() cleanups: http://marc.theaimsgroup.com/?l=linux-kernel&m=113330872125068&w=2 http://marc.theaimsgroup.com/?l=linux-kernel&m=113330888507321&w=2 Greg, on it's way upstream, pci_module_init() return sneaked back in for cyblafb? http://marc.theaimsgroup.com/?l=linux-pci&m=113652969209562&w=2 http://marc.theaimsgroup.com/?l=linux-pci&m=113683930220421&w=2 Remove for good. Signed-off-by: Arthur Othieno Signed-off-by: Greg Kroah-Hartman --- drivers/video/cyblafb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c index 2b972461a030..0ae0a97b0fed 100644 --- a/drivers/video/cyblafb.c +++ b/drivers/video/cyblafb.c @@ -1665,7 +1665,6 @@ static int __devinit cyblafb_init(void) } #endif output("CyblaFB version %s initializing\n", VERSION); - return pci_module_init(&cyblafb_pci_driver); return pci_register_driver(&cyblafb_pci_driver); } From 3103039cc2a8dc6ababc29afac5c3cadbfa69af9 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 27 Jan 2006 02:03:50 +0100 Subject: [PATCH 23/23] [PATCH] PCI: handle bogus MCFG entries Handle more bogus MCFG entries Some Asus P4 boards seem to have broken MCFG tables with only a single entry for busses 0-0. Special case these and assume they mean all busses can be accessed. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/mmconfig.c | 15 +++++++++++++-- arch/x86_64/pci/mmconfig.c | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 4bb4d4b0f73a..0ee8a983708c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) { - /* Not found - fallback to type 1 */ - return 0; + break; } cfg = &pci_mmcfg_config[cfg_num]; if (cfg->pci_segment_group_number != seg) @@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) (cfg->end_bus_number >= bus)) return cfg->base_address; } + + /* Handle more broken MCFG tables on Asus etc. + They only contain a single entry for bus 0-0. Assume + this applies to all busses. */ + cfg = &pci_mmcfg_config[0]; + if (pci_mmcfg_config_num == 1 && + cfg->pci_segment_group_number == 0 && + (cfg->start_bus_number | cfg->end_bus_number) == 0) + return cfg->base_address; + + /* Fall back to type 0 */ + return 0; } static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index f16c0d57c552..00d4ddbf980c 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -29,11 +29,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) while (1) { ++cfg_num; - if (cfg_num >= pci_mmcfg_config_num) { - /* Not found - fall back to type 1. This happens - e.g. on the internal devices of a K8 northbridge. */ - return NULL; - } + if (cfg_num >= pci_mmcfg_config_num) + break; cfg = pci_mmcfg_virt[cfg_num].cfg; if (cfg->pci_segment_group_number != seg) continue; @@ -41,6 +38,18 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) (cfg->end_bus_number >= bus)) return pci_mmcfg_virt[cfg_num].virt; } + + /* Handle more broken MCFG tables on Asus etc. + They only contain a single entry for bus 0-0. Assume + this applies to all busses. */ + cfg = &pci_mmcfg_config[0]; + if (pci_mmcfg_config_num == 1 && + cfg->pci_segment_group_number == 0 && + (cfg->start_bus_number | cfg->end_bus_number) == 0) + return cfg->base_address; + + /* Fall back to type 0 */ + return 0; } static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)