Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 23 Mar 2006 23:49:57 +0000 (15:49 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 23 Mar 2006 23:49:57 +0000 (15:49 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (49 commits)
  [PATCH] acpiphp: fix acpi_path_name
  [PATCH] ibmphp: remove TRUE and FALSE
  [PATCH] PCI Hotplug: add common acpi functions to core
  [PATCH] PCI: kzalloc() conversion in drivers/pci
  [PATCH] acpiphp: Scan slots under the nested P2P bridge
  [PATCH] PCI Hotplug: SN: Fix cleanup on hotplug removal of PPB
  [PATCH] shpchp: cleanup bus speed handling
  [PATCH] PCI: fix pci_request_region[s] arg
  [PATCH] PCI: Provide a boot parameter to disable MSI
  [PATCH] PCI: the scheduled removal of PCI_LEGACY_PROC
  [PATCH] PCI: cpqphp_ctrl.c: board_replaced(): remove dead code
  [PATCH] acpiphp: fix bridge handle
  [PATCH] acpiphp - slot management fix - V4
  [PATCH] acpi: remove dock event handling from ibm_acpi
  [PATCH] acpiphp: add dock event handling
  [PATCH] acpi: export acpi_bus_trim
  [PATCH] acpiphp: add new bus to acpi
  [PATCH] PCI: Move pci_dev_put outside a spinlock
  [PATCH] PCI: PCI/Cardbus cards hidden, needs pci=assign-busses to fix
  [PATCH] PCI: fix problems with MSI-X on ia64
  ...

64 files changed:
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
arch/i386/kernel/efi.c
arch/i386/kernel/setup.c
arch/i386/pci/Makefile
arch/i386/pci/common.c
arch/i386/pci/direct.c
arch/i386/pci/init.c [new file with mode: 0644]
arch/i386/pci/mmconfig.c
arch/i386/pci/pcbios.c
arch/i386/pci/pci.h
arch/x86_64/pci/Makefile
drivers/acpi/Kconfig
drivers/acpi/ibm_acpi.c
drivers/acpi/scan.c
drivers/pci/Kconfig
drivers/pci/hotplug/Makefile
drivers/pci/hotplug/acpi_pcihp.c [moved from drivers/pci/hotplug/shpchprm_acpi.c with 55% similarity]
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_dock.c [new file with mode: 0644]
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpqphp.h
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/ibmphp.h
drivers/pci/hotplug/ibmphp_core.c
drivers/pci/hotplug/ibmphp_ebda.c
drivers/pci/hotplug/ibmphp_hpc.c
drivers/pci/hotplug/ibmphp_pci.c
drivers/pci/hotplug/ibmphp_res.c
drivers/pci/hotplug/pci_hotplug.h
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pciehprm_acpi.c [deleted file]
drivers/pci/hotplug/pciehprm_nonacpi.c [deleted file]
drivers/pci/hotplug/pcihp_skeleton.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/hotplug/shpchp_pci.c
drivers/pci/hotplug/shpchprm_legacy.c [deleted file]
drivers/pci/hotplug/shpchprm_nonacpi.c [deleted file]
drivers/pci/msi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/proc.c
drivers/pci/quirks.c
drivers/pci/search.c
include/acpi/acpi_bus.h
include/linux/pci.h

index afeaf62..c7a4d0f 100644 (file)
@@ -158,13 +158,6 @@ Who:    Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-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 <bunk@stusta.de>
-
----------------------------
-
 What:  pci_module_init(driver)
 When:  January 2007
 Why:   Is replaced by pci_register_driver(pci_driver).
index 7b7382d..44a25f3 100644 (file)
@@ -49,6 +49,7 @@ restrictions referred to are that the relevant option is valid if:
        MCA     MCA bus support is enabled.
        MDA     MDA console support is enabled.
        MOUSE   Appropriate mouse support is enabled.
+       MSI     Message Signaled Interrupts (PCI).
        MTD     MTD support is enabled.
        NET     Appropriate network support is enabled.
        NUMA    NUMA support is enabled.
@@ -1152,6 +1153,9 @@ running once the system is up.
                                Mechanism 2.
                nommconf        [IA-32,X86_64] Disable use of MMCONFIG for PCI
                                Configuration
+               nomsi           [MSI] If the PCI_MSI kernel config parameter is
+                               enabled, this kernel boot option can be used to
+                               disable the use of MSI interrupts system-wide.
                nosort          [IA-32] Don't sort PCI devices according to
                                order given by the PCI BIOS. This sorting is
                                done to get a device order compatible with
index aeabb41..7ec6cfa 100644 (file)
@@ -543,7 +543,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
                    0x100000000ULL)
                        continue;
-               res = alloc_bootmem_low(sizeof(struct resource));
+               res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
                switch (md->type) {
                case EFI_RESERVED_TYPE:
                        res->name = "Reserved Memory";
index 2d87829..d313a11 100644 (file)
@@ -1288,7 +1288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                struct resource *res;
                if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
                        continue;
-               res = alloc_bootmem_low(sizeof(struct resource));
+               res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
                switch (e820.map[i].type) {
                case E820_RAM:  res->name = "System RAM"; break;
                case E820_ACPI: res->name = "ACPI Tables"; break;
@@ -1316,13 +1316,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
 
 /*
  * Request address space for all standard resources
+ *
+ * This is called just before pcibios_assign_resources(), which is also
+ * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c).
  */
-static void __init register_memory(void)
+static int __init request_standard_resources(void)
 {
-       unsigned long gapstart, gapsize, round;
-       unsigned long long last;
-       int           i;
+       int i;
 
+       printk("Setting up standard PCI resources\n");
        if (efi_enabled)
                efi_initialize_iomem_resources(&code_resource, &data_resource);
        else
@@ -1334,6 +1336,16 @@ static void __init register_memory(void)
        /* request I/O space for devices used on all i[345]86 PCs */
        for (i = 0; i < STANDARD_IO_RESOURCES; i++)
                request_resource(&ioport_resource, &standard_io_resources[i]);
+       return 0;
+}
+
+fs_initcall(request_standard_resources);
+
+static void __init register_memory(void)
+{
+       unsigned long gapstart, gapsize, round;
+       unsigned long long last;
+       int i;
 
        /*
         * Search for the bigest gap in the low 32 bits of the e820
index 5461d4d..62ad75c 100644 (file)
@@ -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
index f6bc48d..dbece77 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/dmi.h>
 
 #include <asm/acpi.h>
 #include <asm/segment.h>
@@ -120,11 +121,42 @@ void __devinit  pcibios_fixup_bus(struct pci_bus *b)
        pci_read_bridge_bases(b);
 }
 
+/*
+ * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
+ */
+#ifdef __i386__
+static int __devinit assign_all_busses(struct dmi_system_id *d)
+{
+       pci_probe |= PCI_ASSIGN_ALL_BUSSES;
+       printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
+                       " (pci=assign-busses)\n", d->ident);
+       return 0;
+}
+#endif
+
+/*
+ * Laptops which need pci=assign-busses to see Cardbus cards
+ */
+static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
+#ifdef __i386__
+       {
+               .callback = assign_all_busses,
+               .ident = "Samsung X20 Laptop",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
+               },
+       },
+#endif         /* __i386__ */
+       {}
+};
 
 struct pci_bus * __devinit pcibios_scan_root(int busnum)
 {
        struct pci_bus *bus = NULL;
 
+       dmi_check_system(pciprobe_dmi_table);
+
        while ((bus = pci_find_next_bus(bus)) != NULL) {
                if (bus->number == busnum) {
                        /* Already scanned */
index e3ac502..99012b9 100644 (file)
@@ -245,7 +245,7 @@ static int __init pci_check_type2(void)
        return works;
 }
 
-static int __init pci_direct_init(void)
+void __init pci_direct_init(void)
 {
        struct resource *region, *region2;
 
@@ -258,16 +258,16 @@ static int __init pci_direct_init(void)
        if (pci_check_type1()) {
                printk(KERN_INFO "PCI: Using configuration type 1\n");
                raw_pci_ops = &pci_direct_conf1;
-               return 0;
+               return;
        }
        release_resource(region);
 
  type2:
        if ((pci_probe & PCI_PROBE_CONF2) == 0)
-               goto out;
+               return;
        region = request_region(0xCF8, 4, "PCI conf2");
        if (!region)
-               goto out;
+               return;
        region2 = request_region(0xC000, 0x1000, "PCI conf2");
        if (!region2)
                goto fail2;
@@ -275,15 +275,10 @@ static int __init pci_direct_init(void)
        if (pci_check_type2()) {
                printk(KERN_INFO "PCI: Using configuration type 2\n");
                raw_pci_ops = &pci_direct_conf2;
-               return 0;
+               return;
        }
 
        release_resource(region2);
  fail2:
        release_resource(region);
-
- out:
-       return 0;
 }
-
-arch_initcall(pci_direct_init);
diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c
new file mode 100644 (file)
index 0000000..f9156d3
--- /dev/null
@@ -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_BIOS
+       pci_pcbios_init();
+#endif
+       if (raw_pci_ops)
+               return 0;
+#ifdef CONFIG_PCI_DIRECT
+       pci_direct_init();
+#endif
+       return 0;
+}
+arch_initcall(pci_access_init);
index 0ee8a98..6137890 100644 (file)
@@ -172,25 +172,20 @@ static __init void unreachable_devices(void)
        }
 }
 
-static int __init pci_mmcfg_init(void)
+void __init pci_mmcfg_init(void)
 {
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
-               goto out;
+               return;
 
        acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
        if ((pci_mmcfg_config_num == 0) ||
            (pci_mmcfg_config == NULL) ||
            (pci_mmcfg_config[0].base_address == 0))
-               goto out;
+               return;
 
        printk(KERN_INFO "PCI: Using MMCONFIG\n");
        raw_pci_ops = &pci_mmcfg;
        pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
        unreachable_devices();
-
- out:
-       return 0;
 }
-
-arch_initcall(pci_mmcfg_init);
index b9d65f0..1eec086 100644 (file)
@@ -476,14 +476,12 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
 }
 EXPORT_SYMBOL(pcibios_set_irq_routing);
 
-static int __init pci_pcbios_init(void)
+void __init pci_pcbios_init(void)
 {
        if ((pci_probe & PCI_PROBE_BIOS) 
                && ((raw_pci_ops = pci_find_bios()))) {
                pci_probe |= PCI_BIOS_SORT;
                pci_bios_present = 1;
        }
-       return 0;
 }
 
-arch_initcall(pci_pcbios_init);
index f550781..12035e2 100644 (file)
@@ -80,4 +80,7 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus,
 extern int pci_conf1_read(unsigned int seg, unsigned int bus,
                          unsigned int devfn, int reg, int len, u32 *value);
 
+extern void pci_direct_init(void);
+extern void pci_pcbios_init(void);
+extern void pci_mmcfg_init(void);
 
index a8f75a2..a3f6ad5 100644 (file)
@@ -7,7 +7,7 @@ CFLAGS += -Iarch/i386/pci
 
 obj-y          := i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
-obj-y          += fixup.o
+obj-y          += fixup.o init.o
 obj-$(CONFIG_ACPI)     += acpi.o
 obj-y                  += legacy.o irq.o common.o
 # mmconfig has a 64bit special
@@ -22,3 +22,4 @@ irq-y    += ../../i386/pci/irq.o
 common-y += ../../i386/pci/common.o
 fixup-y  += ../../i386/pci/fixup.o
 i386-y  += ../../i386/pci/i386.o
+init-y += ../../i386/pci/init.o
index 33e2ca8..82710ae 100644 (file)
@@ -205,6 +205,18 @@ config ACPI_IBM
 
          If you have an IBM ThinkPad laptop, say Y or M here.
 
+config ACPI_IBM_DOCK
+       bool "Legacy Docking Station Support"
+       depends on ACPI_IBM
+       default n
+       ---help---
+         Allows the ibm_acpi driver to handle docking station events.
+         This support is obsoleted by CONFIG_HOTPLUG_PCI_ACPI.  It will
+         allow locking and removing the laptop from the docking station,
+         but will not properly connect PCI devices.
+
+         If you are not sure, say N here.
+
 config ACPI_TOSHIBA
        tristate "Toshiba Laptop Extras"
        depends on X86
index 5cc0903..262b1f4 100644 (file)
@@ -160,13 +160,13 @@ IBM_HANDLE(cmos, root, "\\UCMS",  /* R50, R50e, R50p, R51, T4x, X31, X40 */
           "\\CMOS",            /* A3x, G4x, R32, T23, T30, X22-24, X30 */
           "\\CMS",             /* R40, R40e */
     );                         /* all others */
-
+#ifdef CONFIG_ACPI_IBM_DOCK
 IBM_HANDLE(dock, root, "\\_SB.GDCK",   /* X30, X31, X40 */
           "\\_SB.PCI0.DOCK",   /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
           "\\_SB.PCI0.PCI1.DOCK",      /* all others */
           "\\_SB.PCI.ISA.SLCE",        /* 570 */
     );                         /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
-
+#endif
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",       /* 570 */
           "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
           "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
@@ -844,7 +844,7 @@ static int _sta(acpi_handle handle)
 
        return status;
 }
-
+#ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
 
 static int dock_read(char *p)
@@ -907,6 +907,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
                acpi_bus_generate_event(ibm->device, event, 0); /* unknown */
        }
 }
+#endif
 
 static int bay_status_supported;
 static int bay_status2_supported;
@@ -1574,6 +1575,7 @@ static struct ibm_struct ibms[] = {
         .read = light_read,
         .write = light_write,
         },
+#ifdef CONFIG_ACPI_IBM_DOCK
        {
         .name = "dock",
         .read = dock_read,
@@ -1589,6 +1591,7 @@ static struct ibm_struct ibms[] = {
         .handle = &pci_handle,
         .type = ACPI_SYSTEM_NOTIFY,
         },
+#endif
        {
         .name = "bay",
         .init = bay_init,
@@ -1880,7 +1883,9 @@ IBM_PARAM(hotkey);
 IBM_PARAM(bluetooth);
 IBM_PARAM(video);
 IBM_PARAM(light);
+#ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
+#endif
 IBM_PARAM(bay);
 IBM_PARAM(cmos);
 IBM_PARAM(led);
@@ -1927,7 +1932,9 @@ static int __init acpi_ibm_init(void)
        IBM_HANDLE_INIT(hkey);
        IBM_HANDLE_INIT(lght);
        IBM_HANDLE_INIT(cmos);
+#ifdef CONFIG_ACPI_IBM_DOCK
        IBM_HANDLE_INIT(dock);
+#endif
        IBM_HANDLE_INIT(pci);
        IBM_HANDLE_INIT(bay);
        if (bay_handle)
index 9271e52..a0ab828 100644 (file)
@@ -23,7 +23,6 @@ static LIST_HEAD(acpi_device_list);
 DEFINE_SPINLOCK(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
-static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 
 static void acpi_device_release(struct kobject *kobj)
 {
@@ -1284,7 +1283,7 @@ int acpi_bus_start(struct acpi_device *device)
 
 EXPORT_SYMBOL(acpi_bus_start);
 
-static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
+int acpi_bus_trim(struct acpi_device *start, int rmdevice)
 {
        acpi_status status;
        struct acpi_device *parent, *child;
@@ -1337,6 +1336,8 @@ static int acpi_bus_trim(struct acpi_device *start, int rmdevice)
        }
        return err;
 }
+EXPORT_SYMBOL_GPL(acpi_bus_trim);
+
 
 static int acpi_bus_scan_fixed(struct acpi_device *root)
 {
index f187fd8..4d762fc 100644 (file)
@@ -11,24 +11,11 @@ config PCI_MSI
           generate an interrupt using an inbound Memory Write on its
           PCI bus instead of asserting a device IRQ pin.
 
-          If you don't know what to do here, say N.
-
-config PCI_LEGACY_PROC
-       bool "Legacy /proc/pci interface"
-       depends on PCI
-       ---help---
-         This feature enables a procfs file -- /proc/pci -- that provides a 
-         summary of PCI devices in the system. 
-
-         This feature has been deprecated as of v2.5.53, in favor of using the 
-         tool lspci(8). This feature may be removed at a future date. 
+          Use of PCI MSI interrupts can be disabled at kernel boot time
+          by using the 'pci=nomsi' option.  This disables MSI for the
+          entire system.
 
-         lspci can provide the same data, as well as much more. lspci is a part of
-         the pci-utils package, which should be installed by your distribution. 
-         See <file:Documentation/Changes> for information on where to get the latest
-         version. 
-
-         When in doubt, say N.
+          If you don't know what to do here, say N.
 
 config PCI_DEBUG
        bool "PCI Debugging"
index 3c71e30..421cfff 100644 (file)
@@ -22,6 +22,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI
 pci_hotplug-objs       +=      cpci_hotplug_core.o     \
                                cpci_hotplug_pci.o
 endif
+ifdef CONFIG_ACPI
+pci_hotplug-objs       +=      acpi_pcihp.o
+endif
 
 cpqphp-objs            :=      cpqphp_core.o   \
                                cpqphp_ctrl.o   \
@@ -37,7 +40,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    \
@@ -50,23 +54,9 @@ pciehp-objs          :=      pciehp_core.o   \
                                pciehp_ctrl.o   \
                                pciehp_pci.o    \
                                pciehp_hpc.o
-ifdef CONFIG_ACPI
-       pciehp-objs += pciehprm_acpi.o
-else
-       pciehp-objs += pciehprm_nonacpi.o
-endif
 
 shpchp-objs            :=      shpchp_core.o   \
                                shpchp_ctrl.o   \
                                shpchp_pci.o    \
                                shpchp_sysfs.o  \
                                shpchp_hpc.o
-ifdef CONFIG_ACPI
-       shpchp-objs += shpchprm_acpi.o
-else
-       ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
-               shpchp-objs += shpchprm_legacy.o
-       else
-               shpchp-objs += shpchprm_nonacpi.o
-       endif
-endif
similarity index 55%
rename from drivers/pci/hotplug/shpchprm_acpi.c
rename to drivers/pci/hotplug/acpi_pcihp.c
index 17145e5..39af9c3 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform
+ * Common ACPI functions for hot plug platforms
  *
- * Copyright (C) 2003-2004 Intel Corporation
+ * Copyright (C) 2006 Intel Corporation
  *
  * All rights reserved.
  *
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/actypes.h>
-#include "shpchp.h"
+#include "pci_hotplug.h"
 
 #define        METHOD_NAME__SUN        "_SUN"
 #define        METHOD_NAME__HPP        "_HPP"
 #define        METHOD_NAME_OSHP        "OSHP"
 
-static u8 * acpi_path_name( acpi_handle        handle)
-{
-       acpi_status             status;
-       static u8       path_name[ACPI_PATHNAME_MAX];
-       struct acpi_buffer              ret_buf = { ACPI_PATHNAME_MAX, path_name };
-
-       memset(path_name, 0, sizeof (path_name));
-       status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
-
-       if (ACPI_FAILURE(status))
-               return NULL;
-       else
-               return path_name;       
-}
 
 static acpi_status
 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
@@ -58,18 +44,21 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
        acpi_status             status;
        u8                      nui[4];
        struct acpi_buffer      ret_buf = { 0, NULL};
+       struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object       *ext_obj, *package;
-       u8                      *path_name = acpi_path_name(handle);
        int                     i, len = 0;
 
+       acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
+
        /* get _hpp */
        status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
        switch (status) {
        case AE_BUFFER_OVERFLOW:
                ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
                if (!ret_buf.pointer) {
-                       err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
-                                       path_name);
+                       printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
+                               __FUNCTION__, (char *)string.pointer);
+                       acpi_os_free(string.pointer);
                        return AE_NO_MEMORY;
                }
                status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
@@ -78,16 +67,17 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
                        break;
        default:
                if (ACPI_FAILURE(status)) {
-                       dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
-                                       path_name, status);
+                       pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
+                               (char *)string.pointer, status);
+                       acpi_os_free(string.pointer);
                        return status;
                }
        }
 
        ext_obj = (union acpi_object *) ret_buf.pointer;
        if (ext_obj->type != ACPI_TYPE_PACKAGE) {
-               err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
-                               path_name);
+               printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__,
+                               (char *)string.pointer);
                status = AE_ERROR;
                goto free_and_return;
        }
@@ -101,8 +91,8 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
                        nui[i] = (u8)ext_obj->integer.value;
                        break;
                default:
-                       err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
-                                       path_name);
+                       printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
+                               __FUNCTION__, (char *)string.pointer);
                        status = AE_ERROR;
                        goto free_and_return;
                }
@@ -113,54 +103,52 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
        hpp->enable_serr = nui[2];
        hpp->enable_perr = nui[3];
 
-       dbg("  _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
-       dbg("  _HPP: latency timer  =0x%x\n", hpp->latency_timer);
-       dbg("  _HPP: enable SERR    =0x%x\n", hpp->enable_serr);
-       dbg("  _HPP: enable PERR    =0x%x\n", hpp->enable_perr);
+       pr_debug("  _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
+       pr_debug("  _HPP: latency timer  =0x%x\n", hpp->latency_timer);
+       pr_debug("  _HPP: enable SERR    =0x%x\n", hpp->enable_serr);
+       pr_debug("  _HPP: enable PERR    =0x%x\n", hpp->enable_perr);
 
 free_and_return:
-       kfree(ret_buf.pointer);
+       acpi_os_free(string.pointer);
+       acpi_os_free(ret_buf.pointer);
        return status;
 }
 
-static void acpi_run_oshp(acpi_handle handle)
+
+
+/* acpi_run_oshp - get control of hotplug from the firmware
+ *
+ * @handle - the handle of the hotplug controller.
+ */
+acpi_status acpi_run_oshp(acpi_handle handle)
 {
        acpi_status             status;
-       u8                      *path_name = acpi_path_name(handle);
+       struct acpi_buffer      string = { ACPI_ALLOCATE_BUFFER, NULL };
+
+       acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
 
        /* run OSHP */
        status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
-       if (ACPI_FAILURE(status)) {
-               err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
-                               status);
-       } else {
-               dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
-       }
-}
-
-int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
-{
-       int offset = devnum - ctrl->slot_device_offset;
+       if (ACPI_FAILURE(status))
+               printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__,
+                       (char *)string.pointer, status);
+       else
+               pr_debug("%s:%s OSHP passes\n", __FUNCTION__,
+                       (char *)string.pointer);
 
-       dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
-       *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
-       return 0;
+       acpi_os_free(string.pointer);
+       return status;
 }
+EXPORT_SYMBOL_GPL(acpi_run_oshp);
+
 
-void get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
-       /*
-        * OSHP is an optional ACPI firmware control method. If present,
-        * we need to run it to inform BIOS that we will control SHPC
-        * hardware from now on.
-        */
-       acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
-       if (!handle)
-               return;
-       acpi_run_oshp(handle);
-}
 
-void get_hp_params_from_firmware(struct pci_dev *dev,
+/* acpi_get_hp_params_from_firmware
+ *
+ * @dev - the pci_dev of the newly added device
+ * @hpp - allocated by the caller
+ */
+acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
                struct hotplug_params *hpp)
 {
        acpi_status status = AE_NOT_FOUND;
@@ -182,5 +170,42 @@ void get_hp_params_from_firmware(struct pci_dev *dev,
                /* Check if a parent object supports _HPP */
                pdev = pdev->bus->parent->self;
        }
+       return status;
 }
+EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
 
+
+/* acpi_root_bridge - check to see if this acpi object is a root bridge
+ *
+ * @handle - the acpi object in question.
+ */
+int acpi_root_bridge(acpi_handle handle)
+{
+       acpi_status status;
+       struct acpi_device_info *info;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       int i;
+
+       status = acpi_get_object_info(handle, &buffer);
+       if (ACPI_SUCCESS(status)) {
+               info = buffer.pointer;
+               if ((info->valid & ACPI_VALID_HID) &&
+                       !strcmp(PCI_ROOT_HID_STRING,
+                                       info->hardware_id.value)) {
+                       acpi_os_free(buffer.pointer);
+                       return 1;
+               }
+               if (info->valid & ACPI_VALID_CID) {
+                       for (i=0; i < info->compatibility_id.count; i++) {
+                               if (!strcmp(PCI_ROOT_HID_STRING,
+                                       info->compatibility_id.id[i].value)) {
+                                       acpi_os_free(buffer.pointer);
+                                       return 1;
+                               }
+                       }
+               }
+               acpi_os_free(buffer.pointer);
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_root_bridge);
index 293603e..467ac70 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/acpi.h>
 #include <linux/kobject.h>     /* for KOBJ_NAME_LEN */
+#include <linux/mutex.h>
 #include "pci_hotplug.h"
 
 #define dbg(format, arg...)                                    \
@@ -59,26 +60,10 @@ struct acpiphp_slot;
  * struct slot - slot information for each *physical* slot
  */
 struct slot {
-       u8 number;
        struct hotplug_slot     *hotplug_slot;
-       struct list_head        slot_list;
-
        struct acpiphp_slot     *acpi_slot;
 };
 
-/**
- * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
- * @cache_line_size in DWORD
- * @latency_timer in PCI clock
- * @enable_SERR 0 or 1
- * @enable_PERR 0 or 1
- */
-struct hpp_param {
-       u8 cache_line_size;
-       u8 latency_timer;
-       u8 enable_SERR;
-       u8 enable_PERR;
-};
 
 
 /**
@@ -102,7 +87,7 @@ struct acpiphp_bridge {
        struct pci_dev *pci_dev;
 
        /* ACPI 2.0 _HPP parameters */
-       struct hpp_param hpp;
+       struct hotplug_params hpp;
 
        spinlock_t res_lock;
 };
@@ -118,9 +103,9 @@ struct acpiphp_slot {
        struct acpiphp_bridge *bridge;  /* parent */
        struct list_head funcs;         /* one slot may have different
                                           objects (i.e. for each function) */
-       struct semaphore crit_sect;
+       struct slot *slot;
+       struct mutex crit_sect;
 
-       u32             id;             /* slot id (serial #) for hotplug core */
        u8              device;         /* pci device# */
 
        u32             sun;            /* ACPI _SUN (slot unique number) */
@@ -160,6 +145,25 @@ struct acpiphp_attention_info
        struct module *owner;
 };
 
+
+struct dependent_device {
+       struct list_head device_list;
+       struct list_head pci_list;
+       acpi_handle handle;
+       struct acpiphp_func *func;
+};
+
+
+struct acpiphp_dock_station {
+       acpi_handle handle;
+       u32 last_dock_time;
+       u32 flags;
+       struct acpiphp_func *dock_bridge;
+       struct list_head dependent_devices;
+       struct list_head pci_dependent_devices;
+};
+
+
 /* PCI bus bridge HID */
 #define ACPI_PCI_HOST_HID              "PNP0A03"
 
@@ -197,19 +201,27 @@ struct acpiphp_attention_info
 #define FUNC_HAS_PS1           (0x00000020)
 #define FUNC_HAS_PS2           (0x00000040)
 #define FUNC_HAS_PS3           (0x00000080)
+#define FUNC_HAS_DCK            (0x00000100)
+#define FUNC_IS_DD              (0x00000200)
+
+/* dock station flags */
+#define DOCK_DOCKING            (0x00000001)
+#define DOCK_HAS_BRIDGE         (0x00000002)
 
 /* function prototypes */
 
 /* acpiphp_core.c */
 extern int acpiphp_register_attention(struct acpiphp_attention_info*info);
 extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
+extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot);
+extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
 
 /* acpiphp_glue.c */
 extern int acpiphp_glue_init (void);
 extern void acpiphp_glue_exit (void);
 extern int acpiphp_get_num_slots (void);
-extern struct acpiphp_slot *get_slot_from_id (int id);
 typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
+void handle_hotplug_event_func(acpi_handle, u32, void*);
 
 extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
 extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
@@ -219,6 +231,16 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
 extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
 
+/* acpiphp_dock.c */
+extern int find_dock_station(void);
+extern void remove_dock_station(void);
+extern void add_dependent_device(struct dependent_device *new_dd);
+extern void add_pci_dependent_device(struct dependent_device *new_dd);
+extern struct dependent_device *get_dependent_device(acpi_handle handle);
+extern int is_dependent_device(acpi_handle handle);
+extern int detect_dependent_devices(acpi_handle *bridge_handle);
+extern struct dependent_device *alloc_dependent_device(acpi_handle handle);
+
 /* variables */
 extern int acpiphp_debug;
 
index 60c4c38..4f1b0da 100644 (file)
@@ -44,8 +44,6 @@
 #include "pci_hotplug.h"
 #include "acpiphp.h"
 
-static LIST_HEAD(slot_list);
-
 #define MY_NAME        "acpiphp"
 
 static int debug;
@@ -341,62 +339,53 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        kfree(slot);
 }
 
