]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pci/hotplug/cpci_hotplug_core.c
PCI: introduce pci_slot
[linux-2.6-omap-h63xx.git] / drivers / pci / hotplug / cpci_hotplug_core.c
index d06ab4045134a5898d41d38fab9926b79b835346..935947991dc98649dfaa8794fb55604ee12cb895 100644 (file)
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #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 <linux/kthread.h>
 #include "cpci_hotplug.h"
 
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
@@ -59,9 +60,8 @@ 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) */
-static struct semaphore thread_exit;           /* guard ensure thread has exited before calling it quits */
-static int thread_finished = 1;
+static struct task_struct *cpci_thread;
+static int thread_finished;
 
 static int enable_slot(struct hotplug_slot *slot);
 static int disable_slot(struct hotplug_slot *slot);
@@ -108,7 +108,7 @@ enable_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
 
        if (controller->ops->set_power)
                retval = controller->ops->set_power(slot, 1);
@@ -121,25 +121,25 @@ disable_slot(struct hotplug_slot *hotplug_slot)
        struct slot *slot = hotplug_slot->private;
        int retval = 0;
 
-       dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name);
+       dbg("%s - physical_slot = %s", __func__, hotplug_slot->name);
 
        down_write(&list_rwsem);
 
        /* Unconfigure device */
        dbg("%s - unconfiguring slot %s",
-           __FUNCTION__, slot->hotplug_slot->name);
+           __func__, slot->hotplug_slot->name);
        if ((retval = cpci_unconfigure_slot(slot))) {
                err("%s - could not unconfigure slot %s",
-                   __FUNCTION__, slot->hotplug_slot->name);
+                   __func__, slot->hotplug_slot->name);
                goto disable_error;
        }
        dbg("%s - finished unconfiguring slot %s",
-           __FUNCTION__, slot->hotplug_slot->name);
+           __func__, slot->hotplug_slot->name);
 
        /* Clear EXT (by setting it) */
        if (cpci_clear_ext(slot)) {
                err("%s - could not clear EXT for slot %s",
-                   __FUNCTION__, slot->hotplug_slot->name);
+                   __func__, slot->hotplug_slot->name);
                retval = -ENODEV;
                goto disable_error;
        }
@@ -285,7 +285,7 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last)
                info->attention_status = cpci_get_attention_status(slot);
 
                dbg("registering slot %s", slot->hotplug_slot->name);
-               status = pci_hp_register(slot->hotplug_slot);
+               status = pci_hp_register(slot->hotplug_slot, bus, i);
                if (status) {
                        err("pci_hp_register failed with error %d", status);
                        goto error_name;
@@ -357,9 +357,7 @@ cpci_hp_intr(int irq, void *data)
        controller->ops->disable_irq();
 
        /* Trigger processing by the event thread */
-       dbg("Signal event_semaphore");
-       up(&event_semaphore);
-       dbg("exited cpci_hp_intr");
+       wake_up_process(cpci_thread);
        return IRQ_HANDLED;
 }
 
@@ -374,7 +372,7 @@ init_slots(int clear_ins)
        struct slot *slot;
        struct pci_dev* dev;
 
-       dbg("%s - enter", __FUNCTION__);
+       dbg("%s - enter", __func__);
        down_read(&list_rwsem);
        if (!slots) {
                up_read(&list_rwsem);
@@ -382,10 +380,10 @@ init_slots(int clear_ins)
        }
        list_for_each_entry(slot, &slot_list, slot_list) {
                dbg("%s - looking at slot %s",
-                   __FUNCTION__, slot->hotplug_slot->name);
+                   __func__, slot->hotplug_slot->name);
                if (clear_ins && cpci_check_and_clear_ins(slot))
                        dbg("%s - cleared INS for slot %s",
-                           __FUNCTION__, slot->hotplug_slot->name);
+                           __func__, slot->hotplug_slot->name);
                dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0));
                if (dev) {
                        if (update_adapter_status(slot->hotplug_slot, 1))
@@ -396,7 +394,7 @@ init_slots(int clear_ins)
                }
        }
        up_read(&list_rwsem);
