Commit eed7cf45 authored by Vojtech Pavlik's avatar Vojtech Pavlik

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

parent 39606a95
......@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/suspend.h>
#include <linux/slab.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
......@@ -51,19 +52,27 @@ EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close);
EXPORT_SYMBOL(serio_rescan);
static struct serio *serio_list;
static struct serio_dev *serio_dev;
struct serio_event {
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 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)
dev->connect(serio, dev);
dev = dev->next;
}
dev->connect(serio, dev);
}
}
#define SERIO_RESCAN 1
......@@ -73,17 +82,23 @@ static DECLARE_COMPLETION(serio_exited);
void serio_handle_events(void)
{
struct serio *serio = serio_list;
while (serio) {
if (serio->event & SERIO_RESCAN) {
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
serio_find_dev(serio);
struct list_head *node, *next;
struct serio_event *event;
list_for_each_safe(node, next, &serio_event_list) {
event = container_of(node, struct serio_event, node);
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;
}
serio->event = 0;
serio = serio->next;
list_del_init(node);
kfree(event);
}
}
......@@ -95,7 +110,7 @@ static int serio_thread(void *nothing)
do {
serio_handle_events();
interruptible_sleep_on(&serio_wait);
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD);
} while (!signal_pending(current));
......@@ -108,7 +123,15 @@ static int serio_thread(void *nothing)
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);
}
......@@ -122,49 +145,36 @@ void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags
void serio_register_port(struct serio *serio)
{
serio->next = serio_list;
serio_list = serio;
list_add_tail(&serio->node, &serio_list);
serio_find_dev(serio);
}
void serio_unregister_port(struct serio *serio)
{
struct serio **serioptr = &serio_list;
while (*serioptr && (*serioptr != serio)) serioptr = &((*serioptr)->next);
*serioptr = (*serioptr)->next;
list_del_init(&serio->node);
if (serio->dev && serio->dev->disconnect)
serio->dev->disconnect(serio);
}
void serio_register_device(struct serio_dev *dev)
{
struct serio *serio = serio_list;
dev->next = serio_dev;
serio_dev = dev;
while (serio) {
struct serio *serio;
list_add_tail(&dev->node, &serio_dev_list);
list_for_each_entry(serio, &serio_list, node)
if (!serio->dev && dev->connect)
dev->connect(serio, dev);
serio = serio->next;
}
}
void serio_unregister_device(struct serio_dev *dev)
{
struct serio_dev **devptr = &serio_dev;
struct serio *serio = serio_list;
struct serio *serio;
while (*devptr && (*devptr != dev)) devptr = &((*devptr)->next);
*devptr = (*devptr)->next;
list_del_init(&dev->node);
while (serio) {
list_for_each_entry(serio, &serio_list, node) {
if (serio->dev == dev && dev->disconnect)
dev->disconnect(serio);
serio_find_dev(serio);
serio = serio->next;
}
}
......
......@@ -2,36 +2,16 @@
#define _SERIO_H
/*
* $Id: serio.h,v 1.21 2001/12/19 05:15:21 skids Exp $
*
* 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 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.
* Copyright (C) 1999-2002 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.
*/
#include <linux/ioctl.h>
#include <linux/list.h>
#define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
struct serio;
......@@ -57,7 +37,8 @@ struct serio {
void (*close)(struct serio *);
struct serio_dev *dev;
struct serio *next;
struct list_head node;
};
struct serio_dev {
......@@ -71,7 +52,7 @@ struct serio_dev {
void (*disconnect)(struct serio *);
void (*cleanup)(struct serio *);
struct serio_dev *next;
struct list_head node;
};
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