-/**
- * init_slots - initialize 'struct slot' structures for each slot
- *
- */
-static int __init init_slots(void)
+/* callback routine to initialize 'struct slot' for each slot */
+int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 {
        struct slot *slot;
+       struct hotplug_slot *hotplug_slot;
+       struct hotplug_slot_info *hotplug_slot_info;
        int retval = -ENOMEM;
-       int i;
-
-       for (i = 0; i < num_slots; ++i) {
-               slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
-               if (!slot)
-                       goto error;
-               memset(slot, 0, sizeof(struct slot));
-
-               slot->hotplug_slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
-               if (!slot->hotplug_slot)
-                       goto error_slot;
-               memset(slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
-
-               slot->hotplug_slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
-               if (!slot->hotplug_slot->info)
-                       goto error_hpslot;
-               memset(slot->hotplug_slot->info, 0, sizeof(struct hotplug_slot_info));
-
-               slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-               if (!slot->hotplug_slot->name)
-                       goto error_info;
-
-               slot->number = i;
-
-               slot->hotplug_slot->private = slot;
-               slot->hotplug_slot->release = &release_slot;
-               slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
-
-               slot->acpi_slot = get_slot_from_id(i);
-               slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
-               slot->hotplug_slot->info->attention_status = 0;
-               slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
-               slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
-               slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
-               slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
-
-               make_slot_name(slot);
-
-               retval = pci_hp_register(slot->hotplug_slot);
-               if (retval) {
-                       err("pci_hp_register failed with error %d\n", retval);
-                       goto error_name;
-               }
-
-               /* add slot to our internal list */
-               list_add(&slot->slot_list, &slot_list);
-               info("Slot [%s] registered\n", slot->hotplug_slot->name);
-       }
+
+       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+       if (!slot)
+               goto error;
+
+       slot->hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
+       if (!slot->hotplug_slot)
+               goto error_slot;
+
+       slot->hotplug_slot->info = kzalloc(sizeof(*hotplug_slot_info),
+                                          GFP_KERNEL);
+       if (!slot->hotplug_slot->info)
+               goto error_hpslot;
+
+       slot->hotplug_slot->name = kzalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+       if (!slot->hotplug_slot->name)
+               goto error_info;
+
+       slot->hotplug_slot->private = slot;
+       slot->hotplug_slot->release = &release_slot;
+       slot->hotplug_slot->ops = &acpi_hotplug_slot_ops;
+
+       slot->acpi_slot = acpiphp_slot;
+       slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
+       slot->hotplug_slot->info->attention_status = 0;
+       slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
+       slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
+       slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
+       slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
+
+       acpiphp_slot->slot = slot;
+       make_slot_name(slot);
+
+       retval = pci_hp_register(slot->hotplug_slot);
+       if (retval) {
+               err("pci_hp_register failed with error %d\n", retval);
+               goto error_name;
+       }
+
+       info("Slot [%s] registered\n", slot->hotplug_slot->name);
 
        return 0;
 error_name:
@@ -412,42 +401,51 @@ error:
 }
 
 
-static void __exit cleanup_slots (void)
+void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
 {
-       struct list_head *tmp, *n;
-       struct slot *slot;
+       struct slot *slot = acpiphp_slot->slot;
+       int retval = 0;
 
-       list_for_each_safe (tmp, n, &slot_list) {
-               /* memory will be freed in release_slot callback */
-               slot = list_entry(tmp, struct slot, slot_list);
-               list_del(&slot->slot_list);
-               pci_hp_deregister(slot->hotplug_slot);
-       }
+       info ("Slot [%s] unregistered\n", slot->hotplug_slot->name);
+
+       retval = pci_hp_deregister(slot->hotplug_slot);
+       if (retval)
+               err("pci_hp_deregister failed with error %d\n", retval);
 }
 
 
 static int __init acpiphp_init(void)
 {
        int retval;
+       int docking_station;
 
        info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
 
        acpiphp_debug = debug;
 
+       docking_station = find_dock_station();
+
        /* read all the ACPI info from the system */
        retval = init_acpi();
-       if (retval)
-               return retval;
 
-       return init_slots();
+       /* if we have found a docking station, we should
+        * go ahead and load even if init_acpi has found
+        * no slots.  This handles the case when the _DCK
+        * method not defined under the actual dock bridge
+        */
+       if (docking_station)
+               return 0;
+       else
+               return retval;
 }
 
 
 static void __exit acpiphp_exit(void)
 {
-       cleanup_slots();
        /* deallocate internal data structures etc. */
        acpiphp_glue_exit();
+
+       remove_dock_station();
 }
 
 module_init(acpiphp_init);
diff --git a/drivers/pci/hotplug/acpiphp_dock.c b/drivers/pci/hotplug/acpiphp_dock.c
new file mode 100644 (file)
index 0000000..4f1aaf1
--- /dev/null
@@ -0,0 +1,438 @@
+/*
+ * ACPI PCI HotPlug dock functions to ACPI CA subsystem
+ *
+ * Copyright (C) 2006 Kristen Carlson Accardi (kristen.c.accardi@intel.com)
+ * Copyright (C) 2006 Intel Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <kristen.c.accardi@intel.com>
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/smp_lock.h>
+#include <linux/mutex.h>
+
+#include "../pci.h"
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+static struct acpiphp_dock_station *ds;
+#define MY_NAME "acpiphp_dock"
+
+
+int is_dependent_device(acpi_handle handle)
+{
+       return (get_dependent_device(handle) ? 1 : 0);
+}
+
+
+static acpi_status
+find_dependent_device(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       int *count = (int *)context;
+
+       if (is_dependent_device(handle)) {
+               (*count)++;
+               return AE_CTRL_TERMINATE;
+       } else {
+               return AE_OK;
+       }
+}
+
+
+
+
+void add_dependent_device(struct dependent_device *new_dd)
+{
+       list_add_tail(&new_dd->device_list, &ds->dependent_devices);
+}
+
+
+void add_pci_dependent_device(struct dependent_device *new_dd)
+{
+       list_add_tail(&new_dd->pci_list, &ds->pci_dependent_devices);
+}
+
+
+
+struct dependent_device * get_dependent_device(acpi_handle handle)
+{
+       struct dependent_device *dd;
+
+       if (!ds)
+               return NULL;
+
+       list_for_each_entry(dd, &ds->dependent_devices, device_list) {
+               if (handle == dd->handle)
+                       return dd;
+       }
+       return NULL;
+}
+
+
+
+struct dependent_device *alloc_dependent_device(acpi_handle handle)
+{
+       struct dependent_device *dd;
+
+       dd = kzalloc(sizeof(*dd), GFP_KERNEL);
+       if (dd) {
+               INIT_LIST_HEAD(&dd->pci_list);
+               INIT_LIST_HEAD(&dd->device_list);
+               dd->handle = handle;
+       }
+       return dd;
+}
+
+
+
+static int is_dock(acpi_handle handle)
+{
+       acpi_status status;
+       acpi_handle tmp;
+
+       status = acpi_get_handle(handle, "_DCK", &tmp);
+       if (ACPI_FAILURE(status)) {
+               return 0;
+       }
+       return 1;
+}
+
+
+
+static int dock_present(void)
+{
+       unsigned long sta;
+       acpi_status status;
+
+       if (ds) {
+               status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
+               if (ACPI_SUCCESS(status) && sta)
+                       return 1;
+       }
+       return 0;
+}
+
+
+
+static void eject_dock(void)
+{
+       struct acpi_object_list arg_list;
+       union acpi_object arg;
+
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+       arg.type = ACPI_TYPE_INTEGER;
+       arg.integer.value = 1;
+
+       if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0",
+                                       &arg_list, NULL)) || dock_present())
+               warn("%s: failed to eject dock!\n", __FUNCTION__);
+
+       return;
+}
+
+
+
+
+static acpi_status handle_dock(int dock)
+{
+       acpi_status status;
+       struct acpi_object_list arg_list;
+       union acpi_object arg;
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+
+       dbg("%s: %s\n", __FUNCTION__, dock ? "docking" : "undocking");
+
+       /* _DCK method has one argument */
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+       arg.type = ACPI_TYPE_INTEGER;
+       arg.integer.value = dock;
+       status = acpi_evaluate_object(ds->handle, "_DCK",
+                                       &arg_list, &buffer);
+       if (ACPI_FAILURE(status))
+               err("%s: failed to execute _DCK\n", __FUNCTION__);
+       acpi_os_free(buffer.pointer);
+
+       return status;
+}
+
+
+
+static inline void dock(void)
+{
+       handle_dock(1);
+}
+
+
+
+static inline void undock(void)
+{
+       handle_dock(0);
+}
+
+
+
+/*
+ * the _DCK method can do funny things... and sometimes not
+ * hah-hah funny.
+ *
+ * TBD - figure out a way to only call fixups for
+ * systems that require them.
+ */
+static void post_dock_fixups(void)
+{
+       struct pci_bus *bus;
+       u32 buses;
+       struct dependent_device *dd;
+
+       list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list) {
+               bus = dd->func->slot->bridge->pci_bus;
+
+               /* fixup bad _DCK function that rewrites
+                * secondary bridge on slot
+                */
+               pci_read_config_dword(bus->self,
+                               PCI_PRIMARY_BUS,
+                               &buses);
+
+               if (((buses >> 8) & 0xff) != bus->secondary) {
+                       buses = (buses & 0xff000000)
+                               | ((unsigned int)(bus->primary)     <<  0)
+                               | ((unsigned int)(bus->secondary)   <<  8)
+                               | ((unsigned int)(bus->subordinate) << 16);
+                       pci_write_config_dword(bus->self,
+                                       PCI_PRIMARY_BUS,
+                                       buses);
+               }
+       }
+}
+
+
+
+static void hotplug_pci(u32 type)
+{
+       struct dependent_device *dd;
+
+       list_for_each_entry(dd, &ds->pci_dependent_devices, pci_list)
+               handle_hotplug_event_func(dd->handle, type, dd->func);
+}
+
+
+
+static inline void begin_dock(void)
+{
+       ds->flags |= DOCK_DOCKING;
+}
+
+
+static inline void complete_dock(void)
+{
+       ds->flags &= ~(DOCK_DOCKING);
+       ds->last_dock_time = jiffies;
+}
+
+
+static int dock_in_progress(void)
+{
+       if (ds->flags & DOCK_DOCKING ||
+               ds->last_dock_time == jiffies) {
+               dbg("dock in progress\n");
+               return 1;
+       }
+       return 0;
+}
+
+
+
+static void
+handle_hotplug_event_dock(acpi_handle handle, u32 type, void *context)
+{
+       dbg("%s: enter\n", __FUNCTION__);
+
+       switch (type) {
+               case ACPI_NOTIFY_BUS_CHECK:
+                       dbg("BUS Check\n");
+                       if (!dock_in_progress() && dock_present()) {
+                               begin_dock();
+                               dock();
+                               if (!dock_present()) {
+                                       err("Unable to dock!\n");
+                                       break;
+                               }
+                               post_dock_fixups();
+                               hotplug_pci(type);
+                               complete_dock();
+                       }
+                       break;
+               case ACPI_NOTIFY_EJECT_REQUEST:
+                       dbg("EJECT request\n");
+                       if (!dock_in_progress() && dock_present()) {
+                               hotplug_pci(type);
+                               undock();
+                               eject_dock();
+                               if (dock_present())
+                                       err("Unable to undock!\n");
+                       }
+                       break;
+       }
+}
+
+
+
+
+static acpi_status
+find_dock_ejd(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       acpi_status status;
+       acpi_handle tmp;
+       acpi_handle dck_handle = (acpi_handle) context;
+       char objname[64];
+       struct acpi_buffer buffer = { .length = sizeof(objname),
+                                     .pointer = objname };
+       struct acpi_buffer ejd_buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object *ejd_obj;
+
+       status = acpi_get_handle(handle, "_EJD", &tmp);
+       if (ACPI_FAILURE(status))
+               return AE_OK;
+
+       /* make sure we are dependent on the dock device,
+        * by executing the _EJD method, then getting a handle
+        * to the device referenced by that name.  If that
+        * device handle is the same handle as the dock station
+        * handle, then we are a device dependent on the dock station
+        */
+       acpi_get_name(dck_handle, ACPI_FULL_PATHNAME, &buffer);
+       status = acpi_evaluate_object(handle, "_EJD", NULL, &ejd_buffer);
+       if (ACPI_FAILURE(status)) {
+               err("Unable to execute _EJD!\n");
+               goto find_ejd_out;
+       }
+       ejd_obj = ejd_buffer.pointer;
+       status = acpi_get_handle(NULL, ejd_obj->string.pointer, &tmp);
+       if (ACPI_FAILURE(status))
+               goto find_ejd_out;
+
+       if (tmp == dck_handle) {
+               struct dependent_device *dd;
+               dbg("%s: found device dependent on dock\n", __FUNCTION__);
+               dd = alloc_dependent_device(handle);
+               if (!dd) {
+                       err("Can't allocate memory for dependent device!\n");
+                       goto find_ejd_out;
+               }
+               add_dependent_device(dd);
+       }
+
+find_ejd_out:
+       acpi_os_free(ejd_buffer.pointer);
+       return AE_OK;
+}
+
+
+
+int detect_dependent_devices(acpi_handle *bridge_handle)
+{
+       acpi_status status;
+       int count;
+
+       count = 0;
+
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle,
+                                       (u32)1, find_dependent_device,
+                                       (void *)&count, NULL);
+
+       return count;
+}
+
+
+
+
+
+static acpi_status
+find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+       int *count = (int *)context;
+
+       if (is_dock(handle)) {
+               dbg("%s: found dock\n", __FUNCTION__);
+               ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+               ds->handle = handle;
+               INIT_LIST_HEAD(&ds->dependent_devices);
+               INIT_LIST_HEAD(&ds->pci_dependent_devices);
+
+               /* look for devices dependent on dock station */
+               acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                       ACPI_UINT32_MAX, find_dock_ejd, handle, NULL);
+
+               acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+                       handle_hotplug_event_dock, ds);
+               (*count)++;
+       }
+
+       return AE_OK;
+}
+
+
+
+
+int find_dock_station(void)
+{
+       int num = 0;
+
+       ds = NULL;
+
+       /* start from the root object, because some laptops define
+        * _DCK methods outside the scope of PCI (IBM x-series laptop)
+        */
+       acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+                       ACPI_UINT32_MAX, find_dock, &num, NULL);
+
+       return num;
+}
+
+
+
+void remove_dock_station(void)
+{
+       struct dependent_device *dd, *tmp;
+       if (ds) {
+               if (ACPI_FAILURE(acpi_remove_notify_handler(ds->handle,
+                       ACPI_SYSTEM_NOTIFY, handle_hotplug_event_dock)))
+                       err("failed to remove dock notify handler\n");
+
+               /* free all dependent devices */
+               list_for_each_entry_safe(dd, tmp, &ds->dependent_devices,
+                               device_list)
+                       kfree(dd);
+
+               /* no need to touch the pci_dependent_device list,
+                * cause all memory was freed above
+                */
+               kfree(ds);
+       }
+}
+
+
index 509a5b3..053ee84 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "../pci.h"
 #include "pci_hotplug.h"
@@ -57,7 +57,6 @@ static LIST_HEAD(bridge_list);
 #define MY_NAME "acpiphp_glue"
 
 static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
-static void handle_hotplug_event_func (acpi_handle, u32, void *);
 static void acpiphp_sanitize_bus(struct pci_bus *bus);
 static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
 
@@ -125,11 +124,11 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        struct acpiphp_bridge *bridge = (struct acpiphp_bridge *)context;
        struct acpiphp_slot *slot;
        struct acpiphp_func *newfunc;
+       struct dependent_device *dd;
        acpi_handle tmp;
        acpi_status status = AE_OK;
        unsigned long adr, sun;
-       int device, function;
-       static int num_slots = 0;       /* XXX if we support I/O node hotplug... */
+       int device, function, retval;
 
        status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
 
@@ -138,21 +137,21 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
        status = acpi_get_handle(handle, "_EJ0", &tmp);
 
-       if (ACPI_FAILURE(status))
+       if (ACPI_FAILURE(status) && !(is_dependent_device(handle)))
                return AE_OK;
 
        device = (adr >> 16) & 0xffff;
        function = adr & 0xffff;
 
-       newfunc = kmalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
+       newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
        if (!newfunc)
                return AE_NO_MEMORY;
-       memset(newfunc, 0, sizeof(struct acpiphp_func));
 
        INIT_LIST_HEAD(&newfunc->sibling);
        newfunc->handle = handle;
        newfunc->function = function;
-       newfunc->flags = FUNC_HAS_EJ0;
+       if (ACPI_SUCCESS(status))
+               newfunc->flags = FUNC_HAS_EJ0;
 
        if (ACPI_SUCCESS(acpi_get_handle(handle, "_STA", &tmp)))
                newfunc->flags |= FUNC_HAS_STA;
@@ -163,6 +162,19 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        if (ACPI_SUCCESS(acpi_get_handle(handle, "_PS3", &tmp)))
                newfunc->flags |= FUNC_HAS_PS3;
 
+       if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) {
+               newfunc->flags |= FUNC_HAS_DCK;
+               /* add to devices dependent on dock station,
+                * because this may actually be the dock bridge
+                */
+               dd = alloc_dependent_device(handle);
+                if (!dd)
+                        err("Can't allocate memory for "
+                               "new dependent device!\n");
+               else
+                       add_dependent_device(dd);
+       }
+
        status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
        if (ACPI_FAILURE(status))
                sun = -1;
@@ -176,19 +188,17 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                }
 
        if (!slot) {
-               slot = kmalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
+               slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
                if (!slot) {
                        kfree(newfunc);
                        return AE_NO_MEMORY;
                }
 
-               memset(slot, 0, sizeof(struct acpiphp_slot));
                slot->bridge = bridge;
-               slot->id = num_slots++;
                slot->device = device;
                slot->sun = sun;
                INIT_LIST_HEAD(&slot->funcs);
-               init_MUTEX(&slot->crit_sect);
+               mutex_init(&slot->crit_sect);
 
                slot->next = bridge->slots;
                bridge->slots = slot;
@@ -198,6 +208,11 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
                                slot->sun, pci_domain_nr(bridge->pci_bus),
                                bridge->pci_bus->number, slot->device);
+               retval = acpiphp_register_hotplug_slot(slot);
+               if (retval) {
+                       warn("acpiphp_register_hotplug_slot failed(err code = 0x%x)\n", retval);
+                       goto err_exit;
+               }
        }
 
        newfunc->slot = slot;
@@ -210,16 +225,41 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
        }
 
+       /* if this is a device dependent on a dock station,
+        * associate the acpiphp_func to the dependent_device
+        * struct.
+        */
+       if ((dd = get_dependent_device(handle))) {
+               newfunc->flags |= FUNC_IS_DD;
+               /*
+                * we don't want any devices which is dependent
+                * on the dock to have it's _EJ0 method executed.
+                * because we need to run _DCK first.
+                */
+               newfunc->flags &= ~FUNC_HAS_EJ0;
+               dd->func = newfunc;
+               add_pci_dependent_device(dd);
+       }
+
        /* install notify handler */
-       status = acpi_install_notify_handler(handle,
+       if (!(newfunc->flags & FUNC_HAS_DCK)) {
+               status = acpi_install_notify_handler(handle,
                                             ACPI_SYSTEM_NOTIFY,
                                             handle_hotplug_event_func,
                                             newfunc);
 
-       if (ACPI_FAILURE(status)) {
-               err("failed to register interrupt notify handler\n");
-               return status;
-       }
+               if (ACPI_FAILURE(status))
+                       err("failed to register interrupt notify handler\n");
+       } else
+               status = AE_OK;
+
+       return status;
+
+ err_exit:
+       bridge->nr_slots--;
+       bridge->slots = slot->next;
+       kfree(slot);
+       kfree(newfunc);
 
        return AE_OK;
 }
@@ -245,57 +285,19 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
 static void decode_hpp(struct acpiphp_bridge *bridge)
 {
        acpi_status status;
-       struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
-                                     .pointer = NULL};
-       union acpi_object *package;
-       int i;
-
-       /* default numbers */
-       bridge->hpp.cache_line_size = 0x10;
-       bridge->hpp.latency_timer = 0x40;
-       bridge->hpp.enable_SERR = 0;
-       bridge->hpp.enable_PERR = 0;
-
-       status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
 
+       status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp);
        if (ACPI_FAILURE(status)) {
-               dbg("_HPP evaluation failed\n");
-               return;
+               /* use default numbers */
+               bridge->hpp.cache_line_size = 0x10;
+               bridge->hpp.latency_timer = 0x40;
+               bridge->hpp.enable_serr = 0;
+               bridge->hpp.enable_perr = 0;
        }
-
-       package = (union acpi_object *) buffer.pointer;
-
-       if (!package || package->type != ACPI_TYPE_PACKAGE ||
-           package->package.count != 4 || !package->package.elements) {
-               err("invalid _HPP object; ignoring\n");
-               goto err_exit;
-       }
-
-       for (i = 0; i < 4; i++) {
-               if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
-                       err("invalid _HPP parameter type; ignoring\n");
-                       goto err_exit;
-               }
-       }
-
-       bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
-       bridge->hpp.latency_timer = package->package.elements[1].integer.value;
-       bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
-       bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
-
-       dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
-               bridge->hpp.cache_line_size,
-               bridge->hpp.latency_timer,
-               bridge->hpp.enable_SERR,
-               bridge->hpp.enable_PERR);
-
-       bridge->flags |= BRIDGE_HAS_HPP;
-
- err_exit:
-       kfree(buffer.pointer);
 }
 
 
+
 /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
 static void init_bridge_misc(struct acpiphp_bridge *bridge)
 {
@@ -304,9 +306,16 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
        /* decode ACPI 2.0 _HPP (hot plug parameters) */
        decode_hpp(bridge);
 
+       /* must be added to the list prior to calling register_slot */
+       list_add(&bridge->list, &bridge_list);
+
        /* register all slot objects under this bridge */
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
                                     register_slot, bridge, NULL);
+       if (ACPI_FAILURE(status)) {
+               list_del(&bridge->list);
+               return;
+       }
 
        /* install notify handler */
        if (bridge->type != BRIDGE_TYPE_HOST) {
@@ -319,8 +328,6 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
                        err("failed to register interrupt notify handler\n");
                }
        }
-
-       list_add(&bridge->list, &bridge_list);
 }
 
 
@@ -329,12 +336,10 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 {
        struct acpiphp_bridge *bridge;
 
-       bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
+       bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
        if (bridge == NULL)
                return;
 
-       memset(bridge, 0, sizeof(struct acpiphp_bridge));
-
        bridge->type = BRIDGE_TYPE_HOST;
        bridge->handle = handle;
 
@@ -351,14 +356,12 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 {
        struct acpiphp_bridge *bridge;
 
-       bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
+       bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
        if (bridge == NULL) {
                err("out of memory\n");
                return;
        }
 
-       memset(bridge, 0, sizeof(struct acpiphp_bridge));
-
        bridge->type = BRIDGE_TYPE_P2P;
        bridge->handle = handle;
 
@@ -410,11 +413,18 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
                goto out;
 
        /* check if this bridge has ejectable slots */
-       if (detect_ejectable_slots(handle) > 0) {
+       if ((detect_ejectable_slots(handle) > 0) ||
+               (detect_dependent_devices(handle) > 0)) {
                dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
                add_p2p_bridge(handle, dev);
        }
 
+       /* search P2P bridges under this p2p bridge */
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
+                                    find_p2p_bridge, dev->subordinate, NULL);
+       if (ACPI_FAILURE(status))
+               warn("find_p2p_bridge faied (error code = 0x%x)\n", status);
+
  out:
        pci_dev_put(dev);
        return AE_OK;
@@ -512,15 +522,19 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
                list_for_each_safe (list, tmp, &slot->funcs) {
                        struct acpiphp_func *func;
                        func = list_entry(list, struct acpiphp_func, sibling);
-                       status = acpi_remove_notify_handler(func->handle,
+                       if (!(func->flags & FUNC_HAS_DCK)) {
+                               status = acpi_remove_notify_handler(func->handle,
                                                ACPI_SYSTEM_NOTIFY,
                                                handle_hotplug_event_func);
-                       if (ACPI_FAILURE(status))
-                               err("failed to remove notify handler\n");
+                               if (ACPI_FAILURE(status))
+                                       err("failed to remove notify handler\n");
+                       }
                        pci_dev_put(func->pci_dev);
                        list_del(list);
                        kfree(func);
                }
+               acpiphp_unregister_hotplug_slot(slot);
+               list_del(&slot->funcs);
                kfree(slot);
                slot = next;
        }
@@ -551,7 +565,8 @@ static void remove_bridge(acpi_handle handle)
        } else {
                /* clean-up p2p bridges under this host bridge */
                acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
-                               (u32)1, cleanup_p2p_bridge, NULL, NULL);
+                                   ACPI_UINT32_MAX, cleanup_p2p_bridge,
+                                   NULL, NULL);
        }
 }
 
@@ -751,6 +766,113 @@ static int power_off_slot(struct acpiphp_slot *slot)
 }
 
 
+
+/**
+ * acpiphp_max_busnr - return the highest reserved bus number under
+ * the given bus.
+ * @bus: bus to start search with
+ *
+ */
+static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
+{
+       struct list_head *tmp;
+       unsigned char max, n;
+
+       /*
+        * pci_bus_max_busnr will return the highest
+        * reserved busnr for all these children.
+        * that is equivalent to the bus->subordinate
+        * value.  We don't want to use the parent's
+        * bus->subordinate value because it could have
+        * padding in it.
+        */
+       max = bus->secondary;
+
+       list_for_each(tmp, &bus->children) {
+               n = pci_bus_max_busnr(pci_bus_b(tmp));
+               if (n > max)
+                       max = n;
+       }
+       return max;
+}
+
+
+
+/**
+ *  get_func - get a pointer to acpiphp_func given a slot, device
+ *  @slot: slot to search
+ *  @dev:  pci_dev struct to match.
+ *
+ *  This function will increase the reference count of pci_dev,
+ *  so callers should call pci_dev_put when complete.
+ *
+ */
+static struct acpiphp_func *
+get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
+{
+       struct acpiphp_func *func = NULL;
+       struct pci_bus *bus = slot->bridge->pci_bus;
+       struct pci_dev *pdev;
+
+       list_for_each_entry(func, &slot->funcs, sibling) {
+               pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+                                       func->function));
+               if (pdev) {
+                       if (pdev == dev)
+                               break;
+                       pci_dev_put(pdev);
+               }
+       }
+       return func;
+}
+
+
+/**
+ * acpiphp_bus_add - add a new bus to acpi subsystem
+ * @func: acpiphp_func of the bridge
+ *
+ */
+static int acpiphp_bus_add(struct acpiphp_func *func)
+{
+       acpi_handle phandle;
+       struct acpi_device *device, *pdevice;
+       int ret_val;
+
+       acpi_get_parent(func->handle, &phandle);
+       if (acpi_bus_get_device(phandle, &pdevice)) {
+               dbg("no parent device, assuming NULL\n");
+               pdevice = NULL;
+       }
+       if (!acpi_bus_get_device(func->handle, &device)) {
+               dbg("bus exists... trim\n");
+               /* this shouldn't be in here, so remove
+                * the bus then re-add it...
+                */
+               ret_val = acpi_bus_trim(device, 1);
+               dbg("acpi_bus_trim return %x\n", ret_val);
+       }
+
+       ret_val = acpi_bus_add(&device, pdevice, func->handle,
+               ACPI_BUS_TYPE_DEVICE);
+       if (ret_val) {
+               dbg("error adding bus, %x\n",
+                       -ret_val);
+               goto acpiphp_bus_add_out;
+       }
+       /*
+        * try to start anyway.  We could have failed to add
+        * simply because this bus had previously been added
+        * on another add.  Don't bother with the return value
+        * we just keep going.
+        */
+       ret_val = acpi_bus_start(device);
+
+acpiphp_bus_add_out:
+       return ret_val;
+}
+
+
+
 /**
  * enable_device - enable, configure a slot
  * @slot: slot to be enabled
@@ -788,7 +910,7 @@ static int enable_device(struct acpiphp_slot *slot)
                goto err_exit;
        }
 
-       max = bus->secondary;
+       max = acpiphp_max_busnr(bus);
        for (pass = 0; pass < 2; pass++) {
                list_for_each_entry(dev, &bus->devices, bus_list) {
                        if (PCI_SLOT(dev->devfn) != slot->device)
@@ -796,8 +918,15 @@ static int enable_device(struct acpiphp_slot *slot)
                        if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
                            dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
                                max = pci_scan_bridge(bus, dev, max, pass);
-                               if (pass && dev->subordinate)
+                               if (pass && dev->subordinate) {
                                        pci_bus_size_bridges(dev->subordinate);
+                                       func = get_func(slot, dev);
+                                       if (func) {
+                                               acpiphp_bus_add(func);
+                                               /* side effect of get_func */
+                                               pci_dev_put(dev);
+                                       }
+                               }
                        }
                }
        }
@@ -806,8 +935,8 @@ static int enable_device(struct acpiphp_slot *slot)
        acpiphp_sanitize_bus(bus);
        pci_enable_bridges(bus);
        pci_bus_add_devices(bus);
-       acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus);
-       acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev));
+       acpiphp_set_hpp_values(slot->bridge->handle, bus);
+       acpiphp_configure_ioapics(slot->bridge->handle);
 
        /* associate pci_dev to our representation */
        list_for_each (l, &slot->funcs) {
@@ -987,11 +1116,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
        pci_write_config_byte(dev, PCI_LATENCY_TIMER,
                        bridge->hpp.latency_timer);
        pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
-       if (bridge->hpp.enable_SERR)
+       if (bridge->hpp.enable_serr)
                pci_cmd |= PCI_COMMAND_SERR;
        else
                pci_cmd &= ~PCI_COMMAND_SERR;
-       if (bridge->hpp.enable_PERR)
+       if (bridge->hpp.enable_perr)
                pci_cmd |= PCI_COMMAND_PARITY;
        else
                pci_cmd &= ~PCI_COMMAND_PARITY;
@@ -1002,11 +1131,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
                pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
                                bridge->hpp.latency_timer);
                pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
-               if (bridge->hpp.enable_SERR)
+               if (bridge->hpp.enable_serr)
                        pci_bctl |= PCI_BRIDGE_CTL_SERR;
                else
                        pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
-               if (bridge->hpp.enable_PERR)
+               if (bridge->hpp.enable_perr)
                        pci_bctl |= PCI_BRIDGE_CTL_PARITY;
                else
                        pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
@@ -1026,6 +1155,7 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
 
        memset(&bridge, 0, sizeof(bridge));
        bridge.handle = handle;
+       bridge.pci_dev = bus->self;
        decode_hpp(&bridge);
        list_for_each_entry(dev, &bus->devices, bus_list)
                program_hpp(dev, &bridge);
@@ -1200,7 +1330,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
  * handles ACPI event notification on slots
  *
  */
-static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
+void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
 {
        struct acpiphp_func *func;
        char objname[64];
@@ -1242,41 +1372,13 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
        }
 }
 
-static int is_root_bridge(acpi_handle handle)
-{
-       acpi_status status;
-       struct acpi_device_info *info;
-       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       int i;
-
-       status = acpi_get_object_info(handle, &buffer);
-       if (ACPI_SUCCESS(status)) {
-               info = buffer.pointer;
-               if ((info->valid & ACPI_VALID_HID) &&
-                       !strcmp(PCI_ROOT_HID_STRING,
-                                       info->hardware_id.value)) {
-                       acpi_os_free(buffer.pointer);
-                       return 1;
-               }
-               if (info->valid & ACPI_VALID_CID) {
-                       for (i=0; i < info->compatibility_id.count; i++) {
-                               if (!strcmp(PCI_ROOT_HID_STRING,
-                                       info->compatibility_id.id[i].value)) {
-                                       acpi_os_free(buffer.pointer);
-                                       return 1;
-                               }
-                       }
-               }
-       }
-       return 0;
-}
 
 static acpi_status
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        int *count = (int *)context;
 
