Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
authorSteve French <sfrench@hera.kernel.org>
Thu, 19 May 2005 19:26:57 +0000 (12:26 -0700)
committerSteve French <sfrench@hera.kernel.org>
Thu, 19 May 2005 19:26:57 +0000 (12:26 -0700)
28 files changed:
Documentation/filesystems/sysfs-pci.txt
Documentation/power/devices.txt
Documentation/powerpc/hvcs.txt
drivers/base/Makefile
drivers/base/bus.c
drivers/base/core.c
drivers/base/interface.c [deleted file]
drivers/base/power/power.h
drivers/base/power/resume.c
drivers/base/power/shutdown.c
drivers/base/power/suspend.c
drivers/char/raw.c
drivers/pci/hotplug.c
drivers/pci/hotplug/cpci_hotplug.h
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.h
drivers/pci/pcie/portdrv_bus.c
fs/ext3/super.c
include/linux/device.h
kernel/power/main.c
mm/mmap.c

index e97d024eae77e5fa9f1ac338074a24baf42680e5..988a62fae11f883b8b2ba14ba95d83490a3fc5a1 100644 (file)
@@ -7,7 +7,6 @@ that support it.  For example, a given bus might look like this:
      |-- 0000:17:00.0
      |   |-- class
      |   |-- config
-     |   |-- detach_state
      |   |-- device
      |   |-- irq
      |   |-- local_cpus
