All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/16] New set of input patches
@ 2004-12-29  7:17 Dmitry Torokhov
  2004-12-29  7:19 ` [PATCH 1/16] i8042 panicblink cleanup Dmitry Torokhov
  2005-01-13 15:36 ` [PATCH 0/16] New set of input patches Vojtech Pavlik
  0 siblings, 2 replies; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:17 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

Hi Vojtech,

Please take a look at the following input patches. Patches 1-9 are already
in my tree (and were there for quite some time so they should have gotten
at least some testing as Andrew automatically pulls from me) and I'd like
see them pushed to Linus together with your last batch. At least patches
6, 8 and 9 fix bugs introduced by latest changes. Patch 7 should help owners
of Toshibas with Synaptics touchpads.

01-i8042-panicblink-cleanup.patch
	Move panicblink parameter definition together with the rest of i8042
	module parameters, add description and entry in kernel-parameters.txt

02-serio-start-stop.patch
	Add serio start() and stop() methods to serio structure that are
	called when serio port is about to be fully registered and when
	serio port is about to be unregistered. These methods are useful
	for drivers that share interrupt among several serio ports. In this
	case interrupt can not be enabled/disabled in open/close methods
	and it is very hard to determine if interrupt shoudl be ignored or
	passed on.

03-i8042-use-start-stop.patch
	Make use of new serio start/stop methods to safely activate and
	deactivate ports. Also unify as much as possible port handling
	between KBD, AUX and MUX ports. Rename i8042_values into i8042_port.

04-serio-suppress-dup-events.patch
	Do not submit serio event into event queue if there is already one
	of the same type for the same port in front of it. Also look for
	duplicat events once event is processed. This should help with
	disconnected ports generating alot of data and consuming memory for
	events when kseriod gets behind and prevents constant rescans.
	This also allows to remove special check for 0xaa in reconnect path
	of interrupt handler known to cause problems with Toshibas keyboards.

05-evdev-buffer-size.patch
	Return -EINVAL from evdev_read when passed buffer is too small.
	Based on patch by James Lamanna.

06-ps2pp-mouse-name.patch
	Set mouse name to "Mouse" instead of leaving it NULL when using
	PS2++ protocol and don't have any other information (Wheel, Touchpad)
	about the mouse.

07-synaptics-toshiba-rate.patch
	Toshiba Satellite KBCs have trouble handling data stream coming from
	Synaptics at full rate (80 pps, 480 byte/sec) which causes keyboards
	to pause or even get stuck. Use DMI to detect Satellites and limit
	rate to 40 pps which cures keyboard.

08-atkbd-keycode-size.patch
	Fix keycode table size initialization that got broken by my changes
	that exported 'set' and other settings via sysfs.
	setkeycodes should work again now.

09-i8042-sysfs-permissions.patch
	Fix braindamage in sysfs permissions for 'debug' option.

10-twidjoy-build.patch
	Make Kconfig and Makefile agree on the option name so twidjoy
	can be built.

11-input-msecs-to-jiffies.patch
	Use msecs_to_jiffies instead of homegrown ms_to_jiffies
	so everything works when HZ != 1000

12-atkbd-msecs-to-jiffies.patch
	Use msecs_to_jiffies instead of manually calculating
	delay for Toshiba bouncing keys workaround so it works
        when HZ != 1000.

13-serio-drvdata.patch
	Remove serio->private in favor of using driver-specific data
	in device structure, add serio_get_drvdata/serio_put_drvdata
	to access it so serio bus code looks more like other buses.

14-serio-id-match.patch
	Replace serio's type field with serio_id structure and
	add ids table to serio drivers. This will allow splitting
	initial matching and probing routines for better sysfs
	integration.

15-serio-bus-cleanup.patch
	Make serio implementation more in line with standard
	driver model implementations by removing explicit device
	and driver list manipulations and introducing bus_match
	function. serio_register_port is always asynchronous to
	allow freely registering child ports. When deregistering
	serio core still takes care of destroying children ports
	first.

16-serio-connect-errcode.patch
	Make serios' connect methods return error code instead of
        void so exact cause of failur can be comminicated upstream. 

Let me know which ones will you take and I will push them to my tree as
well.

Thanks!

-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/16] i8042 panicblink cleanup
  2004-12-29  7:17 [PATCH 0/16] New set of input patches Dmitry Torokhov
@ 2004-12-29  7:19 ` Dmitry Torokhov
  2004-12-29  7:20   ` [PATCH 2/16] Add serio start and stop methods Dmitry Torokhov
  2005-01-13 15:36 ` [PATCH 0/16] New set of input patches Vojtech Pavlik
  1 sibling, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:19 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.28, 2004-11-12 01:23:12-05:00, dtor_core@ameritech.net
  Input: i8042 - move panicblink with the rest of module paremeters,
         add proper entry to kernel-parameters.txt
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 Documentation/kernel-parameters.txt |    3 +++
 drivers/input/serio/i8042.c         |   35 ++++++++++++++++++++++-------------
 2 files changed, 25 insertions(+), 13 deletions(-)


===================================================================



diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	2004-12-29 01:46:13 -05:00
+++ b/Documentation/kernel-parameters.txt	2004-12-29 01:46:13 -05:00
@@ -486,6 +486,9 @@
 	i8042.noaux	[HW] Don't check for auxiliary (== mouse) port
 	i8042.nomux	[HW] Don't check presence of an active multiplexing
 			     controller
+	i8042.panicblink=
+			[HW] Frequency with which keyboard LEDs should blink
+			     when kernel panics (default is 0.5 sec)
 	i8042.reset	[HW] Reset the controller during init and cleanup
 	i8042.unlock	[HW] Unlock (ignore) the keylock
 
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2004-12-29 01:46:13 -05:00
+++ b/drivers/input/serio/i8042.c	2004-12-29 01:46:13 -05:00
@@ -54,6 +54,10 @@
 module_param_named(noloop, i8042_noloop, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Disable the AUX Loopback command while probing for the AUX port");
 
+static unsigned int i8042_blink_frequency = 500;
+module_param_named(panicblink, i8042_blink_frequency, uint, 0600);
+MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics");
+
 #ifdef CONFIG_ACPI
 static int i8042_noacpi;
 module_param_named(noacpi, i8042_noacpi, bool, 0);
@@ -821,25 +825,29 @@
 }
 
 
-static int blink_frequency = 500;
-module_param_named(panicblink, blink_frequency, int, 0600);
-
-/* Catch the case when the kbd interrupt is off */
-#define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0)
-
-/* Tell the user who may be running in X and not see the console that we have
-   panic'ed. This is to distingush panics from "real" lockups.  */
+/*
+ * i8042_panic_blink() will flash the keyboard LEDs and is called when
+ * kernel panics. Flashing LEDs is useful for users running X who may
+ * not see the console and will help distingushing panics from "real"
+ * lockups.
+ */
 static long i8042_panic_blink(long count)
 {
 	long delay = 0;
 	static long last_blink;
 	static char led;
-	/* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is
-	   different. */
-	if (!blink_frequency)
+
+	/*
+	 * We expect frequency to be about 1/2s. KDB uses about 1s.
+	 * Make sure they are different.
+	 */
+	if (!i8042_blink_frequency)
 		return 0;
-	if (count - last_blink < blink_frequency)
+	if (count - last_blink < i8042_blink_frequency)
 		return 0;
+
+	/* Ensures that we will not get stuck here if kbd interrupt is off */
+#define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0)
 	led ^= 0x01 | 0x04;
 	while (i8042_read_status() & I8042_STR_IBF)
 		DELAY;
@@ -850,11 +858,12 @@
 	DELAY;
 	i8042_write_data(led);
 	DELAY;
+#undef DELAY
+
 	last_blink = count;
 	return delay;
 }
 
-#undef DELAY
 
 /*
  * Here we try to restore the original BIOS settings

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 2/16] Add serio start and stop methods
  2004-12-29  7:19 ` [PATCH 1/16] i8042 panicblink cleanup Dmitry Torokhov
@ 2004-12-29  7:20   ` Dmitry Torokhov
  2004-12-29  7:20     ` [PATCH 3/16] i8042: Make use of new " Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:20 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.29, 2004-11-12 01:25:01-05:00, dtor_core@ameritech.net
  Input: add serio->start() and serio->stop() callback methods that
         are called whenever serio port is finishes being registered
         or unregistered. The callbacks are useful for drivers that
         share interrupt between several ports and there is a danger
         that interrupt handler will reference port that was just
         unregistered.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/serio/serio.c |    8 +++++++-
 include/linux/serio.h       |    2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-12-29 01:46:30 -05:00
+++ b/drivers/input/serio/serio.c	2004-12-29 01:46:30 -05:00
@@ -328,7 +328,10 @@
 	serio->dev.release = serio_release_port;
 	if (serio->parent)
 		serio->dev.parent = &serio->parent->dev;
-	device_register(&serio->dev);
+	device_initialize(&serio->dev);
+	if (serio->start)
+		serio->start(serio);
+	device_add(&serio->dev);
 }
 
 /*
@@ -350,6 +353,9 @@
 		up_write(&serio_bus.subsys.rwsem);
 		put_driver(&drv->driver);
 	}
+
+	if (serio->stop)
+		serio->stop(serio);
 
 	if (serio->parent) {
 		spin_lock_irqsave(&serio->parent->lock, flags);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-12-29 01:46:30 -05:00
+++ b/include/linux/serio.h	2004-12-29 01:46:30 -05:00
@@ -42,6 +42,8 @@
 	int (*write)(struct serio *, unsigned char);
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
+	int (*start)(struct serio *);
+	void (*stop)(struct serio *);
 
 	struct serio *parent, *child;
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3/16] i8042: Make use of new serio start and stop methods
  2004-12-29  7:20   ` [PATCH 2/16] Add serio start and stop methods Dmitry Torokhov
@ 2004-12-29  7:20     ` Dmitry Torokhov
  2004-12-29  7:21       ` [PATCH 4/16] Suppress duplicate events in serio core Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:20 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.30, 2004-11-12 01:26:42-05:00, dtor_core@ameritech.net
  Input: i8042 - make use of new serio start() and stop() callbacks
         to ensure that i8042 interrupt handler that is shared among
         several ports does not reference deleted ports. Also rename
         i8042_valies structure to i8042_port, consolidate handling
         of KBD, AUX and MUX ports, rearrange interrupt handler code.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 i8042.c |  319 ++++++++++++++++++++++++++++++++--------------------------------
 i8042.h |    6 -
 2 files changed, 165 insertions(+), 160 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2004-12-29 01:46:50 -05:00
+++ b/drivers/input/serio/i8042.c	2004-12-29 01:46:50 -05:00
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/serio.h>
 #include <linux/err.h>
+#include <linux/rcupdate.h>
 
 #include <asm/io.h>
 
@@ -82,7 +83,8 @@
 
 spinlock_t i8042_lock = SPIN_LOCK_UNLOCKED;
 
-struct i8042_values {
+struct i8042_port {
+	struct serio *serio;
 	int irq;
 	unsigned char disable;
 	unsigned char irqen;
@@ -91,25 +93,25 @@
 	char name[8];
 };
 
-static struct i8042_values i8042_kbd_values = {
-	.disable	= I8042_CTR_KBDDIS,
-	.irqen 		= I8042_CTR_KBDINT,
-	.mux		= -1,
-	.name		= "KBD",
-};
-
-static struct i8042_values i8042_aux_values = {
-	.disable	= I8042_CTR_AUXDIS,
-	.irqen		= I8042_CTR_AUXINT,
-	.mux		= -1,
-	.name		= "AUX",
+#define I8042_KBD_PORT_NO	0
+#define I8042_AUX_PORT_NO	1
+#define I8042_MUX_PORT_NO	2
+#define I8042_NUM_PORTS		(I8042_NUM_MUX_PORTS + 2)
+static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
+	{
+		.disable	= I8042_CTR_KBDDIS,
+		.irqen 		= I8042_CTR_KBDINT,
+		.mux		= -1,
+		.name		= "KBD",
+	},
+	{
+		.disable	= I8042_CTR_AUXDIS,
+		.irqen		= I8042_CTR_AUXINT,
+		.mux		= -1,
+		.name		= "AUX",
+	}
 };
 
-static struct i8042_values i8042_mux_values[I8042_NUM_MUX_PORTS];
-
-static struct serio *i8042_kbd_port;
-static struct serio *i8042_aux_port;
-static struct serio *i8042_mux_port[I8042_NUM_MUX_PORTS];
 static unsigned char i8042_initial_ctr;
 static unsigned char i8042_ctr;
 static unsigned char i8042_mux_open;
@@ -117,6 +119,7 @@
 static struct timer_list i8042_timer;
 static struct platform_device *i8042_platform_device;
 
+
 /*
  * Shared IRQ's require a device pointer, but this driver doesn't support
  * multiple devices
@@ -250,19 +253,19 @@
  * i8042_aux_write() sends a byte out through the aux interface.
  */
 
-static int i8042_aux_write(struct serio *port, unsigned char c)
+static int i8042_aux_write(struct serio *serio, unsigned char c)
 {
-	struct i8042_values *values = port->port_data;
+	struct i8042_port *port = serio->port_data;
 	int retval;
 
 /*
  * Send the byte out.
  */
 
-	if (values->mux == -1)
+	if (port->mux == -1)
 		retval = i8042_command(&c, I8042_CMD_AUX_SEND);
 	else
-		retval = i8042_command(&c, I8042_CMD_MUX_SEND + values->mux);
+		retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux);
 
 /*
  * Make sure the interrupt happens and the character is received even
@@ -278,9 +281,10 @@
  * i8042_activate_port() enables port on a chip.
  */
 
-static int i8042_activate_port(struct serio *port)
+static int i8042_activate_port(struct i8042_port *port)
 {
-	struct i8042_values *values = port->port_data;
+	if (!port->serio)
+		return -1;
 
 	i8042_flush();
 
@@ -288,12 +292,12 @@
 	 * Enable port again here because it is disabled if we are
 	 * resuming (normally it is enabled already).
 	 */
-	i8042_ctr &= ~values->disable;
+	i8042_ctr &= ~port->disable;
 
-	i8042_ctr |= values->irqen;
+	i8042_ctr |= port->irqen;
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		i8042_ctr &= ~values->irqen;
+		i8042_ctr &= ~port->irqen;
 		return -1;
 	}
 
@@ -306,22 +310,22 @@
  * It allocates the interrupt and calls i8042_enable_port.
  */
 
-static int i8042_open(struct serio *port)
+static int i8042_open(struct serio *serio)
 {
-	struct i8042_values *values = port->port_data;
+	struct i8042_port *port = serio->port_data;
 
-	if (values->mux != -1)
+	if (port->mux != -1)
 		if (i8042_mux_open++)
 			return 0;
 
-	if (request_irq(values->irq, i8042_interrupt,
+	if (request_irq(port->irq, i8042_interrupt,
 			SA_SHIRQ, "i8042", i8042_request_irq_cookie)) {
-		printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", values->irq, values->name);
+		printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", port->irq, port->name);
 		goto irq_fail;
 	}
 
 	if (i8042_activate_port(port)) {
-		printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", values->name);
+		printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", port->name);
 		goto activate_fail;
 	}
 
@@ -330,11 +334,10 @@
 	return 0;
 
 activate_fail:
-	free_irq(values->irq, i8042_request_irq_cookie);
+	free_irq(port->irq, i8042_request_irq_cookie);
 
 irq_fail:
-	values->exists = 0;
-	serio_unregister_port_delayed(port);
+	serio_unregister_port_delayed(serio);
 
 	return -1;
 }
@@ -345,27 +348,58 @@
  * the BIOS could have used the AUX interrupt for PCI.
  */
 
-static void i8042_close(struct serio *port)
+static void i8042_close(struct serio *serio)
 {
-	struct i8042_values *values = port->port_data;
+	struct i8042_port *port = serio->port_data;
 
-	if (values->mux != -1)
+	if (port->mux != -1)
 		if (--i8042_mux_open)
 			return;
 
-	i8042_ctr &= ~values->irqen;
+	i8042_ctr &= ~port->irqen;
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		printk(KERN_ERR "i8042.c: Can't write CTR while closing %s.\n", values->name);
-		return;
+		printk(KERN_WARNING "i8042.c: Can't write CTR while closing %s.\n", port->name);
+/*
+ * We still want to continue and free IRQ so if more data keeps coming in
+ * kernel will just ignore the irq.
+ */
 	}
 
-	free_irq(values->irq, i8042_request_irq_cookie);
+	free_irq(port->irq, i8042_request_irq_cookie);
 
 	i8042_flush();
 }
 
 /*
+ * i8042_start() is called by serio core when port is about to finish
+ * registering. It will mark port as existing so i8042_interrupt can
+ * start sending data through it.
+ */
+static int i8042_start(struct serio *serio)
+{
+	struct i8042_port *port = serio->port_data;
+
+	port->exists = 1;
+	mb();
+	return 0;
+}
+
+/*
+ * i8042_stop() marks serio port as non-existing so i8042_interrupt
+ * will not try to send data to the port that is about to go away.
+ * The function is called by serio core as part of unregister procedure.
+ */
+static void i8042_stop(struct serio *serio)
+{
+	struct i8042_port *port = serio->port_data;
+
+	port->exists = 0;
+	synchronize_kernel();
+	port->serio = NULL;
+}
+
+/*
  * i8042_interrupt() is the most important function in this driver -
  * it handles the interrupts from the i8042, and sends incoming bytes
  * to the upper layers.
@@ -373,25 +407,25 @@
 
 static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	struct i8042_port *port;
 	unsigned long flags;
-	unsigned char str, data = 0;
+	unsigned char str, data;
 	unsigned int dfl;
-	unsigned int aux_idx;
+	unsigned int port_no;
 	int ret;
 
 	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 
 	spin_lock_irqsave(&i8042_lock, flags);
 	str = i8042_read_status();
-	if (str & I8042_STR_OBF)
-		data = i8042_read_data();
-	spin_unlock_irqrestore(&i8042_lock, flags);
-
-	if (~str & I8042_STR_OBF) {
+	if (unlikely(~str & I8042_STR_OBF)) {
+		spin_unlock_irqrestore(&i8042_lock, flags);
 		if (irq) dbg("Interrupt %d, without any data", irq);
 		ret = 0;
 		goto out;
 	}
+	data = i8042_read_data();
+	spin_unlock_irqrestore(&i8042_lock, flags);
 
 	if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
 		static unsigned long last_transmit;
@@ -423,39 +457,28 @@
 			}
 		}
 
-		aux_idx = (str >> 6) & 3;
-
-		dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
-			data, aux_idx, irq,
-			dfl & SERIO_PARITY ? ", bad parity" : "",
-			dfl & SERIO_TIMEOUT ? ", timeout" : "");
-
-		if (likely(i8042_mux_values[aux_idx].exists))
-			serio_interrupt(i8042_mux_port[aux_idx], data, dfl, regs);
-
+		port_no = I8042_MUX_PORT_NO + ((str >> 6) & 3);
 		last_str = str;
 		last_transmit = jiffies;
-		goto irq_ret;
+	} else {
+
+		dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
+		      ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
+
+		port_no = (str & I8042_STR_AUXDATA) ?
+				I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
 	}
 
-	dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
-	      ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
+	port = &i8042_ports[port_no];
 
 	dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-		data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
-		dfl & SERIO_PARITY ? ", bad parity" : "",
-		dfl & SERIO_TIMEOUT ? ", timeout" : "");
+	    data, port->name, irq,
+	    dfl & SERIO_PARITY ? ", bad parity" : "",
+	    dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
+	if (likely(port->exists))
+		serio_interrupt(port->serio, data, dfl, regs);
 
-	if (str & I8042_STR_AUXDATA) {
-		if (likely(i8042_aux_values.exists))
-			serio_interrupt(i8042_aux_port, data, dfl, regs);
-	} else {
-		if (likely(i8042_kbd_values.exists))
-			serio_interrupt(i8042_kbd_port, data, dfl, regs);
-	}
-
-irq_ret:
 	ret = 1;
 out:
 	return IRQ_RETVAL(ret);
@@ -467,7 +490,7 @@
  * Legacy) mode.
  */
 
-static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux_version)
+static int i8042_enable_mux_mode(unsigned char *mux_version)
 {
 
 	unsigned char param;
@@ -505,7 +528,7 @@
  * the controller has been switched into Multiplexed mode
  */
 
-static int i8042_enable_mux_ports(struct i8042_values *values)
+static int i8042_enable_mux_ports(void)
 {
 	unsigned char param;
 	int i;
@@ -540,11 +563,11 @@
  * LCS/Telegraphics.
  */
 
-static int __init i8042_check_mux(struct i8042_values *values)
+static int __init i8042_check_mux(void)
 {
 	unsigned char mux_version;
 
-	if (i8042_enable_mux_mode(values, &mux_version))
+	if (i8042_enable_mux_mode(&mux_version))
 		return -1;
 
 	/* Workaround for broken chips which seem to support MUX, but in reality don't. */
@@ -555,7 +578,7 @@
 	printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
 		(mux_version >> 4) & 0xf, mux_version & 0xf);
 
-	if (i8042_enable_mux_ports(values))
+	if (i8042_enable_mux_ports())
 		return -1;
 
 	i8042_mux_present = 1;
@@ -568,7 +591,7 @@
  * the presence of an AUX interface.
  */
 
-static int __init i8042_check_aux(struct i8042_values *values)
+static int __init i8042_check_aux(void)
 {
 	unsigned char param;
 	static int i8042_check_aux_cookie;
@@ -578,10 +601,10 @@
  * in trying to detect AUX presence.
  */
 
-	if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ,
-				"i8042", &i8042_check_aux_cookie))
+	if (request_irq(i8042_ports[I8042_AUX_PORT_NO].irq, i8042_interrupt,
+			SA_SHIRQ, "i8042", &i8042_check_aux_cookie))
                 return -1;
-	free_irq(values->irq, &i8042_check_aux_cookie);
+	free_irq(i8042_ports[I8042_AUX_PORT_NO].irq, &i8042_check_aux_cookie);
 
 /*
  * Get rid of bytes in the queue.
@@ -646,27 +669,25 @@
  * registers it, and reports to the user.
  */
 
-static int __init i8042_port_register(struct serio *port)
+static int __init i8042_port_register(struct i8042_port *port)
 {
-	struct i8042_values *values = port->port_data;
-
-	values->exists = 1;
-
-	i8042_ctr &= ~values->disable;
+	i8042_ctr &= ~port->disable;
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
 		printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
-		values->exists = 0;
+		kfree(port->serio);
+		port->serio = NULL;
+		i8042_ctr |= port->disable;
 		return -1;
 	}
 
 	printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
-	       values->name,
+	       port->name,
 	       (unsigned long) I8042_DATA_REG,
 	       (unsigned long) I8042_COMMAND_REG,
-	       values->irq);
+	       port->irq);
 
-	serio_register_port(port);
+	serio_register_port(port->serio);
 
 	return 0;
 }