-       if (is_root_bridge(handle)) {
+       if (acpi_root_bridge(handle)) {
                acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
                                handle_hotplug_event_bridge, NULL);
                        (*count)++;
@@ -1373,26 +1475,6 @@ static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
 }
 #endif
 
-/* search matching slot from id  */
-struct acpiphp_slot *get_slot_from_id(int id)
-{
-       struct list_head *node;
-       struct acpiphp_bridge *bridge;
-       struct acpiphp_slot *slot;
-
-       list_for_each (node, &bridge_list) {
-               bridge = (struct acpiphp_bridge *)node;
-               for (slot = bridge->slots; slot; slot = slot->next)
-                       if (slot->id == id)
-                               return slot;
-       }
-
-       /* should never happen! */
-       err("%s: no object for id %d\n", __FUNCTION__, id);
-       WARN_ON(1);
-       return NULL;
-}
-
 
 /**
  * acpiphp_enable_slot - power on slot
@@ -1401,7 +1483,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
 {
        int retval;
 
-       down(&slot->crit_sect);
+       mutex_lock(&slot->crit_sect);
 
        /* wake up all functions */
        retval = power_on_slot(slot);
@@ -1413,7 +1495,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
                retval = enable_device(slot);
 
  err_exit:
-       up(&slot->crit_sect);
+       mutex_unlock(&slot->crit_sect);
        return retval;
 }
 
@@ -1424,7 +1506,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
 {
        int retval = 0;
 
-       down(&slot->crit_sect);
+       mutex_lock(&slot->crit_sect);
 
        /* unconfigure all functions */
        retval = disable_device(slot);
@@ -1437,7 +1519,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
                goto err_exit;
 
  err_exit:
-       up(&slot->crit_sect);
+       mutex_unlock(&slot->crit_sect);
        return retval;
 }
 
index 30af105..037ce4c 100644 (file)
@@ -248,22 +248,19 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
         * with the pci_hotplug subsystem.
         */
        for (i = first; i <= last; ++i) {
-               slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
+               slot = kzalloc(sizeof (struct slot), GFP_KERNEL);
                if (!slot)
                        goto error;
-               memset(slot, 0, sizeof (struct slot));
 
                hotplug_slot =
-                   kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
+                       kzalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
                if (!hotplug_slot)
                        goto error_slot;
-               memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
                slot->hotplug_slot = hotplug_slot;
 
-               info = kmalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
+               info = kzalloc(sizeof (struct hotplug_slot_info), GFP_KERNEL);
                if (!info)
                        goto error_hpslot;
-               memset(info, 0, sizeof (struct hotplug_slot_info));
                hotplug_slot->info = info;
 
                name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
index cb88404..c74e9e3 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>            /* for read? and write? functions */
 #include <linux/delay.h>       /* for delays */
+#include <linux/mutex.h>
 
 #define MY_NAME        "cpqphp"
 
@@ -286,7 +287,7 @@ struct event_info {
 struct controller {
        struct controller *next;
        u32 ctrl_int_comp;
-       struct semaphore crit_sect;     /* critical section semaphore */
+       struct mutex crit_sect;         /* critical section mutex */
        void __iomem *hpc_reg;          /* cookie for our pci controller location */
        struct pci_resource *mem_head;
        struct pci_resource *p_mem_head;
index b3659ff..9bc1deb 100644 (file)
@@ -347,26 +347,22 @@ static int ctrl_slot_setup(struct controller *ctrl,
        slot_number = ctrl->first_slot;
 
        while (number_of_slots) {
-               slot = kmalloc(sizeof(*slot), GFP_KERNEL);
+               slot = kzalloc(sizeof(*slot), GFP_KERNEL);
                if (!slot)
                        goto error;
 
-               memset(slot, 0, sizeof(struct slot));
-               slot->hotplug_slot = kmalloc(sizeof(*(slot->hotplug_slot)),
+               slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)),
                                                GFP_KERNEL);
                if (!slot->hotplug_slot)
                        goto error_slot;
                hotplug_slot = slot->hotplug_slot;
-               memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
 
                hotplug_slot->info =
-                               kmalloc(sizeof(*(hotplug_slot->info)),
+                               kzalloc(sizeof(*(hotplug_slot->info)),
                                                        GFP_KERNEL);
                if (!hotplug_slot->info)
                        goto error_hpslot;
                hotplug_slot_info = hotplug_slot->info;
-               memset(hotplug_slot_info, 0,
-                               sizeof(struct hotplug_slot_info));
                hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
 
                if (!hotplug_slot->name)
@@ -599,7 +595,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
        hp_slot = func->device - ctrl->slot_device_offset;
 
        // Wait for exclusive access to hardware
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        if (status == 1) {
                amber_LED_on (ctrl, hp_slot);
@@ -607,7 +603,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
                amber_LED_off (ctrl, hp_slot);
        } else {
                // Done with exclusive hardware access
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
                return(1);
        }
 
@@ -617,7 +613,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func,
        wait_for_ctrl_irq (ctrl);
 
        // Done with exclusive hardware access
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        return(0);
 }
@@ -854,13 +850,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        goto err_disable_device;
                }
 
-               ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+               ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
                if (!ctrl) {
                        err("%s : out of memory\n", __FUNCTION__);
                        rc = -ENOMEM;
                        goto err_disable_device;
                }
-               memset(ctrl, 0, sizeof(struct controller));
 
                rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
                if (rc) {
@@ -1084,7 +1079,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
                PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
 
-       init_MUTEX(&ctrl->crit_sect);
+       mutex_init(&ctrl->crit_sect);
        init_waitqueue_head(&ctrl->queue);
 
        /* initialize our threads if they haven't already been started up */
@@ -1223,7 +1218,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        // turn off empty slots here unless command line option "ON" set
        // Wait for exclusive access to hardware
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F;
 
@@ -1270,12 +1265,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        rc = init_SERR(ctrl);
        if (rc) {
                err("init_SERR failed\n");
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
                goto err_free_irq;
        }
 
        // Done with exclusive hardware access
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        cpqhp_create_debugfs_files(ctrl);
 
index 771ed34..55d2dc7 100644 (file)
@@ -1282,9 +1282,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
        u8 hp_slot;
        u8 temp_byte;
        u8 adapter_speed;
-       u32 index;
        u32 rc = 0;
-       u32 src = 8;
 
        hp_slot = func->device - ctrl->slot_device_offset;
 
@@ -1299,7 +1297,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                 **********************************/
                rc = CARD_FUNCTIONING;
        } else {
-               down(&ctrl->crit_sect);
+               mutex_lock(&ctrl->crit_sect);
 
                /* turn on board without attaching to the bus */
                enable_slot_power (ctrl, hp_slot);
@@ -1333,12 +1331,12 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
 
                if (rc)
                        return rc;
 
-               down(&ctrl->crit_sect);
+               mutex_lock(&ctrl->crit_sect);
 
                slot_enable (ctrl, hp_slot);
                green_LED_blink (ctrl, hp_slot);
@@ -1350,7 +1348,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
 
                /* Wait for ~1 second because of hot plug spec */
                long_delay(1*HZ);
@@ -1368,76 +1366,30 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
 
                        rc = cpqhp_configure_board(ctrl, func);
 
-                       if (rc || src) {
-                               /* If configuration fails, turn it off
-                                * Get slot won't work for devices behind
-                                * bridges, but in this case it will always be
-                                * called for the "base" bus/dev/func of an
-                                * adapter. */
+                       /* If configuration fails, turn it off
+                        * Get slot won't work for devices behind
+                        * bridges, but in this case it will always be
+                        * called for the "base" bus/dev/func of an
+                        * adapter. */
 
-                               down(&ctrl->crit_sect);
+                       mutex_lock(&ctrl->crit_sect);
 
-                               amber_LED_on (ctrl, hp_slot);
-                               green_LED_off (ctrl, hp_slot);
-                               slot_disable (ctrl, hp_slot);
-
-                               set_SOGO(ctrl);
-
-                               /* Wait for SOBS to be unset */
-                               wait_for_ctrl_irq (ctrl);
-
-                               up(&ctrl->crit_sect);
-
-                               if (rc)
-                                       return rc;
-                               else
-                                       return 1;
-                       }
-
-                       func->status = 0;
-                       func->switch_save = 0x10;
-
-                       index = 1;
-                       while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
-                               rc |= cpqhp_configure_board(ctrl, func);
-                               index++;
-                       }
-
-                       if (rc) {
-                               /* If configuration fails, turn it off
-                                * Get slot won't work for devices behind
-                                * bridges, but in this case it will always be
-                                * called for the "base" bus/dev/func of an
-                                * adapter. */
-
-                               down(&ctrl->crit_sect);
-
-                               amber_LED_on (ctrl, hp_slot);
-                               green_LED_off (ctrl, hp_slot);
-                               slot_disable (ctrl, hp_slot);
-
-                               set_SOGO(ctrl);
-
-                               /* Wait for SOBS to be unset */
-                               wait_for_ctrl_irq (ctrl);
-
-                               up(&ctrl->crit_sect);
-
-                               return rc;
-                       }
-                       /* Done configuring so turn LED on full time */
-
-                       down(&ctrl->crit_sect);
-
-                       green_LED_on (ctrl, hp_slot);
+                       amber_LED_on (ctrl, hp_slot);
+                       green_LED_off (ctrl, hp_slot);
+                       slot_disable (ctrl, hp_slot);
 
                        set_SOGO(ctrl);
 
                        /* Wait for SOBS to be unset */
                        wait_for_ctrl_irq (ctrl);
 
-                       up(&ctrl->crit_sect);
-                       rc = 0;
+                       mutex_unlock(&ctrl->crit_sect);
+
+                       if (rc)
+                               return rc;
+                       else
+                               return 1;
+
                } else {
                        /* Something is wrong
 
@@ -1445,7 +1397,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                         * in this case it will always be called for the "base"
                         * bus/dev/func of an adapter. */
 
-                       down(&ctrl->crit_sect);
+                       mutex_lock(&ctrl->crit_sect);
 
                        amber_LED_on (ctrl, hp_slot);
                        green_LED_off (ctrl, hp_slot);
@@ -1456,7 +1408,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl)
                        /* Wait for SOBS to be unset */
                        wait_for_ctrl_irq (ctrl);
 
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                }
 
        }
@@ -1488,7 +1440,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
            __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
 
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        /* turn on board without attaching to the bus */
        enable_slot_power(ctrl, hp_slot);
@@ -1522,7 +1474,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        /* Wait for SOBS to be unset */
        wait_for_ctrl_irq(ctrl);
 
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        if (rc)
                return rc;
@@ -1532,7 +1484,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        /* turn on board and blink green LED */
 
        dbg("%s: before down\n", __FUNCTION__);
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
        dbg("%s: after down\n", __FUNCTION__);
 
        dbg("%s: before slot_enable\n", __FUNCTION__);
@@ -1553,7 +1505,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
        dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
 
        dbg("%s: before up\n", __FUNCTION__);
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
        dbg("%s: after up\n", __FUNCTION__);
 
        /* Wait for ~1 second because of hot plug spec */
@@ -1607,7 +1559,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
 
                if (rc) {
-                       down(&ctrl->crit_sect);
+                       mutex_lock(&ctrl->crit_sect);
 
                        amber_LED_on (ctrl, hp_slot);
                        green_LED_off (ctrl, hp_slot);
@@ -1618,7 +1570,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                        /* Wait for SOBS to be unset */
                        wait_for_ctrl_irq (ctrl);
 
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        return rc;
                } else {
                        cpqhp_save_slot_config(ctrl, func);
@@ -1640,7 +1592,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                        }
                } while (new_slot);
 
-               down(&ctrl->crit_sect);
+               mutex_lock(&ctrl->crit_sect);
 
                green_LED_on (ctrl, hp_slot);
 
@@ -1649,9 +1601,9 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
        } else {
-               down(&ctrl->crit_sect);
+               mutex_lock(&ctrl->crit_sect);
 
                amber_LED_on (ctrl, hp_slot);
                green_LED_off (ctrl, hp_slot);
@@ -1662,7 +1614,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
                /* Wait for SOBS to be unset */
                wait_for_ctrl_irq (ctrl);
 
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
 
                return rc;
        }
@@ -1721,7 +1673,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
                func->status = 0x01;
        func->configured = 0;
 
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        green_LED_off (ctrl, hp_slot);
        slot_disable (ctrl, hp_slot);
@@ -1736,7 +1688,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
        /* Wait for SOBS to be unset */
        wait_for_ctrl_irq (ctrl);
 
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        if (!replace_flag && ctrl->add_support) {
                while (func) {
@@ -1899,7 +1851,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        dbg("button cancel\n");
                                        del_timer(&p_slot->task_event);
 
-                                       down(&ctrl->crit_sect);
+                                       mutex_lock(&ctrl->crit_sect);
 
                                        if (p_slot->state == BLINKINGOFF_STATE) {
                                                /* slot is on */
@@ -1922,7 +1874,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        /* Wait for SOBS to be unset */
                                        wait_for_ctrl_irq (ctrl);
 
-                                       up(&ctrl->crit_sect);
+                                       mutex_unlock(&ctrl->crit_sect);
                                }
                                /*** button Released (No action on press...) */
                                else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
@@ -1937,7 +1889,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                p_slot->state = BLINKINGON_STATE;
                                                info(msg_button_on, p_slot->number);
                                        }
-                                       down(&ctrl->crit_sect);
+                                       mutex_lock(&ctrl->crit_sect);
                                        
                                        dbg("blink green LED and turn off amber\n");
                                        
@@ -1949,7 +1901,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        /* Wait for SOBS to be unset */
                                        wait_for_ctrl_irq (ctrl);
 
-                                       up(&ctrl->crit_sect);
+                                       mutex_unlock(&ctrl->crit_sect);
                                        init_timer(&p_slot->task_event);
                                        p_slot->hp_slot = hp_slot;
                                        p_slot->ctrl = ctrl;
index 060d747..71b80c2 100644 (file)
@@ -95,15 +95,13 @@ static int add_slot(struct pci_dev *dev)
        struct hotplug_slot *slot;
        int retval = -ENOMEM;
 
-       slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
+       slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
        if (!slot)
                goto error;
-       memset(slot, 0, sizeof(*slot));
 
-       slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
+       slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
        if (!slot->info)
                goto error_slot;
-       memset(slot->info, 0, sizeof(struct hotplug_slot_info));
 
        slot->info->power_status = 1;
        slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
@@ -227,11 +225,10 @@ static void pci_rescan_bus(const struct pci_bus *bus)
 {
        unsigned int devfn;
        struct pci_dev *dev;
-       dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
        if (!dev)
                return;
 
-       memset(dev, 0, sizeof(dev));
        dev->bus = (struct pci_bus*)bus;
        dev->sysdata = bus->sysdata;
        for (devfn = 0; devfn < 0x100; devfn += 8) {
index c22e028..dba6d8c 100644 (file)
@@ -406,8 +406,6 @@ extern void ibmphp_hpc_stop_poll_thread (void);
 //----------------------------------------------------------------------------
 // HPC return codes
 //----------------------------------------------------------------------------
-#define FALSE                          0x00
-#define TRUE                           0x01
 #define HPC_ERROR                      0xFF
 
 //-----------------------------------------------------------------------------
index dc59da6..e13d5b8 100644 (file)
@@ -1141,7 +1141,7 @@ static int enable_slot(struct hotplug_slot *hs)
                goto error_power;
        }
 
-       slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
+       slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
        if (!slot_cur->func) {
                /* We cannot do update_slot_info here, since no memory for
                 * kmalloc n.e.ways, and update_slot_info allocates some */
@@ -1149,7 +1149,6 @@ static int enable_slot(struct hotplug_slot *hs)
                rc = -ENOMEM;
                goto error_power;
        }
-       memset(slot_cur->func, 0, sizeof(struct pci_func));
        slot_cur->func->busno = slot_cur->bus;
        slot_cur->func->device = slot_cur->device;
        for (i = 0; i < 4; i++)
@@ -1240,9 +1239,9 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
        }
        
        flag = slot_cur->flag;
-       slot_cur->flag = TRUE;
+       slot_cur->flag = 1;
 
-       if (flag == TRUE) {
+       if (flag == 1) {
                rc = validate(slot_cur, DISABLE);
                        /* checking if powered off already & valid slot # */
                if (rc)
@@ -1252,13 +1251,12 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
 
        if (slot_cur->func == NULL) {
                /* We need this for fncs's that were there on bootup */
-               slot_cur->func = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
+               slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
                if (!slot_cur->func) {
                        err("out of system memory\n");
                        rc = -ENOMEM;
                        goto error;
                }
-               memset(slot_cur->func, 0, sizeof(struct pci_func));
                slot_cur->func->busno = slot_cur->bus;
                slot_cur->func->device = slot_cur->device;
        }
index aea1187..05e4f5a 100644 (file)
@@ -72,13 +72,7 @@ static int ebda_rio_table (void);
 
 static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
 {
-       struct ebda_hpc_list *list;
-
-       list = kmalloc (sizeof (struct ebda_hpc_list), GFP_KERNEL);
-       if (!list)
-               return NULL;
-       memset (list, 0, sizeof (*list));
-       return list;
+       return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL);
 }
 
 static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
@@ -87,21 +81,18 @@ static struct controller *alloc_ebda_hpc (u32 slot_count, u32 bus_count)
        struct ebda_hpc_slot *slots;
        struct ebda_hpc_bus *buses;
 
-       controller = kmalloc (sizeof (struct controller), GFP_KERNEL);
+       controller = kzalloc(sizeof(struct controller), GFP_KERNEL);
        if (!controller)
                goto error;
-       memset (controller, 0, sizeof (*controller));
 
-       slots = kmalloc (sizeof (struct ebda_hpc_slot) * slot_count, GFP_KERNEL);
+       slots = kcalloc(slot_count, sizeof(struct ebda_hpc_slot), GFP_KERNEL);
        if (!slots)
                goto error_contr;
-       memset (slots, 0, sizeof (*slots) * slot_count);
        controller->slots = slots;
 
-       buses = kmalloc (sizeof (struct ebda_hpc_bus) * bus_count, GFP_KERNEL);
+       buses = kcalloc(bus_count, sizeof(struct ebda_hpc_bus), GFP_KERNEL);
        if (!buses)
                goto error_slots;
-       memset (buses, 0, sizeof (*buses) * bus_count);
        controller->buses = buses;
 
        return controller;
@@ -122,24 +113,12 @@ static void free_ebda_hpc (struct controller *controller)
 
 static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
 {
-       struct ebda_rsrc_list *list;
-
-       list = kmalloc (sizeof (struct ebda_rsrc_list), GFP_KERNEL);
-       if (!list)
-               return NULL;
-       memset (list, 0, sizeof (*list));
-       return list;
+       return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL);
 }
 
 static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
 {
-       struct ebda_pci_rsrc *resource;
-
-       resource = kmalloc (sizeof (struct ebda_pci_rsrc), GFP_KERNEL);
-       if (!resource)
-               return NULL;
-       memset (resource, 0, sizeof (*resource));
-       return resource;
+       return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL);
 }
 
 static void __init print_bus_info (void)
@@ -390,10 +369,9 @@ int __init ibmphp_access_ebda (void)
                        debug ("now enter io table ---\n");
                        debug ("rio blk id: %x\n", blk_id);
 
-                       rio_table_ptr = kmalloc (sizeof (struct rio_table_hdr), GFP_KERNEL);
+                       rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
                        if (!rio_table_ptr)
                                return -ENOMEM; 
-                       memset (rio_table_ptr, 0, sizeof (struct rio_table_hdr) );
                        rio_table_ptr->ver_num = readb (io_mem + offset);
                        rio_table_ptr->scal_count = readb (io_mem + offset + 1);
                        rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
@@ -445,10 +423,9 @@ static int __init ebda_rio_table (void)
 
        // we do concern about rio details
        for (i = 0; i < rio_table_ptr->riodev_count; i++) {
-               rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
+               rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL);
                if (!rio_detail_ptr)
                        return -ENOMEM;
-               memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
                rio_detail_ptr->rio_node_id = readb (io_mem + offset);
                rio_detail_ptr->bbar = readl (io_mem + offset + 1);
                rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
@@ -503,10 +480,9 @@ static int __init combine_wpg_for_chassis (void)
                rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
                opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
                if (!opt_rio_ptr) {
-                       opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
+                       opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
                        if (!opt_rio_ptr)
                                return -ENOMEM;
-                       memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
                        opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
                        opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
                        opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
@@ -546,10 +522,9 @@ static int combine_wpg_for_expansion (void)
                rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
                opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
                if (!opt_rio_lo_ptr) {
-                       opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
+                       opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
                        if (!opt_rio_lo_ptr)
                                return -ENOMEM;
-                       memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
                        opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
                        opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
                        opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
@@ -842,12 +817,11 @@ static int __init ebda_rsrc_controller (void)
 
                        bus_info_ptr2 = ibmphp_find_same_bus_num (slot_ptr->slot_bus_num);
                        if (!bus_info_ptr2) {
-                               bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL);
+                               bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL);
                                if (!bus_info_ptr1) {
                                        rc = -ENOMEM;
                                        goto error_no_hp_slot;
                                }
-                               memset (bus_info_ptr1, 0, sizeof (struct bus_info));
                                bus_info_ptr1->slot_min = slot_ptr->slot_num;
                                bus_info_ptr1->slot_max = slot_ptr->slot_num;
                                bus_info_ptr1->slot_count += 1;
@@ -946,19 +920,17 @@ static int __init ebda_rsrc_controller (void)
                // register slots with hpc core as well as create linked list of ibm slot
                for (index = 0; index < hpc_ptr->slot_count; index++) {
 
-                       hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
+                       hp_slot_ptr = kzalloc(sizeof(*hp_slot_ptr), GFP_KERNEL);
                        if (!hp_slot_ptr) {
                                rc = -ENOMEM;
                                goto error_no_hp_slot;
                        }
-                       memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr));
 
-                       hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL);
+                       hp_slot_ptr->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
                        if (!hp_slot_ptr->info) {
                                rc = -ENOMEM;
                                goto error_no_hp_info;
                        }
-                       memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info));
 
                        hp_slot_ptr->name = kmalloc(30, GFP_KERNEL);
                        if (!hp_slot_ptr->name) {
@@ -966,14 +938,13 @@ static int __init ebda_rsrc_controller (void)
                                goto error_no_hp_name;
                        }
 
-                       tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL);
+                       tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL);
                        if (!tmp_slot) {
                                rc = -ENOMEM;
                                goto error_no_slot;
                        }
-                       memset(tmp_slot, 0, sizeof(*tmp_slot));
 
-                       tmp_slot->flag = TRUE;
+                       tmp_slot->flag = 1;
 
                        tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;
                        if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
index 1a3eb8d..c3ac98a 100644 (file)
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
+
 #include "ibmphp.h"
 
-static int to_debug = FALSE;
+static int to_debug = 0;
 #define debug_polling(fmt, arg...)     do { if (to_debug) debug (fmt, arg); } while (0)
 
 //----------------------------------------------------------------------------
@@ -93,15 +95,15 @@ static int to_debug = FALSE;
 //----------------------------------------------------------------------------
 // macro utilities
 //----------------------------------------------------------------------------
-// if bits 20,22,25,26,27,29,30 are OFF return TRUE
-#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
+// if bits 20,22,25,26,27,29,30 are OFF return 1
+#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? 0 : 1))
 
 //----------------------------------------------------------------------------
 // global variables
 //----------------------------------------------------------------------------
 static int ibmphp_shutdown;
 static int tid_poll;
-static struct semaphore sem_hpcaccess; // lock access to HPC
+static struct mutex sem_hpcaccess;     // lock access to HPC
 static struct semaphore semOperations; // lock all operations and
                                        // access to data structures
 static struct semaphore sem_exit;      // make sure polling thread goes away
