diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-13 10:27:32 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-13 10:27:32 +0000 |
commit | 7371b8e3bf96f28003582afb5f76182b7a9c4062 (patch) | |
tree | f2780b6029998e080850e96e6e67ca4fe60fd51c /pci | |
parent | 1b558141db8b06c61edebaaf5e3394ed98540ac7 (diff) | |
download | patches-7371b8e3bf96f28003582afb5f76182b7a9c4062.tar.gz |
refresh for 2.6.16-rc6
Diffstat (limited to 'pci')
-rw-r--r-- | pci/acpiphp-add-dock-event-handling.patch | 24 | ||||
-rw-r--r-- | pci/altix-msi-support.patch | 386 | ||||
-rw-r--r-- | pci/msi-vector-targeting-abstractions.patch | 520 | ||||
-rw-r--r-- | pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch | 72 | ||||
-rw-r--r-- | pci/pci-msi-save-restore-for-suspend-resume.patch | 200 | ||||
-rw-r--r-- | pci/per-platform-ia64_-first-last-_device_vector-definitions.patch | 46 | ||||
-rw-r--r-- | pci/shpchp-cleanup-check-command-status.patch | 142 | ||||
-rw-r--r-- | pci/shpchp-event-handling-rework.patch | 414 |
8 files changed, 902 insertions, 902 deletions
diff --git a/pci/acpiphp-add-dock-event-handling.patch b/pci/acpiphp-add-dock-event-handling.patch index 064b4d117ab57..1cbbeccd6ead0 100644 --- a/pci/acpiphp-add-dock-event-handling.patch +++ b/pci/acpiphp-add-dock-event-handling.patch @@ -33,6 +33,18 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/pci/hotplug/acpiphp_glue.c | 85 +++++-- 5 files changed, 545 insertions(+), 24 deletions(-) +--- gregkh-2.6.orig/drivers/pci/hotplug/Makefile ++++ gregkh-2.6/drivers/pci/hotplug/Makefile +@@ -37,7 +37,8 @@ ibmphp-objs := ibmphp_core.o \ + ibmphp_hpc.o + + acpiphp-objs := acpiphp_core.o \ +- acpiphp_glue.o ++ acpiphp_glue.o \ ++ acpiphp_dock.o + + rpaphp-objs := rpaphp_core.o \ + rpaphp_pci.o \ --- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h +++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h @@ -161,6 +161,25 @@ struct acpiphp_attention_info @@ -735,15 +747,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { struct acpiphp_func *func; char objname[64]; ---- gregkh-2.6.orig/drivers/pci/hotplug/Makefile -+++ gregkh-2.6/drivers/pci/hotplug/Makefile -@@ -37,7 +37,8 @@ ibmphp-objs := ibmphp_core.o \ - ibmphp_hpc.o - - acpiphp-objs := acpiphp_core.o \ -- acpiphp_glue.o -+ acpiphp_glue.o \ -+ acpiphp_dock.o - - rpaphp-objs := rpaphp_core.o \ - rpaphp_pci.o \ diff --git a/pci/altix-msi-support.patch b/pci/altix-msi-support.patch index 59f99f217b937..fd92f3340f3ee 100644 --- a/pci/altix-msi-support.patch +++ b/pci/altix-msi-support.patch @@ -25,6 +25,199 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> include/asm-ia64/sn/tiocp.h | 3 11 files changed, 405 insertions(+), 118 deletions(-) +--- gregkh-2.6.orig/arch/ia64/sn/kernel/io_init.c ++++ gregkh-2.6/arch/ia64/sn/kernel/io_init.c +@@ -56,7 +56,7 @@ static int max_pcibus_number = 255; /* D + */ + + static dma_addr_t +-sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size) ++sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) + { + return 0; + } +--- gregkh-2.6.orig/arch/ia64/sn/kernel/irq.c ++++ gregkh-2.6/arch/ia64/sn/kernel/irq.c +@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct s + + int sn_force_interrupt_flag = 1; + extern int sn_ioif_inited; +-static struct list_head **sn_irq_lh; ++struct list_head **sn_irq_lh; + static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ + +-static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, +- u64 sn_irq_info, ++u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, ++ struct sn_irq_info *sn_irq_info, + int req_irq, nasid_t req_nasid, + int req_slice) + { +@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t + + SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, + (u64) SAL_INTR_ALLOC, (u64) local_nasid, +- (u64) local_widget, (u64) sn_irq_info, (u64) req_irq, ++ (u64) local_widget, __pa(sn_irq_info), (u64) req_irq, + (u64) req_nasid, (u64) req_slice); ++ + return ret_stuff.status; + } + +-static inline void sn_intr_free(nasid_t local_nasid, int local_widget, ++void sn_intr_free(nasid_t local_nasid, int local_widget, + struct sn_irq_info *sn_irq_info) + { + struct ia64_sal_retval ret_stuff; +@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq) + + static void sn_irq_info_free(struct rcu_head *head); + +-static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) ++struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, ++ nasid_t nasid, int slice) + { +- struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; +- int cpuid, cpuphys; ++ int vector; ++ int cpuphys; ++ int64_t bridge; ++ int local_widget, status; ++ nasid_t local_nasid; ++ struct sn_irq_info *new_irq_info; ++ struct sn_pcibus_provider *pci_provider; + +- cpuid = first_cpu(mask); +- cpuphys = cpu_physical_id(cpuid); ++ new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); ++ if (new_irq_info == NULL) ++ return NULL; + +- list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, +- sn_irq_lh[irq], list) { +- u64 bridge; +- int local_widget, status; +- nasid_t local_nasid; +- struct sn_irq_info *new_irq_info; +- struct sn_pcibus_provider *pci_provider; +- +- new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); +- if (new_irq_info == NULL) +- break; +- memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); +- +- bridge = (u64) new_irq_info->irq_bridge; +- if (!bridge) { +- kfree(new_irq_info); +- break; /* irq is not a device interrupt */ +- } ++ memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); + +- local_nasid = NASID_GET(bridge); ++ bridge = (u64) new_irq_info->irq_bridge; ++ if (!bridge) { ++ kfree(new_irq_info); ++ return NULL; /* irq is not a device interrupt */ ++ } + +- if (local_nasid & 1) +- local_widget = TIO_SWIN_WIDGETNUM(bridge); +- else +- local_widget = SWIN_WIDGETNUM(bridge); +- +- /* Free the old PROM new_irq_info structure */ +- sn_intr_free(local_nasid, local_widget, new_irq_info); +- /* Update kernels new_irq_info with new target info */ +- unregister_intr_pda(new_irq_info); +- +- /* allocate a new PROM new_irq_info struct */ +- status = sn_intr_alloc(local_nasid, local_widget, +- __pa(new_irq_info), irq, +- cpuid_to_nasid(cpuid), +- cpuid_to_slice(cpuid)); +- +- /* SAL call failed */ +- if (status) { +- kfree(new_irq_info); +- break; +- } ++ local_nasid = NASID_GET(bridge); ++ ++ if (local_nasid & 1) ++ local_widget = TIO_SWIN_WIDGETNUM(bridge); ++ else ++ local_widget = SWIN_WIDGETNUM(bridge); ++ ++ vector = sn_irq_info->irq_irq; ++ /* Free the old PROM new_irq_info structure */ ++ sn_intr_free(local_nasid, local_widget, new_irq_info); ++ /* Update kernels new_irq_info with new target info */ ++ unregister_intr_pda(new_irq_info); ++ ++ /* allocate a new PROM new_irq_info struct */ ++ status = sn_intr_alloc(local_nasid, local_widget, ++ new_irq_info, vector, ++ nasid, slice); ++ ++ /* SAL call failed */ ++ if (status) { ++ kfree(new_irq_info); ++ return NULL; ++ } ++ ++ cpuphys = nasid_slice_to_cpuid(nasid, slice); ++ new_irq_info->irq_cpuid = cpuphys; ++ register_intr_pda(new_irq_info); ++ ++ pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; + +- new_irq_info->irq_cpuid = cpuid; +- register_intr_pda(new_irq_info); ++ /* ++ * If this represents a line interrupt, target it. If it's ++ * an msi (irq_int_bit < 0), it's already targeted. ++ */ ++ if (new_irq_info->irq_int_bit >= 0 && ++ pci_provider && pci_provider->target_interrupt) ++ (pci_provider->target_interrupt)(new_irq_info); + +- pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; +- if (pci_provider && pci_provider->target_interrupt) +- (pci_provider->target_interrupt)(new_irq_info); +- +- spin_lock(&sn_irq_info_lock); +- list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); +- spin_unlock(&sn_irq_info_lock); +- call_rcu(&sn_irq_info->rcu, sn_irq_info_free); ++ spin_lock(&sn_irq_info_lock); ++ list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); ++ spin_unlock(&sn_irq_info_lock); ++ call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + + #ifdef CONFIG_SMP +- set_irq_affinity_info((irq & 0xff), cpuphys, 0); ++ set_irq_affinity_info((vector & 0xff), cpuphys, 0); + #endif +- } ++ ++ return new_irq_info; ++} ++ ++static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) ++{ ++ struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; ++ nasid_t nasid; ++ int slice; ++ ++ nasid = cpuid_to_nasid(first_cpu(mask)); ++ slice = cpuid_to_slice(first_cpu(mask)); ++ ++ list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, ++ sn_irq_lh[irq], list) ++ (void)sn_retarget_vector(sn_irq_info, nasid, slice); + } + + struct hw_interrupt_type irq_type_sn = { --- gregkh-2.6.orig/arch/ia64/sn/pci/msi.c +++ gregkh-2.6/arch/ia64/sn/pci/msi.c @@ -6,13 +6,205 @@ @@ -237,199 +430,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + msi_register(&sn_msi_ops); + return 0; } ---- gregkh-2.6.orig/arch/ia64/sn/kernel/io_init.c -+++ gregkh-2.6/arch/ia64/sn/kernel/io_init.c -@@ -56,7 +56,7 @@ static int max_pcibus_number = 255; /* D - */ - - static dma_addr_t --sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size) -+sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) - { - return 0; - } ---- gregkh-2.6.orig/arch/ia64/sn/kernel/irq.c -+++ gregkh-2.6/arch/ia64/sn/kernel/irq.c -@@ -26,11 +26,11 @@ static void unregister_intr_pda(struct s - - int sn_force_interrupt_flag = 1; - extern int sn_ioif_inited; --static struct list_head **sn_irq_lh; -+struct list_head **sn_irq_lh; - static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ - --static inline u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, -- u64 sn_irq_info, -+u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, -+ struct sn_irq_info *sn_irq_info, - int req_irq, nasid_t req_nasid, - int req_slice) - { -@@ -40,12 +40,13 @@ static inline u64 sn_intr_alloc(nasid_t - - SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, - (u64) SAL_INTR_ALLOC, (u64) local_nasid, -- (u64) local_widget, (u64) sn_irq_info, (u64) req_irq, -+ (u64) local_widget, __pa(sn_irq_info), (u64) req_irq, - (u64) req_nasid, (u64) req_slice); -+ - return ret_stuff.status; - } - --static inline void sn_intr_free(nasid_t local_nasid, int local_widget, -+void sn_intr_free(nasid_t local_nasid, int local_widget, - struct sn_irq_info *sn_irq_info) - { - struct ia64_sal_retval ret_stuff; -@@ -112,73 +113,91 @@ static void sn_end_irq(unsigned int irq) - - static void sn_irq_info_free(struct rcu_head *head); - --static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) -+struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, -+ nasid_t nasid, int slice) - { -- struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; -- int cpuid, cpuphys; -+ int vector; -+ int cpuphys; -+ int64_t bridge; -+ int local_widget, status; -+ nasid_t local_nasid; -+ struct sn_irq_info *new_irq_info; -+ struct sn_pcibus_provider *pci_provider; - -- cpuid = first_cpu(mask); -- cpuphys = cpu_physical_id(cpuid); -+ new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); -+ if (new_irq_info == NULL) -+ return NULL; - -- list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, -- sn_irq_lh[irq], list) { -- u64 bridge; -- int local_widget, status; -- nasid_t local_nasid; -- struct sn_irq_info *new_irq_info; -- struct sn_pcibus_provider *pci_provider; -- -- new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); -- if (new_irq_info == NULL) -- break; -- memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); -- -- bridge = (u64) new_irq_info->irq_bridge; -- if (!bridge) { -- kfree(new_irq_info); -- break; /* irq is not a device interrupt */ -- } -+ memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); - -- local_nasid = NASID_GET(bridge); -+ bridge = (u64) new_irq_info->irq_bridge; -+ if (!bridge) { -+ kfree(new_irq_info); -+ return NULL; /* irq is not a device interrupt */ -+ } - -- if (local_nasid & 1) -- local_widget = TIO_SWIN_WIDGETNUM(bridge); -- else -- local_widget = SWIN_WIDGETNUM(bridge); -- -- /* Free the old PROM new_irq_info structure */ -- sn_intr_free(local_nasid, local_widget, new_irq_info); -- /* Update kernels new_irq_info with new target info */ -- unregister_intr_pda(new_irq_info); -- -- /* allocate a new PROM new_irq_info struct */ -- status = sn_intr_alloc(local_nasid, local_widget, -- __pa(new_irq_info), irq, -- cpuid_to_nasid(cpuid), -- cpuid_to_slice(cpuid)); -- -- /* SAL call failed */ -- if (status) { -- kfree(new_irq_info); -- break; -- } -+ local_nasid = NASID_GET(bridge); -+ -+ if (local_nasid & 1) -+ local_widget = TIO_SWIN_WIDGETNUM(bridge); -+ else -+ local_widget = SWIN_WIDGETNUM(bridge); -+ -+ vector = sn_irq_info->irq_irq; -+ /* Free the old PROM new_irq_info structure */ -+ sn_intr_free(local_nasid, local_widget, new_irq_info); -+ /* Update kernels new_irq_info with new target info */ -+ unregister_intr_pda(new_irq_info); -+ -+ /* allocate a new PROM new_irq_info struct */ -+ status = sn_intr_alloc(local_nasid, local_widget, -+ new_irq_info, vector, -+ nasid, slice); -+ -+ /* SAL call failed */ -+ if (status) { -+ kfree(new_irq_info); -+ return NULL; -+ } -+ -+ cpuphys = nasid_slice_to_cpuid(nasid, slice); -+ new_irq_info->irq_cpuid = cpuphys; -+ register_intr_pda(new_irq_info); -+ -+ pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; - -- new_irq_info->irq_cpuid = cpuid; -- register_intr_pda(new_irq_info); -+ /* -+ * If this represents a line interrupt, target it. If it's -+ * an msi (irq_int_bit < 0), it's already targeted. -+ */ -+ if (new_irq_info->irq_int_bit >= 0 && -+ pci_provider && pci_provider->target_interrupt) -+ (pci_provider->target_interrupt)(new_irq_info); - -- pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; -- if (pci_provider && pci_provider->target_interrupt) -- (pci_provider->target_interrupt)(new_irq_info); -- -- spin_lock(&sn_irq_info_lock); -- list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); -- spin_unlock(&sn_irq_info_lock); -- call_rcu(&sn_irq_info->rcu, sn_irq_info_free); -+ spin_lock(&sn_irq_info_lock); -+ list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); -+ spin_unlock(&sn_irq_info_lock); -+ call_rcu(&sn_irq_info->rcu, sn_irq_info_free); - - #ifdef CONFIG_SMP -- set_irq_affinity_info((irq & 0xff), cpuphys, 0); -+ set_irq_affinity_info((vector & 0xff), cpuphys, 0); - #endif -- } -+ -+ return new_irq_info; -+} -+ -+static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) -+{ -+ struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; -+ nasid_t nasid; -+ int slice; -+ -+ nasid = cpuid_to_nasid(first_cpu(mask)); -+ slice = cpuid_to_slice(first_cpu(mask)); -+ -+ list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, -+ sn_irq_lh[irq], list) -+ (void)sn_retarget_vector(sn_irq_info, nasid, slice); - } - - struct hw_interrupt_type irq_type_sn = { --- gregkh-2.6.orig/arch/ia64/sn/pci/pci_dma.c +++ gregkh-2.6/arch/ia64/sn/pci/pci_dma.c @@ -11,7 +11,7 @@ diff --git a/pci/msi-vector-targeting-abstractions.patch b/pci/msi-vector-targeting-abstractions.patch index 9dba47ff61eb7..158129efa562e 100644 --- a/pci/msi-vector-targeting-abstractions.patch +++ b/pci/msi-vector-targeting-abstractions.patch @@ -28,6 +28,148 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> include/asm-x86_64/msi.h | 8 ++ 12 files changed, 300 insertions(+), 129 deletions(-) +--- gregkh-2.6.orig/arch/ia64/sn/pci/Makefile ++++ gregkh-2.6/arch/ia64/sn/pci/Makefile +@@ -3,10 +3,11 @@ + # License. See the file "COPYING" in the main directory of this archive + # for more details. + # +-# Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. ++# Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + # + # Makefile for the sn pci general routines. + + CPPFLAGS += -I$(srctree)/arch/ia64/sn/include + + obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ ++obj-$(CONFIG_PCI_MSI) += msi.o +--- /dev/null ++++ gregkh-2.6/arch/ia64/sn/pci/msi.c +@@ -0,0 +1,18 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. ++ */ ++ ++#include <asm/errno.h> ++ ++int ++sn_msi_init(void) ++{ ++ /* ++ * return error until MSI is supported on altix platforms ++ */ ++ return -EINVAL; ++} +--- gregkh-2.6.orig/drivers/pci/Makefile ++++ gregkh-2.6/drivers/pci/Makefile +@@ -26,7 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o + obj-$(CONFIG_PPC64) += setup-bus.o + obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o + obj-$(CONFIG_X86_VISWS) += setup-irq.o +-obj-$(CONFIG_PCI_MSI) += msi.o ++obj-$(CONFIG_PCI_MSI) += msi.o msi-apic.o + + # + # ACPI Related PCI FW Functions +--- /dev/null ++++ gregkh-2.6/drivers/pci/msi-apic.c +@@ -0,0 +1,92 @@ ++/* ++ * MSI hooks for standard x86 apic ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. ++ */ ++ ++#include <linux/pci.h> ++#include <linux/irq.h> ++ ++#include "pci.h" ++#include "msi.h" ++ ++/* Shifts for APIC-based data */ ++#define MSI_DATA_VECTOR_SHIFT 0 ++#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) ++ ++#define MSI_DATA_DELIVERY_SHIFT 8 ++#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) ++#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT) ++ ++#define MSI_DATA_LEVEL_SHIFT 14 ++#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) ++#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) ++ ++#define MSI_DATA_TRIGGER_SHIFT 15 ++#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) ++#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) ++ ++/* Shift/mask fields for APIC-based bus address */ ++#define MSI_ADDR_HEADER 0xfee00000 ++ ++#define MSI_ADDR_DESTID_MASK 0xfff0000f ++#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT) ++ ++#define MSI_ADDR_DESTMODE_SHIFT 2 ++#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT) ++#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT) ++ ++#define MSI_ADDR_REDIRECTION_SHIFT 3 ++#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) ++#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) ++ ++ ++static void msi_target_apic(unsigned int vector, unsigned int dest_cpu, ++ u32 *address_hi, u32 *address_lo) ++{ ++ u32 addr = *address_lo; ++ ++ addr &= MSI_ADDR_DESTID_MASK; ++ addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu)); ++ ++ *address_lo = addr; ++} ++ ++static int msi_setup_apic(struct pci_dev *pdev, unsigned int vector, ++ u32 *address_hi, u32 *address_lo, u32 *data) ++{ ++ unsigned long dest_phys_id; ++ ++ dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); ++ ++ *address_hi = 0; ++ *address_lo = MSI_ADDR_HEADER | ++ MSI_ADDR_DESTMODE_PHYS | ++ MSI_ADDR_REDIRECTION_CPU | ++ MSI_ADDR_DESTID_CPU(dest_phys_id); ++ ++ *data = MSI_DATA_TRIGGER_EDGE | ++ MSI_DATA_LEVEL_ASSERT | ++ MSI_DATA_DELIVERY_FIXED | ++ MSI_DATA_VECTOR(vector); ++ ++ return 0; ++} ++ ++static void msi_teardown_apic(unsigned int vector) ++{ ++ return; ++} ++ ++/* ++ * Generic ops used on most IA archs/platforms. Set with msi_register() ++ */ ++struct msi_ops msi_apic_ops = { ++ .setup = msi_setup_apic, ++ .teardown = msi_teardown_apic, ++ .target = msi_target_apic, ++}; --- gregkh-2.6.orig/drivers/pci/msi.c +++ gregkh-2.6/drivers/pci/msi.c @@ -23,8 +23,6 @@ @@ -276,266 +418,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[vector]; if (!entry || entry->dev != dev) { ---- gregkh-2.6.orig/include/asm-i386/msi.h -+++ gregkh-2.6/include/asm-i386/msi.h -@@ -12,4 +12,12 @@ - #define LAST_DEVICE_VECTOR 232 - #define MSI_TARGET_CPU_SHIFT 12 - -+extern struct msi_ops msi_apic_ops; -+ -+static inline int msi_arch_init(void) -+{ -+ msi_register(&msi_apic_ops); -+ return 0; -+} -+ - #endif /* ASM_MSI_H */ ---- gregkh-2.6.orig/include/asm-x86_64/msi.h -+++ gregkh-2.6/include/asm-x86_64/msi.h -@@ -13,4 +13,12 @@ - #define LAST_DEVICE_VECTOR 232 - #define MSI_TARGET_CPU_SHIFT 12 - -+extern struct msi_ops msi_apic_ops; -+ -+static inline int msi_arch_init(void) -+{ -+ msi_register(&msi_apic_ops); -+ return 0; -+} -+ - #endif /* ASM_MSI_H */ ---- gregkh-2.6.orig/include/asm-ia64/machvec.h -+++ gregkh-2.6/include/asm-ia64/machvec.h -@@ -74,6 +74,7 @@ typedef unsigned char ia64_mv_readb_rela - typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); - typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); - typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); -+typedef int ia64_mv_msi_init_t (void); - - static inline void - machvec_noop (void) -@@ -146,6 +147,7 @@ extern void machvec_tlb_migrate_finish ( - # define platform_readw_relaxed ia64_mv.readw_relaxed - # define platform_readl_relaxed ia64_mv.readl_relaxed - # define platform_readq_relaxed ia64_mv.readq_relaxed -+# define platform_msi_init ia64_mv.msi_init - # endif - - /* __attribute__((__aligned__(16))) is required to make size of the -@@ -194,6 +196,7 @@ struct ia64_machine_vector { - ia64_mv_readw_relaxed_t *readw_relaxed; - ia64_mv_readl_relaxed_t *readl_relaxed; - ia64_mv_readq_relaxed_t *readq_relaxed; -+ ia64_mv_msi_init_t *msi_init; - } __attribute__((__aligned__(16))); /* align attrib? see above comment */ - - #define MACHVEC_INIT(name) \ -@@ -238,6 +241,7 @@ struct ia64_machine_vector { - platform_readw_relaxed, \ - platform_readl_relaxed, \ - platform_readq_relaxed, \ -+ platform_msi_init, \ - } - - extern struct ia64_machine_vector ia64_mv; -@@ -386,5 +390,13 @@ extern ia64_mv_dma_supported swiotlb_dm - #ifndef platform_readq_relaxed - # define platform_readq_relaxed __ia64_readq_relaxed - #endif -+#ifndef platform_msi_init -+#ifdef CONFIG_PCI_MSI -+#include <asm/msi.h> /* pull in ia64_msi_init() */ -+# define platform_msi_init ia64_msi_init -+#else -+# define platform_msi_init NULL -+#endif /* CONFIG_PCI_MSI */ -+#endif - - #endif /* _ASM_IA64_MACHVEC_H */ ---- gregkh-2.6.orig/include/asm-ia64/machvec_sn2.h -+++ gregkh-2.6/include/asm-ia64/machvec_sn2.h -@@ -66,6 +66,7 @@ extern ia64_mv_dma_sync_single_for_devic - extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; - extern ia64_mv_dma_mapping_error sn_dma_mapping_error; - extern ia64_mv_dma_supported sn_dma_supported; -+extern ia64_mv_msi_init_t sn_msi_init; - - /* - * This stuff has dual use! -@@ -115,6 +116,11 @@ extern ia64_mv_dma_supported sn_dma_sup - #define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device - #define platform_dma_mapping_error sn_dma_mapping_error - #define platform_dma_supported sn_dma_supported -+#ifdef CONFIG_PCI_MSI -+#define platform_msi_init sn_msi_init -+#else -+#define platform_msi_init NULL -+#endif - - #include <asm/sn/io.h> - ---- gregkh-2.6.orig/include/asm-ia64/msi.h -+++ gregkh-2.6/include/asm-ia64/msi.h -@@ -14,4 +14,15 @@ static inline void set_intr_gate (int nr - #define ack_APIC_irq ia64_eoi - #define MSI_TARGET_CPU_SHIFT 4 - -+extern struct msi_ops msi_apic_ops; -+ -+/* default ia64 msi init routine */ -+static inline int ia64_msi_init(void) -+{ -+ msi_register(&msi_apic_ops); -+ return 0; -+} -+ -+#define msi_arch_init platform_msi_init /* in asm/machvec.h */ -+ - #endif /* ASM_MSI_H */ ---- gregkh-2.6.orig/arch/ia64/sn/pci/Makefile -+++ gregkh-2.6/arch/ia64/sn/pci/Makefile -@@ -3,10 +3,11 @@ - # License. See the file "COPYING" in the main directory of this archive - # for more details. - # --# Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. -+# Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - # - # Makefile for the sn pci general routines. - - CPPFLAGS += -I$(srctree)/arch/ia64/sn/include - - obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ -+obj-$(CONFIG_PCI_MSI) += msi.o ---- /dev/null -+++ gregkh-2.6/arch/ia64/sn/pci/msi.c -@@ -0,0 +1,18 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. -+ */ -+ -+#include <asm/errno.h> -+ -+int -+sn_msi_init(void) -+{ -+ /* -+ * return error until MSI is supported on altix platforms -+ */ -+ return -EINVAL; -+} ---- gregkh-2.6.orig/drivers/pci/Makefile -+++ gregkh-2.6/drivers/pci/Makefile -@@ -26,7 +26,7 @@ obj-$(CONFIG_PPC32) += setup-irq.o - obj-$(CONFIG_PPC64) += setup-bus.o - obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o - obj-$(CONFIG_X86_VISWS) += setup-irq.o --obj-$(CONFIG_PCI_MSI) += msi.o -+obj-$(CONFIG_PCI_MSI) += msi.o msi-apic.o - - # - # ACPI Related PCI FW Functions ---- /dev/null -+++ gregkh-2.6/drivers/pci/msi-apic.c -@@ -0,0 +1,92 @@ -+/* -+ * MSI hooks for standard x86 apic -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. -+ */ -+ -+#include <linux/pci.h> -+#include <linux/irq.h> -+ -+#include "pci.h" -+#include "msi.h" -+ -+/* Shifts for APIC-based data */ -+#define MSI_DATA_VECTOR_SHIFT 0 -+#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT) -+ -+#define MSI_DATA_DELIVERY_SHIFT 8 -+#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT) -+#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT) -+ -+#define MSI_DATA_LEVEL_SHIFT 14 -+#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT) -+#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT) -+ -+#define MSI_DATA_TRIGGER_SHIFT 15 -+#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT) -+#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT) -+ -+/* Shift/mask fields for APIC-based bus address */ -+#define MSI_ADDR_HEADER 0xfee00000 -+ -+#define MSI_ADDR_DESTID_MASK 0xfff0000f -+#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT) -+ -+#define MSI_ADDR_DESTMODE_SHIFT 2 -+#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT) -+#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT) -+ -+#define MSI_ADDR_REDIRECTION_SHIFT 3 -+#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) -+#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) -+ -+ -+static void msi_target_apic(unsigned int vector, unsigned int dest_cpu, -+ u32 *address_hi, u32 *address_lo) -+{ -+ u32 addr = *address_lo; -+ -+ addr &= MSI_ADDR_DESTID_MASK; -+ addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu)); -+ -+ *address_lo = addr; -+} -+ -+static int msi_setup_apic(struct pci_dev *pdev, unsigned int vector, -+ u32 *address_hi, u32 *address_lo, u32 *data) -+{ -+ unsigned long dest_phys_id; -+ -+ dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); -+ -+ *address_hi = 0; -+ *address_lo = MSI_ADDR_HEADER | -+ MSI_ADDR_DESTMODE_PHYS | -+ MSI_ADDR_REDIRECTION_CPU | -+ MSI_ADDR_DESTID_CPU(dest_phys_id); -+ -+ *data = MSI_DATA_TRIGGER_EDGE | -+ MSI_DATA_LEVEL_ASSERT | -+ MSI_DATA_DELIVERY_FIXED | -+ MSI_DATA_VECTOR(vector); -+ -+ return 0; -+} -+ -+static void msi_teardown_apic(unsigned int vector) -+{ -+ return; -+} -+ -+/* -+ * Generic ops used on most IA archs/platforms. Set with msi_register() -+ */ -+struct msi_ops msi_apic_ops = { -+ .setup = msi_setup_apic, -+ .teardown = msi_teardown_apic, -+ .target = msi_target_apic, -+}; --- gregkh-2.6.orig/drivers/pci/msi.h +++ gregkh-2.6/drivers/pci/msi.h @@ -63,67 +63,6 @@ extern int pci_vector_resources(int last @@ -693,3 +575,121 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> #endif extern int pcie_mch_quirk; +--- gregkh-2.6.orig/include/asm-i386/msi.h ++++ gregkh-2.6/include/asm-i386/msi.h +@@ -12,4 +12,12 @@ + #define LAST_DEVICE_VECTOR 232 + #define MSI_TARGET_CPU_SHIFT 12 + ++extern struct msi_ops msi_apic_ops; ++ ++static inline int msi_arch_init(void) ++{ ++ msi_register(&msi_apic_ops); ++ return 0; ++} ++ + #endif /* ASM_MSI_H */ +--- gregkh-2.6.orig/include/asm-ia64/machvec.h ++++ gregkh-2.6/include/asm-ia64/machvec.h +@@ -74,6 +74,7 @@ typedef unsigned char ia64_mv_readb_rela + typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); + typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); + typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); ++typedef int ia64_mv_msi_init_t (void); + + static inline void + machvec_noop (void) +@@ -146,6 +147,7 @@ extern void machvec_tlb_migrate_finish ( + # define platform_readw_relaxed ia64_mv.readw_relaxed + # define platform_readl_relaxed ia64_mv.readl_relaxed + # define platform_readq_relaxed ia64_mv.readq_relaxed ++# define platform_msi_init ia64_mv.msi_init + # endif + + /* __attribute__((__aligned__(16))) is required to make size of the +@@ -194,6 +196,7 @@ struct ia64_machine_vector { + ia64_mv_readw_relaxed_t *readw_relaxed; + ia64_mv_readl_relaxed_t *readl_relaxed; + ia64_mv_readq_relaxed_t *readq_relaxed; ++ ia64_mv_msi_init_t *msi_init; + } __attribute__((__aligned__(16))); /* align attrib? see above comment */ + + #define MACHVEC_INIT(name) \ +@@ -238,6 +241,7 @@ struct ia64_machine_vector { + platform_readw_relaxed, \ + platform_readl_relaxed, \ + platform_readq_relaxed, \ ++ platform_msi_init, \ + } + + extern struct ia64_machine_vector ia64_mv; +@@ -386,5 +390,13 @@ extern ia64_mv_dma_supported swiotlb_dm + #ifndef platform_readq_relaxed + # define platform_readq_relaxed __ia64_readq_relaxed + #endif ++#ifndef platform_msi_init ++#ifdef CONFIG_PCI_MSI ++#include <asm/msi.h> /* pull in ia64_msi_init() */ ++# define platform_msi_init ia64_msi_init ++#else ++# define platform_msi_init NULL ++#endif /* CONFIG_PCI_MSI */ ++#endif + + #endif /* _ASM_IA64_MACHVEC_H */ +--- gregkh-2.6.orig/include/asm-ia64/machvec_sn2.h ++++ gregkh-2.6/include/asm-ia64/machvec_sn2.h +@@ -66,6 +66,7 @@ extern ia64_mv_dma_sync_single_for_devic + extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; + extern ia64_mv_dma_mapping_error sn_dma_mapping_error; + extern ia64_mv_dma_supported sn_dma_supported; ++extern ia64_mv_msi_init_t sn_msi_init; + + /* + * This stuff has dual use! +@@ -115,6 +116,11 @@ extern ia64_mv_dma_supported sn_dma_sup + #define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device + #define platform_dma_mapping_error sn_dma_mapping_error + #define platform_dma_supported sn_dma_supported ++#ifdef CONFIG_PCI_MSI ++#define platform_msi_init sn_msi_init ++#else ++#define platform_msi_init NULL ++#endif + + #include <asm/sn/io.h> + +--- gregkh-2.6.orig/include/asm-ia64/msi.h ++++ gregkh-2.6/include/asm-ia64/msi.h +@@ -14,4 +14,15 @@ static inline void set_intr_gate (int nr + #define ack_APIC_irq ia64_eoi + #define MSI_TARGET_CPU_SHIFT 4 + ++extern struct msi_ops msi_apic_ops; ++ ++/* default ia64 msi init routine */ ++static inline int ia64_msi_init(void) ++{ ++ msi_register(&msi_apic_ops); ++ return 0; ++} ++ ++#define msi_arch_init platform_msi_init /* in asm/machvec.h */ ++ + #endif /* ASM_MSI_H */ +--- gregkh-2.6.orig/include/asm-x86_64/msi.h ++++ gregkh-2.6/include/asm-x86_64/msi.h +@@ -13,4 +13,12 @@ + #define LAST_DEVICE_VECTOR 232 + #define MSI_TARGET_CPU_SHIFT 12 + ++extern struct msi_ops msi_apic_ops; ++ ++static inline int msi_arch_init(void) ++{ ++ msi_register(&msi_apic_ops); ++ return 0; ++} ++ + #endif /* ASM_MSI_H */ diff --git a/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch b/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch index 6598904477ebb..28586405592ee 100644 --- a/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch +++ b/pci/pci-give-pci-config-access-initialization-a-defined-ordering.patch @@ -29,6 +29,14 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> arch/x86_64/pci/Makefile | 3 ++- 7 files changed, 40 insertions(+), 23 deletions(-) +--- gregkh-2.6.orig/arch/i386/pci/Makefile ++++ gregkh-2.6/arch/i386/pci/Makefile +@@ -1,4 +1,4 @@ +-obj-y := i386.o ++obj-y := i386.o init.o + + obj-$(CONFIG_PCI_BIOS) += pcbios.o + obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o --- gregkh-2.6.orig/arch/i386/pci/direct.c +++ gregkh-2.6/arch/i386/pci/direct.c @@ -245,7 +245,7 @@ static int __init pci_check_type2(void) @@ -77,6 +85,34 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } - -arch_initcall(pci_direct_init); +--- /dev/null ++++ gregkh-2.6/arch/i386/pci/init.c +@@ -0,0 +1,25 @@ ++#include <linux/config.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include "pci.h" ++ ++/* arch_initcall has too random ordering, so call the initializers ++ in the right sequence from here. */ ++static __init int pci_access_init(void) ++{ ++#ifdef CONFIG_PCI_MMCONFIG ++ pci_mmcfg_init(); ++#endif ++ if (raw_pci_ops) ++ return 0; ++#ifdef CONFIG_PCI_DIRECT ++ pci_direct_init(); ++#endif ++ if (raw_pci_ops) ++ return 0; ++#ifdef CONFIG_PCI_BIOS ++ pci_pcbios_init(); ++#endif ++ return 0; ++} ++arch_initcall(pci_access_init); --- gregkh-2.6.orig/arch/i386/pci/mmconfig.c +++ gregkh-2.6/arch/i386/pci/mmconfig.c @@ -172,25 +172,20 @@ static __init void unreachable_devices(v @@ -152,39 +188,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> fixup-y += ../../i386/pci/fixup.o i386-y += ../../i386/pci/i386.o +init-y += ../../i386/pci/init.o ---- /dev/null -+++ gregkh-2.6/arch/i386/pci/init.c -@@ -0,0 +1,25 @@ -+#include <linux/config.h> -+#include <linux/pci.h> -+#include <linux/init.h> -+#include "pci.h" -+ -+/* arch_initcall has too random ordering, so call the initializers -+ in the right sequence from here. */ -+static __init int pci_access_init(void) -+{ -+#ifdef CONFIG_PCI_MMCONFIG -+ pci_mmcfg_init(); -+#endif -+ if (raw_pci_ops) -+ return 0; -+#ifdef CONFIG_PCI_DIRECT -+ pci_direct_init(); -+#endif -+ if (raw_pci_ops) -+ return 0; -+#ifdef CONFIG_PCI_BIOS -+ pci_pcbios_init(); -+#endif -+ return 0; -+} -+arch_initcall(pci_access_init); ---- gregkh-2.6.orig/arch/i386/pci/Makefile -+++ gregkh-2.6/arch/i386/pci/Makefile -@@ -1,4 +1,4 @@ --obj-y := i386.o -+obj-y := i386.o init.o - - obj-$(CONFIG_PCI_BIOS) += pcbios.o - obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o diff --git a/pci/pci-msi-save-restore-for-suspend-resume.patch b/pci/pci-msi-save-restore-for-suspend-resume.patch index acf089517e216..0bb2d18c0ba47 100644 --- a/pci/pci-msi-save-restore-for-suspend-resume.patch +++ b/pci/pci-msi-save-restore-for-suspend-resume.patch @@ -17,106 +17,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> include/linux/pci.h | 31 ++++++ 4 files changed, 282 insertions(+), 31 deletions(-) ---- gregkh-2.6.orig/include/linux/pci.h -+++ gregkh-2.6/include/linux/pci.h -@@ -100,6 +100,12 @@ enum pci_bus_flags { - PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1, - }; - -+struct pci_cap_saved_state { -+ struct hlist_node next; -+ char cap_nr; -+ u32 data[0]; -+}; -+ - /* - * The pci_dev structure is used to describe PCI devices. - */ -@@ -159,6 +165,7 @@ struct pci_dev { - unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ - - u32 saved_config_space[16]; /* config space saved at suspend time */ -+ struct hlist_head saved_cap_space; - struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ - int rom_attr_enabled; /* has display of the rom attribute been enabled? */ - struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ -@@ -169,6 +176,30 @@ struct pci_dev { - #define to_pci_dev(n) container_of(n, struct pci_dev, dev) - #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) - -+static inline struct pci_cap_saved_state *pci_find_saved_cap( -+ struct pci_dev *pci_dev,char cap) -+{ -+ struct pci_cap_saved_state *tmp; -+ struct hlist_node *pos; -+ -+ hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { -+ if (tmp->cap_nr == cap) -+ return tmp; -+ } -+ return NULL; -+} -+ -+static inline void pci_add_saved_cap(struct pci_dev *pci_dev, -+ struct pci_cap_saved_state *new_cap) -+{ -+ hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); -+} -+ -+static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) -+{ -+ hlist_del(&cap->next); -+} -+ - /* - * For PCI devices, the region numbers are assigned this way: - * ---- gregkh-2.6.orig/drivers/pci/pci.h -+++ gregkh-2.6/drivers/pci/pci.h -@@ -57,6 +57,18 @@ static inline void disable_msi_mode(stru - static inline int msi_register(struct msi_ops *ops) { return 0; } - #endif - -+#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) -+int pci_save_msi_state(struct pci_dev *dev); -+int pci_save_msix_state(struct pci_dev *dev); -+int pci_restore_msi_state(struct pci_dev *dev); -+int pci_restore_msix_state(struct pci_dev *dev); -+#else -+static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } -+static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } -+static inline int pci_restore_msi_state(struct pci_dev *dev) { return 0; } -+static inline int pci_restore_msix_state(struct pci_dev *dev) { return 0; } -+#endif -+ - extern int pcie_mch_quirk; - extern struct device_attribute pci_dev_attrs[]; - extern struct class_device_attribute class_device_attr_cpuaffinity; ---- gregkh-2.6.orig/drivers/pci/pci.c -+++ gregkh-2.6/drivers/pci/pci.c -@@ -444,6 +444,11 @@ pci_save_state(struct pci_dev *dev) - /* XXX: 100% dword access ok here? */ - for (i = 0; i < 16; i++) - pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); -+ if ((i = pci_save_msi_state(dev)) != 0) -+ return i; -+ if ((i = pci_save_msix_state(dev)) != 0) -+ return i; -+ - return 0; - } - -@@ -458,6 +463,10 @@ pci_restore_state(struct pci_dev *dev) - - for (i = 0; i < 16; i++) - pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); -+ if ((i = pci_restore_msi_state(dev)) != 0) -+ return i; -+ if ((i = pci_restore_msix_state(dev)) != 0) -+ return i; - return 0; - } - --- gregkh-2.6.orig/drivers/pci/msi.c +++ gregkh-2.6/drivers/pci/msi.c @@ -514,6 +514,221 @@ void pci_scan_msi_device(struct pci_dev @@ -415,3 +315,103 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } spin_unlock_irqrestore(&msi_lock, flags); dev->irq = temp; +--- gregkh-2.6.orig/drivers/pci/pci.c ++++ gregkh-2.6/drivers/pci/pci.c +@@ -444,6 +444,11 @@ pci_save_state(struct pci_dev *dev) + /* XXX: 100% dword access ok here? */ + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); ++ if ((i = pci_save_msi_state(dev)) != 0) ++ return i; ++ if ((i = pci_save_msix_state(dev)) != 0) ++ return i; ++ + return 0; + } + +@@ -458,6 +463,10 @@ pci_restore_state(struct pci_dev *dev) + + for (i = 0; i < 16; i++) + pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); ++ if ((i = pci_restore_msi_state(dev)) != 0) ++ return i; ++ if ((i = pci_restore_msix_state(dev)) != 0) ++ return i; + return 0; + } + +--- gregkh-2.6.orig/drivers/pci/pci.h ++++ gregkh-2.6/drivers/pci/pci.h +@@ -57,6 +57,18 @@ static inline void disable_msi_mode(stru + static inline int msi_register(struct msi_ops *ops) { return 0; } + #endif + ++#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) ++int pci_save_msi_state(struct pci_dev *dev); ++int pci_save_msix_state(struct pci_dev *dev); ++int pci_restore_msi_state(struct pci_dev *dev); ++int pci_restore_msix_state(struct pci_dev *dev); ++#else ++static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } ++static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; } ++static inline int pci_restore_msi_state(struct pci_dev *dev) { return 0; } ++static inline int pci_restore_msix_state(struct pci_dev *dev) { return 0; } ++#endif ++ + extern int pcie_mch_quirk; + extern struct device_attribute pci_dev_attrs[]; + extern struct class_device_attribute class_device_attr_cpuaffinity; +--- gregkh-2.6.orig/include/linux/pci.h ++++ gregkh-2.6/include/linux/pci.h +@@ -100,6 +100,12 @@ enum pci_bus_flags { + PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1, + }; + ++struct pci_cap_saved_state { ++ struct hlist_node next; ++ char cap_nr; ++ u32 data[0]; ++}; ++ + /* + * The pci_dev structure is used to describe PCI devices. + */ +@@ -159,6 +165,7 @@ struct pci_dev { + unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ + + u32 saved_config_space[16]; /* config space saved at suspend time */ ++ struct hlist_head saved_cap_space; + struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ + int rom_attr_enabled; /* has display of the rom attribute been enabled? */ + struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ +@@ -169,6 +176,30 @@ struct pci_dev { + #define to_pci_dev(n) container_of(n, struct pci_dev, dev) + #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) + ++static inline struct pci_cap_saved_state *pci_find_saved_cap( ++ struct pci_dev *pci_dev,char cap) ++{ ++ struct pci_cap_saved_state *tmp; ++ struct hlist_node *pos; ++ ++ hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { ++ if (tmp->cap_nr == cap) ++ return tmp; ++ } ++ return NULL; ++} ++ ++static inline void pci_add_saved_cap(struct pci_dev *pci_dev, ++ struct pci_cap_saved_state *new_cap) ++{ ++ hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); ++} ++ ++static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) ++{ ++ hlist_del(&cap->next); ++} ++ + /* + * For PCI devices, the region numbers are assigned this way: + * diff --git a/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch b/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch index 740294d42f32f..291d35ba08a51 100644 --- a/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch +++ b/pci/per-platform-ia64_-first-last-_device_vector-definitions.patch @@ -96,6 +96,29 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } static inline void +--- gregkh-2.6.orig/drivers/pci/msi.c ++++ gregkh-2.6/drivers/pci/msi.c +@@ -35,7 +35,7 @@ static int nr_msix_devices; + + #ifndef CONFIG_X86_IO_APIC + int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; +-u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; ++u8 irq_vector[NR_IRQ_VECTORS]; + #endif + + static struct msi_ops *msi_ops; +@@ -378,6 +378,11 @@ static int msi_init(void) + printk(KERN_WARNING "PCI: MSI cache init failed\n"); + return status; + } ++ ++#ifndef CONFIG_X86_IO_APIC ++ irq_vector[0] = FIRST_DEVICE_VECTOR; ++#endif ++ + last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); + if (last_alloc_vector < 0) { + pci_msi_enable = 0; --- gregkh-2.6.orig/include/asm-ia64/hw_irq.h +++ gregkh-2.6/include/asm-ia64/hw_irq.h @@ -47,9 +47,19 @@ typedef u8 ia64_vector; @@ -128,26 +151,3 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); ---- gregkh-2.6.orig/drivers/pci/msi.c -+++ gregkh-2.6/drivers/pci/msi.c -@@ -35,7 +35,7 @@ static int nr_msix_devices; - - #ifndef CONFIG_X86_IO_APIC - int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; --u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; -+u8 irq_vector[NR_IRQ_VECTORS]; - #endif - - static struct msi_ops *msi_ops; -@@ -378,6 +378,11 @@ static int msi_init(void) - printk(KERN_WARNING "PCI: MSI cache init failed\n"); - return status; - } -+ -+#ifndef CONFIG_X86_IO_APIC -+ irq_vector[0] = FIRST_DEVICE_VECTOR; -+#endif -+ - last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); - if (last_alloc_vector < 0) { - pci_msi_enable = 0; diff --git a/pci/shpchp-cleanup-check-command-status.patch b/pci/shpchp-cleanup-check-command-status.patch index d8a7a4e22b574..d54b3a7b52350 100644 --- a/pci/shpchp-cleanup-check-command-status.patch +++ b/pci/shpchp-cleanup-check-command-status.patch @@ -28,77 +28,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ ---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c -+++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c -@@ -231,6 +231,7 @@ static spinlock_t list_lock; - static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); - - static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); -+static int hpc_check_cmd_status(struct controller *ctrl); - - /* This is the interrupt polling timeout function. */ - static void int_poll_timeout(unsigned long lphp_ctlr) -@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *s - int i; - - DBG_ENTER_ROUTINE -- -+ -+ mutex_lock(&slot->ctrl->cmd_lock); -+ - if (!php_ctlr) { - err("%s: Invalid HPC controller handle!\n", __FUNCTION__); -- return -1; -+ retval = -EINVAL; -+ goto out; - } - - for (i = 0; i < 10; i++) { -@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *s - if (cmd_status & 0x1) { - /* After 1 sec and and the controller is still busy */ - err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); -- return -1; -+ retval = -EBUSY; -+ goto out; - } - - ++t_slot; -@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *s - * Wait for command completion. - */ - retval = shpc_wait_cmd(slot->ctrl); -+ if (retval) -+ goto out; -+ -+ cmd_status = hpc_check_cmd_status(slot->ctrl); -+ if (cmd_status) { -+ err("%s: Failed to issued command 0x%x (error code = %d)\n", -+ __FUNCTION__, cmd, cmd_status); -+ retval = -EIO; -+ } -+ out: -+ mutex_unlock(&slot->ctrl->cmd_lock); - - DBG_LEAVE_ROUTINE - return retval; -@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { - .green_led_blink = hpc_set_green_led_blink, - - .release_ctlr = hpc_release_ctlr, -- .check_cmd_status = hpc_check_cmd_status, - }; - - inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, -@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, - dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); - - mutex_init(&ctrl->crit_sect); -+ mutex_init(&ctrl->cmd_lock); -+ - /* Setup wait queue */ - init_waitqueue_head(&ctrl->queue); - --- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c +++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c @@ -242,21 +242,10 @@ static int change_bus_speed(struct contr @@ -346,3 +275,74 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } else { /* refresh notification */ if (p_slot) +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c +@@ -231,6 +231,7 @@ static spinlock_t list_lock; + static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); + + static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); ++static int hpc_check_cmd_status(struct controller *ctrl); + + /* This is the interrupt polling timeout function. */ + static void int_poll_timeout(unsigned long lphp_ctlr) +@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *s + int i; + + DBG_ENTER_ROUTINE +- ++ ++ mutex_lock(&slot->ctrl->cmd_lock); ++ + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); +- return -1; ++ retval = -EINVAL; ++ goto out; + } + + for (i = 0; i < 10; i++) { +@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *s + if (cmd_status & 0x1) { + /* After 1 sec and and the controller is still busy */ + err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); +- return -1; ++ retval = -EBUSY; ++ goto out; + } + + ++t_slot; +@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *s + * Wait for command completion. + */ + retval = shpc_wait_cmd(slot->ctrl); ++ if (retval) ++ goto out; ++ ++ cmd_status = hpc_check_cmd_status(slot->ctrl); ++ if (cmd_status) { ++ err("%s: Failed to issued command 0x%x (error code = %d)\n", ++ __FUNCTION__, cmd, cmd_status); ++ retval = -EIO; ++ } ++ out: ++ mutex_unlock(&slot->ctrl->cmd_lock); + + DBG_LEAVE_ROUTINE + return retval; +@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { + .green_led_blink = hpc_set_green_led_blink, + + .release_ctlr = hpc_release_ctlr, +- .check_cmd_status = hpc_check_cmd_status, + }; + + inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, +@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, + dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); + + mutex_init(&ctrl->crit_sect); ++ mutex_init(&ctrl->cmd_lock); ++ + /* Setup wait queue */ + init_waitqueue_head(&ctrl->queue); + diff --git a/pci/shpchp-event-handling-rework.patch b/pci/shpchp-event-handling-rework.patch index c0668a6de18ed..670e496a23ff3 100644 --- a/pci/shpchp-event-handling-rework.patch +++ b/pci/shpchp-event-handling-rework.patch @@ -27,6 +27,213 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/pci/hotplug/shpchp_hpc.c | 10 + 4 files changed, 120 insertions(+), 267 deletions(-) +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -46,6 +46,7 @@ + extern int shpchp_poll_mode; + extern int shpchp_poll_time; + extern int shpchp_debug; ++extern struct workqueue_struct *shpchp_wq; + + /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ + #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) +@@ -70,11 +71,13 @@ struct slot { + struct hotplug_slot *hotplug_slot; + struct list_head slot_list; + char name[SLOT_NAME_SIZE]; ++ struct work_struct work; /* work for button event */ + }; + + struct event_info { + u32 event_type; +- u8 hp_slot; ++ struct slot *p_slot; ++ struct work_struct work; + }; + + struct controller { +@@ -85,11 +88,9 @@ struct controller { + int num_slots; /* Number of slots on ctlr */ + int slot_num_inc; /* 1 or -1 */ + struct pci_dev *pci_dev; +- struct event_info event_queue[10]; + struct list_head slot_list; + struct hpc_ops *hpc_ops; + wait_queue_head_t queue; /* sleep & wake process */ +- u8 next_event; + u8 bus; + u8 device; + u8 function; +@@ -180,9 +181,6 @@ struct hotplug_params { + /* sysfs functions for the hotplug controller info */ + extern void shpchp_create_ctrl_files (struct controller *ctrl); + +-/* controller functions */ +-extern int shpchp_event_start_thread(void); +-extern void shpchp_event_stop_thread(void); + extern int shpchp_enable_slot(struct slot *slot); + extern int shpchp_disable_slot(struct slot *slot); + +@@ -201,7 +199,8 @@ extern void get_hp_params_from_firmware( + extern int shpchprm_get_physical_slot_number(struct controller *ctrl, + u32 *sun, u8 busnum, u8 devnum); + extern void shpchp_remove_ctrl_files(struct controller *ctrl); +- ++extern void cleanup_slots(struct controller *ctrl); ++extern void shpchp_pushbutton_thread(void *data); + + /* Global variables */ + extern struct list_head shpchp_ctrl_list; +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -32,6 +32,7 @@ + #include <linux/kernel.h> + #include <linux/types.h> + #include <linux/pci.h> ++#include <linux/workqueue.h> + #include "shpchp.h" + + /* Global variables */ +@@ -39,6 +40,7 @@ int shpchp_debug; + int shpchp_poll_mode; + int shpchp_poll_time; + LIST_HEAD(shpchp_ctrl_list); ++struct workqueue_struct *shpchp_wq; + + #define DRIVER_VERSION "0.4" + #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" +@@ -57,7 +59,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Poll + + #define SHPC_MODULE_NAME "shpchp" + +-static int shpc_start_thread (void); + static int set_attention_status (struct hotplug_slot *slot, u8 value); + static int enable_slot (struct hotplug_slot *slot); + static int disable_slot (struct hotplug_slot *slot); +@@ -141,6 +142,7 @@ static int init_slots(struct controller + goto error_info; + + slot->number = sun; ++ INIT_WORK(&slot->work, shpchp_pushbutton_thread, slot); + + /* register this slot with the hotplug pci core */ + hotplug_slot->private = slot; +@@ -176,7 +178,7 @@ error: + return retval; + } + +-static void cleanup_slots(struct controller *ctrl) ++void cleanup_slots(struct controller *ctrl) + { + struct list_head *tmp; + struct list_head *next; +@@ -185,6 +187,8 @@ static void cleanup_slots(struct control + list_for_each_safe(tmp, next, &ctrl->slot_list) { + slot = list_entry(tmp, struct slot, slot_list); + list_del(&slot->slot_list); ++ cancel_delayed_work(&slot->work); ++ flush_workqueue(shpchp_wq); + pci_hp_deregister(slot->hotplug_slot); + } + } +@@ -400,7 +404,7 @@ static int shpc_probe(struct pci_dev *pd + rc = get_ctlr_slot_config(ctrl); + if (rc) { + err(msg_initialization_err, rc); +- goto err_out_unmap_mmio_region; ++ goto err_out_release_ctlr; + } + first_device_num = ctrl->slot_device_offset; + num_ctlr_slots = ctrl->num_slots; +@@ -411,7 +415,7 @@ static int shpc_probe(struct pci_dev *pd + rc = init_slots(ctrl); + if (rc) { + err(msg_initialization_err, 6); +- goto err_out_free_ctrl_slot; ++ goto err_out_release_ctlr; + } + + /* Now hpc_functions (slot->hpc_ops->functions) are ready */ +@@ -427,18 +431,13 @@ static int shpc_probe(struct pci_dev *pd + ctrl->speed = PCI_SPEED_33MHz; + } + +- /* Finish setting up the hot plug ctrl device */ +- ctrl->next_event = 0; +- + list_add(&ctrl->ctrl_list, &shpchp_ctrl_list); + + shpchp_create_ctrl_files(ctrl); + + return 0; + +-err_out_free_ctrl_slot: +- cleanup_slots(ctrl); +-err_out_unmap_mmio_region: ++err_out_release_ctlr: + ctrl->hpc_ops->release_ctlr(ctrl); + err_out_free_ctrl: + kfree(ctrl); +@@ -446,21 +445,6 @@ err_out_none: + return -ENODEV; + } + +-static int shpc_start_thread(void) +-{ +- int retval = 0; +- +- dbg("Initialize + Start the notification/polling mechanism \n"); +- +- retval = shpchp_event_start_thread(); +- if (retval) { +- dbg("shpchp_event_start_thread() failed\n"); +- return retval; +- } +- +- return retval; +-} +- + static void __exit unload_shpchpd(void) + { + struct list_head *tmp; +@@ -470,14 +454,11 @@ static void __exit unload_shpchpd(void) + list_for_each_safe(tmp, next, &shpchp_ctrl_list) { + ctrl = list_entry(tmp, struct controller, ctrl_list); + shpchp_remove_ctrl_files(ctrl); +- cleanup_slots(ctrl); + ctrl->hpc_ops->release_ctlr(ctrl); + kfree(ctrl); + } + +- /* Stop the notification mechanism */ +- shpchp_event_stop_thread(); +- ++ destroy_workqueue(shpchp_wq); + } + + static struct pci_device_id shpcd_pci_tbl[] = { +@@ -501,17 +482,15 @@ static int __init shpcd_init(void) + shpchp_poll_mode = 1; + #endif + +- retval = shpc_start_thread(); +- if (retval) +- goto error_hpc_init; ++ shpchp_wq = create_singlethread_workqueue("shpchpd"); ++ if (!shpchp_wq) ++ return -ENOMEM; + + retval = pci_register_driver(&shpc_driver); + dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); +- +-error_hpc_init: + if (retval) { +- shpchp_event_stop_thread(); ++ destroy_workqueue(shpchp_wq); + } + return retval; + } --- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c +++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c @@ -32,44 +32,46 @@ @@ -512,213 +719,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> } ---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h -+++ gregkh-2.6/drivers/pci/hotplug/shpchp.h -@@ -46,6 +46,7 @@ - extern int shpchp_poll_mode; - extern int shpchp_poll_time; - extern int shpchp_debug; -+extern struct workqueue_struct *shpchp_wq; - - /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ - #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) -@@ -70,11 +71,13 @@ struct slot { - struct hotplug_slot *hotplug_slot; - struct list_head slot_list; - char name[SLOT_NAME_SIZE]; -+ struct work_struct work; /* work for button event */ - }; - - struct event_info { - u32 event_type; -- u8 hp_slot; -+ struct slot *p_slot; -+ struct work_struct work; - }; - - struct controller { -@@ -85,11 +88,9 @@ struct controller { - int num_slots; /* Number of slots on ctlr */ - int slot_num_inc; /* 1 or -1 */ - struct pci_dev *pci_dev; -- struct event_info event_queue[10]; - struct list_head slot_list; - struct hpc_ops *hpc_ops; - wait_queue_head_t queue; /* sleep & wake process */ -- u8 next_event; - u8 bus; - u8 device; - u8 function; -@@ -180,9 +181,6 @@ struct hotplug_params { - /* sysfs functions for the hotplug controller info */ - extern void shpchp_create_ctrl_files (struct controller *ctrl); - --/* controller functions */ --extern int shpchp_event_start_thread(void); --extern void shpchp_event_stop_thread(void); - extern int shpchp_enable_slot(struct slot *slot); - extern int shpchp_disable_slot(struct slot *slot); - -@@ -201,7 +199,8 @@ extern void get_hp_params_from_firmware( - extern int shpchprm_get_physical_slot_number(struct controller *ctrl, - u32 *sun, u8 busnum, u8 devnum); - extern void shpchp_remove_ctrl_files(struct controller *ctrl); -- -+extern void cleanup_slots(struct controller *ctrl); -+extern void shpchp_pushbutton_thread(void *data); - - /* Global variables */ - extern struct list_head shpchp_ctrl_list; ---- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c -+++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c -@@ -32,6 +32,7 @@ - #include <linux/kernel.h> - #include <linux/types.h> - #include <linux/pci.h> -+#include <linux/workqueue.h> - #include "shpchp.h" - - /* Global variables */ -@@ -39,6 +40,7 @@ int shpchp_debug; - int shpchp_poll_mode; - int shpchp_poll_time; - LIST_HEAD(shpchp_ctrl_list); -+struct workqueue_struct *shpchp_wq; - - #define DRIVER_VERSION "0.4" - #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" -@@ -57,7 +59,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Poll - - #define SHPC_MODULE_NAME "shpchp" - --static int shpc_start_thread (void); - static int set_attention_status (struct hotplug_slot *slot, u8 value); - static int enable_slot (struct hotplug_slot *slot); - static int disable_slot (struct hotplug_slot *slot); -@@ -141,6 +142,7 @@ static int init_slots(struct controller - goto error_info; - - slot->number = sun; -+ INIT_WORK(&slot->work, shpchp_pushbutton_thread, slot); - - /* register this slot with the hotplug pci core */ - hotplug_slot->private = slot; -@@ -176,7 +178,7 @@ error: - return retval; - } - --static void cleanup_slots(struct controller *ctrl) -+void cleanup_slots(struct controller *ctrl) - { - struct list_head *tmp; - struct list_head *next; -@@ -185,6 +187,8 @@ static void cleanup_slots(struct control - list_for_each_safe(tmp, next, &ctrl->slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - list_del(&slot->slot_list); -+ cancel_delayed_work(&slot->work); -+ flush_workqueue(shpchp_wq); - pci_hp_deregister(slot->hotplug_slot); - } - } -@@ -400,7 +404,7 @@ static int shpc_probe(struct pci_dev *pd - rc = get_ctlr_slot_config(ctrl); - if (rc) { - err(msg_initialization_err, rc); -- goto err_out_unmap_mmio_region; -+ goto err_out_release_ctlr; - } - first_device_num = ctrl->slot_device_offset; - num_ctlr_slots = ctrl->num_slots; -@@ -411,7 +415,7 @@ static int shpc_probe(struct pci_dev *pd - rc = init_slots(ctrl); - if (rc) { - err(msg_initialization_err, 6); -- goto err_out_free_ctrl_slot; -+ goto err_out_release_ctlr; - } - - /* Now hpc_functions (slot->hpc_ops->functions) are ready */ -@@ -427,18 +431,13 @@ static int shpc_probe(struct pci_dev *pd - ctrl->speed = PCI_SPEED_33MHz; - } - -- /* Finish setting up the hot plug ctrl device */ -- ctrl->next_event = 0; -- - list_add(&ctrl->ctrl_list, &shpchp_ctrl_list); - - shpchp_create_ctrl_files(ctrl); - - return 0; - --err_out_free_ctrl_slot: -- cleanup_slots(ctrl); --err_out_unmap_mmio_region: -+err_out_release_ctlr: - ctrl->hpc_ops->release_ctlr(ctrl); - err_out_free_ctrl: - kfree(ctrl); -@@ -446,21 +445,6 @@ err_out_none: - return -ENODEV; - } - --static int shpc_start_thread(void) --{ -- int retval = 0; -- -- dbg("Initialize + Start the notification/polling mechanism \n"); -- -- retval = shpchp_event_start_thread(); -- if (retval) { -- dbg("shpchp_event_start_thread() failed\n"); -- return retval; -- } -- -- return retval; --} -- - static void __exit unload_shpchpd(void) - { - struct list_head *tmp; -@@ -470,14 +454,11 @@ static void __exit unload_shpchpd(void) - list_for_each_safe(tmp, next, &shpchp_ctrl_list) { - ctrl = list_entry(tmp, struct controller, ctrl_list); - shpchp_remove_ctrl_files(ctrl); -- cleanup_slots(ctrl); - ctrl->hpc_ops->release_ctlr(ctrl); - kfree(ctrl); - } - -- /* Stop the notification mechanism */ -- shpchp_event_stop_thread(); -- -+ destroy_workqueue(shpchp_wq); - } - - static struct pci_device_id shpcd_pci_tbl[] = { -@@ -501,17 +482,15 @@ static int __init shpcd_init(void) - shpchp_poll_mode = 1; - #endif - -- retval = shpc_start_thread(); -- if (retval) -- goto error_hpc_init; -+ shpchp_wq = create_singlethread_workqueue("shpchpd"); -+ if (!shpchp_wq) -+ return -ENOMEM; - - retval = pci_register_driver(&shpc_driver); - dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); - info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); -- --error_hpc_init: - if (retval) { -- shpchp_event_stop_thread(); -+ destroy_workqueue(shpchp_wq); - } - return retval; - } --- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c +++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c @@ -813,6 +813,7 @@ static void hpc_release_ctlr(struct cont |