-       dbg("%s - exit", __FUNCTION__);
+       dbg("%s - exit", __func__);
        return 0;
 }
 
@@ -417,7 +415,7 @@ check_slots(void)
        extracted = inserted = 0;
        list_for_each_entry(slot, &slot_list, slot_list) {
                dbg("%s - looking at slot %s",
-                   __FUNCTION__, slot->hotplug_slot->name);
+                   __func__, slot->hotplug_slot->name);
                if (cpci_check_and_clear_ins(slot)) {
                        /*
                         * Some broken hardware (e.g. PLX 9054AB) asserts
@@ -432,28 +430,28 @@ check_slots(void)
 
                        /* Process insertion */
                        dbg("%s - slot %s inserted",
-                           __FUNCTION__, slot->hotplug_slot->name);
+                           __func__, slot->hotplug_slot->name);
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (1) = %04x",
-                           __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot->hotplug_slot->name, hs_csr);
 
                        /* Configure device */
                        dbg("%s - configuring slot %s",
-                           __FUNCTION__, slot->hotplug_slot->name);
+                           __func__, slot->hotplug_slot->name);
                        if (cpci_configure_slot(slot)) {
                                err("%s - could not configure slot %s",
-                                   __FUNCTION__, slot->hotplug_slot->name);
+                                   __func__, slot->hotplug_slot->name);
                                continue;
                        }
                        dbg("%s - finished configuring slot %s",
-                           __FUNCTION__, slot->hotplug_slot->name);
+                           __func__, slot->hotplug_slot->name);
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (2) = %04x",
-                           __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot->hotplug_slot->name, hs_csr);
 
                        if (update_latch_status(slot->hotplug_slot, 1))
                                warn("failure to update latch file");
@@ -466,18 +464,18 @@ check_slots(void)
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR (3) = %04x",
-                           __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot->hotplug_slot->name, hs_csr);
 
                        inserted++;
                } else if (cpci_check_ext(slot)) {
                        /* Process extraction request */
                        dbg("%s - slot %s extracted",
-                           __FUNCTION__, slot->hotplug_slot->name);
+                           __func__, slot->hotplug_slot->name);
 
                        /* GSM, debug */
                        hs_csr = cpci_get_hs_csr(slot);
                        dbg("%s - slot %s HS_CSR = %04x",
-                           __FUNCTION__, slot->hotplug_slot->name, hs_csr);
+                           __func__, slot->hotplug_slot->name, hs_csr);
 
                        if (!slot->extracting) {
                                if (update_latch_status(slot->hotplug_slot, 0)) {
@@ -521,17 +519,12 @@ event_thread(void *data)
 {
        int rc;
 
-       lock_kernel();
-       daemonize("cpci_hp_eventd");
-       unlock_kernel();
-
-       dbg("%s - event thread started", __FUNCTION__);
+       dbg("%s - event thread started", __func__);
        while (1) {
                dbg("event thread sleeping");
-               down_interruptible(&event_semaphore);
-               dbg("event thread woken, thread_finished = %d",
-                   thread_finished);
-               if (thread_finished || signal_pending(current))
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule();
+               if (kthread_should_stop())
                        break;
                do {
                        rc = check_slots();
@@ -539,20 +532,19 @@ event_thread(void *data)
                                /* Give userspace a chance to handle extraction */
                                msleep(500);
                        } else if (rc < 0) {
-                               dbg("%s - error checking slots", __FUNCTION__);
+                               dbg("%s - error checking slots", __func__);
                                thread_finished = 1;
-                               break;
+                               goto out;
                        }
-               } while (atomic_read(&extracting) && !thread_finished);
-               if (thread_finished)
+               } while (atomic_read(&extracting) && !kthread_should_stop());
+               if (kthread_should_stop())
                        break;
 
                /* Re-enable ENUM# interrupt */
-               dbg("%s - re-enabling irq", __FUNCTION__);
+               dbg("%s - re-enabling irq", __func__);
                controller->ops->enable_irq();
        }
-       dbg("%s - event thread signals exit", __FUNCTION__);
-       up(&thread_exit);
+ out:
        return 0;
 }
 