@@ -131,11 +133,11 @@ void __init ibmphp_hpc_initvars (void)
 {
        debug ("%s - Entry\n", __FUNCTION__);
 
-       init_MUTEX (&sem_hpcaccess);
+       mutex_init(&sem_hpcaccess);
        init_MUTEX (&semOperations);
        init_MUTEX_LOCKED (&sem_exit);
-       to_debug = FALSE;
-       ibmphp_shutdown = FALSE;
+       to_debug = 0;
+       ibmphp_shutdown = 0;
        tid_poll = 0;
 
        debug ("%s - Exit\n", __FUNCTION__);
@@ -737,21 +739,21 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
                // check controller is still not working on the command
                //--------------------------------------------------------------------
                timeout = CMD_COMPLETE_TOUT_SEC;
-               done = FALSE;
+               done = 0;
                while (!done) {
                        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
                                                        &status);
                        if (!rc) {
                                if (NEEDTOCHECK_CMDSTATUS (cmd)) {
                                        if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
-                                               done = TRUE;
+                                               done = 1;
                                } else
-                                       done = TRUE;
+                                       done = 1;
                        }
                        if (!done) {
                                msleep(1000);
                                if (timeout < 1) {
-                                       done = TRUE;
+                                       done = 1;
                                        err ("%s - Error command complete timeout\n", __FUNCTION__);
                                        rc = -EFAULT;
                                } else
@@ -778,7 +780,7 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
 *---------------------------------------------------------------------*/
 static void get_hpc_access (void)
 {
-       down (&sem_hpcaccess);
+       mutex_lock(&sem_hpcaccess);
 }
 
 /*----------------------------------------------------------------------
@@ -786,7 +788,7 @@ static void get_hpc_access (void)
 *---------------------------------------------------------------------*/
 void free_hpc_access (void)
 {
-       up (&sem_hpcaccess);
+       mutex_unlock(&sem_hpcaccess);
 }
 
 /*----------------------------------------------------------------------
@@ -797,7 +799,7 @@ void free_hpc_access (void)
 void ibmphp_lock_operations (void)
 {
        down (&semOperations);
-       to_debug = TRUE;
+       to_debug = 1;
 }
 
 /*----------------------------------------------------------------------
@@ -807,7 +809,7 @@ void ibmphp_unlock_operations (void)
 {
        debug ("%s - Entry\n", __FUNCTION__);
        up (&semOperations);
-       to_debug = FALSE;
+       to_debug = 0;
        debug ("%s - Exit\n", __FUNCTION__);
 }
 
@@ -935,40 +937,40 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
 {
        u8 status;
        int rc = 0;
-       u8 disable = FALSE;
-       u8 update = FALSE;
+       u8 disable = 0;
+       u8 update = 0;
 
        debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
 
        // bit 0 - HPC_SLOT_POWER
        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
-               update = TRUE;
+               update = 1;
 
        // bit 1 - HPC_SLOT_CONNECT
        // ignore
 
        // bit 2 - HPC_SLOT_ATTN
        if ((pslot->status & 0x04) != (poldslot->status & 0x04))
-               update = TRUE;
+               update = 1;
 
        // bit 3 - HPC_SLOT_PRSNT2
        // bit 4 - HPC_SLOT_PRSNT1
        if (((pslot->status & 0x08) != (poldslot->status & 0x08))
                || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
-               update = TRUE;
+               update = 1;
 
        // bit 5 - HPC_SLOT_PWRGD
        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
                // OFF -> ON: ignore, ON -> OFF: disable slot
                if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) 
-                       disable = TRUE;
+                       disable = 1;
 
        // bit 6 - HPC_SLOT_BUS_SPEED
        // ignore
 
        // bit 7 - HPC_SLOT_LATCH
        if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
-               update = TRUE;
+               update = 1;
                // OPEN -> CLOSE
                if (pslot->status & 0x80) {
                        if (SLOT_PWRGD (pslot->status)) {
@@ -977,7 +979,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
                                msleep(1000);
                                rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
                                if (SLOT_PWRGD (status))
-                                       update = TRUE;
+                                       update = 1;
                                else    // overwrite power in pslot to OFF
                                        pslot->status &= ~HPC_SLOT_POWER;
                        }
@@ -985,17 +987,17 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
                // CLOSE -> OPEN 
                else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
                        && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
-                       disable = TRUE;
+                       disable = 1;
                }
                // else - ignore
        }
        // bit 4 - HPC_SLOT_BLINK_ATTN
        if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
-               update = TRUE;
+               update = 1;
 
        if (disable) {
                debug ("process_changeinstatus - disable slot\n");
-               pslot->flag = FALSE;
+               pslot->flag = 0;
                rc = ibmphp_do_disable_slot (pslot);
        }
 
@@ -1100,7 +1102,7 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
 {
        debug ("%s - Entry\n", __FUNCTION__);
 
-       ibmphp_shutdown = TRUE;
+       ibmphp_shutdown = 1;
        debug ("before locking operations \n");
        ibmphp_lock_operations ();
        debug ("after locking operations \n");
@@ -1134,7 +1136,7 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v
                                    u8 * pstatus)
 {
        int rc = 0;
-       u8 done = FALSE;
+       u8 done = 0;
 
        debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
 
@@ -1142,14 +1144,14 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v
                *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
                if (*pstatus == HPC_ERROR) {
                        rc = HPC_ERROR;
-                       done = TRUE;
+                       done = 1;
                }
                if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
-                       done = TRUE;
+                       done = 1;
                if (!done) {
                        msleep(1000);
                        if (timeout < 1) {
-                               done = TRUE;
+                               done = 1;
                                err ("HPCreadslot - Error ctlr timeout\n");
                                rc = HPC_ERROR;
                        } else
index 155133f..d87a9e3 100644 (file)
@@ -164,12 +164,11 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                cleanup_count = 6;
                                                goto error;
                                        }
-                                       newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
+                                       newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                        if (!newfunc) {
                                                err ("out of system memory\n");
                                                return -ENOMEM;
                                        }
-                                       memset (newfunc, 0, sizeof (struct pci_func));
                                        newfunc->busno = cur_func->busno;
                                        newfunc->device = device;
                                        cur_func->next = newfunc;
@@ -200,15 +199,14 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                        }
 
                                        pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
-                                       flag = FALSE;
+                                       flag = 0;
                                        for (i = 0; i < 32; i++) {
                                                if (func->devices[i]) {
-                                                       newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
+                                                       newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                                        if (!newfunc) {
                                                                err ("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
-                                                       memset (newfunc, 0, sizeof (struct pci_func));
                                                        newfunc->busno = sec_number;
                                                        newfunc->device = (u8) i;
                                                        for (j = 0; j < 4; j++)
@@ -228,16 +226,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                                cleanup_count = 2;
                                                                goto error;
                                                        }
-                                                       flag = TRUE;
+                                                       flag = 1;
                                                }
                                        }
 
-                                       newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
+                                       newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                        if (!newfunc) {
                                                err ("out of system memory\n");
                                                return -ENOMEM;
                                        }
-                                       memset (newfunc, 0, sizeof (struct pci_func));
                                        newfunc->busno = cur_func->busno;
                                        newfunc->device = device;
                                        for (j = 0; j < 4; j++)
@@ -275,16 +272,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                cur_func->busno, device, function);
                                        pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
                                        debug ("after configuring bridge..., sec_number = %x\n", sec_number);
-                                       flag = FALSE;
+                                       flag = 0;
                                        for (i = 0; i < 32; i++) {
                                                if (func->devices[i]) {
                                                        debug ("inside for loop, device is %x\n", i);
-                                                       newfunc = kmalloc(sizeof(*newfunc), GFP_KERNEL);
+                                                       newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
                                                        if (!newfunc) {
                                                                err (" out of system memory\n");
                                                                return -ENOMEM;
                                                        }
-                                                       memset (newfunc, 0, sizeof (struct pci_func));
                                                        newfunc->busno = sec_number;
                                                        newfunc->device = (u8) i;
                                                        for (j = 0; j < 4; j++)
@@ -305,7 +301,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
                                                                cleanup_count = 2;
                                                                goto error;
                                                        }
-                                                       flag = TRUE;
+                                                       flag = 1;
                                                }
                                        }
 
@@ -405,13 +401,12 @@ static int configure_device (struct pci_func *func)
 
                        debug ("len[count] in IO %x, count %d\n", len[count], count);
 
-                       io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                       io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 
                        if (!io[count]) {
                                err ("out of system memory\n");
                                return -ENOMEM;
                        }
-                       memset (io[count], 0, sizeof (struct resource_node));
                        io[count]->type = IO;
                        io[count]->busno = func->busno;
                        io[count]->devfunc = PCI_DEVFN(func->device, func->function);
@@ -444,29 +439,27 @@ static int configure_device (struct pci_func *func)
 
                                debug ("len[count] in PFMEM %x, count %d\n", len[count], count);
 
-                               pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                               pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!pfmem[count]) {
                                        err ("out of system memory\n");
                                        return -ENOMEM;
                                }
-                               memset (pfmem[count], 0, sizeof (struct resource_node));
                                pfmem[count]->type = PFMEM;
                                pfmem[count]->busno = func->busno;
                                pfmem[count]->devfunc = PCI_DEVFN(func->device,
                                                        func->function);
                                pfmem[count]->len = len[count];
-                               pfmem[count]->fromMem = FALSE;
+                               pfmem[count]->fromMem = 0;
                                if (ibmphp_check_resource (pfmem[count], 0) == 0) {
                                        ibmphp_add_resource (pfmem[count]);
                                        func->pfmem[count] = pfmem[count];
                                } else {
-                                       mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
+                                       mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                                        if (!mem_tmp) {
                                                err ("out of system memory\n");
                                                kfree (pfmem[count]);
                                                return -ENOMEM;
                                        }
-                                       memset (mem_tmp, 0, sizeof (struct resource_node));
                                        mem_tmp->type = MEM;
                                        mem_tmp->busno = pfmem[count]->busno;
                                        mem_tmp->devfunc = pfmem[count]->devfunc;
@@ -474,7 +467,7 @@ static int configure_device (struct pci_func *func)
                                        debug ("there's no pfmem... going into mem.\n");
                                        if (ibmphp_check_resource (mem_tmp, 0) == 0) {
                                                ibmphp_add_resource (mem_tmp);
-                                               pfmem[count]->fromMem = TRUE;
+                                               pfmem[count]->fromMem = 1;
                                                pfmem[count]->rangeno = mem_tmp->rangeno;
                                                pfmem[count]->start = mem_tmp->start;
                                                pfmem[count]->end = mem_tmp->end;
@@ -512,12 +505,11 @@ static int configure_device (struct pci_func *func)
 
                                debug ("len[count] in Mem %x, count %d\n", len[count], count);
 
-                               mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                               mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!mem[count]) {
                                        err ("out of system memory\n");
                                        return -ENOMEM;
                                }
-                               memset (mem[count], 0, sizeof (struct resource_node));
                                mem[count]->type = MEM;
                                mem[count]->busno = func->busno;
                                mem[count]->devfunc = PCI_DEVFN(func->device,
@@ -579,11 +571,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
        u16 pfmem_base;
        u32 bar[2];
        u32 len[2];
-       u8 flag_io = FALSE;
-       u8 flag_mem = FALSE;
-       u8 flag_pfmem = FALSE;
-       u8 need_io_upper = FALSE;
-       u8 need_pfmem_upper = FALSE;
+       u8 flag_io = 0;
+       u8 flag_mem = 0;
+       u8 flag_pfmem = 0;
+       u8 need_io_upper = 0;
+       u8 need_pfmem_upper = 0;
        struct res_needed *amount_needed = NULL;
        struct resource_node *io = NULL;
        struct resource_node *bus_io[2] = {NULL, NULL};
@@ -677,14 +669,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
                        debug ("len[count] in IO = %x\n", len[count]);
 
-                       bus_io[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                       bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                
                        if (!bus_io[count]) {
                                err ("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
-                       memset (bus_io[count], 0, sizeof (struct resource_node));
                        bus_io[count]->type = IO;
                        bus_io[count]->busno = func->busno;
                        bus_io[count]->devfunc = PCI_DEVFN(func->device,
@@ -711,37 +702,35 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
                                debug ("len[count] in PFMEM = %x\n", len[count]);
 
-                               bus_pfmem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                               bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!bus_pfmem[count]) {
                                        err ("out of system memory\n");
                                        retval = -ENOMEM;
                                        goto error;
                                }
-                               memset (bus_pfmem[count], 0, sizeof (struct resource_node));
                                bus_pfmem[count]->type = PFMEM;
                                bus_pfmem[count]->busno = func->busno;
                                bus_pfmem[count]->devfunc = PCI_DEVFN(func->device,
                                                        func->function);
                                bus_pfmem[count]->len = len[count];
-                               bus_pfmem[count]->fromMem = FALSE;
+                               bus_pfmem[count]->fromMem = 0;
                                if (ibmphp_check_resource (bus_pfmem[count], 0) == 0) {
                                        ibmphp_add_resource (bus_pfmem[count]);
                                        func->pfmem[count] = bus_pfmem[count];
                                } else {
-                                       mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
+                                       mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                                        if (!mem_tmp) {
                                                err ("out of system memory\n");
                                                retval = -ENOMEM;
                                                goto error;
                                        }
-                                       memset (mem_tmp, 0, sizeof (struct resource_node));
                                        mem_tmp->type = MEM;
                                        mem_tmp->busno = bus_pfmem[count]->busno;
                                        mem_tmp->devfunc = bus_pfmem[count]->devfunc;
                                        mem_tmp->len = bus_pfmem[count]->len;
                                        if (ibmphp_check_resource (mem_tmp, 0) == 0) {
                                                ibmphp_add_resource (mem_tmp);
-                                               bus_pfmem[count]->fromMem = TRUE;
+                                               bus_pfmem[count]->fromMem = 1;
                                                bus_pfmem[count]->rangeno = mem_tmp->rangeno;
                                                ibmphp_add_pfmem_from_mem (bus_pfmem[count]);
                                                func->pfmem[count] = bus_pfmem[count];
@@ -770,13 +759,12 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
                                debug ("len[count] in Memory is %x\n", len[count]);
 
-                               bus_mem[count] = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                               bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!bus_mem[count]) {
                                        err ("out of system memory\n");
                                        retval = -ENOMEM;
                                        goto error;
                                }
-                               memset (bus_mem[count], 0, sizeof (struct resource_node));
                                bus_mem[count]->type = MEM;
                                bus_mem[count]->busno = func->busno;
                                bus_mem[count]->devfunc = PCI_DEVFN(func->device,
@@ -838,17 +826,16 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
        if (!amount_needed->io) {
                debug ("it doesn't want IO?\n");
-               flag_io = TRUE;
+               flag_io = 1;
        } else {
                debug ("it wants %x IO behind the bridge\n", amount_needed->io);
-               io = kmalloc(sizeof(*io), GFP_KERNEL);
+               io = kzalloc(sizeof(*io), GFP_KERNEL);
                
                if (!io) {
                        err ("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
-               memset (io, 0, sizeof (struct resource_node));
                io->type = IO;
                io->busno = func->busno;
                io->devfunc = PCI_DEVFN(func->device, func->function);
@@ -856,71 +843,68 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                if (ibmphp_check_resource (io, 1) == 0) {
                        debug ("were we able to add io\n");
                        ibmphp_add_resource (io);
-                       flag_io = TRUE;
+                       flag_io = 1;
                }
        }
 
        if (!amount_needed->mem) {
                debug ("it doesn't want n.e.memory?\n");
-               flag_mem = TRUE;
+               flag_mem = 1;
        } else {
                debug ("it wants %x memory behind the bridge\n", amount_needed->mem);
-               mem = kmalloc(sizeof(*mem), GFP_KERNEL);
+               mem = kzalloc(sizeof(*mem), GFP_KERNEL);
                if (!mem) {
                        err ("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
-               memset (mem, 0, sizeof (struct resource_node));
                mem->type = MEM;
                mem->busno = func->busno;
                mem->devfunc = PCI_DEVFN(func->device, func->function);
                mem->len = amount_needed->mem;
                if (ibmphp_check_resource (mem, 1) == 0) {
                        ibmphp_add_resource (mem);
-                       flag_mem = TRUE;
+                       flag_mem = 1;
                        debug ("were we able to add mem\n");
                }
        }
 
        if (!amount_needed->pfmem) {
                debug ("it doesn't want n.e.pfmem mem?\n");
-               flag_pfmem = TRUE;
+               flag_pfmem = 1;
        } else {
                debug ("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
-               pfmem = kmalloc(sizeof(*pfmem), GFP_KERNEL);
+               pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL);
                if (!pfmem) {
                        err ("out of system memory\n");
                        retval = -ENOMEM;
                        goto error;
                }
-               memset (pfmem, 0, sizeof (struct resource_node));
                pfmem->type = PFMEM;
                pfmem->busno = func->busno;
                pfmem->devfunc = PCI_DEVFN(func->device, func->function);
                pfmem->len = amount_needed->pfmem;
-               pfmem->fromMem = FALSE;
+               pfmem->fromMem = 0;
                if (ibmphp_check_resource (pfmem, 1) == 0) {
                        ibmphp_add_resource (pfmem);
-                       flag_pfmem = TRUE;
+                       flag_pfmem = 1;
                } else {
-                       mem_tmp = kmalloc(sizeof(*mem_tmp), GFP_KERNEL);
+                       mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
                        if (!mem_tmp) {
                                err ("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
-                       memset (mem_tmp, 0, sizeof (struct resource_node));
                        mem_tmp->type = MEM;
                        mem_tmp->busno = pfmem->busno;
                        mem_tmp->devfunc = pfmem->devfunc;
                        mem_tmp->len = pfmem->len;
                        if (ibmphp_check_resource (mem_tmp, 1) == 0) {
                                ibmphp_add_resource (mem_tmp);
-                               pfmem->fromMem = TRUE;
+                               pfmem->fromMem = 1;
                                pfmem->rangeno = mem_tmp->rangeno;
                                ibmphp_add_pfmem_from_mem (pfmem);
-                               flag_pfmem = TRUE;
+                               flag_pfmem = 1;
                        }
                }
        }
@@ -936,13 +920,12 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
                 */
                bus = ibmphp_find_res_bus (sec_number);
                if (!bus) {
-                       bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+                       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
                        if (!bus) {
                                err ("out of system memory\n");
                                retval = -ENOMEM;
                                goto error;
                        }
-                       memset (bus, 0, sizeof (struct bus_node));
                        bus->busno = sec_number;
                        debug ("b4 adding new bus\n");
                        rc = add_new_bus (bus, io, mem, pfmem, func->busno);
@@ -967,11 +950,11 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
 
                if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
                        debug ("io 32\n");
-                       need_io_upper = TRUE;
+                       need_io_upper = 1;
                }
                if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
                        debug ("pfmem 64\n");
-                       need_pfmem_upper = TRUE;
+                       need_pfmem_upper = 1;
                }
 
                if (bus->noIORanges) {
@@ -1111,10 +1094,9 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
        };
        struct res_needed *amount;
 
-       amount = kmalloc(sizeof(*amount), GFP_KERNEL);
+       amount = kzalloc(sizeof(*amount), GFP_KERNEL);
        if (amount == NULL)
                return NULL;
-       memset (amount, 0, sizeof (struct res_needed));
 
        ibmphp_pci_bus->number = busno;
 
@@ -1137,7 +1119,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
                                debug ("hdr_type behind the bridge is %x\n", hdr_type);
                                if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
                                        err ("embedded bridges not supported for hot-plugging.\n");
-                                       amount->not_correct = TRUE;
+                                       amount->not_correct = 1;
                                        return amount;
                                }
 
@@ -1145,12 +1127,12 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
                                if (class == PCI_CLASS_NOT_DEFINED_VGA) {
                                        err ("The device %x is VGA compatible and as is not supported for hot plugging. "
                                             "Please choose another device.\n", device);
-                                       amount->not_correct = TRUE;
+                                       amount->not_correct = 1;
                                        return amount;
                                } else if (class == PCI_CLASS_DISPLAY_VGA) {
                                        err ("The device %x is not supported for hot plugging. "
                                             "Please choose another device.\n", device);
-                                       amount->not_correct = TRUE;
+                                       amount->not_correct = 1;
                                        return amount;
                                }
 
@@ -1210,9 +1192,9 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
        }       /* end for */
 
        if (!howmany)
-               amount->not_correct = TRUE;
+               amount->not_correct = 1;
        else
-               amount->not_correct = FALSE;
+               amount->not_correct = 0;
        if ((amount->io) && (amount->io < IOBRIDGE))
                amount->io = IOBRIDGE;
        if ((amount->mem) && (amount->mem < MEMBRIDGE))
@@ -1672,12 +1654,11 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
                list_add (&bus->bus_list, &cur_bus->bus_list);
        }
        if (io) {
-               io_range = kmalloc(sizeof(*io_range), GFP_KERNEL);
+               io_range = kzalloc(sizeof(*io_range), GFP_KERNEL);
                if (!io_range) {
                        err ("out of system memory\n");
                        return -ENOMEM;
                }
-               memset (io_range, 0, sizeof (struct range_node));
                io_range->start = io->start;
                io_range->end = io->end;
                io_range->rangeno = 1;
@@ -1685,12 +1666,11 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
                bus->rangeIO = io_range;
        }
        if (mem) {
-               mem_range = kmalloc(sizeof(*mem_range), GFP_KERNEL);
+               mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL);
                if (!mem_range) {
                        err ("out of system memory\n");
                        return -ENOMEM;
                }
-               memset (mem_range, 0, sizeof (struct range_node));
                mem_range->start = mem->start;
                mem_range->end = mem->end;
                mem_range->rangeno = 1;
@@ -1698,12 +1678,11 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
                bus->rangeMem = mem_range;
        }
        if (pfmem) {
-               pfmem_range = kmalloc(sizeof(*pfmem_range), GFP_KERNEL);
+               pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL);
                if (!pfmem_range) {     
                        err ("out of system memory\n");
                        return -ENOMEM;
                }
-               memset (pfmem_range, 0, sizeof (struct range_node));
                pfmem_range->start = pfmem->start;
                pfmem_range->end = pfmem->end;
                pfmem_range->rangeno = 1;
index 9c224c9..5636b1a 100644 (file)
@@ -55,13 +55,12 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8
                return NULL;
        }
 
-       newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+       newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
        if (!newbus) {
                err ("out of system memory\n");
                return NULL;
        }
 
-       memset (newbus, 0, sizeof (struct bus_node));
        if (flag)
                newbus->busno = busno;
        else
@@ -79,12 +78,11 @@ static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * cur
                return NULL;
        }
 
-       rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+       rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
        if (!rs) {
                err ("out of system memory\n");
                return NULL;
        }
-       memset (rs, 0, sizeof (struct resource_node));
        rs->busno = curr->bus_num;
        rs->devfunc = curr->dev_fun;
        rs->start = curr->start_addr;
@@ -100,12 +98,11 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
        u8 num_ranges = 0;
 
        if (first_bus) {
-               newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+               newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
                if (!newbus) {
                        err ("out of system memory.\n");
                        return -ENOMEM;
                }
-               memset (newbus, 0, sizeof (struct bus_node));
                newbus->busno = curr->bus_num;
        } else {
                newbus = *new_bus;
@@ -122,14 +119,13 @@ static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node
                }
        }
 
-       newrange = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+       newrange = kzalloc(sizeof(struct range_node), GFP_KERNEL);
        if (!newrange) {
                if (first_bus)
                        kfree (newbus);
                err ("out of system memory\n");
                return -ENOMEM;
        }
-       memset (newrange, 0, sizeof (struct range_node));
        newrange->start = curr->start_addr;
        newrange->end = curr->end_addr;
                
@@ -329,7 +325,7 @@ int __init ibmphp_rsrc_init (void)
                                if (!new_pfmem)
                                        return -ENOMEM;
                                new_pfmem->type = PFMEM;