@@ -811,15 +832,9 @@
  * Reset anything that is connected to the ports.
  */
 
-	if (i8042_kbd_values.exists)
-		serio_cleanup(i8042_kbd_port);
-
-	if (i8042_aux_values.exists)
-		serio_cleanup(i8042_aux_port);
-
-	for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
-		if (i8042_mux_values[i].exists)
-			serio_cleanup(i8042_mux_port[i]);
+	for (i = 0; i < I8042_NUM_PORTS; i++)
+		if (i8042_ports[i].exists)
+			serio_cleanup(i8042_ports[i].serio);
 
 	i8042_controller_reset();
 }
@@ -897,8 +912,7 @@
 	}
 
 	if (i8042_mux_present)
-		if (i8042_enable_mux_mode(&i8042_aux_values, NULL) ||
-		    i8042_enable_mux_ports(&i8042_aux_values)) {
+		if (i8042_enable_mux_mode(NULL) || i8042_enable_mux_ports()) {
 			printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't work.\n");
 		}
 
@@ -906,15 +920,9 @@
  * Reconnect anything that was connected to the ports.
  */
 
-	if (i8042_kbd_values.exists && i8042_activate_port(i8042_kbd_port) == 0)
-		serio_reconnect(i8042_kbd_port);
-
-	if (i8042_aux_values.exists && i8042_activate_port(i8042_aux_port) == 0)
-		serio_reconnect(i8042_aux_port);
-
-	for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
-		if (i8042_mux_values[i].exists && i8042_activate_port(i8042_mux_port[i]) == 0)
-			serio_reconnect(i8042_mux_port[i]);
+	for (i = 0; i < I8042_NUM_PORTS; i++)
+		if (i8042_activate_port(&i8042_ports[i]) == 0)
+			serio_reconnect(i8042_ports[i].serio);
 /*
  * Restart timer (for polling "stuck" data)
  */
@@ -944,9 +952,10 @@
 	.shutdown	= i8042_shutdown,
 };
 
-static struct serio * __init i8042_allocate_kbd_port(void)
+static void __init i8042_create_kbd_port(void)
 {
 	struct serio *serio;
+	struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
 
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
@@ -955,18 +964,22 @@
 		serio->write		= i8042_dumbkbd ? NULL : i8042_kbd_write,
 		serio->open		= i8042_open,
 		serio->close		= i8042_close,
-		serio->port_data	= &i8042_kbd_values,
+		serio->start		= i8042_start,
+		serio->stop		= i8042_stop,
+		serio->port_data	= port,
 		serio->dev.parent	= &i8042_platform_device->dev;
 		strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
 		strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
-	}
 
-	return serio;
+		port->serio = serio;
+		i8042_port_register(port);
+	}
 }
 
-static struct serio * __init i8042_allocate_aux_port(void)
+static void __init i8042_create_aux_port(void)
 {
 	struct serio *serio;
+	struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
 
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
@@ -975,38 +988,44 @@
 		serio->write		= i8042_aux_write;
 		serio->open		= i8042_open;
 		serio->close		= i8042_close;
-		serio->port_data	= &i8042_aux_values,
+		serio->start		= i8042_start,
+		serio->stop		= i8042_stop,
+		serio->port_data	= port,
 		serio->dev.parent	= &i8042_platform_device->dev;
 		strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
 		strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
-	}
 
-	return serio;
+		port->serio = serio;
+		i8042_port_register(port);
+	}
 }
 
-static struct serio * __init i8042_allocate_mux_port(int index)
+static void __init i8042_create_mux_port(int index)
 {
 	struct serio *serio;
-	struct i8042_values *values = &i8042_mux_values[index];
+	struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
 
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
-		*values = i8042_aux_values;
-		snprintf(values->name, sizeof(values->name), "AUX%d", index);
-		values->mux = index;
-
 		memset(serio, 0, sizeof(struct serio));
 		serio->type		= SERIO_8042;
 		serio->write		= i8042_aux_write;
 		serio->open		= i8042_open;
 		serio->close		= i8042_close;
-		serio->port_data	= values;
+		serio->start		= i8042_start,
+		serio->stop		= i8042_stop,
+		serio->port_data	= port;
 		serio->dev.parent	= &i8042_platform_device->dev;
 		snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
 		snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
-	}
 
-	return serio;
+		*port = i8042_ports[I8042_AUX_PORT_NO];
+		port->exists = 0;
+		snprintf(port->name, sizeof(port->name), "AUX%d", index);
+		port->mux = index;
+		port->serio = serio;
+		i8042_port_register(port);
+	}
 }
 
 int __init i8042_init(void)
@@ -1022,8 +1041,8 @@
 	if (i8042_platform_init())
 		return -EBUSY;
 
-	i8042_aux_values.irq = I8042_AUX_IRQ;
-	i8042_kbd_values.irq = I8042_KBD_IRQ;
+	i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
+	i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
 
 	if (i8042_controller_init())
 		return -ENODEV;
@@ -1038,23 +1057,15 @@
 		return PTR_ERR(i8042_platform_device);
 	}
 
-	if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
-		if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))
-			for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
-				i8042_mux_port[i] = i8042_allocate_mux_port(i);
-				if (i8042_mux_port[i])
-					i8042_port_register(i8042_mux_port[i]);
-			}
-		else {
-			i8042_aux_port = i8042_allocate_aux_port();
-			if (i8042_aux_port)
-				i8042_port_register(i8042_aux_port);
-		}
+	if (!i8042_noaux && !i8042_check_aux()) {
+		if (!i8042_nomux && !i8042_check_mux())
+			for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
+				i8042_create_mux_port(i);
+		else
+			i8042_create_aux_port();
 	}
 
-	i8042_kbd_port = i8042_allocate_kbd_port();
-	if (i8042_kbd_port)
-		i8042_port_register(i8042_kbd_port);
+	i8042_create_kbd_port();
 
 	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 
@@ -1067,15 +1078,9 @@
 
 	i8042_controller_cleanup();
 
-	if (i8042_kbd_values.exists)
-		serio_unregister_port(i8042_kbd_port);
-
-	if (i8042_aux_values.exists)
-		serio_unregister_port(i8042_aux_port);
-
-	for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
-		if (i8042_mux_values[i].exists)
-			serio_unregister_port(i8042_mux_port[i]);
+	for (i = 0; i < I8042_NUM_PORTS; i++)
+		if (i8042_ports[i].exists)
+			serio_unregister_port(i8042_ports[i].serio);
 
 	del_timer_sync(&i8042_timer);
 
diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
--- a/drivers/input/serio/i8042.h	2004-12-29 01:46:50 -05:00
+++ b/drivers/input/serio/i8042.h	2004-12-29 01:46:50 -05:00
@@ -117,13 +117,13 @@
  */
 
 #ifdef DEBUG
-static unsigned long i8042_start;
-#define dbg_init() do { i8042_start = jiffies; } while (0)
+static unsigned long i8042_start_time;
+#define dbg_init() do { i8042_start_time = jiffies; } while (0)
 #define dbg(format, arg...) 							\
 	do { 									\
 		if (i8042_debug)						\
 			printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,	\
-	 			## arg, (int) (jiffies - i8042_start));		\
+	 			## arg, (int) (jiffies - i8042_start_time));	\
 	} while (0)
 #else
 #define dbg_init() do { } while (0)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 4/16] Suppress duplicate events in serio core
  2004-12-29  7:20     ` [PATCH 3/16] i8042: Make use of new " Dmitry Torokhov
@ 2004-12-29  7:21       ` Dmitry Torokhov
  2004-12-29  7:22         ` [PATCH 5/16] evdev: return -EINVAL if read buffer is too small Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:21 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.31, 2004-11-12 01:27:45-05:00, dtor_core@ameritech.net
  Input: rearrange serio event processing to get rid of duplicate
         events - do not sumbit event into the event queue if similar
         event has not been processed yet; also once event has been
         processed check the queue and delete events of the same type
         that have been accumulated in the mean time.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serio.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 48 insertions(+), 9 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-12-29 01:47:11 -05:00
+++ b/drivers/input/serio/serio.c	2004-12-29 01:47:11 -05:00
@@ -120,13 +120,28 @@
 static DECLARE_COMPLETION(serio_exited);
 static int serio_pid;
 
-static void serio_queue_event(struct serio *serio, int event_type)
+static void serio_queue_event(struct serio *serio, enum serio_event_type event_type)
 {
 	unsigned long flags;
 	struct serio_event *event;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
+	/*
+ 	 * Scan event list for the other events for the same serio 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, &serio_event_list, node) {
+		if (event->serio == serio) {
+			if (event->type == event_type)
+				goto out;
+			break;
+		}
+	}
+
 	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
 		event->type = event_type;
 		event->serio = serio;
@@ -135,9 +150,37 @@
 		wake_up(&serio_wait);
 	}
 
+out:
+	spin_unlock_irqrestore(&serio_event_lock, flags);
+}
+
+static void serio_remove_duplicate_events(struct serio_event *event)
+{
+	struct list_head *node, *next;
+	struct serio_event *e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	list_for_each_safe(node, next, &serio_event_list) {
+		e = container_of(node, struct serio_event, node);
+		if (event->serio == e->serio) {
+			/*
+			 * If this event is of different type we should not
+			 * look further - we only suppress duplicate events
+			 * that were sent back-to-back.
+			 */
+			if (event->type != e->type)
+				break;	/* Stop, when need to preserve event flow */
+			list_del_init(node);
+			kfree(e);
+		}
+	}
+
 	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
+
 static struct serio_event *serio_get_event(void)
 {
 	struct serio_event *event;
@@ -192,6 +235,7 @@
 		}
 
 		up(&serio_sem);
+		serio_remove_duplicate_events(event);
 		kfree(event);
 	}
 }
@@ -637,14 +681,9 @@
 
         if (likely(serio->drv)) {
                 ret = serio->drv->interrupt(serio, data, dfl, regs);
-	} else {
-		if (!dfl) {
-			if ((serio->type != SERIO_8042 &&
-			     serio->type != SERIO_8042_XL) || (data == 0xaa)) {
-				serio_rescan(serio);
-				ret = IRQ_HANDLED;
-			}
-		}
+	} else if (!dfl) {
+		serio_rescan(serio);
+		ret = IRQ_HANDLED;
 	}
 
 	spin_unlock_irqrestore(&serio->lock, flags);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 5/16] evdev: return -EINVAL if read buffer is too small
  2004-12-29  7:21       ` [PATCH 4/16] Suppress duplicate events in serio core Dmitry Torokhov
@ 2004-12-29  7:22         ` Dmitry Torokhov
  2004-12-29  7:23           ` [PATCH 6/16] Propery set up name for PS/2 Logitech mice Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:22 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.32, 2004-11-12 01:28:33-05:00, dtor_core@ameritech.net
  Input: evdev - return -EINVAL from evdev_read if read buffer
         is too small.
  
         Based on the patch by James Lamanna.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 evdev.c |    3 +++
 1 files changed, 3 insertions(+)


===================================================================



diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c
--- a/drivers/input/evdev.c	2004-12-29 01:47:32 -05:00
+++ b/drivers/input/evdev.c	2004-12-29 01:47:32 -05:00
@@ -169,6 +169,9 @@
 	struct evdev_list *list = file->private_data;
 	int retval;
 
+	if (count < sizeof(struct input_event))
+		return -EINVAL;
+
 	if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 6/16] Propery set up name for PS/2 Logitech mice
  2004-12-29  7:22         ` [PATCH 5/16] evdev: return -EINVAL if read buffer is too small Dmitry Torokhov
@ 2004-12-29  7:23           ` Dmitry Torokhov
  2004-12-29  7:24             ` [PATCH 7/16] Limit Synaptics rate on Toshiba Satellites Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:23 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.33, 2004-11-12 01:30:17-05:00, dtor_core@ameritech.net
  Input: psmouse - set mouse name to "Mouse" when using PS2++ and
         don't have any other information about the mouse.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 logips2pp.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c	2004-12-29 01:47:52 -05:00
+++ b/drivers/input/mouse/logips2pp.c	2004-12-29 01:47:52 -05:00
@@ -245,7 +245,8 @@
  * Set up input device's properties based on the detected mouse model.
  */
 
-static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info)
+static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
+				       int using_ps2pp)
 {
 	if (model_info->features & PS2PP_SIDE_BTN)
 		set_bit(BTN_SIDE, psmouse->dev.keybit);
@@ -279,6 +280,16 @@
 		case PS2PP_KIND_TP3:
 			psmouse->name = "TouchPad 3";
 			break;
+
+		default:
+			/*
+			 * Set name to "Mouse" only when using PS2++,
+			 * otherwise let other protocols define suitable
+			 * name
+			 */
+			if (using_ps2pp)
+				psmouse->name = "Mouse";
+			break;
 	}
 }
 
@@ -371,7 +382,7 @@
 			clear_bit(BTN_RIGHT, psmouse->dev.keybit);
 
 		if (model_info)
-			ps2pp_set_model_properties(psmouse, model_info);
+			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
 	}
 
 	return use_ps2pp ? 0 : -1;

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 7/16] Limit Synaptics rate on Toshiba Satellites
  2004-12-29  7:23           ` [PATCH 6/16] Propery set up name for PS/2 Logitech mice Dmitry Torokhov
@ 2004-12-29  7:24             ` Dmitry Torokhov
  2004-12-29  7:25               ` [PATCH 8/16] Allow setkeycodes work again Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:24 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1957.1.34, 2004-11-12 01:31:15-05:00, dtor_core@ameritech.net
  Input: synaptics - use DMI to detect Toshiba Satellite notebooks
         and automatically reduce touchpad reporting rate to 40 pps
         as they have trouble handling high rate (80 pps).
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 synaptics.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+)


===================================================================



diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	2004-12-29 01:48:12 -05:00
+++ b/drivers/input/mouse/synaptics.c	2004-12-29 01:48:12 -05:00
@@ -604,6 +604,20 @@
 	return 0;
 }
 
+#if defined(__i386__)
+#include <linux/dmi.h>
+static struct dmi_system_id toshiba_dmi_table[] = {
+	{
+		.ident = "Toshiba Satellite",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"),
+		},
+	},
+	{ }
+};
+#endif
+
 int synaptics_init(struct psmouse *psmouse)
 {
 	struct synaptics_data *priv;
@@ -636,6 +650,18 @@
 	psmouse->disconnect = synaptics_disconnect;
 	psmouse->reconnect = synaptics_reconnect;
 	psmouse->pktsize = 6;
+
+#if defined(__i386__)
+	/*
+	 * Toshiba's KBC seems to have trouble handling data from
+	 * Synaptics as full rate, switch to lower rate which is roughly
+	 * thye same as rate of standard PS/2 mouse.
+	 */
+	if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) {
+		printk(KERN_INFO "synaptics: Toshiba Satellite detected, limiting rate to 40pps.\n");
+		psmouse->rate = 40;
+	}
+#endif
 
 	return 0;
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 8/16] Allow setkeycodes work again
  2004-12-29  7:24             ` [PATCH 7/16] Limit Synaptics rate on Toshiba Satellites Dmitry Torokhov
@ 2004-12-29  7:25               ` Dmitry Torokhov
  2004-12-29  7:26                 ` [PATCH 9/16] i8042: fix sysfs permissiions for 'debug' parameter Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:25 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1967, 2004-11-20 02:27:37-05:00, dtor_core@ameritech.net
  Input: atkbd - fix keycode table size initialization that got broken
         by my changes that exported 'set' and other settings via sysfs.
         setkeycodes should work again now.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 atkbd.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


===================================================================



diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-12-29 01:48:53 -05:00
+++ b/drivers/input/keyboard/atkbd.c	2004-12-29 01:48:53 -05:00
@@ -756,6 +756,10 @@
 		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
 	}
 
+	atkbd->dev.keycode = atkbd->keycode;
+	atkbd->dev.keycodesize = sizeof(unsigned char);
+	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+
 	for (i = 0; i < 512; i++)
 		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
 			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
@@ -803,10 +807,6 @@
 
 	if (atkbd->softrepeat)
 		atkbd->softraw = 1;
-
-	atkbd->dev.keycode = atkbd->keycode;
-	atkbd->dev.keycodesize = sizeof(unsigned char);
-	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
 	serio->private = atkbd;
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 9/16] i8042: fix sysfs permissiions for 'debug' parameter
  2004-12-29  7:25               ` [PATCH 8/16] Allow setkeycodes work again Dmitry Torokhov
@ 2004-12-29  7:26                 ` Dmitry Torokhov
  2004-12-29  7:27                   ` [PATCH 10/16] Fix building twidjoy module Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:26 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1968, 2004-11-25 01:24:31-05:00, dtor_core@ameritech.net
  Input: i8042 - fix "debug" parameter sysfs permissions.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 i8042.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


===================================================================



diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2004-12-29 01:49:41 -05:00
+++ b/drivers/input/serio/i8042.c	2004-12-29 01:49:41 -05:00
@@ -68,7 +68,7 @@
 #define DEBUG
 #ifdef DEBUG
 static int i8042_debug;
-module_param_named(debug, i8042_debug, bool, 600);
+module_param_named(debug, i8042_debug, bool, 0600);
 MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
 #endif
 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 10/16] Fix building twidjoy module
  2004-12-29  7:26                 ` [PATCH 9/16] i8042: fix sysfs permissiions for 'debug' parameter Dmitry Torokhov
@ 2004-12-29  7:27                   ` Dmitry Torokhov
  2004-12-29  7:28                     ` [PATCH 11/16] Use msecs_to_jiffies in input core Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:27 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1970, 2004-12-28 00:45:17-05:00, dtor_core@ameritech.net
  Input: twidjoy - apparently Kconfig and Makefile disagreed on the
         name for config option so the module was never built.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 Kconfig   |    2 +-
 twidjoy.c |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
--- a/drivers/input/joystick/Kconfig	2004-12-29 01:50:22 -05:00
+++ b/drivers/input/joystick/Kconfig	2004-12-29 01:50:22 -05:00
@@ -187,7 +187,7 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called stinger.
 
-config JOYSTICK_TWIDDLER
+config JOYSTICK_TWIDJOY
 	tristate "Twiddler as a joystick"
 	depends on INPUT && INPUT_JOYSTICK
 	select SERIO
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	2004-12-29 01:50:22 -05:00
+++ b/drivers/input/joystick/twidjoy.c	2004-12-29 01:50:22 -05:00
@@ -58,7 +58,9 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
-MODULE_DESCRIPTION("Handykey Twiddler keyboard as a joystick driver");
+#define DRIVER_DESC	"Handykey Twiddler keyboard as a joystick driver"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 11/16] Use msecs_to_jiffies in input core
  2004-12-29  7:27                   ` [PATCH 10/16] Fix building twidjoy module Dmitry Torokhov
@ 2004-12-29  7:28                     ` Dmitry Torokhov
  2004-12-29  7:28                       ` [PATCH 12/16] Use msecs_to_jiffies in atkbd Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:28 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1971, 2004-12-28 00:47:11-05:00, dtor_core@ameritech.net
  Input: use msecs_to_jiffies instead of homegrown ms_to_jiffies
         when setting timer for autorepeat handling. This will
         make sure that autorepeat is scheduled correctly when
         HZ != 1000.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 input.c |   15 ++++-----------
 1 files changed, 4 insertions(+), 11 deletions(-)


===================================================================



diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	2004-12-29 01:51:20 -05:00
+++ b/drivers/input/input.c	2004-12-29 01:51:20 -05:00
@@ -54,14 +54,6 @@
 static int input_devices_state;
 #endif
 
-static inline unsigned int ms_to_jiffies(unsigned int ms)
-{
-        unsigned int j;
-        j = (ms * HZ + 500) / 1000;
-        return (j > 0) ? j : 1;
-}
-
-
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct input_handle *handle;
@@ -96,9 +88,9 @@
 
 			change_bit(code, dev->key);
 
-			if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && dev->timer.data && value) {
+			if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && dev->timer.data && value) {
 				dev->repeat_key = code;
-				mod_timer(&dev->timer, jiffies + ms_to_jiffies(dev->rep[REP_DELAY]));
+				mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
 			}
 
 			break;
@@ -198,7 +190,8 @@
 	input_event(dev, EV_KEY, dev->repeat_key, 2);
 	input_sync(dev);
 
-	mod_timer(&dev->timer, jiffies + ms_to_jiffies(dev->rep[REP_PERIOD]));
+	if (dev->rep[REP_PERIOD])
+		mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD]));
 }
 
 int input_accept_process(struct input_handle *handle, struct file *file)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 12/16] Use msecs_to_jiffies in atkbd
  2004-12-29  7:28                     ` [PATCH 11/16] Use msecs_to_jiffies in input core Dmitry Torokhov
@ 2004-12-29  7:28                       ` Dmitry Torokhov
  2004-12-29  7:29                         ` [PATCH 13/16] Introduce serio_get/set_drvdata helpers Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:28 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1972, 2004-12-28 00:47:30-05:00, dtor_core@ameritech.net
  Input: use msecs_to_jiffies instead of manually calculating
         delay for Toshiba bouncing keys workaround to the code
         works with HZ != 1000.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 atkbd.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


===================================================================



diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-12-29 01:51:48 -05:00
+++ b/drivers/input/keyboard/atkbd.c	2004-12-29 01:51:48 -05:00
@@ -378,7 +378,7 @@
 					break;
 				case 1:
 					atkbd->last = code;
-					atkbd->time = jiffies + (atkbd->dev.rep[REP_DELAY] * HZ + 500) / 1000 / 2;
+					atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2;
 					break;
 				case 2:
 					if (!time_after(jiffies, atkbd->time) && atkbd->last == code)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 13/16] Introduce serio_get/set_drvdata helpers
  2004-12-29  7:28                       ` [PATCH 12/16] Use msecs_to_jiffies in atkbd Dmitry Torokhov
@ 2004-12-29  7:29                         ` Dmitry Torokhov
  2004-12-29  7:31                           ` [PATCH 14/16] Introduce serio_id to match ports and drivers Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:29 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1973, 2004-12-28 01:00:28-05:00, dtor_core@ameritech.net
  Input: remove serio->private in favor of using driver-specific data
         in device structure, add serio_get_drvdata/serio_put_drvdata
         to access it.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/joystick/iforce/iforce-serio.c |   14 +++++++++----
 drivers/input/joystick/magellan.c            |    9 +++++---
 drivers/input/joystick/spaceball.c           |    9 +++++---
 drivers/input/joystick/spaceorb.c            |    9 +++++---
 drivers/input/joystick/stinger.c             |   10 ++++++---
 drivers/input/joystick/twidjoy.c             |   10 ++++++---
 drivers/input/joystick/warrior.c             |    9 +++++---
 drivers/input/keyboard/atkbd.c               |   18 +++++++++-------
 drivers/input/keyboard/lkkbd.c               |    8 ++++---
 drivers/input/keyboard/newtonkbd.c           |   10 ++++++---
 drivers/input/keyboard/sunkbd.c              |    9 +++++---
 drivers/input/keyboard/xtkbd.c               |    9 +++++---
 drivers/input/mouse/psmouse-base.c           |   29 ++++++++++++++-------------
 drivers/input/mouse/sermouse.c               |   11 ++++++----
 drivers/input/mouse/synaptics.c              |    7 +++---
 drivers/input/mouse/vsxxxaa.c                |    9 +++++---
 drivers/input/serio/serio_raw.c              |   12 +++++------
 drivers/input/touchscreen/gunze.c            |   10 ++++++---
 drivers/input/touchscreen/h3600_ts_input.c   |   13 +++++++-----
 include/linux/serio.h                        |   14 ++++++++++++-
 20 files changed, 149 insertions(+), 80 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 01:52:28 -05:00