@@ -562,12 +554,8 @@ poll_thread(void *data)
 {
        int rc;
 
-       lock_kernel();
-       daemonize("cpci_hp_polld");
-       unlock_kernel();
-
        while (1) {
-               if (thread_finished || signal_pending(current))
+               if (kthread_should_stop() || signal_pending(current))
                        break;
                if (controller->ops->query_enum()) {
                        do {
@@ -576,50 +564,38 @@ poll_thread(void *data)
                                        /* Give userspace a chance to handle extraction */
                                        msleep(500);
                                } else if (rc < 0) {
-                                       dbg("%s - error checking slots", __FUNCTION__);
+                                       dbg("%s - error checking slots", __func__);
                                        thread_finished = 1;
-                                       break;
+                                       goto out;
                                }
-                       } while (atomic_read(&extracting) && !thread_finished);
+                       } while (atomic_read(&extracting) && !kthread_should_stop());
                }
                msleep(100);
        }
-       dbg("poll thread signals exit");
-       up(&thread_exit);
+ out:
        return 0;
 }
 
 static int
 cpci_start_thread(void)
 {
-       int pid;
-
-       /* initialize our semaphores */
-       init_MUTEX_LOCKED(&event_semaphore);
-       init_MUTEX_LOCKED(&thread_exit);
-       thread_finished = 0;
-
        if (controller->irq)
-               pid = kernel_thread(event_thread, NULL, 0);
+               cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd");
        else
-               pid = kernel_thread(poll_thread, NULL, 0);
-       if (pid < 0) {
+               cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld");
+       if (IS_ERR(cpci_thread)) {
                err("Can't start up our thread");
-               return -1;
+               return PTR_ERR(cpci_thread);
        }
-       dbg("Our thread pid = %d", pid);
+       thread_finished = 0;
        return 0;
 }
 
 static void
 cpci_stop_thread(void)
 {
+       kthread_stop(cpci_thread);
        thread_finished = 1;
-       dbg("thread finish command given");
-       if (controller->irq)
-               up(&event_semaphore);
-       dbg("wait for thread to exit");
-       down(&thread_exit);
 }
 
 int
@@ -645,7 +621,7 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller)
                        status = -ENODEV;
                }
                dbg("%s - acquired controller irq %d",
-                   __FUNCTION__, new_controller->irq);
+                   __func__, new_controller->irq);
        }
        if (!status)
                controller = new_controller;
@@ -697,7 +673,7 @@ cpci_hp_start(void)
        static int first = 1;
        int status;
 
-       dbg("%s - enter", __FUNCTION__);
+       dbg("%s - enter", __func__);
        if (!controller)
                return -ENODEV;
 
@@ -717,14 +693,14 @@ cpci_hp_start(void)
        status = cpci_start_thread();
        if (status)
                return status;
-       dbg("%s - thread started", __FUNCTION__);
+       dbg("%s - thread started", __func__);
 
        if (controller->irq) {
                /* Start enum interrupt processing */
-               dbg("%s - enabling irq", __FUNCTION__);
+               dbg("%s - enabling irq", __func__);
                controller->ops->enable_irq();
        }
-       dbg("%s - exit", __FUNCTION__);
+       dbg("%s - exit", __func__);
        return 0;
 }
 
@@ -735,7 +711,7 @@ cpci_hp_stop(void)
                return -ENODEV;
        if (controller->irq) {
                /* Stop enum interrupt processing */
-               dbg("%s - disabling irq", __FUNCTION__);
+               dbg("%s - disabling irq", __func__);
                controller->ops->disable_irq();
        }
        cpci_stop_thread();