-                               new_pfmem->fromMem = FALSE;
+                               new_pfmem->fromMem = 0;
                                if (ibmphp_add_resource (new_pfmem) < 0) {
                                        newbus = alloc_error_bus (curr, 0, 0);
                                        if (!newbus)
@@ -466,7 +462,7 @@ static int add_range (int type, struct range_node *range, struct bus_node *bus_c
 static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
 {
        struct resource_node *res = NULL;
-       u8 eol = FALSE; /* end of list indicator */
+       u8 eol = 0;     /* end of list indicator */
 
        switch (type) {
                case MEM:
@@ -492,7 +488,7 @@ static void update_resources (struct bus_node *bus_cur, int type, int rangeno)
                        else if (res->nextRange)
                                res = res->nextRange;
                        else {
-                               eol = TRUE;
+                               eol = 1;
                                break;
                        }
                }
@@ -983,7 +979,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
        int noranges = 0;
        u32 tmp_start;          /* this is to make sure start address is divisible by the length needed */
        u32 tmp_divide;
-       u8 flag = FALSE;
+       u8 flag = 0;
 
        if (!res)
                return -EINVAL;
@@ -1050,17 +1046,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
 
                                        if ((range->start % tmp_divide) == 0) {
                                                /* just perfect, starting address is divisible by length */
-                                               flag = TRUE;
+                                               flag = 1;
                                                len_cur = len_tmp;
                                                start_cur = range->start;
                                        } else {
                                                /* Needs adjusting */
                                                tmp_start = range->start;
-                                               flag = FALSE;
+                                               flag = 0;
 
                                                while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
                                                        if ((tmp_start % tmp_divide) == 0) {
-                                                               flag = TRUE;
+                                                               flag = 1;
                                                                len_cur = len_tmp;
                                                                start_cur = tmp_start;
                                                                break;
@@ -1089,17 +1085,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
 
                                        if (((res_cur->end + 1) % tmp_divide) == 0) {
                                                /* just perfect, starting address is divisible by length */
-                                               flag = TRUE;
+                                               flag = 1;
                                                len_cur = len_tmp;
                                                start_cur = res_cur->end + 1;
                                        } else {
                                                /* Needs adjusting */
                                                tmp_start = res_cur->end + 1;
-                                               flag = FALSE;
+                                               flag = 0;
 
                                                while ((len_tmp = range->end - tmp_start) >= res->len) {
                                                        if ((tmp_start % tmp_divide) == 0) {
-                                                               flag = TRUE;
+                                                               flag = 1;
                                                                len_cur = len_tmp;
                                                                start_cur = tmp_start;
                                                                break;
@@ -1127,17 +1123,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                        if ((len_tmp < len_cur) || (len_cur == 0)) {
                                                if ((range->start % tmp_divide) == 0) { 
                                                        /* just perfect, starting address is divisible by length */
-                                                       flag = TRUE;
+                                                       flag = 1;
                                                        len_cur = len_tmp;
                                                        start_cur = range->start;
                                                } else {
                                                        /* Needs adjusting */
                                                        tmp_start = range->start;
-                                                       flag = FALSE;
+                                                       flag = 0;
 
                                                        while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
                                                                if ((tmp_start % tmp_divide) == 0) {
-                                                                       flag = TRUE;
+                                                                       flag = 1;
                                                                        len_cur = len_tmp;
                                                                        start_cur = tmp_start;
                                                                        break;
@@ -1162,17 +1158,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                        if ((len_tmp < len_cur) || (len_cur == 0)) {
                                                if (((res_prev->end + 1) % tmp_divide) == 0) {
                                                        /* just perfect, starting address's divisible by length */
-                                                       flag = TRUE;
+                                                       flag = 1;
                                                        len_cur = len_tmp;
                                                        start_cur = res_prev->end + 1;
                                                } else {
                                                        /* Needs adjusting */
                                                        tmp_start = res_prev->end + 1;
-                                                       flag = FALSE;
+                                                       flag = 0;
 
                                                        while ((len_tmp = res_cur->start - 1 - tmp_start) >= res->len) {
                                                                if ((tmp_start % tmp_divide) == 0) {
-                                                                       flag = TRUE;
+                                                                       flag = 1;
                                                                        len_cur = len_tmp;
                                                                        start_cur = tmp_start;
                                                                        break;
@@ -1221,17 +1217,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                if ((len_tmp < len_cur) || (len_cur == 0)) {
                                        if ((range->start % tmp_divide) == 0) {
                                                /* just perfect, starting address's divisible by length */
-                                               flag = TRUE;
+                                               flag = 1;
                                                len_cur = len_tmp;
                                                start_cur = range->start;
                                        } else {
                                                /* Needs adjusting */
                                                tmp_start = range->start;
-                                               flag = FALSE;
+                                               flag = 0;
 
                                                while ((len_tmp = range->end - tmp_start) >= res->len) {
                                                        if ((tmp_start % tmp_divide) == 0) {
-                                                               flag = TRUE;
+                                                               flag = 1;
                                                                len_cur = len_tmp;
                                                                start_cur = tmp_start;
                                                                break;
@@ -1285,17 +1281,17 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
                                        if ((len_tmp < len_cur) || (len_cur == 0)) {
                                                if ((range->start % tmp_divide) == 0) {
                                                        /* just perfect, starting address's divisible by length */
-                                                       flag = TRUE;
+                                                       flag = 1;
                                                        len_cur = len_tmp;
                                                        start_cur = range->start;
                                                } else {
                                                        /* Needs adjusting */
                                                        tmp_start = range->start;
-                                                       flag = FALSE;
+                                                       flag = 0;
 
                                                        while ((len_tmp = range->end - tmp_start) >= res->len) {
                                                                if ((tmp_start % tmp_divide) == 0) {
-                                                                       flag = TRUE;
+                                                                       flag = 1;
                                                                        len_cur = len_tmp;
                                                                        start_cur = tmp_start;
                                                                        break;
@@ -1688,7 +1684,7 @@ static int __init once_over (void)
                bus_cur = list_entry (tmp, struct bus_node, bus_list);
                if ((!bus_cur->rangePFMem) && (bus_cur->firstPFMem)) {
                        for (pfmem_cur = bus_cur->firstPFMem, pfmem_prev = NULL; pfmem_cur; pfmem_prev = pfmem_cur, pfmem_cur = pfmem_cur->next) {
-                               pfmem_cur->fromMem = TRUE;
+                               pfmem_cur->fromMem = 1;
                                if (pfmem_prev)
                                        pfmem_prev->next = pfmem_cur->next;
                                else
@@ -1705,12 +1701,11 @@ static int __init once_over (void)
 
                                bus_cur->firstPFMemFromMem = pfmem_cur;
 
-                               mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);              
+                               mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                if (!mem) {
                                        err ("out of system memory\n");
                                        return -ENOMEM;
                                }
-                               memset (mem, 0, sizeof (struct resource_node));
                                mem->type = MEM;
                                mem->busno = pfmem_cur->busno;
                                mem->devfunc = pfmem_cur->devfunc;
@@ -1994,12 +1989,11 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                end_address |= (upper_io_end << 16);
 
                                                if ((start_address) && (start_address <= end_address)) {
-                                                       range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+                                                       range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
                                                                err ("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
-                                                       memset (range, 0, sizeof (struct range_node));
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfff;
 
@@ -2020,13 +2014,12 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                        fix_resources (bus_sec);
 
                                                        if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
-                                                               io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);                                                       
+                                                               io = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!io) {
                                                                        kfree (range);
                                                                        err ("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
-                                                               memset (io, 0, sizeof (struct resource_node));
                                                                io->type = IO;
                                                                io->busno = bus_cur->busno;
                                                                io->devfunc = ((device << 3) | (function & 0x7));
@@ -2045,12 +2038,11 @@ static int __init update_bridge_ranges (struct bus_node **bus)
 
                                                if ((start_address) && (start_address <= end_address)) {
 
-                                                       range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+                                                       range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
                                                                err ("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
-                                                       memset (range, 0, sizeof (struct range_node));
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfffff;
 
@@ -2072,13 +2064,12 @@ static int __init update_bridge_ranges (struct bus_node **bus)
                                                        fix_resources (bus_sec);
 
                                                        if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
-                                                               mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                                                               mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!mem) {
                                                                        kfree (range);
                                                                        err ("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
-                                                               memset (mem, 0, sizeof (struct resource_node));
                                                                mem->type = MEM;
                                                                mem->busno = bus_cur->busno;
                                                                mem->devfunc = ((device << 3) | (function & 0x7));
@@ -2101,12 +2092,11 @@ static int __init update_bridge_ranges (struct bus_node **bus)
 
                                                if ((start_address) && (start_address <= end_address)) {
 
-                                                       range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
+                                                       range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
                                                        if (!range) {
                                                                err ("out of system memory\n");
                                                                return -ENOMEM;
                                                        }
-                                                       memset (range, 0, sizeof (struct range_node));
                                                        range->start = start_address;
                                                        range->end = end_address + 0xfffff;
 
@@ -2127,20 +2117,19 @@ static int __init update_bridge_ranges (struct bus_node **bus)
 
                                                        fix_resources (bus_sec);
                                                        if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
-                                                               pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+                                                               pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
                                                                if (!pfmem) {
                                                                        kfree (range);
                                                                        err ("out of system memory\n");
                                                                        return -ENOMEM;
                                                                }
-                                                               memset (pfmem, 0, sizeof (struct resource_node));
                                                                pfmem->type = PFMEM;
                                                                pfmem->busno = bus_cur->busno;
                                                                pfmem->devfunc = ((device << 3) | (function & 0x7));
                                                                pfmem->start = start_address;
                                                                pfmem->end = end_address + 0xfffff;
                                                                pfmem->len = pfmem->end - pfmem->start + 1;
-                                                               pfmem->fromMem = FALSE;
+                                                               pfmem->fromMem = 0;
 
                                                                ibmphp_add_resource (pfmem);
                                                        }
index 88d44f7..eb0d01d 100644 (file)
@@ -176,5 +176,21 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
                                         struct hotplug_slot_info *info);
 extern struct subsystem pci_hotplug_slots_subsys;
 
+struct hotplug_params {
+       u8 cache_line_size;
+       u8 latency_timer;
+       u8 enable_serr;
+       u8 enable_perr;
+};
+
+#ifdef CONFIG_ACPI
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/actypes.h>
+extern acpi_status acpi_run_oshp(acpi_handle handle);
+extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
+                               struct hotplug_params *hpp);
+int acpi_root_bridge(acpi_handle handle);
+#endif
 #endif
 
index 0aac6a6..92c1f0f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/sched.h>               /* signal_pending() */
 #include <linux/pcieport_if.h>
+#include <linux/mutex.h>
 #include "pci_hotplug.h"
 
 #define MY_NAME        "pciehp"
@@ -49,12 +50,6 @@ extern int pciehp_force;
 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
-struct hotplug_params {
-       u8 cache_line_size;
-       u8 latency_timer;
-       u8 enable_serr;
-       u8 enable_perr;
-};
 
 struct slot {
        struct slot *next;
@@ -96,7 +91,7 @@ struct php_ctlr_state_s {
 #define MAX_EVENTS             10
 struct controller {
        struct controller *next;
-       struct semaphore crit_sect;     /* critical section semaphore */
+       struct mutex crit_sect;         /* critical section mutex */
        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 */
@@ -191,9 +186,6 @@ extern u8   pciehp_handle_power_fault       (u8 hp_slot, void *inst_id);
 /* pci functions */
 extern int     pciehp_configure_device         (struct slot *p_slot);
 extern int     pciehp_unconfigure_device       (struct slot *p_slot);
-extern int     pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
-extern void    pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp);
 
 
 
@@ -285,4 +277,19 @@ struct hpc_ops {
        int     (*check_lnk_status)     (struct controller *ctrl);
 };
 
+
+#ifdef CONFIG_ACPI
+#define pciehp_get_hp_hw_control_from_firmware(dev) \
+       pciehp_acpi_get_hp_hw_control_from_firmware(dev)
+static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
+                       struct hotplug_params *hpp)
+{
+       if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
+               return -ENODEV;
+       return 0;
+}
+#else
+#define pciehp_get_hp_hw_control_from_firmware(dev)    0
+#define pciehp_get_hp_params_from_firmware(dev, hpp)    (-ENODEV)
+#endif                                 /* CONFIG_ACPI */
 #endif                         /* _PCIEHP_H */
index 4fb5690..601cf90 100644 (file)
@@ -117,27 +117,23 @@ static int init_slots(struct controller *ctrl)
        slot_number = ctrl->first_slot;
 
        while (number_of_slots) {
-               slot = kmalloc(sizeof(*slot), GFP_KERNEL);
+               slot = kzalloc(sizeof(*slot), GFP_KERNEL);
                if (!slot)
                        goto error;
 
-               memset(slot, 0, sizeof(struct slot));
                slot->hotplug_slot =
-                               kmalloc(sizeof(*(slot->hotplug_slot)),
+                               kzalloc(sizeof(*(slot->hotplug_slot)),
                                                GFP_KERNEL);
                if (!slot->hotplug_slot)
                        goto error_slot;
                hotplug_slot = slot->hotplug_slot;
-               memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
 
                hotplug_slot->info =
-                       kmalloc(sizeof(*(hotplug_slot->info)),
+                       kzalloc(sizeof(*(hotplug_slot->info)),
                                                GFP_KERNEL);
                if (!hotplug_slot->info)
                        goto error_hpslot;
                hotplug_slot_info = hotplug_slot->info;
-               memset(hotplug_slot_info, 0,
-                                       sizeof(struct hotplug_slot_info));
                hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
                if (!hotplug_slot->name)
                        goto error_info;
@@ -373,12 +369,11 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        u8 value;
        struct pci_dev *pdev;
        
-       ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
+       ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
        if (!ctrl) {
                err("%s : out of memory\n", __FUNCTION__);
                goto err_out_none;
        }
-       memset(ctrl, 0, sizeof(struct controller));
 
        pdev = dev->port;
        ctrl->pci_dev = pdev;
@@ -439,7 +434,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        }
 
        /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
        
@@ -447,7 +442,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
                rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
                if (rc) {
                        /* Done with exclusive hardware access */
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        goto err_out_free_ctrl_slot;
                } else
                        /* Wait for the command to complete */
@@ -455,7 +450,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        }
 
        /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        return 0;
 
index 83c4b86..33d1987 100644 (file)
@@ -229,13 +229,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 {
        /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
        if (POWER_CTRL(ctrl->ctrlcap)) {
                if (pslot->hpc_ops->power_off_slot(pslot)) {   
                        err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        return;
                }
                wait_for_ctrl_irq (ctrl);
@@ -249,14 +249,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
        if (ATTN_LED(ctrl->ctrlcap)) { 
                if (pslot->hpc_ops->set_attention_status(pslot, 1)) {   
                        err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        return;
                }
                wait_for_ctrl_irq (ctrl);
        }
 
        /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 }
 
 /**
@@ -279,13 +279,13 @@ static int board_added(struct slot *p_slot)
                        ctrl->slot_device_offset, hp_slot);
 
        /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* Power on slot */
                rc = p_slot->hpc_ops->power_on_slot(p_slot);
                if (rc) {
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        return -1;
                }
 
@@ -301,7 +301,7 @@ static int board_added(struct slot *p_slot)
        }
 
        /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        /* Wait for ~1 second */
        wait_for_ctrl_irq (ctrl);
@@ -335,7 +335,7 @@ static int board_added(struct slot *p_slot)
                pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
        if (PWR_LED(ctrl->ctrlcap)) {
                /* Wait for exclusive access to hardware */
-               down(&ctrl->crit_sect);
+               mutex_lock(&ctrl->crit_sect);
 
                p_slot->hpc_ops->green_led_on(p_slot);
   
@@ -343,7 +343,7 @@ static int board_added(struct slot *p_slot)
                wait_for_ctrl_irq (ctrl);
        
                /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->crit_sect);
        }
        return 0;
 
@@ -375,14 +375,14 @@ static int remove_board(struct slot *p_slot)
        dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
 
        /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
+       mutex_lock(&ctrl->crit_sect);
 
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* power off slot */
                rc = p_slot->hpc_ops->power_off_slot(p_slot);
                if (rc) {
                        err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-                       up(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->crit_sect);
                        return rc;
                }
                /* Wait for the command to complete */
@@ -398,7 +398,7 @@ static int remove_board(struct slot *p_slot)
        }
 
        /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->crit_sect);
 
        return 0;
 }
@@ -445,7 +445,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
 
                if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
                        /* Wait for exclusive access to hardware */
-                       down(&p_slot->ctrl->crit_sect);
+                       mutex_lock(&p_slot->ctrl->crit_sect);
 
                        p_slot->hpc_ops->green_led_off(p_slot);
 
@@ -453,7 +453,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
                        wait_for_ctrl_irq (p_slot->ctrl);
 
                        /* Done with exclusive hardware access */
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                }
                p_slot->state = STATIC_STATE;
        }
@@ -495,7 +495,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
 
                if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
                        /* Wait for exclusive access to hardware */
-                       down(&p_slot->ctrl->crit_sect);
+                       mutex_lock(&p_slot->ctrl->crit_sect);
 
                        p_slot->hpc_ops->green_led_off(p_slot);
 
@@ -503,7 +503,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
                        wait_for_ctrl_irq (p_slot->ctrl);
 
                        /* Done with exclusive hardware access */
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                }
                p_slot->state = STATIC_STATE;
        }
@@ -616,7 +616,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        switch (p_slot->state) {
                                        case BLINKINGOFF_STATE:
                                                /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->crit_sect);
                                                
                                                if (PWR_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->green_led_on(p_slot);
@@ -630,11 +630,11 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        wait_for_ctrl_irq (ctrl);
                                                }
                                                /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->crit_sect);
                                                break;
                                        case BLINKINGON_STATE:
                                                /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->crit_sect);
 
                                                if (PWR_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->green_led_off(p_slot);
@@ -647,7 +647,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        wait_for_ctrl_irq (ctrl);
                                                }
                                                /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->crit_sect);
 
                                                break;
                                        default:
@@ -676,7 +676,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                }
 
                                                /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->crit_sect);
 
                                                /* blink green LED and turn off amber */
                                                if (PWR_LED(ctrl->ctrlcap)) {
@@ -693,7 +693,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                }
 
                                                /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->crit_sect);
 
                                                init_timer(&p_slot->task_event);
                                                p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
@@ -708,7 +708,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        if (POWER_CTRL(ctrl->ctrlcap)) {
                                                dbg("power fault\n");
                                                /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->crit_sect);
 
                                                if (ATTN_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->set_attention_status(p_slot, 1);
@@ -721,7 +721,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                }
 
                                                /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->crit_sect);
                                        }
                                }
                                /***********SURPRISE REMOVAL********************/
@@ -756,19 +756,19 @@ int pciehp_enable_slot(struct slot *p_slot)
        int rc;
 
        /* Check to see if (latch closed, card present, power off) */
-       down(&p_slot->ctrl->crit_sect);
+       mutex_lock(&p_slot->ctrl->crit_sect);
 
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
+               mutex_unlock(&p_slot->ctrl->crit_sect);
                return 1;
        }
        if (MRL_SENS(p_slot->ctrl->ctrlcap)) {  
                rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (rc || getstatus) {
                        info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                        return 1;
                }
        }
@@ -777,11 +777,11 @@ int pciehp_enable_slot(struct slot *p_slot)
                rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (rc || getstatus) {
                        info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                        return 1;
                }
        }
-       up(&p_slot->ctrl->crit_sect);
+       mutex_unlock(&p_slot->ctrl->crit_sect);
 
        p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
@@ -806,13 +806,13 @@ int pciehp_disable_slot(struct slot *p_slot)
                return 1;
 
        /* Check to see if (latch closed, card present, power on) */
-       down(&p_slot->ctrl->crit_sect);
+       mutex_lock(&p_slot->ctrl->crit_sect);
 
        if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {       
                ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
                if (ret || !getstatus) {
                        info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                        return 1;
                }
        }
@@ -821,7 +821,7 @@ int pciehp_disable_slot(struct slot *p_slot)
                ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (ret || getstatus) {
                        info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                        return 1;
                }
        }
@@ -830,12 +830,12 @@ int pciehp_disable_slot(struct slot *p_slot)
                ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (ret || !getstatus) {
                        info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
-                       up(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->crit_sect);
                        return 1;
                }
        }
 
-       up(&p_slot->ctrl->crit_sect);
+       mutex_unlock(&p_slot->ctrl->crit_sect);
 
        ret = remove_board(p_slot);
        update_slot_info(p_slot);
index 77e5303..6c14d9e 100644 (file)
 
 #include "../pci.h"
 #include "pciehp.h"
-
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/actypes.h>
+#include <linux/pci-acpi.h>
 #ifdef DEBUG
 #define DBG_K_TRACE_ENTRY      ((unsigned int)0x00000001)      /* On function entry */
 #define DBG_K_TRACE_EXIT       ((unsigned int)0x00000002)      /* On function exit */
@@ -1236,6 +1239,76 @@ static struct hpc_ops pciehp_hpc_ops = {
        .check_lnk_status               = hpc_check_lnk_status,
 };
 
+#ifdef CONFIG_ACPI
+int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
+{
+       acpi_status status;
+       acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
+       struct pci_dev *pdev = dev;
+       struct pci_bus *parent;
+       struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
+
+       /*
+        * Per PCI firmware specification, we should run the ACPI _OSC
+        * method to get control of hotplug hardware before using it.
+        * If an _OSC is missing, we look for an OSHP to do the same thing.
+        * To handle different BIOS behavior, we look for _OSC and OSHP
+        * within the scope of the hotplug controller and its parents, upto
+        * the host bridge under which this controller exists.
+        */
+       while (!handle) {
+               /*
+                * This hotplug controller was not listed in the ACPI name
+                * space at all. Try to get acpi handle of parent pci bus.
+                */
+               if (!pdev || !pdev->bus->parent)
+                       break;
+               parent = pdev->bus->parent;
+               dbg("Could not find %s in acpi namespace, trying parent\n",
+                               pci_name(pdev));
+               if (!parent->self)
+                       /* Parent must be a host bridge */
+                       handle = acpi_get_pci_rootbridge_handle(
+                                       pci_domain_nr(parent),
+                                       parent->number);
+               else
+                       handle = DEVICE_ACPI_HANDLE(
+                                       &(parent->self->dev));
+               pdev = parent->self;
+       }
+
+       while (handle) {
+               acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
+               dbg("Trying to get hotplug control for %s \n",
+                       (char *)string.pointer);
+               status = pci_osc_control_set(handle,
+                               OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
+               if (status == AE_NOT_FOUND)
+                       status = acpi_run_oshp(handle);
+               if (ACPI_SUCCESS(status)) {
+                       dbg("Gained control for hotplug HW for pci %s (%s)\n",
+                               pci_name(dev), (char *)string.pointer);
+                       acpi_os_free(string.pointer);
+                       return 0;
+               }
+               if (acpi_root_bridge(handle))
+                       break;
+               chandle = handle;
+               status = acpi_get_parent(chandle, &handle);
+               if (ACPI_FAILURE(status))
+                       break;
+       }
+
+       err("Cannot get control of hotplug hardware for pci %s\n",
+                       pci_name(dev));
+
+       acpi_os_free(string.pointer);
+       return -1;
+}
+#endif
+
+
+
 int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 {
        struct php_ctlr_state_s *php_ctlr, *p;
@@ -1334,7 +1407,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
        if (pci_enable_device(pdev))
                goto abort_free_ctlr;
        
-       init_MUTEX(&ctrl->crit_sect);
+       mutex_init(&ctrl->crit_sect);
        /* setup wait queue */
        init_waitqueue_head(&ctrl->queue);
 
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
deleted file mode 100644 (file)
index 2bdb30f..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
- *
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <kristen.c.accardi@intel.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include <linux/pci-acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/actypes.h>
-#include "pciehp.h"
-
-#define        METHOD_NAME__SUN        "_SUN"
-#define        METHOD_NAME__HPP        "_HPP"
-#define        METHOD_NAME_OSHP        "OSHP"
-
-static u8 * acpi_path_name( acpi_handle        handle)
-{
-       acpi_status             status;
-       static u8               path_name[ACPI_PATHNAME_MAX];
-       struct acpi_buffer      ret_buf = { ACPI_PATHNAME_MAX, path_name };
-
-       memset(path_name, 0, sizeof (path_name));
-       status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
-
-       if (ACPI_FAILURE(status))
-               return NULL;
-       else
-               return path_name;       
-}
-
-static acpi_status
-acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
-{
-       acpi_status             status;
-       u8                      nui[4];
-       struct acpi_buffer      ret_buf = { 0, NULL};
-       union acpi_object       *ext_obj, *package;
-       u8                      *path_name = acpi_path_name(handle);
-       int                     i, len = 0;
-
-       /* get _hpp */
-       status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
-       switch (status) {
-       case AE_BUFFER_OVERFLOW:
-               ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
-               if (!ret_buf.pointer) {
-                       err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
-                                       path_name);
-                       return AE_NO_MEMORY;
-               }
-               status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
-                               NULL, &ret_buf);
-               if (ACPI_SUCCESS(status))
-                       break;
-       default:
-               if (ACPI_FAILURE(status)) {
-                       dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
-                                       path_name, status);
-                       return status;
-               }
-       }
-
-       ext_obj = (union acpi_object *) ret_buf.pointer;
-       if (ext_obj->type != ACPI_TYPE_PACKAGE) {
-               err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
-                               path_name);
-               status = AE_ERROR;
-               goto free_and_return;
-       }
-
-       len = ext_obj->package.count;
-       package = (union acpi_object *) ret_buf.pointer;
-       for ( i = 0; (i < len) || (i < 4); i++) {
-               ext_obj = (union acpi_object *) &package->package.elements[i];
-               switch (ext_obj->type) {
-               case ACPI_TYPE_INTEGER:
-                       nui[i] = (u8)ext_obj->integer.value;
-                       break;
-               default:
-                       err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
-                                       path_name);
-                       status = AE_ERROR;
-                       goto free_and_return;
-               }
-       }
-
-       hpp->cache_line_size = nui[0];
-       hpp->latency_timer = nui[1];
-       hpp->enable_serr = nui[2];
-       hpp->enable_perr = nui[3];
-
-       dbg("  _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
-       dbg("  _HPP: latency timer  =0x%x\n", hpp->latency_timer);
-       dbg("  _HPP: enable SERR    =0x%x\n", hpp->enable_serr);
-       dbg("  _HPP: enable PERR    =0x%x\n", hpp->enable_perr);
-
-free_and_return:
-       kfree(ret_buf.pointer);
-       return status;
-}
-
-static acpi_status acpi_run_oshp(acpi_handle handle)
-{
-       acpi_status             status;
-       u8                      *path_name = acpi_path_name(handle);
-
-       /* run OSHP */
-       status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
-       if (ACPI_FAILURE(status)) {
-               dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
-                               status);
-       } else {
-               dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
-       }
-       return status;
-}
-
-static int is_root_bridge(acpi_handle handle)
-{
-       acpi_status status;
-       struct acpi_device_info *info;
-       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       int i;
-
-       status = acpi_get_object_info(handle, &buffer);
-       if (ACPI_SUCCESS(status)) {
-               info = buffer.pointer;
-               if ((info->valid & ACPI_VALID_HID) &&
-                       !strcmp(PCI_ROOT_HID_STRING,
-                                       info->hardware_id.value)) {
-                       acpi_os_free(buffer.pointer);
-                       return 1;
-               }
-               if (info->valid & ACPI_VALID_CID) {
-                       for (i=0; i < info->compatibility_id.count; i++) {
-                               if (!strcmp(PCI_ROOT_HID_STRING,
-                                       info->compatibility_id.id[i].value)) {
-                                       acpi_os_free(buffer.pointer);
-                                       return 1;
-                               }
-                       }
-               }
-       }
-       return 0;
-}
-
-int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
-       acpi_status status;
-       acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
-       struct pci_dev *pdev = dev;
-       struct pci_bus *parent;
-       u8 *path_name;
-
-       /*
-        * Per PCI firmware specification, we should run the ACPI _OSC
-        * method to get control of hotplug hardware before using it.
-        * If an _OSC is missing, we look for an OSHP to do the same thing.
-        * To handle different BIOS behavior, we look for _OSC and OSHP
-        * within the scope of the hotplug controller and its parents, upto
-        * the host bridge under which this controller exists.
-        */
-       while (!handle) {
-               /*
-                * This hotplug controller was not listed in the ACPI name
-                * space at all. Try to get acpi handle of parent pci bus.
-                */
-               if (!pdev || !pdev->bus->parent)
-                       break;
-               parent = pdev->bus->parent;
-               dbg("Could not find %s in acpi namespace, trying parent\n",
-                               pci_name(pdev));
-               if (!parent->self)
-                       /* Parent must be a host bridge */
-                       handle = acpi_get_pci_rootbridge_handle(
-                                       pci_domain_nr(parent),
-                                       parent->number);
-               else
-                       handle = DEVICE_ACPI_HANDLE(
-                                       &(parent->self->dev));
-               pdev = parent->self;
-       }
-
-       while (handle) {
-               path_name = acpi_path_name(handle);
-               dbg("Trying to get hotplug control for %s \n", path_name);
-               status = pci_osc_control_set(handle,
-                               OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
-               if (status == AE_NOT_FOUND)
-                       status = acpi_run_oshp(handle);
-               if (ACPI_SUCCESS(status)) {
-                       dbg("Gained control for hotplug HW for pci %s (%s)\n",
-                               pci_name(dev), path_name);
-                       return 0;
-               }
-               if (is_root_bridge(handle))
-                       break;
-               chandle = handle;
-               status = acpi_get_parent(chandle, &handle);
-               if (ACPI_FAILURE(status))
-                       break;
-       }
-
-       err("Cannot get control of hotplug hardware for pci %s\n",
-                       pci_name(dev));
-       return -1;
-}
-
-void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp)
-{
-       acpi_status status = AE_NOT_FOUND;
-       struct pci_dev *pdev = dev;
-
-       /*
-        * _HPP settings apply to all child buses, until another _HPP is
-        * encountered. If we don't find an _HPP for the input pci dev,
-        * look for it in the parent device scope since that would apply to
-        * this pci dev. If we don't find any _HPP, use hardcoded defaults
-        */
-       while (pdev && (ACPI_FAILURE(status))) {
-               acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
-               if (!handle)
-                       break;
-               status = acpi_run_hpp(handle, hpp);
-               if (!(pdev->bus->parent))
-                       break;
-               /* Check if a parent object supports _HPP */
-               pdev = pdev->bus->parent->self;
-       }
-}
-
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
deleted file mode 100644 (file)
index 29180df..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include "pciehp.h"
-
-void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp)
-{
-       return;
-}
-
-int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
-       return 0;
-}
index 3194d51..0a46f54 100644 (file)
 #include <linux/init.h>
 #include "pci_hotplug.h"
 
+#define SLOT_NAME_SIZE 10
 struct slot {
        u8 number;
        struct hotplug_slot *hotplug_slot;
        struct list_head slot_list;
+       char name[SLOT_NAME_SIZE];
 };
 
 static LIST_HEAD(slot_list);
@@ -233,12 +235,10 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
        kfree(slot);
 }
 
-#define SLOT_NAME_SIZE 10
 static void make_slot_name(struct slot *slot)
 {
        /*
@@ -257,7 +257,6 @@ static int __init init_slots(void)
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
-       char *name;
        int retval = -ENOMEM;
        int i;
 
@@ -266,31 +265,23 @@ static int __init init_slots(void)
         * with the pci_hotplug subsystem.
         */
        for (i = 0; i < num_slots; ++i) {
-               slot = kmalloc(sizeof(struct slot), GFP_KERNEL);
+               slot = kzalloc(sizeof(*slot), GFP_KERNEL);
                if (!slot)
                        goto error;
-               memset(slot, 0, sizeof(struct slot));
 
-               hotplug_slot = kmalloc(sizeof(struct hotplug_slot),
-                                       GFP_KERNEL);
+               hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
                if (!hotplug_slot)
                        goto error_slot;
-               memset(hotplug_slot, 0, sizeof (struct hotplug_slot));
                slot->hotplug_slot = hotplug_slot;
 
-               info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
+               info = kzalloc(sizeof(*info), GFP_KERNEL);
                if (!info)
                        goto error_hpslot;
-               memset(info, 0, sizeof (struct hotplug_slot_info));
                hotplug_slot->info = info;
 
-               name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-               if (!name)
-                       goto error_info;
-               hotplug_slot->name = name;
-
                slot->number = i;
 
+               hotplug_slot->name = slot->name;
                hotplug_slot->private = slot;
                hotplug_slot->release = &release_slot;
                make_slot_name(slot);
@@ -300,16 +291,16 @@ static int __init init_slots(void)
                 * Initialize the slot info structure with some known
                 * good values.
                 */
-               info->power_status = get_power_status(slot);
-               info->attention_status = get_attention_status(slot);
-               info->latch_status = get_latch_status(slot);
-               info->adapter_status = get_adapter_status(slot);
+               get_power_status(hotplug_slot, &info->power_status);
+               get_attention_status(hotplug_slot, &info->attention_status);
+               get_latch_status(hotplug_slot, &info->latch_status);
+               get_adapter_status(hotplug_slot, &info->adapter_status);
                
                dbg("registering slot %d\n", i);
                retval = pci_hp_register(slot->hotplug_slot);
                if (retval) {
                        err("pci_hp_register failed with error %d\n", retval);
-                       goto error_name;
+                       goto error_info;
                }
 
                /* add slot to our internal list */
@@ -317,8 +308,6 @@ static int __init init_slots(void)
        }
 
        return 0;
-error_name:
-       kfree(name);
 error_info:
        kfree(info);
 error_hpslot:
index 78943e0..b771196 100644 (file)
@@ -84,19 +84,16 @@ struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_
 {
        struct slot *slot;
        
-       slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
+       slot = kzalloc(sizeof(struct slot), GFP_KERNEL);
        if (!slot)
                goto error_nomem;
-       memset(slot, 0, sizeof (struct slot));
-       slot->hotplug_slot = kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
+       slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
        if (!slot->hotplug_slot)
                goto error_slot;        
-       memset(slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
-       slot->hotplug_slot->info = kmalloc(sizeof (struct hotplug_slot_info),
+       slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
                                           GFP_KERNEL);
        if (!slot->hotplug_slot->info)
                goto error_hpslot;
-       memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
        slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL);
        if (!slot->hotplug_slot->name)
                goto error_info;        
index a32ae82..c402da8 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
  *
  * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
  * Work to add BIOS PROM support was completed by Mike Habeck.
@@ -230,6 +230,13 @@ static void sn_bus_free_data(struct pci_dev *dev)
                list_for_each_entry(child, &subordinate_bus->devices, bus_list)
                        sn_bus_free_data(child);
        }
+       /*
+        * Some drivers may use dma accesses during the
+        * driver remove function. We release the sysdata
+        * areas after the driver remove functions have
+        * been called.
+        */
+       sn_bus_store_sysdata(dev);
        sn_pci_unfixup_slot(dev);
 }
 
@@ -429,13 +436,6 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
                                   PCI_DEVFN(slot->device_num + 1,
                                             PCI_FUNC(func)));
                if (dev) {
-                       /*
-                        * Some drivers may use dma accesses during the
-                        * driver remove function. We release the sysdata
-                        * areas after the driver remove functions have
-                        * been called.
-                        */
-                       sn_bus_store_sysdata(dev);
                        sn_bus_free_data(dev);
                        pci_remove_bus_device(dev);
                        pci_dev_put(dev);
index 7d6f521..5c70f43 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/sched.h>       /* signal_pending(), struct timer_list */
+#include <linux/mutex.h>
 
 #include "pci_hotplug.h"
 
@@ -45,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)
@@ -52,10 +54,8 @@ extern int shpchp_debug;
 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
-#define SLOT_MAGIC     0x67267321
+#define SLOT_NAME_SIZE 10
 struct slot {
-       u32 magic;
-       struct slot *next;
        u8 bus;
        u8 device;
        u16 status;
@@ -70,26 +70,27 @@ struct slot {
        struct hpc_ops *hpc_ops;
        struct hotplug_slot *hotplug_slot;
        struct list_head        slot_list;
+       char name[SLOT_NAME_SIZE];
+       struct work_struct work;        /* work for button event */
+       struct mutex lock;
 };
 
 struct event_info {
        u32 event_type;
-       u8 hp_slot;
+       struct slot *p_slot;
+       struct work_struct work;
 };
 
 struct controller {
-       struct controller *next;
-       struct semaphore crit_sect;     /* critical section semaphore */
+       struct mutex crit_sect;         /* critical section mutex */
+       struct mutex cmd_lock;          /* command lock */
        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 */
        struct pci_dev *pci_dev;
-       struct pci_bus *pci_bus;
-       struct event_info event_queue[10];
-       struct slot *slot;
+       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;
@@ -105,12 +106,6 @@ struct controller {
        volatile int cmd_busy;
 };
 
-struct hotplug_params {
-       u8      cache_line_size;
-       u8      latency_timer;
-       u8      enable_serr;
-       u8      enable_perr;
-};
 
 /* Define AMD SHPC ID  */
 #define PCI_DEVICE_ID_AMD_GOLAM_7450   0x7450 
@@ -180,11 +175,8 @@ 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);
+extern int     shpchp_sysfs_enable_slot(struct slot *slot);
+extern int     shpchp_sysfs_disable_slot(struct slot *slot);
 
 extern u8      shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
 extern u8      shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
@@ -195,16 +187,28 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
 extern int     shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
 extern int     shpchp_configure_device(struct slot *p_slot);
 extern int     shpchp_unconfigure_device(struct slot *p_slot);
-extern void    get_hp_hw_control_from_firmware(struct pci_dev *dev);
-extern void    get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp);
-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    queue_pushbutton_work(void *data);
 
 
-/* Global variables */
-extern struct controller *shpchp_ctrl_list;
+#ifdef CONFIG_ACPI
+static inline int get_hp_params_from_firmware(struct pci_dev *dev,
+                       struct hotplug_params *hpp)
+{
+       if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
+                       return -ENODEV;
+       return 0;
+}
+#define get_hp_hw_control_from_firmware(pdev) \
+       do { \
+               if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
+                       acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
+       } while (0)
+#else
+#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
+#define get_hp_hw_control_from_firmware(dev) do { } while (0)
+#endif
 
 struct ctrl_reg {
        volatile u32 base_offset;
@@ -286,10 +290,6 @@ static inline int slot_paranoia_check (struct slot *slot, const char *function)
                dbg("%s - slot == NULL", function);
                return -1;
        }
-       if (slot->magic != SLOT_MAGIC) {
-               dbg("%s - bad magic number for slot", function);
-               return -1;
-       }
        if (!slot->hotplug_slot) {
                dbg("%s - slot->hotplug_slot == NULL!", function);
                return -1;
@@ -314,44 +314,19 @@ static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const ch
 
 static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
 {
-       struct slot *p_slot, *tmp_slot = NULL;
+       struct slot *slot;
 
        if (!ctrl)
                return NULL;
 
-       p_slot = ctrl->slot;
-
-       while (p_slot && (p_slot->device != device)) {
-               tmp_slot = p_slot;
-               p_slot = p_slot->next;
+       list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
+               if (slot->device == device)
+                       return slot;
        }
-       if (p_slot == NULL) {
-               err("ERROR: shpchp_find_slot device=0x%x\n", device);
-               p_slot = tmp_slot;
-       }
-
-       return (p_slot);
-}
-
-static inline int wait_for_ctrl_irq (struct controller *ctrl)
-{
-    DECLARE_WAITQUEUE(wait, current);
-       int retval = 0;
-
-       add_wait_queue(&ctrl->queue, &wait);
 
-       if (!shpchp_poll_mode) {
-               /* Sleep for up to 1 second */
-               msleep_interruptible(1000);
-       } else {
-               /* Sleep for up to 2 seconds */
-               msleep_interruptible(2000);
-       }
-       remove_wait_queue(&ctrl->queue, &wait);
-       if (signal_pending(current))
-               retval =  -EINTR;
+       err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
 
-       return retval;
+       return NULL;
 }
 
 static inline void amd_pogo_errata_save_misc_reg(struct slot *p_slot)
@@ -427,13 +402,6 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
        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)
-{
-       snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
-}
-
 enum php_ctlr_type {
        PCI,
        ISA,
index a2b3f00..3be4d49 100644 (file)
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/workqueue.h>
 #include "shpchp.h"
 
 /* Global variables */
 int shpchp_debug;
 int shpchp_poll_mode;
 int shpchp_poll_time;
-struct controller *shpchp_ctrl_list;   /* = NULL */
+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 +58,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
 
 #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);
@@ -94,107 +94,120 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
        kfree(slot->hotplug_slot->info);
-       kfree(slot->hotplug_slot->name);
        kfree(slot->hotplug_slot);
        kfree(slot);
 }
 
+static void make_slot_name(struct slot *slot)
+{
+       snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
+                slot->bus, slot->number);
+}
+
+
+
+
+static int
+shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
+                               u8 busnum, u8 devnum)
+{
+       int offset = devnum - ctrl->slot_device_offset;
+
+       dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
+                       ctrl->slot_num_inc, offset);
+       *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
+       return 0;
+}
+
+
+
 static int init_slots(struct controller *ctrl)
 {
-       struct slot *new_slot;
-       u8 number_of_slots;
-       u8 slot_device;
-       u32 slot_number, sun;
-       int result = -ENOMEM;
-
-       number_of_slots = ctrl->num_slots;
-       slot_device = ctrl->slot_device_offset;
-       slot_number = ctrl->first_slot;
-
-       while (number_of_slots) {
-               new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL);
-               if (!new_slot)
+       struct slot *slot;
+       struct hotplug_slot *hotplug_slot;
+       struct hotplug_slot_info *info;
+       int retval = -ENOMEM;
+       int i;
+       u32 sun;
+
+       for (i = 0; i < ctrl->num_slots; i++) {
+               slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+               if (!slot)
                        goto error;
 
-               memset(new_slot, 0, sizeof(struct slot));
-               new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL);
-               if (!new_slot->hotplug_slot)
+               hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
+               if (!hotplug_slot)
                        goto error_slot;
-               memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot));
+               slot->hotplug_slot = hotplug_slot;
 
-               new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
-               if (!new_slot->hotplug_slot->info)
+               info = kzalloc(sizeof(*info), GFP_KERNEL);
+               if (!info)
                        goto error_hpslot;
-               memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info));
-               new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL);
-               if (!new_slot->hotplug_slot->name)
-                       goto error_info;
+               hotplug_slot->info = info;
+
+               hotplug_slot->name = slot->name;
 
-               new_slot->magic = SLOT_MAGIC;
-               new_slot->ctrl = ctrl;
-               new_slot->bus = ctrl->slot_bus;
-               new_slot->device = slot_device;
-               new_slot->hpc_ops = ctrl->hpc_ops;
+               slot->hp_slot = i;
+               slot->ctrl = ctrl;
+               slot->bus = ctrl->slot_bus;
+               slot->device = ctrl->slot_device_offset + i;
+               slot->hpc_ops = ctrl->hpc_ops;
+               mutex_init(&slot->lock);
 
                if (shpchprm_get_physical_slot_number(ctrl, &sun,
-                                       new_slot->bus, new_slot->device))
-                       goto error_name;
+                                                     slot->bus, slot->device))
+                       goto error_info;
 