@@ -19,7 +18,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- subsystem_device
      |   |-- subsystem_vendor
      |   `-- vendor
-     `-- detach_state
+     `-- ...
 
 The topmost element describes the PCI domain and bus number.  In this case,
 the domain number is 0000 and the bus number is 17 (both values are in hex).
@@ -31,7 +30,6 @@ files, each with their own function.
        ----               --------
        class              PCI class (ascii, ro)
        config             PCI config space (binary, rw)
-       detach_state       connection status (bool, rw)
        device             PCI device (ascii, ro)
        irq                IRQ number (ascii, ro)
        local_cpus         nearby CPU mask (cpumask, ro)
@@ -85,4 +83,4 @@ useful return codes should be provided.
 
 Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
 wishing to support legacy functionality should define it and provide
-pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
\ No newline at end of file
+pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
index 5d4ae9a39f1d5df7ffa644d39d0235a71b22c125..f987afe43e28e1327ee76ab4f3fdb617abfe0829 100644 (file)
@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
 #READY_AFTER_RESUME
 #
 
-Driver Detach Power Management
-
-The kernel now supports the ability to place a device in a low-power
-state when it is detached from its driver, which happens when its
-module is removed. 
-
-Each device contains a 'detach_state' file in its sysfs directory
-which can be used to control this state. Reading from this file
-displays what the current detach state is set to. This is 0 (On) by
-default. A user may write a positive integer value to this file in the
-range of 1-4 inclusive. 
-
-A value of 1-3 will indicate the device should be placed in that
-low-power state, which will cause ->suspend() to be called for that
-device. A value of 4 indicates that the device should be shutdown, so
-->shutdown() will be called for that device. 
-
-The driver is responsible for reinitializing the device when the
-module is re-inserted during it's ->probe() (or equivalent) method. 
-The driver core will not call any extra functions when binding the
-device to the driver. 
 
 pm_message_t meaning
 
index c0a62e116e6e969e2e6e6cbe7b354a1e16a42fdc..dca75cbda6f8abc144afb9efcdea77b7b5f21eac 100644 (file)
@@ -347,8 +347,8 @@ address that is created by firmware.  An example vty-server sysfs entry
 looks like the following:
 
        Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
-       .   current_vty   devspec  name          partner_vtys
-       ..  detach_state  index    partner_clcs  vterm_state
+       .   current_vty   devspec       name          partner_vtys
+       ..  index         partner_clcs  vterm_state
 
 Each entry is provided, by default with a "name" attribute.  Reading the
 "name" attribute will reveal the device type as shown in the following
index 6662b545e0a910cde8cccee988efe337b54fd2a6..a47928a2e57508a30bb527143d3c503201592f00 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for the Linux device tree
 
-obj-y                  := core.o sys.o interface.o bus.o \
+obj-y                  := core.o sys.o bus.o \
                           driver.o class.o class_simple.o platform.o \
                           cpu.o firmware.o init.o map.o dmapool.o \
                           attribute_container.o transport_class.o
index 2b3902c867dab76cf5b9b9d65d1778be20ac20e1..3cb04bb04c2b8e0d80ad910f8b6e94935be1c089 100644 (file)
@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev)
                sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
                sysfs_remove_link(&dev->kobj, "driver");
                list_del_init(&dev->driver_list);
-               device_detach_shutdown(dev);
                if (drv->remove)
                        drv->remove(dev);
                dev->driver = NULL;
index 268a9c8d168b6ac72a46e0c624830b030b79df51..d21eb7744496de8b6705df42def7a60347842416 100644 (file)
@@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
 #define to_dev(obj) container_of(obj, struct device, kobj)
 #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
 
-extern struct attribute * dev_default_attrs[];
-
 static ssize_t
 dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj)
 static struct kobj_type ktype_device = {
        .release        = device_release,
        .sysfs_ops      = &dev_sysfs_ops,
-       .default_attrs  = dev_default_attrs,
 };
 
 
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
deleted file mode 100644 (file)
index bd51584..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * drivers/base/interface.c - common driverfs interface that's exported to
- *     the world for all devices.
- *
- * Copyright (c) 2002-3 Patrick Mochel
- * Copyright (c) 2002-3 Open Source Development Labs
- *
- * This file is released under the GPLv2
- *
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-
-/**
- *     detach_state - control the default power state for the device.
- *
- *     This is the state the device enters when it's driver module is
- *     unloaded. The value is an unsigned integer, in the range of 0-4.
- *     '0' indicates 'On', so no action will be taken when the driver is
- *     unloaded. This is the default behavior.
- *     '4' indicates 'Off', meaning the driver core will call the driver's
- *     shutdown method to quiesce the device.
- *     1-3 indicate a low-power state for the device to enter via the
- *     driver's suspend method.
- */
-
-static ssize_t detach_show(struct device * dev, char * buf)
-{
-       return sprintf(buf, "%u\n", dev->detach_state);
-}
-
-static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
-{
-       u32 state;
-       state = simple_strtoul(buf, NULL, 10);
-       if (state > 4)
-               return -EINVAL;
-       dev->detach_state = state;
-       return n;
-}
-
-static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
-
-
-struct attribute * dev_default_attrs[] = {
-       &dev_attr_detach_state.attr,
-       NULL,
-};
index e5eda746f2a6d1f2a543e017665d2dac90f0fe5c..2e700d795cf15033c933e4a1a71a4d73afa59a14 100644 (file)
@@ -1,18 +1,7 @@
-
-
-enum {
-       DEVICE_PM_ON,
-       DEVICE_PM1,
-       DEVICE_PM2,
-       DEVICE_PM3,
-       DEVICE_PM_OFF,
-};
-
 /*
  * shutdown.c
  */
 
-extern int device_detach_shutdown(struct device *);
 extern void device_shutdown(void);
 
 
index f8f5055754d65b3fd1c41348dade1e1092b9bc5e..26468971ef5a7711179e87f0d500cdc680888157 100644 (file)
@@ -22,8 +22,17 @@ extern int sysdev_resume(void);
 
 int resume_device(struct device * dev)
 {
-       if (dev->bus && dev->bus->resume)
+       if (dev->power.pm_parent
+                       && dev->power.pm_parent->power.power_state) {
+               dev_err(dev, "PM: resume from %d, parent %s still %d\n",
+                       dev->power.power_state,
+                       dev->power.pm_parent->bus_id,
+                       dev->power.pm_parent->power.power_state);
+       }
+       if (dev->bus && dev->bus->resume) {
+               dev_dbg(dev,"resuming\n");
                return dev->bus->resume(dev);
+       }
        return 0;
 }
 
index d1e023fbe16939051739c8424dc7515d9f965f42..f50a08be424b1c524122b19ba769342f38caf02b 100644 (file)
 extern struct subsystem devices_subsys;
 
 
-int device_detach_shutdown(struct device * dev)
-{
-       if (!dev->detach_state)
-               return 0;
-
-       if (dev->detach_state == DEVICE_PM_OFF) {
-               if (dev->driver && dev->driver->shutdown)
-                       dev->driver->shutdown(dev);
-               return 0;
-       }
-       return dpm_runtime_suspend(dev, dev->detach_state);
-}
-
-
 /**
  * We handle system devices differently - we suspend and shut them
  * down last and resume them first. That way, we don't do anything stupid like
@@ -52,13 +38,12 @@ void device_shutdown(void)
        struct device * dev;
 
        down_write(&devices_subsys.rwsem);
-       list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
-               pr_debug("shutting down %s: ", dev->bus_id);
+       list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
+                               kobj.entry) {
                if (dev->driver && dev->driver->shutdown) {
-                       pr_debug("Ok\n");
+                       dev_dbg(dev, "shutdown\n");
                        dev->driver->shutdown(dev);
-               } else
-                       pr_debug("Ignored.\n");
+               }
        }
        up_write(&devices_subsys.rwsem);
 
index a0b5cf689e6398422be2db4c1e37119d97856be1..0ec44ef840beaf42c89d2fdb897be5f60685a369 100644 (file)
@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state)
 {
        int error = 0;
 
-       dev_dbg(dev, "suspending\n");
+       if (dev->power.power_state) {
+               dev_dbg(dev, "PM: suspend %d-->%d\n",
+                       dev->power.power_state, state);
+       }
+       if (dev->power.pm_parent
+                       && dev->power.pm_parent->power.power_state) {
+               dev_err(dev,
+                       "PM: suspend %d->%d, parent %s already %d\n",
+                       dev->power.power_state, state,
+                       dev->power.pm_parent->bus_id,
+                       dev->power.pm_parent->power.power_state);
+       }
 
        dev->power.prev_state = dev->power.power_state;
 
-       if (dev->bus && dev->bus->suspend && !dev->power.power_state)
+       if (dev->bus && dev->bus->suspend && !dev->power.power_state) {
+               dev_dbg(dev, "suspending\n");
                error = dev->bus->suspend(dev, state);
+       }
 
        return error;
 }
index 131465e8de5aa72b6e8f5621a6b000c97862f73a..ca5f42bcaad91eeca08a3984cf530ab2f7b5818c 100644 (file)
@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
 {
        struct block_device *bdev = filp->private_data;
 
-       return blkdev_ioctl(bdev->bd_inode, filp, command, arg);
+       return blkdev_ioctl(bdev->bd_inode, NULL, command, arg);
 }
 
 static void bind_device(struct raw_config_request *rq)
index 021d0f76bc4c4db9b914c194c4a97103ed4e34b0..3903f8c559b603989068767f30bae7fceb2144f6 100644 (file)
@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
        if ((buffer_size - length <= 0) || (i >= num_envp))
                return -ENOMEM;
 
+       envp[i++] = scratch;
+       length += scnprintf (scratch, buffer_size - length,
+                           "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+                           pdev->vendor, pdev->device,
+                           pdev->subsystem_vendor, pdev->subsystem_device,
+                           (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+                           (u8)(pdev->class));
+       if ((buffer_size - length <= 0) || (i >= num_envp))
+               return -ENOMEM;
+
        envp[i] = NULL;
 
        return 0;
 }
-
-static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
-{
-       struct list_head *ln;
-       struct pci_dev *dev;
-       struct pci_dev_wrapped wrapped_dev;
-       int result = 0;
-
-       pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus),
-               wrapped_bus->bus->number);
-
-       if (fn->pre_visit_pci_bus) {
-               result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       ln = wrapped_bus->bus->devices.next; 
-       while (ln != &wrapped_bus->bus->devices) {
-               dev = pci_dev_b(ln);
-               ln = ln->next;
-
-               memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-               wrapped_dev.dev = dev;
-
-               result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
-               if (result)
-                       return result;
-       }
-
-       if (fn->post_visit_pci_bus)
-               result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
-
-       return result;
-}
-
-static int pci_visit_bridge (struct pci_visit * fn,
-                            struct pci_dev_wrapped *wrapped_dev,
-                            struct pci_bus_wrapped *wrapped_parent)
-{
-       struct pci_bus *bus;
-       struct pci_bus_wrapped wrapped_bus;
-       int result = 0;
-
-       pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev));
-
-       if (fn->visit_pci_dev) {
-               result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       bus = wrapped_dev->dev->subordinate;
-       if (bus) {
-               memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-               wrapped_bus.bus = bus;
-
-               result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
-       }
-       return result;
-}
-
-/**
- * pci_visit_dev - scans the pci buses.
- * @fn: callback functions that are called while visiting
- * @wrapped_dev: the device to scan
- * @wrapped_parent: the bus where @wrapped_dev is connected to
- *
- * Every bus and every function is presented to a custom
- * function that can act upon it.
- */
-int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev,
-                 struct pci_bus_wrapped *wrapped_parent)
-{
-       struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
-       int result = 0;
-
-       if (!dev)
-               return 0;
-
-       if (fn->pre_visit_pci_dev) {
-               result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
-               if (result)
-                       return result;
-       }
-
-       switch (dev->class >> 8) {
-               case PCI_CLASS_BRIDGE_PCI:
-                       result = pci_visit_bridge(fn, wrapped_dev,
-                                                 wrapped_parent);
-                       if (result)
-                               return result;
-                       break;
-               default:
-                       pr_debug("PCI: Scanning device %s\n", pci_name(dev));
-                       if (fn->visit_pci_dev) {
-                               result = fn->visit_pci_dev (wrapped_dev,
-                                                           wrapped_parent);
-                               if (result)
-                                       return result;
-                       }
-       }
-
-       if (fn->post_visit_pci_dev)
-               result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
-
-       return result;
-}
-EXPORT_SYMBOL(pci_visit_dev);
index 3ddd75937a40e3d089f5ed2b964c0336bb80564e..d9769b30be9a6f175a89c68340b0526c885ec5f2 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 
-/* PICMG 2.12 R2.0 HS CSR bits: */
+/* PICMG 2.1 R2.0 HS CSR bits: */
 #define HS_CSR_INS     0x0080
 #define HS_CSR_EXT     0x0040
 #define HS_CSR_PI      0x0030
index ed243605dc7b36bd687fb72b0d96de3aa8f1c2f4..9e9dab7fe86a043caeda7031fb02c57e9579c097 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
+#include <asm/atomic.h>
 #include <linux/delay.h>
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
-#define DRIVER_VERSION "0.2"
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
 #define DRIVER_DESC    "CompactPCI Hot Plug Core"
 
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
 
 /* local variables */
-static spinlock_t list_lock;
+static DECLARE_RWSEM(list_rwsem);
 static LIST_HEAD(slot_list);
 static int slots;
+static atomic_t extracting;
 int cpci_debug;
 static struct cpci_hp_controller *controller;
 static struct semaphore event_semaphore;       /* mutex for process loop (up if something to process) */
@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot);
 static int set_attention_status(struct hotplug_slot *slot, u8 value);
 static int get_power_status(struct hotplug_slot *slot, u8 * value);
 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
+static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
+static int get_latch_status(struct hotplug_slot *slot, u8 * value);
 
 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
        .owner = THIS_MODULE,
@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
        .set_attention_status = set_attention_status,
        .get_power_status = get_power_status,
        .get_attention_status = get_attention_status,
+       .get_adapter_status = get_adapter_status,
+       .get_latch_status = get_latch_status,
 };
 
 static int
@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot)
                warn("failure to update adapter file");
        }
 
-       slot->extracting = 0;
-
+       if(slot->extracting) {
+               slot->extracting = 0;
+               atomic_dec(&extracting);
+       }
        return retval;
 }
 
@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
        return cpci_set_attention_status(hotplug_slot->private, status);
 }
 
+static int
+get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+       *value = hotplug_slot->info->adapter_status;
+       return 0;
+}
+
+static int
+get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
+{
+       *value = hotplug_slot->info->latch_status;
+       return 0;
+}
+
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
        struct slot *slot = hotplug_slot->private;
@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                }
 
                /* Add slot to our internal list */
-               spin_lock(&list_lock);
+               down_write(&list_rwsem);
                list_add(&slot->slot_list, &slot_list);
                slots++;
-               spin_unlock(&list_lock);
+               up_write(&list_rwsem);
        }
        return 0;
 error_name:
@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
        struct list_head *next;
        int status;
 
-       spin_lock(&list_lock);
+       down_write(&list_rwsem);
        if(!slots) {
-               spin_unlock(&list_lock);
+               up_write(&list_rwsem);
                return -1;
        }
        list_for_each_safe(tmp, next, &slot_list) {
@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
                        slots--;
                }
        }
-       spin_unlock(&list_lock);
+       up_write(&list_rwsem);
        return 0;
 }
 
@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
 }
 
 /*
- * According to PICMG 2.12 R2.0, section 6.3.2, upon
+ * According to PICMG 2.1 R2.0, section 6.3.2, upon
  * initialization, the system driver shall clear the
  * INS bits of the cold-inserted devices.
  */
@@ -359,9 +380,9 @@ init_slots(void)
        struct pci_dev* dev;
 
        dbg("%s - enter", __FUNCTION__);
-       spin_lock(&list_lock);
+       down_read(&list_rwsem);
        if(!slots) {
-               spin_unlock(&list_lock);
+               up_read(&list_rwsem);
                return -1;
        }
        list_for_each(tmp, &slot_list) {
@@ -386,7 +407,7 @@ init_slots(void)
                        }
                }
        }
-       spin_unlock(&list_lock);
+       up_read(&list_rwsem);
        dbg("%s - exit", __FUNCTION__);
        return 0;
 }
@@ -398,10 +419,11 @@ check_slots(void)
        struct list_head *tmp;
        int extracted;
        int inserted;
+       u16 hs_csr;
 
-       spin_lock(&list_lock);
+       down_read(&list_rwsem);
        if(!slots) {
-               spin_unlock(&list_lock);
+               up_read(&list_rwsem);
                err("no slots registered, shutting down");
                return -1;
        }
@@ -411,8 +433,6 @@ check_slots(void)
                dbg("%s - looking at slot %s",
                    __FUNCTION__, slot->hotplug_slot->name);
                if(cpci_check_and_clear_ins(slot)) {
-                       u16 hs_csr;
-
                        /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */
                        if(slot->dev) {
                                warn("slot %s already inserted", slot->hotplug_slot->name);
@@ -462,8 +482,6 @@ check_slots(void)
 
                        inserted++;
                } else if(cpci_check_ext(slot)) {
-                       u16 hs_csr;
-
                        /* Process extraction request */
                        dbg("%s - slot %s extracted",
                            __FUNCTION__, slot->hotplug_slot->name);
@@ -476,20 +494,40 @@ check_slots(void)
                        if(!slot->extracting) {
                                if(update_latch_status(slot->hotplug_slot, 0)) {
                                        warn("failure to update latch file");
+
                                }
+                               atomic_inc(&extracting);
                                slot->extracting = 1;
                        }
                        extracted++;
+               } else if(slot->extracting) {
+                       hs_csr = cpci_get_hs_csr(slot);
+                       if(hs_csr == 0xffff) {
+                               /*
+                                * Hmmm, we're likely hosed at this point, should we
+                                * bother trying to tell the driver or not?
+                                */
+                               err("card in slot %s was improperly removed",
+                                   slot->hotplug_slot->name);
+                               if(update_adapter_status(slot->hotplug_slot, 0)) {
+                                       warn("failure to update adapter file");
+                               }
+                               slot->extracting = 0;
+                               atomic_dec(&extracting);
+                       }
                }
        }
-       spin_unlock(&list_lock);
+       up_read(&list_rwsem);
+       dbg("inserted=%d, extracted=%d, extracting=%d",
+           inserted, extracted, atomic_read(&extracting));
        if(inserted || extracted) {
                return extracted;
        }
-       else {
+       else if(!atomic_read(&extracting)) {
                err("cannot find ENUM# source, shutting down");
                return -1;
        }
+       return 0;
 }
 
 /* This is the interrupt mode worker thread body */
@@ -497,8 +535,6 @@ static int
 event_thread(void *data)
 {
        int rc;
-       struct slot *slot;
-       struct list_head *tmp;
 
        lock_kernel();
        daemonize("cpci_hp_eventd");
@@ -512,39 +548,22 @@ event_thread(void *data)
                    thread_finished);
                if(thread_finished || signal_pending(current))
                        break;
-               while(controller->ops->query_enum()) {
+               do {
                        rc = check_slots();
-                       if (rc > 0)
+                       if (rc > 0) {
                                /* Give userspace a chance to handle extraction */
                                msleep(500);
-                       else if (rc < 0) {
+                       else if (rc < 0) {
                                dbg("%s - error checking slots", __FUNCTION__);
                                thread_finished = 1;
                                break;
                        }
-               }
-               /* Check for someone yanking out a board */
-               list_for_each(tmp, &slot_list) {
-                       slot = list_entry(tmp, struct slot, slot_list);
-                       if(slot->extracting) {
-                               /*
-                                * Hmmm, we're likely hosed at this point, should we
-                                * bother trying to tell the driver or not?
-                                */
-                               err("card in slot %s was improperly removed",
-                                   slot->hotplug_slot->name);
-                               if(update_adapter_status(slot->hotplug_slot, 0)) {
-                                       warn("failure to update adapter file");
-                               }
-                               slot->extracting = 0;
-                       }
-               }
+               } while(atomic_read(&extracting) != 0);
 
                /* Re-enable ENUM# interrupt */
                dbg("%s - re-enabling irq", __FUNCTION__);
                controller->ops->enable_irq();
        }
-
        dbg("%s - event thread signals exit", __FUNCTION__);
        up(&thread_exit);
        return 0;
@@ -555,8 +574,6 @@ static int
 poll_thread(void *data)
 {
        int rc;
-       struct slot *slot;
-       struct list_head *tmp;
 
        lock_kernel();
        daemonize("cpci_hp_polld");
@@ -565,35 +582,19 @@ poll_thread(void *data)
        while(1) {
                if(thread_finished || signal_pending(current))
                        break;
-
-               while(controller->ops->query_enum()) {
-                       rc = check_slots();
-                       if(rc > 0)
-                               /* Give userspace a chance to handle extraction */
-                               msleep(500);
-                       else if (rc < 0) {
-                               dbg("%s - error checking slots", __FUNCTION__);
-                               thread_finished = 1;
-                               break;
-                       }
-               }
-               /* Check for someone yanking out a board */
-               list_for_each(tmp, &slot_list) {
-                       slot = list_entry(tmp, struct slot, slot_list);
-                       if(slot->extracting) {
-                               /*
-                                * Hmmm, we're likely hosed at this point, should we
-                                * bother trying to tell the driver or not?
-                                */
-                               err("card in slot %s was improperly removed",
-                                   slot->hotplug_slot->name);
-                               if(update_adapter_status(slot->hotplug_slot, 0)) {
-                                       warn("failure to update adapter file");
+               if(controller->ops->query_enum()) {
+                       do {
+                               rc = check_slots();
+                               if(rc > 0) {
+                                       /* Give userspace a chance to handle extraction */
+                                       msleep(500);
+                               } else if(rc < 0) {
+                                       dbg("%s - error checking slots", __FUNCTION__);
+                                       thread_finished = 1;
+                                       break;
                                }
-                               slot->extracting = 0;
-                       }
+                       } while(atomic_read(&extracting) != 0);
                }
-
                msleep(100);
        }
        dbg("poll thread signals exit");
@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller)
        int status = 0;
 
        if(controller) {
+               if(atomic_read(&extracting) != 0) {
+                       return -EBUSY;
+               }
                if(!thread_finished) {
                        cpci_stop_thread();
                }
@@ -691,12 +695,12 @@ cpci_hp_start(void)
                return -ENODEV;
        }
 
-       spin_lock(&list_lock);
-       if(!slots) {
-               spin_unlock(&list_lock);
+       down_read(&list_rwsem);
+       if(list_empty(&slot_list)) {
+               up_read(&list_rwsem);
                return -ENODEV;
        }
-       spin_unlock(&list_lock);
+       up_read(&list_rwsem);
 
        if(first) {
                status = init_slots();
@@ -727,7 +731,9 @@ cpci_hp_stop(void)
        if(!controller) {
                return -ENODEV;
        }
-
+       if(atomic_read(&extracting) != 0) {
+               return -EBUSY;
+       }
        if(controller->irq) {
                /* Stop enum interrupt processing */
                dbg("%s - disabling irq", __FUNCTION__);
@@ -747,7 +753,7 @@ cleanup_slots(void)
         * Unregister all of our slots with the pci_hotplug subsystem,
         * and free up all memory that we had allocated.
         */
-       spin_lock(&list_lock);
+       down_write(&list_rwsem);
        if(!slots) {
                goto null_cleanup;
        }
@@ -761,17 +767,14 @@ cleanup_slots(void)
                kfree(slot);
        }
       null_cleanup:
-       spin_unlock(&list_lock);
+       up_write(&list_rwsem);
        return;
 }
 
 int __init
 cpci_hotplug_init(int debug)
 {
-       spin_lock_init(&list_lock);
        cpci_debug = debug;
-
-       info(DRIVER_DESC " version: " DRIVER_VERSION);
        return 0;
 }
 
index 2e969616f298d620fc0b62876460e557d7505058..69eb4fc54f2f6678c77d66432353402abc2b0571 100644 (file)
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
-#if !defined(MODULE)
 #define MY_NAME        "cpci_hotplug"
-#else
-#define MY_NAME        THIS_MODULE->name
-#endif
 
 extern int cpci_debug;
 
@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot)
        return hs_csr;
 }
 
-#if 0
-u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
-{
-       int hs_cap;
-       u16 new_hs_csr;
-
-       hs_cap = pci_bus_find_capability(slot->bus,
-                                        slot->devfn,
-                                        PCI_CAP_ID_CHSWP);
-       if(!hs_cap) {
-               return 0xFFFF;
-       }
-
-       /* Write out the new value */
-       if(pci_bus_write_config_word(slot->bus,
-                                     slot->devfn,
-                                     hs_cap + 2,
-                                     hs_csr)) {
-               return 0xFFFF;
-       }
-
-       /* Read back what we just wrote out */
-       if(pci_bus_read_config_word(slot->bus,
-                                    slot->devfn,
-                                    hs_cap + 2,
-                                    &new_hs_csr)) {
-               return 0xFFFF;
-       }
-       return new_hs_csr;
-}
-#endif
-
 int cpci_check_and_clear_ins(struct slot* slot)
 {
        int hs_cap;
@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot)
                return -ENODEV;
        }
        if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
-               /* Set LOO */
                hs_csr |= HS_CSR_LOO;
                if(pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot)
                return -ENODEV;
        }
        if(hs_csr & HS_CSR_LOO) {
-               /* Clear LOO */
                hs_csr &= ~HS_CSR_LOO;
                if(pci_bus_write_config_word(slot->bus,
                                              slot->devfn,
@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot)
  * Device configuration functions
  */
 
-static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
-{
-       u8 irq_pin;
-       int r;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /* NOTE: device already setup from prior scan */
-
-       /* FIXME: How would we know if we need to enable the expansion ROM? */
-       pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
-
-       /* Assign resources */
-       dbg("assigning resources for %02x:%02x.%x",
-           dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       for (r = 0; r < 6; r++) {
-               struct resource *res = dev->resource + r;
-               if(res->flags)
-                       pci_assign_resource(dev, r);
-       }
-       dbg("finished assigning resources for %02x:%02x.%x",
-           dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-       /* Does this function have an interrupt at all? */
-       dbg("checking for function interrupt");
-       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
-       if(irq_pin) {
-               dbg("function uses interrupt pin %d", irq_pin);
-       }
-
-       /*
-        * Need to explicitly set irq field to 0 so that it'll get assigned
-        * by the pcibios platform dependent code called by pci_enable_device.
-        */
-       dev->irq = 0;
-
-       dbg("enabling device");
-       pci_enable_device(dev); /* XXX check return */
-       dbg("now dev->irq = %d", dev->irq);
-       if(irq_pin && dev->irq) {
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-       }
-
-       /* Can't use pci_insert_device at the moment, do it manually for now */
-       pci_proc_attach_device(dev);
-       dbg("notifying drivers");
-       //pci_announce_device_to_drivers(dev);
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
+static void cpci_enable_device(struct pci_dev *dev)
 {
-       int rc;
-       struct pci_bus* child;
-       struct resource* r;
-       u8 max, n;
-       u16 command;
-
-       dbg("%s - enter", __FUNCTION__);
+       struct pci_bus *bus;
 
-       /* Do basic bridge initialization */
-       rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
-       }
-       rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
-       }
-       rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
-       if(rc) {
-               printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
-       }
-
-       /*
-        * Set parent bridge's subordinate field so that configuration space
-        * access will work in pci_scan_bridge and friends.
-        */
-       max = pci_max_busnr();
-       bus->subordinate = max + 1;
-       pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
-
-       /* Scan behind bridge */
-       n = pci_scan_bridge(bus, dev, max, 2);
-       child = pci_find_bus(0, max + 1);
-       if (!child)
-               return -ENODEV;
-       pci_proc_attach_bus(child);
-
-       /*
-        * Update parent bridge's subordinate field if there were more bridges
-        * behind the bridge that was scanned.
-        */
-       if(n > max) {
-               bus->subordinate = n;
-               pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
-       }
-
-       /*
-        * Update the bridge resources of the bridge to accommodate devices
-        * behind it.
-        */
-       pci_bus_size_bridges(child);
-       pci_bus_assign_resources(child);
-
-       /* Enable resource mapping via command register */
-       command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
-       r = child->resource[0];
-       if(r && r->start) {
-               command |= PCI_COMMAND_IO;
-       }
-       r = child->resource[1];
-       if(r && r->start) {
-               command |= PCI_COMMAND_MEMORY;
-       }
-       r = child->resource[2];
-       if(r && r->start) {
-               command |= PCI_COMMAND_MEMORY;
-       }
-       rc = pci_write_config_word(dev, PCI_COMMAND, command);
-       if(rc) {
-               err("Error setting command register");
-               return rc;
-       }
-
-       /* Set bridge control register */
-       command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
-       rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
-       if(rc) {
-               err("Error setting bridge control register");
-               return rc;
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
-                                  struct pci_bus_wrapped *wrapped_bus)
-{
-       int rc;
-       struct pci_dev *dev = wrapped_dev->dev;
-       struct pci_bus *bus = wrapped_bus->bus;
-       struct slot* slot;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /*
-        * We need to fix up the hotplug representation with the Linux
-        * representation.
-        */
-       if(wrapped_dev->data) {
-               slot = (struct slot*) wrapped_dev->data;
-               slot->dev = dev;
-       }
-
-       /* If it's a bridge, scan behind it for devices */
+       pci_enable_device(dev);
        if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-               rc = cpci_configure_bridge(bus, dev);
-               if(rc)
-                       return rc;
-       }
-
-       /* Actually configure device */
-       if(dev) {
-               rc = cpci_configure_dev(bus, dev);
-               if(rc)
-                       return rc;
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
-                                           struct pci_bus_wrapped *wrapped_bus)
-{
-       struct pci_dev *dev = wrapped_dev->dev;
-       struct slot* slot;
-
-       dbg("%s - enter", __FUNCTION__);
-       if(!dev)
-               return -ENODEV;
-
-       /* Remove the Linux representation */
-       if(pci_remove_device_safe(dev)) {
-               err("Could not remove device\n");
-               return -1;
-       }
-
-       /*
-        * Now remove the hotplug representation.
-        */
-       if(wrapped_dev->data) {
-               slot = (struct slot*) wrapped_dev->data;
-               slot->dev = NULL;
-       } else {
-               dbg("No hotplug representation for %02x:%02x.%x",
-                   dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
-}
-
-static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
-                                           struct pci_dev_wrapped *wrapped_dev)
-{
-       struct pci_bus *bus = wrapped_bus->bus;
-       struct pci_bus *parent = bus->self->bus;
-
-       dbg("%s - enter", __FUNCTION__);
-
-       /* The cleanup code for proc entries regarding buses should be in the kernel... */
-       if(bus->procdir)
-               dbg("detach_pci_bus %s", bus->procdir->name);
-       pci_proc_detach_bus(bus);
-
-       /* The cleanup code should live in the kernel... */
-       bus->self->subordinate = NULL;
-
-       /* unlink from parent bus */
-       list_del(&bus->node);
-
-       /* Now, remove */
-       if(bus)
-               kfree(bus);
-
-       /* Update parent's subordinate field */
-       if(parent) {
-               u8 n = pci_bus_max_busnr(parent);
-               if(n < parent->subordinate) {
-                       parent->subordinate = n;
-                       pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
+               bus = dev->subordinate;
+               list_for_each_entry(dev, &bus->devices, bus_list) {
+                       cpci_enable_device(dev);
                }
        }
-       dbg("%s - exit", __FUNCTION__);
-       return 0;
 }
 
-static struct pci_visit configure_functions = {
-       .visit_pci_dev = configure_visit_pci_dev,
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-       .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
-       .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
-};
-
-
 int cpci_configure_slot(struct slot* slot)
 {
-       int rc = 0;
+       unsigned char busnr;
+       struct pci_bus *child;
 
        dbg("%s - enter", __FUNCTION__);
 
@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot)
                slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
                if(slot->dev == NULL) {
                        err("Could not find PCI device for slot %02x", slot->number);
-                       return 0;
+                       return 1;
                }
        }
-       dbg("slot->dev = %p", slot->dev);
-       if(slot->dev) {
-               struct pci_dev *dev;
-               struct pci_dev_wrapped wrapped_dev;
-               struct pci_bus_wrapped wrapped_bus;
-               int i;
-
-               memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-               memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-               for (i = 0; i < 8; i++) {
-                       dev = pci_find_slot(slot->bus->number,
-                                           PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
-                       if(!dev)
-                               continue;
-                       wrapped_dev.dev = dev;
-                       wrapped_bus.bus = slot->dev->bus;
-                       if(i)
-                               wrapped_dev.data = NULL;
-                       else
-                               wrapped_dev.data = (void*) slot;
-                       rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-               }
+
+       if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+               pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr);
+               child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr);
+               pci_do_scan_bus(child);
+               pci_bus_size_bridges(child);
        }
 
-       dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-       return rc;
+       pci_bus_assign_resources(slot->dev->bus);
+
+       cpci_enable_device(slot->dev);
+
+       dbg("%s - exit", __FUNCTION__);
+       return 0;
 }
 
 int cpci_unconfigure_slot(struct slot* slot)
 {
-       int rc = 0;
        int i;
-       struct pci_dev_wrapped wrapped_dev;
-       struct pci_bus_wrapped wrapped_bus;
        struct pci_dev *dev;
 
        dbg("%s - enter", __FUNCTION__);
-
        if(!slot->dev) {
                err("No device for slot %02x\n", slot->number);
                return -ENODEV;
        }
 
-       memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-       memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
        for (i = 0; i < 8; i++) {
                dev = pci_find_slot(slot->bus->number,
                                    PCI_DEVFN(PCI_SLOT(slot->devfn), i));
                if(dev) {
-                       wrapped_dev.dev = dev;
-                       wrapped_bus.bus = dev->bus;
-                       if(i)
-                               wrapped_dev.data = NULL;
-                       else
-                               wrapped_dev.data = (void*) slot;
-                       dbg("%s - unconfigure phase 2", __FUNCTION__);
-                       rc = pci_visit_dev(&unconfigure_functions_phase2,
-                                          &wrapped_dev,
-                                          &wrapped_bus);
-                       if(rc)
-                               break;
+                       pci_remove_bus_device(dev);
+                       slot->dev = NULL;
                }
        }
-       dbg("%s - exit, rc = %d", __FUNCTION__, rc);
-       return rc;
+       dbg("%s - exit", __FUNCTION__);
+       return 0;
 }
index f313121d51414d9a3f12bf26bea28a6bfe0b2bcc..46b294a12418a65eb58055c2535a9e2f23bd39d5 100644 (file)
@@ -130,6 +130,7 @@ struct controller {
        u8 slot_bus;            /* Bus where the slots handled by this controller sit */
        u8 ctrlcap;
        u16 vendor_id;
+       u8 cap_base;
 };
 
 struct irq_mapping {
index ed1fd8d6178d7f7418d840f93db0ef6e04142c67..df4915dbc321ca21622dd187b1a8ebc852b5bfae 100644 (file)
@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev)
 static struct pcie_port_service_id port_pci_ids[] = { { 
        .vendor = PCI_ANY_ID, 
        .device = PCI_ANY_ID,
-       .port_type = PCIE_RC_PORT, 
+       .port_type = PCIE_ANY_PORT,
        .service_type = PCIE_PORT_SERVICE_HP,
        .driver_data =  0, 
        }, { /* end: all zeroes */ }
index 9e70c4681f77e57d782116ce6d74afb3729c7ceb..1cda30bd6e47c90020fec4290f15aee624f95a4f 100644 (file)
@@ -109,20 +109,20 @@ enum ctrl_offsets {
 };
 static int pcie_cap_base = 0;          /* Base of the PCI Express capability item structure */ 
 
-#define PCIE_CAP_ID    ( pcie_cap_base + PCIECAPID )
-#define NXT_CAP_PTR    ( pcie_cap_base + NXTCAPPTR )
-#define CAP_REG                ( pcie_cap_base + CAPREG )
-#define DEV_CAP                ( pcie_cap_base + DEVCAP )
-#define DEV_CTRL       ( pcie_cap_base + DEVCTRL )
-#define DEV_STATUS     ( pcie_cap_base + DEVSTATUS )
-#define LNK_CAP                ( pcie_cap_base + LNKCAP )
-#define LNK_CTRL       ( pcie_cap_base + LNKCTRL )
-#define LNK_STATUS     ( pcie_cap_base + LNKSTATUS )
-#define SLOT_CAP       ( pcie_cap_base + SLOTCAP )
-#define SLOT_CTRL      ( pcie_cap_base + SLOTCTRL )
-#define SLOT_STATUS    ( pcie_cap_base + SLOTSTATUS )
-#define ROOT_CTRL      ( pcie_cap_base + ROOTCTRL )
-#define ROOT_STATUS    ( pcie_cap_base + ROOTSTATUS )
+#define PCIE_CAP_ID(cb)        ( cb + PCIECAPID )
+#define NXT_CAP_PTR(cb)        ( cb + NXTCAPPTR )
+#define CAP_REG(cb)    ( cb + CAPREG )
+#define DEV_CAP(cb)    ( cb + DEVCAP )
+#define DEV_CTRL(cb)   ( cb + DEVCTRL )
+#define DEV_STATUS(cb) ( cb + DEVSTATUS )
+#define LNK_CAP(cb)    ( cb + LNKCAP )
+#define LNK_CTRL(cb)   ( cb + LNKCTRL )
+#define LNK_STATUS(cb) ( cb + LNKSTATUS )
+#define SLOT_CAP(cb)   ( cb + SLOTCAP )
+#define SLOT_CTRL(cb)  ( cb + SLOTCTRL )
+#define SLOT_STATUS(cb)        ( cb + SLOTSTATUS )
+#define ROOT_CTRL(cb)  ( cb + ROOTCTRL )
+#define ROOT_STATUS(cb)        ( cb + ROOTSTATUS )
 
 #define hp_register_read_word(pdev, reg , value)               \
        pci_read_config_word(pdev, reg, &value)
@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
        if (retval) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return retval;
@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
        }
 
        dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
-       retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
+       retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
        if (retval) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl)
                return -1;
        }
        
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
 
-       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
 
@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
 
@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
                err("%s: Invalid HPC slot number!\n", __FUNCTION__);
                return -1;
        }
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 
        pcie_write_cmd(slot, slot_cmd);
-       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        
        return rc;
 }
@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot)
 
        pcie_write_cmd(slot, slot_cmd);
 
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        return;
 }
 
@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot)
        if (!pciehp_poll_mode)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
        pcie_write_cmd(slot, slot_cmd);
-       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        return;
 }
@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
                return ;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
                slot_cmd = slot_cmd | HP_INTR_ENABLE; 
        pcie_write_cmd(slot, slot_cmd);
 
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
        return;
 }
 
@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl,
        *first_device_num = 0;
        *num_ctlr_slots = 1; 
 
-       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
+       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
 
        if (rc) {
                err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL
+       dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
                slot_ctrl);
 
        slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot)
                err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
                return -1;
        }
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        DBG_LEAVE_ROUTINE
 
@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot)
                err("%s: Invalid HPC slot number!\n", __FUNCTION__);
                return -1;
        }
-       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
        if (retval) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                return retval;
        }
-       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL
+       dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
                slot_ctrl);
 
        slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot)
                err("%s: Write command failed!\n", __FUNCTION__);
                return -1;
        }
-       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd);
+       dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
 
        DBG_LEAVE_ROUTINE
 
@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                return IRQ_NONE;
        }
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                return IRQ_NONE;
@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
        dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
        /* Mask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
                }
                dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                
                /* Clear command complete interrupt caused by this write */
                temp_word = 0x1f;
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
 
        /* Clear all events after serving them */
        temp_word = 0x1F;
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                return IRQ_NONE;
        }
        /* Unmask Hot-plug Interrupt Enable */
        if (!pciehp_poll_mode) {
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
                temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
 
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                        return IRQ_NONE;
                }
                dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);   
        
-               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+               rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
                if (rc) {
                        err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
                
                /* Clear command complete interrupt caused by this write */
                temp_word = 0x1F;
-               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+               rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
                if (rc) {
                        err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                        return IRQ_NONE;
@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
                return -1;
        }
 
-       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
+       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
 
        if (retval) {
                err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
                return -1;
        }
 
-       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap);
+       retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
 
        if (retval) {
                err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value
                return -1;
        }
 
-       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status);
+       retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
 
        if (retval) {
                err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl,
                goto abort_free_ctlr;
        }
 
-       pcie_cap_base = cap_base;
+       ctrl->cap_base = cap_base;
 
        dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
 
-       rc = hp_register_read_word(pdev, CAP_REG, cap_reg);
+       rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
        if (rc) {
                err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg);
+       dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
 
-       if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){
+       if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
+               && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
                dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
 
-       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap);
+       rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
        if (rc) {
                err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap);
+       dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
 
        if (!(slot_cap & HP_CAP)) {
                dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        /* For debugging purpose */
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
+       dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl);
+       dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
 
        if (first) {
                spin_lock_init(&hpc_event_lock);
@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl,
        php_ctlr->num_slots = 1;
 
        /* Mask Hot-plug Interrupt Enable */
-       rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
 
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
        temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
-       rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
 
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
+       dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
+               , slot_status);
 
        temp_word = 0x1F; /* Clear all events */
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
+       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
 
        if (pciehp_poll_mode)  {/* Install interrupt polling code */
                /* Install and start the interrupt polling timer */
@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl,
                }
        }
 
-       rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+       dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
        dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
 
        intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl,
        dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
 
        /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
-       rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
+       rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
-       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
+       rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
        if (rc) {
                err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
        dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, 
-               SLOT_STATUS, slot_status);
+               SLOT_STATUS(ctrl->cap_base), slot_status);
        
        temp_word =  0x1F; /* Clear all events */
-       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
+       rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
        if (rc) {
                err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
                goto abort_free_ctlr;
        }
-       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
+       dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
        
        /*  Add this HPC instance into the HPC list */
        spin_lock(&list_lock);
index f0c53f850aedb12b2c7be0eeaeb5b39146b12eff..a70a5c5705f2dee83f0da960c3a836269735e43d 100644 (file)
@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = {
  */
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = (struct slot *)hotplug_slot->private;
+       struct slot *slot = hotplug_slot->private;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
index 9f90eb8e6ecd8302812dd90d5da19c8fffaf17cc..490a9553a0625175d7ba02783988f6915fbc57b7 100644 (file)
@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot)
        func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
        if (!func) {
                dbg("%s: Error! slot NULL\n", __FUNCTION__);
-               return 1;
+               return -ENODEV;
        }
 
        /* Check to see if (latch closed, card present, power off) */
@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot)
        if (rc || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        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 1;
+               return -ENODEV;
        }
        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 1;
+               return -ENODEV;
        }
        up(&p_slot->ctrl->crit_sect);
 
@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot)
 
        func = shpchp_slot_create(p_slot->bus);
        if (func == NULL)
-               return 1;
+               return -ENOMEM;
 
        func->bus = p_slot->bus;
        func->device = p_slot->device;
@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot)
                /* Setup slot structure with entry for empty slot */
                func = shpchp_slot_create(p_slot->bus);
                if (func == NULL)
-                       return (1);     /* Out of memory */
+                       return -ENOMEM; /* Out of memory */
 
                func->bus = p_slot->bus;
                func->device = p_slot->device;
@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot)
        struct pci_func *func;
 
        if (!p_slot->ctrl)
-               return 1;
+               return -ENODEV;
 
        pci_bus = p_slot->ctrl->pci_dev->subordinate;
 
@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot)
        if (ret || !getstatus) {
                info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
                up(&p_slot->ctrl->crit_sect);
-               return 1;
+               return -ENODEV;
        }
        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);
-               return 1;
+               return -ENODEV;
        }
        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);
-               return 1;
+               return -ENODEV;
        }
        up(&p_slot->ctrl->crit_sect);
 
@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot)
                /* Check the Class Code */
                rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
                if (rc)
-                       return rc;
+                       return -ENODEV;
 
                if (class_code == PCI_BASE_CLASS_DISPLAY) {
                        /* Display/Video adapter (not supported) */
@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot)
                        /* See if it's a bridge */
                        rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
                        if (rc)
-                               return rc;
+                               return -ENODEV;
 
                        /* If it's a bridge, check the VGA Enable bit */
                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
                                rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
                                if (rc)
-                                       return rc;
+                                       return -ENODEV;
 
                                /* If the VGA Enable bit is set, remove isn't supported */
                                if (BCR & PCI_BRIDGE_CTL_VGA) {
@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot)
        if ((func != NULL) && !rc) {
                rc = remove_board(func, p_slot->ctrl);
        } else if (!rc)
-               rc = 1;
+               rc = -ENODEV;
 
        if (p_slot)
                update_slot_info(p_slot);
 
-       return(rc);
+       return rc;
 }
 
 
index 8568b207f18927f4d4cc23006ff2edf07dc932be..6ca0061137a6937891fb1757699e010abec9d688 100644 (file)
@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf)
        return (str - buf);
 }
 
+static ssize_t modalias_show(struct device *dev, char *buf)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+
+       return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+                      pci_dev->vendor, pci_dev->device,
+                      pci_dev->subsystem_vendor, pci_dev->subsystem_device,
+                      (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
+                      (u8)(pci_dev->class));
+}
+
 struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(resource),
        __ATTR_RO(vendor),
@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = {
        __ATTR_RO(class),
        __ATTR_RO(irq),
        __ATTR_RO(local_cpus),
+       __ATTR_RO(modalias),
        __ATTR_NULL,
 };
 
index 79cdc16c52c826b7a1633de4dfb634c6f9f3b8f3..744da0d4ae5f90614a1f719299d23e23854c749e 100644 (file)
@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void);
 extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
 
-struct pci_dev_wrapped {
-       struct pci_dev  *dev;
-       void            *data;
-};
-
-struct pci_bus_wrapped {
-       struct pci_bus  *bus;
-       void            *data;
-};
-
-struct pci_visit {
-       int (* pre_visit_pci_bus)       (struct pci_bus_wrapped *,
-                                        struct pci_dev_wrapped *);
-       int (* post_visit_pci_bus)      (struct pci_bus_wrapped *,
-                                        struct pci_dev_wrapped *);
-
-       int (* pre_visit_pci_dev)       (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-       int (* visit_pci_dev)           (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-       int (* post_visit_pci_dev)      (struct pci_dev_wrapped *,
-                                        struct pci_bus_wrapped *);
-};
-
-extern int pci_visit_dev(struct pci_visit *fn,
-                        struct pci_dev_wrapped *wrapped_dev,
-                        struct pci_bus_wrapped *wrapped_parent);
 extern void pci_remove_legacy_files(struct pci_bus *bus);
 
 /* Lock for read/write access to pci device and bus lists */
index 4037a3e568de9d97043a946e6eb936f914de27cb..3e84b501e6a419ea2b7e28452983c36a8a127bff 100644 (file)
@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
                driver->id_table->vendor != pciedev->id.vendor) ||
               (driver->id_table->device != PCI_ANY_ID &&
                driver->id_table->device != pciedev->id.device) ||      
-               driver->id_table->port_type != pciedev->id.port_type ||
+              (driver->id_table->port_type != PCIE_ANY_PORT &&
+               driver->id_table->port_type != pciedev->id.port_type) ||
                driver->id_table->service_type != pciedev->id.service_type )
                return 0;
 
index 545b440a2d2fac2d2cd193c40938a440be24c953..981ccb233ef5e29949152a6dea0aeb55edc84b8c 100644 (file)
@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function,
                       int errno)
 {
        char nbuf[16];
-       const char *errstr = ext3_decode_error(sb, errno, nbuf);
+       const char *errstr;
+
+       /* Special case: if the error is EROFS, and we're not already
+        * inside a transaction, then there's really no point in logging
+        * an error. */
+       if (errno == -EROFS && journal_current_handle() == NULL &&
+           (sb->s_flags & MS_RDONLY))
+               return;
 
+       errstr = ext3_decode_error(sb, errno, nbuf);
        printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n",
                sb->s_id, function, errstr);
 
index cf470459fa691985be0b4c79fb86a7c2945f534a..df94c0de53f2b6b0d91c56142838766db5fd0a3b 100644 (file)
@@ -273,9 +273,6 @@ struct device {
                                           BIOS data relevant to device) */
        struct dev_pm_info      power;
 
-       u32             detach_state;   /* State to enter when device is
-                                          detached from its driver. */
-
        u64             *dma_mask;      /* dma mask (if dma'able device) */
        u64             coherent_dma_mask;/* Like dma_mask, but for
                                             alloc_coherent mappings as
index 7960ddf04a57fca65ce7562ed565a1e1f5f872cd..4cdebc972ff2a55c7fdac702dca0c36f81905558 100644 (file)
@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state)
                goto Unlock;
        }
 
-       pr_debug("PM: Preparing system for suspend\n");
+       pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
        if ((error = suspend_prepare(state)))
                goto Unlock;
 
-       pr_debug("PM: Entering state.\n");
+       pr_debug("PM: Entering %s sleep\n", pm_states[state]);
        error = suspend_enter(state);
 
-       pr_debug("PM: Finishing up.\n");
+       pr_debug("PM: Finishing wakeup.\n");
        suspend_finish(state);
  Unlock:
        up(&pm_sem);
index 01f9793591f666965342df8ef886358680bbae4c..63df2d698414a631078a294afe419f0d4fb0bd6d 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        addr = mm->free_area_cache;
 
        /* make sure it can fit in the remaining address space */
-       if (addr >= len) {
+       if (addr > len) {
                vma = find_vma(mm, addr-len);
                if (!vma || addr <= vma->vm_start)
                        /* remember the address as a hint for next time */
@@ -1266,7 +1266,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
                /* try just below the current vma->vm_start */
                addr = vma->vm_start-len;
-       } while (len <= vma->vm_start);
+       } while (len < vma->vm_start);
 
        /*
         * A failed mmap() very likely causes application failure,