@@ -75,13 +75,15 @@
 
 static void iforce_serio_write_wakeup(struct serio *serio)
 {
-	iforce_serial_xmit((struct iforce *)serio->private);
+	struct iforce *iforce = serio_get_drvdata(serio);
+
+	iforce_serial_xmit(iforce);
 }
 
 static irqreturn_t iforce_serio_irq(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct iforce* iforce = serio->private;
+	struct iforce *iforce = serio_get_drvdata(serio);
 
 	if (!iforce->pkt) {
 		if (data == 0x2b)
@@ -135,15 +137,18 @@
 
 	iforce->bus = IFORCE_232;
 	iforce->serio = serio;
-	serio->private = iforce;
+
+	serio_set_drvdata(serio, iforce);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(iforce);
 		return;
 	}
 
 	if (iforce_init_device(iforce)) {
 		serio_close(serio);
+		serio_set_drvdata(serio, NULL);
 		kfree(iforce);
 		return;
 	}
@@ -151,10 +156,11 @@
 
 static void iforce_serio_disconnect(struct serio *serio)
 {
-	struct iforce* iforce = serio->private;
+	struct iforce *iforce = serio_get_drvdata(serio);
 
 	input_unregister_device(&iforce->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(iforce);
 }
 
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/magellan.c	2004-12-29 01:52:28 -05:00
@@ -118,7 +118,7 @@
 static irqreturn_t magellan_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct magellan* magellan = serio->private;
+	struct magellan* magellan = serio_get_drvdata(serio);
 
 	if (data == '\r') {
 		magellan_process_packet(magellan, regs);
@@ -136,9 +136,11 @@
 
 static void magellan_disconnect(struct serio *serio)
 {
-	struct magellan* magellan = serio->private;
+	struct magellan* magellan = serio_get_drvdata(serio);
+
 	input_unregister_device(&magellan->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(magellan);
 }
 
@@ -185,9 +187,10 @@
 	magellan->dev.id.version = 0x0100;
 	magellan->dev.dev = &serio->dev;
 
-	serio->private = magellan;
+	serio_set_drvdata(serio, magellan);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(magellan);
 		return;
 	}
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/spaceball.c	2004-12-29 01:52:28 -05:00
@@ -154,7 +154,7 @@
 static irqreturn_t spaceball_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct spaceball *spaceball = serio->private;
+	struct spaceball *spaceball = serio_get_drvdata(serio);
 
 	switch (data) {
 		case 0xd:
@@ -191,9 +191,11 @@
 
 static void spaceball_disconnect(struct serio *serio)
 {
-	struct spaceball* spaceball = serio->private;
+	struct spaceball* spaceball = serio_get_drvdata(serio);
+
 	input_unregister_device(&spaceball->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(spaceball);
 }
 
@@ -255,9 +257,10 @@
 	spaceball->dev.id.version = 0x0100;
 	spaceball->dev.dev = &serio->dev;
 
-	serio->private = spaceball;
+	serio_set_drvdata(serio, spaceball);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(spaceball);
 		return;
 	}
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/spaceorb.c	2004-12-29 01:52:28 -05:00
@@ -135,7 +135,7 @@
 static irqreturn_t spaceorb_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct spaceorb* spaceorb = serio->private;
+	struct spaceorb* spaceorb = serio_get_drvdata(serio);
 
 	if (~data & 0x80) {
 		if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs);
@@ -152,9 +152,11 @@
 
 static void spaceorb_disconnect(struct serio *serio)
 {
-	struct spaceorb* spaceorb = serio->private;
+	struct spaceorb* spaceorb = serio_get_drvdata(serio);
+
 	input_unregister_device(&spaceorb->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(spaceorb);
 }
 
@@ -202,9 +204,10 @@
 	spaceorb->dev.id.version = 0x0100;
 	spaceorb->dev.dev = &serio->dev;
 
-	serio->private = spaceorb;
+	serio_set_drvdata(serio, spaceorb);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(spaceorb);
 		return;
 	}
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/stinger.c	2004-12-29 01:52:28 -05:00
@@ -103,7 +103,7 @@
 static irqreturn_t stinger_interrupt(struct serio *serio,
 	unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct stinger* stinger = serio->private;
+	struct stinger *stinger = serio_get_drvdata(serio);
 
 	/* All Stinger packets are 4 bytes */
 
@@ -124,9 +124,11 @@
 
 static void stinger_disconnect(struct serio *serio)
 {
-	struct stinger* stinger = serio->private;
+	struct stinger *stinger = serio_get_drvdata(serio);
+
 	input_unregister_device(&stinger->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(stinger);
 }
 
@@ -173,9 +175,11 @@
 	}
 
 	stinger->dev.private = stinger;
-	serio->private = stinger;
+
+	serio_set_drvdata(serio, stinger);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(stinger);
 		return;
 	}
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/twidjoy.c	2004-12-29 01:52:28 -05:00
@@ -149,7 +149,7 @@
 
 static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct twidjoy *twidjoy = serio->private;
+	struct twidjoy *twidjoy = serio_get_drvdata(serio);
 
 	/* All Twiddler packets are 5 bytes. The fact that the first byte
 	 * has a MSB of 0 and all other bytes have a MSB of 1 can be used
@@ -177,9 +177,11 @@
 
 static void twidjoy_disconnect(struct serio *serio)
 {
-	struct twidjoy *twidjoy = serio->private;
+	struct twidjoy *twidjoy = serio_get_drvdata(serio);
+
 	input_unregister_device(&twidjoy->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(twidjoy);
 }
 
@@ -233,9 +235,11 @@
 	}
 
 	twidjoy->dev.private = twidjoy;
-	serio->private = twidjoy;
+
+	serio_set_drvdata(serio, twidjoy);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(twidjoy);
 		return;
 	}
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/joystick/warrior.c	2004-12-29 01:52:28 -05:00
@@ -104,7 +104,7 @@
 static irqreturn_t warrior_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct warrior* warrior = serio->private;
+	struct warrior *warrior = serio_get_drvdata(serio);
 
 	if (data & 0x80) {
 		if (warrior->idx) warrior_process_packet(warrior, regs);
@@ -129,9 +129,11 @@
 
 static void warrior_disconnect(struct serio *serio)
 {
-	struct warrior* warrior = serio->private;
+	struct warrior *warrior = serio_get_drvdata(serio);
+
 	input_unregister_device(&warrior->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(warrior);
 }
 
@@ -186,9 +188,10 @@
 
 	warrior->dev.private = warrior;
 
-	serio->private = warrior;
+	serio_set_drvdata(serio, warrior);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(warrior);
 		return;
 	}
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/keyboard/atkbd.c	2004-12-29 01:52:28 -05:00
@@ -248,7 +248,7 @@
 static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
 			unsigned int flags, struct pt_regs *regs)
 {
-	struct atkbd *atkbd = serio->private;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 	unsigned int code = data;
 	int scroll = 0, click = -1;
 	int value;
@@ -645,7 +645,7 @@
 
 static void atkbd_cleanup(struct serio *serio)
 {
-	struct atkbd *atkbd = serio->private;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 	ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT);
 }
 
@@ -656,7 +656,7 @@
 
 static void atkbd_disconnect(struct serio *serio)
 {
-	struct atkbd *atkbd = serio->private;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 
 	atkbd_disable(atkbd);
 
@@ -672,6 +672,7 @@
 
 	input_unregister_device(&atkbd->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(atkbd);
 }
 
@@ -808,9 +809,10 @@
 	if (atkbd->softrepeat)
 		atkbd->softraw = 1;
 
-	serio->private = atkbd;
+	serio_set_drvdata(serio, atkbd);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(atkbd);
 		return;
 	}
@@ -819,7 +821,7 @@
 
 		if (atkbd_probe(atkbd)) {
 			serio_close(serio);
-			serio->private = NULL;
+			serio_set_drvdata(serio, NULL);
 			kfree(atkbd);
 			return;
 		}
@@ -863,7 +865,7 @@
 
 static int atkbd_reconnect(struct serio *serio)
 {
-	struct atkbd *atkbd = serio->private;
+	struct atkbd *atkbd = serio_get_drvdata(serio);
 	struct serio_driver *drv = serio->drv;
 	unsigned char param[1];
 
@@ -922,7 +924,7 @@
 		goto out;
 	}
 
-	retval = handler((struct atkbd *)serio->private, buf);
+	retval = handler((struct atkbd *)serio_get_drvdata(serio), buf);
 
 out:
 	serio_unpin_driver(serio);
@@ -945,7 +947,7 @@
 		goto out;
 	}
 
-	atkbd = serio->private;
+	atkbd = serio_get_drvdata(serio);
 	atkbd_disable(atkbd);
 	retval = handler(atkbd, buf, count);
 	atkbd_enable(atkbd);
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/keyboard/lkkbd.c	2004-12-29 01:52:28 -05:00
@@ -417,7 +417,7 @@
 lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 		struct pt_regs *regs)
 {
-	struct lkkbd *lk = serio->private;
+	struct lkkbd *lk = serio_get_drvdata (serio);
 	int i;
 
 	DBG (KERN_INFO "Got byte 0x%02x\n", data);
@@ -665,9 +665,10 @@
 	lk->dev.event = lkkbd_event;
 	lk->dev.private = lk;
 
-	serio->private = lk;
+	serio_set_drvdata (serio, lk);
 
 	if (serio_open (serio, drv)) {
+		serio_set_drvdata (serio, NULL);
 		kfree (lk);
 		return;
 	}
@@ -699,10 +700,11 @@
 static void
 lkkbd_disconnect (struct serio *serio)
 {
-	struct lkkbd *lk = serio->private;
+	struct lkkbd *lk = serio_get_drvdata (serio);
 
 	input_unregister_device (&lk->dev);
 	serio_close (serio);
+	serio_set_drvdata (serio, NULL);
 	kfree (lk);
 }
 
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/keyboard/newtonkbd.c	2004-12-29 01:52:28 -05:00
@@ -69,7 +69,7 @@
 irqreturn_t nkbd_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct nkbd *nkbd = serio->private;
+	struct nkbd *nkbd = serio_get_drvdata(serio);
 
 	/* invalid scan codes are probably the init sequence, so we ignore them */
 	if (nkbd->keycode[data & NKBD_KEY]) {
@@ -106,9 +106,11 @@
 	nkbd->dev.keycodesize = sizeof(unsigned char);
 	nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
 	nkbd->dev.private = nkbd;
-	serio->private = nkbd;
+
+	serio_set_drvdata(serio, nkbd);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(nkbd);
 		return;
 	}
@@ -135,9 +137,11 @@
 
 void nkbd_disconnect(struct serio *serio)
 {
-	struct nkbd *nkbd = serio->private;
+	struct nkbd *nkbd = serio_get_drvdata(serio);
+
 	input_unregister_device(&nkbd->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(nkbd);
 }
 
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/keyboard/sunkbd.c	2004-12-29 01:52:28 -05:00
@@ -95,7 +95,7 @@
 static irqreturn_t sunkbd_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct sunkbd* sunkbd = serio->private;
+	struct sunkbd* sunkbd = serio_get_drvdata(serio);
 
 	if (sunkbd->reset <= -1) {		/* If cp[i] is 0xff, sunkbd->reset will stay -1. */
 		sunkbd->reset = data;		/* The keyboard sends 0xff 0xff 0xID on powerup */
@@ -257,15 +257,17 @@
 	sunkbd->dev.event = sunkbd_event;
 	sunkbd->dev.private = sunkbd;
 
-	serio->private = sunkbd;
+	serio_set_drvdata(serio, sunkbd);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(sunkbd);
 		return;
 	}
 
 	if (sunkbd_initialize(sunkbd) < 0) {
 		serio_close(serio);
+		serio_set_drvdata(serio, NULL);
 		kfree(sunkbd);
 		return;
 	}
@@ -298,9 +300,10 @@
 
 static void sunkbd_disconnect(struct serio *serio)
 {
-	struct sunkbd *sunkbd = serio->private;
+	struct sunkbd *sunkbd = serio_get_drvdata(serio);
 	input_unregister_device(&sunkbd->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(sunkbd);
 }
 
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/keyboard/xtkbd.c	2004-12-29 01:52:28 -05:00
@@ -68,7 +68,7 @@
 irqreturn_t xtkbd_interrupt(struct serio *serio,
 	unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct xtkbd *xtkbd = serio->private;
+	struct xtkbd *xtkbd = serio_get_drvdata(serio);
 
 	switch (data) {
 		case XTKBD_EMUL0:
@@ -111,9 +111,10 @@
 	xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
 	xtkbd->dev.private = xtkbd;
 
-	serio->private = xtkbd;
+	serio_set_drvdata(serio, xtkbd);
 
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(xtkbd);
 		return;
 	}
@@ -140,9 +141,11 @@
 
 void xtkbd_disconnect(struct serio *serio)
 {
-	struct xtkbd *xtkbd = serio->private;
+	struct xtkbd *xtkbd = serio_get_drvdata(serio);
+
 	input_unregister_device(&xtkbd->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(xtkbd);
 }
 
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/mouse/psmouse-base.c	2004-12-29 01:52:28 -05:00
@@ -142,7 +142,7 @@
 static irqreturn_t psmouse_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct psmouse *psmouse = serio->private;
+	struct psmouse *psmouse = serio_get_drvdata(serio);
 	psmouse_ret_t rc;
 
 	if (psmouse->state == PSMOUSE_IGNORE)
@@ -632,7 +632,7 @@
 
 static void psmouse_cleanup(struct serio *serio)
 {
-	struct psmouse *psmouse = serio->private;
+	struct psmouse *psmouse = serio_get_drvdata(serio);
 
 	psmouse_reset(psmouse);
 }
@@ -649,11 +649,11 @@
 	device_remove_file(&serio->dev, &psmouse_attr_resolution);
 	device_remove_file(&serio->dev, &psmouse_attr_resetafter);
 
-	psmouse = serio->private;
+	psmouse = serio_get_drvdata(serio);
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 
 	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
-		parent = serio->parent->private;
+		parent = serio_get_drvdata(serio->parent);
 		if (parent->pt_deactivate)
 			parent->pt_deactivate(parent);
 	}
@@ -665,6 +665,7 @@
 
 	input_unregister_device(&psmouse->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(psmouse);
 }
 
@@ -685,7 +686,7 @@
 	 * connected to this port can be successfully identified
 	 */
 	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
-		parent = serio->parent->private;
+		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
 
@@ -702,17 +703,18 @@
 	psmouse->dev.dev = &serio->dev;
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
-	serio->private = psmouse;
+	serio_set_drvdata(serio, psmouse);
+
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(psmouse);
-		serio->private = NULL;
 		goto out;
 	}
 
 	if (psmouse_probe(psmouse) < 0) {
 		serio_close(serio);
+		serio_set_drvdata(serio, NULL);
 		kfree(psmouse);
-		serio->private = NULL;
 		goto out;
 	}
 
@@ -773,7 +775,7 @@
 
 static int psmouse_reconnect(struct serio *serio)
 {
-	struct psmouse *psmouse = serio->private;
+	struct psmouse *psmouse = serio_get_drvdata(serio);
 	struct psmouse *parent = NULL;
 	struct serio_driver *drv = serio->drv;
 	int rc = -1;
@@ -784,7 +786,7 @@
 	}
 
 	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
-		parent = serio->parent->private;
+		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
 
@@ -846,7 +848,7 @@
 		goto out;
 	}
 
-	retval = handler(serio->private, buf);
+	retval = handler(serio_get_drvdata(serio), buf);
 
 out:
 	serio_unpin_driver(serio);
@@ -857,7 +859,8 @@
 				ssize_t (*handler)(struct psmouse *, const char *, size_t))
 {
 	struct serio *serio = to_serio_port(dev);
-	struct psmouse *psmouse = serio->private, *parent = NULL;
+	struct psmouse *psmouse = serio_get_drvdata(serio);
+	struct psmouse *parent = NULL;
 	int retval;
 
 	retval = serio_pin_driver(serio);
@@ -870,7 +873,7 @@
 	}
 
 	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
-		parent = serio->parent->private;
+		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
 	psmouse_deactivate(psmouse);
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/mouse/sermouse.c	2004-12-29 01:52:28 -05:00
@@ -209,7 +209,7 @@
 static irqreturn_t sermouse_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct sermouse *sermouse = serio->private;
+	struct sermouse *sermouse = serio_get_drvdata(serio);
 
 	if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0;
 	sermouse->last = jiffies;
@@ -228,9 +228,11 @@
 
 static void sermouse_disconnect(struct serio *serio)
 {
-	struct sermouse *sermouse = serio->private;
+	struct sermouse *sermouse = serio_get_drvdata(serio);
+
 	input_unregister_device(&sermouse->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(sermouse);
 }
 
@@ -261,8 +263,6 @@
 	sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
 	sermouse->dev.private = sermouse;
 
-	serio->private = sermouse;
-
 	sermouse->type = serio->type & SERIO_PROTO;
 	c = (serio->type & SERIO_EXTRA) >> 16;
 
@@ -282,7 +282,10 @@
 	sermouse->dev.id.version = 0x0100;
 	sermouse->dev.dev = &serio->dev;
 
+	serio_set_drvdata(serio, sermouse);
+
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(sermouse);
 		return;
 	}
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/mouse/synaptics.c	2004-12-29 01:52:28 -05:00
@@ -229,7 +229,7 @@
  ****************************************************************************/
 static int synaptics_pt_write(struct serio *serio, unsigned char c)
 {
-	struct psmouse *parent = serio->parent->private;
+	struct psmouse *parent = serio_get_drvdata(serio->parent);
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
 	if (psmouse_sliced_command(parent, c))
@@ -246,7 +246,7 @@
 
 static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet)
 {
-	struct psmouse *child = ptport->private;
+	struct psmouse *child = serio_get_drvdata(ptport);
 
 	if (child && child->state == PSMOUSE_ACTIVATED) {
 		serio_interrupt(ptport, packet[1], 0, NULL);
@@ -260,7 +260,8 @@
 
 static void synaptics_pt_activate(struct psmouse *psmouse)
 {
-	struct psmouse *child = psmouse->ps2dev.serio->child->private;
+	struct serio *ptport = psmouse->ps2dev.serio->child;
+	struct psmouse *child = serio_get_drvdata(ptport);
 	struct synaptics_data *priv = psmouse->private;
 
 	/* adjust the touchpad to child's choice of protocol */
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/mouse/vsxxxaa.c	2004-12-29 01:52:28 -05:00
@@ -470,7 +470,7 @@
 vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 		struct pt_regs *regs)
 {
-	struct vsxxxaa *mouse = serio->private;
+	struct vsxxxaa *mouse = serio_get_drvdata (serio);
 
 	vsxxxaa_queue_byte (mouse, data);
 	vsxxxaa_parse_buffer (mouse, regs);
@@ -481,10 +481,11 @@
 static void
 vsxxxaa_disconnect (struct serio *serio)
 {
-	struct vsxxxaa *mouse = serio->private;
+	struct vsxxxaa *mouse = serio_get_drvdata (serio);
 
 	input_unregister_device (&mouse->dev);
 	serio_close (serio);
+	serio_set_drvdata (serio, NULL);
 	kfree (mouse);
 }
 
@@ -522,7 +523,6 @@
 	mouse->dev.absmax[ABS_Y] = 1023;
 
 	mouse->dev.private = mouse;
-	serio->private = mouse;
 
 	sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
 	sprintf (mouse->phys, "%s/input0", serio->phys);
@@ -532,7 +532,10 @@
 	mouse->dev.dev = &serio->dev;
 	mouse->serio = serio;
 
+	serio_set_drvdata (serio, mouse);
+
 	if (serio_open (serio, drv)) {
+		serio_set_drvdata (serio, NULL);
 		kfree (mouse);
 		return;
 	}
diff -Nru a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- a/drivers/input/serio/serio_raw.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/serio/serio_raw.c	2004-12-29 01:52:28 -05:00
@@ -253,7 +253,7 @@
 static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
 					unsigned int dfl, struct pt_regs *regs)
 {
-	struct serio_raw *serio_raw = serio->private;
+	struct serio_raw *serio_raw = serio_get_drvdata(serio);
 	struct serio_raw_list *list;
 	unsigned int head = serio_raw->head;
 
@@ -292,7 +292,7 @@
 	INIT_LIST_HEAD(&serio_raw->list);
 	init_waitqueue_head(&serio_raw->wait);
 
-	serio->private = serio_raw;
+	serio_set_drvdata(serio, serio_raw);
 	if (serio_open(serio, drv))
 		goto out_free;
 
@@ -322,7 +322,7 @@
 	serio_close(serio);
 	list_del_init(&serio_raw->node);
 out_free:
-	serio->private = NULL;
+	serio_set_drvdata(serio, NULL);
 	kfree(serio_raw);
 out:
 	up(&serio_raw_sem);
@@ -330,7 +330,7 @@
 
 static int serio_raw_reconnect(struct serio *serio)
 {
-	struct serio_raw *serio_raw = serio->private;
+	struct serio_raw *serio_raw = serio_get_drvdata(serio);
 	struct serio_driver *drv = serio->drv;
 
 	if (!drv || !serio_raw) {
@@ -351,10 +351,10 @@
 
 	down(&serio_raw_sem);
 
-	serio_raw = serio->private;
+	serio_raw = serio_get_drvdata(serio);
 
 	serio_close(serio);
-	serio->private = NULL;
+	serio_set_drvdata(serio, NULL);
 
 	serio_raw->serio = NULL;
 	if (!serio_raw_cleanup(serio_raw))
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/touchscreen/gunze.c	2004-12-29 01:52:28 -05:00
@@ -83,7 +83,7 @@
 static irqreturn_t gunze_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
-	struct gunze* gunze = serio->private;
+	struct gunze* gunze = serio_get_drvdata(serio);
 
 	if (data == '\r') {
 		gunze_process_packet(gunze, regs);
@@ -101,9 +101,11 @@
 
 static void gunze_disconnect(struct serio *serio)
 {
-	struct gunze* gunze = serio->private;
+	struct gunze* gunze = serio_get_drvdata(serio);
+
 	input_unregister_device(&gunze->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(gunze);
 }
 
@@ -132,7 +134,6 @@
 	input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
 
 	gunze->serio = serio;
-	serio->private = gunze;
 
 	sprintf(gunze->phys, "%s/input0", serio->phys);
 
@@ -144,7 +145,10 @@
 	gunze->dev.id.product = 0x0051;
 	gunze->dev.id.version = 0x0100;
 
+	serio_set_drvdata(serio, gunze);
+
 	if (serio_open(serio, drv)) {
+		serio_set_drvdata(serio, NULL);
 		kfree(gunze);
 		return;
 	}
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 01:52:28 -05:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 01:52:28 -05:00
@@ -331,7 +331,7 @@
 static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
                                      unsigned int flags, struct pt_regs *regs)
 {
-        struct h3600_dev *ts = serio->private;
+        struct h3600_dev *ts = serio_get_drvdata(serio);
 
 	/*
          * We have a new frame coming in.
@@ -431,7 +431,6 @@
 	ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
 
 	ts->serio = serio;
-	serio->private = ts;
 
 	sprintf(ts->phys, "%s/input0", serio->phys);
 
@@ -444,9 +443,12 @@
 	ts->dev.id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
 	ts->dev.id.version = 0x0100;
 
+	serio_set_drvdata(serio, ts);
+
 	if (serio_open(serio, drv)) {
         	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
         	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
+		serio_set_drvdata(serio, NULL);
 		kfree(ts);
 		return;
 	}
@@ -468,12 +470,13 @@
 
 static void h3600ts_disconnect(struct serio *serio)
 {
-	struct h3600_dev *ts = serio->private;
+	struct h3600_dev *ts = serio_get_drvdata(serio);
 
-        free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
-        free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
+	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
+	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
 	input_unregister_device(&ts->dev);
 	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
 	kfree(ts);
 }
 
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-12-29 01:52:28 -05:00
+++ b/include/linux/serio.h	2004-12-29 01:52:28 -05:00
@@ -21,7 +21,6 @@
 #include <linux/device.h>
 
 struct serio {
-	void *private;
 	void *port_data;
 
 	char name[32];
@@ -110,6 +109,19 @@
 		serio->drv->cleanup(serio);
 }
 
+/*
+ * Use the following fucntions to manipulate serio's per-port
+ * driver-specific data.
+ */
+static __inline__ void *serio_get_drvdata(struct serio *serio)
+{
+	return dev_get_drvdata(&serio->dev);
+}
+
+static __inline__ void serio_set_drvdata(struct serio *serio, void *data)
+{
+	dev_set_drvdata(&serio->dev, data);
+}
 
 /*
  * Use the following fucntions to protect critical sections in

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 14/16] Introduce serio_id to match ports and drivers
  2004-12-29  7:29                         ` [PATCH 13/16] Introduce serio_get/set_drvdata helpers Dmitry Torokhov
@ 2004-12-29  7:31                           ` Dmitry Torokhov
  2004-12-29  7:32                             ` [PATCH 15/16] serio bus implementation cleanup Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:31 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1974, 2004-12-28 01:14:03-05:00, dtor_core@ameritech.net
  Input: replace serio's type field with serio_id structure and
         add ids table to serio drivers. This will allow split
         initial matching and probing routines for better sysfs
         integration.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/joystick/iforce/iforce-serio.c |   16 ++++++++--
 drivers/input/joystick/magellan.c            |   20 +++++++++---
 drivers/input/joystick/spaceball.c           |   22 +++++++++-----
 drivers/input/joystick/spaceorb.c            |   18 ++++++++---
 drivers/input/joystick/stinger.c             |   20 +++++++++---
 drivers/input/joystick/twidjoy.c             |   17 ++++++++--
 drivers/input/joystick/warrior.c             |   16 +++++++---
 drivers/input/keyboard/atkbd.c               |   31 +++++++++++++++----
 drivers/input/keyboard/lkkbd.c               |   16 +++++++---
 drivers/input/keyboard/newtonkbd.c           |   14 +++++++--
 drivers/input/keyboard/sunkbd.c              |   23 ++++++++++----
 drivers/input/keyboard/xtkbd.c               |   14 +++++++--
 drivers/input/mouse/psmouse-base.c           |   28 ++++++++++++------
 drivers/input/mouse/sermouse.c               |   20 +++++++++---
 drivers/input/mouse/synaptics.c              |    2 -
 drivers/input/mouse/vsxxxaa.c                |   16 +++++++---
 drivers/input/serio/ambakmi.c                |    2 -
 drivers/input/serio/ct82c710.c               |    2 -
 drivers/input/serio/gscps2.c                 |    6 ---
 drivers/input/serio/i8042.c                  |    6 +--
 drivers/input/serio/maceps2.c                |    2 -
 drivers/input/serio/parkbd.c                 |    2 -
 drivers/input/serio/pcips2.c                 |    2 -
 drivers/input/serio/q40kbd.c                 |    2 -
 drivers/input/serio/rpckbd.c                 |    2 -
 drivers/input/serio/sa1111ps2.c              |    2 -
 drivers/input/serio/serio.c                  |   30 ++++++++++++++-----
 drivers/input/serio/serio_raw.c              |   14 +++++++--
 drivers/input/serio/serport.c                |   18 ++++++++---
 drivers/input/touchscreen/gunze.c            |   20 +++++++++---
 drivers/input/touchscreen/h3600_ts_input.c   |   21 +++++++++----
 drivers/serial/sunsu.c                       |    7 ++--
 drivers/serial/sunzilog.c                    |    7 ++--
 include/linux/serio.h                        |   42 +++++++++++++++------------
 34 files changed, 334 insertions(+), 146 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 01:52:53 -05:00
@@ -129,10 +129,9 @@
 static void iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct iforce *iforce;
-	if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
-		return;
 
-	if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL))) return;
+	if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
+		return;
 	memset(iforce, 0, sizeof(struct iforce));
 
 	iforce->bus = IFORCE_232;
@@ -164,11 +163,22 @@
 	kfree(iforce);
 }
 
+static struct serio_id iforce_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_IFORCE,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 struct serio_driver iforce_serio_drv = {
 	.driver		= {
 		.name	= "iforce",
 	},
 	.description	= "RS232 I-Force joysticks and wheels driver",
+	.ids		= iforce_serio_ids,
 	.write_wakeup	= iforce_serio_write_wakeup,
 	.interrupt	= iforce_serio_irq,
 	.connect	= iforce_serio_connect,
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/magellan.c	2004-12-29 01:52:53 -05:00
@@ -146,8 +146,8 @@
 
 /*
  * magellan_connect() is the routine that is called when someone adds a
- * new serio device. It looks for the Magellan, and if found, registers
- * it as an input device.
+ * new serio device that supports Magellan protocol and registers it as
+ * an input device.
  */
 
 static void magellan_connect(struct serio *serio, struct serio_driver *drv)
@@ -155,9 +155,6 @@
 	struct magellan *magellan;
 	int i, t;
 
-	if (serio->type != (SERIO_RS232 | SERIO_MAGELLAN))
-		return;
-
 	if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
 		return;
 
@@ -202,14 +199,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id magellan_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_MAGELLAN,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver magellan_drv = {
 	.driver		= {
 		.name	= "magellan",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= magellan_serio_ids,
 	.interrupt	= magellan_interrupt,
 	.connect	= magellan_connect,
 	.disconnect	= magellan_disconnect,
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/spaceball.c	2004-12-29 01:52:53 -05:00
@@ -201,8 +201,8 @@
 
 /*
  * spaceball_connect() is the routine that is called when someone adds a
- * new serio device. It looks for the Magellan, and if found, registers
- * it as an input device.
+ * new serio device that supports Spaceball protocol and registers it as
+ * an input device.
  */
 
 static void spaceball_connect(struct serio *serio, struct serio_driver *drv)
@@ -210,10 +210,7 @@
 	struct spaceball *spaceball;
 	int i, t, id;
 
-	if ((serio->type & ~SERIO_ID) != (SERIO_RS232 | SERIO_SPACEBALL))
-		return;
-
-	if ((id = (serio->type & SERIO_ID) >> 8) > SPACEBALL_MAX_ID)
+	if ((id = serio->id.id) > SPACEBALL_MAX_ID)
 		return;
 
 	if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL)))
@@ -272,14 +269,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id spaceball_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_SPACEBALL,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver spaceball_drv = {
 	.driver		= {
 		.name	= "spaceball",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= spaceball_serio_ids,
 	.interrupt	= spaceball_interrupt,
 	.connect	= spaceball_connect,
 	.disconnect	= spaceball_disconnect,
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/spaceorb.c	2004-12-29 01:52:53 -05:00
@@ -162,7 +162,7 @@
 
 /*
  * spaceorb_connect() is the routine that is called when someone adds a
- * new serio device. It looks for the SpaceOrb/Avenger, and if found, registers
+ * new serio device that supports SpaceOrb/Avenger protocol and registers
  * it as an input device.
  */
 
@@ -171,9 +171,6 @@
 	struct spaceorb *spaceorb;
 	int i, t;
 
-	if (serio->type != (SERIO_RS232 | SERIO_SPACEORB))
-		return;
-
 	if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
 		return;
 	memset(spaceorb, 0, sizeof(struct spaceorb));
@@ -216,14 +213,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id spaceorb_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_SPACEORB,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver spaceorb_drv = {
 	.driver		= {
 		.name	= "spaceorb",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= spaceorb_serio_ids,
 	.interrupt	= spaceorb_interrupt,
 	.connect	= spaceorb_connect,
 	.disconnect	= spaceorb_disconnect,
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/stinger.c	2004-12-29 01:52:53 -05:00
@@ -134,8 +134,8 @@
 
 /*
  * stinger_connect() is the routine that is called when someone adds a
- * new serio device. It looks for the Stinger, and if found, registers
- * it as an input device.
+ * new serio device that supports Stinger protocol and registers it as
+ * an input device.
  */
 
 static void stinger_connect(struct serio *serio, struct serio_driver *drv)
@@ -143,9 +143,6 @@
 	struct stinger *stinger;
 	int i;
 
-	if (serio->type != (SERIO_RS232 | SERIO_STINGER))
-		return;
-
 	if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
 		return;
 
@@ -191,14 +188,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id stinger_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_STINGER,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver stinger_drv = {
 	.driver		= {
 		.name	= "stinger",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= stinger_serio_ids,
 	.interrupt	= stinger_interrupt,
 	.connect	= stinger_connect,
 	.disconnect	= stinger_disconnect,
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/twidjoy.c	2004-12-29 01:52:53 -05:00
@@ -197,9 +197,6 @@
 	struct twidjoy *twidjoy;
 	int i;
 
-	if (serio->type != (SERIO_RS232 | SERIO_TWIDJOY))
-		return;
-
 	if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
 		return;
 
@@ -250,14 +247,26 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id twidjoy_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_TWIDJOY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+
 static struct serio_driver twidjoy_drv = {
 	.driver		= {
 		.name	= "twidjoy",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= twidjoy_serio_ids,
 	.interrupt	= twidjoy_interrupt,
 	.connect	= twidjoy_connect,
 	.disconnect	= twidjoy_disconnect,
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/joystick/warrior.c	2004-12-29 01:52:53 -05:00
@@ -148,9 +148,6 @@
 	struct warrior *warrior;
 	int i;
 
-	if (serio->type != (SERIO_RS232 | SERIO_WARRIOR))
-		return;
-
 	if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
 		return;
 
@@ -202,14 +199,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id warrior_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_WARRIOR,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver warrior_drv = {
 	.driver		= {
 		.name	= "warrior",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= warrior_serio_ids,
 	.interrupt	= warrior_interrupt,
 	.connect	= warrior_connect,
 	.disconnect	= warrior_disconnect,
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/keyboard/atkbd.c	2004-12-29 01:52:53 -05:00
@@ -783,7 +783,7 @@
 
 	ps2_init(&atkbd->ps2dev, serio);
 
-	switch (serio->type & SERIO_TYPE) {
+	switch (serio->id.type) {
 
 		case SERIO_8042_XL:
 			atkbd->translated = 1;
@@ -791,12 +791,6 @@
 			if (serio->write)
 				atkbd->write = 1;
 			break;
-		case SERIO_RS232:
-			if ((serio->type & SERIO_PROTO) == SERIO_PS2SER)
-				break;
-		default:
-			kfree(atkbd);
-			return;
 	}
 
 	atkbd->softraw = atkbd_softraw;
@@ -897,11 +891,34 @@
 	return 0;
 }
 
+static struct serio_id atkbd_serio_ids[] = {
+	{
+		.type	= SERIO_8042,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{
+		.type	= SERIO_8042_XL,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_PS2SER,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver atkbd_drv = {
 	.driver		= {
 		.name	= "atkbd",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= atkbd_serio_ids,
 	.interrupt	= atkbd_interrupt,
 	.connect	= atkbd_connect,
 	.reconnect	= atkbd_reconnect,
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/keyboard/lkkbd.c	2004-12-29 01:52:53 -05:00
@@ -629,11 +629,6 @@
 	struct lkkbd *lk;
 	int i;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_RS232)
-		return;
-	if ((serio->type & SERIO_PROTO) != SERIO_LKKBD)
-		return;
-
 	if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
 		return;
 	memset (lk, 0, sizeof (struct lkkbd));
@@ -708,11 +703,22 @@
 	kfree (lk);
 }
 
+static struct serio_id lkkbd_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_LKKBD,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver lkkbd_drv = {
 	.driver		= {
 		.name	= "lkkbd",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= lkkbd_serio_ids,
 	.connect	= lkkbd_connect,
 	.disconnect	= lkkbd_disconnect,
 	.interrupt	= lkkbd_interrupt,
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/keyboard/newtonkbd.c	2004-12-29 01:52:53 -05:00
@@ -89,9 +89,6 @@
 	struct nkbd *nkbd;
 	int i;
 
-	if (serio->type != (SERIO_RS232 | SERIO_NEWTON))
-		return;
-
 	if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
 		return;
 
@@ -145,11 +142,22 @@
 	kfree(nkbd);
 }
 
+static struct serio_id nkbd_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_NEWTON,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 struct serio_driver nkbd_drv = {
 	.driver		= {
 		.name	= "newtonkbd",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= nkbd_serio_ids,
 	.interrupt	= nkbd_interrupt,
 	.connect	= nkbd_connect,
 	.disconnect	= nkbd_disconnect,
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/keyboard/sunkbd.c	2004-12-29 01:52:53 -05:00
@@ -228,12 +228,6 @@
 	struct sunkbd *sunkbd;
 	int i;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_RS232)
-		return;
-
-	if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD)
-		return;
-
 	if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
 		return;
 
@@ -307,11 +301,28 @@
 	kfree(sunkbd);
 }
 
+static struct serio_id sunkbd_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_SUNKBD,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_UNKNOWN, /* sunkbd does probe */
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver sunkbd_drv = {
 	.driver		= {
 		.name	= "sunkbd",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= sunkbd_serio_ids,
 	.interrupt	= sunkbd_interrupt,
 	.connect	= sunkbd_connect,
 	.disconnect	= sunkbd_disconnect,
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/keyboard/xtkbd.c	2004-12-29 01:52:53 -05:00
@@ -93,9 +93,6 @@
 	struct xtkbd *xtkbd;
 	int i;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_XT)
-		return;
-
 	if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
 		return;
 
@@ -149,11 +146,22 @@
 	kfree(xtkbd);
 }
 
+static struct serio_id xtkbd_serio_ids[] = {
+	{
+		.type	= SERIO_XT,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 struct serio_driver xtkbd_drv = {
 	.driver		= {
 		.name	= "xtkbd",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= xtkbd_serio_ids,
 	.interrupt	= xtkbd_interrupt,
 	.connect	= xtkbd_connect,
 	.disconnect	= xtkbd_disconnect,
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/mouse/psmouse-base.c	2004-12-29 01:52:53 -05:00
@@ -652,7 +652,7 @@
 	psmouse = serio_get_drvdata(serio);
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 
-	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		if (parent->pt_deactivate)
 			parent->pt_deactivate(parent);
@@ -677,15 +677,11 @@
 {
 	struct psmouse *psmouse, *parent = NULL;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
-	    (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
-		return;
-
 	/*
 	 * If this is a pass-through port deactivate parent so the device
 	 * connected to this port can be successfully identified
 	 */
-	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
@@ -785,7 +781,7 @@
 		return -1;
 	}
 
-	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
@@ -820,12 +816,28 @@
 	return rc;
 }
 
+static struct serio_id psmouse_serio_ids[] = {
+	{
+		.type	= SERIO_8042,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{
+		.type	= SERIO_PS_PSTHRU,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
 
 static struct serio_driver psmouse_drv = {
 	.driver		= {
 		.name	= "psmouse",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= psmouse_serio_ids,
 	.interrupt	= psmouse_interrupt,
 	.connect	= psmouse_connect,
 	.reconnect	= psmouse_reconnect,
@@ -872,7 +884,7 @@
 		goto out;
 	}
 
-	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/mouse/sermouse.c	2004-12-29 01:52:53 -05:00
@@ -246,10 +246,7 @@
 	struct sermouse *sermouse;
 	unsigned char c;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_RS232)
-		return;
-
-	if (!(serio->type & SERIO_PROTO) || ((serio->type & SERIO_PROTO) > SERIO_MZPP))
+	if (!serio->id.proto || serio->id.proto > SERIO_MZPP)
 		return;
 
 	if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL)))
@@ -263,8 +260,8 @@
 	sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
 	sermouse->dev.private = sermouse;
 
-	sermouse->type = serio->type & SERIO_PROTO;
-	c = (serio->type & SERIO_EXTRA) >> 16;
+	sermouse->type = serio->id.proto;
+	c = serio->id.extra;
 
 	if (c & 0x01) set_bit(BTN_MIDDLE, sermouse->dev.keybit);
 	if (c & 0x02) set_bit(BTN_SIDE, sermouse->dev.keybit);
@@ -295,11 +292,22 @@
 	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
 }
 
+static struct serio_id sermouse_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver sermouse_drv = {
 	.driver		= {
 		.name	= "sermouse",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= sermouse_serio_ids,
 	.interrupt	= sermouse_interrupt,
 	.connect	= sermouse_connect,
 	.disconnect	= sermouse_disconnect,
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/mouse/synaptics.c	2004-12-29 01:52:53 -05:00
@@ -288,7 +288,7 @@
 
 	memset(serio, 0, sizeof(struct serio));
 
-	serio->type = SERIO_PS_PSTHRU;
+	serio->id.type = SERIO_PS_PSTHRU;
 	strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
 	strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
 	serio->write = synaptics_pt_write;
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/mouse/vsxxxaa.c	2004-12-29 01:52:53 -05:00
@@ -494,11 +494,6 @@
 {
 	struct vsxxxaa *mouse;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_RS232)
-		return;
-	if ((serio->type & SERIO_PROTO) != SERIO_VSXXXAA)
-		return;
-
 	if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
 		return;
 
@@ -551,11 +546,22 @@
 	printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
 }
 
+static struct serio_id vsxxaa_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_VSXXXAA,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver vsxxxaa_drv = {
 	.driver		= {
 		.name	= "vsxxxaa",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= vsxxaa_serio_ids,
 	.connect	= vsxxxaa_connect,
 	.interrupt	= vsxxxaa_interrupt,
 	.disconnect	= vsxxxaa_disconnect,
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/ambakmi.c	2004-12-29 01:52:53 -05:00
@@ -134,7 +134,7 @@
 	memset(kmi, 0, sizeof(struct amba_kmi_port));
 	memset(io, 0, sizeof(struct serio));
 
-	io->type	= SERIO_8042;
+	io->id.type	= SERIO_8042;
 	io->write	= amba_kmi_write;
 	io->open	= amba_kmi_open;
 	io->close	= amba_kmi_close;
diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
--- a/drivers/input/serio/ct82c710.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/ct82c710.c	2004-12-29 01:52:53 -05:00
@@ -181,7 +181,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type = SERIO_8042;
+		serio->id.type = SERIO_8042;
 		serio->open = ct82c710_open;
 		serio->close = ct82c710_close;
 		serio->write = ct82c710_write;
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/gscps2.c	2004-12-29 01:52:53 -05:00
@@ -363,11 +363,7 @@
 	snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
 		 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
 	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
-	serio->idbus		= BUS_GSC;
-	serio->idvendor		= PCI_VENDOR_ID_HP;
-	serio->idproduct	= 0x0001;
-	serio->idversion	= 0x0010;
-	serio->type		= SERIO_8042;
+	serio->id.type		= SERIO_8042;
 	serio->write		= gscps2_write;
 	serio->open		= gscps2_open;
 	serio->close		= gscps2_close;
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/i8042.c	2004-12-29 01:52:53 -05:00
@@ -960,7 +960,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type		= i8042_direct ? SERIO_8042 : SERIO_8042_XL,
+		serio->id.type		= i8042_direct ? SERIO_8042 : SERIO_8042_XL,
 		serio->write		= i8042_dumbkbd ? NULL : i8042_kbd_write,
 		serio->open		= i8042_open,
 		serio->close		= i8042_close,
@@ -984,7 +984,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type		= SERIO_8042;
+		serio->id.type		= SERIO_8042;
 		serio->write		= i8042_aux_write;
 		serio->open		= i8042_open;
 		serio->close		= i8042_close;
@@ -1008,7 +1008,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type		= SERIO_8042;
+		serio->id.type		= SERIO_8042;
 		serio->write		= i8042_aux_write;
 		serio->open		= i8042_open;
 		serio->close		= i8042_close;
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/maceps2.c	2004-12-29 01:52:53 -05:00
@@ -125,7 +125,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type		= SERIO_8042;
+		serio->id.type		= SERIO_8042;
 		serio->write		= maceps2_write;
 		serio->open		= maceps2_open;
 		serio->close		= maceps2_close;
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/parkbd.c	2004-12-29 01:52:53 -05:00
@@ -158,7 +158,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type = parkbd_mode;
+		serio->id.type = parkbd_mode;
 		serio->write = parkbd_write,
 		strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
 		snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/pcips2.c	2004-12-29 01:52:53 -05:00
@@ -150,7 +150,7 @@
 	memset(ps2if, 0, sizeof(struct pcips2_data));
 	memset(serio, 0, sizeof(struct serio));
 
-	serio->type		= SERIO_8042;
+	serio->id.type		= SERIO_8042;
 	serio->write		= pcips2_write;
 	serio->open		= pcips2_open;
 	serio->close		= pcips2_close;
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/q40kbd.c	2004-12-29 01:52:53 -05:00
@@ -122,7 +122,7 @@
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 		memset(serio, 0, sizeof(struct serio));
-		serio->type		= SERIO_8042;
+		serio->id.type		= SERIO_8042;
 		serio->open		= q40kbd_open;
 		serio->close		= q40kbd_close;
 		serio->dev.parent	= &q40kbd_device->dev;
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
--- a/drivers/input/serio/rpckbd.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/rpckbd.c	2004-12-29 01:52:53 -05:00
@@ -115,7 +115,7 @@
 		return -ENOMEM;
 
 	memset(serio, 0, sizeof(struct serio));
-	serio->type		= SERIO_8042;
+	serio->id.type		= SERIO_8042;
 	serio->write		= rpckbd_write;
 	serio->open		= rpckbd_open;
 	serio->close		= rpckbd_close;
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/sa1111ps2.c	2004-12-29 01:52:53 -05:00
@@ -245,7 +245,7 @@
 	memset(ps2if, 0, sizeof(struct ps2if));
 	memset(serio, 0, sizeof(struct serio));
 
-	serio->type		= SERIO_8042;
+	serio->id.type		= SERIO_8042;
 	serio->write		= ps2_write;
 	serio->open		= ps2_open;
 	serio->close		= ps2_close;
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/serio.c	2004-12-29 01:52:53 -05:00
@@ -69,17 +69,33 @@
 static void serio_reconnect_port(struct serio *serio);
 static void serio_disconnect_port(struct serio *serio);
 
+static int serio_match_port(const struct serio_id *ids, struct serio *serio)
+{
+	while (ids->type || ids->proto) {
+		if ((ids->type == SERIO_ANY || ids->type == serio->id.type) &&
+		    (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) &&
+		    (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) &&
+		    (ids->id == SERIO_ANY || ids->id == serio->id.id))
+			return 1;
+		ids++;
+	}
+	return 0;
+}
+
 static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
 {
 	get_driver(&drv->driver);
 
-	drv->connect(serio, drv);
-	if (serio->drv) {
-		down_write(&serio_bus.subsys.rwsem);
-		serio->dev.driver = &drv->driver;
-		device_bind_driver(&serio->dev);
-		up_write(&serio_bus.subsys.rwsem);
-		return 1;
+	if (serio_match_port(drv->ids, serio)) {
+		drv->connect(serio, drv);
+
+		if (serio->drv) {
+			down_write(&serio_bus.subsys.rwsem);
+			serio->dev.driver = &drv->driver;
+			device_bind_driver(&serio->dev);
+			up_write(&serio_bus.subsys.rwsem);
+			return 1;
+		}
 	}
 
 	put_driver(&drv->driver);
diff -Nru a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- a/drivers/input/serio/serio_raw.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/serio_raw.c	2004-12-29 01:52:53 -05:00
@@ -275,9 +275,6 @@
 	struct serio_raw *serio_raw;
 	int err;
 
-	if ((serio->type & SERIO_TYPE) != SERIO_8042)
-		return;
-
 	if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) {
 		printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n");
 		return;
@@ -363,11 +360,22 @@
 	up(&serio_raw_sem);
 }
 
+static struct serio_id serio_raw_serio_ids[] = {
+	{
+		.type	= SERIO_8042,
+		.proto	= SERIO_ANY,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver serio_raw_drv = {
 	.driver		= {
 		.name	= "serio_raw",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= serio_raw_serio_ids,
 	.interrupt	= serio_raw_interrupt,
 	.connect	= serio_raw_connect,
 	.reconnect	= serio_raw_reconnect,
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/serio/serport.c	2004-12-29 01:52:53 -05:00
@@ -49,7 +49,7 @@
 {
 	struct serport *serport = serio->port_data;
 
-	serport->serio->type = 0;
+	serport->serio->id.type = 0;
 	wake_up_interruptible(&serport->wait);
 }
 
@@ -81,7 +81,7 @@
 	memset(serio, 0, sizeof(struct serio));
 	strlcpy(serio->name, "Serial port", sizeof(serio->name));
 	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name));
-	serio->type = SERIO_RS232;
+	serio->id.type = SERIO_RS232;
 	serio->write = serport_serio_write;
 	serio->close = serport_serio_close;
 	serio->port_data = serport;
@@ -145,7 +145,7 @@
 
 	serio_register_port(serport->serio);
 	printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name));
-	wait_event_interruptible(serport->wait, !serport->serio->type);
+	wait_event_interruptible(serport->wait, !serport->serio->id.type);
 	serio_unregister_port(serport->serio);
 
 	clear_bit(SERPORT_BUSY, &serport->flags);
@@ -160,9 +160,17 @@
 static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
 	struct serport *serport = (struct serport*) tty->disc_data;
+	struct serio *serio = serport->serio;
+	unsigned long type;
 
-	if (cmd == SPIOCSTYPE)
-		return get_user(serport->serio->type, (unsigned long __user *) arg);
+	if (cmd == SPIOCSTYPE) {
+		if (get_user(type, (unsigned long __user *) arg))
+			return -EFAULT;
+
+		serio->id.proto	= type & 0x000000ff;
+		serio->id.id	= (type & 0x0000ff00) >> 8;
+		serio->id.extra	= (type & 0x00ff0000) >> 16;
+	}
 
 	return -EINVAL;
 }
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/touchscreen/gunze.c	2004-12-29 01:52:53 -05:00
@@ -111,17 +111,14 @@
 
 /*
  * gunze_connect() is the routine that is called when someone adds a
- * new serio device. It looks whether it was registered as a Gunze touchscreen
- * and if yes, registers it as an input device.
+ * new serio device that supports Gunze protocol and registers it as
+ * an input device.
  */
 
 static void gunze_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct gunze *gunze;
 
-	if (serio->type != (SERIO_RS232 | SERIO_GUNZE))
-		return;
-
 	if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
 		return;
 
@@ -159,14 +156,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id gunze_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_GUNZE,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver gunze_drv = {
 	.driver		= {
 		.name	= "gunze",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= gunze_serio_ids,
 	.interrupt	= gunze_interrupt,
 	.connect	= gunze_connect,
 	.disconnect	= gunze_disconnect,
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 01:52:53 -05:00
@@ -102,6 +102,7 @@
 	struct input_dev dev;
 	struct pm_dev *pm_dev;
 	struct serio *serio;
+	struct pm_dev *pm_dev;
 	unsigned char event;	/* event ID from packet */
 	unsigned char chksum;
 	unsigned char len;
@@ -373,16 +374,13 @@
 
 /*
  * h3600ts_connect() is the routine that is called when someone adds a
- * new serio device. It looks whether it was registered as a H3600 touchscreen
- * and if yes, registers it as an input device.
+ * new serio device that supports H3600 protocol and registers it as
+ * an input device.
  */
 static void h3600ts_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct h3600_dev *ts;
 
-	if (serio->type != (SERIO_RS232 | SERIO_H3600))
-		return;
-
 	if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL)))
 		return;
 
@@ -481,14 +479,25 @@
 }
 
 /*
- * The serio device structure.
+ * The serio driver structure.
  */
 
+static struct serio_id h3600ts_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_H3600,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
 static struct serio_driver h3600ts_drv = {
 	.driver		= {
 		.name	= "h3600ts",
 	},
 	.description	= DRIVER_DESC,
+	.ids		= h3600ts_serio_ids,
 	.interrupt	= h3600ts_interrupt,
 	.connect	= h3600ts_connect,
 	.disconnect	= h3600ts_disconnect,
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/serial/sunsu.c	2004-12-29 01:52:53 -05:00
@@ -1312,12 +1312,13 @@
 
 		serio->port_data = up;
 
-		serio->type = SERIO_RS232;
+		serio->id.type = SERIO_RS232;
 		if (up->su_type == SU_PORT_KBD) {
-			serio->type |= SERIO_SUNKBD;
+			serio->id.proto = SERIO_SUNKBD;
 			strlcpy(serio->name, "sukbd", sizeof(serio->name));
 		} else {
-			serio->type |= (SERIO_SUN | (1 << 16));
+			serio->id.proto = SERIO_SUN;
+			serio->id.extra = 1;
 			strlcpy(serio->name, "sums", sizeof(serio->name));
 		}
 		strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	2004-12-29 01:52:53 -05:00
+++ b/drivers/serial/sunzilog.c	2004-12-29 01:52:53 -05:00
@@ -1562,12 +1562,13 @@
 
 		serio->port_data = up;
 
-		serio->type = SERIO_RS232;
+		serio->id.type = SERIO_RS232;
 		if (channel == KEYBOARD_LINE) {
-			serio->type |= SERIO_SUNKBD;
+			serio->id.proto = SERIO_SUNKBD;
 			strlcpy(serio->name, "zskbd", sizeof(serio->name));
 		} else {
-			serio->type |= (SERIO_SUN | (1 << 16));
+			serio->id.proto = SERIO_SUN;
+			serio->id.extra = 1;
 			strlcpy(serio->name, "zsms", sizeof(serio->name));
 		}
 		strlcpy(serio->phys,
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-12-29 01:52:53 -05:00
+++ b/include/linux/serio.h	2004-12-29 01:52:53 -05:00
@@ -20,6 +20,13 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
+struct serio_id {
+	unsigned char type;
+	unsigned char extra;
+	unsigned char id;
+	unsigned char proto;
+};
+
 struct serio {
 	void *port_data;
 
@@ -28,13 +35,7 @@
 
 	unsigned int manual_bind;
 
-	unsigned short idbus;
-	unsigned short idvendor;
-	unsigned short idproduct;
-	unsigned short idversion;
-
-	unsigned long type;
-	unsigned long event;
+	struct serio_id id;
 
 	spinlock_t lock;		/* protects critical sections from port's interrupt handler */
 
@@ -59,6 +60,7 @@
 	void *private;
 	char *description;
 
+	struct serio_id *ids;
 	unsigned int manual_bind;
 
 	void (*write_wakeup)(struct serio *);
@@ -160,15 +162,22 @@
 #define SERIO_PARITY	2
 #define SERIO_FRAME	4
 
-#define SERIO_TYPE	0xff000000UL
-#define SERIO_XT	0x00000000UL
-#define SERIO_8042	0x01000000UL
-#define SERIO_RS232	0x02000000UL
-#define SERIO_HIL_MLC	0x03000000UL
-#define SERIO_PS_PSTHRU	0x05000000UL
-#define SERIO_8042_XL	0x06000000UL
+#define SERIO_ANY	0xff
 
-#define SERIO_PROTO	0xFFUL
+/*
+ * Serio types
+ */
+#define SERIO_XT	0x00
+#define SERIO_8042	0x01
+#define SERIO_RS232	0x02
+#define SERIO_HIL_MLC	0x03
+#define SERIO_PS_PSTHRU	0x05
+#define SERIO_8042_XL	0x06
+
+/*
+ * Serio types
+ */
+#define SERIO_UNKNOWN	0x00
 #define SERIO_MSC	0x01
 #define SERIO_SUN	0x02
 #define SERIO_MS	0x03
@@ -195,8 +204,5 @@
 #define SERIO_SNES232	0x26
 #define SERIO_SEMTECH	0x27
 #define SERIO_LKKBD	0x28
-
-#define SERIO_ID	0xff00UL
-#define SERIO_EXTRA	0xff0000UL
 
 #endif

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 15/16] serio bus implementation cleanup
  2004-12-29  7:31                           ` [PATCH 14/16] Introduce serio_id to match ports and drivers Dmitry Torokhov
@ 2004-12-29  7:32                             ` Dmitry Torokhov
  2004-12-29  7:33                               ` [PATCH 16/16] serio connect methods should return error codes Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:32 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1975, 2004-12-28 01:24:56-05:00, dtor_core@ameritech.net
  Input: make serio implementation more in line with standard
         driver model implementations. serio_register_port is
         always asynchronous to allow freely registering child
         ports. When deregistering serio core still takes care
         of destroying children ports first.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  


 drivers/input/mouse/psmouse-base.c |   11 -
 drivers/input/mouse/synaptics.c    |   10 -
 drivers/input/serio/serio.c        |  363 ++++++++++++++++++++-----------------
 include/linux/serio.h              |   17 +
 4 files changed, 219 insertions(+), 182 deletions(-)


===================================================================



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2004-12-29 01:53:31 -05:00
+++ b/drivers/input/mouse/psmouse-base.c	2004-12-29 01:53:31 -05:00
@@ -692,6 +692,7 @@
 	memset(psmouse, 0, sizeof(struct psmouse));
 
 	ps2_init(&psmouse->ps2dev, serio);
+	sprintf(psmouse->phys, "%s/input0", serio->phys);
 	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
 	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
@@ -727,8 +728,6 @@
 
 	sprintf(psmouse->devname, "%s %s %s",
 		psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
-	sprintf(psmouse->phys, "%s/input0",
-		serio->phys);
 
 	psmouse->dev.name = psmouse->devname;
 	psmouse->dev.phys = psmouse->phys;
@@ -751,14 +750,6 @@
 	device_create_file(&serio->dev, &psmouse_attr_rate);
 	device_create_file(&serio->dev, &psmouse_attr_resolution);
 	device_create_file(&serio->dev, &psmouse_attr_resetafter);
-
-	if (serio->child) {
-		/*
-		 * Nothing to be done here, serio core will detect that
-		 * the driver set serio->child and will register it for us.
-		 */
-		printk(KERN_INFO "serio: %s port at %s\n", serio->child->name, psmouse->phys);
-	}
 
 	psmouse_activate(psmouse);
 
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	2004-12-29 01:53:31 -05:00
+++ b/drivers/input/mouse/synaptics.c	2004-12-29 01:53:31 -05:00
@@ -296,7 +296,8 @@
 
 	psmouse->pt_activate = synaptics_pt_activate;
 
-	psmouse->ps2dev.serio->child = serio;
+	printk(KERN_INFO "serio: %s port at %s\n", serio->name, psmouse->phys);
+	serio_register_port(serio);
 }
 
 /*****************************************************************************
@@ -552,6 +553,7 @@
 {
 	synaptics_reset(psmouse);
 	kfree(psmouse->private);
+	psmouse->private = NULL;
 }
 
 static int synaptics_reconnect(struct psmouse *psmouse)
@@ -640,9 +642,6 @@
 
 	priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
 
-	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
-		synaptics_pt_create(psmouse);
-
 	print_ident(priv);
 	set_input_params(&psmouse->dev, priv);
 
@@ -651,6 +650,9 @@
 	psmouse->disconnect = synaptics_disconnect;
 	psmouse->reconnect = synaptics_reconnect;
 	psmouse->pktsize = 6;
+
+	if (SYN_CAP_PASS_THROUGH(priv->capabilities))
+		synaptics_pt_create(psmouse);
 
 #if defined(__i386__)
 	/*
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-12-29 01:53:31 -05:00
+++ b/drivers/input/serio/serio.c	2004-12-29 01:53:31 -05:00
@@ -42,10 +42,9 @@
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(serio_interrupt);
-EXPORT_SYMBOL(serio_register_port);
-EXPORT_SYMBOL(serio_register_port_delayed);
+EXPORT_SYMBOL(__serio_register_port);
 EXPORT_SYMBOL(serio_unregister_port);
-EXPORT_SYMBOL(serio_unregister_port_delayed);
+EXPORT_SYMBOL(__serio_unregister_port_delayed);
 EXPORT_SYMBOL(serio_register_driver);
 EXPORT_SYMBOL(serio_unregister_driver);
 EXPORT_SYMBOL(serio_open);
@@ -53,19 +52,20 @@
 EXPORT_SYMBOL(serio_rescan);
 EXPORT_SYMBOL(serio_reconnect);
 
-static DECLARE_MUTEX(serio_sem);	/* protects serio_list and serio_diriver_list */
+/*
+ * serio_sem protects entire serio subsystem and is taken every time
+ * serio port or driver registrered or unregistered.
+ */
+static DECLARE_MUTEX(serio_sem);
+
 static LIST_HEAD(serio_list);
-static LIST_HEAD(serio_driver_list);
-static unsigned int serio_no;
 
 struct bus_type serio_bus = {
 	.name =	"serio",
 };
 
-static void serio_find_driver(struct serio *serio);
-static void serio_create_port(struct serio *serio);
+static void serio_add_port(struct serio *serio);
 static void serio_destroy_port(struct serio *serio);
-static void serio_connect_port(struct serio *serio, struct serio_driver *drv);
 static void serio_reconnect_port(struct serio *serio);
 static void serio_disconnect_port(struct serio *serio);
 
@@ -82,37 +82,42 @@
 	return 0;
 }
 
-static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
+/*
+ * Basic serio -> driver core mappings
+ */
+
+static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
 {
-	get_driver(&drv->driver);
+	down_write(&serio_bus.subsys.rwsem);
 
 	if (serio_match_port(drv->ids, serio)) {
+		serio->dev.driver = &drv->driver;
 		drv->connect(serio, drv);
-
-		if (serio->drv) {
-			down_write(&serio_bus.subsys.rwsem);
-			serio->dev.driver = &drv->driver;
-			device_bind_driver(&serio->dev);
-			up_write(&serio_bus.subsys.rwsem);
-			return 1;
+		if (!serio->drv) {
+			serio->dev.driver = NULL;
+			goto out;
 		}
+		device_bind_driver(&serio->dev);
 	}
+out:
+	up_write(&serio_bus.subsys.rwsem);
+}
 
-	put_driver(&drv->driver);
-	return 0;
+static void serio_release_driver(struct serio *serio)
+{
+	down_write(&serio_bus.subsys.rwsem);
+	device_release_driver(&serio->dev);
+	up_write(&serio_bus.subsys.rwsem);
 }
 
-/* serio_find_driver() must be called with serio_sem down.  */
 static void serio_find_driver(struct serio *serio)
 {
-	struct serio_driver *drv;
-
-	list_for_each_entry(drv, &serio_driver_list, node)
-		if (!drv->manual_bind)
-			if (serio_bind_driver(serio, drv))
-				break;
+	down_write(&serio_bus.subsys.rwsem);
+	device_attach(&serio->dev);
+	up_write(&serio_bus.subsys.rwsem);
 }
 
+
 /*
  * Serio event processing.
  */
@@ -120,6 +125,7 @@
 struct serio_event {
 	int type;
 	struct serio *serio;
+	struct module *owner;
 	struct list_head node;
 };
 
@@ -136,7 +142,8 @@
 static DECLARE_COMPLETION(serio_exited);
 static int serio_pid;
 
-static void serio_queue_event(struct serio *serio, enum serio_event_type event_type)
+static void serio_queue_event(struct serio *serio, struct module *owner,
+			      enum serio_event_type event_type)
 {
 	unsigned long flags;
 	struct serio_event *event;
@@ -159,17 +166,30 @@
 	}
 
 	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
+		if (!try_module_get(owner)) {
+			printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
+			goto out;
+		}
+
 		event->type = event_type;
 		event->serio = serio;
+		event->owner = owner;
 
 		list_add_tail(&event->node, &serio_event_list);
 		wake_up(&serio_wait);
+	} else {
+		printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type);
 	}
-
 out:
 	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
+static void serio_free_event(struct serio_event *event)
+{
+	module_put(event->owner);
+	kfree(event);
+}
+
 static void serio_remove_duplicate_events(struct serio_event *event)
 {
 	struct list_head *node, *next;
@@ -179,7 +199,7 @@
 	spin_lock_irqsave(&serio_event_lock, flags);
 
 	list_for_each_safe(node, next, &serio_event_list) {
-		e = container_of(node, struct serio_event, node);
+		e = list_entry(node, struct serio_event, node);
 		if (event->serio == e->serio) {
 			/*
 			 * If this event is of different type we should not
@@ -187,9 +207,10 @@
 			 * that were sent back-to-back.
 			 */
 			if (event->type != e->type)
-				break;	/* Stop, when need to preserve event flow */
+				break;
+
 			list_del_init(node);
-			kfree(e);
+			serio_free_event(e);
 		}
 	}
 
@@ -211,7 +232,7 @@
 	}
 
 	node = serio_event_list.next;
-	event = container_of(node, struct serio_event, node);
+	event = list_entry(node, struct serio_event, node);
 	list_del_init(node);
 
 	spin_unlock_irqrestore(&serio_event_lock, flags);
@@ -223,39 +244,44 @@
 {
 	struct serio_event *event;
 
-	while ((event = serio_get_event())) {
+	down(&serio_sem);
 
-		down(&serio_sem);
+	while ((event = serio_get_event())) {
 
 		switch (event->type) {
-			case SERIO_REGISTER_PORT :
-				serio_create_port(event->serio);
-				serio_connect_port(event->serio, NULL);
+			case SERIO_REGISTER_PORT:
+				serio_add_port(event->serio);
+				serio_find_driver(event->serio);
 				break;
 
-			case SERIO_UNREGISTER_PORT :
+			case SERIO_UNREGISTER_PORT:
 				serio_disconnect_port(event->serio);
 				serio_destroy_port(event->serio);
 				break;
 
-			case SERIO_RECONNECT :
+			case SERIO_RECONNECT:
 				serio_reconnect_port(event->serio);
 				break;
 
-			case SERIO_RESCAN :
+			case SERIO_RESCAN:
 				serio_disconnect_port(event->serio);
-				serio_connect_port(event->serio, NULL);
+				serio_find_driver(event->serio);
 				break;
+
 			default:
 				break;
 		}
 
-		up(&serio_sem);
 		serio_remove_duplicate_events(event);
-		kfree(event);
+		serio_free_event(event);
 	}
+
+	up(&serio_sem);
 }
 
+/*
+ * Remove all events that have been submitted for a given serio port.
+ */
 static void serio_remove_pending_events(struct serio *serio)
 {
 	struct list_head *node, *next;
@@ -265,16 +291,42 @@
 	spin_lock_irqsave(&serio_event_lock, flags);
 
 	list_for_each_safe(node, next, &serio_event_list) {
-		event = container_of(node, struct serio_event, node);
+		event = list_entry(node, struct serio_event, node);
 		if (event->serio == serio) {
 			list_del_init(node);
-			kfree(event);
+			serio_free_event(event);
 		}
 	}
 
 	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
+/*
+ * Destroy child serio port (if any) that has not been fully registered yet.
+ *
+ * Note that we rely on the fact that port can have only one child and therefore
+ * only one child registration request can be pending. Additionally, children
+ * are registered by driver's connect() handler so there can't be a grandchild
+ * pending registration together with a child.
+ */
+static struct serio *serio_get_pending_child(struct serio *parent)
+{
+	struct serio_event *event;
+	struct serio *serio = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	list_for_each_entry(event, &serio_event_list, node) {
+		if (event->type == SERIO_REGISTER_PORT && event->serio->parent == parent) {
+			serio = event->serio;
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
+	return serio;
+}
 
 static int serio_thread(void *nothing)
 {
@@ -323,10 +375,10 @@
 		serio_reconnect_port(serio);
 	} else if (!strncmp(buf, "rescan", count)) {
 		serio_disconnect_port(serio);
-		serio_connect_port(serio, NULL);
+		serio_find_driver(serio);
 	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
 		serio_disconnect_port(serio);
-		serio_connect_port(serio, to_serio_driver(drv));
+		serio_bind_driver(serio, to_serio_driver(drv));
 		put_driver(drv);
 	} else {
 		retval = -EINVAL;
@@ -376,22 +428,43 @@
 	module_put(THIS_MODULE);
 }
 
-static void serio_create_port(struct serio *serio)
+/*
+ * Prepare serio port for registration.
+ */
+static void serio_init_port(struct serio *serio)
 {
-	try_module_get(THIS_MODULE);
+	static atomic_t serio_no = ATOMIC_INIT(0);
+
+	__module_get(THIS_MODULE);
 
 	spin_lock_init(&serio->lock);
 	init_MUTEX(&serio->drv_sem);
-	list_add_tail(&serio->node, &serio_list);
-	snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++);
+	device_initialize(&serio->dev);
+	snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id),
+		 "serio%d", atomic_inc_return(&serio_no) - 1);
 	serio->dev.bus = &serio_bus;
 	serio->dev.release = serio_release_port;
 	if (serio->parent)
 		serio->dev.parent = &serio->parent->dev;
-	device_initialize(&serio->dev);
+}
+
+/*
+ * Complete serio port registration.
+ * Driver core will attempt to find appropriate driver for the port.
+ */
+static void serio_add_port(struct serio *serio)
+{
+	if (serio->parent) {
+		serio_pause_rx(serio->parent);
+		serio->parent->child = serio;
+		serio_continue_rx(serio->parent);
+	}
+
+	list_add_tail(&serio->node, &serio_list);
 	if (serio->start)
 		serio->start(serio);
 	device_add(&serio->dev);
+	serio->registered = 1;
 }
 
 /*
@@ -400,77 +473,43 @@
  */
 static void serio_destroy_port(struct serio *serio)
 {
-	struct serio_driver *drv = serio->drv;
-	unsigned long flags;
+	struct serio *child;
 
-	serio_remove_pending_events(serio);
-	list_del_init(&serio->node);
-
-	if (drv) {
-		drv->disconnect(serio);
-		down_write(&serio_bus.subsys.rwsem);
-		device_release_driver(&serio->dev);
-		up_write(&serio_bus.subsys.rwsem);
-		put_driver(&drv->driver);
+	child = serio_get_pending_child(serio);
+	if (child) {
+		serio_remove_pending_events(child);
+		put_device(&child->dev);
 	}
 
 	if (serio->stop)
 		serio->stop(serio);
 
 	if (serio->parent) {
-		spin_lock_irqsave(&serio->parent->lock, flags);
+		serio_pause_rx(serio->parent);
 		serio->parent->child = NULL;
-		spin_unlock_irqrestore(&serio->parent->lock, flags);
+		serio->parent = NULL;
+		serio_continue_rx(serio->parent);
 	}
 
-	device_unregister(&serio->dev);
-}
-
-/*
- * serio_connect_port() tries to bind the port and possible all its
- * children to appropriate drivers. If driver passed in the function will not
- * try otehr drivers when binding parent port.
- */
-static void serio_connect_port(struct serio *serio, struct serio_driver *drv)
-{
-	WARN_ON(serio->drv);
-	WARN_ON(serio->child);
-
-	if (drv)
-		serio_bind_driver(serio, drv);
-	else if (!serio->manual_bind)
-		serio_find_driver(serio);
-
-	/* Ok, now bind children, if any */
-	while (serio->child) {
-		serio = serio->child;
-
-		WARN_ON(serio->drv);
-		WARN_ON(serio->child);
-
-		serio_create_port(serio);
-
-		if (!serio->manual_bind) {
-			/*
-			 * With children we just _prefer_ passed in driver,
-			 * but we will try other options in case preferred
-			 * is not the one
-			 */
-			if (!drv || !serio_bind_driver(serio, drv))
-				serio_find_driver(serio);
-		}
+	if (serio->registered) {
+		device_del(&serio->dev);
+		list_del_init(&serio->node);
+		serio->registered = 0;
 	}
+
+	serio_remove_pending_events(serio);
+	put_device(&serio->dev);
 }
 
 /*
- *
+ * Reconnect serio port and all its children (re-initialize attached devices)
  */
 static void serio_reconnect_port(struct serio *serio)
 {
 	do {
 		if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
 			serio_disconnect_port(serio);
-			serio_connect_port(serio, NULL);
+			serio_find_driver(serio);
 			/* Ok, old children are now gone, we are done */
 			break;
 		}
@@ -484,8 +523,7 @@
  */
 static void serio_disconnect_port(struct serio *serio)
 {
-	struct serio_driver *drv = serio->drv;
-	struct serio *s;
+	struct serio *s, *parent;
 
 	if (serio->child) {
 		/*
@@ -493,56 +531,46 @@
 		 * first, staring with the leaf one, since we don't want
 		 * to do recursion
 		 */
+		for (s = serio; s->child; s = s->child)
+			/* empty */;
+
 		do {
-			s = serio->child;
-		} while (s->child);
+			parent = s->parent;
 
-		while (s != serio) {
-			s = s->parent;
-			serio_destroy_port(s->child);
-		}
+			serio_release_driver(s);
+			serio_destroy_port(s);
+		} while ((s = parent) != serio);
 	}
 
 	/*
 	 * Ok, no children left, now disconnect this port
 	 */
-	if (drv) {
-		drv->disconnect(serio);
-		down_write(&serio_bus.subsys.rwsem);
-		device_release_driver(&serio->dev);
-		up_write(&serio_bus.subsys.rwsem);
-		put_driver(&drv->driver);
-	}
+	serio_release_driver(serio);
 }
 
 void serio_rescan(struct serio *serio)
 {
-	serio_queue_event(serio, SERIO_RESCAN);
+	serio_queue_event(serio, NULL, SERIO_RESCAN);
 }
 
 void serio_reconnect(struct serio *serio)
 {
-	serio_queue_event(serio, SERIO_RECONNECT);
-}
-
-void serio_register_port(struct serio *serio)
-{
-	down(&serio_sem);
-	serio_create_port(serio);
-	serio_connect_port(serio, NULL);
-	up(&serio_sem);
+	serio_queue_event(serio, NULL, SERIO_RECONNECT);
 }
 
 /*
  * Submits register request to kseriod for subsequent execution.
- * Can be used when it is not obvious whether the serio_sem is
- * taken or not and when delayed execution is feasible.
+ * Note that port registration is always asynchronous.
  */
-void serio_register_port_delayed(struct serio *serio)
+void __serio_register_port(struct serio *serio, struct module *owner)
 {
-	serio_queue_event(serio, SERIO_REGISTER_PORT);
+	serio_init_port(serio);
+	serio_queue_event(serio, owner, SERIO_REGISTER_PORT);
 }
 
+/*
+ * Synchronously unregisters serio port.
+ */
 void serio_unregister_port(struct serio *serio)
 {
 	down(&serio_sem);
@@ -552,13 +580,13 @@
 }
 
 /*
- * Submits unregister request to kseriod for subsequent execution.
+ * Submits register request to kseriod for subsequent execution.
  * Can be used when it is not obvious whether the serio_sem is
  * taken or not and when delayed execution is feasible.
  */
-void serio_unregister_port_delayed(struct serio *serio)
+void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
 {
-	serio_queue_event(serio, SERIO_UNREGISTER_PORT);
+	serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT);
 }
 
 
@@ -603,34 +631,33 @@
 	__ATTR_NULL
 };
 
-void serio_register_driver(struct serio_driver *drv)
+static int serio_driver_probe(struct device *dev)
 {
-	struct serio *serio;
+	struct serio *serio = to_serio_port(dev);
+	struct serio_driver *drv = to_serio_driver(dev->driver);
 
-	down(&serio_sem);
+	drv->connect(serio, drv);
+	return serio->drv ? 0 : -ENODEV;
+}
 
-	list_add_tail(&drv->node, &serio_driver_list);
+static int serio_driver_remove(struct device *dev)
+{
+	struct serio *serio = to_serio_port(dev);
+	struct serio_driver *drv = to_serio_driver(dev->driver);
 
-	drv->driver.bus = &serio_bus;
-	driver_register(&drv->driver);
+	drv->disconnect(serio);
+	return 0;
+}
 
-	if (drv->manual_bind)
-		goto out;
+void serio_register_driver(struct serio_driver *drv)
+{
+	down(&serio_sem);
 
-start_over:
-	list_for_each_entry(serio, &serio_list, node) {
-		if (!serio->drv) {
-			serio_connect_port(serio, drv);
-			/*
-			 * if new child appeared then the list is changed,
-			 * we need to start over
-			 */
-			if (serio->child)
-				goto start_over;
-		}
-	}
+	drv->driver.bus = &serio_bus;
+	drv->driver.probe = serio_driver_probe;
+	drv->driver.remove = serio_driver_remove;
+	driver_register(&drv->driver);
 
-out:
 	up(&serio_sem);
 }
 
@@ -639,21 +666,19 @@
 	struct serio *serio;
 
 	down(&serio_sem);
-
-	list_del_init(&drv->node);
+	drv->manual_bind = 1;	/* so serio_find_driver ignores it */
 
 start_over:
 	list_for_each_entry(serio, &serio_list, node) {
 		if (serio->drv == drv) {
 			serio_disconnect_port(serio);
-			serio_connect_port(serio, NULL);
+			serio_find_driver(serio);
 			/* we could've deleted some ports, restart */
 			goto start_over;
 		}
 	}
 
 	driver_unregister(&drv->driver);
-
 	up(&serio_sem);
 }
 
@@ -666,6 +691,17 @@
 	up(&serio->drv_sem);
 }
 
+static int serio_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct serio *serio = to_serio_port(dev);
+	struct serio_driver *serio_drv = to_serio_driver(drv);
+
+	if (serio->manual_bind || serio_drv->manual_bind)
+		return 0;
+
+	return serio_match_port(serio_drv->ids, serio);
+}
+
 /* called from serio_driver->connect/disconnect methods under serio_sem */
 int serio_open(struct serio *serio, struct serio_driver *drv)
 {
@@ -697,7 +733,7 @@
 
         if (likely(serio->drv)) {
                 ret = serio->drv->interrupt(serio, data, dfl, regs);
-	} else if (!dfl) {
+	} else if (!dfl && serio->registered) {
 		serio_rescan(serio);
 		ret = IRQ_HANDLED;
 	}
@@ -710,12 +746,13 @@
 static int __init serio_init(void)
 {
 	if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
-		printk(KERN_WARNING "serio: Failed to start kseriod\n");
+		printk(KERN_ERR "serio: Failed to start kseriod\n");
 		return -1;
 	}
 
 	serio_bus.dev_attrs = serio_device_attrs;
 	serio_bus.drv_attrs = serio_driver_attrs;
+	serio_bus.match = serio_bus_match;
 	bus_register(&serio_bus);
 
 	return 0;
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-12-29 01:53:31 -05:00
+++ b/include/linux/serio.h	2004-12-29 01:53:31 -05:00
@@ -51,6 +51,7 @@
 	struct semaphore drv_sem;	/* protects serio->drv so attributes can pin driver */
 
 	struct device dev;
+	unsigned int registered;	/* port has been fully registered with driver core */
 
 	struct list_head node;
 };
@@ -72,8 +73,6 @@
 	void (*cleanup)(struct serio *);
 
 	struct device_driver driver;
-
-	struct list_head node;
 };
 #define to_serio_driver(d)	container_of(d, struct serio_driver, driver)
 
@@ -83,10 +82,18 @@
 void serio_reconnect(struct serio *serio);
 irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
 
-void serio_register_port(struct serio *serio);
-void serio_register_port_delayed(struct serio *serio);
+void __serio_register_port(struct serio *serio, struct module *owner);
+static inline void serio_register_port(struct serio *serio)
+{
+	__serio_register_port(serio, THIS_MODULE);
+}
+
 void serio_unregister_port(struct serio *serio);
-void serio_unregister_port_delayed(struct serio *serio);
+void __serio_unregister_port_delayed(struct serio *serio, struct module *owner);
+static inline void serio_unregister_port_delayed(struct serio *serio)
+{
+	__serio_unregister_port_delayed(serio, THIS_MODULE);
+}
 
 void serio_register_driver(struct serio_driver *drv);
 void serio_unregister_driver(struct serio_driver *drv);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 16/16] serio connect methods should return error codes
  2004-12-29  7:32                             ` [PATCH 15/16] serio bus implementation cleanup Dmitry Torokhov
@ 2004-12-29  7:33                               ` Dmitry Torokhov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry Torokhov @ 2004-12-29  7:33 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML


===================================================================


ChangeSet@1.1977, 2004-12-29 02:00:32-05:00, dtor_core@ameritech.net
  Input: make serio's connect routines return error code
         instead of void.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/joystick/iforce/iforce-serio.c |   15 ++++++++++-----
 drivers/input/joystick/magellan.c            |   11 +++++++----
 drivers/input/joystick/spaceorb.c            |   13 +++++++++----
 drivers/input/joystick/stinger.c             |   11 +++++++----
 drivers/input/joystick/twidjoy.c             |   12 ++++++++----
 drivers/input/joystick/warrior.c             |   12 ++++++++----
 drivers/input/keyboard/atkbd.c               |   15 ++++++++++-----
 drivers/input/keyboard/lkkbd.c               |   13 +++++++++----
 drivers/input/keyboard/newtonkbd.c           |   12 ++++++++----
 drivers/input/keyboard/sunkbd.c              |   14 +++++++++-----
 drivers/input/keyboard/xtkbd.c               |   12 ++++++++----
 drivers/input/mouse/psmouse-base.c           |   15 ++++++++++++---
 drivers/input/mouse/sermouse.c               |   12 ++++++++----
 drivers/input/mouse/vsxxxaa.c                |   12 ++++++++----
 drivers/input/serio/serio.c                  |    6 ++----
 drivers/input/touchscreen/gunze.c            |   12 ++++++++----
 drivers/input/touchscreen/h3600_ts_input.c   |   16 ++++++++++------
 include/linux/serio.h                        |    2 +-
 18 files changed, 142 insertions(+), 73 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/iforce/iforce-serio.c	2004-12-29 02:01:00 -05:00
@@ -126,12 +126,14 @@
 	return IRQ_HANDLED;
 }
 
-static void iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
+static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct iforce *iforce;
+	int err;
 
 	if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
+
 	memset(iforce, 0, sizeof(struct iforce));
 
 	iforce->bus = IFORCE_232;
@@ -139,18 +141,21 @@
 
 	serio_set_drvdata(serio, iforce);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(iforce);
-		return;
+		return err;
 	}
 
 	if (iforce_init_device(iforce)) {
 		serio_close(serio);
 		serio_set_drvdata(serio, NULL);
 		kfree(iforce);
-		return;
+		return -ENODEV;
 	}
+
+	return 0;
 }
 
 static void iforce_serio_disconnect(struct serio *serio)
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/magellan.c	2004-12-29 02:01:00 -05:00
@@ -150,13 +150,14 @@
  * an input device.
  */
 
-static void magellan_connect(struct serio *serio, struct serio_driver *drv)
+static int magellan_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct magellan *magellan;
 	int i, t;
+	int err;
 
 	if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(magellan, 0, sizeof(struct magellan));
 
@@ -186,16 +187,18 @@
 
 	serio_set_drvdata(serio, magellan);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(magellan);
-		return;
+		return err;
 	}
 
 	input_register_device(&magellan->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
 
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/spaceorb.c	2004-12-29 02:01:00 -05:00
@@ -166,13 +166,15 @@
  * it as an input device.
  */
 
-static void spaceorb_connect(struct serio *serio, struct serio_driver *drv)
+static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct spaceorb *spaceorb;
 	int i, t;
+	int err;
 
 	if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
+
 	memset(spaceorb, 0, sizeof(struct spaceorb));
 
 	spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
@@ -203,13 +205,16 @@
 
 	serio_set_drvdata(serio, spaceorb);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(spaceorb);
-		return;
+		return err;
 	}
 
 	input_register_device(&spaceorb->dev);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/stinger.c	2004-12-29 02:01:00 -05:00
@@ -138,13 +138,14 @@
  * an input device.
  */
 
-static void stinger_connect(struct serio *serio, struct serio_driver *drv)
+static int stinger_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct stinger *stinger;
 	int i;
+	int err;
 
 	if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(stinger, 0, sizeof(struct stinger));
 
@@ -175,16 +176,18 @@
 
 	serio_set_drvdata(serio, stinger);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(stinger);
-		return;
+		return err;
 	}
 
 	input_register_device(&stinger->dev);
 
 	printk(KERN_INFO "input: %s on %s\n",  stinger_name, serio->phys);
 
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/twidjoy.c	2004-12-29 02:01:00 -05:00
@@ -191,14 +191,15 @@
  * it as an input device.
  */
 
-static void twidjoy_connect(struct serio *serio, struct serio_driver *drv)
+static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct twidjoy_button_spec *bp;
 	struct twidjoy *twidjoy;
 	int i;
+	int err;
 
 	if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(twidjoy, 0, sizeof(struct twidjoy));
 
@@ -235,15 +236,18 @@
 
 	serio_set_drvdata(serio, twidjoy);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(twidjoy);
-		return;
+		return err;
 	}
 
 	input_register_device(&twidjoy->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/joystick/warrior.c	2004-12-29 02:01:00 -05:00
@@ -143,13 +143,14 @@
  * it as an input device.
  */
 
-static void warrior_connect(struct serio *serio, struct serio_driver *drv)
+static int warrior_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct warrior *warrior;
 	int i;
+	int err;
 
 	if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(warrior, 0, sizeof(struct warrior));
 
@@ -187,15 +188,18 @@
 
 	serio_set_drvdata(serio, warrior);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(warrior);
-		return;
+		return err;
 	}
 
 	input_register_device(&warrior->dev);
 
 	printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/keyboard/atkbd.c	2004-12-29 02:01:00 -05:00
@@ -773,12 +773,14 @@
  * to the input module.
  */
 
-static void atkbd_connect(struct serio *serio, struct serio_driver *drv)
+static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct atkbd *atkbd;
+	int err;
 
 	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
-		return;
+		return - ENOMEM;
+
 	memset(atkbd, 0, sizeof(struct atkbd));
 
 	ps2_init(&atkbd->ps2dev, serio);
@@ -805,10 +807,11 @@
 
 	serio_set_drvdata(serio, atkbd);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(atkbd);
-		return;
+		return err;
 	}
 
 	if (atkbd->write) {
@@ -817,7 +820,7 @@
 			serio_close(serio);
 			serio_set_drvdata(serio, NULL);
 			kfree(atkbd);
-			return;
+			return -ENODEV;
 		}
 
 		atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
@@ -850,6 +853,8 @@
 	atkbd_enable(atkbd);
 
 	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/keyboard/lkkbd.c	2004-12-29 02:01:00 -05:00
@@ -623,14 +623,16 @@
 /*
  * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
  */
-static void
+static int
 lkkbd_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct lkkbd *lk;
 	int i;
+	int err;
 
 	if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
+
 	memset (lk, 0, sizeof (struct lkkbd));
 
 	init_input_dev (&lk->dev);
@@ -662,10 +664,11 @@
 
 	serio_set_drvdata (serio, lk);
 
-	if (serio_open (serio, drv)) {
+	err = serio_open (serio, drv);
+	if (err) {
 		serio_set_drvdata (serio, NULL);
 		kfree (lk);
-		return;
+		return err;
 	}
 
 	sprintf (lk->name, "DEC LK keyboard");
@@ -687,6 +690,8 @@
 
 	printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
 	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/keyboard/newtonkbd.c	2004-12-29 02:01:00 -05:00
@@ -84,13 +84,14 @@
 
 }
 
-void nkbd_connect(struct serio *serio, struct serio_driver *drv)
+int nkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct nkbd *nkbd;
 	int i;
+	int err;
 
 	if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(nkbd, 0, sizeof(struct nkbd));
 
@@ -106,10 +107,11 @@
 
 	serio_set_drvdata(serio, nkbd);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(nkbd);
-		return;
+		return err;
 	}
 
 	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
@@ -130,6 +132,8 @@
 	input_register_device(&nkbd->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+
+	return 0;
 }
 
 void nkbd_disconnect(struct serio *serio)
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/keyboard/sunkbd.c	2004-12-29 02:01:00 -05:00
@@ -223,13 +223,14 @@
  * sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
  */
 
-static void sunkbd_connect(struct serio *serio, struct serio_driver *drv)
+static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sunkbd *sunkbd;
 	int i;
+	int err;
 
 	if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(sunkbd, 0, sizeof(struct sunkbd));
 
@@ -253,17 +254,18 @@
 
 	serio_set_drvdata(serio, sunkbd);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(sunkbd);
-		return;
+		return err;
 	}
 
 	if (sunkbd_initialize(sunkbd) < 0) {
 		serio_close(serio);
 		serio_set_drvdata(serio, NULL);
 		kfree(sunkbd);
-		return;
+		return -ENODEV;
 	}
 
 	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
@@ -286,6 +288,8 @@
 	input_register_device(&sunkbd->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/keyboard/xtkbd.c	2004-12-29 02:01:00 -05:00
@@ -88,13 +88,14 @@
 	return IRQ_HANDLED;
 }
 
-void xtkbd_connect(struct serio *serio, struct serio_driver *drv)
+int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct xtkbd *xtkbd;
 	int i;
+	int err;
 
 	if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(xtkbd, 0, sizeof(struct xtkbd));
 
@@ -110,10 +111,11 @@
 
 	serio_set_drvdata(serio, xtkbd);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(xtkbd);
-		return;
+		return err;
 	}
 
 	memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
@@ -134,6 +136,8 @@
 	input_register_device(&xtkbd->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
+
+	return 0;
 }
 
 void xtkbd_disconnect(struct serio *serio)
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/mouse/psmouse-base.c	2004-12-29 02:01:00 -05:00
@@ -673,9 +673,10 @@
  * psmouse_connect() is a callback from the serio module when
  * an unhandled serio port is found.
  */
-static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
+static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct psmouse *psmouse, *parent = NULL;
+	int retval;
 
 	/*
 	 * If this is a pass-through port deactivate parent so the device
@@ -686,8 +687,10 @@
 		psmouse_deactivate(parent);
 	}
 
-	if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
+	if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL))) {
+		retval = -ENOMEM;
 		goto out;
+	}
 
 	memset(psmouse, 0, sizeof(struct psmouse));
 
@@ -702,7 +705,8 @@
 
 	serio_set_drvdata(serio, psmouse);
 
-	if (serio_open(serio, drv)) {
+	retval = serio_open(serio, drv);
+	if (retval) {
 		serio_set_drvdata(serio, NULL);
 		kfree(psmouse);
 		goto out;
@@ -712,6 +716,7 @@
 		serio_close(serio);
 		serio_set_drvdata(serio, NULL);
 		kfree(psmouse);
+		retval = -ENODEV;
 		goto out;
 	}
 
@@ -753,10 +758,14 @@
 
 	psmouse_activate(psmouse);
 
+	retval = 0;
+
 out:
 	/* If this is a pass-through port the parent awaits to be activated */
 	if (parent)
 		psmouse_activate(parent);
+
+	return retval;
 }
 
 
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/mouse/sermouse.c	2004-12-29 02:01:00 -05:00
@@ -241,16 +241,17 @@
  * an unhandled serio port is found.
  */
 
-static void sermouse_connect(struct serio *serio, struct serio_driver *drv)
+static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sermouse *sermouse;
 	unsigned char c;
+	int err;
 
 	if (!serio->id.proto || serio->id.proto > SERIO_MZPP)
-		return;
+		return -ENODEV;
 
 	if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(sermouse, 0, sizeof(struct sermouse));
 
@@ -281,15 +282,18 @@
 
 	serio_set_drvdata(serio, sermouse);
 
+	err = serio_open(serio, drv);
 	if (serio_open(serio, drv)) {
 		serio_set_drvdata(serio, NULL);
 		kfree(sermouse);
-		return;
+		return err;
 	}
 
 	input_register_device(&sermouse->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
+
+	return 0;
 }
 
 static struct serio_id sermouse_serio_ids[] = {
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/mouse/vsxxxaa.c	2004-12-29 02:01:00 -05:00
@@ -489,13 +489,14 @@
 	kfree (mouse);
 }
 
-static void
+static int
 vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct vsxxxaa *mouse;
+	int err;
 
 	if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset (mouse, 0, sizeof (struct vsxxxaa));
 
@@ -529,10 +530,11 @@
 
 	serio_set_drvdata (serio, mouse);
 
-	if (serio_open (serio, drv)) {
+	err = serio_open (serio, drv);
+	if (err) {
 		serio_set_drvdata (serio, NULL);
 		kfree (mouse);
-		return;
+		return err;
 	}
 
 	/*
@@ -544,6 +546,8 @@
 	input_register_device (&mouse->dev);
 
 	printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
+
+	return 0;
 }
 
 static struct serio_id vsxxaa_serio_ids[] = {
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/serio/serio.c	2004-12-29 02:01:00 -05:00
@@ -92,8 +92,7 @@
 
 	if (serio_match_port(drv->ids, serio)) {
 		serio->dev.driver = &drv->driver;
-		drv->connect(serio, drv);
-		if (!serio->drv) {
+		if (drv->connect(serio, drv)) {
 			serio->dev.driver = NULL;
 			goto out;
 		}
@@ -636,8 +635,7 @@
 	struct serio *serio = to_serio_port(dev);
 	struct serio_driver *drv = to_serio_driver(dev->driver);
 
-	drv->connect(serio, drv);
-	return serio->drv ? 0 : -ENODEV;
+	return drv->connect(serio, drv);
 }
 
 static int serio_driver_remove(struct device *dev)
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/touchscreen/gunze.c	2004-12-29 02:01:00 -05:00
@@ -115,12 +115,13 @@
  * an input device.
  */
 
-static void gunze_connect(struct serio *serio, struct serio_driver *drv)
+static int gunze_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct gunze *gunze;
+	int err;
 
 	if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(gunze, 0, sizeof(struct gunze));
 
@@ -144,15 +145,18 @@
 
 	serio_set_drvdata(serio, gunze);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
 		serio_set_drvdata(serio, NULL);
 		kfree(gunze);
-		return;
+		return err;
 	}
 
 	input_register_device(&gunze->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 02:01:00 -05:00
+++ b/drivers/input/touchscreen/h3600_ts_input.c	2004-12-29 02:01:00 -05:00
@@ -377,12 +377,13 @@
  * new serio device that supports H3600 protocol and registers it as
  * an input device.
  */
-static void h3600ts_connect(struct serio *serio, struct serio_driver *drv)
+static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct h3600_dev *ts;
+	int err;
 
 	if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL)))
-		return;
+		return -ENOMEM;
 
 	memset(ts, 0, sizeof(struct h3600_dev));
 
@@ -397,7 +398,7 @@
 			"h3600_action", &ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
 		kfree(ts);
-		return;
+		return -EBUSY;
 	}
 
         if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
@@ -406,7 +407,7 @@
 		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
 		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
 		kfree(ts);
-		return;
+		return -EBUSY;
 	}
 
 	/* Now we have things going we setup our input device */
@@ -443,12 +444,13 @@
 
 	serio_set_drvdata(serio, ts);
 
-	if (serio_open(serio, drv)) {
+	err = serio_open(serio, drv);
+	if (err) {
         	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
         	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
 		serio_set_drvdata(serio, NULL);
 		kfree(ts);
-		return;
+		return err;
 	}
 
 	//h3600_flite_control(1, 25);     /* default brightness */
@@ -460,6 +462,8 @@
 	input_register_device(&ts->dev);
 
 	printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys);
+
+	return 0;
 }
 
 /*
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	2004-12-29 02:01:00 -05:00
+++ b/include/linux/serio.h	2004-12-29 02:01:00 -05:00
@@ -67,7 +67,7 @@
 	void (*write_wakeup)(struct serio *);
 	irqreturn_t (*interrupt)(struct serio *, unsigned char,
 			unsigned int, struct pt_regs *);
-	void (*connect)(struct serio *, struct serio_driver *drv);
+	int  (*connect)(struct serio *, struct serio_driver *drv);
 	int  (*reconnect)(struct serio *);
 	void (*disconnect)(struct serio *);
 	void (*cleanup)(struct serio *);

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2004-12-29  7:17 [PATCH 0/16] New set of input patches Dmitry Torokhov
  2004-12-29  7:19 ` [PATCH 1/16] i8042 panicblink cleanup Dmitry Torokhov
@ 2005-01-13 15:36 ` Vojtech Pavlik
  2005-01-13 17:52   ` Dmitry Torokhov
  1 sibling, 1 reply; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-13 15:36 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, LKML

On Wed, Dec 29, 2004 at 02:17:36AM -0500, Dmitry Torokhov wrote:
> Hi Vojtech,
> 
> Please take a look at the following input patches. Patches 1-9 are already
> in my tree (and were there for quite some time so they should have gotten
> at least some testing as Andrew automatically pulls from me) and I'd like
> see them pushed to Linus together with your last batch. At least patches
> 6, 8 and 9 fix bugs introduced by latest changes. Patch 7 should help owners
> of Toshibas with Synaptics touchpads.
> 
> 01-i8042-panicblink-cleanup.patch
> 	Move panicblink parameter definition together with the rest of i8042
> 	module parameters, add description and entry in kernel-parameters.txt

I think I prefer the DELAY definition to be outside the function. Other
than that the patch is OK.

> 02-serio-start-stop.patch
> 	Add serio start() and stop() methods to serio structure that are
> 	called when serio port is about to be fully registered and when
> 	serio port is about to be unregistered. These methods are useful
> 	for drivers that share interrupt among several serio ports. In this
> 	case interrupt can not be enabled/disabled in open/close methods
> 	and it is very hard to determine if interrupt shoudl be ignored or
> 	passed on.

> 03-i8042-use-start-stop.patch
> 	Make use of new serio start/stop methods to safely activate and
> 	deactivate ports. Also unify as much as possible port handling
> 	between KBD, AUX and MUX ports. Rename i8042_values into i8042_port.

Would we need this at all if we made the port registration completely
asynchronous, only binding devices to ports _after_ the port is
completely registered?

I'm rather reluctant to add even more callbacks.

> 04-serio-suppress-dup-events.patch
> 	Do not submit serio event into event queue if there is already one
> 	of the same type for the same port in front of it. Also look for
> 	duplicat events once event is processed. This should help with
> 	disconnected ports generating alot of data and consuming memory for
> 	events when kseriod gets behind and prevents constant rescans.
> 	This also allows to remove special check for 0xaa in reconnect path
> 	of interrupt handler known to cause problems with Toshibas keyboards.

Ok. Since we'll be usually scanning an empty list, this shouldn't add
any overhead.

Btw, why do we need _both_ to scan for duplicate events on event
completion and check at event insert time? One should be enough - if we
always check, then we cannot have duplicate events and if we always are
able to deal with them, we don't have to care ...

> 05-evdev-buffer-size.patch
> 	Return -EINVAL from evdev_read when passed buffer is too small.
> 	Based on patch by James Lamanna.

OK.

> 06-ps2pp-mouse-name.patch
> 	Set mouse name to "Mouse" instead of leaving it NULL when using
> 	PS2++ protocol and don't have any other information (Wheel, Touchpad)
> 	about the mouse.

Already merged.

> 07-synaptics-toshiba-rate.patch
> 	Toshiba Satellite KBCs have trouble handling data stream coming from
> 	Synaptics at full rate (80 pps, 480 byte/sec) which causes keyboards
> 	to pause or even get stuck. Use DMI to detect Satellites and limit
> 	rate to 40 pps which cures keyboard.

OK.

> 08-atkbd-keycode-size.patch
> 	Fix keycode table size initialization that got broken by my changes
> 	that exported 'set' and other settings via sysfs.
> 	setkeycodes should work again now.

Already merged.

> 09-i8042-sysfs-permissions.patch
> 	Fix braindamage in sysfs permissions for 'debug' option.

OK.

> 10-twidjoy-build.patch
> 	Make Kconfig and Makefile agree on the option name so twidjoy
> 	can be built.

OK.

> 11-input-msecs-to-jiffies.patch
> 	Use msecs_to_jiffies instead of homegrown ms_to_jiffies
> 	so everything works when HZ != 1000

OK.

> 12-atkbd-msecs-to-jiffies.patch
> 	Use msecs_to_jiffies instead of manually calculating
> 	delay for Toshiba bouncing keys workaround so it works
>         when HZ != 1000.

OK.

> 13-serio-drvdata.patch
> 	Remove serio->private in favor of using driver-specific data
> 	in device structure, add serio_get_drvdata/serio_put_drvdata
> 	to access it so serio bus code looks more like other buses.

OK.

> 14-serio-id-match.patch
> 	Replace serio's type field with serio_id structure and
> 	add ids table to serio drivers. This will allow splitting
> 	initial matching and probing routines for better sysfs
> 	integration.

OK. Maybe we should add a new SPIOCSTYPE ioctl to pass the structure
directly.

> 15-serio-bus-cleanup.patch
> 	Make serio implementation more in line with standard
> 	driver model implementations by removing explicit device
> 	and driver list manipulations and introducing bus_match
> 	function. serio_register_port is always asynchronous to
> 	allow freely registering child ports. When deregistering
> 	serio core still takes care of destroying children ports
> 	first.

OK. I suppose the synchronous unregister variant is needed for module
unload? I suppose refcounting would be enough there ... 

> 16-serio-connect-errcode.patch
> 	Make serios' connect methods return error code instead of
>         void so exact cause of failur can be comminicated upstream. 

OK.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-13 15:36 ` [PATCH 0/16] New set of input patches Vojtech Pavlik
@ 2005-01-13 17:52   ` Dmitry Torokhov
  2005-01-13 19:25     ` Vojtech Pavlik
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-13 17:52 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

On Thu, 13 Jan 2005 16:36:44 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
> On Wed, Dec 29, 2004 at 02:17:36AM -0500, Dmitry Torokhov wrote:
> >
> > 01-i8042-panicblink-cleanup.patch
> >       Move panicblink parameter definition together with the rest of i8042
> >       module parameters, add description and entry in kernel-parameters.txt
> 
> I think I prefer the DELAY definition to be outside the function. Other
> than that the patch is OK.
 
Will do.

> > 02-serio-start-stop.patch
> >       Add serio start() and stop() methods to serio structure that are
> >       called when serio port is about to be fully registered and when
> >       serio port is about to be unregistered. These methods are useful
> >       for drivers that share interrupt among several serio ports. In this
> >       case interrupt can not be enabled/disabled in open/close methods
> >       and it is very hard to determine if interrupt shoudl be ignored or
> >       passed on.
> 
> > 03-i8042-use-start-stop.patch
> >       Make use of new serio start/stop methods to safely activate and
> >       deactivate ports. Also unify as much as possible port handling
> >       between KBD, AUX and MUX ports. Rename i8042_values into i8042_port.
> 
> Would we need this at all if we made the port registration completely
> asynchronous, only binding devices to ports _after_ the port is
> completely registered?
> 
> I'm rather reluctant to add even more callbacks.
> 

The problem is not with binding devices, it is with mostly with
sharing the same IRQ between different ports.

Look at the MUX case, you have 4 ports all sharing the same IRQ. At
startup i8042 enables all on-chip ports and registers them with
serio_register_port(). When first serio driver class i8042_open it
installs IRQ handler. All 4 ports are enabled now (because we want to
do hot-plug) but, especially with async. serio registration, only the
first is fully registered with serio subsystem. If data was to come
from any other port the shared IRQ handler will call serio_reconnect
on half-alive port. The similar issues happen when you try to
unregister port.

With start/stop methods allow serop core signal driver that the port
is fully registered and now is safe to use. If IRQ is not shared
between ports one can safely register/unregister handler in open/close
methods (at the expense of hotplug device support) but with shared IRQ
you need additional callbacks.

> > 04-serio-suppress-dup-events.patch
> >       Do not submit serio event into event queue if there is already one
> >       of the same type for the same port in front of it. Also look for
> >       duplicat events once event is processed. This should help with
> >       disconnected ports generating alot of data and consuming memory for
> >       events when kseriod gets behind and prevents constant rescans.
> >       This also allows to remove special check for 0xaa in reconnect path
> >       of interrupt handler known to cause problems with Toshibas keyboards.
> 
> Ok. Since we'll be usually scanning an empty list, this shouldn't add
> any overhead.

Plus serio events are rare so unless there are "runaway" serio interrupt this
patch tries to procet from there shoudl not be pretty much any overhead.

> Btw, why do we need _both_ to scan for duplicate events on event
> completion and check at event insert time? One should be enough - if we
> always check, then we cannot have duplicate events and if we always are
> able to deal with them, we don't have to care ...

A duplicate event can be queued while kseriod was processing current event,
checking for a dupe is cheaper then doing duplicate work we'd just done and
the lis is mostr likely empty anyway.

> 
> Already merged.
> 
> > 09-i8042-sysfs-permissions.patch
> >       Fix braindamage in sysfs permissions for 'debug' option.
> 
> OK.

This one has already been merged as well I think.

> 
> > 14-serio-id-match.patch
> >       Replace serio's type field with serio_id structure and
> >       add ids table to serio drivers. This will allow splitting
> >       initial matching and probing routines for better sysfs
> >       integration.
> 
> OK. Maybe we should add a new SPIOCSTYPE ioctl to pass the structure
> directly.

I am not sure it is needed ATM and I am a bit fuzzy on 32/64 bit ioctl
issues so I'll leave it alone for now ;)
 
> 
> > 15-serio-bus-cleanup.patch
> >       Make serio implementation more in line with standard
> >       driver model implementations by removing explicit device
> >       and driver list manipulations and introducing bus_match
> >       function. serio_register_port is always asynchronous to
> >       allow freely registering child ports. When deregistering
> >       serio core still takes care of destroying children ports
> >       first.
> 
> OK. I suppose the synchronous unregister variant is needed for module
> unload? I suppose refcounting would be enough there ...

I don't see how. Kobject refcounting protects data structures but not
code and I can't bump up module's reference count in module_exit
function to delay its removal and we do not want to take module's
reference for every registered port otherwise unload will not be
possible. That's why synchronous removal method is needed.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-13 17:52   ` Dmitry Torokhov
@ 2005-01-13 19:25     ` Vojtech Pavlik
  2005-01-13 20:16       ` Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-13 19:25 UTC (permalink / raw)
  To: dtor_core; +Cc: linux-input, LKML

On Thu, Jan 13, 2005 at 12:52:14PM -0500, Dmitry Torokhov wrote:

> The problem is not with binding devices, it is with mostly with
> sharing the same IRQ between different ports.
> 
> Look at the MUX case, you have 4 ports all sharing the same IRQ. At
> startup i8042 enables all on-chip ports and registers them with
> serio_register_port(). When first serio driver class i8042_open it
> installs IRQ handler. All 4 ports are enabled now (because we want to
> do hot-plug) but, especially with async. serio registration, only the
> first is fully registered with serio subsystem. If data was to come
> from any other port the shared IRQ handler will call serio_reconnect
> on half-alive port. The similar issues happen when you try to
> unregister port.
> 
> With start/stop methods allow serop core signal driver that the port
> is fully registered and now is safe to use. If IRQ is not shared
> between ports one can safely register/unregister handler in open/close
> methods (at the expense of hotplug device support) but with shared IRQ
> you need additional callbacks.

Yes, this can result in calling serio_reconnect on a port that's not
registered yet. But I believe we don't need a callback for this, just a
flag in the serio struct that will say "live", be set during
registration, and until that time all serio_interrupt() calls would be
ignored?

This is transparent to the port drivers, and doesn't change any
interfaces. What do you think?

> > > 04-serio-suppress-dup-events.patch
> > >       Do not submit serio event into event queue if there is already one
> > >       of the same type for the same port in front of it. Also look for
> > >       duplicat events once event is processed. This should help with
> > >       disconnected ports generating alot of data and consuming memory for
> > >       events when kseriod gets behind and prevents constant rescans.
> > >       This also allows to remove special check for 0xaa in reconnect path
> > >       of interrupt handler known to cause problems with Toshibas keyboards.
> > 
> > Ok. Since we'll be usually scanning an empty list, this shouldn't add
> > any overhead.
> 
> Plus serio events are rare so unless there are "runaway" serio interrupt this
> patch tries to procet from there shoudl not be pretty much any overhead.

Indeed.

> > Btw, why do we need _both_ to scan for duplicate events on event
> > completion and check at event insert time? One should be enough - if we
> > always check, then we cannot have duplicate events and if we always are
> > able to deal with them, we don't have to care ...
> 
> A duplicate event can be queued while kseriod was processing current event,
> checking for a dupe is cheaper then doing duplicate work we'd just done and
> the list is most likely empty anyway.

Yes. So I'd probably drop the check when we're inserting the event?

> > > 09-i8042-sysfs-permissions.patch
> > >       Fix braindamage in sysfs permissions for 'debug' option.
> > 
> > OK.
> 
> This one has already been merged as well I think.

Probably yes.

> > > 14-serio-id-match.patch
> > >       Replace serio's type field with serio_id structure and
> > >       add ids table to serio drivers. This will allow splitting
> > >       initial matching and probing routines for better sysfs
> > >       integration.
> > 
> > OK. Maybe we should add a new SPIOCSTYPE ioctl to pass the structure
> > directly.
> 
> I am not sure it is needed ATM and I am a bit fuzzy on 32/64 bit ioctl
> issues so I'll leave it alone for now ;)

OK.

> > > 15-serio-bus-cleanup.patch
> > >       Make serio implementation more in line with standard
> > >       driver model implementations by removing explicit device
> > >       and driver list manipulations and introducing bus_match
> > >       function. serio_register_port is always asynchronous to
> > >       allow freely registering child ports. When deregistering
> > >       serio core still takes care of destroying children ports
> > >       first.
> > 
> > OK. I suppose the synchronous unregister variant is needed for module
> > unload? I suppose refcounting would be enough there ...
> 
> I don't see how. Kobject refcounting protects data structures but not
> code and I can't bump up module's reference count in module_exit
> function to delay its removal and we do not want to take module's
> reference for every registered port otherwise unload will not be
> possible. That's why synchronous removal method is needed.

I think it could be done by marking the port dead, but still leaving it
there when the module exits, but it's probably not worth it.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-13 19:25     ` Vojtech Pavlik
@ 2005-01-13 20:16       ` Dmitry Torokhov
  2005-01-27 14:04         ` Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-13 20:16 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

On Thu, 13 Jan 2005 20:25:25 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
> On Thu, Jan 13, 2005 at 12:52:14PM -0500, Dmitry Torokhov wrote:
> 
> > The problem is not with binding devices, it is with mostly with
> > sharing the same IRQ between different ports.
> >
> > Look at the MUX case, you have 4 ports all sharing the same IRQ. At
> > startup i8042 enables all on-chip ports and registers them with
> > serio_register_port(). When first serio driver class i8042_open it
> > installs IRQ handler. All 4 ports are enabled now (because we want to
> > do hot-plug) but, especially with async. serio registration, only the
> > first is fully registered with serio subsystem. If data was to come
> > from any other port the shared IRQ handler will call serio_reconnect
> > on half-alive port. The similar issues happen when you try to
> > unregister port.
> >
> > With start/stop methods allow serop core signal driver that the port
> > is fully registered and now is safe to use. If IRQ is not shared
> > between ports one can safely register/unregister handler in open/close
> > methods (at the expense of hotplug device support) but with shared IRQ
> > you need additional callbacks.
> 
> Yes, this can result in calling serio_reconnect on a port that's not
> registered yet. But I believe we don't need a callback for this, just a
> flag in the serio struct that will say "live", be set during
> registration, and until that time all serio_interrupt() calls would be
> ignored?
>

You can't have this flag in serio struct because unless this flag is
set you should not access serio struct in question, this is chicken
and egg problem. While you can somewhat control creation the deletion
is especially tricky. You need to service interrupts up until the
close is called but not a moment later as serio structure will be
freed by serio core. Therefore flag should be in the driver and having
code poking in the driver guts is not a giood idea.

start/stop are not mandatory methods so only problem drivers needs to
be adjusted.
 
> 
> > > > 04-serio-suppress-dup-events.patch
> > > >       Do not submit serio event into event queue if there is already one
> > > >       of the same type for the same port in front of it. Also look for
> > > >       duplicat events once event is processed. This should help with
> > > >       disconnected ports generating alot of data and consuming memory for
> > > >       events when kseriod gets behind and prevents constant rescans.
> > > >       This also allows to remove special check for 0xaa in reconnect path
> > > >       of interrupt handler known to cause problems with Toshibas keyboards.
> > >
> > > Ok. Since we'll be usually scanning an empty list, this shouldn't add
> > > any overhead.
> >
> > Plus serio events are rare so unless there are "runaway" serio interrupt this
> > patch tries to procet from there shoudl not be pretty much any overhead.
> 
> Indeed.
> 
> > > Btw, why do we need _both_ to scan for duplicate events on event
> > > completion and check at event insert time? One should be enough - if we
> > > always check, then we cannot have duplicate events and if we always are
> > > able to deal with them, we don't have to care ...
> >
> > A duplicate event can be queued while kseriod was processing current event,
> > checking for a dupe is cheaper then doing duplicate work we'd just done and
> > the list is most likely empty anyway.
> 
> Yes. So I'd probably drop the check when we're inserting the event?
>

No because (potentially) while kseriod is busy waiting on semaphore or
doing something else psmouse with synaptics touchpad can generate
rescan events at rate of 480 events/sec consuming memory for no good
reason.
 
> 
> I think it could be done by marking the port dead, but still leaving it
> there when the module exits, but it's probably not worth it.
> 

Then you would have to have 2 separate paths for hardware cleanup on
unload and for cleanup on driver disconnect...

-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-13 20:16       ` Dmitry Torokhov
@ 2005-01-27 14:04         ` Dmitry Torokhov
  2005-01-27 16:15           ` Vojtech Pavlik
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-27 14:04 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

Vojtech,

I have dropped the patches that have already been applied and
re-diffed the remaining patches. I have also merged Adrian's global ->
static cleanup and 2 patches from Prarit Bhargava (one re: releasing
resources acquired by i8042_platform_init if controller initialization
fails and the other is re: making educating guess whether controller
is absent or really times out).

There also was couple of additional changes - serio drivers now use
MODULE_DEVICE_TABLE to export information about the ports they can
possible work with; serio core exports port's type, protocol, id and
"extra" data as sysfs attributes and there is hotplug function to
signal userspace about new port. This all was done so that hotplug can
automatically load appropriate driver (for example psmouse) when a new
port is detected. I have patches for module-init-tools and hotplug
scripts that I will sent to Greg and Rusty as soon as you take the
pathes (if you will).

I think that the very first path ("while true; do xset led 3; xset
-led 3; done" makes keyboard miss release events and makes it
unusable) should go in 2.6.11 so please do:

        bk pull bk://dtor.bkbits.net/for-2.6.11

That repository has only this change. The rest of the patches are in
my usual repository:

        bk pull bk://dtor.bkbits.net/input

I am not sending the patches separately as they had been posted to the
lists couple of times already.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 14:04         ` Dmitry Torokhov
@ 2005-01-27 16:15           ` Vojtech Pavlik
  2005-01-27 16:36             ` Vojtech Pavlik
  2005-01-28  7:13             ` Dmitry Torokhov
  0 siblings, 2 replies; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-27 16:15 UTC (permalink / raw)
  To: dtor_core; +Cc: linux-input, LKML

On Thu, Jan 27, 2005 at 09:04:06AM -0500, Dmitry Torokhov wrote:
> Vojtech,
> 
> I have dropped the patches that have already been applied and
> re-diffed the remaining patches. I have also merged Adrian's global ->
> static cleanup and 2 patches from Prarit Bhargava (one re: releasing
> resources acquired by i8042_platform_init if controller initialization
> fails and the other is re: making educating guess whether controller
> is absent or really times out).
> 
> There also was couple of additional changes - serio drivers now use
> MODULE_DEVICE_TABLE to export information about the ports they can
> possible work with; serio core exports port's type, protocol, id and
> "extra" data as sysfs attributes and there is hotplug function to
> signal userspace about new port. This all was done so that hotplug can
> automatically load appropriate driver (for example psmouse) when a new
> port is detected. I have patches for module-init-tools and hotplug
> scripts that I will sent to Greg and Rusty as soon as you take the
> pathes (if you will).
> 
> I think that the very first path ("while true; do xset led 3; xset
> -led 3; done" makes keyboard miss release events and makes it
> unusable) should go in 2.6.11 so please do:
> 
>         bk pull bk://dtor.bkbits.net/for-2.6.11

Pulled, pushed into my tree. I verified the patch, and it is indeed
correct. Before we get an ACK for a command we sent, we still may
receive normal data. After we got the ACK we know for sure that no more
regular data will come, and can expect the command response.

> That repository has only this change. The rest of the patches are in
> my usual repository:
> 
>         bk pull bk://dtor.bkbits.net/input
> 
> I am not sending the patches separately as they had been posted to the
> lists couple of times already.

OK. I'll go through them, and apply as appropriate. I still need to wrap
my mind around the start() and stop() methods and see the necessity. I
still think a variable in the serio struct, only accessed by the serio.c
core driver itself (and never by the port driver) that'd cause all
serio_interrupt() calls to be ignored until set in the asynchronous port
registration would be well enough.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 16:15           ` Vojtech Pavlik
@ 2005-01-27 16:36             ` Vojtech Pavlik
  2005-01-27 18:18               ` Dmitry Torokhov
  2005-01-28  7:13             ` Dmitry Torokhov
  1 sibling, 1 reply; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-27 16:36 UTC (permalink / raw)
  To: dtor_core; +Cc: linux-input, LKML

On Thu, Jan 27, 2005 at 05:15:18PM +0100, Vojtech Pavlik wrote:

> OK. I'll go through them, and apply as appropriate. I still need to wrap
> my mind around the start() and stop() methods and see the necessity. I
> still think a variable in the serio struct, only accessed by the serio.c
> core driver itself (and never by the port driver) that'd cause all
> serio_interrupt() calls to be ignored until set in the asynchronous port
> registration would be well enough.

I've read he start() and stop() code, and I came to the conclusion
again that we don't need them as serio port driver methods. i8042 uses
them to set the exists variable only and uses that variable _solely_ for
the purpose of skipping calls to serio_interrupt(), serio_cleanup() and
serio_unregister().

By instead checking a member of the serio struct in these functions, and
doing nothing if not set, we achieve the same goal, without adding extra
cruft to the interface, making it allowed to call these serio functions
on a non-registered or half-registered serio struct, with the effect
being defined to nothing.

Similarly, it's perfectly allowed to call input_event() on an struct
input_dev that hasn't been registered with the input layer, again with
no effect. It simplifies the driver code a lot.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 16:36             ` Vojtech Pavlik
@ 2005-01-27 18:18               ` Dmitry Torokhov
  2005-01-27 22:16                 ` Vojtech Pavlik
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-27 18:18 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

On Thu, 27 Jan 2005 17:36:05 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
> On Thu, Jan 27, 2005 at 05:15:18PM +0100, Vojtech Pavlik wrote:
> 
> > OK. I'll go through them, and apply as appropriate. I still need to wrap
> > my mind around the start() and stop() methods and see the necessity. I
> > still think a variable in the serio struct, only accessed by the serio.c
> > core driver itself (and never by the port driver) that'd cause all
> > serio_interrupt() calls to be ignored until set in the asynchronous port
> > registration would be well enough.
> 
> I've read he start() and stop() code, and I came to the conclusion
> again that we don't need them as serio port driver methods. i8042 uses
> them to set the exists variable only and uses that variable _solely_ for
> the purpose of skipping calls to serio_interrupt(), serio_cleanup() and
> serio_unregister().
> 
> By instead checking a member of the serio struct in these functions, and
> doing nothing if not set, we achieve the same goal, without adding extra
> cruft to the interface, making it allowed to call these serio functions
> on a non-registered or half-registered serio struct, with the effect
> being defined to nothing.
> 

No, you can not peek into serio structure from a driver, not when it
was dynamically allocated and can be gone at any time. Please consider
the following screnario when shutting down 8042 when you have a MUX
with several ports:

The rough call sequence is:
i8042_exit
  serio_unregister_port
     driver->disconnect
        serio_close
           i8042->close
     free(serio)

We need to keep interrupts passed to serio core until serio_close is
completed so device properly ACKs/responds to cleanup commands.
Additionally, in i8042 close we do not free IRQ until last port is
unregistered nor we disable the port because we want to support
hotplugging. If interrupt comes after port was freed but before
serio_unregister_port has returned i8042_interrupt will call
serio_interrupt for port that was just free()ed. Special flag in serio
will not help because you need to know that port pointer is valid. You
could try pinning the port in memory buy taking a refernce but then
asynchronous unregister is not possible and it is needed in some
cases.

I think that having these 2 interface functions helps clearly define
these sequence points when port can/can not be used, simplifies logic
and alerts driver authors of this potential problem.
 
-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 18:18               ` Dmitry Torokhov
@ 2005-01-27 22:16                 ` Vojtech Pavlik
  2005-01-30 23:35                   ` Dmitry Torokhov
  0 siblings, 1 reply; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-27 22:16 UTC (permalink / raw)
  To: dtor_core; +Cc: linux-input, LKML

On Thu, Jan 27, 2005 at 01:18:55PM -0500, Dmitry Torokhov wrote:
> On Thu, 27 Jan 2005 17:36:05 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
> > On Thu, Jan 27, 2005 at 05:15:18PM +0100, Vojtech Pavlik wrote:
> > 
> > > OK. I'll go through them, and apply as appropriate. I still need to wrap
> > > my mind around the start() and stop() methods and see the necessity. I
> > > still think a variable in the serio struct, only accessed by the serio.c
> > > core driver itself (and never by the port driver) that'd cause all
> > > serio_interrupt() calls to be ignored until set in the asynchronous port
> > > registration would be well enough.
> > 
> > I've read he start() and stop() code, and I came to the conclusion
> > again that we don't need them as serio port driver methods. i8042 uses
> > them to set the exists variable only and uses that variable _solely_ for
> > the purpose of skipping calls to serio_interrupt(), serio_cleanup() and
> > serio_unregister().
> > 
> > By instead checking a member of the serio struct in these functions, and
> > doing nothing if not set, we achieve the same goal, without adding extra
> > cruft to the interface, making it allowed to call these serio functions
> > on a non-registered or half-registered serio struct, with the effect
> > being defined to nothing.
> > 
> 
> No, you can not peek into serio structure from a driver, not when it
> was dynamically allocated and can be gone at any time. Please consider
> the following screnario when shutting down 8042 when you have a MUX
> with several ports:
> 
> The rough call sequence is:
> i8042_exit
>   serio_unregister_port
>      driver->disconnect
>         serio_close
>            i8042->close
>      free(serio)
> 
> We need to keep interrupts passed to serio core until serio_close is
> completed so device properly ACKs/responds to cleanup commands.
> Additionally, in i8042 close we do not free IRQ until last port is
> unregistered nor we disable the port because we want to support
> hotplugging. If interrupt comes after port was freed but before
> serio_unregister_port has returned i8042_interrupt will call
> serio_interrupt for port that was just free()ed. Special flag in serio
> will not help because you need to know that port pointer is valid. You
> could try pinning the port in memory buy taking a refernce but then
> asynchronous unregister is not possible and it is needed in some
> cases.
> 
> I think that having these 2 interface functions helps clearly define
> these sequence points when port can/can not be used, simplifies logic
> and alerts driver authors of this potential problem.
 
You're right. I forgot that serio isn't anymore tied to the driver and
can cease to exist on its own asynchronously. However, I'm still not
sure whether it's worth it. We might as well simply drop the unregister
call in i8042_open for AUX completely and forget about asynchronous
unregisters and use normal refcounting. As far as grep knows, it's the
only user.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 16:15           ` Vojtech Pavlik
  2005-01-27 16:36             ` Vojtech Pavlik
@ 2005-01-28  7:13             ` Dmitry Torokhov
  2005-01-28 11:24               ` Vojtech Pavlik
  1 sibling, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-28  7:13 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

On Thursday 27 January 2005 11:15, Vojtech Pavlik wrote:
> > I think that the very first path ("while true; do xset led 3; xset
> > -led 3; done" makes keyboard miss release events and makes it
> > unusable) should go in 2.6.11 so please do:
> > 
> >         bk pull bk://dtor.bkbits.net/for-2.6.11
> 
> Pulled, pushed into my tree. I verified the patch, and it is indeed
> correct. Before we get an ACK for a command we sent, we still may
> receive normal data. After we got the ACK we know for sure that no more
> regular data will come, and can expect the command response.

Hi Vojtech,

I have another one that I think needs to be in 2.6.11 - in ps2_command
does not update timeout variable when waiting for the first byte of
response so even if command times out the code still goes and tries to
wait for more data. It actually causes problems with GETID command - we
end up reporting success even if we did not get any response (except for
initial ACK). 

Also, now taht wait_event_timeout is available we shoudl use it instead
of wait_event_interruptible_timeout.

-- 
Dmitry


===================================================================


ChangeSet@1.1986, 2005-01-28 01:53:11-05:00, dtor_core@ameritech.net
  Input: libps2 - fix timeout handling in ps2_command, switch to using
         wait_event_timeout instead of wait_event_interruptible_timeout
         now that first form is available.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 libps2.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
--- a/drivers/input/serio/libps2.c	2005-01-28 02:12:06 -05:00
+++ b/drivers/input/serio/libps2.c	2005-01-28 02:12:06 -05:00
@@ -60,9 +60,9 @@
 	serio_continue_rx(ps2dev->serio);
 
 	if (serio_write(ps2dev->serio, byte) == 0)
-		wait_event_interruptible_timeout(ps2dev->wait,
-					!(ps2dev->flags & PS2_FLAG_ACK),
-					msecs_to_jiffies(timeout));
+		wait_event_timeout(ps2dev->wait,
+				   !(ps2dev->flags & PS2_FLAG_ACK),
+				   msecs_to_jiffies(timeout));
 
 	serio_pause_rx(ps2dev->serio);
 	ps2dev->flags &= ~PS2_FLAG_ACK;
@@ -115,8 +115,8 @@
 	 */
 	timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
 
-	wait_event_interruptible_timeout(ps2dev->wait,
-		!(ps2dev->flags & PS2_FLAG_CMD1), timeout);
+	timeout = wait_event_timeout(ps2dev->wait,
+				     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
 
 	if (ps2dev->cmdcnt && timeout > 0) {
 
@@ -147,8 +147,8 @@
 			serio_continue_rx(ps2dev->serio);
 		}
 
-		wait_event_interruptible_timeout(ps2dev->wait,
-				!(ps2dev->flags & PS2_FLAG_CMD), timeout);
+		wait_event_timeout(ps2dev->wait,
+				   !(ps2dev->flags & PS2_FLAG_CMD), timeout);
 	}
 
 	if (param)
@@ -259,7 +259,7 @@
 		ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
 
 	ps2dev->flags &= ~PS2_FLAG_ACK;
-	wake_up_interruptible(&ps2dev->wait);
+	wake_up(&ps2dev->wait);
 
 	if (data != PS2_RET_ACK)
 		ps2_handle_response(ps2dev, data);
@@ -281,12 +281,12 @@
 	if (ps2dev->flags & PS2_FLAG_CMD1) {
 		ps2dev->flags &= ~PS2_FLAG_CMD1;
 		if (ps2dev->cmdcnt)
-			wake_up_interruptible(&ps2dev->wait);
+			wake_up(&ps2dev->wait);
 	}
 
 	if (!ps2dev->cmdcnt) {
 		ps2dev->flags &= ~PS2_FLAG_CMD;
-		wake_up_interruptible(&ps2dev->wait);
+		wake_up(&ps2dev->wait);
 	}
 
 	return 1;
@@ -298,7 +298,7 @@
 		ps2dev->nak = 1;
 
 	if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
-		wake_up_interruptible(&ps2dev->wait);
+		wake_up(&ps2dev->wait);
 
 	ps2dev->flags = 0;
 }



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-28  7:13             ` Dmitry Torokhov
@ 2005-01-28 11:24               ` Vojtech Pavlik
  0 siblings, 0 replies; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-28 11:24 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, LKML

On Fri, Jan 28, 2005 at 02:13:12AM -0500, Dmitry Torokhov wrote:
> On Thursday 27 January 2005 11:15, Vojtech Pavlik wrote:
> > > I think that the very first path ("while true; do xset led 3; xset
> > > -led 3; done" makes keyboard miss release events and makes it
> > > unusable) should go in 2.6.11 so please do:
> > > 
> > >         bk pull bk://dtor.bkbits.net/for-2.6.11
> > 
> > Pulled, pushed into my tree. I verified the patch, and it is indeed
> > correct. Before we get an ACK for a command we sent, we still may
> > receive normal data. After we got the ACK we know for sure that no more
> > regular data will come, and can expect the command response.
> 
> Hi Vojtech,
> 
> I have another one that I think needs to be in 2.6.11 - in ps2_command
> does not update timeout variable when waiting for the first byte of
> response so even if command times out the code still goes and tries to
> wait for more data. It actually causes problems with GETID command - we
> end up reporting success even if we did not get any response (except for
> initial ACK). 
> 
> Also, now taht wait_event_timeout is available we shoudl use it instead
> of wait_event_interruptible_timeout.
 
OK.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-27 22:16                 ` Vojtech Pavlik
@ 2005-01-30 23:35                   ` Dmitry Torokhov
  2005-01-31  9:13                     ` Vojtech Pavlik
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Torokhov @ 2005-01-30 23:35 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: linux-input, LKML

On Thursday 27 January 2005 17:16, Vojtech Pavlik wrote:
> On Thu, Jan 27, 2005 at 01:18:55PM -0500, Dmitry Torokhov wrote:
> > On Thu, 27 Jan 2005 17:36:05 +0100, Vojtech Pavlik <vojtech@suse.cz> wrote:
> > > On Thu, Jan 27, 2005 at 05:15:18PM +0100, Vojtech Pavlik wrote:
> > > 
> > > > OK. I'll go through them, and apply as appropriate. I still need to wrap
> > > > my mind around the start() and stop() methods and see the necessity. I
> > > > still think a variable in the serio struct, only accessed by the serio.c
> > > > core driver itself (and never by the port driver) that'd cause all
> > > > serio_interrupt() calls to be ignored until set in the asynchronous port
> > > > registration would be well enough.
> > > 
> > > I've read he start() and stop() code, and I came to the conclusion
> > > again that we don't need them as serio port driver methods. i8042 uses
> > > them to set the exists variable only and uses that variable _solely_ for
> > > the purpose of skipping calls to serio_interrupt(), serio_cleanup() and
> > > serio_unregister().
> > > 
> > > By instead checking a member of the serio struct in these functions, and
> > > doing nothing if not set, we achieve the same goal, without adding extra
> > > cruft to the interface, making it allowed to call these serio functions
> > > on a non-registered or half-registered serio struct, with the effect
> > > being defined to nothing.
> > > 
> > 
> > No, you can not peek into serio structure from a driver, not when it
> > was dynamically allocated and can be gone at any time. Please consider
> > the following screnario when shutting down 8042 when you have a MUX
> > with several ports:
> > 
> > The rough call sequence is:
> > i8042_exit
> >   serio_unregister_port
> >      driver->disconnect
> >         serio_close
> >            i8042->close
> >      free(serio)
> > 
> > We need to keep interrupts passed to serio core until serio_close is
> > completed so device properly ACKs/responds to cleanup commands.
> > Additionally, in i8042 close we do not free IRQ until last port is
> > unregistered nor we disable the port because we want to support
> > hotplugging. If interrupt comes after port was freed but before
> > serio_unregister_port has returned i8042_interrupt will call
> > serio_interrupt for port that was just free()ed. Special flag in serio
> > will not help because you need to know that port pointer is valid. You
> > could try pinning the port in memory buy taking a refernce but then
> > asynchronous unregister is not possible and it is needed in some
> > cases.
> > 
> > I think that having these 2 interface functions helps clearly define
> > these sequence points when port can/can not be used, simplifies logic
> > and alerts driver authors of this potential problem.
>  
> You're right. I forgot that serio isn't anymore tied to the driver and
> can cease to exist on its own asynchronously. However, I'm still not
> sure whether it's worth it. We might as well simply drop the unregister
> call in i8042_open for AUX completely and forget about asynchronous
> unregisters and use normal refcounting. As far as grep knows, it's the
> only user.

I am pretty sure I will need asynchronous unregister in some form when
I finish dynamic protocol switching in psmouse (those darned pass-through
ports!). Plus again, having these 2 methods will draw driver writers'
attention to the existence of this particular problem.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/16] New set of input patches
  2005-01-30 23:35                   ` Dmitry Torokhov
@ 2005-01-31  9:13                     ` Vojtech Pavlik
  0 siblings, 0 replies; 30+ messages in thread
From: Vojtech Pavlik @ 2005-01-31  9:13 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, LKML

On Sun, Jan 30, 2005 at 06:35:18PM -0500, Dmitry Torokhov wrote:

> > You're right. I forgot that serio isn't anymore tied to the driver and
> > can cease to exist on its own asynchronously. However, I'm still not
> > sure whether it's worth it. We might as well simply drop the unregister
> > call in i8042_open for AUX completely and forget about asynchronous
> > unregisters and use normal refcounting. As far as grep knows, it's the
> > only user.
> 
> I am pretty sure I will need asynchronous unregister in some form when
> I finish dynamic protocol switching in psmouse (those darned pass-through
> ports!). Plus again, having these 2 methods will draw driver writers'
> attention to the existence of this particular problem.

OK. I'm convinced.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2005-01-31  9:09 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-29  7:17 [PATCH 0/16] New set of input patches Dmitry Torokhov
2004-12-29  7:19 ` [PATCH 1/16] i8042 panicblink cleanup Dmitry Torokhov
2004-12-29  7:20   ` [PATCH 2/16] Add serio start and stop methods Dmitry Torokhov
2004-12-29  7:20     ` [PATCH 3/16] i8042: Make use of new " Dmitry Torokhov
2004-12-29  7:21       ` [PATCH 4/16] Suppress duplicate events in serio core Dmitry Torokhov
2004-12-29  7:22         ` [PATCH 5/16] evdev: return -EINVAL if read buffer is too small Dmitry Torokhov
2004-12-29  7:23           ` [PATCH 6/16] Propery set up name for PS/2 Logitech mice Dmitry Torokhov
2004-12-29  7:24             ` [PATCH 7/16] Limit Synaptics rate on Toshiba Satellites Dmitry Torokhov
2004-12-29  7:25               ` [PATCH 8/16] Allow setkeycodes work again Dmitry Torokhov
2004-12-29  7:26                 ` [PATCH 9/16] i8042: fix sysfs permissiions for 'debug' parameter Dmitry Torokhov
2004-12-29  7:27                   ` [PATCH 10/16] Fix building twidjoy module Dmitry Torokhov
2004-12-29  7:28                     ` [PATCH 11/16] Use msecs_to_jiffies in input core Dmitry Torokhov
2004-12-29  7:28                       ` [PATCH 12/16] Use msecs_to_jiffies in atkbd Dmitry Torokhov
2004-12-29  7:29                         ` [PATCH 13/16] Introduce serio_get/set_drvdata helpers Dmitry Torokhov
2004-12-29  7:31                           ` [PATCH 14/16] Introduce serio_id to match ports and drivers Dmitry Torokhov
2004-12-29  7:32                             ` [PATCH 15/16] serio bus implementation cleanup Dmitry Torokhov
2004-12-29  7:33                               ` [PATCH 16/16] serio connect methods should return error codes Dmitry Torokhov
2005-01-13 15:36 ` [PATCH 0/16] New set of input patches Vojtech Pavlik
2005-01-13 17:52   ` Dmitry Torokhov
2005-01-13 19:25     ` Vojtech Pavlik
2005-01-13 20:16       ` Dmitry Torokhov
2005-01-27 14:04         ` Dmitry Torokhov
2005-01-27 16:15           ` Vojtech Pavlik
2005-01-27 16:36             ` Vojtech Pavlik
2005-01-27 18:18               ` Dmitry Torokhov
2005-01-27 22:16                 ` Vojtech Pavlik
2005-01-30 23:35                   ` Dmitry Torokhov
2005-01-31  9:13                     ` Vojtech Pavlik
2005-01-28  7:13             ` Dmitry Torokhov
2005-01-28 11:24               ` Vojtech Pavlik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.