-               new_slot->number = sun;
-               new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
+               slot->number = sun;
+               INIT_WORK(&slot->work, queue_pushbutton_work, slot);
 
                /* register this slot with the hotplug pci core */
-               new_slot->hotplug_slot->private = new_slot;
-               new_slot->hotplug_slot->release = &release_slot;
-               make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
-               new_slot->hotplug_slot->ops = &shpchp_hotplug_slot_ops;
-
-               new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
-               new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
-               new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
-               new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
-
-               dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", new_slot->bus, 
-                       new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
-               result = pci_hp_register (new_slot->hotplug_slot);
-               if (result) {
-                       err ("pci_hp_register failed with error %d\n", result);
-                       goto error_name;
+               hotplug_slot->private = slot;
+               hotplug_slot->release = &release_slot;
+               make_slot_name(slot);
+               hotplug_slot->ops = &shpchp_hotplug_slot_ops;
+
+               get_power_status(hotplug_slot, &info->power_status);
+               get_attention_status(hotplug_slot, &info->attention_status);
+               get_latch_status(hotplug_slot, &info->latch_status);
+               get_adapter_status(hotplug_slot, &info->adapter_status);
+
+               dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
+                   "slot_device_offset=%x\n", slot->bus, slot->device,
+                   slot->hp_slot, slot->number, ctrl->slot_device_offset);
+               retval = pci_hp_register(slot->hotplug_slot);
+               if (retval) {
+                       err("pci_hp_register failed with error %d\n", retval);
+                       goto error_info;
                }
 
-               new_slot->next = ctrl->slot;
-               ctrl->slot = new_slot;
-
-               number_of_slots--;
-               slot_device++;
-               slot_number += ctrl->slot_num_inc;
+               list_add(&slot->slot_list, &ctrl->slot_list);
        }
 
        return 0;
-
-error_name:
-       kfree(new_slot->hotplug_slot->name);
 error_info:
-       kfree(new_slot->hotplug_slot->info);
+       kfree(info);
 error_hpslot:
-       kfree(new_slot->hotplug_slot);
+       kfree(hotplug_slot);
 error_slot:
-       kfree(new_slot);
+       kfree(slot);
 error:
-       return result;
+       return retval;
 }
 
-static void cleanup_slots(struct controller *ctrl)
+void cleanup_slots(struct controller *ctrl)
 {
-       struct slot *old_slot, *next_slot;
-
-       old_slot = ctrl->slot;
-       ctrl->slot = NULL;
-
-       while (old_slot) {
-               next_slot = old_slot->next;
-               pci_hp_deregister(old_slot->hotplug_slot);
-               old_slot = next_slot;
+       struct list_head *tmp;
+       struct list_head *next;
+       struct slot *slot;
+
+       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_scheduled_work();
+               flush_workqueue(shpchp_wq);
+               pci_hp_deregister(slot->hotplug_slot);
        }
 }
 
@@ -207,9 +220,12 @@ static int get_ctlr_slot_config(struct controller *ctrl)
        int rc;
        int flags;
 
-       rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags);
+       rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots,
+                                      &first_device_num, &physical_slot_num,
+                                      &updown, &flags);
        if (rc) {
-               err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
+               err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n",
+                   __FUNCTION__, ctrl->bus, ctrl->device);
                return -1;
        }
 
@@ -218,19 +234,19 @@ static int get_ctlr_slot_config(struct controller *ctrl)
        ctrl->first_slot = physical_slot_num;
        ctrl->slot_num_inc = updown;            /* either -1 or 1 */
 
-       dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n",
-               __FUNCTION__, num_ctlr_slots, first_device_num, physical_slot_num, updown, ctrl->bus, ctrl->device);
+       dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d "
+           "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num,
+           physical_slot_num, updown, ctrl->bus, ctrl->device);
 
        return 0;
 }
 
-
 /*
  * set_attention_status - Turns the Amber LED for a slot on, off or blink
  */
 static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -240,29 +256,27 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
        return 0;
 }
 
-
 static int enable_slot (struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
-       return shpchp_enable_slot(slot);
+       return shpchp_sysfs_enable_slot(slot);
 }
 
-
 static int disable_slot (struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
-       return shpchp_disable_slot(slot);
+       return shpchp_sysfs_disable_slot(slot);
 }
 
 static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -276,7 +290,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -290,7 +304,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -304,7 +318,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -318,7 +332,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -330,11 +344,11 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
 
 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-       
+
        retval = slot->hpc_ops->get_max_bus_speed(slot, value);
        if (retval < 0)
                *value = PCI_SPEED_UNKNOWN;
@@ -344,11 +358,11 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
 
 static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-       struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
-       
+
        retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
        if (retval < 0)
                *value = PCI_SPEED_UNKNOWN;
@@ -372,61 +386,54 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        int rc;
        struct controller *ctrl;
        struct slot *t_slot;
-       int first_device_num;   /* first PCI device number supported by this SHPC */
-       int num_ctlr_slots;     /* number of slots supported by this SHPC */
+       int first_device_num;   /* first PCI device number */
+       int num_ctlr_slots;     /* number of slots implemented */
 
        if (!is_shpc_capable(pdev))
                return -ENODEV;
 
-       ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
+       ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
        if (!ctrl) {
                err("%s : out of memory\n", __FUNCTION__);
                goto err_out_none;
        }
-       memset(ctrl, 0, sizeof(struct controller));
+       INIT_LIST_HEAD(&ctrl->slot_list);
 
        rc = shpc_init(ctrl, pdev);
        if (rc) {
-               dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME);
+               dbg("%s: controller initialization failed\n",
+                   SHPC_MODULE_NAME);
                goto err_out_free_ctrl;
        }
 
        pci_set_drvdata(pdev, ctrl);
 
-       ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
-       if (!ctrl->pci_bus) {
-               err("out of memory\n");
-               rc = -ENOMEM;
-               goto err_out_unmap_mmio_region;
-       }
-       
-       memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
        ctrl->bus = pdev->bus->number;
        ctrl->slot_bus = pdev->subordinate->number;
-
        ctrl->device = PCI_SLOT(pdev->devfn);
        ctrl->function = PCI_FUNC(pdev->devfn);
-       dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
+
+       dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
+           ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
 
        /*
-        *      Save configuration headers for this and subordinate PCI buses
+        * Save configuration headers for this and subordinate PCI buses
         */
-
        rc = get_ctlr_slot_config(ctrl);
        if (rc) {
                err(msg_initialization_err, rc);
-               goto err_out_free_ctrl_bus;
+               goto err_out_release_ctlr;
        }
        first_device_num = ctrl->slot_device_offset;
        num_ctlr_slots = ctrl->num_slots;
 
        ctrl->add_support = 1;
-       
+
        /* Setup the slot information structures */
        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  */
@@ -437,30 +444,16 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
 
        if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
-               err(SHPC_MODULE_NAME ": Can't get current bus speed. Set to 33MHz PCI.\n");
+               err(SHPC_MODULE_NAME ": Can't get current bus speed. "
+                   "Set to 33MHz PCI.\n");
                ctrl->speed = PCI_SPEED_33MHz;
        }
 
-       /* Finish setting up the hot plug ctrl device */
-       ctrl->next_event = 0;
-
-       if (!shpchp_ctrl_list) {
-               shpchp_ctrl_list = ctrl;
-               ctrl->next = NULL;
-       } else {
-               ctrl->next = shpchp_ctrl_list;
-               shpchp_ctrl_list = ctrl;
-       }
-
        shpchp_create_ctrl_files(ctrl);
 
        return 0;
 
-err_out_free_ctrl_slot:
-       cleanup_slots(ctrl);
-err_out_free_ctrl_bus:
-       kfree(ctrl->pci_bus);
-err_out_unmap_mmio_region:
+err_out_release_ctlr:
        ctrl->hpc_ops->release_ctlr(ctrl);
 err_out_free_ctrl:
        kfree(ctrl);
@@ -468,74 +461,28 @@ 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)
+static void shpc_remove(struct pci_dev *dev)
 {
-       struct controller *ctrl;
-       struct controller *tctrl;
-
-       ctrl = shpchp_ctrl_list;
-
-       while (ctrl) {
-               shpchp_remove_ctrl_files(ctrl);
-               cleanup_slots(ctrl);
-
-               kfree (ctrl->pci_bus);
-               ctrl->hpc_ops->release_ctlr(ctrl);
-
-               tctrl = ctrl;
-               ctrl = ctrl->next;
-
-               kfree(tctrl);
-       }
-
-       /* Stop the notification mechanism */
-       shpchp_event_stop_thread();
+       struct controller *ctrl = pci_get_drvdata(dev);
 
+       shpchp_remove_ctrl_files(ctrl);
+       ctrl->hpc_ops->release_ctlr(ctrl);
+       kfree(ctrl);
 }
 
-
 static struct pci_device_id shpcd_pci_tbl[] = {
-       {
-       .class =        ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
-       .class_mask =   ~0,
-       .vendor =       PCI_ANY_ID,
-       .device =       PCI_ANY_ID,
-       .subvendor =    PCI_ANY_ID,
-       .subdevice =    PCI_ANY_ID,
-       },
-       
+       {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)},
        { /* end: all zeroes */ }
 };
-
 MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl);
 
-
-
 static struct pci_driver shpc_driver = {
        .name =         SHPC_MODULE_NAME,
        .id_table =     shpcd_pci_tbl,
        .probe =        shpc_probe,
-       /* remove:      shpc_remove_one, */
+       .remove =       shpc_remove,
 };
 
-
-
 static int __init shpcd_init(void)
 {
        int retval = 0;
@@ -544,17 +491,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;
 }
@@ -562,10 +507,8 @@ error_hpc_init:
 static void __exit shpcd_cleanup(void)
 {
        dbg("unload_shpchpd()\n");
-       unload_shpchpd();
-
        pci_unregister_driver(&shpc_driver);
-
+       destroy_workqueue(shpchp_wq);
        info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
 }
 
index 643252d..4e63814 100644 (file)
 #include <linux/types.h>
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
+#include <linux/workqueue.h>
 #include "../pci.h"
 #include "shpchp.h"
 
-static void interrupt_event_handler(struct controller *ctrl);
+static void interrupt_event_handler(void *data);
+static int shpchp_enable_slot(struct slot *p_slot);
+static int shpchp_disable_slot(struct slot *p_slot);
 
-static struct semaphore event_semaphore;       /* mutex for process loop (up if something to process) */
-static struct semaphore event_exit;            /* guard ensure thread has exited before calling it quits */
-static int event_finished;
-static unsigned long pushbutton_pending;       /* = 0 */
+static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
+{
+       struct event_info *info;
+
+       info = kmalloc(sizeof(*info), GFP_ATOMIC);
+       if (!info)
+               return -ENOMEM;
+
+       info->event_type = event_type;
+       info->p_slot = p_slot;
+       INIT_WORK(&info->work, interrupt_event_handler, info);
+
+       schedule_work(&info->work);
+
+       return 0;
+}
 
 u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
 {
        struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
-       u8 rc = 0;
-       u8 getstatus;
-       struct event_info *taskInfo;
+       u32 event_type;
 
        /* Attention Button Change */
        dbg("shpchp:  Attention button interrupt received.\n");
        
-       /* This is the structure that tells the worker thread what to do */
-       taskInfo = &(ctrl->event_queue[ctrl->next_event]);
        p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
-
        p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
-       p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-       
-       ctrl->next_event = (ctrl->next_event + 1) % 10;
-       taskInfo->hp_slot = hp_slot;
-
-       rc++;
 
        /*
         *  Button pressed - See if need to TAKE ACTION!!!
         */
        info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
-       taskInfo->event_type = INT_BUTTON_PRESS;
-
-       if ((p_slot->state == BLINKINGON_STATE)
-           || (p_slot->state == BLINKINGOFF_STATE)) {
-               /* Cancel if we are still blinking; this means that we press the
-                * attention again before the 5 sec. limit expires to cancel hot-add
-                * or hot-remove
-                */
-               taskInfo->event_type = INT_BUTTON_CANCEL;
-               info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
-       } else if ((p_slot->state == POWERON_STATE)
-                  || (p_slot->state == POWEROFF_STATE)) {
-               /* Ignore if the slot is on power-on or power-off state; this 
-                * means that the previous attention button action to hot-add or
-                * hot-remove is undergoing
-                */
-               taskInfo->event_type = INT_BUTTON_IGNORE;
-               info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
-       }
+       event_type = INT_BUTTON_PRESS;
 
-       if (rc)
-               up(&event_semaphore);   /* signal event thread that new event is posted */
+       queue_interrupt_event(p_slot, event_type);
 
        return 0;
 
@@ -100,21 +85,12 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
 {
        struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
-       u8 rc = 0;
        u8 getstatus;
-       struct event_info *taskInfo;
+       u32 event_type;
 
        /* Switch Change */
        dbg("shpchp:  Switch interrupt received.\n");
 
-       /* This is the structure that tells the worker thread
-        * what to do
-        */
-       taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-       ctrl->next_event = (ctrl->next_event + 1) % 10;
-       taskInfo->hp_slot = hp_slot;
-
-       rc++;
        p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
        p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
        p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
@@ -126,9 +102,9 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
                 * Switch opened
                 */
                info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
-               taskInfo->event_type = INT_SWITCH_OPEN;
+               event_type = INT_SWITCH_OPEN;
                if (p_slot->pwr_save && p_slot->presence_save) {
-                       taskInfo->event_type = INT_POWER_FAULT;
+                       event_type = INT_POWER_FAULT;
                        err("Surprise Removal of card\n");
                }
        } else {
@@ -136,34 +112,23 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
                 *  Switch closed
                 */
                info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
-               taskInfo->event_type = INT_SWITCH_CLOSE;
+               event_type = INT_SWITCH_CLOSE;
        }
 
-       if (rc)
-               up(&event_semaphore);   /* signal event thread that new event is posted */
+       queue_interrupt_event(p_slot, event_type);
 
-       return rc;
+       return 1;
 }
 
 u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
 {
        struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
-       u8 rc = 0;
-       /*u8 temp_byte;*/
-       struct event_info *taskInfo;
+       u32 event_type;
 
        /* Presence Change */
        dbg("shpchp:  Presence/Notify input change.\n");
 
-       /* This is the structure that tells the worker thread
-        * what to do
-        */
-       taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-       ctrl->next_event = (ctrl->next_event + 1) % 10;
-       taskInfo->hp_slot = hp_slot;
-
-       rc++;
        p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
        /* 
@@ -175,39 +140,29 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
                 * Card Present
                 */
                info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
-               taskInfo->event_type = INT_PRESENCE_ON;
+               event_type = INT_PRESENCE_ON;
        } else {
                /*
                 * Not Present
                 */
                info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
-               taskInfo->event_type = INT_PRESENCE_OFF;
+               event_type = INT_PRESENCE_OFF;
        }
 
-       if (rc)
-               up(&event_semaphore);   /* signal event thread that new event is posted */
+       queue_interrupt_event(p_slot, event_type);
 
-       return rc;
+       return 1;
 }
 
 u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
 {
        struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
-       u8 rc = 0;
-       struct event_info *taskInfo;
+       u32 event_type;
 
        /* Power fault */
        dbg("shpchp:  Power fault interrupt received.\n");
 
-       /* This is the structure that tells the worker thread
-        * what to do
-        */
-       taskInfo = &(ctrl->event_queue[ctrl->next_event]);
-       ctrl->next_event = (ctrl->next_event + 1) % 10;
-       taskInfo->hp_slot = hp_slot;
-
-       rc++;
        p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
        if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
@@ -216,21 +171,21 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
                 */
                info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
                p_slot->status = 0x00;
-               taskInfo->event_type = INT_POWER_FAULT_CLEAR;
+               event_type = INT_POWER_FAULT_CLEAR;
        } else {
                /*
                 *   Power fault
                 */
                info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
-               taskInfo->event_type = INT_POWER_FAULT;
+               event_type = INT_POWER_FAULT;
                /* set power fault status for this board */
                p_slot->status = 0xFF;
                info("power fault bit %x set\n", hp_slot);
        }
-       if (rc)
-               up(&event_semaphore);   /* signal event thread that new event is posted */
 
-       return rc;
+       queue_interrupt_event(p_slot, event_type);
+
+       return 1;
 }
 
 /* The following routines constitute the bulk of the 
@@ -242,21 +197,11 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
        int rc = 0;
 
        dbg("%s: change to speed %d\n", __FUNCTION__, speed);
-       down(&ctrl->crit_sect);
        if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
-               err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-               up(&ctrl->crit_sect);
+               err("%s: Issue of set bus speed mode command failed\n",
+                   __FUNCTION__);
                return WRONG_BUS_FREQUENCY;
        }
-               
-       if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-               err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-                         __FUNCTION__);
-               err("%s: Error code (%d)\n", __FUNCTION__, rc);
-               up(&ctrl->crit_sect);
-               return WRONG_BUS_FREQUENCY;
-       }
-       up(&ctrl->crit_sect);
        return rc;
 }
 
@@ -265,33 +210,26 @@ static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,
                enum pci_bus_speed msp)
 { 
        int rc = 0;
-       
-       if (flag != 0) { /* Other slots on the same bus are occupied */
-               if ( asp < bsp ) {
-                       err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
-                       return WRONG_BUS_FREQUENCY;
+
+       /*
+        * If other slots on the same bus are occupied, we cannot
+        * change the bus speed.
+        */
+       if (flag) {
+               if (asp < bsp) {
+                       err("%s: speed of bus %x and adapter %x mismatch\n",
+                           __FUNCTION__, bsp, asp);
+                       rc = WRONG_BUS_FREQUENCY;
                }
+               return rc;
+       }
+
+       if (asp < msp) {
+               if (bsp != asp)
+                       rc = change_bus_speed(ctrl, pslot, asp);
        } else {
-               /* Other slots on the same bus are empty */
-               if (msp == bsp) {
-               /* if adapter_speed >= bus_speed, do nothing */
-                       if (asp < bsp) {
-                               /* 
-                               * Try to lower bus speed to accommodate the adapter if other slots 
-                               * on the same controller are empty
-                               */
-                               if ((rc = change_bus_speed(ctrl, pslot, asp)))
-                                       return rc;
-                       } 
-               } else {
-                       if (asp < msp) {
-                               if ((rc = change_bus_speed(ctrl, pslot, asp)))
-                                       return rc;
-                       } else {
-                               if ((rc = change_bus_speed(ctrl, pslot, msp)))
-                                       return rc;
-                       }
-               }
+               if (bsp != msp)
+                       rc = change_bus_speed(ctrl, pslot, msp);
        }
        return rc;
 }
@@ -308,8 +246,7 @@ static int board_added(struct slot *p_slot)
        u8 hp_slot;
        u8 slots_not_empty = 0;
        int rc = 0;
-       enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
-       u8 pi, mode;
+       enum pci_bus_speed asp, bsp, msp;
        struct controller *ctrl = p_slot->ctrl;
 
        hp_slot = p_slot->device - ctrl->slot_device_offset;
@@ -318,187 +255,68 @@ static int board_added(struct slot *p_slot)
                        __FUNCTION__, p_slot->device,
                        ctrl->slot_device_offset, hp_slot);
 
-       /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
-
        /* Power on slot without connecting to bus */
        rc = p_slot->hpc_ops->power_on_slot(p_slot);
        if (rc) {
                err("%s: Failed to power on slot\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
                return -1;
        }
        
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
-               return -1;
-       }
-
-       
        if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
                if (slots_not_empty)
                        return WRONG_BUS_FREQUENCY;
                
                if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
                        err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-                       up(&ctrl->crit_sect);
                        return WRONG_BUS_FREQUENCY;
                }
                
-               if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-                       err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-                                 __FUNCTION__);
-                       err("%s: Error code (%d)\n", __FUNCTION__, rc);
-                       up(&ctrl->crit_sect);
-                       return WRONG_BUS_FREQUENCY;
-               }
                /* turn on board, blink green LED, turn off Amber LED */
                if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
                        err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
-                       up(&ctrl->crit_sect);
                        return rc;
                }
-
-               if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-                       err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-                       up(&ctrl->crit_sect);
-                       return rc;  
-               }
        }
  
-       rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
-       /* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */
-       /* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC,  0xa = PCI-X 133 Mhz 266, */
-       /* 0xd = PCI-X 133 Mhz 533 */
-       /* This encoding is different from the one used in cur_bus_speed & */
-       /* max_bus_speed */
-
-       if (rc  || adapter_speed == PCI_SPEED_UNKNOWN) {
-               err("%s: Can't get adapter speed or bus mode mismatch\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
+       rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp);
+       if (rc) {
+               err("%s: Can't get adapter speed or bus mode mismatch\n",
+                   __FUNCTION__);
                return WRONG_BUS_FREQUENCY;
        }
 
-       rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed);
-       if (rc || bus_speed == PCI_SPEED_UNKNOWN) {
+       rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp);
+       if (rc) {
                err("%s: Can't get bus operation speed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
                return WRONG_BUS_FREQUENCY;
        }
 
-       rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
-       if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
+       rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp);
+       if (rc) {
                err("%s: Can't get max bus operation speed\n", __FUNCTION__);
-               max_bus_speed = bus_speed;
-       }
-
-       /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
-
-       if ((rc  = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
-               err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
-               pi = 1;
+               msp = bsp;
        }
 
        /* Check if there are other slots or devices on the same bus */
        if (!list_empty(&ctrl->pci_dev->subordinate->devices))
                slots_not_empty = 1;
 
-       dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__, 
-               slots_not_empty, pi);
-       dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n", 
-               adapter_speed, bus_speed, max_bus_speed);
-
-       if (pi == 2) {
-               dbg("%s: In PI = %d\n", __FUNCTION__, pi);
-               if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
-                       err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
-                       mode = 0;
-               }
+       dbg("%s: slots_not_empty %d, adapter_speed %d, bus_speed %d, "
+           "max_bus_speed %d\n", __FUNCTION__, slots_not_empty, asp,
+           bsp, msp);
 
-               switch (adapter_speed) {
-               case PCI_SPEED_133MHz_PCIX_533:
-               case PCI_SPEED_133MHz_PCIX_266:
-                       if ((bus_speed != adapter_speed) &&
-                          ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                               return rc;
-                       break;  
-               case PCI_SPEED_133MHz_PCIX_ECC:
-               case PCI_SPEED_133MHz_PCIX:
-                       if (mode) { /* Bus - Mode 1 ECC */
-                               if ((bus_speed != 0x7) &&
-                                  ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                                       return rc;
-                       } else {
-                               if ((bus_speed != 0x4) &&
-                                  ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                                       return rc;
-                       }
-                       break;
-               case PCI_SPEED_66MHz_PCIX_ECC:
-               case PCI_SPEED_66MHz_PCIX:
-                       if (mode) { /* Bus - Mode 1 ECC */
-                               if ((bus_speed != 0x5) &&
-                                  ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                                       return rc;
-                       } else {
-                               if ((bus_speed != 0x2) &&
-                                  ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                                       return rc;
-                       }
-                       break;
-               case PCI_SPEED_66MHz:
-                       if ((bus_speed != 0x1) &&
-                          ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
-                               return rc;
-                       break;  
-               case PCI_SPEED_33MHz:
-                       if (bus_speed > 0x0) {
-                               if (slots_not_empty == 0) {
-                                       if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
-                                               return rc;
-                               } else {
-                                       err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-                                       return WRONG_BUS_FREQUENCY;
-                               }
-                       }
-                       break;
-               default:
-                       err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-                       return WRONG_BUS_FREQUENCY;
-               }
-       } else {
-               /* If adpater_speed == bus_speed, nothing to do here */
-               dbg("%s: In PI = %d\n", __FUNCTION__, pi);
-               if ((adapter_speed != bus_speed) &&
-                  ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
-                               return rc;
-       }
+       rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, asp, bsp, msp);
+       if (rc)
+               return rc;
 
-       down(&ctrl->crit_sect);
        /* turn on board, blink green LED, turn off Amber LED */
        if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
                err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
-               up(&ctrl->crit_sect);
                return rc;
        }
 
-       if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
-               err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-               up(&ctrl->crit_sect);
-               return rc;  
-       }
-
-       up(&ctrl->crit_sect);
-
        /* Wait for ~1 second */
-       wait_for_ctrl_irq (ctrl);
+       msleep(1000);
 
        dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
        /* Check for a power fault */
@@ -520,40 +338,18 @@ static int board_added(struct slot *p_slot)
        p_slot->is_a_board = 0x01;
        p_slot->pwr_save = 1;
 
-       /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
-
        p_slot->hpc_ops->green_led_on(p_slot);
 
-       /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
-
        return 0;
 
 err_exit:
-       /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
-
        /* turn off slot, turn on Amber LED, turn off Green LED */
        rc = p_slot->hpc_ops->slot_disable(p_slot);
        if (rc) {
                err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
-               return rc;
-       }
-
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
                return rc;
        }
 
-       /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
-
        return(rc);
 }
 
@@ -580,37 +376,19 @@ static int remove_board(struct slot *p_slot)
        if (p_slot->is_a_board)
                p_slot->status = 0x01;
 
-       /* Wait for exclusive access to hardware */
-       down(&ctrl->crit_sect);
-
        /* turn off slot, turn on Amber LED, turn off Green LED */
        rc = p_slot->hpc_ops->slot_disable(p_slot);
        if (rc) {
                err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
                return rc;
        }
-
-       rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-       if (rc) {
-               err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
-               return rc;  
-       }
        
        rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
        if (rc) {
                err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
-               /* Done with exclusive hardware access */
-               up(&ctrl->crit_sect);
                return rc;
        }
 
-       /* Done with exclusive hardware access */
-       up(&ctrl->crit_sect);
-
        p_slot->pwr_save = 0;
        p_slot->is_a_board = 0;
 
@@ -618,13 +396,10 @@ static int remove_board(struct slot *p_slot)
 }
 
 
-static void pushbutton_helper_thread (unsigned long data)
-{
-       pushbutton_pending = data;
-
-       up(&event_semaphore);
-}
-
+struct pushbutton_work_info {
+       struct slot *p_slot;
+       struct work_struct work;
+};
 
 /**
  * shpchp_pushbutton_thread
@@ -633,96 +408,63 @@ static void pushbutton_helper_thread (unsigned long data)
  * Handles all pending events and exits.
  *
  */
