vserver 1.9.3
[linux-2.6.git] / drivers / pci / hotplug / cpci_hotplug_core.c
index 4f9405b..ed24360 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
+#include <linux/delay.h>
 #include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
 #define DRIVER_DESC    "CompactPCI Hot Plug Core"
 
-#if !defined(CONFIG_HOTPLUG_CPCI_MODULE)
 #define MY_NAME        "cpci_hotplug"
-#else
-#define MY_NAME        THIS_MODULE->name
-#endif
 
 #define dbg(format, arg...)                                    \
        do {                                                    \
@@ -71,63 +68,21 @@ 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_latch_status(struct hotplug_slot *slot, u8 * value);
-static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
 
 static struct hotplug_slot_ops cpci_hotplug_slot_ops = {
        .owner = THIS_MODULE,
        .enable_slot = enable_slot,
        .disable_slot = disable_slot,
        .set_attention_status = set_attention_status,
-       .hardware_test = NULL,
        .get_power_status = get_power_status,
        .get_attention_status = get_attention_status,
-       .get_latch_status = get_latch_status,
-       .get_adapter_status = get_adapter_status,
 };
 
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int
-slot_paranoia_check(struct slot *slot, const char *function)
-{
-       if(!slot) {
-               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;
-       }
-       return 0;
-}
-
-static inline struct slot *
-get_slot(struct hotplug_slot *hotplug_slot, const char *function)
-{
-       struct slot *slot;
-
-       if(!hotplug_slot) {
-               dbg("%s - hotplug_slot == NULL", function);
-               return NULL;
-       }
-
-       slot = (struct slot *) hotplug_slot->private;
-       if(slot_paranoia_check(slot, function))
-               return NULL;
-       return slot;
-}
-
 static int
 update_latch_status(struct hotplug_slot *hotplug_slot, u8 value)
 {
        struct hotplug_slot_info info;
 
-       if(!(hotplug_slot && hotplug_slot->info))
-               return -EINVAL;
        memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
        info.latch_status = value;
        return pci_hp_change_slot_info(hotplug_slot, &info);
@@ -138,8 +93,6 @@ update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
 {
        struct hotplug_slot_info info;
 
-       if(!(hotplug_slot && hotplug_slot->info))
-               return -EINVAL;
        memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
        info.adapter_status = value;
        return pci_hp_change_slot_info(hotplug_slot, &info);
@@ -148,12 +101,9 @@ update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value)
 static int
 enable_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       if(slot == NULL)
-               return -ENODEV;
-
        dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
 
        if(controller->ops->set_power) {
@@ -166,12 +116,9 @@ enable_slot(struct hotplug_slot *hotplug_slot)
 static int
 disable_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       if(slot == NULL)
-               return -ENODEV;
-
        dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
 
        /* Unconfigure device */
@@ -220,10 +167,8 @@ cpci_get_power_status(struct 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 = hotplug_slot->private;
 
-       if(slot == NULL)
-               return -ENODEV;
        *value = cpci_get_power_status(slot);
        return 0;
 }
@@ -231,10 +176,8 @@ 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 = hotplug_slot->private;
 
-       if(slot == NULL)
-               return -ENODEV;
        *value = cpci_get_attention_status(slot);
        return 0;
 }
@@ -242,48 +185,12 @@ get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
 static int
 set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-       if(slot == NULL)
-               return -ENODEV;
-       switch (status) {
-       case 0:
-               cpci_set_attention_status(slot, 0);
-               break;
-
-       case 1:
-       default:
-               cpci_set_attention_status(slot, 1);
-               break;
-       }
-
-       return 0;
-}
-
-static int
-get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-       if(hotplug_slot == NULL || hotplug_slot->info == NULL)
-               return -ENODEV;
-       *value = hotplug_slot->info->latch_status;
-       return 0;
-}
-
-static int
-get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value)
-{
-       if(hotplug_slot == NULL || hotplug_slot->info == NULL)
-               return -ENODEV;
-       *value = hotplug_slot->info->adapter_status;
-       return 0;
+       return cpci_set_attention_status(hotplug_slot->private, status);
 }
 
 static void release_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
-
-       if(slot == NULL)
-               return;
+       struct slot *slot = hotplug_slot->private;
 
        kfree(slot->hotplug_slot->info);
        kfree(slot->hotplug_slot->name);
@@ -306,15 +213,12 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
        char *name;
