#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>"
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);
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);
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;
}
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;
/* This is the interrupt mode interrupt handler */
static irqreturn_t
-cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
+cpci_hp_intr(int irq, void *data)
{
dbg("entered cpci_hp_intr");
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;
}
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);
}
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))
}
}
up_read(&list_rwsem);
- dbg("%s - exit", __FUNCTION__);
+ dbg("%s - exit", __func__);
return 0;
}
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
/* 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");
/* 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)) {
{
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();
/* 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;
}
{
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 {
/* 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
status = -ENODEV;
}
dbg("%s - acquired controller irq %d",
- __FUNCTION__, new_controller->irq);
+ __func__, new_controller->irq);
}
if (!status)
controller = new_controller;
static int first = 1;
int status;
- dbg("%s - enter", __FUNCTION__);
+ dbg("%s - enter", __func__);
if (!controller)
return -ENODEV;
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;
}
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();