-static void shpchp_pushbutton_thread (unsigned long slot)
+static void shpchp_pushbutton_thread(void *data)
 {
-       struct slot *p_slot = (struct slot *) slot;
-       u8 getstatus;
-       
-       pushbutton_pending = 0;
-
-       if (!p_slot) {
-               dbg("%s: Error! slot NULL\n", __FUNCTION__);
-               return;
-       }
-
-       p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
-       if (getstatus) {
-               p_slot->state = POWEROFF_STATE;
+       struct pushbutton_work_info *info = data;
+       struct slot *p_slot = info->p_slot;
 
+       mutex_lock(&p_slot->lock);
+       switch (p_slot->state) {
+       case POWEROFF_STATE:
+               mutex_unlock(&p_slot->lock);
                shpchp_disable_slot(p_slot);
+               mutex_lock(&p_slot->lock);
                p_slot->state = STATIC_STATE;
-       } else {
-               p_slot->state = POWERON_STATE;
-
-               if (shpchp_enable_slot(p_slot)) {
-                       /* Wait for exclusive access to hardware */
-                       down(&p_slot->ctrl->crit_sect);
-
+               break;
+       case POWERON_STATE:
+               mutex_unlock(&p_slot->lock);
+               if (shpchp_enable_slot(p_slot))
                        p_slot->hpc_ops->green_led_off(p_slot);
-
-                       /* Done with exclusive hardware access */
-                       up(&p_slot->ctrl->crit_sect);
-               }
+               mutex_lock(&p_slot->lock);
                p_slot->state = STATIC_STATE;
+               break;
+       default:
+               break;
        }
+       mutex_unlock(&p_slot->lock);
 
-       return;
-}
-
-
-/* this is the main worker thread */
-static int event_thread(void* data)
-{
-       struct controller *ctrl;
-       lock_kernel();
-       daemonize("shpchpd_event");
-       unlock_kernel();
-
-       while (1) {
-               dbg("!!!!event_thread sleeping\n");
-               down_interruptible (&event_semaphore);
-               dbg("event_thread woken finished = %d\n", event_finished);
-               if (event_finished || signal_pending(current))
-                       break;
-               /* Do stuff here */
-               if (pushbutton_pending)
-                       shpchp_pushbutton_thread(pushbutton_pending);
-               else
-                       for (ctrl = shpchp_ctrl_list; ctrl; ctrl=ctrl->next)
-                               interrupt_event_handler(ctrl);
-       }
-       dbg("event_thread signals exit\n");
-       up(&event_exit);
-       return 0;
+       kfree(info);
 }
 
-int shpchp_event_start_thread (void)
+void queue_pushbutton_work(void *data)
 {
-       int pid;
+       struct slot *p_slot = data;
+       struct pushbutton_work_info *info;
 
-       /* initialize our semaphores */
-       init_MUTEX_LOCKED(&event_exit);
-       event_finished=0;
-
-       init_MUTEX_LOCKED(&event_semaphore);
-       pid = kernel_thread(event_thread, NULL, 0);
-
-       if (pid < 0) {
-               err ("Can't start up our event thread\n");
-               return -1;
+       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               err("%s: Cannot allocate memory\n", __FUNCTION__);
+               return;
        }
-       return 0;
-}
-
+       info->p_slot = p_slot;
+       INIT_WORK(&info->work, shpchp_pushbutton_thread, info);
 
-void shpchp_event_stop_thread (void)
-{
-       event_finished = 1;
-       up(&event_semaphore);
-       down(&event_exit);
+       mutex_lock(&p_slot->lock);
+       switch (p_slot->state) {
+       case BLINKINGOFF_STATE:
+               p_slot->state = POWEROFF_STATE;
+               break;
+       case BLINKINGON_STATE:
+               p_slot->state = POWERON_STATE;
+               break;
+       default:
+               goto out;
+       }
+       queue_work(shpchp_wq, &info->work);
+ out:
+       mutex_unlock(&p_slot->lock);
 }
 
-
 static int update_slot_info (struct slot *slot)
 {
        struct hotplug_slot_info *info;
@@ -742,149 +484,110 @@ static int update_slot_info (struct slot *slot)
        return result;
 }
 
-static void interrupt_event_handler(struct controller *ctrl)
+/*
+ * Note: This function must be called with slot->lock held
+ */
+static void handle_button_press_event(struct slot *p_slot)
 {
-       int loop = 0;
-       int change = 1;
-       u8 hp_slot;
        u8 getstatus;
-       struct slot *p_slot;
 
-       while (change) {
-               change = 0;
-
-               for (loop = 0; loop < 10; loop++) {
-                       if (ctrl->event_queue[loop].event_type != 0) {
-                               dbg("%s:loop %x event_type %x\n", __FUNCTION__, loop, 
-                                       ctrl->event_queue[loop].event_type);
-                               hp_slot = ctrl->event_queue[loop].hp_slot;
-
-                               p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
-
-                               if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
-                                       dbg("%s: button cancel\n", __FUNCTION__);
-                                       del_timer(&p_slot->task_event);
-
-                                       switch (p_slot->state) {
-                                       case BLINKINGOFF_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
-
-                                               p_slot->hpc_ops->green_led_on(p_slot);
-
-                                               p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
-                                               /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
-                                               break;
-                                       case BLINKINGON_STATE:
-                                               /* Wait for exclusive access to hardware */
-                                               down(&ctrl->crit_sect);
-
-                                               p_slot->hpc_ops->green_led_off(p_slot);
-
-                                               p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
-                                               /* Done with exclusive hardware access */
-                                               up(&ctrl->crit_sect);
-
-                                               break;
-                                       default:
-                                               warn("Not a valid state\n");
-                                               return;
-                                       }
-                                       info(msg_button_cancel, p_slot->number);
-                                       p_slot->state = STATIC_STATE;
-                               } else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
-                                       /* Button Pressed (No action on 1st press...) */
-                                       dbg("%s: Button pressed\n", __FUNCTION__);
-
-                                       p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
-                                       if (getstatus) {
-                                               /* slot is on */
-                                               dbg("%s: slot is on\n", __FUNCTION__);
-                                               p_slot->state = BLINKINGOFF_STATE;
-                                               info(msg_button_off, p_slot->number);
-                                       } else {
-                                               /* slot is off */
-                                               dbg("%s: slot is off\n", __FUNCTION__);
-                                               p_slot->state = BLINKINGON_STATE;
-                                               info(msg_button_on, p_slot->number);
-                                       }
-
-                                       /* Wait for exclusive access to hardware */
-                                       down(&ctrl->crit_sect);
-
-                                       /* blink green LED and turn off amber */
-                                       p_slot->hpc_ops->green_led_blink(p_slot);
-                                       
-                                       p_slot->hpc_ops->set_attention_status(p_slot, 0);
-
-                                       /* Done with exclusive hardware access */
-                                       up(&ctrl->crit_sect);
-
-                                       init_timer(&p_slot->task_event);
-                                       p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
-                                       p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
-                                       p_slot->task_event.data = (unsigned long) p_slot;
-
-                                       dbg("%s: add_timer p_slot = %p\n", __FUNCTION__,(void *) p_slot);
-                                       add_timer(&p_slot->task_event);
-                               } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
-                                       /***********POWER FAULT********************/
-                                       dbg("%s: power fault\n", __FUNCTION__);
-                                       /* Wait for exclusive access to hardware */
-                                       down(&ctrl->crit_sect);
-
-                                       p_slot->hpc_ops->set_attention_status(p_slot, 1);
-                                       
-                                       p_slot->hpc_ops->green_led_off(p_slot);
-
-                                       /* Done with exclusive hardware access */
-                                       up(&ctrl->crit_sect);
-                               } else {
-                                       /* refresh notification */
-                                       if (p_slot)
-                                               update_slot_info(p_slot);
-                               }
-
-                               ctrl->event_queue[loop].event_type = 0;
-
-                               change = 1;
-                       }
-               }               /* End of FOR loop */
+       switch (p_slot->state) {
+       case STATIC_STATE:
+               p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+               if (getstatus) {
+                       p_slot->state = BLINKINGOFF_STATE;
+                       info(msg_button_off, p_slot->number);
+               } else {
+                       p_slot->state = BLINKINGON_STATE;
+                       info(msg_button_on, p_slot->number);
+               }
+               /* blink green LED and turn off amber */
+               p_slot->hpc_ops->green_led_blink(p_slot);
+               p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+               schedule_delayed_work(&p_slot->work, 5*HZ);
+               break;
+       case BLINKINGOFF_STATE:
+       case BLINKINGON_STATE:
+               /*
+                * Cancel if we are still blinking; this means that we
+                * press the attention again before the 5 sec. limit
+                * expires to cancel hot-add or hot-remove
+                */
+               info("Button cancel on Slot(%s)\n", p_slot->name);
+               dbg("%s: button cancel\n", __FUNCTION__);
+               cancel_delayed_work(&p_slot->work);
+               if (p_slot->state == BLINKINGOFF_STATE)
+                       p_slot->hpc_ops->green_led_on(p_slot);
+               else
+                       p_slot->hpc_ops->green_led_off(p_slot);
+               p_slot->hpc_ops->set_attention_status(p_slot, 0);
+               info(msg_button_cancel, p_slot->number);
+               p_slot->state = STATIC_STATE;
+               break;
+       case POWEROFF_STATE:
+       case POWERON_STATE:
+               /*
+                * Ignore if the slot is on power-on or power-off state;
+                * this means that the previous attention button action
+                * to hot-add or hot-remove is undergoing
+                */
+               info("Button ignore on Slot(%s)\n", p_slot->name);
+               update_slot_info(p_slot);
+               break;
+       default:
+               warn("Not a valid state\n");
+               break;
        }
+}
+
+static void interrupt_event_handler(void *data)
+{
+       struct event_info *info = data;
+       struct slot *p_slot = info->p_slot;
+
+       mutex_lock(&p_slot->lock);
+       switch (info->event_type) {
+       case INT_BUTTON_PRESS:
+               handle_button_press_event(p_slot);
+               break;
+       case INT_POWER_FAULT:
+               dbg("%s: power fault\n", __FUNCTION__);
+               p_slot->hpc_ops->set_attention_status(p_slot, 1);
+               p_slot->hpc_ops->green_led_off(p_slot);
+               break;
+       default:
+               update_slot_info(p_slot);
+               break;
+       }
+       mutex_unlock(&p_slot->lock);
 
-       return;
+       kfree(info);
 }
 
 
-int shpchp_enable_slot (struct slot *p_slot)
+static int shpchp_enable_slot (struct slot *p_slot)
 {
        u8 getstatus = 0;
-       int rc;
+       int rc, retval = -ENODEV;
 
        /* Check to see if (latch closed, card present, power off) */
-       down(&p_slot->ctrl->crit_sect);
+       mutex_lock(&p_slot->ctrl->crit_sect);
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
        rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        if (rc || getstatus) {
                info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
        rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
        if (rc || getstatus) {
                info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
-       up(&p_slot->ctrl->crit_sect);
 
        p_slot->is_a_board = 1;
 
@@ -899,56 +602,119 @@ int shpchp_enable_slot (struct slot *p_slot)
             && 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);
+               retval = 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);
+               retval = board_added(p_slot);
 
-       if (rc) {
+       if (retval) {
                p_slot->hpc_ops->get_adapter_status(p_slot,
                                &(p_slot->presence_save));
                p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        }
 
        update_slot_info(p_slot);
-       return rc;
+ out:
+       mutex_unlock(&p_slot->ctrl->crit_sect);
+       return retval;
 }
 
 
-int shpchp_disable_slot (struct slot *p_slot)
+static int shpchp_disable_slot (struct slot *p_slot)
 {
        u8 getstatus = 0;
-       int ret = 0;
+       int rc, retval = -ENODEV;
 
        if (!p_slot->ctrl)
                return -ENODEV;
 
        /* Check to see if (latch closed, card present, power on) */
-       down(&p_slot->ctrl->crit_sect);
+       mutex_lock(&p_slot->ctrl->crit_sect);
 
-       ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
-       if (ret || !getstatus) {
+       rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
+       if (rc || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
-       ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
-       if (ret || getstatus) {
+       rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+       if (rc || getstatus) {
                info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
-       ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
-       if (ret || !getstatus) {
+       rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+       if (rc || !getstatus) {
                info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
-               up(&p_slot->ctrl->crit_sect);
-               return -ENODEV;
+               goto out;
        }
-       up(&p_slot->ctrl->crit_sect);
 
-       ret = remove_board(p_slot);
+       retval = remove_board(p_slot);
        update_slot_info(p_slot);
-       return ret;
+ out:
+       mutex_unlock(&p_slot->ctrl->crit_sect);
+       return retval;
 }
 
+int shpchp_sysfs_enable_slot(struct slot *p_slot)
+{
+       int retval = -ENODEV;
+
+       mutex_lock(&p_slot->lock);
+       switch (p_slot->state) {
+       case BLINKINGON_STATE:
+               cancel_delayed_work(&p_slot->work);
+       case STATIC_STATE:
+               p_slot->state = POWERON_STATE;
+               mutex_unlock(&p_slot->lock);
+               retval = shpchp_enable_slot(p_slot);
+               mutex_lock(&p_slot->lock);
+               p_slot->state = STATIC_STATE;
+               break;
+       case POWERON_STATE:
+               info("Slot %s is already in powering on state\n",
+                    p_slot->name);
+               break;
+       case BLINKINGOFF_STATE:
+       case POWEROFF_STATE:
+               info("Already enabled on slot %s\n", p_slot->name);
+               break;
+       default:
+               err("Not a valid state on slot %s\n", p_slot->name);
+               break;
+       }
+       mutex_unlock(&p_slot->lock);
+
+       return retval;
+}
+
+int shpchp_sysfs_disable_slot(struct slot *p_slot)
+{
+       int retval = -ENODEV;
+
+       mutex_lock(&p_slot->lock);
+       switch (p_slot->state) {
+       case BLINKINGOFF_STATE:
+               cancel_delayed_work(&p_slot->work);
+       case STATIC_STATE:
+               p_slot->state = POWEROFF_STATE;
+               mutex_unlock(&p_slot->lock);
+               retval = shpchp_disable_slot(p_slot);
+               mutex_lock(&p_slot->lock);
+               p_slot->state = STATIC_STATE;
+               break;
+       case POWEROFF_STATE:
+               info("Slot %s is already in powering off state\n",
+                    p_slot->name);
+               break;
+       case BLINKINGON_STATE:
+       case POWERON_STATE:
+               info("Already disabled on slot %s\n", p_slot->name);
+               break;
+       default:
+               err("Not a valid state on slot %s\n", p_slot->name);
+               break;
+       }
+       mutex_unlock(&p_slot->lock);
+
+       return retval;
+}
index b4226ff..66123cf 100644 (file)
 #define SLOT_100MHZ_PCIX_533   0x0f000000
 #define SLOT_133MHZ_PCIX_533   0xf0000000
 
-
-/* Secondary Bus Configuration Register */
-/* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */
-#define PCI_33MHZ              0x0
-#define PCI_66MHZ              0x1
-#define PCIX_66MHZ             0x2
-#define PCIX_100MHZ            0x3
-#define PCIX_133MHZ            0x4
-
-/* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */
-#define PCI_33MHZ              0x0
-#define PCI_66MHZ              0x1
-#define PCIX_66MHZ             0x2
-#define PCIX_100MHZ            0x3
-#define PCIX_133MHZ            0x4
-#define PCIX_66MHZ_ECC         0x5
-#define PCIX_100MHZ_ECC                0x6
-#define PCIX_133MHZ_ECC                0x7
-#define PCIX_66MHZ_266         0x9
-#define PCIX_100MHZ_266                0xa
-#define PCIX_133MHZ_266                0xb
-#define PCIX_66MHZ_533         0x11
-#define PCIX_100MHZ_533                0x12
-#define PCIX_133MHZ_533                0x13
-
 /* Slot Configuration */
 #define SLOT_NUM               0x0000001F
 #define        FIRST_DEV_NUM           0x00001F00
@@ -231,6 +206,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 +279,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        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 +302,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        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 +320,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
         * 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;
@@ -532,81 +523,41 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
 
 static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
 {
-       struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
-       u32 slot_reg;
-       u16 slot_status, sec_bus_status;
-       u8 m66_cap, pcix_cap, pi;
        int retval = 0;
+       struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+       u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot);
+       u8 pcix_cap = (slot_reg >> 12) & 7;
+       u8 m66_cap  = (slot_reg >> 9) & 1;
 
        DBG_ENTER_ROUTINE 
 
-       if (!slot->ctrl->hpc_ctlr_handle) {
-               err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-               return -1;
-       }
-
-       if (slot->hp_slot >= php_ctlr->num_slots) {
-               err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-               return -1;
-       }
-       
-       pi = readb(php_ctlr->creg + PROG_INTERFACE);
-       slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
-       dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg);
-       slot_status = (u16) slot_reg;
-       dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status);
-       sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
-
-       pcix_cap = (u8) ((slot_status & 0x3000) >> 12);
-       dbg("%s:  pcix_cap = %x\n", __FUNCTION__, pcix_cap);
-       m66_cap = (u8) ((slot_status & 0x0200) >> 9);
-       dbg("%s:  m66_cap = %x\n", __FUNCTION__, m66_cap);
-
+       dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n",
+           __FUNCTION__, slot_reg, pcix_cap, m66_cap);
 
-       if (pi == 2) {
-               switch (pcix_cap) {
-               case 0:
-                       *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
-                       break;
-               case 1:
-                       *value = PCI_SPEED_66MHz_PCIX;
-                       break;
-               case 3:
-                       *value = PCI_SPEED_133MHz_PCIX;
-                       break;
-               case 4:
-                       *value = PCI_SPEED_133MHz_PCIX_266;     
-                       break;
-               case 5:
-                       *value = PCI_SPEED_133MHz_PCIX_533;     
-                       break;
-               case 2: /* Reserved */
-               default:
-                       *value = PCI_SPEED_UNKNOWN;
-                       retval = -ENODEV;
-                       break;
-               }
-       } else {
-               switch (pcix_cap) {
-               case 0:
-                       *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
-                       break;
-               case 1:
-                       *value = PCI_SPEED_66MHz_PCIX;
-                       break;
-               case 3:
-                       *value = PCI_SPEED_133MHz_PCIX; 
-                       break;
-               case 2: /* Reserved */
-               default:
-                       *value = PCI_SPEED_UNKNOWN;
-                       retval = -ENODEV;
-                       break;
-               }
+       switch (pcix_cap) {
+       case 0x0:
+               *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
+               break;
+       case 0x1:
+               *value = PCI_SPEED_66MHz_PCIX;
+               break;
+       case 0x3:
+               *value = PCI_SPEED_133MHz_PCIX;
+               break;
+       case 0x4:
+               *value = PCI_SPEED_133MHz_PCIX_266;
+               break;
+       case 0x5:
+               *value = PCI_SPEED_133MHz_PCIX_533;
+               break;
+       case 0x2:
+       default:
+               *value = PCI_SPEED_UNKNOWN;
+               retval = -ENODEV;
+               break;
        }
 
        dbg("Adapter speed = %d\n", *value);
-       
        DBG_LEAVE_ROUTINE 
        return retval;
 }
@@ -797,6 +748,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
 {
        struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
        struct php_ctlr_state_s *p, *p_prev;
+       int i;
 
        DBG_ENTER_ROUTINE 
 
@@ -805,6 +757,14 @@ static void hpc_release_ctlr(struct controller *ctrl)
                return ;
        }
 
+       /*
+        * Mask all slot event interrupts
+        */
+       for (i = 0; i < ctrl->num_slots; i++)
+               writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i));
+
+       cleanup_slots(ctrl);
+
        if (shpchp_poll_mode) {
            del_timer(&php_ctlr->int_poll_timer);
        } else {        
@@ -814,6 +774,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
                        pci_disable_msi(php_ctlr->pci_dev);
                }
        }
+
        if (php_ctlr->pci_dev) {
                iounmap(php_ctlr->creg);
                release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
@@ -939,98 +900,66 @@ static int hpc_slot_disable(struct slot * slot)
 
 static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
 {
-       u8 slot_cmd;
-       u8 pi;
-       int retval = 0;
+       int retval;
        struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+       u8 pi, cmd;
 
        DBG_ENTER_ROUTINE 
-       
-       if (!slot->ctrl->hpc_ctlr_handle) {
-               err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-               return -1;
-       }
 
        pi = readb(php_ctlr->creg + PROG_INTERFACE);
-       
-       if (pi == 1) {
-               switch (value) {
-               case 0:
-                       slot_cmd = SETA_PCI_33MHZ;
-                       break;
-               case 1:
-                       slot_cmd = SETA_PCI_66MHZ;
-                       break;
-               case 2:
-                       slot_cmd = SETA_PCIX_66MHZ;
-                       break;
-               case 3:
-                       slot_cmd = SETA_PCIX_100MHZ;    
-                       break;
-               case 4:
-                       slot_cmd = SETA_PCIX_133MHZ;    
-                       break;
-               default:
-                       slot_cmd = PCI_SPEED_UNKNOWN;
-                       retval = -ENODEV;
-                       return retval;  
-               }
-       } else {
-               switch (value) {
-               case 0:
-                       slot_cmd = SETB_PCI_33MHZ;
-                       break;
-               case 1:
-                       slot_cmd = SETB_PCI_66MHZ;
-                       break;
-               case 2:
-                       slot_cmd = SETB_PCIX_66MHZ_PM;
-                       break;
-               case 3:
-                       slot_cmd = SETB_PCIX_100MHZ_PM; 
-                       break;
-               case 4:
-                       slot_cmd = SETB_PCIX_133MHZ_PM; 
-                       break;
-               case 5:
-                       slot_cmd = SETB_PCIX_66MHZ_EM;  
-                       break;
-               case 6:
-                       slot_cmd = SETB_PCIX_100MHZ_EM; 
-                       break;
-               case 7:
-                       slot_cmd = SETB_PCIX_133MHZ_EM; 
-                       break;
-               case 8:
-                       slot_cmd = SETB_PCIX_66MHZ_266; 
-                       break;
-               case 0x9:
-                       slot_cmd = SETB_PCIX_100MHZ_266;        
-                       break;
-               case 0xa:
-                       slot_cmd = SETB_PCIX_133MHZ_266;        
-                       break;
-               case 0xb:
-                       slot_cmd = SETB_PCIX_66MHZ_533; 
-                       break;
-               case 0xc:
-                       slot_cmd = SETB_PCIX_100MHZ_533;        
-                       break;
-               case 0xd:
-                       slot_cmd = SETB_PCIX_133MHZ_533;        
-                       break;
-               default:
-                       slot_cmd = PCI_SPEED_UNKNOWN;
-                       retval = -ENODEV;
-                       return retval;  
-               }
+       if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX))
+               return -EINVAL;
 
+       switch (value) {
+       case PCI_SPEED_33MHz:
+               cmd = SETA_PCI_33MHZ;
+               break;
+       case PCI_SPEED_66MHz:
+               cmd = SETA_PCI_66MHZ;
+               break;
+       case PCI_SPEED_66MHz_PCIX:
+               cmd = SETA_PCIX_66MHZ;
+               break;
+       case PCI_SPEED_100MHz_PCIX:
+               cmd = SETA_PCIX_100MHZ;
+               break;
+       case PCI_SPEED_133MHz_PCIX:
+               cmd = SETA_PCIX_133MHZ;
+               break;
+       case PCI_SPEED_66MHz_PCIX_ECC:
+               cmd = SETB_PCIX_66MHZ_EM;
+               break;
+       case PCI_SPEED_100MHz_PCIX_ECC:
+               cmd = SETB_PCIX_100MHZ_EM;
+               break;
+       case PCI_SPEED_133MHz_PCIX_ECC:
+               cmd = SETB_PCIX_133MHZ_EM;
+               break;
+       case PCI_SPEED_66MHz_PCIX_266:
+               cmd = SETB_PCIX_66MHZ_266;
+               break;
+       case PCI_SPEED_100MHz_PCIX_266:
+               cmd = SETB_PCIX_100MHZ_266;
+               break;
+       case PCI_SPEED_133MHz_PCIX_266:
+               cmd = SETB_PCIX_133MHZ_266;
+               break;
+       case PCI_SPEED_66MHz_PCIX_533:
+               cmd = SETB_PCIX_66MHZ_533;
+               break;
+       case PCI_SPEED_100MHz_PCIX_533:
+               cmd = SETB_PCIX_100MHZ_533;
+               break;
+       case PCI_SPEED_133MHz_PCIX_533:
+               cmd = SETB_PCIX_133MHZ_533;
+               break;
+       default:
+               return -EINVAL;
        }
-       retval = shpc_write_cmd(slot, 0, slot_cmd);
-       if (retval) {
+
+       retval = shpc_write_cmd(slot, 0, cmd);
+       if (retval)
                err("%s: Write command failed!\n", __FUNCTION__);
-               return -1;
-       }
 
        DBG_LEAVE_ROUTINE
        return retval;
@@ -1093,14 +1022,8 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                wake_up_interruptible(&ctrl->queue);
        }
 
-       if ((intr_loc = (intr_loc >> 1)) == 0) {
-               /* Unmask Global Interrupt Mask */
-               temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
-               temp_dword &= 0xfffffffe;
-               writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
-
-               return IRQ_NONE;
-       }
+       if ((intr_loc = (intr_loc >> 1)) == 0)
+               goto out;
 
        for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { 
        /* To find out which slot has interrupt pending */
@@ -1130,6 +1053,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                        dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 
                }
        }
+ out:
        if (!shpchp_poll_mode) {
                /* Unmask Global Interrupt Mask */
                temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
@@ -1142,64 +1066,43 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
 
 static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 {
+       int retval = 0;
        struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
        enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
-       int retval = 0;
-       u8 pi;
-       u32 slot_avail1, slot_avail2;
+       u8 pi = readb(php_ctlr->creg + PROG_INTERFACE);
+       u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1);
+       u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
 
        DBG_ENTER_ROUTINE 
 
-       if (!slot->ctrl->hpc_ctlr_handle) {
-               err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-               return -1;
-       }
-
-       if (slot->hp_slot >= php_ctlr->num_slots) {
-               err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-               return -1;
-       }
-
-       pi = readb(php_ctlr->creg + PROG_INTERFACE);
-       slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1);
-       slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
-
        if (pi == 2) {
                if (slot_avail2 & SLOT_133MHZ_PCIX_533)
-                       bus_speed = PCIX_133MHZ_533;
+                       bus_speed = PCI_SPEED_133MHz_PCIX_533;
                else if (slot_avail2 & SLOT_100MHZ_PCIX_533)
-                       bus_speed = PCIX_100MHZ_533;
+                       bus_speed = PCI_SPEED_100MHz_PCIX_533;
                else if (slot_avail2 & SLOT_66MHZ_PCIX_533)
-                       bus_speed = PCIX_66MHZ_533;
+                       bus_speed = PCI_SPEED_66MHz_PCIX_533;
                else if (slot_avail2 & SLOT_133MHZ_PCIX_266)
-                       bus_speed = PCIX_133MHZ_266;
+                       bus_speed = PCI_SPEED_133MHz_PCIX_266;
                else if (slot_avail2 & SLOT_100MHZ_PCIX_266)
-                       bus_speed = PCIX_100MHZ_266;
+                       bus_speed = PCI_SPEED_100MHz_PCIX_266;
                else if (slot_avail2 & SLOT_66MHZ_PCIX_266)
-                       bus_speed = PCIX_66MHZ_266;
-               else if (slot_avail1 & SLOT_133MHZ_PCIX)
-                       bus_speed = PCIX_133MHZ;
-               else if (slot_avail1 & SLOT_100MHZ_PCIX)
-                       bus_speed = PCIX_100MHZ;
-               else if (slot_avail1 & SLOT_66MHZ_PCIX)
-                       bus_speed = PCIX_66MHZ;
-               else if (slot_avail2 & SLOT_66MHZ)
-                       bus_speed = PCI_66MHZ;
-               else if (slot_avail1 & SLOT_33MHZ)
-                       bus_speed = PCI_33MHZ;
-               else bus_speed = PCI_SPEED_UNKNOWN;
-       } else {
+                       bus_speed = PCI_SPEED_66MHz_PCIX_266;
+       }
+
+       if (bus_speed == PCI_SPEED_UNKNOWN) {
                if (slot_avail1 & SLOT_133MHZ_PCIX)
-                       bus_speed = PCIX_133MHZ;
+                       bus_speed = PCI_SPEED_133MHz_PCIX;
                else if (slot_avail1 & SLOT_100MHZ_PCIX)
-                       bus_speed = PCIX_100MHZ;
+                       bus_speed = PCI_SPEED_100MHz_PCIX;
                else if (slot_avail1 & SLOT_66MHZ_PCIX)
-                       bus_speed = PCIX_66MHZ;
+                       bus_speed = PCI_SPEED_66MHz_PCIX;
                else if (slot_avail2 & SLOT_66MHZ)
-                       bus_speed = PCI_66MHZ;
+                       bus_speed = PCI_SPEED_66MHz;
                else if (slot_avail1 & SLOT_33MHZ)
-                       bus_speed = PCI_33MHZ;
-               else bus_speed = PCI_SPEED_UNKNOWN;
+                       bus_speed = PCI_SPEED_33MHz;
+               else
+                       retval = -ENODEV;
        }
 
        *value = bus_speed;
@@ -1210,111 +1113,69 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 
 static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 {
+       int retval = 0;
        struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
        enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
-       u16 sec_bus_status;
-       int retval = 0;
-       u8 pi;
+       u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG);
+       u8 pi = readb(php_ctlr->creg + PROG_INTERFACE);
+       u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7);
 
        DBG_ENTER_ROUTINE 
 
-       if (!slot->ctrl->hpc_ctlr_handle) {
-               err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-               return -1;
-       }
-
-       if (slot->hp_slot >= php_ctlr->num_slots) {
-               err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-               return -1;
+       if ((pi == 1) && (speed_mode > 4)) {
+               *value = PCI_SPEED_UNKNOWN;
+               return -ENODEV;
        }
 
-       pi = readb(php_ctlr->creg + PROG_INTERFACE);
-       sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
-
-       if (pi == 2) {
-               switch (sec_bus_status & 0x000f) {
-               case 0:
-                       bus_speed = PCI_SPEED_33MHz;
-                       break;
-               case 1:
-                       bus_speed = PCI_SPEED_66MHz;
-                       break;
-               case 2:
-                       bus_speed = PCI_SPEED_66MHz_PCIX;
-                       break;
-               case 3:
-                       bus_speed = PCI_SPEED_100MHz_PCIX;      
-                       break;
-               case 4:
-                       bus_speed = PCI_SPEED_133MHz_PCIX;      
-                       break;
-               case 5:
-                       bus_speed = PCI_SPEED_66MHz_PCIX_ECC;
-                       break;
-               case 6:
-                       bus_speed = PCI_SPEED_100MHz_PCIX_ECC;
-                       break;
-               case 7:
-                       bus_speed = PCI_SPEED_133MHz_PCIX_ECC;  
-                       break;
-               case 8:
-                       bus_speed = PCI_SPEED_66MHz_PCIX_266;   
-                       break;
-               case 9:
-                       bus_speed = PCI_SPEED_100MHz_PCIX_266;  
-                       break;
-               case 0xa:
-                       bus_speed = PCI_SPEED_133MHz_PCIX_266;  
-                       break;
-               case 0xb:
-                       bus_speed = PCI_SPEED_66MHz_PCIX_533;   
-                       break;
-               case 0xc:
-                       bus_speed = PCI_SPEED_100MHz_PCIX_533;  
-                       break;
-               case 0xd:
-                       bus_speed = PCI_SPEED_133MHz_PCIX_533;  
-                       break;
-               case 0xe:
-               case 0xf:
-               default:
-                       bus_speed = PCI_SPEED_UNKNOWN;
-                       break;
-               }
-       } else {
-               /* In the case where pi is undefined, default it to 1 */ 
-               switch (sec_bus_status & 0x0007) {
-               case 0:
-                       bus_speed = PCI_SPEED_33MHz;
-                       break;
-               case 1:
-                       bus_speed = PCI_SPEED_66MHz;
-                       break;
-               case 2:
-                       bus_speed = PCI_SPEED_66MHz_PCIX;
-                       break;
-               case 3:
-                       bus_speed = PCI_SPEED_100MHz_PCIX;      
-                       break;
-               case 4:
-                       bus_speed = PCI_SPEED_133MHz_PCIX;      
-                       break;
-               case 5:
-                       bus_speed = PCI_SPEED_UNKNOWN;          /*      Reserved */
-                       break;
-               case 6:
-                       bus_speed = PCI_SPEED_UNKNOWN;          /*      Reserved */
-                       break;
-               case 7:
-                       bus_speed = PCI_SPEED_UNKNOWN;          /*      Reserved */     
-                       break;
-               default:
-                       bus_speed = PCI_SPEED_UNKNOWN;
-                       break;
-               }
+       switch (speed_mode) {
+       case 0x0:
+               *value = PCI_SPEED_33MHz;
+               break;
+       case 0x1:
+               *value = PCI_SPEED_66MHz;
+               break;
+       case 0x2:
+               *value = PCI_SPEED_66MHz_PCIX;
+               break;
+       case 0x3:
+               *value = PCI_SPEED_100MHz_PCIX;
+               break;
+       case 0x4:
+               *value = PCI_SPEED_133MHz_PCIX;
+               break;
+       case 0x5:
+               *value = PCI_SPEED_66MHz_PCIX_ECC;
+               break;
+       case 0x6:
+               *value = PCI_SPEED_100MHz_PCIX_ECC;
+               break;
+       case 0x7:
+               *value = PCI_SPEED_133MHz_PCIX_ECC;
+               break;
+       case 0x8:
+               *value = PCI_SPEED_66MHz_PCIX_266;
+               break;
+       case 0x9:
+               *value = PCI_SPEED_100MHz_PCIX_266;
+               break;
+       case 0xa:
+               *value = PCI_SPEED_133MHz_PCIX_266;
+               break;
+       case 0xb:
+               *value = PCI_SPEED_66MHz_PCIX_533;
+               break;
+       case 0xc:
+               *value = PCI_SPEED_100MHz_PCIX_533;
+               break;
+       case 0xd:
+               *value = PCI_SPEED_133MHz_PCIX_533;
+               break;
+       default:
+               *value = PCI_SPEED_UNKNOWN;
+               retval = -ENODEV;
+               break;
        }
 
-       *value = bus_speed;
        dbg("Current bus speed = %d\n", bus_speed);
        DBG_LEAVE_ROUTINE 
        return retval;
@@ -1343,7 +1204,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,
@@ -1375,15 +1235,13 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
 
        spin_lock_init(&list_lock);
-       php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
+       php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL);
 
        if (!php_ctlr) {        /* allocate controller state data */
                err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
                goto abort;
        }
 
-       memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
-
        php_ctlr->pci_dev = pdev;       /* save pci_dev in context */
 
        if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
@@ -1454,7 +1312,9 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        }
        dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
 