-       int status = 0;
+       int status = -ENOMEM;
        int i;
 
        if(!(controller && bus)) {
                return -ENODEV;
        }
-       if(last < first) {
-               return -EINVAL;
-       }
 
        /*
         * Create a structure for each slot, and register that slot
@@ -322,38 +226,28 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
         */
        for (i = first; i <= last; ++i) {
                slot = kmalloc(sizeof (struct slot), GFP_KERNEL);
-               if(!slot)
-                       return -ENOMEM;
+               if (!slot)
+                       goto error;
                memset(slot, 0, sizeof (struct slot));
 
                hotplug_slot =
                    kmalloc(sizeof (struct hotplug_slot), GFP_KERNEL);
-               if(!hotplug_slot) {
-                       kfree(slot);
-                       return -ENOMEM;
-               }
+               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);
-               if(!info) {
-                       kfree(hotplug_slot);
-                       kfree(slot);
-                       return -ENOMEM;
-               }
+               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) {
-                       kfree(info);
-                       kfree(hotplug_slot);
-                       kfree(slot);
-                       return -ENOMEM;
-               }
+               if (!name)
+                       goto error_info;
                hotplug_slot->name = name;
 
-               slot->magic = SLOT_MAGIC;
                slot->bus = bus;
                slot->number = i;
                slot->devfn = PCI_DEVFN(i, 0);
@@ -373,13 +267,9 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
 
                dbg("registering slot %s", slot->hotplug_slot->name);
                status = pci_hp_register(slot->hotplug_slot);
-               if(status) {
+               if (status) {
                        err("pci_hp_register failed with error %d", status);
-                       kfree(info);
-                       kfree(name);
-                       kfree(hotplug_slot);
-                       kfree(slot);
-                       return status;
+                       goto error_name;
                }
 
                /* Add slot to our internal list */
@@ -388,6 +278,16 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                slots++;
                spin_unlock(&list_lock);
        }
+       return 0;
+error_name:
+       kfree(name);
+error_info:
+       kfree(info);
+error_hpslot:
+       kfree(hotplug_slot);
+error_slot:
+       kfree(slot);
+error:
        return status;
 }
 
@@ -399,10 +299,6 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
        struct list_head *next;
        int status;
 
-       if(!bus) {
-               return -ENODEV;
-       }
-
        spin_lock(&list_lock);
        if(!slots) {
                spin_unlock(&list_lock);
@@ -428,7 +324,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
 }
 
 /* This is the interrupt mode interrupt handler */
-irqreturn_t
+static irqreturn_t
 cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
 {
        dbg("entered cpci_hp_intr");
@@ -618,11 +514,10 @@ event_thread(void *data)
                        break;
                while(controller->ops->query_enum()) {
                        rc = check_slots();
-                       if(rc > 0) {
+                       if (rc > 0)
                                /* Give userspace a chance to handle extraction */
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(HZ / 2);
-                       } else if(rc < 0) {
+                               msleep(500);
+                       else if (rc < 0) {
                                dbg("%s - error checking slots", __FUNCTION__);
                                thread_finished = 1;
                                break;
@@ -673,11 +568,10 @@ poll_thread(void *data)
 
                while(controller->ops->query_enum()) {
                        rc = check_slots();
-                       if(rc > 0) {
+                       if(rc > 0)
                                /* Give userspace a chance to handle extraction */
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(HZ / 2);
-                       } else if(rc < 0) {
+                               msleep(500);
+                       else if (rc < 0) {
                                dbg("%s - error checking slots", __FUNCTION__);
                                thread_finished = 1;
                                break;
@@ -700,8 +594,7 @@ poll_thread(void *data)
                        }
                }
 
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ / 10);
+               msleep(100);
        }
        dbg("poll thread signals exit");
        up(&thread_exit);
@@ -719,9 +612,9 @@ cpci_start_thread(void)
        thread_finished = 0;
 
        if(controller->irq) {
-               pid = kernel_thread(event_thread, 0, 0);
+               pid = kernel_thread(event_thread, NULL, 0);
        } else {
-               pid = kernel_thread(poll_thread, 0, 0);
+               pid = kernel_thread(poll_thread, NULL, 0);
        }
        if(pid < 0) {
                err("Can't start up our thread");
@@ -891,7 +784,6 @@ cpci_hotplug_exit(void)
        cleanup_slots();
 }
 
-
 EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
 EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
 EXPORT_SYMBOL_GPL(cpci_hp_register_bus);