|
@@ -17,11 +17,10 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/gameport.h>
|
|
|
#include <linux/wait.h>
|
|
|
-#include <linux/completion.h>
|
|
|
#include <linux/sched.h>
|
|
|
-#include <linux/smp_lock.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/delay.h>
|
|
|
+#include <linux/kthread.h>
|
|
|
|
|
|
/*#include <asm/io.h>*/
|
|
|
|
|
@@ -238,8 +237,7 @@ struct gameport_event {
|
|
|
static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */
|
|
|
static LIST_HEAD(gameport_event_list);
|
|
|
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
|
|
|
-static DECLARE_COMPLETION(gameport_exited);
|
|
|
-static int gameport_pid;
|
|
|
+static struct task_struct *gameport_task;
|
|
|
|
|
|
static void gameport_queue_event(void *object, struct module *owner,
|
|
|
enum gameport_event_type event_type)
|
|
@@ -250,12 +248,12 @@ static void gameport_queue_event(void *object, struct module *owner,
|
|
|
spin_lock_irqsave(&gameport_event_lock, flags);
|
|
|
|
|
|
/*
|
|
|
- * Scan event list for the other events for the same gameport port,
|
|
|
+ * Scan event list for the other events for the same gameport port,
|
|
|
* starting with the most recent one. If event is the same we
|
|
|
* do not need add new one. If event is of different type we
|
|
|
* need to add this event and should not look further because
|
|
|
* we need to preseve sequence of distinct events.
|
|
|
- */
|
|
|
+ */
|
|
|
list_for_each_entry_reverse(event, &gameport_event_list, node) {
|
|
|
if (event->object == object) {
|
|
|
if (event->type == event_type)
|
|
@@ -432,20 +430,15 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
|
|
|
|
|
|
static int gameport_thread(void *nothing)
|
|
|
{
|
|
|
- lock_kernel();
|
|
|
- daemonize("kgameportd");
|
|
|
- allow_signal(SIGTERM);
|
|
|
-
|
|
|
do {
|
|
|
gameport_handle_events();
|
|
|
- wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
|
|
|
+ wait_event_interruptible(gameport_wait,
|
|
|
+ kthread_should_stop() || !list_empty(&gameport_event_list));
|
|
|
try_to_freeze(PF_FREEZE);
|
|
|
- } while (!signal_pending(current));
|
|
|
+ } while (!kthread_should_stop());
|
|
|
|
|
|
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
|
|
|
-
|
|
|
- unlock_kernel();
|
|
|
- complete_and_exit(&gameport_exited, 0);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -773,9 +766,10 @@ void gameport_close(struct gameport *gameport)
|
|
|
|
|
|
static int __init gameport_init(void)
|
|
|
{
|
|
|
- if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) {
|
|
|
+ gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
|
|
+ if (IS_ERR(gameport_task)) {
|
|
|
printk(KERN_ERR "gameport: Failed to start kgameportd\n");
|
|
|
- return -1;
|
|
|
+ return PTR_ERR(gameport_task);
|
|
|
}
|
|
|
|
|
|
gameport_bus.dev_attrs = gameport_device_attrs;
|
|
@@ -789,8 +783,7 @@ static int __init gameport_init(void)
|
|
|
static void __exit gameport_exit(void)
|
|
|
{
|
|
|
bus_unregister(&gameport_bus);
|
|
|
- kill_proc(gameport_pid, SIGTERM, 1);
|
|
|
- wait_for_completion(&gameport_exited);
|
|
|
+ kthread_stop(gameport_task);
|
|
|
}
|
|
|
|
|
|
module_init(gameport_init);
|