-       init_MUTEX(&ctrl->crit_sect);
+       mutex_init(&ctrl->crit_sect);
+       mutex_init(&ctrl->cmd_lock);
+
        /* Setup wait queue */
        init_waitqueue_head(&ctrl->queue);
 
index 19e1a5e..257adc2 100644 (file)
@@ -38,7 +38,7 @@ static void program_fw_provided_values(struct pci_dev *dev)
 {
        u16 pci_cmd, pci_bctl;
        struct pci_dev *cdev;
-       struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
+       struct hotplug_params hpp;
 
        /* Program hpp values for this device */
        if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
@@ -46,7 +46,13 @@ static void program_fw_provided_values(struct pci_dev *dev)
                        (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
                return;
 
-       get_hp_params_from_firmware(dev, &hpp);
+       /* use default values if we can't get them from firmware */
+       if (get_hp_params_from_firmware(dev, &hpp)) {
+               hpp.cache_line_size = 8;
+               hpp.latency_timer = 0x40;
+               hpp.enable_serr = 0;
+               hpp.enable_perr = 0;
+       }
 
        pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
        pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
deleted file mode 100644 (file)
index ed6c125..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include "shpchp.h"
-
-int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
-{
-       int     offset = devnum - ctrl->slot_device_offset;
-
-       *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
-       return 0;
-}
-
-void get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp)
-{
-       return;
-}
-
-void get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
-       return;
-}
-
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
deleted file mode 100644 (file)
index c6b4099..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2003-2004 Intel Corporation
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "shpchp.h"
-
-int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
-{
-       int     offset = devnum - ctrl->slot_device_offset;
-
-       dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
-       *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
-       return 0;
-}
-
-void get_hp_params_from_firmware(struct pci_dev *dev,
-               struct hotplug_params *hpp)
-{
-       return;
-}
-
-void get_hp_hw_control_from_firmware(struct pci_dev *dev)
-{
-       return;
-}
index 48723d6..a77e79c 100644 (file)
@@ -103,9 +103,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
-               int pos;
+               int pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI);
 
-               if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI)))
+               if (!pos)
                        return;
 
                pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
@@ -347,9 +347,9 @@ static int assign_msi_vector(void)
 
 static int get_new_vector(void)
 {
-       int vector;
+       int vector = assign_msi_vector();
 
-       if ((vector = assign_msi_vector()) > 0)
+       if (vector > 0)
                set_intr_gate(vector, interrupt[vector]);
 
        return vector;
@@ -369,7 +369,8 @@ static int msi_init(void)
                return status;
        }
 
-       if ((status = msi_cache_init()) < 0) {
+       status = msi_cache_init();
+       if (status < 0) {
                pci_msi_enable = 0;
                printk(KERN_WARNING "PCI: MSI cache init failed\n");
                return status;
@@ -523,10 +524,12 @@ static int msi_capability_init(struct pci_dev *dev)
        pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        /* MSI Entry Initialization */
-       if (!(entry = alloc_msi_entry()))
+       entry = alloc_msi_entry();
+       if (!entry)
                return -ENOMEM;
 
-       if ((vector = get_msi_vector(dev)) < 0) {
+       vector = get_msi_vector(dev);
+       if (vector < 0) {
                kmem_cache_free(msi_cachep, entry);
                return -EBUSY;
        }
@@ -597,7 +600,8 @@ static int msix_capability_init(struct pci_dev *dev,
        struct msg_address address;
        struct msg_data data;
        int vector, pos, i, j, nr_entries, temp = 0;
-       u32 phys_addr, table_offset;
+       unsigned long phys_addr;
+       u32 table_offset;
        u16 control;
        u8 bir;
        void __iomem *base;
@@ -606,11 +610,11 @@ static int msix_capability_init(struct pci_dev *dev,
        /* Request & Map MSI-X table region */
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        nr_entries = multi_msix_capable(control);
-       pci_read_config_dword(dev, msix_table_offset_reg(pos),
-               &table_offset);
+
+       pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-       phys_addr = pci_resource_start (dev, bir);
-       phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
+       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+       phys_addr = pci_resource_start (dev, bir) + table_offset;
        base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
        if (base == NULL)
                return -ENOMEM;
@@ -620,7 +624,8 @@ static int msix_capability_init(struct pci_dev *dev,
                entry = alloc_msi_entry();
                if (!entry)
                        break;
-               if ((vector = get_msi_vector(dev)) < 0)
+               vector = get_msi_vector(dev);
+               if (vector < 0)
                        break;
 
                j = entries[i].entry;
@@ -699,12 +704,17 @@ int pci_enable_msi(struct pci_dev* dev)
        if (dev->no_msi)
                return status;
 
+       if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+               return -EINVAL;
+
        temp = dev->irq;
 
-       if ((status = msi_init()) < 0)
+       status = msi_init();
+       if (status < 0)
                return status;
 
-       if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSI)))
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (!pos)
                return -EINVAL;
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -728,8 +738,8 @@ int pci_enable_msi(struct pci_dev* dev)
                dev->irq = temp;
        }
        /* Check whether driver already requested for MSI-X vectors */
-       if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
-               !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
                        printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
                               "Device already has MSI-X vectors assigned\n",
                               pci_name(dev));
@@ -755,7 +765,13 @@ void pci_disable_msi(struct pci_dev* dev)
        u16 control;
        unsigned long flags;
 
-       if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSI)))
+       if (!pci_msi_enable)
+               return;
+       if (!dev)
+               return;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (!pos)
                return;
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -826,8 +842,10 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
                         * Detect last MSI-X vector to be released.
                         * Release the MSI-X memory-mapped table.
                         */
+#if 0
                        int pos, nr_entries;
-                       u32 phys_addr, table_offset;
+                       unsigned long phys_addr;
+                       u32 table_offset;
                        u16 control;
                        u8 bir;
 
@@ -838,9 +856,12 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
                        pci_read_config_dword(dev, msix_table_offset_reg(pos),
                                &table_offset);
                        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-                       phys_addr = pci_resource_start (dev, bir);
-                       phys_addr += (u32)(table_offset &
-                               ~PCI_MSIX_FLAGS_BIRMASK);
+                       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+                       phys_addr = pci_resource_start(dev, bir) + table_offset;
+/*
+ * FIXME!  and what did you want to do with phys_addr?
+ */
+#endif
                        iounmap(base);
                }
        }
@@ -924,10 +945,12 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
        if (!pci_msi_enable || !dev || !entries)
                return -EINVAL;
 
-       if ((status = msi_init()) < 0)
+       status = msi_init();
+       if (status < 0)
                return status;
 
-       if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (!pos)
                return -EINVAL;
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -1006,7 +1029,13 @@ void pci_disable_msix(struct pci_dev* dev)
        int pos, temp;
        u16 control;
 
-       if (!dev || !(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
+       if (!pci_msi_enable)
+               return;
+       if (!dev)
+               return;
+
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (!pos)
                return;
 
        pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -1066,8 +1095,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                return;
 
        temp = dev->irq;                /* Save IOAPIC IRQ */
-       if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) > 0 &&
-               !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
                spin_lock_irqsave(&msi_lock, flags);
                state = msi_desc[dev->irq]->msi_attrib.state;
                spin_unlock_irqrestore(&msi_lock, flags);
@@ -1080,8 +1109,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                        msi_free_vector(dev, dev->irq, 0);
                dev->irq = temp;                /* Restore IOAPIC IRQ */
        }
-       if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
-               !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
+       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+       if (pos > 0 && !msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
                int vector, head, tail = 0, warning = 0;
                void __iomem *base = NULL;
 
@@ -1101,7 +1130,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                msi_free_vector(dev, vector, 0);
                if (warning) {
                        /* Force to release the MSI-X memory-mapped table */
-                       u32 phys_addr, table_offset;
+#if 0
+                       unsigned long phys_addr;
+                       u32 table_offset;
                        u16 control;
                        u8 bir;
 
@@ -1110,9 +1141,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
                        pci_read_config_dword(dev, msix_table_offset_reg(pos),
                                &table_offset);
                        bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
-                       phys_addr = pci_resource_start (dev, bir);
-                       phys_addr += (u32)(table_offset &
-                               ~PCI_MSIX_FLAGS_BIRMASK);
+                       table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
+                       phys_addr = pci_resource_start(dev, bir) + table_offset;
+/*
+ * FIXME! and what did you want to do with phys_addr?
+ */
+#endif
                        iounmap(base);
                        printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
                               "called without free_irq() on all MSI-X vectors\n",
@@ -1123,6 +1157,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
        }
 }
 
+void pci_no_msi(void)
+{
+       pci_msi_enable = 0;
+}
+
 EXPORT_SYMBOL(pci_enable_msi);
 EXPORT_SYMBOL(pci_disable_msi);
 EXPORT_SYMBOL(pci_enable_msix);
index 0aa14c9..f22f69a 100644 (file)
@@ -53,11 +53,10 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
        if (fields < 0)
                return -EINVAL;
 
-       dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
+       dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
        if (!dynid)
                return -ENOMEM;
 
-       memset(dynid, 0, sizeof(*dynid));
        INIT_LIST_HEAD(&dynid->node);
        dynid->id.vendor = vendor;
        dynid->id.device = device;
@@ -380,14 +379,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
        /* initialize common driver fields */
        drv->driver.name = drv->name;
        drv->driver.bus = &pci_bus_type;
-       /* FIXME, once all of the existing PCI drivers have been fixed to set
-        * the pci shutdown function, this test can go away. */
-       if (!drv->driver.shutdown)
-               drv->driver.shutdown = pci_device_shutdown;
-       else
-               printk(KERN_WARNING "Warning: PCI driver %s has a struct "
-                       "device_driver shutdown method, please update!\n",
-                       drv->name);
        drv->driver.owner = owner;
        drv->driver.kobj.ktype = &pci_driver_kobj_type;
 
@@ -514,6 +505,7 @@ struct bus_type pci_bus_type = {
        .probe          = pci_device_probe,
        .remove         = pci_device_remove,
        .suspend        = pci_device_suspend,
+       .shutdown       = pci_device_shutdown,
        .resume         = pci_device_resume,
        .dev_attrs      = pci_dev_attrs,
 };
index 965a593..56ac2bc 100644 (file)
@@ -501,9 +501,8 @@ int pci_create_sysfs_dev_files (struct pci_dev *pdev)
        if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
                struct bin_attribute *rom_attr;
                
-               rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+               rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC);
                if (rom_attr) {
-                       memset(rom_attr, 0x00, sizeof(*rom_attr));
                        pdev->rom_attr = rom_attr;
                        rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
                        rom_attr->attr.name = "rom";
index d2d1879..bea1ad1 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
-#if 0
 
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
@@ -34,7 +33,7 @@ pci_bus_max_busnr(struct pci_bus* bus)
        struct list_head *tmp;
        unsigned char max, n;
 
-       max = bus->number;
+       max = bus->subordinate;
        list_for_each(tmp, &bus->children) {
                n = pci_bus_max_busnr(pci_bus_b(tmp));
                if(n > max)
@@ -42,7 +41,9 @@ pci_bus_max_busnr(struct pci_bus* bus)
        }
        return max;
 }
+EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
 
+#if 0
 /**
  * pci_max_busnr - returns maximum PCI bus number
  *
@@ -495,9 +496,8 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
 int
 pci_enable_device(struct pci_dev *dev)
 {
-       int err;
-
-       if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
+       int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+       if (err)
                return err;
        pci_fixup_device(pci_fixup_enable, dev);
        dev->is_enabled = 1;
@@ -639,7 +639,7 @@ void pci_release_region(struct pci_dev *pdev, int bar)
  *     Returns 0 on success, or %EBUSY on error.  A warning
  *     message is also printed on failure.
  */
-int pci_request_region(struct pci_dev *pdev, int bar, char *res_name)
+int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
 {
        if (pci_resource_len(pdev, bar) == 0)
                return 0;
@@ -697,7 +697,7 @@ void pci_release_regions(struct pci_dev *pdev)
  *     Returns 0 on success, or %EBUSY on error.  A warning
  *     message is also printed on failure.
  */
-int pci_request_regions(struct pci_dev *pdev, char *res_name)
+int pci_request_regions(struct pci_dev *pdev, const char *res_name)
 {
        int i;
        
@@ -900,8 +900,12 @@ static int __devinit pci_setup(char *str)
                if (k)
                        *k++ = 0;
                if (*str && (str = pcibios_setup(str)) && *str) {
-                       /* PCI layer options should be handled here */
-                       printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+                       if (!strcmp(str, "nomsi")) {
+                               pci_no_msi();
+                       } else {
+                               printk(KERN_ERR "PCI: Unknown option `%s'\n",
+                                               str);
+                       }
                }
                str = k;
        }
index a6dfee2..8f3fb47 100644 (file)
@@ -50,8 +50,10 @@ extern int pci_msi_quirk;
 
 #ifdef CONFIG_PCI_MSI
 void disable_msi_mode(struct pci_dev *dev, int pos, int type);
+void pci_no_msi(void);
 #else
 static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
+static inline void pci_no_msi(void) { }
 #endif
 
 extern int pcie_mch_quirk;
index a63bd8f..1d317d2 100644 (file)
@@ -29,7 +29,6 @@
 
 struct pcie_port_device_ext {
        int interrupt_mode;     /* [0:INTx | 1:MSI | 2:MSI-X] */
-       unsigned int saved_msi_config_space[5];
 };
 
 extern struct bus_type pcie_port_bus_type;
index e4e5f1e..55c6622 100644 (file)
@@ -248,11 +248,10 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
 {
        struct pcie_device *device;
 
-       device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
+       device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL);
        if (!device)
                return NULL;
 
-       memset(device, 0, sizeof(struct pcie_device));
        pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
        printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);
        return device;
index 0226014..50bfc1b 100644 (file)
@@ -30,75 +30,16 @@ MODULE_LICENSE("GPL");
 /* global data */
 static const char device_name[] = "pcieport-driver";
 
-static void pci_save_msi_state(struct pci_dev *dev)
+static int pcie_portdrv_save_config(struct pci_dev *dev)
 {
-       struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
-       int i = 0, pos;
-       u16 control;
-
-       if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
-               return;
-
-       pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]);
-       control = p_ext->saved_msi_config_space[0] >> 16;
-       pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
-               &p_ext->saved_msi_config_space[i++]);
-       if (control & PCI_MSI_FLAGS_64BIT) {
-               pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
-                       &p_ext->saved_msi_config_space[i++]);
-               pci_read_config_dword(dev, pos + PCI_MSI_DATA_64,
-                       &p_ext->saved_msi_config_space[i++]);
-       } else
-               pci_read_config_dword(dev, pos + PCI_MSI_DATA_32,
-                       &p_ext->saved_msi_config_space[i++]);
-       if (control & PCI_MSI_FLAGS_MASKBIT)
-               pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT,
-                       &p_ext->saved_msi_config_space[i++]);
-}
-
-static void pci_restore_msi_state(struct pci_dev *dev)
-{
-       struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
-       int i = 0, pos;
-       u16 control;
-
-       if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
-               return;
-
-       control = p_ext->saved_msi_config_space[i++] >> 16;
-       pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
-       pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
-               p_ext->saved_msi_config_space[i++]);
-       if (control & PCI_MSI_FLAGS_64BIT) {
-               pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
-                       p_ext->saved_msi_config_space[i++]);
-               pci_write_config_dword(dev, pos + PCI_MSI_DATA_64,
-                       p_ext->saved_msi_config_space[i++]);
-       } else
-               pci_write_config_dword(dev, pos + PCI_MSI_DATA_32,
-                       p_ext->saved_msi_config_space[i++]);
-       if (control & PCI_MSI_FLAGS_MASKBIT)
-               pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT,
-                       p_ext->saved_msi_config_space[i++]);
-}
-
-static void pcie_portdrv_save_config(struct pci_dev *dev)
-{
-       struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
-
-       pci_save_state(dev);
-       if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
-               pci_save_msi_state(dev);
+       return pci_save_state(dev);
 }
 
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
-       struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
        int retval;
 
        pci_restore_state(dev);
-       if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
-               pci_restore_msi_state(dev);
        retval = pci_enable_device(dev);
        if (retval)
                return retval;
@@ -149,7 +90,8 @@ static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
 {
        int ret = pcie_port_device_suspend(dev, state);
 
-       pcie_portdrv_save_config(dev);
+       if (!ret)
+               ret = pcie_portdrv_save_config(dev);
        return ret;
 }
 
index adfad4f..a10ed9d 100644 (file)
@@ -33,10 +33,9 @@ LIST_HEAD(pci_devices);
  */
 static void pci_create_legacy_files(struct pci_bus *b)
 {
-       b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2,
+       b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
                               GFP_ATOMIC);
        if (b->legacy_io) {
-               memset(b->legacy_io, 0, sizeof(struct bin_attribute) * 2);
                b->legacy_io->attr.name = "legacy_io";
                b->legacy_io->size = 0xffff;
                b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
@@ -320,9 +319,8 @@ static struct pci_bus * __devinit pci_alloc_bus(void)
 {
        struct pci_bus *b;
 
-       b = kmalloc(sizeof(*b), GFP_KERNEL);
+       b = kzalloc(sizeof(*b), GFP_KERNEL);
        if (b) {
-               memset(b, 0, sizeof(*b));
                INIT_LIST_HEAD(&b->node);
                INIT_LIST_HEAD(&b->children);
                INIT_LIST_HEAD(&b->devices);
@@ -347,6 +345,7 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
        child->parent = parent;
        child->ops = parent->ops;
        child->sysdata = parent->sysdata;
+       child->bus_flags = parent->bus_flags;
        child->bridge = get_device(&bridge->dev);
 
        child->class_dev.class = &pcibus_class;
@@ -456,7 +455,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                 * pass and just note the configuration.
                 */
                if (pass)
-                       return max;
+                       goto out;
                busnr = (buses >> 8) & 0xFF;
 
                /*
@@ -466,12 +465,12 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                if (pci_find_bus(pci_domain_nr(bus), busnr)) {
                        printk(KERN_INFO "PCI: Bus %04x:%02x already known\n",
                                        pci_domain_nr(bus), busnr);
-                       return max;
+                       goto out;
                }
 
                child = pci_add_new_bus(bus, dev, busnr);
                if (!child)
-                       return max;
+                       goto out;
                child->primary = buses & 0xFF;
                child->subordinate = (buses >> 16) & 0xFF;
                child->bridge_ctl = bctl;
@@ -496,7 +495,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                                   bus ranges. */
                                pci_write_config_dword(dev, PCI_PRIMARY_BUS,
                                                       buses & ~0xffffff);
-                       return max;
+                       goto out;
                }
 
                /* Clear errors */
@@ -505,7 +504,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                /* Prevent assigning a bus number that already exists.
                 * This can happen when a bridge is hot-plugged */
                if (pci_find_bus(pci_domain_nr(bus), max+1))
-                       return max;
+                       goto out;
                child = pci_add_new_bus(bus, dev, ++max);
                buses = (buses & 0xff000000)
                      | ((unsigned int)(child->primary)     <<  0)
@@ -537,6 +536,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                        pci_fixup_parent_subordinate_busnr(child, max);
                        /* Now we can scan all subordinate buses... */
                        max = pci_scan_child_bus(child);
+                       /*
+                        * now fix it up again since we have found
+                        * the real value of max.
+                        */
+                       pci_fixup_parent_subordinate_busnr(child, max);
                } else {
                        /*
                         * For CardBus bridges, we leave 4 bus numbers
@@ -576,8 +580,6 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
        }
 
-       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl);
-
        sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
 
        while (bus->parent) {
@@ -585,17 +587,22 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
                    (child->number > bus->subordinate) ||
                    (child->number < bus->number) ||
                    (child->subordinate < bus->number)) {
-                       printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be "
+                       printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is "
                               "hidden behind%s bridge #%02x (-#%02x)%s\n",
                               child->number, child->subordinate,
                               bus->self->transparent ? " transparent" : " ",
                               bus->number, bus->subordinate,
                               pcibios_assign_all_busses() ? " " :
                               " (try 'pci=assign-busses')");
+                       printk(KERN_WARNING "Please report the result to "
+                              "linux-kernel to fix this permanently\n");
                }
                bus = bus->parent;
        }
 
+out:
+       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl);
+
        return max;
 }
 
@@ -788,11 +795,10 @@ pci_scan_device(struct pci_bus *bus, int devfn)
        if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
                return NULL;
 
-       dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
        if (!dev)
                return NULL;
 
-       memset(dev, 0, sizeof(struct pci_dev));
        dev->bus = bus;
        dev->sysdata = bus->sysdata;
        dev->dev.parent = bus->bridge;
index 92a8857..54b2ebc 100644 (file)
@@ -458,131 +458,6 @@ int pci_proc_detach_bus(struct pci_bus* bus)
        return 0;
 }
 
-#ifdef CONFIG_PCI_LEGACY_PROC
-
-/*
- *  Backward compatible /proc/pci interface.
- */
-
-/*
- * Convert some of the configuration space registers of the device at
- * address (bus,devfn) into a string (possibly several lines each).
- * The configuration string is stored starting at buf[len].  If the
- * string would exceed the size of the buffer (SIZE), 0 is returned.
- */
-static int show_dev_config(struct seq_file *m, void *v)
-{
-       struct pci_dev *dev = v;
-       struct pci_dev *first_dev;
-       struct pci_driver *drv;
-       u32 class_rev;
-       unsigned char latency, min_gnt, max_lat;
-       int reg;
-
-       first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
-       if (dev == first_dev)
-               seq_puts(m, "PCI devices found:\n");
-       pci_dev_put(first_dev);
-
-       drv = pci_dev_driver(dev);
-
-       pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-       pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
-       pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt);
-       pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat);
-       seq_printf(m, "  Bus %2d, device %3d, function %2d:\n",
-              dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       seq_printf(m, "    Class %04x", class_rev >> 16);
-       seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device);
-       seq_printf(m, " (rev %d).\n", class_rev & 0xff);
-
-       if (dev->irq)
-               seq_printf(m, "      IRQ %d.\n", dev->irq);
-
-       if (latency || min_gnt || max_lat) {
-               seq_printf(m, "      Master Capable.  ");
-               if (latency)
-                       seq_printf(m, "Latency=%d.  ", latency);
-               else
-                       seq_puts(m, "No bursts.  ");
-               if (min_gnt)
-                       seq_printf(m, "Min Gnt=%d.", min_gnt);
-               if (max_lat)
-                       seq_printf(m, "Max Lat=%d.", max_lat);
-               seq_putc(m, '\n');
-       }
-
-       for (reg = 0; reg < 6; reg++) {
-               struct resource *res = dev->resource + reg;
-               unsigned long base, end, flags;
-
-               base = res->start;
-               end = res->end;
-               flags = res->flags;
-               if (!end)
-                       continue;
-
-               if (flags & PCI_BASE_ADDRESS_SPACE_IO) {
-                       seq_printf(m, "      I/O at 0x%lx [0x%lx].\n",
-                               base, end);
-               } else {
-                       const char *pref, *type = "unknown";
-
-                       if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
-                               pref = "P";
-                       else
-                               pref = "Non-p";
-                       switch (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
-                             case PCI_BASE_ADDRESS_MEM_TYPE_32:
-                               type = "32 bit"; break;
-                             case PCI_BASE_ADDRESS_MEM_TYPE_1M:
-                               type = "20 bit"; break;
-                             case PCI_BASE_ADDRESS_MEM_TYPE_64:
-                               type = "64 bit"; break;
-                       }
-                       seq_printf(m, "      %srefetchable %s memory at "
-                                      "0x%lx [0x%lx].\n", pref, type,
-                                      base,
-                                      end);
-               }
-       }
-       return 0;
-}
-
-static struct seq_operations proc_pci_op = {
-       .start  = pci_seq_start,
-       .next   = pci_seq_next,
-       .stop   = pci_seq_stop,
-       .show   = show_dev_config
-};
-
-static int proc_pci_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &proc_pci_op);
-}
-static struct file_operations proc_pci_operations = {
-       .open           = proc_pci_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-static void legacy_proc_init(void)
-{
-       struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL);
-       if (entry)
-               entry->proc_fops = &proc_pci_operations;
-}
-
-#else
-
-static void legacy_proc_init(void)
-{
-
-}
-
-#endif /* CONFIG_PCI_LEGACY_PROC */
-
 static int proc_bus_pci_dev_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &proc_bus_pci_devices_op);
@@ -606,7 +481,6 @@ static int __init pci_proc_init(void)
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
                pci_proc_attach_device(dev);
        }
-       legacy_proc_init();
        return 0;
 }
 
index dda6099..4970f47 100644 (file)
@@ -575,8 +575,11 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
 { 
         unsigned char revid, tmp;
         
-       pci_msi_quirk = 1;
-       printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+       if (dev->subordinate) {
+               printk(KERN_WARNING "PCI: MSI quirk detected. "
+                      "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n");
+               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+       }
 
         if (nr_ioapics == 0) 
                 return;
@@ -934,6 +937,12 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x12bd: /* HP D530 */
                                asus_hides_smbus = 1;
                        }
+               if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+                       switch (dev->subsystem_device) {
+                       case 0x099c: /* HP Compaq nx6110 */
+                               asus_hides_smbus = 1;
+                       }
+               }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
                if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
                        switch(dev->subsystem_device) {
@@ -1068,6 +1077,37 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_651,           quirk_sis_96x_
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_735,           quirk_sis_96x_compatible );
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_503,           quirk_sis_503 );
+/*
+ * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
+ * and MC97 modem controller are disabled when a second PCI soundcard is
+ * present. This patch, tweaking the VT8237 ISA bridge, enables them.
+ * -- bjd
+ */
+static void __init asus_hides_ac97_lpc(struct pci_dev *dev)
+{
+       u8 val;
+       int asus_hides_ac97 = 0;
+
+       if (likely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
+               if (dev->device == PCI_DEVICE_ID_VIA_8237)
+                       asus_hides_ac97 = 1;
+       }
+
+       if (!asus_hides_ac97)
+               return;
+
+       pci_read_config_byte(dev, 0x50, &val);
+       if (val & 0xc0) {
+               pci_write_config_byte(dev, 0x50, val & (~0xc0));
+               pci_read_config_byte(dev, 0x50, &val);
+               if (val & 0xc0)
+                       printk(KERN_INFO "PCI: onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n", val);
+               else
+                       printk(KERN_INFO "PCI: enabled onboard AC97/MC97 devices\n");
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
+
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
@@ -1242,6 +1282,33 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,     PCI_DEVICE_ID_INTEL_PXH_1,      quirk_pc
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_PXHV,       quirk_pcie_pxh);
 
 
+/*
+ * Fixup the cardbus bridges on the IBM Dock II docking station
+ */
+static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev)
+{
+       u32 val;
+
+       /*
+        * tie the 2 interrupt pins to INTA, and configure the
+        * multifunction routing register to handle this.
+        */
+       if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) &&
+               (dev->subsystem_device == 0x0148)) {
+               printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge "
+                       "applying quirk\n");
+               pci_read_config_dword(dev, 0x8c, &val);
+               val = ((val & 0xffffff00) | 0x1002);
+               pci_write_config_dword(dev, 0x8c, val);
+               pci_read_config_dword(dev, 0x80, &val);
+               val = ((val & 0x00ffff00) | 0x2864c077);
+               pci_write_config_dword(dev, 0x80, val);
+       }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420,
+                               quirk_ibm_dock2_cardbus);
+
 static void __devinit quirk_netmos(struct pci_dev *dev)
 {
        unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
index 05fa91a..ce7dd6e 100644 (file)
@@ -246,9 +246,9 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
        }
        dev = NULL;
 exit:
-       pci_dev_put(from);
        dev = pci_dev_get(dev);
        spin_unlock(&pci_bus_lock);
+       pci_dev_put(from);
        return dev;
 }
 
@@ -339,9 +339,9 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
        }
        dev = NULL;
 exit:
-       pci_dev_put(from);
        dev = pci_dev_get(dev);
        spin_unlock(&pci_bus_lock);
+       pci_dev_put(from);
        return dev;
 }
 
index 0b54e9a..e496fac 100644 (file)
@@ -330,6 +330,7 @@ int acpi_bus_register_driver(struct acpi_driver *driver);
 int acpi_bus_unregister_driver(struct acpi_driver *driver);
 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
                 acpi_handle handle, int type);
+int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_start(struct acpi_device *device);
 
 int acpi_match_ids(struct acpi_device *device, char *ids);
index fe1a2b0..0aad5a3 100644 (file)
@@ -95,6 +95,11 @@ enum pci_channel_state {
        pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,
 };
 
+typedef unsigned short __bitwise pci_bus_flags_t;
+enum pci_bus_flags {
+       PCI_BUS_FLAGS_NO_MSI = (pci_bus_flags_t) 1,
+};
+
 /*
  * The pci_dev structure is used to describe PCI devices.
  */
@@ -203,7 +208,7 @@ struct pci_bus {
        char            name[48];
 
        unsigned short  bridge_ctl;     /* manage NO_ISA/FBB/et al behaviors */
-       unsigned short  pad2;
+       pci_bus_flags_t bus_flags;      /* Inherited by child busses */
        struct device           *bridge;
        struct class_device     class_dev;
        struct bin_attribute    *legacy_io; /* legacy I/O for this bus */
@@ -485,9 +490,9 @@ void pdev_sort_resources(struct pci_dev *, struct resource_list *);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
                    int (*)(struct pci_dev *, u8, u8));
 #define HAVE_PCI_REQ_REGIONS   2
-int pci_request_regions(struct pci_dev *, char *);
+int pci_request_regions(struct pci_dev *, const char *);
 void pci_release_regions(struct pci_dev *);
-int pci_request_region(struct pci_dev *, int, char *);
+int pci_request_region(struct pci_dev *, int, const char *);
 void pci_release_region(struct pci_dev *, int);
 
 /* drivers/pci/bus.c */
@@ -516,6 +521,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass
 void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
                  void *userdata);
 int pci_cfg_space_size(struct pci_dev *dev);
+unsigned char pci_bus_max_busnr(struct pci_bus* bus);
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */