Commit eed7cf45 authored by Vojtech Pavlik's avatar Vojtech Pavlik

Convert serio.[ch] to use list.h lists.

parent 39606a95
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/slab.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core"); MODULE_DESCRIPTION("Serio abstraction core");
...@@ -51,19 +52,27 @@ EXPORT_SYMBOL(serio_open); ...@@ -51,19 +52,27 @@ EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close); EXPORT_SYMBOL(serio_close);
EXPORT_SYMBOL(serio_rescan); EXPORT_SYMBOL(serio_rescan);
static struct serio *serio_list; struct serio_event {
static struct serio_dev *serio_dev; int type;
struct serio *serio;
struct list_head node;
};
static LIST_HEAD(serio_list);
static LIST_HEAD(serio_dev_list);
static LIST_HEAD(serio_event_list);
static int serio_pid; static int serio_pid;
static void serio_find_dev(struct serio *serio) static void serio_find_dev(struct serio *serio)
{ {
struct serio_dev *dev = serio_dev; struct serio_dev *dev;
while (dev && !serio->dev) { list_for_each_entry(dev, &serio_dev_list, node) {
if (serio->dev)
break;
if (dev->connect) if (dev->connect)
dev->connect(serio, dev); dev->connect(serio, dev);
dev = dev->next; }
}
} }
#define SERIO_RESCAN 1 #define SERIO_RESCAN 1
...@@ -73,17 +82,23 @@ static DECLARE_COMPLETION(serio_exited); ...@@ -73,17 +82,23 @@ static DECLARE_COMPLETION(serio_exited);
void serio_handle_events(void) void serio_handle_events(void)
{ {
struct serio *serio = serio_list; struct list_head *node, *next;
struct serio_event *event;
while (serio) {
if (serio->event & SERIO_RESCAN) { list_for_each_safe(node, next, &serio_event_list) {
if (serio->dev && serio->dev->disconnect) event = container_of(node, struct serio_event, node);
serio->dev->disconnect(serio);
serio_find_dev(serio); switch (event->type) {
case SERIO_RESCAN :
if (event->serio->dev && event->serio->dev->disconnect)
event->serio->dev->disconnect(event->serio);
serio_find_dev(event->serio);
break;
default:
break;
} }
list_del_init(node);
serio->event = 0; kfree(event);
serio = serio->next;
} }
} }
...@@ -95,7 +110,7 @@ static int serio_thread(void *nothing) ...@@ -95,7 +110,7 @@ static int serio_thread(void *nothing)
do { do {
serio_handle_events(); serio_handle_events();
interruptible_sleep_on(&serio_wait); wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
if (current->flags & PF_FREEZE) if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD); refrigerator(PF_IOTHREAD);
} while (!signal_pending(current)); } while (!signal_pending(current));
...@@ -108,7 +123,15 @@ static int serio_thread(void *nothing) ...@@ -108,7 +123,15 @@ static int serio_thread(void *nothing)
void serio_rescan(struct serio *serio) void serio_rescan(struct serio *serio)
{ {
serio->event |= SERIO_RESCAN; struct serio_event *event;
if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC)))
return;
event->type = SERIO_RESCAN;
event->serio = serio;
list_add_tail(&event->node, &serio_event_list);
wake_up(&serio_wait); wake_up(&serio_wait);
} }
...@@ -122,49 +145,36 @@ void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags ...@@ -122,49 +145,36 @@ void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags
void serio_register_port(struct serio *serio) void serio_register_port(struct serio *serio)
{ {
serio->next = serio_list; list_add_tail(&serio->node, &serio_list);
serio_list = serio;
serio_find_dev(serio); serio_find_dev(serio);
} }
void serio_unregister_port(struct serio *serio) void serio_unregister_port(struct serio *serio)
{ {
struct serio **serioptr = &serio_list; list_del_init(&serio->node);
while (*serioptr && (*serioptr != serio)) serioptr = &((*serioptr)->next);
*serioptr = (*serioptr)->next;
if (serio->dev && serio->dev->disconnect) if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio); serio->dev->disconnect(serio);
} }
void serio_register_device(struct serio_dev *dev) void serio_register_device(struct serio_dev *dev)
{ {
struct serio *serio = serio_list; struct serio *serio;
list_add_tail(&dev->node, &serio_dev_list);
dev->next = serio_dev; list_for_each_entry(serio, &serio_list, node)
serio_dev = dev;
while (serio) {
if (!serio->dev && dev->connect) if (!serio->dev && dev->connect)
dev->connect(serio, dev); dev->connect(serio, dev);
serio = serio->next;
}
} }
void serio_unregister_device(struct serio_dev *dev) void serio_unregister_device(struct serio_dev *dev)
{ {
struct serio_dev **devptr = &serio_dev; struct serio *serio;
struct serio *serio = serio_list;
while (*devptr && (*devptr != dev)) devptr = &((*devptr)->next); list_del_init(&dev->node);
*devptr = (*devptr)->next;
while (serio) { list_for_each_entry(serio, &serio_list, node) {
if (serio->dev == dev && dev->disconnect) if (serio->dev == dev && dev->disconnect)
dev->disconnect(serio); dev->disconnect(serio);
serio_find_dev(serio); serio_find_dev(serio);
serio = serio->next;
} }
} }
......
...@@ -2,36 +2,16 @@ ...@@ -2,36 +2,16 @@
#define _SERIO_H #define _SERIO_H
/* /*
* $Id: serio.h,v 1.21 2001/12/19 05:15:21 skids Exp $ * Copyright (C) 1999-2002 Vojtech Pavlik
* *
* Copyright (C) 1999-2001 Vojtech Pavlik * This program is free software; you can redistribute it and/or modify it
*/ * under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
/*
* The serial port set type ioctl.
*/ */
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/list.h>
#define SPIOCSTYPE _IOW('q', 0x01, unsigned long) #define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
struct serio; struct serio;
...@@ -57,7 +37,8 @@ struct serio { ...@@ -57,7 +37,8 @@ struct serio {
void (*close)(struct serio *); void (*close)(struct serio *);
struct serio_dev *dev; struct serio_dev *dev;
struct serio *next;
struct list_head node;
}; };
struct serio_dev { struct serio_dev {
...@@ -71,7 +52,7 @@ struct serio_dev { ...@@ -71,7 +52,7 @@ struct serio_dev {
void (*disconnect)(struct serio *); void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *); void (*cleanup)(struct serio *);
struct serio_dev *next; struct list_head node;
}; };
int serio_open(struct serio *serio, struct serio_dev *dev); int serio_open(struct serio *serio, struct serio_dev *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment