public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patches] Input updates
@ 2004-07-29 14:07 Vojtech Pavlik
  2004-07-29 14:09 ` [PATCH 1/47] Add 64-bit compatible ioctls for hiddev Vojtech Pavlik
  2004-07-29 16:59 ` [patches] Input updates Vojtech Pavlik
  0 siblings, 2 replies; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:07 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

Hi!

Again, quite a bunch of patches has accumulated in my tree - now that
they're well tested through Andrew's mm tree, I'd like to merge them to
you.

There still are imperfections in atkbd/psmouse locking, but the races
are rather hard to hit - and it's still better than before. They should
be fixed in the next round of patches, however I'd still like to have
this round of patches in before the next one.

Please pull from bk://kernel.bkbits.net/vojtech/input

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

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

* [PATCH 11/47] Make atkbd.c's atkbd_command() function immune to keys being pressed while running
  2004-07-29 14:09                   ` [PATCH 10/47] Disable the AUX LoopBack command in i8042.c on Compaq ProLiant Vojtech Pavlik
@ 2004-07-29 14:09                     ` Vojtech Pavlik
  2004-07-29 14:09                       ` [PATCH 12/47] More locking improvements (and a fix) for serio Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.84.3, 2004-06-02 15:46:14+02:00, vojtech@suse.cz
  input: Make atkbd.c's atkbd_command() function immune to keys being pressed
         and scancodes coming from the keyboard while it's executing.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:41:36 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:41:36 2004
@@ -252,6 +252,11 @@
 		switch (code) {
 			case ATKBD_RET_ACK:
 				atkbd->nak = 0;
+				if (atkbd->cmdcnt) {
+					set_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+					set_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
+					set_bit(ATKBD_FLAG_ID, &atkbd->flags);
+				}
 				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 				goto out;
 			case ATKBD_RET_NAK:
@@ -414,6 +419,7 @@
 #endif
 
 	set_bit(ATKBD_FLAG_ACK, &atkbd->flags);
+	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
 	if (serio_write(atkbd->serio, byte))
 		return -1;
 	while (test_bit(ATKBD_FLAG_ACK, &atkbd->flags) && timeout--) udelay(1);
@@ -443,23 +449,13 @@
 		for (i = 0; i < receive; i++)
 			atkbd->cmdbuf[(receive - 1) - i] = param[i];
 
-	if (receive) {
-		set_bit(ATKBD_FLAG_CMD, &atkbd->flags);
-		set_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
-		set_bit(ATKBD_FLAG_ID, &atkbd->flags);
-	}
-
 	if (command & 0xff)
-		if (atkbd_sendbyte(atkbd, command & 0xff)) {
-			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+		if (atkbd_sendbyte(atkbd, command & 0xff))
 			return -1;
-		}
 
 	for (i = 0; i < send; i++)
-		if (atkbd_sendbyte(atkbd, param[i])) {
-			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+		if (atkbd_sendbyte(atkbd, param[i]))
 			return -1;
-		}
 
 	while (test_bit(ATKBD_FLAG_CMD, &atkbd->flags) && timeout--) {
 


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

* [PATCH 2/47] Fix locking in i8042.c and serio.c
  2004-07-29 14:09 ` [PATCH 1/47] Add 64-bit compatible ioctls for hiddev Vojtech Pavlik
@ 2004-07-29 14:09   ` Vojtech Pavlik
  2004-07-29 14:09     ` [PATCH 3/47] Fix an oops in poll() on uinput Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.24.2, 2004-05-28 18:24:08+02:00, vojtech@suse.cz
  input: An attempt at fixing locking in i8042.c and serio.c


 drivers/input/serio/i8042.c |    4 ++
 drivers/input/serio/serio.c |   64 +++++++++++++++++++++++++++++++++++++-------
 include/linux/serio.h       |    2 -
 3 files changed, 59 insertions(+), 11 deletions(-)

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:42:23 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:42:23 2004
@@ -95,6 +95,7 @@
 /*
  * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
  * be ready for reading values from it / writing values to it.
+ * Called always with i8042_lock held.
  */
 
 static int i8042_wait_read(void)
@@ -677,6 +678,7 @@
 
 static int i8042_controller_init(void)
 {
+	unsigned long flags;
 
 /*
  * Test the i8042. We need to know if it thinks it's working correctly
@@ -723,12 +725,14 @@
  * Handle keylock.
  */
 
+	spin_lock_irqsave(&i8042_lock, flags);
 	if (~i8042_read_status() & I8042_STR_KEYLOCK) {
 		if (i8042_unlock)
 			i8042_ctr |= I8042_CTR_IGNKEYLOCK;
 		 else
 			printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
 	}
+	spin_unlock_irqrestore(&i8042_lock, flags);
 
 /*
  * If the chip is configured into nontranslated mode by the BIOS, don't
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:42:23 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:42:23 2004
@@ -67,12 +67,18 @@
 	struct list_head node;
 };
 
-static DECLARE_MUTEX(serio_sem);
+
+spinlock_t serio_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list and serio->dev */
+static DECLARE_MUTEX(serio_sem);		/* protects serio_list and serio_dev_list */
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_dev_list);
 static LIST_HEAD(serio_event_list);
 static int serio_pid;
 
+/*
+ * serio_find_dev() must be called with serio_sem down.
+ */
+
 static void serio_find_dev(struct serio *serio)
 {
 	struct serio_dev *dev;
@@ -96,22 +102,42 @@
 static void serio_invalidate_pending_events(struct serio *serio)
 {
 	struct serio_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_lock, flags);
 
 	list_for_each_entry(event, &serio_event_list, node)
 		if (event->serio == serio)
 			event->serio = NULL;
+
+	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 void serio_handle_events(void)
 {
-	struct list_head *node, *next;
+	struct list_head *node;
 	struct serio_event *event;
+	unsigned long flags;
+
+	
+	while (1) {
+
+		spin_lock_irqsave(&serio_lock, flags);
+		
+		if (list_empty(&serio_event_list)) {
+			spin_unlock_irqrestore(&serio_lock, flags);
+			break;
+		}
 
-	list_for_each_safe(node, next, &serio_event_list) {
+		node = serio_event_list.next;
 		event = container_of(node, struct serio_event, node);
+		list_del_init(node);
+
+		spin_unlock_irqrestore(&serio_lock, flags);
 
 		down(&serio_sem);
-		if (event->serio == NULL)
+
+		if (event->serio == NULL) /*!!!*/
 			goto event_done;
 
 		switch (event->type) {
@@ -139,7 +165,6 @@
 		}
 event_done:
 		up(&serio_sem);
-		list_del_init(node);
 		kfree(event);
 	}
 }
@@ -178,12 +203,18 @@
 
 void serio_rescan(struct serio *serio)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&serio_lock, flags);
 	serio_queue_event(serio, SERIO_RESCAN);
+	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 void serio_reconnect(struct serio *serio)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&serio_lock, flags);
 	serio_queue_event(serio, SERIO_RECONNECT);
+	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 irqreturn_t serio_interrupt(struct serio *serio,
@@ -191,17 +222,22 @@
 {
 	irqreturn_t ret = IRQ_NONE;
 
+	spin_lock_irq(&serio_lock);
+
         if (serio->dev && serio->dev->interrupt) {
                 ret = serio->dev->interrupt(serio, data, flags, regs);
 	} else {
 		if (!flags) {
-			if ((serio->type == SERIO_8042 ||
-				serio->type == SERIO_8042_XL) && (data != 0xaa))
-					return ret;
-			serio_rescan(serio);
-			ret = IRQ_HANDLED;
+			if ((serio->type != SERIO_8042 &&
+			     serio->type != SERIO_8042_XL) || (data == 0xaa)) {
+				serio_queue_event(serio, SERIO_RESCAN);
+				ret = IRQ_HANDLED;
+			}
 		}
 	}
+	
+	spin_unlock_irq(&serio_lock);
+
 	return ret;
 }
 
@@ -292,7 +328,11 @@
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 int serio_open(struct serio *serio, struct serio_dev *dev)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_lock, flags);
 	serio->dev = dev;
+	spin_unlock_irqrestore(&serio_lock, flags);
 	if (serio->open && serio->open(serio)) {
 		serio->dev = NULL;
 		return -1;
@@ -303,9 +343,13 @@
 /* called from serio_dev->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
+	unsigned long flags;
+
 	if (serio->close)
 		serio->close(serio);
+	spin_lock_irqsave(&serio_lock, flags);
 	serio->dev = NULL;
+	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 static int __init serio_init(void)
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:42:23 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:42:23 2004
@@ -36,7 +36,7 @@
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
 
-	struct serio_dev *dev;
+	struct serio_dev *dev; /* Accessed from interrupt, writes must be protected by serio_lock */
 
 	struct list_head node;
 };


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

* [PATCH 6/47] Explicit variable access rules for psmouse.c
  2004-07-29 14:09         ` [PATCH 5/47] Return 0 from uinput poll if device isn't yet created Vojtech Pavlik
@ 2004-07-29 14:09           ` Vojtech Pavlik
  2004-07-29 14:09             ` [PATCH 7/47] Add reporting of raw scancodes to atkbd.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.63.1, 2004-05-31 15:11:41+02:00, vojtech@suse.cz
  input: Explicit variable access rules for psmouse.c, using bitops.


 keyboard/atkbd.c     |    2 
 mouse/psmouse-base.c |  129 +++++++++++++++++++++++++++++++--------------------
 mouse/psmouse.h      |    9 ++-
 3 files changed, 87 insertions(+), 53 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:04 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:04 2004
@@ -435,7 +435,7 @@
 	atkbd->cmdcnt = receive;
 
 	if (command == ATKBD_CMD_RESET_BAT)
-		timeout = 2000000; /* 2 sec */
+		timeout = 4000000; /* 4 sec */
 
 	if (receive && param)
 		for (i = 0; i < receive; i++)
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:42:04 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:42:04 2004
@@ -142,34 +142,45 @@
 			printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
 				flags & SERIO_TIMEOUT ? " timeout" : "",
 				flags & SERIO_PARITY ? " bad parity" : "");
-		if (psmouse->acking) {
-			psmouse->ack = -1;
-			psmouse->acking = 0;
-		}
-		psmouse->pktcnt = 0;
+		psmouse->nak = 1;
+		clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+		clear_bit(PSMOUSE_FLAG_CMD,  &psmouse->flags);
 		goto out;
 	}
 
-	if (psmouse->acking) {
+	if (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags))
 		switch (data) {
 			case PSMOUSE_RET_ACK:
-				psmouse->ack = 1;
+				psmouse->nak = 0;
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				goto out;
 				break;
 			case PSMOUSE_RET_NAK:
-				psmouse->ack = -1;
-				break;
+				psmouse->nak = 1;
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				goto out;
 			default:
-				psmouse->ack = 1;	/* Workaround for mice which don't ACK the Get ID command */
-				if (psmouse->cmdcnt)
-					psmouse->cmdbuf[--psmouse->cmdcnt] = data;
-				break;
+				psmouse->nak = 0;	/* Workaround for mice which don't ACK the Get ID command */
+				clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+				if (!test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags))
+					goto out;
+
 		}
-		psmouse->acking = 0;
-		goto out;
-	}
 
-	if (psmouse->cmdcnt) {
-		psmouse->cmdbuf[--psmouse->cmdcnt] = data;
+	if (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags)) {
+
+		psmouse->cmdcnt--;
+		psmouse->cmdbuf[psmouse->cmdcnt] = data;
+
+		if (psmouse->cmdcnt == 1) {
+			if (data != 0xab && data != 0xac)
+				clear_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
+			clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
+		}
+
+		if (!psmouse->cmdcnt)
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+
 		goto out;
 	}
 
@@ -242,18 +253,15 @@
 
 static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
 {
-	int timeout = 10000; /* 100 msec */
-	psmouse->ack = 0;
-	psmouse->acking = 1;
+	int timeout = 200000; /* 200 msec */
 
-	if (serio_write(psmouse->serio, byte)) {
-		psmouse->acking = 0;
+	set_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+	if (serio_write(psmouse->serio, byte))
 		return -1;
-	}
-
-	while (!psmouse->ack && timeout--) udelay(10);
+	while (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags) && timeout--) udelay(1);
+	clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
 
-	return -(psmouse->ack <= 0);
+	return -psmouse->nak;
 }
 
 /*
@@ -271,46 +279,62 @@
 	psmouse->cmdcnt = receive;
 
 	if (command == PSMOUSE_CMD_RESET_BAT)
-                timeout = 4000000; /* 4 sec */
+		timeout = 4000000; /* 4 sec */
 
-	/* initialize cmdbuf with preset values from param */
-	if (receive)
-	   for (i = 0; i < receive; i++)
-		psmouse->cmdbuf[(receive - 1) - i] = param[i];
+	if (receive && param)
+		for (i = 0; i < receive; i++)
+			psmouse->cmdbuf[(receive - 1) - i] = param[i];
+
+	if (receive) {
+		set_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+		set_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags);
+		set_bit(PSMOUSE_FLAG_ID, &psmouse->flags);
+	}
 
 	if (command & 0xff)
-		if (psmouse_sendbyte(psmouse, command & 0xff))
-			return (psmouse->cmdcnt = 0) - 1;
+		if (psmouse_sendbyte(psmouse, command & 0xff)) {
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+			return -1;
+		}
 
 	for (i = 0; i < send; i++)
-		if (psmouse_sendbyte(psmouse, param[i]))
-			return (psmouse->cmdcnt = 0) - 1;
+		if (psmouse_sendbyte(psmouse, param[i])) {
+			clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+			return -1;
+		}
 
-	while (psmouse->cmdcnt && timeout--) {
+	while (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags) && timeout--) {
 
-		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT &&
-				timeout > 100000) /* do not run in a endless loop */
-			timeout = 100000; /* 1 sec */
-
-		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID &&
-		    psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) {
-			psmouse->cmdcnt = 0;
-			break;
+		if (!test_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags)) {
+		    
+			if (command == PSMOUSE_CMD_RESET_BAT && timeout > 100000)
+				timeout = 100000;
+
+			if (command == PSMOUSE_CMD_GETID && !test_bit(PSMOUSE_FLAG_ID, &psmouse->flags)) {
+				clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+				psmouse->cmdcnt = 0;
+				break;
+			}
 		}
 
 		udelay(1);
 	}
 
-	for (i = 0; i < receive; i++)
-		param[i] = psmouse->cmdbuf[(receive - 1) - i];
+	clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags);
+
+	if (param)
+		for (i = 0; i < receive; i++)
+			param[i] = psmouse->cmdbuf[(receive - 1) - i];
+
+	if (command == PSMOUSE_CMD_RESET_BAT && psmouse->cmdcnt == 1)
+		return 0;
 
 	if (psmouse->cmdcnt)
-		return (psmouse->cmdcnt = 0) - 1;
+		return -1;
 
 	return 0;
 }
 
-
 /*
  * psmouse_sliced_command() sends an extended PS/2 command to the mouse
  * using sliced syntax, understood by advanced devices, such as Logitech
@@ -735,7 +759,12 @@
 	}
 
 	psmouse->state = PSMOUSE_CMD_MODE;
-	psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
+
+	clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags);
+	clear_bit(PSMOUSE_FLAG_CMD,  &psmouse->flags);
+
+	psmouse->pktcnt = psmouse->out_of_sync = 0;
+
 	if (psmouse->reconnect) {
 	       if (psmouse->reconnect(psmouse))
 			return -1;
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	Thu Jul 29 14:42:04 2004
+++ b/drivers/input/mouse/psmouse.h	Thu Jul 29 14:42:04 2004
@@ -22,6 +22,11 @@
 #define PSMOUSE_ACTIVATED	1
 #define PSMOUSE_IGNORE		2
 
+#define PSMOUSE_FLAG_ACK	0	/* Waiting for ACK/NAK */
+#define PSMOUSE_FLAG_CMD	1	/* Waiting for command to finish */
+#define PSMOUSE_FLAG_CMD1	2	/* First byte of command response */
+#define PSMOUSE_FLAG_ID		3	/* First byte is not keyboard ID */
+
 /* psmouse protocol handler return codes */
 typedef enum {
 	PSMOUSE_BAD_DATA,
@@ -54,11 +59,11 @@
 	unsigned long last;
 	unsigned long out_of_sync;
 	unsigned char state;
-	char acking;
-	volatile char ack;
+	unsigned char nak;
 	char error;
 	char devname[64];
 	char phys[32];
+	unsigned long flags;
 
 	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 
 	int (*reconnect)(struct psmouse *psmouse);


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

* [PATCH 7/47] Add reporting of raw scancodes to atkbd.c
  2004-07-29 14:09           ` [PATCH 6/47] Explicit variable access rules for psmouse.c Vojtech Pavlik
@ 2004-07-29 14:09             ` Vojtech Pavlik
  2004-07-29 14:09               ` [PATCH 8/47] Use raw events generated by atkbd in keyboard.c to implement true rawmode for PS/2 keyboards Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.63.2, 2004-05-31 15:49:05+02:00, vojtech@suse.cz
  input: Add reporting of raw scancodes to atkbd.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 drivers/input/keyboard/atkbd.c |    8 +++++---
 include/linux/input.h          |    1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:00 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:00 2004
@@ -280,6 +280,8 @@
 	if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
 		goto out;
 
+	input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
+
 	if (atkbd->translated) {
 
 		if (atkbd->emul ||
@@ -753,9 +755,10 @@
 	}
 
 	if (atkbd->write) {
-		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC);
 		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+	atkbd->dev.mscbit[0] = BIT(MSC_RAW);
 
 	if (!atkbd_softrepeat) {
 		atkbd->dev.rep[REP_DELAY] = 250;
@@ -795,7 +798,6 @@
 		atkbd->set = 2;
 		atkbd->id = 0xab00;
 	}
-
 
 	if (atkbd->extra) {
 		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	Thu Jul 29 14:42:00 2004
+++ b/include/linux/input.h	Thu Jul 29 14:42:00 2004
@@ -527,6 +527,7 @@
 #define MSC_SERIAL		0x00
 #define MSC_PULSELED		0x01
 #define MSC_GESTURE		0x02
+#define MSC_RAW			0x03
 #define MSC_MAX			0x07
 
 /*


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

* [PATCH 9/47] Fixes in serio locking.
  2004-07-29 14:09               ` [PATCH 8/47] Use raw events generated by atkbd in keyboard.c to implement true rawmode for PS/2 keyboards Vojtech Pavlik
@ 2004-07-29 14:09                 ` Vojtech Pavlik
  2004-07-29 14:09                   ` [PATCH 10/47] Disable the AUX LoopBack command in i8042.c on Compaq ProLiant Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.66.2, 2004-06-02 09:37:24+02:00, vojtech@suse.cz
  input: Fixes in serio locking. We need per-serio lock for passthrough
         ports, some locks were missing, and spin_lock_irq was wishful
         thinking in serio_interrupt. There is no guarantee
         that serio_interrupt won't be called twice at the same time.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 drivers/input/serio/serio.c |   55 +++++++++++++++++++++++---------------------
 include/linux/serio.h       |    3 ++
 2 files changed, 32 insertions(+), 26 deletions(-)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:41:50 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:41:50 2004
@@ -68,8 +68,8 @@
 };
 
 
-spinlock_t serio_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list and serio->dev */
-static DECLARE_MUTEX(serio_sem);		/* protects serio_list and serio_dev_list */
+spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
+static DECLARE_MUTEX(serio_sem);			/* protects serio_list and serio_dev_list */
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_dev_list);
 static LIST_HEAD(serio_event_list);
@@ -104,13 +104,13 @@
 	struct serio_event *event;
 	unsigned long flags;
 
-	spin_lock_irqsave(&serio_lock, flags);
+	spin_lock_irqsave(&serio_event_lock, flags);
 
 	list_for_each_entry(event, &serio_event_list, node)
 		if (event->serio == serio)
 			event->serio = NULL;
 
-	spin_unlock_irqrestore(&serio_lock, flags);
+	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
 void serio_handle_events(void)
@@ -119,13 +119,13 @@
 	struct serio_event *event;
 	unsigned long flags;
 
-	
+
 	while (1) {
 
-		spin_lock_irqsave(&serio_lock, flags);
-		
+		spin_lock_irqsave(&serio_event_lock, flags);
+
 		if (list_empty(&serio_event_list)) {
-			spin_unlock_irqrestore(&serio_lock, flags);
+			spin_unlock_irqrestore(&serio_event_lock, flags);
 			break;
 		}
 
@@ -133,7 +133,7 @@
 		event = container_of(node, struct serio_event, node);
 		list_del_init(node);
 
-		spin_unlock_irqrestore(&serio_lock, flags);
+		spin_unlock_irqrestore(&serio_event_lock, flags);
 
 		down(&serio_sem);
 
@@ -190,8 +190,11 @@
 
 static void serio_queue_event(struct serio *serio, int event_type)
 {
+	unsigned long flags;
 	struct serio_event *event;
 
+	spin_lock_irqsave(&serio_event_lock, flags);
+
 	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
 		event->type = event_type;
 		event->serio = serio;
@@ -199,44 +202,41 @@
 		list_add_tail(&event->node, &serio_event_list);
 		wake_up(&serio_wait);
 	}
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
 void serio_rescan(struct serio *serio)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&serio_lock, flags);
 	serio_queue_event(serio, SERIO_RESCAN);
-	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 void serio_reconnect(struct serio *serio)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&serio_lock, flags);
 	serio_queue_event(serio, SERIO_RECONNECT);
-	spin_unlock_irqrestore(&serio_lock, flags);
 }
 
 irqreturn_t serio_interrupt(struct serio *serio,
-		unsigned char data, unsigned int flags, struct pt_regs *regs)
+		unsigned char data, unsigned int dfl, struct pt_regs *regs)
 {
+	unsigned long flags;
 	irqreturn_t ret = IRQ_NONE;
 
-	spin_lock_irq(&serio_lock);
+	spin_lock_irqsave(&serio->lock, flags);
 
         if (serio->dev && serio->dev->interrupt) {
-                ret = serio->dev->interrupt(serio, data, flags, regs);
+                ret = serio->dev->interrupt(serio, data, dfl, regs);
 	} else {
-		if (!flags) {
+		if (!dfl) {
 			if ((serio->type != SERIO_8042 &&
 			     serio->type != SERIO_8042_XL) || (data == 0xaa)) {
-				serio_queue_event(serio, SERIO_RESCAN);
+				serio_rescan(serio);
 				ret = IRQ_HANDLED;
 			}
 		}
 	}
-	
-	spin_unlock_irq(&serio_lock);
+
+	spin_unlock_irqrestore(&serio->lock, flags);
 
 	return ret;
 }
@@ -265,6 +265,7 @@
  */
 void __serio_register_port(struct serio *serio)
 {
+	spin_lock_init(&serio->lock);
 	list_add_tail(&serio->node, &serio_list);
 	serio_find_dev(serio);
 }
@@ -330,11 +331,13 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&serio_lock, flags);
+	spin_lock_irqsave(&serio->lock, flags);
 	serio->dev = dev;
-	spin_unlock_irqrestore(&serio_lock, flags);
+	spin_unlock_irqrestore(&serio->lock, flags);
 	if (serio->open && serio->open(serio)) {
+		spin_lock_irqsave(&serio->lock, flags);
 		serio->dev = NULL;
+		spin_unlock_irqrestore(&serio->lock, flags);
 		return -1;
 	}
 	return 0;
@@ -347,9 +350,9 @@
 
 	if (serio->close)
 		serio->close(serio);
-	spin_lock_irqsave(&serio_lock, flags);
+	spin_lock_irqsave(&serio->lock, flags);
 	serio->dev = NULL;
-	spin_unlock_irqrestore(&serio_lock, flags);
+	spin_unlock_irqrestore(&serio->lock, flags);
 }
 
 static int __init serio_init(void)
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:41:50 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:41:50 2004
@@ -17,6 +17,7 @@
 #ifdef __KERNEL__
 
 #include <linux/list.h>
+#include <linux/spinlock.h>
 
 struct serio {
 	void *private;
@@ -31,6 +32,8 @@
 
 	unsigned long type;
 	unsigned long event;
+
+	spinlock_t lock;
 
 	int (*write)(struct serio *, unsigned char);
 	int (*open)(struct serio *);


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

* [PATCH 8/47] Use raw events generated by atkbd in keyboard.c to implement true rawmode for PS/2 keyboards.
  2004-07-29 14:09             ` [PATCH 7/47] Add reporting of raw scancodes to atkbd.c Vojtech Pavlik
@ 2004-07-29 14:09               ` Vojtech Pavlik
  2004-07-29 14:09                 ` [PATCH 9/47] Fixes in serio locking Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.63.3, 2004-05-31 16:25:29+02:00, vojtech@suse.cz
  input: Use raw events generated by atkbd in keyboard.c to implement true
         rawmode for PS/2 keyboards.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 keyboard.c |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

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

diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Thu Jul 29 14:41:55 2004
+++ b/drivers/char/keyboard.c	Thu Jul 29 14:41:55 2004
@@ -942,6 +942,8 @@
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SH_MPC1211)
 
+#define HW_RAW(dev) (((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
+
 static unsigned short x86_keycodes[256] =
 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
 	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
@@ -1008,6 +1010,8 @@
 
 #else
 
+#define HW_RAW(dev)	0
+
 #warning "Cannot generate rawmode keyboard for your architecture yet."
 
 static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
@@ -1020,7 +1024,15 @@
 }
 #endif
 
-void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
+void kbd_rawcode(unsigned char data)
+{
+	struct vc_data *vc = vc_cons[fg_console].d;
+	kbd = kbd_table + fg_console;
+	if (kbd->kbdmode == VC_RAW)
+		put_queue(vc, data);
+}
+
+void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
 	unsigned short keysym, *key_map;
@@ -1054,7 +1066,7 @@
 		return;
 #endif /* CONFIG_MAC_EMUMOUSEBTN */
 
-	if ((raw_mode = (kbd->kbdmode == VC_RAW)))
+	if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
 		if (emulate_raw(vc, keycode, !down << 7))
 			if (keycode < BTN_MISC)
 				printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
@@ -1149,11 +1161,12 @@
 }
 
 static void kbd_event(struct input_handle *handle, unsigned int event_type, 
-		      unsigned int keycode, int down)
+		      unsigned int event_code, int value)
 {
-	if (event_type != EV_KEY)
-		return;
-	kbd_keycode(keycode, down, handle->dev->regs);
+	if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
+		kbd_rawcode(value);
+	if (event_type == EV_KEY)
+		kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
 	tasklet_schedule(&keyboard_tasklet);
 	do_poke_blanked_console = 1;
 	schedule_console_callback();


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

* [PATCH 1/47] Add 64-bit compatible ioctls for hiddev.
  2004-07-29 14:07 [patches] Input updates Vojtech Pavlik
@ 2004-07-29 14:09 ` Vojtech Pavlik
  2004-07-29 14:09   ` [PATCH 2/47] Fix locking in i8042.c and serio.c Vojtech Pavlik
  2004-07-29 16:59 ` [patches] Input updates Vojtech Pavlik
  1 sibling, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.1.20, 2004-05-19 00:13:58+02:00, akropel1@rochester.rr.com
  input: Add 64-bit compatible ioctls for hiddev.


 drivers/usb/input/hiddev.c   |    2 +-
 fs/compat_ioctl.c            |    2 ++
 include/linux/compat_ioctl.h |   17 +++++++++++++++++
 include/linux/hiddev.h       |    8 +++++++-
 4 files changed, 27 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Thu Jul 29 14:42:28 2004
+++ b/drivers/usb/input/hiddev.c	Thu Jul 29 14:42:28 2004
@@ -642,7 +642,7 @@
 				goto inval;
 
 			if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-				if (uref_multi->num_values >= HID_MAX_USAGES || 
+				if (uref_multi->num_values >= HID_MAX_MULTI_USAGES || 
 				    uref->usage_index >= field->maxusage || 
 				   (uref->usage_index + uref_multi->num_values) >= field->maxusage)
 					goto inval;
diff -Nru a/fs/compat_ioctl.c b/fs/compat_ioctl.c
--- a/fs/compat_ioctl.c	Thu Jul 29 14:42:28 2004
+++ b/fs/compat_ioctl.c	Thu Jul 29 14:42:28 2004
@@ -114,6 +114,8 @@
 #include <linux/filter.h>
 #include <linux/msdos_fs.h>
 
+#include <linux/hiddev.h>
+
 #undef INCLUDES
 #endif
 
diff -Nru a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
--- a/include/linux/compat_ioctl.h	Thu Jul 29 14:42:28 2004
+++ b/include/linux/compat_ioctl.h	Thu Jul 29 14:42:28 2004
@@ -720,3 +720,20 @@
 COMPATIBLE_IOCTL(SIOCGIWRETRY)
 COMPATIBLE_IOCTL(SIOCSIWPOWER)
 COMPATIBLE_IOCTL(SIOCGIWPOWER)
+/* hiddev */
+COMPATIBLE_IOCTL(HIDIOCGVERSION)
+COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
+COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
+COMPATIBLE_IOCTL(HIDIOCGSTRING)
+COMPATIBLE_IOCTL(HIDIOCINITREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORT)
+COMPATIBLE_IOCTL(HIDIOCSREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
+COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
+COMPATIBLE_IOCTL(HIDIOCGUSAGE)
+COMPATIBLE_IOCTL(HIDIOCSUSAGE)
+COMPATIBLE_IOCTL(HIDIOCGUCODE)
+COMPATIBLE_IOCTL(HIDIOCGFLAG)
+COMPATIBLE_IOCTL(HIDIOCSFLAG)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
--- a/include/linux/hiddev.h	Thu Jul 29 14:42:28 2004
+++ b/include/linux/hiddev.h	Thu Jul 29 14:42:28 2004
@@ -128,10 +128,11 @@
 
 /* hiddev_usage_ref_multi is used for sending multiple bytes to a control.
  * It really manifests itself as setting the value of consecutive usages */
+#define HID_MAX_MULTI_USAGES 1024
 struct hiddev_usage_ref_multi {
 	struct hiddev_usage_ref uref;
 	__u32 num_values;
-	__s32 values[HID_MAX_USAGES];
+	__s32 values[HID_MAX_MULTI_USAGES];
 };
 
 /* FIELD_INDEX_NONE is returned in read() data from the kernel when flags
@@ -213,6 +214,11 @@
  */
 
 #ifdef CONFIG_USB_HIDDEV
+struct hid_device;
+struct hid_usage;
+struct hid_field;
+struct hid_report;
+
 int hiddev_connect(struct hid_device *);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,


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

* [PATCH 3/47] Fix an oops in poll() on uinput.
  2004-07-29 14:09   ` [PATCH 2/47] Fix locking in i8042.c and serio.c Vojtech Pavlik
@ 2004-07-29 14:09     ` Vojtech Pavlik
  2004-07-29 14:09       ` [PATCH 4/47] Ensure exclusive access to variables in atkbd.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.1.22, 2004-05-28 22:57:43+02:00, vojtech@suse.cz
  input: Fix an oops in poll() on uinput.  Thanks to Dmitry Torokhov
         for suggesting the fix.


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

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

diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c	Thu Jul 29 14:42:19 2004
+++ b/drivers/input/misc/uinput.c	Thu Jul 29 14:42:19 2004
@@ -279,6 +279,9 @@
 {
 	struct uinput_device *udev = file->private_data;
 
+	if (!test_bit(UIST_CREATED, &(udev->state)))
+		return -ENODEV;
+
 	poll_wait(file, &udev->waitq, wait);
 
 	if (udev->head != udev->tail)


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

* [PATCH 5/47] Return 0 from uinput poll if device isn't yet created.
  2004-07-29 14:09       ` [PATCH 4/47] Ensure exclusive access to variables in atkbd.c Vojtech Pavlik
@ 2004-07-29 14:09         ` Vojtech Pavlik
  2004-07-29 14:09           ` [PATCH 6/47] Explicit variable access rules for psmouse.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.54.3, 2004-05-31 12:27:40+02:00, vojtech@suse.cz
  input: Return 0 from uinput poll if device isn't yet created.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c	Thu Jul 29 14:42:09 2004
+++ b/drivers/input/misc/uinput.c	Thu Jul 29 14:42:09 2004
@@ -280,7 +280,7 @@
 	struct uinput_device *udev = file->private_data;
 
 	if (!test_bit(UIST_CREATED, &(udev->state)))
-		return -ENODEV;
+		return 0;
 
 	poll_wait(file, &udev->waitq, wait);
 


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

* [PATCH 4/47] Ensure exclusive access to variables in atkbd.c
  2004-07-29 14:09     ` [PATCH 3/47] Fix an oops in poll() on uinput Vojtech Pavlik
@ 2004-07-29 14:09       ` Vojtech Pavlik
  2004-07-29 14:09         ` [PATCH 5/47] Return 0 from uinput poll if device isn't yet created Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.54.2, 2004-05-30 16:57:22+02:00, vojtech@suse.cz
  input: Make atomicity and exclusive access to variables explicit
  in atkbd.c, using bitops.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 atkbd.c |  133 ++++++++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 89 insertions(+), 44 deletions(-)

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

diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:14 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:42:14 2004
@@ -164,34 +164,48 @@
 	{ ATKBD_SCR_CLICK, 0x60 },
 };
 
+#define ATKBD_FLAG_ACK		0	/* Waiting for ACK/NAK */
+#define ATKBD_FLAG_CMD		1	/* Waiting for command to finish */
+#define ATKBD_FLAG_CMD1		2	/* First byte of command response */
+#define ATKBD_FLAG_ID		3	/* First byte is not keyboard ID */
+#define ATKBD_FLAG_ENABLED	4	/* Waining for init to finish */
+
 /*
  * The atkbd control structure
  */
 
 struct atkbd {
-	unsigned char keycode[512];
-	struct input_dev dev;
-	struct serio *serio;
 
+	/* Written only during init */
 	char name[64];
 	char phys[32];
-	unsigned short id;
+	struct serio *serio;
+	struct input_dev dev;
+
 	unsigned char set;
-	unsigned int translated:1;
-	unsigned int extra:1;
-	unsigned int write:1;
+	unsigned short id;
+	unsigned char keycode[512];
+	unsigned char translated;
+	unsigned char extra;
+	unsigned char write;
+
+	/* Protected by FLAG_ACK */
+	unsigned char nak;
 
+	/* Protected by FLAG_CMD */
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
-	volatile signed char ack;
-	unsigned char emul;
-	unsigned int resend:1;
-	unsigned int release:1;
-	unsigned int bat_xl:1;
-	unsigned int enabled:1;
 
+	/* Accessed only from interrupt */
+	unsigned char emul;
+	unsigned char resend;
+	unsigned char release;
+	unsigned char bat_xl;
 	unsigned int last;
 	unsigned long time;
+
+	/* Flags */
+	unsigned long flags;
 };
 
 static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value)
@@ -224,7 +238,7 @@
 
 #if !defined(__i386__) && !defined (__x86_64__)
 	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
-		printk("atkbd.c: frame/parity error: %02x\n", flags);
+		printk(KERN_WARNING "atkbd.c: frame/parity error: %02x\n", flags);
 		serio_write(serio, ATKBD_CMD_RESEND);
 		atkbd->resend = 1;
 		goto out;
@@ -234,22 +248,36 @@
 		atkbd->resend = 0;
 #endif
 
-	if (!atkbd->ack)
+	if (test_bit(ATKBD_FLAG_ACK, &atkbd->flags))
 		switch (code) {
 			case ATKBD_RET_ACK:
-				atkbd->ack = 1;
+				atkbd->nak = 0;
+				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 				goto out;
 			case ATKBD_RET_NAK:
-				atkbd->ack = -1;
+				atkbd->nak = 1;
+				clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 				goto out;
 		}
 
-	if (atkbd->cmdcnt) {
-		atkbd->cmdbuf[--atkbd->cmdcnt] = code;
+	if (test_bit(ATKBD_FLAG_CMD, &atkbd->flags)) {
+
+		atkbd->cmdcnt--;
+		atkbd->cmdbuf[atkbd->cmdcnt] = code;
+
+		if (atkbd->cmdcnt == 1) {
+		    	if (code != 0xab && code != 0xac)
+				clear_bit(ATKBD_FLAG_ID, &atkbd->flags);
+			clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
+		}
+
+		if (!atkbd->cmdcnt)
+			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+
 		goto out;
 	}
 
-	if (!atkbd->enabled)
+	if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags))
 		goto out;
 
 	if (atkbd->translated) {
@@ -270,6 +298,7 @@
 
 	switch (code) {
 		case ATKBD_RET_BAT:
+			clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 			serio_rescan(atkbd->serio);
 			goto out;
 		case ATKBD_RET_EMUL0:
@@ -376,18 +405,19 @@
 
 static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
 {
-	int timeout = 20000; /* 200 msec */
-	atkbd->ack = 0;
+	int timeout = 200000; /* 200 msec */
 
 #ifdef ATKBD_DEBUG
 	printk(KERN_DEBUG "atkbd.c: Sent: %02x\n", byte);
 #endif
+
+	set_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 	if (serio_write(atkbd->serio, byte))
 		return -1;
+	while (test_bit(ATKBD_FLAG_ACK, &atkbd->flags) && timeout--) udelay(1);
+	clear_bit(ATKBD_FLAG_ACK, &atkbd->flags);
 
-	while (!atkbd->ack && timeout--) udelay(10);
-
-	return -(atkbd->ack <= 0);
+	return -atkbd->nak;
 }
 
 /*
@@ -411,40 +441,52 @@
 		for (i = 0; i < receive; i++)
 			atkbd->cmdbuf[(receive - 1) - i] = param[i];
 
+	if (receive) {
+		set_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+		set_bit(ATKBD_FLAG_CMD1, &atkbd->flags);
+		set_bit(ATKBD_FLAG_ID, &atkbd->flags);
+	}
+
 	if (command & 0xff)
-		if (atkbd_sendbyte(atkbd, command & 0xff))
-			return (atkbd->cmdcnt = 0) - 1;
+		if (atkbd_sendbyte(atkbd, command & 0xff)) {
+			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+			return -1;
+		}
 
 	for (i = 0; i < send; i++)
-		if (atkbd_sendbyte(atkbd, param[i]))
-			return (atkbd->cmdcnt = 0) - 1;
+		if (atkbd_sendbyte(atkbd, param[i])) {
+			clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+			return -1;
+		}
 
-	while (atkbd->cmdcnt && timeout--) {
+	while (test_bit(ATKBD_FLAG_CMD, &atkbd->flags) && timeout--) {
 
-		if (atkbd->cmdcnt == 1 &&
-		    command == ATKBD_CMD_RESET_BAT && timeout > 100000)
-			timeout = 100000;
-
-		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
-		    atkbd->cmdbuf[1] != 0xab && atkbd->cmdbuf[1] != 0xac) {
-			atkbd->cmdcnt = 0;
-			break;
+		if (!test_bit(ATKBD_FLAG_CMD1, &atkbd->flags)) {
+		    
+			if (command == ATKBD_CMD_RESET_BAT && timeout > 100000)
+				timeout = 100000;
+
+			if (command == ATKBD_CMD_GETID && !test_bit(ATKBD_FLAG_ID, &atkbd->flags)) {
+				clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+				atkbd->cmdcnt = 0;
+				break;
+			}
 		}
 
 		udelay(1);
 	}
 
+	clear_bit(ATKBD_FLAG_CMD, &atkbd->flags);
+
 	if (param)
 		for (i = 0; i < receive; i++)
 			param[i] = atkbd->cmdbuf[(receive - 1) - i];
 
 	if (command == ATKBD_CMD_RESET_BAT && atkbd->cmdcnt == 1)
-		atkbd->cmdcnt = 0;
+		return 0;
 
-	if (atkbd->cmdcnt) {
-		atkbd->cmdcnt = 0;
+	if (atkbd->cmdcnt)
 		return -1;
-	}
 
 	return 0;
 }
@@ -672,6 +714,7 @@
 static void atkbd_disconnect(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
+	clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 	input_unregister_device(&atkbd->dev);
 	serio_close(serio);
 	kfree(atkbd);
@@ -719,7 +762,6 @@
 		atkbd->dev.rep[REP_PERIOD] = 33;
 	}
 
-	atkbd->ack = 1;
 	atkbd->serio = serio;
 
 	init_input_dev(&atkbd->dev);
@@ -754,7 +796,6 @@
 		atkbd->id = 0xab00;
 	}
 
-	atkbd->enabled = 1;
 
 	if (atkbd->extra) {
 		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
@@ -797,6 +838,8 @@
 
 	input_register_device(&atkbd->dev);
 
+	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
+
 	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
 }
 
@@ -831,6 +874,8 @@
 		if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
 			return -1;
 	}
+
+	set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags);
 
 	return 0;
 }


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

* [PATCH 10/47] Disable the AUX LoopBack command in i8042.c on Compaq ProLiant
  2004-07-29 14:09                 ` [PATCH 9/47] Fixes in serio locking Vojtech Pavlik
@ 2004-07-29 14:09                   ` Vojtech Pavlik
  2004-07-29 14:09                     ` [PATCH 11/47] Make atkbd.c's atkbd_command() function immune to keys being pressed while running Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.85.1, 2004-06-02 13:44:20+02:00, vojtech@suse.cz
  input: Disable the AUX LoopBack command in i8042.c on Compaq ProLiant
         8-way Xeon ProFusion systems, as it causes crashes and reboots
         on these machines. DMI data is used for determining if the
         workaround should be enabled.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 arch/i386/kernel/dmi_scan.c |   31 +++++++++++++++++++++++++++++++
 drivers/input/serio/i8042.c |   14 +++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

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

diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Thu Jul 29 14:41:45 2004
+++ b/arch/i386/kernel/dmi_scan.c	Thu Jul 29 14:41:45 2004
@@ -15,6 +15,9 @@
 unsigned long dmi_broken;
 EXPORT_SYMBOL(dmi_broken);
 
+unsigned int i8042_dmi_noloop = 0;
+EXPORT_SYMBOL(i8042_dmi_noloop);
+
 int is_sony_vaio_laptop;
 int is_unsafe_smbus;
 int es7000_plat = 0;
@@ -401,6 +404,17 @@
 }
 
 /*
+ * Several HP Proliant (and maybe other OSB4/ProFusion) systems
+ * shouldn't use the AUX LoopBack command, or they crash or reboot.
+ */
+
+static __init int set_8042_noloop(struct dmi_blacklist *d)
+{
+	i8042_dmi_noloop = 1;
+	return 0;
+}
+
+/*
  * This bios swaps the APM minute reporting bytes over (Many sony laptops
  * have this problem).
  */
@@ -874,6 +888,23 @@
 			MATCH(DMI_BIOS_VERSION, "3A71"),
 			NO_MATCH, NO_MATCH,
 			} },
+
+	/*      
+	 * Several HP Proliant (and maybe other OSB4/ProFusion) systems
+	 * can't use i8042 in mux mode, or they crash or reboot.
+	 */                     
+
+	{ set_8042_noloop, "Compaq Proliant 8500", {
+			MATCH(DMI_SYS_VENDOR, "Compaq"),
+			MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			MATCH(DMI_PRODUCT_VERSION, "8500"),
+			NO_MATCH }},
+
+	{ set_8042_noloop, "Compaq Proliant DL760", {
+			MATCH(DMI_SYS_VENDOR, "Compaq"),
+			MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			MATCH(DMI_PRODUCT_VERSION, "DL760"),
+			NO_MATCH }},
 
 #ifdef	CONFIG_ACPI_BOOT
 	/*
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:41:45 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:41:45 2004
@@ -1,7 +1,7 @@
 /*
  *  i8042 keyboard and mouse controller driver for Linux
  *
- *  Copyright (c) 1999-2002 Vojtech Pavlik
+ *  Copyright (c) 1999-2004 Vojtech Pavlik
  */
 
 /*
@@ -52,6 +52,8 @@
 module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
+static unsigned int i8042_noloop;
+
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");
 __obsolete_setup("i8042_unlock");
@@ -154,6 +156,9 @@
 	unsigned long flags;
 	int retval = 0, i = 0;
 
+	if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
+		return -1;
+
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	retval = i8042_wait_write();
@@ -954,6 +959,13 @@
 
 	if (i8042_dumbkbd)
 		i8042_kbd_port.write = NULL;
+
+#ifdef __i386__
+	if (i8042_dmi_noloop) {
+		printk(KERN_INFO "i8042.c: AUX LoopBack command disabled by DMI.\n");
+		i8042_noloop = 1;
+	}
+#endif
 
 	if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
 		if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))


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

* [PATCH 12/47] More locking improvements (and a fix) for serio.
  2004-07-29 14:09                     ` [PATCH 11/47] Make atkbd.c's atkbd_command() function immune to keys being pressed while running Vojtech Pavlik
@ 2004-07-29 14:09                       ` Vojtech Pavlik
  2004-07-29 14:09                         ` [PATCH 13/47] Add a missing dmi_noloop declaration in i8042.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.84.4, 2004-06-02 16:09:25+02:00, vojtech@suse.cz
  input: More locking improvements (and a fix) for serio. This
         merges both my and Dmitry's changes.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 serio.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:41:31 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:41:31 2004
@@ -68,8 +68,8 @@
 };
 
 
-spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
-static DECLARE_MUTEX(serio_sem);			/* protects serio_list and serio_dev_list */
+static spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
+static DECLARE_MUTEX(serio_sem);				/* protects serio_list and serio_dev_list */
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_dev_list);
 static LIST_HEAD(serio_event_list);
@@ -99,16 +99,21 @@
 static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
 static DECLARE_COMPLETION(serio_exited);
 
-static void serio_invalidate_pending_events(struct serio *serio)
+static void serio_remove_pending_events(struct serio *serio)
 {
+	struct list_head *node, *next;
 	struct serio_event *event;
 	unsigned long flags;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
-	list_for_each_entry(event, &serio_event_list, node)
-		if (event->serio == serio)
-			event->serio = NULL;
+	list_for_each_safe(node, next, &serio_event_list) {
+		event = container_of(node, struct serio_event, node);
+		if (event->serio == serio) {
+			list_del_init(node);
+			kfree(event);
+		}
+	}
 
 	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
@@ -137,9 +142,6 @@
 
 		down(&serio_sem);
 
-		if (event->serio == NULL) /*!!!*/
-			goto event_done;
-
 		switch (event->type) {
 			case SERIO_REGISTER_PORT :
 				__serio_register_port(event->serio);
@@ -163,7 +165,7 @@
 			default:
 				break;
 		}
-event_done:
+
 		up(&serio_sem);
 		kfree(event);
 	}
@@ -224,7 +226,7 @@
 
 	spin_lock_irqsave(&serio->lock, flags);
 
-        if (serio->dev && serio->dev->interrupt) {
+        if (likely(serio->dev)) {
                 ret = serio->dev->interrupt(serio, data, dfl, regs);
 	} else {
 		if (!dfl) {
@@ -294,7 +296,7 @@
  */
 void __serio_unregister_port(struct serio *serio)
 {
-	serio_invalidate_pending_events(serio);
+	serio_remove_pending_events(serio);
 	list_del_init(&serio->node);
 	if (serio->dev && serio->dev->disconnect)
 		serio->dev->disconnect(serio);


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

* [PATCH 30/47] Add CodeMercs IOWarrior to hid-core device blacklist
  2004-07-29 14:09                                                         ` [PATCH 29/47] Add Audigy LS PCI ID to emu10k1-gp Vojtech Pavlik
@ 2004-07-29 14:09                                                           ` Vojtech Pavlik
  2004-07-29 14:09                                                             ` [PATCH 31/47] Fix Peter Nelson's e-mail address in gamecon.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.28.15, 2004-06-24 15:44:37+02:00, cr7@os.inf.tu-dresden.de
  input: Add CodeMercs IOWarrior to hid-core device blacklist.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 hid-core.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Thu Jul 29 14:39:51 2004
+++ b/drivers/usb/input/hid-core.c	Thu Jul 29 14:39:51 2004
@@ -1430,6 +1430,11 @@
 #define USB_DEVICE_ID_1_PHIDGETSERVO_20	0x8101
 #define USB_DEVICE_ID_4_PHIDGETSERVO_20	0x8104
 
+#define USB_VENDOR_ID_CODEMERCS		0x07c0
+#define USB_DEVICE_ID_CODEMERCS_IOW40	0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW24	0x1501
+
+
 static struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1444,20 +1449,20 @@
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
-
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
-
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },


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

* [PATCH 25/47] Enhancements/fixes for PSX pad support
  2004-07-29 14:09                                               ` [PATCH 24/47] Remove an extra dmi_noloop declaration in i8042.c Vojtech Pavlik
@ 2004-07-29 14:09                                                 ` Vojtech Pavlik
  2004-07-29 14:09                                                   ` [PATCH 26/47] when probing for ImExPS/2 mice, the ImPS/2 sequence needs to be sent first Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.11, 2004-06-21 08:35:20+02:00, pnelson@andrew.cmu.edu
  input: Enhancements/fixes for PSX pad support:
  
      * Adds support for more than one controller. Previously more than
        one controller was initialized and the docs said they worked, but
        only one was actually read.                                      
      * Removes unnecessary detection on initialization. This allows the
        module to be initialized without controllers plugged in (hot    
        swapping controllers works). This removes a warning if the user
        has an unrecognized controller plugged in, but the only        
        unrecognized controller I have been able to find information about
        online is the PSX mouse, which I've never actually seen.          
      * Adds a GC_DDR option value to have direction presses register as
        buttons instead of axes. Allows the module to be used for Dance
        Dance Revolution emulators like Stepmania.                     
      * Adds psx_* to documentation.   
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>           


 Documentation/input/joystick-parport.txt |   13 +-
 drivers/input/joystick/gamecon.c         |  192 ++++++++++++++++---------------
 2 files changed, 112 insertions(+), 93 deletions(-)

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

diff -Nru a/Documentation/input/joystick-parport.txt b/Documentation/input/joystick-parport.txt
--- a/Documentation/input/joystick-parport.txt	Thu Jul 29 14:40:19 2004
+++ b/Documentation/input/joystick-parport.txt	Thu Jul 29 14:40:19 2004
@@ -335,6 +335,7 @@
  * Analog PSX Pad (red mode)
  * Analog PSX Pad (green mode)
  * PSX Rumble Pad
+ * PSX DDR Pad
 
 2.4 Sega
 ~~~~~~~~
@@ -452,13 +453,21 @@
 	  5  | Multisystem 2-button joystick
 	  6  | N64 pad
 	  7  | Sony PSX controller
+	  8  | Sony PSX DDR controller
 
-  The exact type of the PSX controller type is autoprobed, so you must have
-your controller plugged in before initializing.
+  The exact type of the PSX controller type is autoprobed when used so
+hot swapping should work (but is not recomended).
 
   Should you want to use more than one of parallel ports at once, you can use
 gamecon.map2 and gamecon.map3 as additional command line parameters for two
 more parallel ports.
+
+  There are two options specific to PSX driver portion.  gamecon.psx_delay sets
+the command delay when talking to the controllers. The default of 25 should
+work but you can try lowering it for better performace. If your pads don't
+respond try raising it untill they work. Setting the type to 8 allows the
+driver to be used with Dance Dance Revolution or similar games. Arrow keys are
+registered as key presses instead of X and Y axes.
 
 3.2 db9.c
 ~~~~~~~~~
diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c	Thu Jul 29 14:40:19 2004
+++ b/drivers/input/joystick/gamecon.c	Thu Jul 29 14:40:19 2004
@@ -1,7 +1,8 @@
 /*
- * $Id: gamecon.c,v 1.22 2002/07/01 15:42:25 vojtech Exp $
+ * NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
  *
- *  Copyright (c) 1999-2001 Vojtech Pavlik
+ *  Copyright (c) 1999-2004 	Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2004 		Peter Nelson <pnelson@andrew.cmu.edu>
  *
  *  Based on the work of:
  *  	Andree Borrmann		John Dahlstrom
@@ -9,10 +10,6 @@
  */
 
 /*
- * NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
- */
-
-/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -72,8 +69,9 @@
 #define GC_MULTI2	5
 #define GC_N64		6
 #define GC_PSX		7
+#define GC_DDR		8
 
-#define GC_MAX		7
+#define GC_MAX		8
 
 #define GC_REFRESH_TIME	HZ/100
 
@@ -91,7 +89,8 @@
 static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };
 
 static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick",
-				"Multisystem 2-button joystick", "N64 controller", "PSX controller" };
+				"Multisystem 2-button joystick", "N64 controller", "PSX controller"
+				"PSX DDR controller" };
 /*
  * N64 support.
  */
@@ -237,7 +236,7 @@
 #define GC_PSX_RUMBLE	7		/* Rumble in Red mode */
 
 #define GC_PSX_CLOCK	0x04		/* Pin 4 */
-#define GC_PSX_COMMAND	0x01		/* Pin 1 */
+#define GC_PSX_COMMAND	0x01		/* Pin 2 */
 #define GC_PSX_POWER	0xf8		/* Pins 5-9 */
 #define GC_PSX_SELECT	0x02		/* Pin 3 */
 
@@ -253,25 +252,29 @@
 static short gc_psx_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_HAT0X, ABS_HAT0Y };
 static short gc_psx_btn[] = { BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_A, BTN_B, BTN_X, BTN_Y,
 				BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR };
+static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };
 
 /*
  * gc_psx_command() writes 8bit command and reads 8bit data from
  * the psx pad.
  */
 
-static int gc_psx_command(struct gc *gc, int b)
+static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_PSX_LENGTH])
 {
-	int i, cmd, data = 0;
+	int i, j, cmd, read;
+	for (i = 0; i < 5; i++)
+		data[i] = 0;
 
 	for (i = 0; i < 8; i++, b >>= 1) {
 		cmd = (b & 1) ? GC_PSX_COMMAND : 0;
 		parport_write_data(gc->pd->port, cmd | GC_PSX_POWER);
 		udelay(gc_psx_delay);
-		data |= ((parport_read_status(gc->pd->port) ^ 0x80) & gc->pads[GC_PSX]) ? (1 << i) : 0;
+		read = parport_read_status(gc->pd->port) ^ 0x80;
+		for (j = 0; j < 5; j++)
+			data[j] |= (read & gc_status_bit[j] & gc->pads[GC_PSX]) ? (1 << i) : 0;
 		parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER);
 		udelay(gc_psx_delay);
 	}
-	return data;
 }
 
 /*
@@ -279,30 +282,39 @@
  * device identifier code.
  */
 
-static int gc_psx_read_packet(struct gc *gc, unsigned char *data)
+static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_LENGTH], unsigned char id[5])
 {
-	int i, id;
+	int i, j, max_len = 0;
 	unsigned long flags;
+	unsigned char data2[5];
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);	/* Select pad */
-	udelay(gc_psx_delay * 2);
+	udelay(gc_psx_delay);
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_POWER);			/* Deselect, begin command */
-	udelay(gc_psx_delay * 2);
+	udelay(gc_psx_delay);
 
 	local_irq_save(flags);
 
-	gc_psx_command(gc, 0x01);							/* Access pad */
-	id = gc_psx_command(gc, 0x42);							/* Get device id */
-	if (gc_psx_command(gc, 0) == 0x5a) {						/* Okay? */
-		for (i = 0; i < GC_PSX_LEN(id) * 2; i++)
-			data[i] = gc_psx_command(gc, 0);
-	} else id = 0;
+	gc_psx_command(gc, 0x01, data2);						/* Access pad */
+	gc_psx_command(gc, 0x42, id);							/* Get device ids */
+	gc_psx_command(gc, 0, data2);							/* Dump status */
+
+	for (i =0; i < 5; i++)								/* Find the longest pad */
+		if((gc_status_bit[i] & gc->pads[GC_PSX]) && (GC_PSX_LEN(id[i]) > max_len))
+			max_len = GC_PSX_LEN(id[i]);
+
+	for (i = 0; i < max_len * 2; i++) {						/* Read in all the data */
+		gc_psx_command(gc, 0, data2);
+		for (j = 0; j < 5; j++)
+			data[j][i] = data2[j];
+	}
 
 	local_irq_restore(flags);
 
 	parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER);
 
-	return GC_PSX_ID(id);
+	for(i = 0; i < 5; i++)								/* Set id's to the real value */
+		id[i] = GC_PSX_ID(id[i]);
 }
 
 /*
@@ -316,6 +328,7 @@
 	struct gc *gc = (void *) private;
 	struct input_dev *dev = gc->dev;
 	unsigned char data[GC_MAX_LENGTH];
+	unsigned char data_psx[5][GC_PSX_LENGTH];
 	int i, j, s;
 
 /*
@@ -412,53 +425,72 @@
  * PSX controllers
  */
 
-	if (gc->pads[GC_PSX]) {
+	if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) {
 
-		for (i = 0; i < 5; i++)
-	       		if (gc->pads[GC_PSX] & gc_status_bit[i])
-				break;
+		gc_psx_read_packet(gc, data_psx, data);
 
- 		switch (gc_psx_read_packet(gc, data)) {
+		for (i = 0; i < 5; i++) {
+	 		switch (data[i]) {
 
-			case GC_PSX_RUMBLE:
+				case GC_PSX_RUMBLE:
 
-				input_report_key(dev + i, BTN_THUMBL, ~data[0] & 0x04);
-				input_report_key(dev + i, BTN_THUMBR, ~data[0] & 0x02);
-				input_sync(dev + i);
+					input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);
+					input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);
 
-			case GC_PSX_NEGCON:
-			case GC_PSX_ANALOG:
+				case GC_PSX_NEGCON:
+				case GC_PSX_ANALOG:
 
-				for (j = 0; j < 4; j++)
-					input_report_abs(dev + i, gc_psx_abs[j], data[j + 2]);
+					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+						for(j = 0; j < 4; j++)
+							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+					} else {
+						for (j = 0; j < 4; j++)
+							input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);
 
-				input_report_abs(dev + i, ABS_HAT0X, !(data[0] & 0x20) - !(data[0] & 0x80));
-				input_report_abs(dev + i, ABS_HAT0Y, !(data[0] & 0x40) - !(data[0] & 0x10));
+						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+					}
 
-				for (j = 0; j < 8; j++)
-					input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j));
+					for (j = 0; j < 8; j++)
+						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
 
-				input_report_key(dev + i, BTN_START,  ~data[0] & 0x08);
-				input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01);
+					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
+					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
 
-				input_sync(dev + i);
+					input_sync(dev + i);
 
-				break;
+					break;
 
-			case GC_PSX_NORMAL:
+				case GC_PSX_NORMAL:
+					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+						for(j = 0; j < 4; j++)
+							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+					} else {
+						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
 
-				input_report_abs(dev + i, ABS_X, 128 + !(data[0] & 0x20) * 127 - !(data[0] & 0x80) * 128);
-				input_report_abs(dev + i, ABS_Y, 128 + !(data[0] & 0x40) * 127 - !(data[0] & 0x10) * 128);
+						/* for some reason if the extra axes are left unset they drift */
+						/* for (j = 0; j < 4; j++)
+							input_report_abs(dev + i, gc_psx_abs[j+2], 128);
+						 * This needs to be debugged properly,
+						 * maybe fuzz processing needs to be done in input_sync()
+						 *				 --vojtech
+						 */
+					}
 
-				for (j = 0; j < 8; j++)
-					input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << j));
+					for (j = 0; j < 8; j++)
+						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
 
-				input_report_key(dev + i, BTN_START,  ~data[0] & 0x08);
-				input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01);
+					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
+					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
 
-				input_sync(dev + i);
+					input_sync(dev + i);
 
-				break;
+					break;
+
+				case 0: /* not a pad, ignore */
+					break;
+			}
 		}
 	}
 
@@ -490,8 +522,7 @@
 {
 	struct gc *gc;
 	struct parport *pp;
-	int i, j, psx;
-	unsigned char data[32];
+	int i, j;
 
 	if (config[0] < 0)
 		return NULL;
@@ -588,43 +619,22 @@
 				break;
 
 			case GC_PSX:
+			case GC_DDR:
+				if(config[i + 1] == GC_DDR) {
+					for (j = 0; j < 4; j++)
+						set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);
+				} else {
+					for (j = 0; j < 6; j++) {
+						set_bit(gc_psx_abs[j], gc->dev[i].absbit);
+						gc->dev[i].absmin[gc_psx_abs[j]] = 4;
+						gc->dev[i].absmax[gc_psx_abs[j]] = 252;
+						gc->dev[i].absflat[gc_psx_abs[j]] = 2;
+					}
+				}
 
-				psx = gc_psx_read_packet(gc, data);
+				for (j = 0; j < 12; j++)
+					set_bit(gc_psx_btn[j], gc->dev[i].keybit);
 
-				switch(psx) {
-					case GC_PSX_NEGCON:
-					case GC_PSX_NORMAL:
-					case GC_PSX_ANALOG:
-					case GC_PSX_RUMBLE:
-
-						for (j = 0; j < 6; j++) {
-							psx = gc_psx_abs[j];
-							set_bit(psx, gc->dev[i].absbit);
-							if (j < 4) {
-								gc->dev[i].absmin[psx] = 4;
-								gc->dev[i].absmax[psx] = 252;
-								gc->dev[i].absflat[psx] = 2;
-							} else {
-								gc->dev[i].absmin[psx] = -1;
-								gc->dev[i].absmax[psx] = 1;
-							}
-						}
-
-						for (j = 0; j < 12; j++)
-							set_bit(gc_psx_btn[j], gc->dev[i].keybit);
-
-						break;
-
-					case 0:
-						gc->pads[GC_PSX] &= ~gc_status_bit[i];
-						printk(KERN_ERR "gamecon.c: No PSX controller found.\n");
-						break;
-
-					default:
-						gc->pads[GC_PSX] &= ~gc_status_bit[i];
-						printk(KERN_WARNING "gamecon.c: Unsupported PSX controller %#x,"
-							" please report to <vojtech@ucw.cz>.\n", psx);
-				}
 				break;
 		}
 


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

* [PATCH 29/47] Add Audigy LS PCI ID to emu10k1-gp
  2004-07-29 14:09                                                       ` [PATCH 28/47] Add Dell SB Live! PCI ID to the emu10k1-gp driver Vojtech Pavlik
@ 2004-07-29 14:09                                                         ` Vojtech Pavlik
  2004-07-29 14:09                                                           ` [PATCH 30/47] Add CodeMercs IOWarrior to hid-core device blacklist Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.16, 2004-06-23 22:19:54+02:00, James@superbug.demon.co.uk
  input: Add Audigy LS PCI ID to emu10k1-gp.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 emu10k1-gp.c |    1 +
 1 files changed, 1 insertion(+)

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

diff -Nru a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c
--- a/drivers/input/gameport/emu10k1-gp.c	Thu Jul 29 14:39:56 2004
+++ b/drivers/input/gameport/emu10k1-gp.c	Thu Jul 29 14:39:56 2004
@@ -54,6 +54,7 @@
 	{ 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
 	{ 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
 	{ 0x1102, 0x7004, PCI_ANY_ID, PCI_ANY_ID }, /* Dell SB Live */
+	{ 0x1102, 0x7005, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy LS gameport */
 	{ 0, }
 };
 


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

* [PATCH 14/47] logips2pp - do not call get_model_info 2 times
  2004-07-29 14:09                         ` [PATCH 13/47] Add a missing dmi_noloop declaration in i8042.c Vojtech Pavlik
@ 2004-07-29 14:09                           ` Vojtech Pavlik
  2004-07-29 14:09                             ` [PATCH 15/47] Fix compilation breakage when CONFIG_USB_HIDDEV not defined Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.25.2, 2004-06-02 13:00:58-05:00, dtor_core@ameritech.net
  Input: logips2pp - do not call get_model_info 2 times
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


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

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

diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c	Thu Jul 29 14:41:21 2004
+++ b/drivers/input/mouse/logips2pp.c	Thu Jul 29 14:41:21 2004
@@ -277,7 +277,7 @@
 				protocol = PSMOUSE_PS2TPP;
 			}
 
-		} else if (get_model_info(model) != NULL) {
+		} else if (model_info != NULL) {
 
 			param[0] = param[1] = param[2] = 0;
 			ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */


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

* [PATCH 23/47] Fix bad struct hidinput initialization in hid-tmff.c
  2004-07-29 14:09                                           ` [PATCH 22/47] rearrangements and cleanups in serio.c Vojtech Pavlik
@ 2004-07-29 14:09                                             ` Vojtech Pavlik
  2004-07-29 14:09                                               ` [PATCH 24/47] Remove an extra dmi_noloop declaration in i8042.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.9, 2004-06-17 08:38:07+02:00, zinx@epicsol.org
  input: Fix bad struct hidinput initialization in hid-tmff.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
--- a/drivers/usb/input/hid-tmff.c	Thu Jul 29 14:40:32 2004
+++ b/drivers/usb/input/hid-tmff.c	Thu Jul 29 14:40:32 2004
@@ -110,7 +110,7 @@
 {
 	struct tmff_device *private;
 	struct list_head *pos;
-	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
+	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
 
 	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
 	if (!private)


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

* [PATCH 20/47] mousedev - implement tapping for touchpads
  2004-07-29 14:09                                     ` [PATCH 19/47] mousedev - better handle button presses when under load Vojtech Pavlik
@ 2004-07-29 14:09                                       ` Vojtech Pavlik
  2004-07-29 14:09                                         ` [PATCH 21/47] Remove OSB4/Profusion hack in i8042 Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.25.4, 2004-06-06 11:37:05-05:00, dtor_core@ameritech.net
  Input: mousedev - implement tapping for touchpads working in absolute
         mode, such as Synaptics
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 Documentation/kernel-parameters.txt |    6 +++++
 drivers/input/mouse/Kconfig         |    2 -
 drivers/input/mousedev.c            |   38 +++++++++++++++++++++++++++++-------
 3 files changed, 37 insertions(+), 9 deletions(-)

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

diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Thu Jul 29 14:40:47 2004
+++ b/Documentation/kernel-parameters.txt	Thu Jul 29 14:40:47 2004
@@ -652,6 +652,12 @@
 
 	mga=		[HW,DRM]
 
+	mousedev.tap_time=
+			[MOUSE] Maximum time between finger touching and
+			leaving touchpad surface for touch to be considered
+			a tap and be reported as a left button click (for
+			touchpads working in absolute mode only).
+			Format: <msecs>
 	mousedev.xres=	[MOUSE] Horizontal screen resolution, used for devices
 			reporting absolute coordinates, such as tablets
 	mousedev.yres=	[MOUSE] Vertical screen resolution, used for devices
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	Thu Jul 29 14:40:47 2004
+++ b/drivers/input/mouse/Kconfig	Thu Jul 29 14:40:47 2004
@@ -30,8 +30,6 @@
 	  and a new verion of GPM at:
 		http://www.geocities.com/dt_or/gpm/gpm.html
 	  to take advantage of the advanced features of the touchpad.
-	  If you do not want install specialized drivers but want tapping
-	  working please use option psmouse.proto=imps.
 
 	  If unsure, say Y.
 
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Thu Jul 29 14:40:47 2004
+++ b/drivers/input/mousedev.c	Thu Jul 29 14:40:47 2004
@@ -48,6 +48,10 @@
 module_param(yres, uint, 0);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
+static unsigned tap_time = 200;
+module_param(tap_time, uint, 0);
+MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
+
 struct mousedev_motion {
 	int dx, dy, dz;
 	unsigned long buttons;
@@ -65,7 +69,7 @@
 	struct mousedev_motion packet;
 	unsigned int pkt_count;
 	int old_x[4], old_y[4];
-	unsigned int touch;
+	unsigned long touch;
 };
 
 enum mousedev_emul {
@@ -216,6 +220,30 @@
 	wake_up_interruptible(&mousedev->wait);
 }
 
+static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
+{
+	if (!value) {
+		if (mousedev->touch &&
+		    !time_after(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
+			/*
+			 * Toggle left button to emulate tap.
+			 * We rely on the fact that mousedev_mix always has 0
+			 * motion packet so we won't mess current position.
+			 */
+			set_bit(0, &mousedev->packet.buttons);
+			set_bit(0, &mousedev_mix.packet.buttons);
+			mousedev_notify_readers(mousedev, &mousedev_mix.packet);
+			mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
+			clear_bit(0, &mousedev->packet.buttons);
+			clear_bit(0, &mousedev_mix.packet.buttons);
+		}
+		mousedev->touch = mousedev->pkt_count = 0;
+	}
+	else
+		if (!mousedev->touch)
+			mousedev->touch = jiffies;
+}
+
 static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
 	struct mousedev *mousedev = handle->private;
@@ -239,12 +267,8 @@
 
 		case EV_KEY:
 			if (value != 2) {
-				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
-					/* Handle touchpad data */
-					mousedev->touch = value;
-					if (!mousedev->touch)
-						mousedev->pkt_count = 0;
-				}
+				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+					mousedev_touchpad_touch(mousedev, value);
 				else
 					mousedev_key_event(mousedev, code, value);
 			}


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

* [PATCH 21/47] Remove OSB4/Profusion hack in i8042
  2004-07-29 14:09                                       ` [PATCH 20/47] mousedev - implement tapping for touchpads Vojtech Pavlik
@ 2004-07-29 14:09                                         ` Vojtech Pavlik
  2004-07-29 14:09                                           ` [PATCH 22/47] rearrangements and cleanups in serio.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.110.26, 2004-06-06 20:13:56+02:00, vojtech@suse.cz
  input: Remove OSB4/Profusion hack in i8042, as it's handled by
         DMI blacklist now.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 i8042.c |   11 +----------
 1 files changed, 1 insertion(+), 10 deletions(-)

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:40:42 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:40:42 2004
@@ -481,17 +481,8 @@
 	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
 		return -1;
 	param = 0xa4;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
-
-/*
- * Do another loop test with the 0x5a value. Doing anything else upsets
- * Profusion/ServerWorks OSB4 chipsets.
- */
-
-		param = 0x5a;
-		i8042_command(&param, I8042_CMD_AUX_LOOP);
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
 		return -1;
-	}
 
 	if (mux_version)
 		*mux_version = ~param;


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

* [PATCH 19/47] mousedev - better handle button presses when under load
  2004-07-29 14:09                                   ` [PATCH 18/47] Updates to the tsdev driver (raw protocol, calib ioctls, ...) Vojtech Pavlik
@ 2004-07-29 14:09                                     ` Vojtech Pavlik
  2004-07-29 14:09                                       ` [PATCH 20/47] mousedev - implement tapping for touchpads Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1612.25.3, 2004-06-06 11:34:24-05:00, dtor_core@ameritech.net
  Input: mousedev - better handle button presses when under load
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 mousedev.c |  152 +++++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 104 insertions(+), 48 deletions(-)

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

diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Thu Jul 29 14:40:52 2004
+++ b/drivers/input/mousedev.c	Thu Jul 29 14:40:52 2004
@@ -50,6 +50,7 @@
 
 struct mousedev_motion {
 	int dx, dy, dz;
+	unsigned long buttons;
 };
 
 struct mousedev {
@@ -62,21 +63,31 @@
 	struct input_handle handle;
 
 	struct mousedev_motion packet;
-	unsigned long buttons;
 	unsigned int pkt_count;
 	int old_x[4], old_y[4];
 	unsigned int touch;
 };
 
+enum mousedev_emul {
+	MOUSEDEV_EMUL_PS2,
+	MOUSEDEV_EMUL_IMPS,
+	MOUSEDEV_EMUL_EXPS
+} __attribute__ ((packed));
+
+#define PACKET_QUEUE_LEN	16
 struct mousedev_list {
 	struct fasync_struct *fasync;
 	struct mousedev *mousedev;
 	struct list_head node;
-	int dx, dy, dz;
-	unsigned long buttons;
+
+	struct mousedev_motion packets[PACKET_QUEUE_LEN];
+	unsigned int head, tail;
+	spinlock_t packet_lock;
+
 	signed char ps2[6];
 	unsigned char ready, buffer, bufsiz;
-	unsigned char mode, imexseq, impsseq;
+	unsigned char imexseq, impsseq;
+	enum mousedev_emul mode;
 };
 
 #define MOUSEDEV_SEQ_LEN	6
@@ -165,24 +176,40 @@
 	}
 
 	if (value) {
-		set_bit(index, &mousedev->buttons);
-		set_bit(index, &mousedev_mix.buttons);
+		set_bit(index, &mousedev->packet.buttons);
+		set_bit(index, &mousedev_mix.packet.buttons);
 	} else {
-		clear_bit(index, &mousedev->buttons);
-		clear_bit(index, &mousedev_mix.buttons);
+		clear_bit(index, &mousedev->packet.buttons);
+		clear_bit(index, &mousedev_mix.packet.buttons);
 	}
 }
 
 static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
 	struct mousedev_list *list;
+	struct mousedev_motion *p;
+	unsigned long flags;
 
 	list_for_each_entry(list, &mousedev->list, node) {
-		list->dx += packet->dx;
-		list->dy += packet->dy;
-		list->dz += packet->dz;
-		list->buttons = mousedev->buttons;
+		spin_lock_irqsave(&list->packet_lock, flags);
+
+		p = &list->packets[list->head];
+		if (list->ready && p->buttons != packet->buttons) {
+			unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN;
+			if (new_head != list->tail) {
+				p = &list->packets[list->head = new_head];
+				memset(p, 0, sizeof(struct mousedev_motion));
+			}
+		}
+
+		p->dx += packet->dx;
+		p->dy += packet->dy;
+		p->dz += packet->dz;
+		p->buttons = mousedev->packet.buttons;
+
 		list->ready = 1;
+
+		spin_unlock_irqrestore(&list->packet_lock, flags);
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
 
@@ -237,7 +264,7 @@
 				mousedev_notify_readers(mousedev, &mousedev->packet);
 				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
-				memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+				mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
 			}
 			break;
 	}
@@ -322,6 +349,7 @@
 		return -ENOMEM;
 	memset(list, 0, sizeof(struct mousedev_list));
 
+	spin_lock_init(&list->packet_lock);
 	list->mousedev = mousedev_table[i];
 	list_add_tail(&list->node, &mousedev_table[i]->list);
 	file->private_data = list;
@@ -341,32 +369,56 @@
 	return 0;
 }
 
-static void mousedev_packet(struct mousedev_list *list, unsigned char off)
+static inline int mousedev_limit_delta(int delta, int limit)
 {
-	list->ps2[off] = 0x08 | ((list->dx < 0) << 4) | ((list->dy < 0) << 5) | (list->buttons & 0x07);
-	list->ps2[off + 1] = (list->dx > 127 ? 127 : (list->dx < -127 ? -127 : list->dx));
-	list->ps2[off + 2] = (list->dy > 127 ? 127 : (list->dy < -127 ? -127 : list->dy));
-	list->dx -= list->ps2[off + 1];
-	list->dy -= list->ps2[off + 2];
-	list->bufsiz = off + 3;
-
-	if (list->mode == 2) {
-		list->ps2[off + 3] = (list->dz > 7 ? 7 : (list->dz < -7 ? -7 : list->dz));
-		list->dz -= list->ps2[off + 3];
-		list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
-		list->bufsiz++;
-	} else {
-		list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
+	return delta > limit ? limit : (delta < -limit ? -limit : delta);
+}
+
+static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data)
+{
+	struct mousedev_motion *p;
+	unsigned long flags;
+
+	spin_lock_irqsave(&list->packet_lock, flags);
+	p = &list->packets[list->tail];
+
+	ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
+	ps2_data[1] = mousedev_limit_delta(p->dx, 127);
+	ps2_data[2] = mousedev_limit_delta(p->dy, 127);
+	p->dx -= ps2_data[1];
+	p->dy -= ps2_data[2];
+
+	switch (list->mode) {
+		case MOUSEDEV_EMUL_EXPS:
+			ps2_data[3] = mousedev_limit_delta(p->dz, 127);
+			p->dz -= ps2_data[3];
+			ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
+			list->bufsiz = 4;
+			break;
+
+		case MOUSEDEV_EMUL_IMPS:
+			ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+			ps2_data[3] = mousedev_limit_delta(p->dz, 127);
+			p->dz -= ps2_data[3];
+			list->bufsiz = 4;
+			break;
+
+		case MOUSEDEV_EMUL_PS2:
+		default:
+			ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+			p->dz = 0;
+			list->bufsiz = 3;
+			break;
 	}
 
-	if (list->mode == 1) {
-		list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
-		list->dz -= list->ps2[off + 3];
-		list->bufsiz++;
+	if (!p->dx && !p->dy && !p->dz) {
+		if (list->tail != list->head)
+			list->tail = (list->tail + 1) % PACKET_QUEUE_LEN;
+		if (list->tail == list->head)
+			list->ready = 0;
 	}
 
-	if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready = 0;
-	list->buffer = list->bufsiz;
+	spin_unlock_irqrestore(&list->packet_lock, flags);
 }
 
 
@@ -384,31 +436,31 @@
 		if (c == mousedev_imex_seq[list->imexseq]) {
 			if (++list->imexseq == MOUSEDEV_SEQ_LEN) {
 				list->imexseq = 0;
-				list->mode = 2;
+				list->mode = MOUSEDEV_EMUL_EXPS;
 			}
 		} else list->imexseq = 0;
 
 		if (c == mousedev_imps_seq[list->impsseq]) {
 			if (++list->impsseq == MOUSEDEV_SEQ_LEN) {
 				list->impsseq = 0;
-				list->mode = 1;
+				list->mode = MOUSEDEV_EMUL_IMPS;
 			}
 		} else list->impsseq = 0;
 
 		list->ps2[0] = 0xfa;
-		list->bufsiz = 1;
 
 		switch (c) {
 
 			case 0xeb: /* Poll */
-				mousedev_packet(list, 1);
+				mousedev_packet(list, &list->ps2[1]);
+				list->bufsiz++; /* account for leading ACK */
 				break;
 
 			case 0xf2: /* Get ID */
 				switch (list->mode) {
-					case 0: list->ps2[1] = 0; break;
-					case 1: list->ps2[1] = 3; break;
-					case 2: list->ps2[1] = 4; break;
+					case MOUSEDEV_EMUL_PS2:  list->ps2[1] = 0; break;
+					case MOUSEDEV_EMUL_IMPS: list->ps2[1] = 3; break;
+					case MOUSEDEV_EMUL_EXPS: list->ps2[1] = 4; break;
 				}
 				list->bufsiz = 2;
 				break;
@@ -419,13 +471,15 @@
 				break;
 
 			case 0xff: /* Reset */
-				list->impsseq = 0;
-				list->imexseq = 0;
-				list->mode = 0;
-				list->ps2[1] = 0xaa;
-				list->ps2[2] = 0x00;
+				list->impsseq = list->imexseq = 0;
+				list->mode = MOUSEDEV_EMUL_PS2;
+				list->ps2[1] = 0xaa; list->ps2[2] = 0x00;
 				list->bufsiz = 3;
 				break;
+
+			default:
+				list->bufsiz = 1;
+				break;
 		}
 
 		list->buffer = list->bufsiz;
@@ -451,8 +505,10 @@
 	if (retval)
 		return retval;
 
-	if (!list->buffer && list->ready)
-		mousedev_packet(list, 0);
+	if (!list->buffer && list->ready) {
+		mousedev_packet(list, list->ps2);
+		list->buffer = list->bufsiz;
+	}
 
 	if (count > list->buffer)
 		count = list->buffer;


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

* [PATCH 27/47] Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128
  2004-07-29 14:09                                                   ` [PATCH 26/47] when probing for ImExPS/2 mice, the ImPS/2 sequence needs to be sent first Vojtech Pavlik
@ 2004-07-29 14:09                                                     ` Vojtech Pavlik
  2004-07-29 14:09                                                       ` [PATCH 28/47] Add Dell SB Live! PCI ID to the emu10k1-gp driver Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.14, 2004-06-23 08:06:20+02:00, vojtech@suse.cz
  input: Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 keyboard.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

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

diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Thu Jul 29 14:40:08 2004
+++ b/drivers/char/keyboard.c	Thu Jul 29 14:40:08 2004
@@ -124,7 +124,7 @@
  */
 
 static struct input_handler kbd_handler;
-static unsigned long key_down[256/BITS_PER_LONG];	/* keyboard key bitmap */
+static unsigned long key_down[NBITS(KEY_MAX)];		/* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];		/* shift state counters.. */
 static int dead_key_next;
 static int npadch = -1;					/* -1 or number assembled on pad */
@@ -143,7 +143,7 @@
 /* Simple translation table for the SysRq keys */
 
 #ifdef CONFIG_MAGIC_SYSRQ
-unsigned char kbd_sysrq_xlate[128] =
+unsigned char kbd_sysrq_xlate[KEY_MAX] =
         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
@@ -1132,6 +1132,9 @@
 		kbd->slockstate = 0;
 		return;
 	}
+
+	if (keycode > NR_KEYS)
+		return;
 
 	keysym = key_map[keycode];
 	type = KTYP(keysym);


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

* [PATCH 13/47] Add a missing dmi_noloop declaration in i8042.c
  2004-07-29 14:09                       ` [PATCH 12/47] More locking improvements (and a fix) for serio Vojtech Pavlik
@ 2004-07-29 14:09                         ` Vojtech Pavlik
  2004-07-29 14:09                           ` [PATCH 14/47] logips2pp - do not call get_model_info 2 times Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.84.5, 2004-06-02 16:30:53+02:00, vojtech@suse.cz
  input: Add a missong dmi_noloop declaration in i8042.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:41:26 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:41:26 2004
@@ -53,6 +53,7 @@
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
 static unsigned int i8042_noloop;
+extern unsigned int i8042_dmi_noloop;
 
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");


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

* [PATCH 15/47] Fix compilation breakage when CONFIG_USB_HIDDEV not defined
  2004-07-29 14:09                           ` [PATCH 14/47] logips2pp - do not call get_model_info 2 times Vojtech Pavlik
@ 2004-07-29 14:09                             ` Vojtech Pavlik
  2004-07-29 14:09                               ` [PATCH 16/47] Make hardware rawmode optional for AT-keyboards Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.106.1, 2004-06-04 07:18:00+02:00, wli@holomorphy.com
  input: Move CONFIG_USB_HIDDEV a little lower in hiddev.h, to fix
         compilation breakage when it is not defined.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 hiddev.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
--- a/include/linux/hiddev.h	Thu Jul 29 14:41:17 2004
+++ b/include/linux/hiddev.h	Thu Jul 29 14:41:17 2004
@@ -213,12 +213,12 @@
  * In-kernel definitions.
  */
 
-#ifdef CONFIG_USB_HIDDEV
 struct hid_device;
 struct hid_usage;
 struct hid_field;
 struct hid_report;
 
+#ifdef CONFIG_USB_HIDDEV
 int hiddev_connect(struct hid_device *);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,


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

* [PATCH 24/47] Remove an extra dmi_noloop declaration in i8042.c
  2004-07-29 14:09                                             ` [PATCH 23/47] Fix bad struct hidinput initialization in hid-tmff.c Vojtech Pavlik
@ 2004-07-29 14:09                                               ` Vojtech Pavlik
  2004-07-29 14:09                                                 ` [PATCH 25/47] Enhancements/fixes for PSX pad support Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.10, 2004-06-21 07:48:47+02:00, vojtech@suse.cz
  input: Remove an extra dmi_noloop declaration in i8042.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:40:26 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:40:26 2004
@@ -52,9 +52,10 @@
 module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
+#ifdef __i386__
 extern unsigned int i8042_dmi_noloop;
+#endif
 static unsigned int i8042_noloop;
-extern unsigned int i8042_dmi_noloop;
 
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");


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

* [PATCH 22/47] rearrangements and cleanups in serio.c
  2004-07-29 14:09                                         ` [PATCH 21/47] Remove OSB4/Profusion hack in i8042 Vojtech Pavlik
@ 2004-07-29 14:09                                           ` Vojtech Pavlik
  2004-07-29 14:09                                             ` [PATCH 23/47] Fix bad struct hidinput initialization in hid-tmff.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.152.2, 2004-06-12 13:55:01+02:00, vojtech@suse.cz
  Input: rearrangements and cleanups in serio.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 serio.c |  191 ++++++++++++++++++++++++++++++++++------------------------------
 1 files changed, 102 insertions(+), 89 deletions(-)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:40:37 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:40:37 2004
@@ -1,11 +1,9 @@
 /*
- * $Id: serio.c,v 1.15 2002/01/22 21:12:03 vojtech Exp $
- *
- *  Copyright (c) 1999-2001 Vojtech Pavlik
- */
-
-/*
  *  The Serio abstraction module
+ *
+ *  Copyright (c) 1999-2004 Vojtech Pavlik
+ *  Copyright (c) 2004 Dmitry Torokhov
+ *  Copyright (c) 2003 Daniele Bellucci
  */
 
 /*
@@ -26,10 +24,6 @@
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- *
- * Changes:
- * 20 Jul. 2003    Daniele Bellucci <bellucda@tiscali.it>
- *                 Minor cleanups.
  */
 
 #include <linux/stddef.h>
@@ -61,23 +55,11 @@
 EXPORT_SYMBOL(serio_rescan);
 EXPORT_SYMBOL(serio_reconnect);
 
-struct serio_event {
-	int type;
-	struct serio *serio;
-	struct list_head node;
-};
-
-
-static spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
 static DECLARE_MUTEX(serio_sem);				/* protects serio_list and serio_dev_list */
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_dev_list);
-static LIST_HEAD(serio_event_list);
-static int serio_pid;
 
-/*
- * serio_find_dev() must be called with serio_sem down.
- */
+/* serio_find_dev() must be called with serio_sem down.  */
 
 static void serio_find_dev(struct serio *serio)
 {
@@ -91,54 +73,74 @@
 	}
 }
 
-#define SERIO_RESCAN		1
-#define SERIO_RECONNECT		2
-#define SERIO_REGISTER_PORT	3
-#define SERIO_UNREGISTER_PORT	4
+/*
+ * Serio event processing.
+ */
 
+struct serio_event {
+	int type;
+	struct serio *serio;
+	struct list_head node;
+};
+
+enum serio_event_type {
+	SERIO_RESCAN,
+	SERIO_RECONNECT,
+	SERIO_REGISTER_PORT,
+	SERIO_UNREGISTER_PORT,
+};
+
+static spinlock_t serio_event_lock = SPIN_LOCK_UNLOCKED;	/* protects serio_event_list */
+static LIST_HEAD(serio_event_list);
 static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
 static DECLARE_COMPLETION(serio_exited);
+static int serio_pid;
 
-static void serio_remove_pending_events(struct serio *serio)
+static void serio_queue_event(struct serio *serio, int event_type)
 {
-	struct list_head *node, *next;
-	struct serio_event *event;
 	unsigned long flags;
+	struct serio_event *event;
 
 	spin_lock_irqsave(&serio_event_lock, flags);
 
-	list_for_each_safe(node, next, &serio_event_list) {
-		event = container_of(node, struct serio_event, node);
-		if (event->serio == serio) {
-			list_del_init(node);
-			kfree(event);
-		}
+	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
+		event->type = event_type;
+		event->serio = serio;
+
+		list_add_tail(&event->node, &serio_event_list);
+		wake_up(&serio_wait);
 	}
 
 	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
-void serio_handle_events(void)
+static struct serio_event *serio_get_event(void)
 {
-	struct list_head *node;
 	struct serio_event *event;
+	struct list_head *node;
 	unsigned long flags;
 
+	spin_lock_irqsave(&serio_event_lock, flags);
 
-	while (1) {
+	if (list_empty(&serio_event_list)) {
+		spin_unlock_irqrestore(&serio_event_lock, flags);
+		return NULL;
+	}
 
-		spin_lock_irqsave(&serio_event_lock, flags);
+	node = serio_event_list.next;
+	event = container_of(node, struct serio_event, node);
+	list_del_init(node);
 
-		if (list_empty(&serio_event_list)) {
-			spin_unlock_irqrestore(&serio_event_lock, flags);
-			break;
-		}
+	spin_unlock_irqrestore(&serio_event_lock, flags);
 
-		node = serio_event_list.next;
-		event = container_of(node, struct serio_event, node);
-		list_del_init(node);
+	return event;
+}
 
-		spin_unlock_irqrestore(&serio_event_lock, flags);
+static void serio_handle_events(void)
+{
+	struct serio_event *event;
+
+	while ((event = serio_get_event())) {
 
 		down(&serio_sem);
 
@@ -171,6 +173,26 @@
 	}
 }
 
+static void serio_remove_pending_events(struct serio *serio)
+{
+	struct list_head *node, *next;
+	struct serio_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&serio_event_lock, flags);
+
+	list_for_each_safe(node, next, &serio_event_list) {
+		event = container_of(node, struct serio_event, node);
+		if (event->serio == serio) {
+			list_del_init(node);
+			kfree(event);
+		}
+	}
+
+	spin_unlock_irqrestore(&serio_event_lock, flags);
+}
+
+
 static int serio_thread(void *nothing)
 {
 	lock_kernel();
@@ -190,23 +212,10 @@
 	complete_and_exit(&serio_exited, 0);
 }
 
-static void serio_queue_event(struct serio *serio, int event_type)
-{
-	unsigned long flags;
-	struct serio_event *event;
-
-	spin_lock_irqsave(&serio_event_lock, flags);
-
-	if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
-		event->type = event_type;
-		event->serio = serio;
-
-		list_add_tail(&event->node, &serio_event_list);
-		wake_up(&serio_wait);
-	}
 
-	spin_unlock_irqrestore(&serio_event_lock, flags);
-}
+/*
+ * Serio port operations
+ */
 
 void serio_rescan(struct serio *serio)
 {
@@ -218,31 +227,6 @@
 	serio_queue_event(serio, SERIO_RECONNECT);
 }
 
-irqreturn_t serio_interrupt(struct serio *serio,
-		unsigned char data, unsigned int dfl, struct pt_regs *regs)
-{
-	unsigned long flags;
-	irqreturn_t ret = IRQ_NONE;
-
-	spin_lock_irqsave(&serio->lock, flags);
-
-        if (likely(serio->dev)) {
-                ret = serio->dev->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;
-			}
-		}
-	}
-
-	spin_unlock_irqrestore(&serio->lock, flags);
-
-	return ret;
-}
-
 void serio_register_port(struct serio *serio)
 {
 	down(&serio_sem);
@@ -302,6 +286,10 @@
 		serio->dev->disconnect(serio);
 }
 
+/*
+ * Serio device operations
+ */
+
 void serio_register_device(struct serio_dev *dev)
 {
 	struct serio *serio;
@@ -355,6 +343,31 @@
 	spin_lock_irqsave(&serio->lock, flags);
 	serio->dev = NULL;
 	spin_unlock_irqrestore(&serio->lock, flags);
+}
+
+irqreturn_t serio_interrupt(struct serio *serio,
+		unsigned char data, unsigned int dfl, struct pt_regs *regs)
+{
+	unsigned long flags;
+	irqreturn_t ret = IRQ_NONE;
+
+	spin_lock_irqsave(&serio->lock, flags);
+
+        if (likely(serio->dev)) {
+                ret = serio->dev->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;
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&serio->lock, flags);
+
+	return ret;
 }
 
 static int __init serio_init(void)


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

* [PATCH 26/47] when probing for ImExPS/2 mice, the ImPS/2 sequence needs to be sent first
  2004-07-29 14:09                                                 ` [PATCH 25/47] Enhancements/fixes for PSX pad support Vojtech Pavlik
@ 2004-07-29 14:09                                                   ` Vojtech Pavlik
  2004-07-29 14:09                                                     ` [PATCH 27/47] Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128 Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.13, 2004-06-21 20:31:56+02:00, vojtech@suse.cz
  input: when probing for ImExPS/2 mice, the ImPS/2 sequence needs
         to be sent first, but the result should be ignored.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 psmouse-base.c |    2 ++
 1 files changed, 2 insertions(+)

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

diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:40:13 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:40:13 2004
@@ -418,6 +418,8 @@
 {
 	unsigned char param[2];
 
+	intellimouse_detect(psmouse);
+
 	param[0] = 200;
 	psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
 	param[0] = 200;


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

* [PATCH 18/47] Updates to the tsdev driver (raw protocol, calib ioctls, ...)
  2004-07-29 14:09                                 ` [PATCH 17/47] Fix boundary checks for GUSAGE/SUSAGE in hiddev Vojtech Pavlik
@ 2004-07-29 14:09                                   ` Vojtech Pavlik
  2004-07-29 14:09                                     ` [PATCH 19/47] mousedev - better handle button presses when under load Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.117.5, 2004-06-06 11:56:42+02:00, zap@homelink.ru
  input: 
  
  From: Andrew Zabolotny <zap@homelink.ru>
  
  - Implement the 'raw' touchscreen protocol for backward compatibility
    (/dev/input/ts[0-7] now speaks the protocol of the old /dev/h3600_ts, and
    the /dev/input/tsraw[0-7] speaks the protocol of the old /dev/h3600_tsraw
    device).
  
  - Support the ioctls for setting the calibration parameters.  The default
    calibration matrix is computed from the xres,yres parameters (duplicate the
    old behaviour), however this is not enough for a good translation from
    touchscreen space to screen space.
  
  - Fixed a old bug in tsdev: on a pen motion event X1,Y1 -> X2,Y2 the driver
    would output three events with coordinates: X1,Y1, X2,Y1, X2,Y2.  This
    happened not only with coordinates, but with pressure too.
  
  - Update James's email address
  
  - Remove mention of Transvirtual Technologies: they no longer exist.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 tsdev.c |  291 ++++++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 186 insertions(+), 105 deletions(-)

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

diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c
--- a/drivers/input/tsdev.c	Thu Jul 29 14:40:58 2004
+++ b/drivers/input/tsdev.c	Thu Jul 29 14:40:58 2004
@@ -3,9 +3,17 @@
  *
  *  Copyright (c) 2001 "Crazy" james Simmons 
  *
- *  Input driver to Touchscreen device driver module.
+ *  Compaq touchscreen protocol driver. The protocol emulated by this driver
+ *  is obsolete; for new programs use the tslib library which can read directly
+ *  from evdev and perform dejittering, variance filtering and calibration -
+ *  all in user space, not at kernel level. The meaning of this driver is
+ *  to allow usage of newer input drivers with old applications that use the
+ *  old /dev/h3600_ts and /dev/h3600_tsraw devices.
  *
- *  Sponsored by Transvirtual Technology
+ *  09-Apr-2004: Andrew Zabolotny <zap@homelink.ru>
+ *      Fixed to actually work, not just output random numbers.
+ *      Added support for both h3600_ts and h3600_tsraw protocol
+ *      emulation.
  */
 
 /*
@@ -24,11 +32,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <jsimmons@transvirtual.com>.
+ * e-mail - mail your message to <jsimmons@infradead.org>.
  */
 
 #define TSDEV_MINOR_BASE 	128
 #define TSDEV_MINORS		32
+/* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */
+#define TSDEV_MINOR_MASK	15
 #define TSDEV_BUFFER_SIZE	64
 
 #include <linux/slab.h>
@@ -52,48 +62,84 @@
 #define CONFIG_INPUT_TSDEV_SCREEN_Y	320
 #endif
 
+/* This driver emulates both protocols of the old h3600_ts and h3600_tsraw
+ * devices. The first one must output X/Y data in 'cooked' format, e.g.
+ * filtered, dejittered and calibrated. Second device just outputs raw
+ * data received from the hardware.
+ *
+ * This driver doesn't support filtering and dejittering; it supports only
+ * calibration. Filtering and dejittering must be done in the low-level
+ * driver, if needed, because it may gain additional benefits from knowing
+ * the low-level details, the nature of noise and so on.
+ *
+ * The driver precomputes a calibration matrix given the initial xres and
+ * yres values (quite innacurate for most touchscreens) that will result
+ * in a more or less expected range of output values. The driver supports
+ * the TS_SET_CAL ioctl, which will replace the calibration matrix with a
+ * new one, supposedly generated from the values taken from the raw device.
+ */
+
 MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
 MODULE_DESCRIPTION("Input driver to touchscreen converter");
 MODULE_LICENSE("GPL");
 
 static int xres = CONFIG_INPUT_TSDEV_SCREEN_X;
 module_param(xres, uint, 0);
-MODULE_PARM_DESC(xres, "Horizontal screen resolution");
+MODULE_PARM_DESC(xres, "Horizontal screen resolution (can be negative for X-mirror)");
 
 static int yres = CONFIG_INPUT_TSDEV_SCREEN_Y;
 module_param(yres, uint, 0);
-MODULE_PARM_DESC(yres, "Vertical screen resolution");
+MODULE_PARM_DESC(yres, "Vertical screen resolution (can be negative for Y-mirror)");
+
+/* From Compaq's Touch Screen Specification version 0.2 (draft) */
+struct ts_event {
+	short pressure;
+	short x;
+	short y;
+	short millisecs;
+};
+
+struct ts_calibration {
+	int xscale;
+	int xtrans;
+	int yscale;
+	int ytrans;
+	int xyswap;
+};
 
 struct tsdev {
 	int exist;
 	int open;
 	int minor;
-	char name[16];
+	char name[8];
 	wait_queue_head_t wait;
 	struct list_head list;
 	struct input_handle handle;
+	int x, y, pressure;
+	struct ts_calibration cal;
 };
 
-/* From Compaq's Touch Screen Specification version 0.2 (draft) */
-typedef struct {
-	short pressure;
-	short x;
-	short y;
-	short millisecs;
-} TS_EVENT;
-
 struct tsdev_list {
 	struct fasync_struct *fasync;
 	struct list_head node;
 	struct tsdev *tsdev;
 	int head, tail;
-	int oldx, oldy, pendown;
-	TS_EVENT event[TSDEV_BUFFER_SIZE];
+	struct ts_event event[TSDEV_BUFFER_SIZE];
+	int raw;
 };
 
+/* The following ioctl codes are defined ONLY for backward compatibility.
+ * Don't use tsdev for new developement; use the tslib library instead.
+ * Touchscreen calibration is a fully userspace task.
+ */
+/* Use 'f' as magic number */
+#define IOC_H3600_TS_MAGIC  'f'
+#define TS_GET_CAL	_IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
+#define TS_SET_CAL	_IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
+
 static struct input_handler tsdev_handler;
 
-static struct tsdev *tsdev_table[TSDEV_MINORS];
+static struct tsdev *tsdev_table[TSDEV_MINORS/2];
 
 static int tsdev_fasync(int fd, struct file *file, int on)
 {
@@ -109,13 +155,16 @@
 	int i = iminor(inode) - TSDEV_MINOR_BASE;
 	struct tsdev_list *list;
 
-	if (i >= TSDEV_MINORS || !tsdev_table[i])
+	if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
 		return -ENODEV;
 
 	if (!(list = kmalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
 		return -ENOMEM;
 	memset(list, 0, sizeof(struct tsdev_list));
 
+	list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0;
+
+	i &= TSDEV_MINOR_MASK;
 	list->tsdev = tsdev_table[i];
 	list_add_tail(&list->node, &tsdev_table[i]->list);
 	file->private_data = list;
@@ -169,11 +218,13 @@
 	if (!list->tsdev->exist)
 		return -ENODEV;
 
-	while (list->head != list->tail && retval + sizeof(TS_EVENT) <= count) {
-		if (copy_to_user (buffer + retval, list->event + list->tail, sizeof(TS_EVENT)))
+	while (list->head != list->tail &&
+	       retval + sizeof (struct ts_event) <= count) {
+		if (copy_to_user (buffer + retval, list->event + list->tail,
+				  sizeof (struct ts_event)))
 			return -EFAULT;
 		list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
-		retval += sizeof(TS_EVENT);
+		retval += sizeof (struct ts_event);
 	}
 
 	return retval;
@@ -193,22 +244,27 @@
 static int tsdev_ioctl(struct inode *inode, struct file *file,
 		       unsigned int cmd, unsigned long arg)
 {
-/*
 	struct tsdev_list *list = file->private_data;
-        struct tsdev *evdev = list->tsdev;
-        struct input_dev *dev = tsdev->handle.dev;
-        int retval;
-	
+	struct tsdev *tsdev = list->tsdev;
+	int retval = 0;
+
 	switch (cmd) {
-		case HHEHE:
-			return 0;
-		case hjff:
-			return 0;
-		default:
-			return 0;
+	case TS_GET_CAL:
+		if (copy_to_user ((void *)arg, &tsdev->cal,
+				  sizeof (struct ts_calibration)))
+			retval = -EFAULT;
+		break;
+	case TS_SET_CAL:
+		if (copy_from_user (&tsdev->cal, (void *)arg,
+				    sizeof (struct ts_calibration)))
+			retval = -EFAULT;
+		break;
+	default:
+		retval = -EINVAL;
+		break;
 	}
-*/
-	return -EINVAL;
+
+	return retval;
 }
 
 struct file_operations tsdev_fops = {
@@ -227,82 +283,85 @@
 	struct tsdev *tsdev = handle->private;
 	struct tsdev_list *list;
 	struct timeval time;
-	int size;
 
-	list_for_each_entry(list, &tsdev->list, node) {
-		switch (type) {
-		case EV_ABS:
-			switch (code) {
-			case ABS_X:
-				if (!list->pendown)
-					return;
-				size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-				if (size > 0)
-					list->oldx = ((value - handle->dev->absmin[ABS_X]) * xres / size);
-				else
-					list->oldx = ((value - handle->dev->absmin[ABS_X]));
-				break;
-			case ABS_Y:
-				if (!list->pendown)
-					return;
-				size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-				if (size > 0)
-					list->oldy = ((value - handle->dev->absmin[ABS_Y]) * yres / size);
-				else
-					list->oldy = ((value - handle->dev->absmin[ABS_Y]));
-				break;
-			case ABS_PRESSURE:
-				list->pendown = ((value > handle->dev-> absmin[ABS_PRESSURE])) ?
-				    value - handle->dev->absmin[ABS_PRESSURE] : 0;
-				break;
-			}
+	switch (type) {
+	case EV_ABS:
+		switch (code) {
+		case ABS_X:
+			tsdev->x = value;
+			break;
+		case ABS_Y:
+			tsdev->y = value;
+			break;
+		case ABS_PRESSURE:
+			if (value > handle->dev->absmax[ABS_PRESSURE])
+				value = handle->dev->absmax[ABS_PRESSURE];
+			value -= handle->dev->absmin[ABS_PRESSURE];
+			if (value < 0)
+				value = 0;
+			tsdev->pressure = value;
+			break;
+		}
+		break;
+
+	case EV_REL:
+		switch (code) {
+		case REL_X:
+			tsdev->x += value;
+			if (tsdev->x < 0)
+				tsdev->x = 0;
+			else if (tsdev->x > xres)
+				tsdev->x = xres;
+			break;
+		case REL_Y:
+			tsdev->y += value;
+			if (tsdev->y < 0)
+				tsdev->y = 0;
+			else if (tsdev->y > yres)
+				tsdev->y = yres;
 			break;
+		}
+		break;
 
-		case EV_REL:
-			switch (code) {
-			case REL_X:
-				if (!list->pendown)
-					return;
-				list->oldx += value;
-				if (list->oldx < 0)
-					list->oldx = 0;
-				else if (list->oldx > xres)
-					list->oldx = xres;
+	case EV_KEY:
+		if (code == BTN_TOUCH || code == BTN_MOUSE) {
+			switch (value) {
+			case 0:
+				tsdev->pressure = 0;
 				break;
-			case REL_Y:
-				if (!list->pendown)
-					return;
-				list->oldy += value;
-				if (list->oldy < 0)
-					list->oldy = 0;
-				else if (list->oldy > xres)
-					list->oldy = xres;
+			case 1:
+				if (!tsdev->pressure)
+					tsdev->pressure = 1;
 				break;
 			}
-			break;
-
-		case EV_KEY:
-			if (code == BTN_TOUCH || code == BTN_MOUSE) {
-				switch (value) {
-				case 0:
-					list->pendown = 0;
-					break;
-				case 1:
-					if (!list->pendown)
-						list->pendown = 1;
-					break;
-				case 2:
-					return;
-				}
-			} else
-				return;
-			break;
 		}
+		break;
+	}
+
+	if (type != EV_SYN || code != SYN_REPORT)
+		return;
+
+	list_for_each_entry(list, &tsdev->list, node) {
+		int x, y, tmp;
+
 		do_gettimeofday(&time);
 		list->event[list->head].millisecs = time.tv_usec / 100;
-		list->event[list->head].pressure = list->pendown;
-		list->event[list->head].x = list->oldx;
-		list->event[list->head].y = list->oldy;
+		list->event[list->head].pressure = tsdev->pressure;
+
+		x = tsdev->x;
+		y = tsdev->y;
+
+		/* Calibration */
+		if (!list->raw) {
+			x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans;
+			y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans;
+			if (tsdev->cal.xyswap) {
+				tmp = x; x = y; y = tmp;
+			}
+		}
+
+		list->event[list->head].x = x;
+		list->event[list->head].y = y;
 		list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
 		kill_fasync(&list->fasync, SIGIO, POLL_IN);
 	}
@@ -314,11 +373,11 @@
 					  struct input_device_id *id)
 {
 	struct tsdev *tsdev;
-	int minor;
+	int minor, delta;
 
-	for (minor = 0; minor < TSDEV_MINORS && tsdev_table[minor];
+	for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
 	     minor++);
-	if (minor == TSDEV_MINORS) {
+	if (minor >= TSDEV_MINORS/2) {
 		printk(KERN_ERR
 		       "tsdev: You have way too many touchscreens\n");
 		return NULL;
@@ -340,10 +399,25 @@
 	tsdev->handle.handler = handler;
 	tsdev->handle.private = tsdev;
 
+	/* Precompute the rough calibration matrix */
+	delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
+	if (delta == 0)
+		delta = 1;
+	tsdev->cal.xscale = (xres << 8) / delta;
+	tsdev->cal.xtrans = - ((dev->absmin [ABS_X] * tsdev->cal.xscale) >> 8);
+
+	delta = dev->absmax [ABS_Y] - dev->absmin [ABS_Y] + 1;
+	if (delta == 0)
+		delta = 1;
+	tsdev->cal.yscale = (yres << 8) / delta;
+	tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
+
 	tsdev_table[minor] = tsdev;
-	
+
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
+	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
+			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
 	class_simple_device_add(input_class, 
 				MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
 				dev->dev, "ts%d", minor);
@@ -362,6 +436,7 @@
 		wake_up_interruptible(&tsdev->wait);
 	} else
 		tsdev_free(tsdev);
+	devfs_remove("input/tsraw%d", tsdev->minor);
 }
 
 static struct input_device_id tsdev_ids[] = {
@@ -378,6 +453,12 @@
 	      .keybit	= { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
 	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) },
 	 },/* A tablet like device, at least touch detection, two absolute axes */
+
+	{
+	      .flags	= INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+	      .evbit	= { BIT(EV_ABS) },
+	      .absbit	= { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
+	 },/* A tablet like device with several gradations of pressure */
 
 	{},/* Terminating entry */
 };


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

* [PATCH 28/47] Add Dell SB Live! PCI ID to the emu10k1-gp driver
  2004-07-29 14:09                                                     ` [PATCH 27/47] Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128 Vojtech Pavlik
@ 2004-07-29 14:09                                                       ` Vojtech Pavlik
  2004-07-29 14:09                                                         ` [PATCH 29/47] Add Audigy LS PCI ID to emu10k1-gp Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.148.15, 2004-06-23 19:58:19+02:00, vojtech@suse.cz
  input: Add Dell SB Live! PCI ID to the emu10k1-gp driver.
  
  Reported-by: Francisco Moraes <fmoraes74@netzero.net>
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 emu10k1-gp.c |    2 ++
 1 files changed, 2 insertions(+)

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

diff -Nru a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c
--- a/drivers/input/gameport/emu10k1-gp.c	Thu Jul 29 14:40:03 2004
+++ b/drivers/input/gameport/emu10k1-gp.c	Thu Jul 29 14:40:03 2004
@@ -50,8 +50,10 @@
 };
 
 static struct pci_device_id emu_tbl[] = {
+ 
 	{ 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
 	{ 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
+	{ 0x1102, 0x7004, PCI_ANY_ID, PCI_ANY_ID }, /* Dell SB Live */
 	{ 0, }
 };
 


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

* [PATCH 16/47] Make hardware rawmode optional for AT-keyboards
  2004-07-29 14:09                             ` [PATCH 15/47] Fix compilation breakage when CONFIG_USB_HIDDEV not defined Vojtech Pavlik
@ 2004-07-29 14:09                               ` Vojtech Pavlik
  2004-07-29 14:09                                 ` [PATCH 17/47] Fix boundary checks for GUSAGE/SUSAGE in hiddev Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.117.2, 2004-06-06 11:08:20+02:00, vojtech@suse.cz
  input: Make hardware rawmode optional for AT-keyboards, and check
         for rawmode bits in keyboard.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 drivers/char/keyboard.c        |    3 ++-
 drivers/input/keyboard/atkbd.c |   16 ++++++++++++++--
 include/linux/input.h          |    1 +
 3 files changed, 17 insertions(+), 3 deletions(-)

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

diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Thu Jul 29 14:41:12 2004
+++ b/drivers/char/keyboard.c	Thu Jul 29 14:41:12 2004
@@ -942,7 +942,8 @@
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SH_MPC1211)
 
-#define HW_RAW(dev) (((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
+#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
+			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
 
 static unsigned short x86_keycodes[256] =
 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:41:12 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:41:12 2004
@@ -47,6 +47,10 @@
 module_param_named(softrepeat, atkbd_softrepeat, bool, 0);
 MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat");
 
+static int atkbd_softraw = 1;
+module_param_named(softraw, atkbd_softraw, bool, 0);
+MODULE_PARM_DESC(softraw, "Use software generated rawmode");
+
 static int atkbd_scroll;
 module_param_named(scroll, atkbd_scroll, bool, 0);
 MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards");
@@ -336,6 +340,9 @@
 		code |= (atkbd->set != 3) ? 0x80 : 0x100;
 	}
 
+	if (atkbd->keycode[code] != ATKBD_KEY_NULL)
+		input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
+
 	switch (atkbd->keycode[code]) {
 		case ATKBD_KEY_NULL:
 			break;
@@ -750,16 +757,21 @@
 			return;
 	}
 
+	if (!atkbd->write)
+		atkbd_softrepeat = 1;
+	if (atkbd_softrepeat)
+		atkbd_softraw = 1;
+
 	if (atkbd->write) {
 		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC);
 		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
 	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
-	atkbd->dev.mscbit[0] = BIT(MSC_RAW);
+	atkbd->dev.mscbit[0] = atkbd_softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
 
 	if (!atkbd_softrepeat) {
 		atkbd->dev.rep[REP_DELAY] = 250;
 		atkbd->dev.rep[REP_PERIOD] = 33;
-	}
+	} else atkbd_softraw = 1;
 
 	atkbd->serio = serio;
 
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	Thu Jul 29 14:41:12 2004
+++ b/include/linux/input.h	Thu Jul 29 14:41:12 2004
@@ -528,6 +528,7 @@
 #define MSC_PULSELED		0x01
 #define MSC_GESTURE		0x02
 #define MSC_RAW			0x03
+#define MSC_SCAN		0x04
 #define MSC_MAX			0x07
 
 /*


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

* [PATCH 17/47] Fix boundary checks for GUSAGE/SUSAGE in hiddev.
  2004-07-29 14:09                               ` [PATCH 16/47] Make hardware rawmode optional for AT-keyboards Vojtech Pavlik
@ 2004-07-29 14:09                                 ` Vojtech Pavlik
  2004-07-29 14:09                                   ` [PATCH 18/47] Updates to the tsdev driver (raw protocol, calib ioctls, ...) Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1722.117.4, 2004-06-06 11:37:43+02:00, herbert@gondor.apana.org.au
  input: Fix boundary checks for GUSAGE/SUSAGE in hiddev.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 hiddev.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

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

diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Thu Jul 29 14:41:02 2004
+++ b/drivers/usb/input/hiddev.c	Thu Jul 29 14:41:02 2004
@@ -638,16 +638,22 @@
 				goto inval;
 
 			field = report->field[uref->field_index];
-			if (uref->usage_index >= field->maxusage)
-				goto inval;
 
-			if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-				if (uref_multi->num_values >= HID_MAX_MULTI_USAGES || 
-				    uref->usage_index >= field->maxusage || 
-				   (uref->usage_index + uref_multi->num_values) >= field->maxusage)
+			if (cmd == HIDIOCGCOLLECTIONINDEX) {
+				if (uref->usage_index >= field->maxusage)
 					goto inval;
+			} else if (uref->usage_index >= field->report_count)
+				goto inval;
+
+			else if ((cmd == HIDIOCGUSAGES ||
+				  cmd == HIDIOCSUSAGES) &&
+				 (uref->usage_index + uref_multi->num_values >=
+				  field->report_count ||
+				  uref->usage_index + uref_multi->num_values <
+				  uref->usage_index))
+				goto inval;
+
 			}
-		}
 
 		switch (cmd) {
 			case HIDIOCGUSAGE:


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

* [PATCH 46/47] Fix a missing index in tmdc.c
  2004-07-29 14:09                                                                                         ` [PATCH 45/47] Re-add PC Speaker support for PPC Vojtech Pavlik
@ 2004-07-29 14:09                                                                                           ` Vojtech Pavlik
  2004-07-29 14:09                                                                                             ` [PATCH 47/47] Check the range for HIDIOC?USAGES num_values Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1858, 2004-07-29 13:42:55+02:00, vojtech@suse.cz
  input: Fix a missing index in tmdc.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
--- a/drivers/input/joystick/tmdc.c	Thu Jul 29 14:38:28 2004
+++ b/drivers/input/joystick/tmdc.c	Thu Jul 29 14:38:28 2004
@@ -322,7 +322,7 @@
 			tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 			for (i = 0; i < models[m].abs && i < TMDC_ABS; i++) {
-				if (tmdc->abs[i] < 0) continue;
+				if (tmdc->abs[j][i] < 0) continue;
 				set_bit(tmdc->abs[j][i], tmdc->dev[j].absbit);
 				tmdc->dev[j].absmin[tmdc->abs[j][i]] = 8;
 				tmdc->dev[j].absmax[tmdc->abs[j][i]] = 248;


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

* [PATCH 43/47] Move Compaq ProLiant DMI handling to i8042.c.
  2004-07-29 14:09                                                                                   ` [PATCH 42/47] Fix Kconfig so that the joydump module can be compiled Vojtech Pavlik
@ 2004-07-29 14:09                                                                                     ` Vojtech Pavlik
  2004-07-29 14:09                                                                                       ` [PATCH 44/47] This patch fixes another disconnect oops in hiddev Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.50.2, 2004-06-29 11:59:04+02:00, vojtech@suse.cz
  input: Move Compaq ProLiant DMI handling (ServerWorks/OSB workaround)
         to i8042.c.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 i8042-io.h |   31 +++++++++++++++++++++++++++++++
 i8042.c    |   12 ++----------
 2 files changed, 33 insertions(+), 10 deletions(-)

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

diff -Nru a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
--- a/drivers/input/serio/i8042-io.h	Thu Jul 29 14:38:43 2004
+++ b/drivers/input/serio/i8042-io.h	Thu Jul 29 14:38:43 2004
@@ -63,6 +63,31 @@
 	return;
 }
 
+#if defined(__i386__)
+
+#include <linux/dmi.h>
+
+static struct dmi_system_id __initdata i8042_dmi_table[] = {
+	{
+		.ident = "Compaq Proliant 8500",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
+		},
+	},
+	{
+		.ident = "Compaq Proliant DL760",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
+		},
+	},
+	{ }
+};
+#endif
+
 static inline int i8042_platform_init(void)
 {
 /*
@@ -77,6 +102,12 @@
 #if !defined(__i386__) && !defined(__x86_64__)
         i8042_reset = 1;
 #endif
+
+#if defined(__i386__)
+	if (dmi_check_system(i8042_dmi_table))
+		i8042_noloop = 1;
+#endif
+
 	return 0;
 }
 
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:38:43 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:38:43 2004
@@ -52,10 +52,9 @@
 module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
-#ifdef __i386__
-extern unsigned int i8042_dmi_noloop;
-#endif
 static unsigned int i8042_noloop;
+module_param_named(noloop, i8042_noloop, bool, 0);
+MODULE_PARM_DESC(dumbkbd, "Disable the AUX Loopback command while probing for the AUX port");
 
 __obsolete_setup("i8042_noaux");
 __obsolete_setup("i8042_nomux");
@@ -966,13 +965,6 @@
 
 	if (i8042_dumbkbd)
 		i8042_kbd_port.write = NULL;
-
-#ifdef __i386__
-	if (i8042_dmi_noloop) {
-		printk(KERN_INFO "i8042.c: AUX LoopBack command disabled by DMI.\n");
-		i8042_noloop = 1;
-	}
-#endif
 
 	if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
 		if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))


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

* [PATCH 42/47] Fix Kconfig so that the joydump module can be compiled
  2004-07-29 14:09                                                                                 ` [PATCH 41/47] link (some) serio ports to their parent devices Vojtech Pavlik
@ 2004-07-29 14:09                                                                                   ` Vojtech Pavlik
  2004-07-29 14:09                                                                                     ` [PATCH 43/47] Move Compaq ProLiant DMI handling to i8042.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.49.1, 2004-06-29 09:48:40+02:00, vojtech@suse.cz
  input: Fix Kconfig so that the joydump module can be compiled.
  
  Reported-by: Matthieu Castet <castetm@ensimag.imag.fr>
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 Kconfig |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

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

diff -Nru a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
--- a/drivers/input/joystick/Kconfig	Thu Jul 29 14:38:50 2004
+++ b/drivers/input/joystick/Kconfig	Thu Jul 29 14:38:50 2004
@@ -247,7 +247,7 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called amijoy.
 
-config INPUT_JOYDUMP
+config JOYSTICK_JOYDUMP
 	tristate "Gameport data dumper"
 	depends on INPUT && INPUT_JOYSTICK
 	help


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

* [PATCH 40/47] Add serio_raw driver
  2004-07-29 14:09                                                                             ` [PATCH 39/47] allow marking some drivers as manual bind only Vojtech Pavlik
@ 2004-07-29 14:09                                                                               ` Vojtech Pavlik
  2004-07-29 14:09                                                                                 ` [PATCH 41/47] link (some) serio ports to their parent devices Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.35, 2004-06-29 01:31:03-05:00, dtor_core@ameritech.net
  Input: Add serio_raw driver that binds to serio ports and provides
         unobstructed access to the underlying serio port via a char
         device. The driver tries to register char device 10,1
         (/dev/psaux) first and if it fails goes for dynamically
         allocated minor. To bind use sysfs interface:
  
         echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 Kconfig     |   16 ++
 Makefile    |    1 
 serio_raw.c |  390 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 407 insertions(+)

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

diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig	Thu Jul 29 14:39:02 2004
+++ b/drivers/input/serio/Kconfig	Thu Jul 29 14:39:02 2004
@@ -130,3 +130,19 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called maceps2.
+
+config SERIO_RAW
+	tristate "Raw access to serio ports"
+	depends on SERIO
+	help
+	  Say Y here if you want to have raw access to serio ports, such as
+	  AUX ports on i8042 keyboard controller. Each serio port that is
+	  bound to this driver will be accessible via a char device with
+	  major 10 and dynamically allocated minor. The driver will try
+	  allocating minor 1 (that historically corresponds to /dev/psaux)
+	  first. To bind this driver to a serio port use sysfs interface:
+
+	      echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called serio_raw.
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile	Thu Jul 29 14:39:02 2004
+++ b/drivers/input/serio/Makefile	Thu Jul 29 14:39:02 2004
@@ -17,3 +17,4 @@
 obj-$(CONFIG_SERIO_GSCPS2)	+= gscps2.o
 obj-$(CONFIG_SERIO_PCIPS2)	+= pcips2.o
 obj-$(CONFIG_SERIO_MACEPS2)	+= maceps2.o
+obj-$(CONFIG_SERIO_RAW)		+= serio_raw.o
diff -Nru a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/serio/serio_raw.c	Thu Jul 29 14:39:02 2004
@@ -0,0 +1,390 @@
+/*
+ * Raw serio device providing access to a raw byte stream from underlying
+ * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
+ *
+ * Copyright (c) 2004 Dmitry Torokhov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/device.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/wait.h>
+
+#define DRIVER_DESC	"Raw serio driver"
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+#define SERIO_RAW_QUEUE_LEN	64
+struct serio_raw {
+	unsigned char queue[SERIO_RAW_QUEUE_LEN];
+	unsigned int tail, head;
+
+	char name[16];
+	unsigned int refcnt;
+	struct serio *serio;
+	struct miscdevice dev;
+	wait_queue_head_t wait;
+	struct list_head list;
+	struct list_head node;
+};
+
+struct serio_raw_list {
+	struct fasync_struct *fasync;
+	struct serio_raw *serio_raw;
+	struct list_head node;
+};
+
+static DECLARE_MUTEX(serio_raw_sem);
+static LIST_HEAD(serio_raw_list);
+static unsigned int serio_raw_no;
+
+/*********************************************************************
+ *             Interface with userspace (file operations)            *
+ *********************************************************************/
+
+static int serio_raw_fasync(int fd, struct file *file, int on)
+{
+	struct serio_raw_list *list = file->private_data;
+	int retval;
+
+	retval = fasync_helper(fd, file, on, &list->fasync);
+	return retval < 0 ? retval : 0;
+}
+
+static struct serio_raw *serio_raw_locate(int minor)
+{
+	struct serio_raw *serio_raw;
+
+	list_for_each_entry(serio_raw, &serio_raw_list, node) {
+		if (serio_raw->dev.minor == minor)
+			return serio_raw;
+	}
+
+	return NULL;
+}
+
+static int serio_raw_open(struct inode *inode, struct file *file)
+{
+	struct serio_raw *serio_raw;
+	struct serio_raw_list *list;
+	int retval = 0;
+
+	retval = down_interruptible(&serio_raw_sem);
+	if (retval)
+		return retval;
+
+	if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	if (!serio_raw->serio) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	if (!(list = kmalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+		retval = -ENOMEM;
+		goto out;
+	}
+
+	memset(list, 0, sizeof(struct serio_raw_list));
+	list->serio_raw = serio_raw;
+	file->private_data = list;
+
+	serio_raw->refcnt++;
+	list_add_tail(&list->node, &serio_raw->list);
+
+out:
+	up(&serio_raw_sem);
+	return retval;
+}
+
+static int serio_raw_cleanup(struct serio_raw *serio_raw)
+{
+	if (--serio_raw->refcnt == 0) {
+		misc_deregister(&serio_raw->dev);
+		list_del_init(&serio_raw->node);
+		kfree(serio_raw);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int serio_raw_release(struct inode *inode, struct file *file)
+{
+	struct serio_raw_list *list = file->private_data;
+	struct serio_raw *serio_raw = list->serio_raw;
+
+	down(&serio_raw_sem);
+
+	serio_raw_fasync(-1, file, 0);
+	serio_raw_cleanup(serio_raw);
+
+	up(&serio_raw_sem);
+	return 0;
+}
+
+static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
+{
+	unsigned long flags;
+	int empty;
+
+	spin_lock_irqsave(&serio_raw->serio->lock, flags);
+
+	empty = serio_raw->head == serio_raw->tail;
+	if (!empty) {
+		*c = serio_raw->queue[serio_raw->tail];
+		serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
+	}
+
+	spin_unlock_irqrestore(&serio_raw->serio->lock, flags);
+
+	return !empty;
+}
+
+static ssize_t serio_raw_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct serio_raw_list *list = file->private_data;
+	struct serio_raw *serio_raw = list->serio_raw;
+	char c;
+	ssize_t retval = 0;
+
+	if (!serio_raw->serio)
+		return -ENODEV;
+
+	if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+
+	retval = wait_event_interruptible(list->serio_raw->wait,
+					  serio_raw->head != serio_raw->tail || !serio_raw->serio);
+	if (retval)
+		return retval;
+
+	if (!serio_raw->serio)
+		return -ENODEV;
+
+	while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
+		if (put_user(c, buffer++))
+			return -EFAULT;
+		retval++;
+	}
+
+	return retval;
+}
+
+static ssize_t serio_raw_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct serio_raw_list *list = file->private_data;
+	ssize_t written = 0;
+	int retval;
+	unsigned char c;
+
+	retval = down_interruptible(&serio_raw_sem);
+	if (retval)
+		return retval;
+
+	if (!list->serio_raw->serio) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	if (count > 32)
+		count = 32;
+
+	while (count--) {
+		if (get_user(c, buffer++)) {
+			retval = -EFAULT;
+			goto out;
+		}
+		if (serio_write(list->serio_raw->serio, c)) {
+			retval = -EIO;
+			goto out;
+		}
+		written++;
+	};
+
+out:
+	up(&serio_raw_sem);
+	return written;
+}
+
+static unsigned int serio_raw_poll(struct file *file, poll_table *wait)
+{
+	struct serio_raw_list *list = file->private_data;
+
+	poll_wait(file, &list->serio_raw->wait, wait);
+
+	if (list->serio_raw->head != list->serio_raw->tail)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+struct file_operations serio_raw_fops = {
+	.owner =	THIS_MODULE,
+	.open =		serio_raw_open,
+	.release =	serio_raw_release,
+	.read =		serio_raw_read,
+	.write =	serio_raw_write,
+	.poll =		serio_raw_poll,
+	.fasync =	serio_raw_fasync,
+};
+
+
+/*********************************************************************
+ *                   Interface with serio port   	             *
+ *********************************************************************/
+
+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_list *list;
+	unsigned int head = serio_raw->head;
+
+	/* we are holding serio->lock here so we are prootected */
+	serio_raw->queue[head] = data;
+	head = (head + 1) % SERIO_RAW_QUEUE_LEN;
+	if (likely(head != serio_raw->tail)) {
+		serio_raw->head = head;
+		list_for_each_entry(list, &serio_raw->list, node)
+			kill_fasync(&list->fasync, SIGIO, POLL_IN);
+		wake_up_interruptible(&serio_raw->wait);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void serio_raw_connect(struct serio *serio, struct serio_driver *drv)
+{
+	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;
+	}
+
+	down(&serio_raw_sem);
+
+	memset(serio_raw, 0, sizeof(struct serio_raw));
+	snprintf(serio_raw->name, sizeof(serio_raw->name), "serio_raw%d", serio_raw_no++);
+	serio_raw->refcnt = 1;
+	serio_raw->serio = serio;
+	INIT_LIST_HEAD(&serio_raw->list);
+	init_waitqueue_head(&serio_raw->wait);
+
+	serio->private = serio_raw;
+	if (serio_open(serio, drv))
+		goto out_free;
+
+	list_add_tail(&serio_raw->node, &serio_raw_list);
+
+	serio_raw->dev.minor = PSMOUSE_MINOR;
+	serio_raw->dev.name = serio_raw->name;
+	serio_raw->dev.fops = &serio_raw_fops;
+
+	err = misc_register(&serio_raw->dev);
+	if (err) {
+		serio_raw->dev.minor = MISC_DYNAMIC_MINOR;
+		err = misc_register(&serio_raw->dev);
+	}
+
+	if (err) {
+		printk(KERN_INFO "serio_raw: failed to register raw access device for %s\n",
+			serio->phys);
+		goto out_close;
+	}
+
+	printk(KERN_INFO "serio_raw: raw access enabled on %s (%s, minor %d)\n",
+		serio->phys, serio_raw->name, serio_raw->dev.minor);
+	goto out;
+
+out_close:
+	serio_close(serio);
+	list_del_init(&serio_raw->node);
+out_free:
+	serio->private = NULL;
+	kfree(serio_raw);
+out:
+	up(&serio_raw_sem);
+}
+
+static int serio_raw_reconnect(struct serio *serio)
+{
+	struct serio_raw *serio_raw = serio->private;
+	struct serio_driver *drv = serio->drv;
+
+	if (!drv || !serio_raw) {
+		printk(KERN_DEBUG "serio_raw: reconnect request, but serio is disconnected, ignoring...\n");
+		return -1;
+	}
+
+	/*
+	 * Nothing needs to be done here, we just need this method to
+	 * keep the same device.
+	 */
+	return 0;
+}
+
+static void serio_raw_disconnect(struct serio *serio)
+{
+	struct serio_raw *serio_raw;
+
+	down(&serio_raw_sem);
+
+	serio_raw = serio->private;
+
+	serio_close(serio);
+	serio->private = NULL;
+
+	serio_raw->serio = NULL;
+	if (!serio_raw_cleanup(serio_raw))
+		wake_up_interruptible(&serio_raw->wait);
+
+	up(&serio_raw_sem);
+}
+
+static struct serio_driver serio_raw_drv = {
+	.driver		= {
+		.name	= "serio_raw",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= serio_raw_interrupt,
+	.connect	= serio_raw_connect,
+	.reconnect	= serio_raw_reconnect,
+	.disconnect	= serio_raw_disconnect,
+	.manual_bind	= 1,
+};
+
+int __init serio_raw_init(void)
+{
+	serio_register_driver(&serio_raw_drv);
+	return 0;
+}
+
+void __exit serio_raw_exit(void)
+{
+	serio_unregister_driver(&serio_raw_drv);
+}
+
+module_init(serio_raw_init);
+module_exit(serio_raw_exit);


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

* [PATCH 37/47] serio sysfs integration
  2004-07-29 14:09                                                                       ` [PATCH 36/47] allow serio drivers to create children ports Vojtech Pavlik
@ 2004-07-29 14:09                                                                         ` Vojtech Pavlik
  2004-07-29 14:09                                                                           ` [PATCH 38/47] allow users to manually rebind serio ports Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.32, 2004-06-29 01:28:53-05:00, dtor_core@ameritech.net
  Input: serio sysfs integration
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/Makefile                             |    2 
 drivers/input/joystick/iforce/iforce-serio.c |   12 ++-
 drivers/input/joystick/magellan.c            |   14 +++-
 drivers/input/joystick/spaceball.c           |   14 +++-
 drivers/input/joystick/spaceorb.c            |   14 +++-
 drivers/input/joystick/stinger.c             |   14 +++-
 drivers/input/joystick/twidjoy.c             |   10 ++-
 drivers/input/joystick/warrior.c             |   14 +++-
 drivers/input/keyboard/atkbd.c               |   18 +++--
 drivers/input/keyboard/lkkbd.c               |   14 +++-
 drivers/input/keyboard/newtonkbd.c           |   14 +++-
 drivers/input/keyboard/sunkbd.c              |   14 +++-
 drivers/input/keyboard/xtkbd.c               |   14 +++-
 drivers/input/mouse/psmouse-base.c           |   18 +++--
 drivers/input/mouse/sermouse.c               |   14 +++-
 drivers/input/mouse/vsxxxaa.c                |   14 +++-
 drivers/input/serio/serio.c                  |   85 +++++++++++++++++++++++----
 drivers/input/touchscreen/gunze.c            |   14 +++-
 drivers/input/touchscreen/h3600_ts_input.c   |   14 +++-
 include/linux/serio.h                        |    9 ++
 20 files changed, 253 insertions(+), 83 deletions(-)

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

diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Thu Jul 29 14:39:17 2004
+++ b/drivers/Makefile	Thu Jul 29 14:39:17 2004
@@ -37,9 +37,9 @@
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB)		+= usb/
 obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
+obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_INPUT)		+= input/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
-obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_I2O)		+= message/
 obj-$(CONFIG_I2C)		+= i2c/
 obj-$(CONFIG_PHONE)		+= telephony/
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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/joystick/iforce/iforce-serio.c	Thu Jul 29 14:39:17 2004
@@ -159,8 +159,12 @@
 }
 
 struct serio_driver iforce_serio_drv = {
-	.write_wakeup =	iforce_serio_write_wakeup,
-	.interrupt =	iforce_serio_irq,
-	.connect =	iforce_serio_connect,
-	.disconnect =	iforce_serio_disconnect,
+	.driver		= {
+		.name	= "iforce",
+	},
+	.description	= "RS232 I-Force joysticks and wheels driver",
+	.write_wakeup	= iforce_serio_write_wakeup,
+	.interrupt	= iforce_serio_irq,
+	.connect	= iforce_serio_connect,
+	.disconnect	= iforce_serio_disconnect,
 };
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	Thu Jul 29 14:39:16 2004
+++ b/drivers/input/joystick/magellan.c	Thu Jul 29 14:39:17 2004
@@ -35,8 +35,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Magellan and SpaceMouse 6dof controller driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Magellan and SpaceMouse 6dof controller driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -200,9 +202,13 @@
  */
 
 static struct serio_driver magellan_drv = {
-	.interrupt =	magellan_interrupt,
-	.connect =	magellan_connect,
-	.disconnect =	magellan_disconnect,
+	.driver		= {
+		.name	= "magellan",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/joystick/spaceball.c	Thu Jul 29 14:39:17 2004
@@ -39,8 +39,10 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 
+#define DRIVER_DESC	"SpaceTec SpaceBall 2003/3003/4000 FLX driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("SpaceTec SpaceBall 2003/3003/4000 FLX driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -270,9 +272,13 @@
  */
 
 static struct serio_driver spaceball_drv = {
-	.interrupt =	spaceball_interrupt,
-	.connect =	spaceball_connect,
-	.disconnect =	spaceball_disconnect,
+	.driver		= {
+		.name	= "spaceball",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/joystick/spaceorb.c	Thu Jul 29 14:39:17 2004
@@ -38,8 +38,10 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 
+#define DRIVER_DESC	"SpaceTec SpaceOrb 360 and Avenger 6dof controller driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("SpaceTec SpaceOrb 360 and Avenger 6dof controller driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -214,9 +216,13 @@
  */
 
 static struct serio_driver spaceorb_drv = {
-	.interrupt =	spaceorb_interrupt,
-	.connect =	spaceorb_connect,
-	.disconnect =	spaceorb_disconnect,
+	.driver		= {
+		.name	= "spaceorb",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:16 2004
+++ b/drivers/input/joystick/stinger.c	Thu Jul 29 14:39:16 2004
@@ -36,8 +36,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Gravis Stinger gamepad driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Gravis Stinger gamepad driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -188,9 +190,13 @@
  */
 
 static struct serio_driver stinger_drv = {
-	.interrupt =	stinger_interrupt,
-	.connect =	stinger_connect,
-	.disconnect =	stinger_disconnect,
+	.driver		= {
+		.name	= "stinger",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/joystick/twidjoy.c	Thu Jul 29 14:39:17 2004
@@ -247,9 +247,13 @@
  */
 
 static struct serio_driver twidjoy_drv = {
-	.interrupt =	twidjoy_interrupt,
-	.connect =	twidjoy_connect,
-	.disconnect =	twidjoy_disconnect,
+	.driver		= {
+		.name	= "twidjoy",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/joystick/warrior.c	Thu Jul 29 14:39:17 2004
@@ -35,8 +35,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Logitech WingMan Warrior joystick driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Logitech WingMan Warrior joystick driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -200,9 +202,13 @@
  */
 
 static struct serio_driver warrior_drv = {
-	.interrupt =	warrior_interrupt,
-	.connect =	warrior_connect,
-	.disconnect =	warrior_disconnect,
+	.driver		= {
+		.name	= "warrior",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:39:17 2004
@@ -27,8 +27,10 @@
 #include <linux/serio.h>
 #include <linux/workqueue.h>
 
+#define DRIVER_DESC	"AT and PS/2 keyboard driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
-MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 static int atkbd_set = 2;
@@ -891,11 +893,15 @@
 }
 
 static struct serio_driver atkbd_drv = {
-	.interrupt =	atkbd_interrupt,
-	.connect =	atkbd_connect,
-	.reconnect = 	atkbd_reconnect,
-	.disconnect =	atkbd_disconnect,
-	.cleanup =	atkbd_cleanup,
+	.driver		= {
+		.name	= "atkbd",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= atkbd_interrupt,
+	.connect	= atkbd_connect,
+	.reconnect	= atkbd_reconnect,
+	.disconnect	= atkbd_disconnect,
+	.cleanup	= atkbd_cleanup,
 };
 
 int __init atkbd_init(void)
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/keyboard/lkkbd.c	Thu Jul 29 14:39:17 2004
@@ -76,8 +76,10 @@
 #include <linux/serio.h>
 #include <linux/workqueue.h>
 
+#define DRIVER_DESC	"LK keyboard driver"
+
 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION ("LK keyboard driver");
+MODULE_DESCRIPTION (DRIVER_DESC);
 MODULE_LICENSE ("GPL");
 
 /*
@@ -704,9 +706,13 @@
 }
 
 static struct serio_driver lkkbd_drv = {
-	.connect = lkkbd_connect,
-	.disconnect = lkkbd_disconnect,
-	.interrupt = lkkbd_interrupt,
+	.driver		= {
+		.name	= "lkkbd",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:16 2004
+++ b/drivers/input/keyboard/newtonkbd.c	Thu Jul 29 14:39:16 2004
@@ -32,8 +32,10 @@
 #include <linux/init.h>
 #include <linux/serio.h>
 
+#define DRIVER_DESC	"Newton keyboard driver"
+
 MODULE_AUTHOR("Justin Cormack <j.cormack@doc.ic.ac.uk>");
-MODULE_DESCRIPTION("Newton keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 #define NKBD_KEY	0x7f
@@ -139,9 +141,13 @@
 }
 
 struct serio_driver nkbd_drv = {
-	.interrupt =	nkbd_interrupt,
-	.connect =	nkbd_connect,
-	.disconnect =	nkbd_disconnect
+	.driver		= {
+		.name	= "newtonkbd",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= nkbd_interrupt,
+	.connect	= nkbd_connect,
+	.disconnect	= nkbd_disconnect,
 };
 
 int __init nkbd_init(void)
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	Thu Jul 29 14:39:16 2004
+++ b/drivers/input/keyboard/sunkbd.c	Thu Jul 29 14:39:16 2004
@@ -37,8 +37,10 @@
 #include <linux/serio.h>
 #include <linux/workqueue.h>
 
+#define DRIVER_DESC	"Sun keyboard driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Sun keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 static unsigned char sunkbd_keycode[128] = {
@@ -302,9 +304,13 @@
 }
 
 static struct serio_driver sunkbd_drv = {
-	.interrupt =	sunkbd_interrupt,
-	.connect =	sunkbd_connect,
-	.disconnect =	sunkbd_disconnect
+	.driver		= {
+		.name	= "sunkbd",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/keyboard/xtkbd.c	Thu Jul 29 14:39:17 2004
@@ -34,8 +34,10 @@
 #include <linux/init.h>
 #include <linux/serio.h>
 
+#define DRIVER_DESC	"XT keyboard driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("XT keyboard driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 #define XTKBD_EMUL0	0xe0
@@ -144,9 +146,13 @@
 }
 
 struct serio_driver xtkbd_drv = {
-	.interrupt =	xtkbd_interrupt,
-	.connect =	xtkbd_connect,
-	.disconnect =	xtkbd_disconnect
+	.driver		= {
+		.name	= "xtkbd",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= xtkbd_interrupt,
+	.connect	= xtkbd_connect,
+	.disconnect	= xtkbd_disconnect,
 };
 
 int __init xtkbd_init(void)
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:17 2004
@@ -22,8 +22,10 @@
 #include "synaptics.h"
 #include "logips2pp.h"
 
+#define DRIVER_DESC	"PS/2 mouse driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
-MODULE_DESCRIPTION("PS/2 mouse driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 static char *psmouse_proto;
@@ -815,11 +817,15 @@
 
 
 static struct serio_driver psmouse_drv = {
-	.interrupt =	psmouse_interrupt,
-	.connect =	psmouse_connect,
-	.reconnect =	psmouse_reconnect,
-	.disconnect =	psmouse_disconnect,
-	.cleanup =	psmouse_cleanup,
+	.driver		= {
+		.name	= "psmouse",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= psmouse_interrupt,
+	.connect	= psmouse_connect,
+	.reconnect	= psmouse_reconnect,
+	.disconnect	= psmouse_disconnect,
+	.cleanup	= psmouse_cleanup,
 };
 
 static inline void psmouse_parse_proto(void)
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/mouse/sermouse.c	Thu Jul 29 14:39:17 2004
@@ -37,8 +37,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Serial mouse driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Serial mouse driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
@@ -290,9 +292,13 @@
 }
 
 static struct serio_driver sermouse_drv = {
-	.interrupt =	sermouse_interrupt,
-	.connect =	sermouse_connect,
-	.disconnect =	sermouse_disconnect
+	.driver		= {
+		.name	= "sermouse",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= sermouse_interrupt,
+	.connect	= sermouse_connect,
+	.disconnect	= sermouse_disconnect,
 };
 
 int __init sermouse_init(void)
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/mouse/vsxxxaa.c	Thu Jul 29 14:39:17 2004
@@ -82,8 +82,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Serial DEC VSXXX-AA/GA mouse / DEC tablet driver"
+
 MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
-MODULE_DESCRIPTION ("Serial DEC VSXXX-AA/GA mouse / DEC tablet driver");
+MODULE_DESCRIPTION (DRIVER_DESC);
 MODULE_LICENSE ("GPL");
 
 #undef VSXXXAA_DEBUG
@@ -541,9 +543,13 @@
 }
 
 static struct serio_driver vsxxxaa_drv = {
-	.connect = vsxxxaa_connect,
-	.interrupt = vsxxxaa_interrupt,
-	.disconnect = vsxxxaa_disconnect,
+	.driver		= {
+		.name	= "vsxxxaa",
+	},
+	.description	= DRIVER_DESC,
+	.connect	= vsxxxaa_connect,
+	.interrupt	= vsxxxaa_interrupt,
+	.disconnect	= vsxxxaa_disconnect,
 };
 
 int __init
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:17 2004
@@ -56,6 +56,11 @@
 static DECLARE_MUTEX(serio_sem);	/* protects serio_list and serio_diriver_list */
 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);
@@ -66,9 +71,19 @@
 
 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;
+	}
 
-	return serio->drv != NULL;
+	put_driver(&drv->driver);
+	return 0;
 }
 
 /* serio_find_driver() must be called with serio_sem down.  */
@@ -224,10 +239,41 @@
  * Serio port operations
  */
 
+static ssize_t serio_show_description(struct device *dev, char *buf)
+{
+	struct serio *serio = to_serio_port(dev);
+	return sprintf(buf, "%s\n", serio->name);
+}
+static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL);
+
+static ssize_t serio_show_driver(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%s\n", dev->driver ? dev->driver->name : "(none)");
+}
+static DEVICE_ATTR(driver, S_IRUGO, serio_show_driver, NULL);
+
+static void serio_release_port(struct device *dev)
+{
+	struct serio *serio = to_serio_port(dev);
+
+	kfree(serio);
+	module_put(THIS_MODULE);
+}
+
 static void serio_create_port(struct serio *serio)
 {
+	try_module_get(THIS_MODULE);
+
 	spin_lock_init(&serio->lock);
 	list_add_tail(&serio->node, &serio_list);
+	snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++);
+	serio->dev.bus = &serio_bus;
+	serio->dev.release = serio_release_port;
+	if (serio->parent)
+		serio->dev.parent = &serio->parent->dev;
+	device_register(&serio->dev);
+	device_create_file(&serio->dev, &dev_attr_description);
+	device_create_file(&serio->dev, &dev_attr_driver);
 }
 
 /*
@@ -242,8 +288,13 @@
 	serio_remove_pending_events(serio);
 	list_del_init(&serio->node);
 
-	if (drv)
+	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);
+	}
 
 	if (serio->parent) {
 		spin_lock_irqsave(&serio->parent->lock, flags);
@@ -251,7 +302,7 @@
 		spin_unlock_irqrestore(&serio->parent->lock, flags);
 	}
 
-	kfree(serio);
+	device_unregister(&serio->dev);
 }
 
 /*
@@ -332,8 +383,13 @@
 	/*
 	 * Ok, no children left, now disconnect this port
 	 */
-	if (drv)
+	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);
+	}
 }
 
 void serio_rescan(struct serio *serio)
@@ -387,6 +443,12 @@
  * Serio driver operations
  */
 
+static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf)
+{
+	struct serio_driver *driver = to_serio_driver(drv);
+	return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)");
+}
+static DRIVER_ATTR(description, S_IRUGO, serio_driver_show_description, NULL);
 
 void serio_register_driver(struct serio_driver *drv)
 {
@@ -396,6 +458,10 @@
 
 	list_add_tail(&drv->node, &serio_driver_list);
 
+	drv->driver.bus = &serio_bus;
+	driver_register(&drv->driver);
+	driver_create_file(&drv->driver, &driver_attr_description);
+
 start_over:
 	list_for_each_entry(serio, &serio_list, node) {
 		if (!serio->drv) {
@@ -430,6 +496,8 @@
 		}
 	}
 
+	driver_unregister(&drv->driver);
+
 	up(&serio_sem);
 }
 
@@ -489,22 +557,19 @@
 
 static int __init serio_init(void)
 {
-	int pid;
-
-	pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL);
-
-	if (!pid) {
+	if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
 		printk(KERN_WARNING "serio: Failed to start kseriod\n");
 		return -1;
 	}
 
-	serio_pid = pid;
+	bus_register(&serio_bus);
 
 	return 0;
 }
 
 static void __exit serio_exit(void)
 {
+	bus_unregister(&serio_bus);
 	kill_proc(serio_pid, SIGTERM, 1);
 	wait_for_completion(&serio_exited);
 }
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/touchscreen/gunze.c	Thu Jul 29 14:39:17 2004
@@ -36,8 +36,10 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+#define DRIVER_DESC	"Gunze AHL-51S touchscreen driver"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Gunze AHL-51S touchscreen driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -157,9 +159,13 @@
  */
 
 static struct serio_driver gunze_drv = {
-	.interrupt =	gunze_interrupt,
-	.connect =	gunze_connect,
-	.disconnect =	gunze_disconnect,
+	.driver		= {
+		.name	= "gunze",
+	},
+	.description	= DRIVER_DESC,
+	.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	Thu Jul 29 14:39:17 2004
+++ b/drivers/input/touchscreen/h3600_ts_input.c	Thu Jul 29 14:39:17 2004
@@ -45,8 +45,10 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/irqs.h>
 
+#define DRIVER_DESC	"H3600 touchscreen driver"
+
 MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
-MODULE_DESCRIPTION("H3600 touchscreen driver");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 /*
@@ -479,9 +481,13 @@
  */
 
 static struct serio_driver h3600ts_drv = {
-	.interrupt =	h3600ts_interrupt,
-	.connect =	h3600ts_connect,
-	.disconnect =	h3600ts_disconnect,
+	.driver		= {
+		.name	= "h3600ts",
+	},
+	.description	= DRIVER_DESC,
+	.interrupt	= h3600ts_interrupt,
+	.connect	= h3600ts_connect,
+	.disconnect	= h3600ts_disconnect,
 };
 
 /*
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:17 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:17 2004
@@ -18,6 +18,7 @@
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/device.h>
 
 struct serio {
 	void *private;
@@ -44,12 +45,15 @@
 
 	struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */
 
+	struct device dev;
+
 	struct list_head node;
 };
+#define to_serio_port(d)	container_of(d, struct serio, dev)
 
 struct serio_driver {
 	void *private;
-	char *name;
+	char *description;
 
 	void (*write_wakeup)(struct serio *);
 	irqreturn_t (*interrupt)(struct serio *, unsigned char,
@@ -59,8 +63,11 @@
 	void (*disconnect)(struct serio *);
 	void (*cleanup)(struct serio *);
 
+	struct device_driver driver;
+
 	struct list_head node;
 };
+#define to_serio_driver(d)	container_of(d, struct serio_driver, driver)
 
 int serio_open(struct serio *serio, struct serio_driver *drv);
 void serio_close(struct serio *serio);


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

* [PATCH 45/47] Re-add PC Speaker support for PPC
  2004-07-29 14:09                                                                                       ` [PATCH 44/47] This patch fixes another disconnect oops in hiddev Vojtech Pavlik
@ 2004-07-29 14:09                                                                                         ` Vojtech Pavlik
  2004-07-29 14:09                                                                                           ` [PATCH 46/47] Fix a missing index in tmdc.c Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1840.1.90, 2004-07-27 14:46:36+02:00, olh@suse.de
  input: Re-add PC Speaker support for PPC
  
  Signed-off-by: Olaf Hering <olh@suse.de>
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 drivers/input/misc/Kconfig  |    2 +-
 include/asm-ppc/8253pit.h   |   10 ++++++++++
 include/asm-ppc64/8253pit.h |   10 ++++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

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

diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	Thu Jul 29 14:38:33 2004
+++ b/drivers/input/misc/Kconfig	Thu Jul 29 14:38:33 2004
@@ -14,7 +14,7 @@
 
 config INPUT_PCSPKR
 	tristate "PC Speaker support"
-	depends on (ALPHA || X86 || X86_64 || MIPS) && INPUT && INPUT_MISC
+	depends on (ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES) && INPUT && INPUT_MISC
 	help
 	  Say Y here if you want the standard PC Speaker to be used for
 	  bells and whistles.
diff -Nru a/include/asm-ppc/8253pit.h b/include/asm-ppc/8253pit.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc/8253pit.h	Thu Jul 29 14:38:33 2004
@@ -0,0 +1,10 @@
+/*
+ * 8253/8254 Programmable Interval Timer
+ */
+
+#ifndef _8253PIT_H
+#define _8253PIT_H
+
+#define PIT_TICK_RATE 	1193182UL
+
+#endif
diff -Nru a/include/asm-ppc64/8253pit.h b/include/asm-ppc64/8253pit.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/8253pit.h	Thu Jul 29 14:38:33 2004
@@ -0,0 +1,10 @@
+/*
+ * 8253/8254 Programmable Interval Timer
+ */
+
+#ifndef _8253PIT_H
+#define _8253PIT_H
+
+#define PIT_TICK_RATE 	1193182UL
+
+#endif


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

* [PATCH 47/47] Check the range for HIDIOC?USAGES num_values.
  2004-07-29 14:09                                                                                           ` [PATCH 46/47] Fix a missing index in tmdc.c Vojtech Pavlik
@ 2004-07-29 14:09                                                                                             ` Vojtech Pavlik
  0 siblings, 0 replies; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1859, 2004-07-29 14:13:12+02:00, vojtech@suse.cz
  input: Check the range for HIDIOC?USAGES num_values.
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 hiddev.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

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

diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Thu Jul 29 14:38:23 2004
+++ b/drivers/usb/input/hiddev.c	Thu Jul 29 14:38:23 2004
@@ -633,14 +633,11 @@
 			} else if (uref->usage_index >= field->report_count)
 				goto inval;
 
-			else if ((cmd == HIDIOCGUSAGES ||
-				  cmd == HIDIOCSUSAGES) &&
-				 (uref->usage_index + uref_multi->num_values >=
-				  field->report_count ||
-				  uref->usage_index + uref_multi->num_values <
-				  uref->usage_index))
+			else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+				 (uref_multi->num_values >= HID_MAX_MULTI_USAGES ||
+				  uref->usage_index + uref_multi->num_values >= field->report_count ||
+				  uref->usage_index + uref_multi->num_values < uref->usage_index))
 				goto inval;
-
 			}
 
 		switch (cmd) {


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

* [PATCH 31/47] Fix Peter Nelson's e-mail address in gamecon.c
  2004-07-29 14:09                                                           ` [PATCH 30/47] Add CodeMercs IOWarrior to hid-core device blacklist Vojtech Pavlik
@ 2004-07-29 14:09                                                             ` Vojtech Pavlik
  2004-07-29 14:09                                                               ` [PATCH 32/47] make connect and disconnect methods mandatory for serio Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.28.16, 2004-06-24 17:55:29+02:00, vojtech@suse.cz
  input: Fix Peter Nelson's e-mail address in gamecon.c
  
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


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

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

diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c	Thu Jul 29 14:39:46 2004
+++ b/drivers/input/joystick/gamecon.c	Thu Jul 29 14:39:46 2004
@@ -2,7 +2,7 @@
  * NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
  *
  *  Copyright (c) 1999-2004 	Vojtech Pavlik <vojtech@suse.cz>
- *  Copyright (c) 2004 		Peter Nelson <pnelson@andrew.cmu.edu>
+ *  Copyright (c) 2004 		Peter Nelson <rufus-kernel@hackish.org>
  *
  *  Based on the work of:
  *  	Andree Borrmann		John Dahlstrom


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

* [PATCH 32/47] make connect and disconnect methods mandatory for serio
  2004-07-29 14:09                                                             ` [PATCH 31/47] Fix Peter Nelson's e-mail address in gamecon.c Vojtech Pavlik
@ 2004-07-29 14:09                                                               ` Vojtech Pavlik
  2004-07-29 14:09                                                                 ` [PATCH 33/47] rename serio->driver to serio->port_data Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.27, 2004-06-29 01:25:59-05:00, dtor_core@ameritech.net
  Input: make connect and disconnect methods mandatory for serio
         drivers since that's where serio_{open|close} are called
         from to actually bind driver to a port.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serio.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:41 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:41 2004
@@ -68,8 +68,7 @@
 	list_for_each_entry(dev, &serio_dev_list, node) {
 		if (serio->dev)
 			break;
-		if (dev->connect)
-			dev->connect(serio, dev);
+		dev->connect(serio, dev);
 	}
 }
 
@@ -160,7 +159,7 @@
 				/* reconnect failed - fall through to rescan */
 
 			case SERIO_RESCAN :
-				if (event->serio->dev && event->serio->dev->disconnect)
+				if (event->serio->dev)
 					event->serio->dev->disconnect(event->serio);
 				serio_find_dev(event->serio);
 				break;
@@ -282,7 +281,7 @@
 {
 	serio_remove_pending_events(serio);
 	list_del_init(&serio->node);
-	if (serio->dev && serio->dev->disconnect)
+	if (serio->dev)
 		serio->dev->disconnect(serio);
 }
 
@@ -296,7 +295,7 @@
 	down(&serio_sem);
 	list_add_tail(&dev->node, &serio_dev_list);
 	list_for_each_entry(serio, &serio_list, node)
-		if (!serio->dev && dev->connect)
+		if (!serio->dev)
 			dev->connect(serio, dev);
 	up(&serio_sem);
 }
@@ -309,7 +308,7 @@
 	list_del_init(&dev->node);
 
 	list_for_each_entry(serio, &serio_list, node) {
-		if (serio->dev == dev && dev->disconnect)
+		if (serio->dev == dev)
 			dev->disconnect(serio);
 		serio_find_dev(serio);
 	}


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

* [PATCH 44/47] This patch fixes another disconnect oops in hiddev.
  2004-07-29 14:09                                                                                     ` [PATCH 43/47] Move Compaq ProLiant DMI handling to i8042.c Vojtech Pavlik
@ 2004-07-29 14:09                                                                                       ` Vojtech Pavlik
  2004-07-29 14:09                                                                                         ` [PATCH 45/47] Re-add PC Speaker support for PPC Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.50.5, 2004-07-05 13:38:52+02:00, akropel1@rochester.rr.com
  This patch fixes another disconnect oops in hiddev.
  
  hid-core calls hiddev_disconnect() when the underlying device goes away
  (hot unplug or system shutdown). Normally, hiddev_disconnect() will
  clean up nicely and return to hid-core who then frees the hid structure.
  However, if the corresponding hiddev node is open at disconnect time,
  hiddev delays the majority of disconnect work until the device is closed
  via hiddev_release(). hiddev_release() calls hiddev_cleanup() which
  proceeds to dereference the hid struct which hid-core freed back when   
  the hardware was disconnected. Oops.
  
  To solve this, we change hiddev_disconnect() to deregister the hiddev
  minor and invalidate its table entry immediately and delay only the
  freeing of the hiddev structure itself. We're protected against future
  operations on the fd since the major fops check hiddev->exists.
  
  There may still be an ordering of events that causes a problem but I can
  no longer reproduce any manually. There are enough different subsystems
  and object lifetimes interacting here that I may have screwed something
  else up; review is certainly welcome.
  
  Signed-off-by: Adam Kropelin <akropel1@rochester.rr.com>
  Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>


 hiddev.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)

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

diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Thu Jul 29 14:38:38 2004
+++ b/drivers/usb/input/hiddev.c	Thu Jul 29 14:38:38 2004
@@ -226,16 +226,6 @@
 	return retval < 0 ? retval : 0;
 }
 
-/*
- * De-allocate a hiddev structure
- */
-static struct usb_class_driver hiddev_class;
-static void hiddev_cleanup(struct hiddev *hiddev)
-{
-	hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
-	usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
-	kfree(hiddev);
-}
 
 /*
  * release file op
@@ -256,7 +246,7 @@
 		if (list->hiddev->exist) 
 			hid_close(list->hiddev->hid);
 		else
-			hiddev_cleanup(list->hiddev);
+			kfree(list->hiddev);
 	}
 
 	kfree(list);
@@ -804,17 +794,21 @@
  * This is where hid.c calls us to disconnect a hiddev device from the
  * corresponding hid device (usually because the usb device has disconnected)
  */
+static struct usb_class_driver hiddev_class;
 void hiddev_disconnect(struct hid_device *hid)
 {
 	struct hiddev *hiddev = hid->hiddev;
 
 	hiddev->exist = 0;
 
+	hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
+	usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
+
 	if (hiddev->open) {
 		hid_close(hiddev->hid);
 		wake_up_interruptible(&hiddev->wait);
 	} else {
-		hiddev_cleanup(hiddev);
+		kfree(hiddev);
 	}
 }
 


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

* [PATCH 35/47] switch to dynamic (heap) serio port allocation
  2004-07-29 14:09                                                                   ` [PATCH 34/47] more renames in serio in preparation for sysfs integration Vojtech Pavlik
@ 2004-07-29 14:09                                                                     ` Vojtech Pavlik
  2004-07-29 14:09                                                                       ` [PATCH 36/47] allow serio drivers to create children ports Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.30, 2004-06-29 01:27:46-05:00, dtor_core@ameritech.net
  Input: switch to dynamic (heap) serio port allocation in preparation
         to sysfs integration. By having all data structures dynamically
         allocated serio driver modules can be unloaded without waiting
         for the last reference to the port to be dropped.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/mouse/psmouse-base.c |   12 +-
 drivers/input/mouse/psmouse.h      |    3 
 drivers/input/mouse/synaptics.c    |   33 +++--
 drivers/input/serio/ambakmi.c      |   35 +++---
 drivers/input/serio/ct82c710.c     |   62 ++++++-----
 drivers/input/serio/gscps2.c       |   55 ++++++---
 drivers/input/serio/i8042.c        |  208 ++++++++++++++++++++-----------------
 drivers/input/serio/i8042.h        |    7 +
 drivers/input/serio/maceps2.c      |   69 ++++++------
 drivers/input/serio/parkbd.c       |   47 +++++---
 drivers/input/serio/pcips2.c       |   30 +++--
 drivers/input/serio/q40kbd.c       |  107 ++++++++++++++-----
 drivers/input/serio/rpckbd.c       |   40 +++++--
 drivers/input/serio/sa1111ps2.c    |   32 +++--
 drivers/input/serio/serio.c        |    1 
 drivers/input/serio/serport.c      |   45 ++++----
 drivers/serial/sunsu.c             |   83 ++++++++------
 drivers/serial/sunzilog.c          |   60 ++++++----
 include/linux/serio.h              |    5 
 19 files changed, 562 insertions(+), 372 deletions(-)

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

diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:26 2004
@@ -659,7 +659,7 @@
 	if (psmouse->ptport) {
 		if (psmouse->ptport->deactivate)
 			psmouse->ptport->deactivate(psmouse);
-		__serio_unregister_port(&psmouse->ptport->serio); /* we have serio_sem */
+		__serio_unregister_port(psmouse->ptport->serio); /* we have serio_sem */
 		kfree(psmouse->ptport);
 		psmouse->ptport = NULL;
 	}
@@ -740,8 +740,8 @@
 	psmouse_initialize(psmouse);
 
 	if (psmouse->ptport) {
-		printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio.name, psmouse->phys);
-		__serio_register_port(&psmouse->ptport->serio); /* we have serio_sem */
+		printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio->name, psmouse->phys);
+		__serio_register_port(psmouse->ptport->serio); /* we have serio_sem */
 		if (psmouse->ptport->activate)
 			psmouse->ptport->activate(psmouse);
 	}
@@ -780,9 +780,9 @@
 	psmouse_initialize(psmouse);
 
 	if (psmouse->ptport) {
-       		if (psmouse_reconnect(&psmouse->ptport->serio)) {
-			__serio_unregister_port(&psmouse->ptport->serio);
-			__serio_register_port(&psmouse->ptport->serio);
+       		if (psmouse_reconnect(psmouse->ptport->serio)) {
+			__serio_unregister_port(psmouse->ptport->serio);
+			__serio_register_port(psmouse->ptport->serio);
 			if (psmouse->ptport->activate)
 				psmouse->ptport->activate(psmouse);
 		}
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/mouse/psmouse.h	Thu Jul 29 14:39:26 2004
@@ -37,7 +37,8 @@
 struct psmouse;
 
 struct psmouse_ptport {
-	struct serio serio;
+	struct serio *serio;
+	struct psmouse *parent;
 
 	void (*activate)(struct psmouse *parent);
 	void (*deactivate)(struct psmouse *parent);
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:26 2004
@@ -214,12 +214,12 @@
  ****************************************************************************/
 static int synaptics_pt_write(struct serio *port, unsigned char c)
 {
-	struct psmouse *parent = port->port_data;
+	struct psmouse_ptport *ptport = port->port_data;
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
-	if (psmouse_sliced_command(parent, c))
+	if (psmouse_sliced_command(ptport->parent, c))
 		return -1;
-	if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
+	if (psmouse_command(ptport->parent, &rate_param, PSMOUSE_CMD_SETRATE))
 		return -1;
 	return 0;
 }
@@ -248,7 +248,7 @@
 
 static void synaptics_pt_activate(struct psmouse *psmouse)
 {
-	struct psmouse *child = psmouse->ptport->serio.private;
+	struct psmouse *child = psmouse->ptport->serio->private;
 
 	/* adjust the touchpad to child's choice of protocol */
 	if (child && child->type >= PSMOUSE_GENPS) {
@@ -260,22 +260,29 @@
 static void synaptics_pt_create(struct psmouse *psmouse)
 {
 	struct psmouse_ptport *port;
+	struct serio *serio;
 
-	psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
-	if (!port) {
+	port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!port || !serio) {
 		printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
 		return;
 	}
 
 	memset(port, 0, sizeof(struct psmouse_ptport));
+	memset(serio, 0, sizeof(struct serio));
 
-	port->serio.type = SERIO_PS_PSTHRU;
-	port->serio.name = "Synaptics pass-through";
-	port->serio.phys = "synaptics-pt/serio0";
-	port->serio.write = synaptics_pt_write;
-	port->serio.port_data = psmouse;
+	serio->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;
+	serio->port_data = port;
 
+	port->serio = serio;
+	port->parent = psmouse;
 	port->activate = synaptics_pt_activate;
+
+	psmouse->ptport = port;
 }
 
 /*****************************************************************************
@@ -470,8 +477,8 @@
 		if (unlikely(priv->pkt_type == SYN_NEWABS))
 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
-		if (psmouse->ptport && psmouse->ptport->serio.drv && synaptics_is_pt_packet(psmouse->packet))
-			synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
+		if (psmouse->ptport && psmouse->ptport->serio->drv && synaptics_is_pt_packet(psmouse->packet))
+			synaptics_pass_pt_packet(psmouse->ptport->serio, psmouse->packet);
 		else
 			synaptics_process_packet(psmouse);
 
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/ambakmi.c	Thu Jul 29 14:39:26 2004
@@ -29,7 +29,7 @@
 #define KMI_BASE	(kmi->base)
 
 struct amba_kmi_port {
-	struct serio		io;
+	struct serio		*io;
 	struct clk		*clk;
 	unsigned char		*base;
 	unsigned int		irq;
@@ -44,7 +44,7 @@
 	int handled = IRQ_NONE;
 
 	while (status & KMIIR_RXINTR) {
-		serio_interrupt(&kmi->io, readb(KMIDATA), 0, regs);
+		serio_interrupt(kmi->io, readb(KMIDATA), 0, regs);
 		status = readb(KMIIR);
 		handled = IRQ_HANDLED;
 	}
@@ -117,6 +117,7 @@
 static int amba_kmi_probe(struct amba_device *dev, void *id)
 {
 	struct amba_kmi_port *kmi;
+	struct serio *io;
 	int ret;
 
 	ret = amba_request_regions(dev, NULL);
@@ -124,22 +125,25 @@
 		return ret;
 
 	kmi = kmalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
-	if (!kmi) {
+	io = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!kmi || !io) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
 	memset(kmi, 0, sizeof(struct amba_kmi_port));
+	memset(io, 0, sizeof(struct serio));
 
-	kmi->io.type		= SERIO_8042;
-	kmi->io.write		= amba_kmi_write;
-	kmi->io.open		= amba_kmi_open;
-	kmi->io.close		= amba_kmi_close;
-	kmi->io.name		= dev->dev.bus_id;
-	kmi->io.phys		= dev->dev.bus_id;
-	kmi->io.port_data	= kmi;
+	io->type	= SERIO_8042;
+	io->write	= amba_kmi_write;
+	io->open	= amba_kmi_open;
+	io->close	= amba_kmi_close;
+	strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
+	strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
+	io->port_data	= kmi;
 
-	kmi->base		= ioremap(dev->res.start, KMI_SIZE);
+	kmi->io 	= io;
+	kmi->base	= ioremap(dev->res.start, KMI_SIZE);
 	if (!kmi->base) {
 		ret = -ENOMEM;
 		goto out;
@@ -154,13 +158,14 @@
 	kmi->irq = dev->irq[0];
 	amba_set_drvdata(dev, kmi);
 
-	serio_register_port(&kmi->io);
+	serio_register_port(kmi->io);
 	return 0;
 
  unmap:
 	iounmap(kmi->base);
  out:
 	kfree(kmi);
+	kfree(io);
 	amba_release_regions(dev);
 	return ret;
 }
@@ -171,7 +176,7 @@
 
 	amba_set_drvdata(dev, NULL);
 
-	serio_unregister_port(&kmi->io);
+	serio_unregister_port(kmi->io);
 	clk_put(kmi->clk);
 	iounmap(kmi->base);
 	kfree(kmi);
@@ -184,7 +189,7 @@
 	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
 
 	/* kick the serio layer to rescan this port */
-	serio_rescan(&kmi->io);
+	serio_reconnect(kmi->io);
 
 	return 0;
 }
@@ -214,7 +219,7 @@
 
 static void __exit amba_kmi_exit(void)
 {
-	return amba_driver_unregister(&ambakmi_driver);
+	amba_driver_unregister(&ambakmi_driver);
 }
 
 module_init(amba_kmi_init);
diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
--- a/drivers/input/serio/ct82c710.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/ct82c710.c	Thu Jul 29 14:39:26 2004
@@ -43,9 +43,6 @@
 MODULE_DESCRIPTION("82C710 C&T mouse port chip driver");
 MODULE_LICENSE("GPL");
 
-static char ct82c710_name[] = "C&T 82c710 mouse port";
-static char ct82c710_phys[16];
-
 /*
  * ct82c710 interface
  */
@@ -61,10 +58,20 @@
 
 #define CT82C710_IRQ          12
 
+static struct serio *ct82c710_port;
 static int ct82c710_data;
 static int ct82c710_status;
 
-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs);
+
+/*
+ * Interrupt handler for the 82C710 mouse port. A character
+ * is waiting in the 82C710.
+ */
+
+static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
+{
+	return serio_interrupt(ct82c710_port, inb(ct82c710_data), 0, regs);
+}
 
 /*
  * Wait for device to send output char and flush any input char.
@@ -139,26 +146,6 @@
 	return 0;
 }
 
-static struct serio ct82c710_port =
-{
-	.type	= SERIO_8042,
-	.name	= ct82c710_name,
-	.phys	= ct82c710_phys,
-	.write	= ct82c710_write,
-	.open	= ct82c710_open,
-	.close	= ct82c710_close,
-};
-
-/*
- * Interrupt handler for the 82C710 mouse port. A character
- * is waiting in the 82C710.
- */
-
-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
-{
-	return serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0, regs);
-}
-
 /*
  * See if we can find a 82C710 device. Read mouse address.
  */
@@ -183,6 +170,24 @@
 	return 0;
 }
 
+static struct serio * __init ct82c710_allocate_port(void)
+{
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		memset(serio, 0, sizeof(struct serio));
+		serio->type = SERIO_8042;
+		serio->open = ct82c710_open;
+		serio->close = ct82c710_close;
+		serio->write = ct82c710_write;
+		strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name));
+		snprintf(serio->phys, sizeof(serio->phys), "isa%04x/serio0", ct82c710_data);
+	}
+
+	return serio;
+}
+
 int __init ct82c710_init(void)
 {
 	if (ct82c710_probe())
@@ -191,9 +196,12 @@
 	if (request_region(ct82c710_data, 2, "ct82c710"))
 		return -EBUSY;
 
-	sprintf(ct82c710_phys, "isa%04x/serio0", ct82c710_data);
+	if (!(ct82c710_port = ct82c710_allocate_port())) {
+		release_region(ct82c710_data, 2);
+		return -ENOMEM;
+	}
 
-	serio_register_port(&ct82c710_port);
+	serio_register_port(ct82c710_port);
 
 	printk(KERN_INFO "serio: C&T 82c710 mouse port at %#x irq %d\n",
 		ct82c710_data, CT82C710_IRQ);
@@ -203,7 +211,7 @@
 
 void __exit ct82c710_exit(void)
 {
-	serio_unregister_port(&ct82c710_port);
+	serio_unregister_port(ct82c710_port);
 	release_region(ct82c710_data, 2);
 }
 
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/gscps2.c	Thu Jul 29 14:39:26 2004
@@ -91,7 +91,7 @@
 struct gscps2port {
 	struct list_head node;
 	struct parisc_device *padev;
-	struct serio port;
+	struct serio *port;
 	spinlock_t lock;
 	char *addr;
 	u8 act, append; /* position in buffer[] */
@@ -100,7 +100,6 @@
 		u8 str;
 	} buffer[BUFFER_SIZE+1];
 	int id;
-	char name[32];
 };
 
 /*
@@ -272,7 +271,7 @@
 	    rxflags =	((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
 			((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
 
-	    serio_interrupt(&ps2port->port, data, rxflags, regs);
+	    serio_interrupt(ps2port->port, data, rxflags, regs);
 
 	  } /* while() */
 
@@ -343,7 +342,8 @@
 
 static int __init gscps2_probe(struct parisc_device *dev)
 {
-        struct gscps2port *ps2port;
+	struct gscps2port *ps2port;
+	struct serio *serio;
 	unsigned long hpa = dev->hpa;
 	int ret;
 
@@ -355,34 +355,44 @@
 		hpa += GSC_DINO_OFFSET;
 
 	ps2port = kmalloc(sizeof(struct gscps2port), GFP_KERNEL);
-	if (!ps2port)
-		return -ENOMEM;
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2port || !serio) {
+		ret = -ENOMEM;
+		goto fail_nomem;
+	}
 
 	dev_set_drvdata(&dev->dev, ps2port);
 
 	memset(ps2port, 0, sizeof(struct gscps2port));
+	memset(serio, 0, sizeof(struct serio));
+	ps2port->port = serio;
 	ps2port->padev = dev;
 	ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
 	spin_lock_init(&ps2port->lock);
 
 	gscps2_reset(ps2port);
-	ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
-	snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
-		gscps2_serio_port.name,
-		(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
-
-	memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
-	ps2port->port.port_data = ps2port;
-	ps2port->port.name = ps2port->name;
-	ps2port->port.phys = dev->dev.bus_id;
+	ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
+
+	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->write		= gscps2_write;
+	serio->open		= gscps2_open;
+	serio->close		= gscps2_close;
+	serio->port_data	= ps2port;
 
 	list_add_tail(&ps2port->node, &ps2port_list);
 
 	ret = -EBUSY;
-	if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->name, ps2port))
+	if (request_irq(dev->irq, gscps2_interrupt, SA_SHIRQ, ps2port->port->name, ps2port))
 		goto fail_miserably;
 
-	if ( (ps2port->id != GSC_ID_KEYBOARD) && (ps2port->id != GSC_ID_MOUSE) ) {
+	if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
 		printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
 				hpa, ps2port->id);
 		ret = -ENODEV;
@@ -395,12 +405,12 @@
 #endif
 
 	printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
-		ps2port->name,
+		ps2port->port->name,
 		ps2port->addr,
 		ps2port->padev->irq,
-		ps2port->port.phys);
+		ps2port->port->phys);
 
-	serio_register_port(&ps2port->port);
+	serio_register_port(ps2port->port);
 
 	return 0;
 
@@ -411,7 +421,10 @@
 	list_del(&ps2port->node);
 	iounmap(ps2port->addr);
 	release_mem_region(dev->hpa, GSC_STATUS + 4);
+
+fail_nomem:
 	kfree(ps2port);
+	kfree(serio);
 	return ret;
 }
 
@@ -424,7 +437,7 @@
 {
 	struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
 
-	serio_unregister_port(&ps2port->port);
+	serio_unregister_port(ps2port->port);
 	free_irq(dev->irq, ps2port);
 	gscps2_flush(ps2port);
 	list_del(&ps2port->node);
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:39:26 2004
@@ -75,19 +75,35 @@
 	unsigned char irqen;
 	unsigned char exists;
 	signed char mux;
-	unsigned char *name;
-	unsigned char *phys;
+	char name[8];
 };
 
-static struct serio i8042_kbd_port;
-static struct serio i8042_aux_port;
+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",
+};
+
+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;
 static unsigned char i8042_mux_present;
 static unsigned char i8042_sysdev_initialized;
 static struct pm_dev *i8042_pm_dev;
-struct timer_list i8042_timer;
+static struct timer_list i8042_timer;
 
 /*
  * Shared IRQ's require a device pointer, but this driver doesn't support
@@ -337,52 +353,6 @@
 }
 
 /*
- * Structures for registering the devices in the serio.c module.
- */
-
-static struct i8042_values i8042_kbd_values = {
-	.irqen =	I8042_CTR_KBDINT,
-	.disable =	I8042_CTR_KBDDIS,
-	.name =		"KBD",
-	.mux =		-1,
-};
-
-static struct serio i8042_kbd_port =
-{
-	.type =		SERIO_8042_XL,
-	.write =	i8042_kbd_write,
-	.open =		i8042_open,
-	.close =	i8042_close,
-	.port_data =	&i8042_kbd_values,
-	.name =		"i8042 Kbd Port",
-	.phys =		I8042_KBD_PHYS_DESC,
-};
-
-static struct i8042_values i8042_aux_values = {
-	.irqen =	I8042_CTR_AUXINT,
-	.disable =	I8042_CTR_AUXDIS,
-	.name =		"AUX",
-	.mux =		-1,
-};
-
-static struct serio i8042_aux_port =
-{
-	.type =		SERIO_8042,
-	.write =	i8042_aux_write,
-	.open =		i8042_open,
-	.close =	i8042_close,
-	.port_data =	&i8042_aux_values,
-	.name =		"i8042 Aux Port",
-	.phys =		I8042_AUX_PHYS_DESC,
-};
-
-static struct i8042_values i8042_mux_values[4];
-static struct serio i8042_mux_port[4];
-static char i8042_mux_names[4][32];
-static char i8042_mux_short[4][16];
-static char i8042_mux_phys[4][32];
-
-/*
  * 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.
@@ -428,7 +398,7 @@
 			dfl & SERIO_PARITY ? ", bad parity" : "",
 			dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-		serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
+		serio_interrupt(i8042_mux_port[(str >> 6) & 3], data, dfl, regs);
 
 		goto irq_ret;
 	}
@@ -439,14 +409,14 @@
 		dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
 	if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) {
-		serio_interrupt(&i8042_aux_port, data, dfl, regs);
+		serio_interrupt(i8042_aux_port, data, dfl, regs);
 		goto irq_ret;
 	}
 
 	if (!i8042_kbd_values.exists)
 		goto irq_ret;
 
-	serio_interrupt(&i8042_kbd_port, data, dfl, regs);
+	serio_interrupt(i8042_kbd_port, data, dfl, regs);
 
 irq_ret:
 	ret = 1;
@@ -639,8 +609,10 @@
  * registers it, and reports to the user.
  */
 
-static int __init i8042_port_register(struct i8042_values *values, struct serio *port)
+static int __init i8042_port_register(struct serio *port)
 {
+	struct i8042_values *values = port->port_data;
+
 	values->exists = 1;
 
 	i8042_ctr &= ~values->disable;
@@ -748,10 +720,8 @@
  * BIOSes.
  */
 
-	if (i8042_direct) {
+	if (i8042_direct)
 		i8042_ctr &= ~I8042_CTR_XLATE;
-		i8042_kbd_port.type = SERIO_8042;
-	}
 
 /*
  * Write CTR back.
@@ -805,14 +775,14 @@
  */
 
 	if (i8042_kbd_values.exists)
-		serio_cleanup(&i8042_kbd_port);
+		serio_cleanup(i8042_kbd_port);
 
 	if (i8042_aux_values.exists)
-		serio_cleanup(&i8042_aux_port);
+		serio_cleanup(i8042_aux_port);
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
 		if (i8042_mux_values[i].exists)
-			serio_cleanup(i8042_mux_port + i);
+			serio_cleanup(i8042_mux_port[i]);
 
 	i8042_controller_reset();
 }
@@ -854,15 +824,15 @@
  * 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_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);
+	if (i8042_aux_values.exists && i8042_activate_port(i8042_aux_port) == 0)
+		serio_reconnect(i8042_aux_port);
 
-	for (i = 0; i < 4; 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_MUX_PORTS; i++)
+		if (i8042_mux_values[i].exists && i8042_activate_port(i8042_mux_port[i]) == 0)
+			serio_reconnect(i8042_mux_port[i]);
 /*
  * Restart timer (for polling "stuck" data)
  */
@@ -932,18 +902,66 @@
 	return 0;
 }
 
-static void __init i8042_init_mux_values(struct i8042_values *values, struct serio *port, int index)
+static struct serio * __init i8042_allocate_kbd_port(void)
+{
+	struct serio *serio;
+
+	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->write		= i8042_dumbkbd ? NULL : i8042_kbd_write,
+		serio->open		= i8042_open,
+		serio->close		= i8042_close,
+		serio->port_data	= &i8042_kbd_values,
+		strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
+		strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+	}
+
+	return serio;
+}
+
+static struct serio * __init i8042_allocate_aux_port(void)
 {
-	memcpy(port, &i8042_aux_port, sizeof(struct serio));
-	memcpy(values, &i8042_aux_values, sizeof(struct i8042_values));
-	sprintf(i8042_mux_names[index], "i8042 Aux-%d Port", index);
-	sprintf(i8042_mux_phys[index], I8042_MUX_PHYS_DESC, index + 1);
-	sprintf(i8042_mux_short[index], "AUX%d", index);
-	port->name = i8042_mux_names[index];
-	port->phys = i8042_mux_phys[index];
-	port->port_data = values;
-	values->name = i8042_mux_short[index];
-	values->mux = index;
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		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	= &i8042_aux_values,
+		strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
+		strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+	}
+
+	return serio;
+}
+
+static struct serio * __init i8042_allocate_mux_port(int index)
+{
+	struct serio *serio;
+	struct i8042_values *values = &i8042_mux_values[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;
+		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;
 }
 
 int __init i8042_init(void)
@@ -964,9 +982,6 @@
 	if (i8042_controller_init())
 		return -ENODEV;
 
-	if (i8042_dumbkbd)
-		i8042_kbd_port.write = NULL;
-
 #ifdef __i386__
 	if (i8042_dmi_noloop) {
 		printk(KERN_INFO "i8042.c: AUX LoopBack command disabled by DMI.\n");
@@ -976,15 +991,21 @@
 
 	if (!i8042_noaux && !i8042_check_aux(&i8042_aux_values)) {
 		if (!i8042_nomux && !i8042_check_mux(&i8042_aux_values))
-			for (i = 0; i < 4; i++) {
-				i8042_init_mux_values(i8042_mux_values + i, i8042_mux_port + i, i);
-				i8042_port_register(i8042_mux_values + i, i8042_mux_port + i);
+			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_port_register(&i8042_aux_values, &i8042_aux_port);
+		else {
+			i8042_aux_port = i8042_allocate_aux_port();
+			if (i8042_aux_port)
+				i8042_port_register(i8042_aux_port);
+		}
 	}
 
-	i8042_port_register(&i8042_kbd_values, &i8042_kbd_port);
+	i8042_kbd_port = i8042_allocate_kbd_port();
+	if (i8042_kbd_port)
+		i8042_port_register(i8042_kbd_port);
 
 	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 
@@ -1019,14 +1040,15 @@
 	i8042_controller_cleanup();
 
 	if (i8042_kbd_values.exists)
-		serio_unregister_port(&i8042_kbd_port);
+		serio_unregister_port(i8042_kbd_port);
 
 	if (i8042_aux_values.exists)
-		serio_unregister_port(&i8042_aux_port);
+		serio_unregister_port(i8042_aux_port);
 
-	for (i = 0; i < 4; i++)
+	for (i = 0; i < I8042_NUM_MUX_PORTS; i++)
 		if (i8042_mux_values[i].exists)
-			serio_unregister_port(i8042_mux_port + i);
+			serio_unregister_port(i8042_mux_port[i]);
+
 	del_timer_sync(&i8042_timer);
 
 	i8042_platform_exit();
diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
--- a/drivers/input/serio/i8042.h	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/i8042.h	Thu Jul 29 14:39:26 2004
@@ -104,6 +104,13 @@
 #define I8042_BUFFER_SIZE	32
 
 /*
+ * Number of AUX ports on controllers supporting active multiplexing
+ * specification
+ */
+
+#define I8042_NUM_MUX_PORTS	4
+
+/*
  * Debug.
  */
 
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/maceps2.c	Thu Jul 29 14:39:26 2004
@@ -46,12 +46,14 @@
 #define PS2_CONTROL_RX_CLOCK_ENABLE  BIT(4) /* pause reception if set to 0 */
 #define PS2_CONTROL_RESET            BIT(5) /* reset */
 
-
 struct maceps2_data {
 	struct mace_ps2port *port;
 	int irq;
 };
 
+static struct maceps2_data port_data[2];
+static struct serio *maceps2_port[2];
+
 static int maceps2_write(struct serio *dev, unsigned char val)
 {
 	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
@@ -68,8 +70,7 @@
 	return -1;
 }
 
-static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
-				     struct pt_regs *regs)
+static irqreturn_t maceps2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct serio *dev = dev_id;
 	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
@@ -114,46 +115,52 @@
 	free_irq(data->irq, dev);
 }
 
-static struct maceps2_data port0_data, port1_data;
 
-static struct serio maceps2_port0 =
+static struct serio * __init maceps2_allocate_port(int idx)
 {
-	.type		= SERIO_8042,
-	.open		= maceps2_open,
-	.close		= maceps2_close,
-	.write		= maceps2_write,
-	.name		= "MACE PS/2 port0",
-	.phys		= "mace/serio0",
-	.port_data	= &port0_data,
-};
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		memset(serio, 0, sizeof(struct serio));
+		serio->type	= SERIO_8042;
+		serio->write	= maceps2_write;
+		serio->open	= maceps2_open;
+		serio->close	= maceps2_close;
+		snprintf(serio->name, sizeof(serio->name), "MACE PS/2 port%d", idx);
+		snprintf(serio->phys, sizeof(serio->phys), "mace/serio%d", idx);
+		serio->port_data = &port_data[idx];
+	}
+
+	return serio;
+}
 
-static struct serio maceps2_port1 =
-{
-	.type		= SERIO_8042,
-	.open		= maceps2_open,
-	.close		= maceps2_close,
-	.write		= maceps2_write,
-	.name		= "MACE PS/2 port1",
-	.phys		= "mace/serio1",
-	.port_data	= &port1_data,
-};
 
 static int __init maceps2_init(void)
 {
-	port0_data.port = &mace->perif.ps2.keyb;
-	port0_data.irq  = MACEISA_KEYB_IRQ;
-	port1_data.port = &mace->perif.ps2.mouse;
-	port1_data.irq  = MACEISA_MOUSE_IRQ;
-	serio_register_port(&maceps2_port0);
-	serio_register_port(&maceps2_port1);
+	port_data[0].port = &mace->perif.ps2.keyb;
+	port_data[0].irq  = MACEISA_KEYB_IRQ;
+	port_data[1].port = &mace->perif.ps2.mouse;
+	port_data[1].irq  = MACEISA_MOUSE_IRQ;
+
+	maceps2_port[0] = maceps2_allocate_port(0);
+	maceps2_port[1] = maceps2_allocate_port(1);
+	if (!maceps2_port[0] || !maceps2_port[1]) {
+		kfree(maceps2_port[0]);
+		kfree(maceps2_port[1]);
+		return -ENOMEM;
+	}
+
+	serio_register_port(maceps2_port[0]);
+	serio_register_port(maceps2_port[1]);
 
 	return 0;
 }
 
 static void __exit maceps2_exit(void)
 {
-	serio_unregister_port(&maceps2_port0);
-	serio_unregister_port(&maceps2_port1);
+	serio_unregister_port(maceps2_port[0]);
+	serio_unregister_port(maceps2_port[1]);
 }
 
 module_init(maceps2_init);
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/parkbd.c	Thu Jul 29 14:39:26 2004
@@ -53,9 +53,7 @@
 static unsigned long parkbd_start;
 
 static struct pardevice *parkbd_dev;
-
-static char parkbd_name[] = "PARKBD AT/XT keyboard adapter";
-static char parkbd_phys[32];
+static struct serio *parkbd_port;
 
 static int parkbd_readlines(void)
 {
@@ -86,13 +84,6 @@
 	return 0;
 }
 
-static struct serio parkbd_port =
-{
-	.write	= parkbd_write,
-	.name	= parkbd_name,
-	.phys	= parkbd_phys,
-};
-
 static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 
@@ -125,7 +116,7 @@
 		parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
 
 		if (parkbd_counter == parkbd_mode + 10)
-			serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
+			serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
 	}
 
 	parkbd_last = jiffies;
@@ -163,16 +154,38 @@
 	return 0;
 }
 
+static struct serio * __init parkbd_allocate_serio(void)
+{
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		serio->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);
+	}
+
+	return serio;
+}
 
 int __init parkbd_init(void)
 {
-	if (parkbd_getport()) return -1;
-	parkbd_writelines(3);
-	parkbd_port.type = parkbd_mode;
+	int err;
 
-	sprintf(parkbd_phys, "%s/serio0", parkbd_dev->port->name);
+	err = parkbd_getport();
+	if (err)
+		return err;
+
+	parkbd_port = parkbd_allocate_serio();
+	if (!parkbd_port) {
+		parport_release(parkbd_dev);
+		return -ENOMEM;
+	}
+
+	parkbd_writelines(3);
 
-	serio_register_port(&parkbd_port);
+	serio_register_port(parkbd_port);
 
 	printk(KERN_INFO "serio: PARKBD %s adapter on %s\n",
                         parkbd_mode ? "AT" : "XT", parkbd_dev->port->name);
@@ -183,7 +196,7 @@
 void __exit parkbd_exit(void)
 {
 	parport_release(parkbd_dev);
-	serio_unregister_port(&parkbd_port);
+	serio_unregister_port(parkbd_port);
 	parport_unregister_device(parkbd_dev);
 }
 
diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/pcips2.c	Thu Jul 29 14:39:26 2004
@@ -38,7 +38,7 @@
 #define PS2_STAT_TXEMPTY	(1<<7)
 
 struct pcips2_data {
-	struct serio	io;
+	struct serio	*io;
 	unsigned int	base;
 	struct pci_dev	*dev;
 };
@@ -80,7 +80,7 @@
 		if (hweight8(scancode) & 1)
 			flag ^= SERIO_PARITY;
 
-		serio_interrupt(&ps2if->io, scancode, flag, regs);
+		serio_interrupt(ps2if->io, scancode, flag, regs);
 	} while (1);
 	return IRQ_RETVAL(handled);
 }
@@ -129,6 +129,7 @@
 static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct pcips2_data *ps2if;
+	struct serio *serio;
 	int ret;
 
 	ret = pci_enable_device(dev);
@@ -142,29 +143,34 @@
 	}
 
 	ps2if = kmalloc(sizeof(struct pcips2_data), GFP_KERNEL);
-	if (!ps2if) {
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2if || !serio) {
 		ret = -ENOMEM;
 		goto release;
 	}
 
 	memset(ps2if, 0, sizeof(struct pcips2_data));
+	memset(serio, 0, sizeof(struct serio));
 
-	ps2if->io.type		= SERIO_8042;
-	ps2if->io.write		= pcips2_write;
-	ps2if->io.open		= pcips2_open;
-	ps2if->io.close		= pcips2_close;
-	ps2if->io.name		= pci_name(dev);
-	ps2if->io.phys		= dev->dev.bus_id;
-	ps2if->io.port_data	= ps2if;
+	serio->type		= SERIO_8042;
+	serio->write		= pcips2_write;
+	serio->open		= pcips2_open;
+	serio->close		= pcips2_close;
+	strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
+	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+	serio->port_data	= ps2if;
+	ps2if->io		= serio;
 	ps2if->dev		= dev;
 	ps2if->base		= pci_resource_start(dev, 0);
 
 	pci_set_drvdata(dev, ps2if);
 
-	serio_register_port(&ps2if->io);
+	serio_register_port(ps2if->io);
 	return 0;
 
  release:
+	kfree(ps2if);
+	kfree(serio);
 	release_region(pci_resource_start(dev, 0),
 		       pci_resource_len(dev, 0));
  disable:
@@ -176,7 +182,7 @@
 {
 	struct pcips2_data *ps2if = pci_get_drvdata(dev);
 
-	serio_unregister_port(&ps2if->io);
+	serio_unregister_port(ps2if->io);
 	release_region(pci_resource_start(dev, 0),
 		       pci_resource_len(dev, 0));
 	pci_set_drvdata(dev, NULL);
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/q40kbd.c	Thu Jul 29 14:39:26 2004
@@ -47,43 +47,98 @@
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-static struct serio q40kbd_port =
-{
-	.type	= SERIO_8042,
-	.name	= "Q40 kbd port",
-	.phys	= "Q40",
-	.write	= NULL,
-};
+spinlock_t q40kbd_lock = SPIN_LOCK_UNLOCKED;
+static struct serio *q40kbd_port;
 
-static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
-				    struct pt_regs *regs)
+static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&q40kbd_lock, flags);
+
 	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
-		serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
+		serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
+
+	spin_unlock_irqrestore(&q40kbd_lock, flags);
+
 	return IRQ_HANDLED;
 }
 
-static int __init q40kbd_init(void)
+/*
+ * q40kbd_flush() flushes all data that may be in the keyboard buffers
+ */
+
+static void q40kbd_flush(void)
 {
-	int maxread = 100;
+ 	int maxread = 100;
+	unsigned long flags;
+
+	spin_lock_irqsave(&q40kbd_lock, flags);
+
+ 	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
+ 		master_inb(KEYCODE_REG);
+
+	spin_unlock_irqrestore(&q40kbd_lock, flags);
+}
+
+/*
+ * q40kbd_open() is called when a port is open by the higher layer.
+ * It allocates the interrupt and enables in in the chip.
+ */
+
+static int q40kbd_open(struct serio *port)
+{
+	q40kbd_flush();
+
+	if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
+		printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
+		return -1;
+	}
+
+ 	/* off we go */
+ 	master_outb(-1, KEYBOARD_UNLOCK_REG);
+ 	master_outb(1, KEY_IRQ_ENABLE_REG);
+
+ 	return 0;
+}
 
+static void q40kbd_close(struct serio *port)
+{
+	master_outb(0, KEY_IRQ_ENABLE_REG);
+	master_outb(-1, KEYBOARD_UNLOCK_REG);
+	free_irq(Q40_IRQ_KEYBOARD, NULL);
+
+	q40kbd_flush();
+}
+
+static struct serio * __init q40kbd_allocate_port(void)
+{
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		memset(serio, 0, sizeof(struct serio));
+		serio->type	= SERIO_8042;
+		serio->open	= q40kbd_open;
+		serio->close	= q40kbd_close;
+		strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name));
+		strlcpy(serio->phys, "Q40", sizeof(serio->phys));
+	}
+
+	return serio;
+}
+
+static int __init q40kbd_init(void)
+{
 	if (!MACH_IS_Q40)
 		return -EIO;
 
-	/* allocate the IRQ */
-	request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL);
-
-	/* flush any pending input */
-	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
-		master_inb(KEYCODE_REG);
-
-	/* off we go */
-	master_outb(-1,KEYBOARD_UNLOCK_REG);
-	master_outb(1,KEY_IRQ_ENABLE_REG);
+	if (!(q40kbd_port = q40kbd_allocate_port()))
+		return -ENOMEM;
 
-	serio_register_port(&q40kbd_port);
+	serio_register_port(q40kbd_port);
 	printk(KERN_INFO "serio: Q40 kbd registered\n");
 
 	return 0;
@@ -91,11 +146,7 @@
 
 static void __exit q40kbd_exit(void)
 {
-	master_outb(0,KEY_IRQ_ENABLE_REG);
-	master_outb(-1,KEYBOARD_UNLOCK_REG);
-
-	serio_unregister_port(&q40kbd_port);
-	free_irq(Q40_IRQ_KEYBOARD, NULL);
+	serio_unregister_port(q40kbd_port);
 }
 
 module_init(q40kbd_init);
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
--- a/drivers/input/serio/rpckbd.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/rpckbd.c	Thu Jul 29 14:39:26 2004
@@ -44,6 +44,8 @@
 MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
+static struct serio *rpckbd_port;
+
 static int rpckbd_write(struct serio *port, unsigned char val)
 {
 	while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -101,25 +103,41 @@
 	free_irq(IRQ_KEYBOARDTX, port);
 }
 
-static struct serio rpckbd_port =
-{
-	.type	= SERIO_8042,
-	.open	= rpckbd_open,
-	.close	= rpckbd_close,
-	.write	= rpckbd_write,
-	.name	= "RiscPC PS/2 kbd port",
-	.phys	= "rpckbd/serio0",
-};
+/*
+ * Allocate and initialize serio structure for subsequent registration
+ * with serio core.
+ */
+
+static struct serio * __init rpckbd_allocate_port(void)
+{
+	struct serio *serio;
+
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		memset(serio, 0, sizeof(struct serio));
+		serio->type	= SERIO_8042;
+		serio->write	= rpckbd_write;
+		serio->open	= rpckbd_open;
+		serio->close	= rpckbd_close;
+		strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
+		strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
+	}
+
+	return serio;
+}
 
 static int __init rpckbd_init(void)
 {
-	serio_register_port(&rpckbd_port);
+	if (!(rpckbd_port = rpckbd_allocate_port()))
+		return -ENOMEM;
+
+	serio_register_port(rpckbd_port);
 	return 0;
 }
 
 static void __exit rpckbd_exit(void)
 {
-	serio_unregister_port(&rpckbd_port);
+	serio_unregister_port(rpckbd_port);
 }
 
 module_init(rpckbd_init);
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:39:26 2004
@@ -26,7 +26,7 @@
 #include <asm/hardware/sa1111.h>
 
 struct ps2if {
-	struct serio		io;
+	struct serio		*io;
 	struct sa1111_dev	*dev;
 	unsigned long		base;
 	unsigned int		open;
@@ -59,7 +59,7 @@
 		if (hweight8(scancode) & 1)
 			flag ^= SERIO_PARITY;
 
-		serio_interrupt(&ps2if->io, scancode, flag, regs);
+		serio_interrupt(ps2if->io, scancode, flag, regs);
 
 		status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
         }
@@ -232,22 +232,27 @@
 static int ps2_probe(struct sa1111_dev *dev)
 {
 	struct ps2if *ps2if;
+	struct serio *serio;
 	int ret;
 
 	ps2if = kmalloc(sizeof(struct ps2if), GFP_KERNEL);
-	if (!ps2if) {
-		return -ENOMEM;
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ps2if || !serio) {
+		ret = -ENOMEM;
+		goto free;
 	}
 
 	memset(ps2if, 0, sizeof(struct ps2if));
+	memset(serio, 0, sizeof(struct serio));
 
-	ps2if->io.type		= SERIO_8042;
-	ps2if->io.write		= ps2_write;
-	ps2if->io.open		= ps2_open;
-	ps2if->io.close		= ps2_close;
-	ps2if->io.name		= dev->dev.bus_id;
-	ps2if->io.phys		= dev->dev.bus_id;
-	ps2if->io.port_data	= ps2if;
+	serio->type		= SERIO_8042;
+	serio->write		= ps2_write;
+	serio->open		= ps2_open;
+	serio->close		= ps2_close;
+	strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
+	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+	serio->port_data	= ps2if;
+	ps2if->io		= serio;
 	ps2if->dev		= dev;
 	sa1111_set_drvdata(dev, ps2if);
 
@@ -292,7 +297,7 @@
 	ps2_clear_input(ps2if);
 
 	sa1111_disable_device(ps2if->dev);
-	serio_register_port(&ps2if->io);
+	serio_register_port(ps2if->io);
 	return 0;
 
  out:
@@ -302,6 +307,7 @@
  free:
 	sa1111_set_drvdata(dev, NULL);
 	kfree(ps2if);
+	kfree(serio);
 	return ret;
 }
 
@@ -312,7 +318,7 @@
 {
 	struct ps2if *ps2if = sa1111_get_drvdata(dev);
 
-	serio_unregister_port(&ps2if->io);
+	serio_unregister_port(ps2if->io);
 	release_mem_region(dev->res.start,
 			   dev->res.end - dev->res.start + 1);
 	sa1111_set_drvdata(dev, NULL);
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:26 2004
@@ -283,6 +283,7 @@
 	list_del_init(&serio->node);
 	if (serio->drv)
 		serio->drv->disconnect(serio);
+	kfree(serio);
 }
 
 /*
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/input/serio/serport.c	Thu Jul 29 14:39:26 2004
@@ -31,13 +31,10 @@
 struct serport {
 	struct tty_struct *tty;
 	wait_queue_head_t wait;
-	struct serio serio;
+	struct serio *serio;
 	unsigned long flags;
-	char phys[32];
 };
 
-char serport_name[] = "Serial port";
-
 /*
  * Callback functions from the serio code.
  */
@@ -52,7 +49,7 @@
 {
 	struct serport *serport = serio->port_data;
 
-	serport->serio.type = 0;
+	serport->serio->type = 0;
 	wake_up_interruptible(&serport->wait);
 }
 
@@ -64,26 +61,30 @@
 static int serport_ldisc_open(struct tty_struct *tty)
 {
 	struct serport *serport;
+	struct serio *serio;
 	char name[64];
 
 	serport = kmalloc(sizeof(struct serport), GFP_KERNEL);
-	if (unlikely(!serport))
+	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (unlikely(!serport || !serio)) {
+		kfree(serport);
+		kfree(serio);
 		return -ENOMEM;
-	memset(serport, 0, sizeof(struct serport));
+	}
 
+	memset(serport, 0, sizeof(struct serport));
+	serport->serio = serio;
 	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 	serport->tty = tty;
 	tty->disc_data = serport;
 
-	snprintf(serport->phys, sizeof(serport->phys), "%s/serio0", tty_name(tty, name));
-
-	serport->serio.name = serport_name;
-	serport->serio.phys = serport->phys;
-
-	serport->serio.type = SERIO_RS232;
-	serport->serio.write = serport_serio_write;
-	serport->serio.close = serport_serio_close;
-	serport->serio.port_data = serport;
+	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->write = serport_serio_write;
+	serio->close = serport_serio_close;
+	serio->port_data = serport;
 
 	init_waitqueue_head(&serport->wait);
 
@@ -114,7 +115,7 @@
 	struct serport *serport = (struct serport*) tty->disc_data;
 	int i;
 	for (i = 0; i < count; i++)
-		serio_interrupt(&serport->serio, cp[i], 0, NULL);
+		serio_interrupt(serport->serio, cp[i], 0, NULL);
 }
 
 /*
@@ -142,10 +143,10 @@
 	if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
 		return -EBUSY;
 
-	serio_register_port(&serport->serio);
+	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);
-	serio_unregister_port(&serport->serio);
+	wait_event_interruptible(serport->wait, !serport->serio->type);
+	serio_unregister_port(serport->serio);
 
 	clear_bit(SERPORT_BUSY, &serport->flags);
 
@@ -161,7 +162,7 @@
 	struct serport *serport = (struct serport*) tty->disc_data;
 
 	if (cmd == SPIOCSTYPE)
-		return get_user(serport->serio.type, (unsigned long __user *) arg);
+		return get_user(serport->serio->type, (unsigned long __user *) arg);
 
 	return -EINVAL;
 }
@@ -170,7 +171,7 @@
 {
 	struct serport *sp = (struct serport *) tty->disc_data;
 
-	serio_drv_write_wakeup(&sp->serio);
+	serio_drv_write_wakeup(sp->serio);
 }
 
 /*
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/serial/sunsu.c	Thu Jul 29 14:39:26 2004
@@ -98,7 +98,7 @@
 	unsigned int		irq;
 
 #ifdef CONFIG_SERIO
-	struct serio		serio;
+	struct serio		*serio;
 	int			serio_open;
 #endif
 };
@@ -520,7 +520,7 @@
 		/* Stop-A is handled by drivers/char/keyboard.c now. */
 		if (up->su_type == SU_PORT_KBD) {
 #ifdef CONFIG_SERIO
-			serio_interrupt(&up->serio, ch, 0, regs);
+			serio_interrupt(up->serio, ch, 0, regs);
 #endif
 		} else if (up->su_type == SU_PORT_MS) {
 			int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -534,7 +534,7 @@
 
 			case 0:
 #ifdef CONFIG_SERIO
-				serio_interrupt(&up->serio, ch, 0, regs);
+				serio_interrupt(up->serio, ch, 0, regs);
 #endif
 				break;
 			};
@@ -1284,54 +1284,58 @@
 	.major			= TTY_MAJOR,
 };
 
-static int __init sunsu_kbd_ms_init(void)
+static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up, int channel)
 {
-	struct uart_sunsu_port *up;
-	int i;
+	struct serio *serio;
 
-	for (i = 0, up = sunsu_ports; i < 2; i++, up++) {
-		up->port.line = i;
-		up->port.type = PORT_UNKNOWN;
-		up->port.uartclk = (SU_BASE_BAUD * 16);
+	up->port.line = channel;
+	up->port.type = PORT_UNKNOWN;
+	up->port.uartclk = (SU_BASE_BAUD * 16);
 
-		if (up->su_type == SU_PORT_KBD)
-			up->cflag = B1200 | CS8 | CLOCAL | CREAD;
-		else
-			up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+	if (up->su_type == SU_PORT_KBD)
+		up->cflag = B1200 | CS8 | CLOCAL | CREAD;
+	else
+		up->cflag = B4800 | CS8 | CLOCAL | CREAD;
 
-		sunsu_autoconfig(up);
-		if (up->port.type == PORT_UNKNOWN)
-			continue;
+	sunsu_autoconfig(up);
+	if (up->port.type == PORT_UNKNOWN)
+		return -1;
 
-		printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
-		       i,
-		       up->port.membase, __irq_itoa(up->irq),
-		       sunsu_type(&up->port));
+	printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
+	       channel,
+	       up->port.membase, __irq_itoa(up->irq),
+	       sunsu_type(&up->port));
 
 #ifdef CONFIG_SERIO
-		memset(&up->serio, 0, sizeof(up->serio));
+	up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
+		memset(serio, 0, sizeof(serio));
 
-		up->serio.port_data = up;
+		serio->port_data = up;
 
-		up->serio.type = SERIO_RS232;
+		serio->type = SERIO_RS232;
 		if (up->su_type == SU_PORT_KBD) {
-			up->serio.type |= SERIO_SUNKBD;
-			up->serio.name = "sukbd";
+			serio->type |= SERIO_SUNKBD;
+			strlcpy(serio->name, "sukbd", sizeof(serio->name));
 		} else {
-			up->serio.type |= (SERIO_SUN | (1 << 16));
-			up->serio.name = "sums";
+			serio->type |= (SERIO_SUN | (1 << 16));
+			strlcpy(serio->name, "sums", sizeof(serio->name));
 		}
-		up->serio.phys = (i == 0 ? "su/serio0" : "su/serio1");
+		strlcpy(serio->phys, (channel == 0 ? "su/serio0" : "su/serio1"),
+			sizeof(serio->phys));
 
-		up->serio.write = sunsu_serio_write;
-		up->serio.open = sunsu_serio_open;
-		up->serio.close = sunsu_serio_close;
+		serio->write = sunsu_serio_write;
+		serio->open = sunsu_serio_open;
+		serio->close = sunsu_serio_close;
 
-		serio_register_port(&up->serio);
+		serio_register_port(serio);
+	} else {
+		printk(KERN_WARNING "su%d: not enough memory for serio port\n",
+			channel);
+	}
 #endif
 
-		sunsu_startup(&up->port);
-	}
+	sunsu_startup(&up->port);
 	return 0;
 }
 
@@ -1680,10 +1684,12 @@
 	if (scan.msx != -1 && scan.kbx != -1) {
 		sunsu_ports[0].su_type = SU_PORT_MS;
 		sunsu_ports[0].port_node = scan.msnode;
+		sunsu_kbd_ms_init(&sunsu_ports[0], 0);
+
 		sunsu_ports[1].su_type = SU_PORT_KBD;
 		sunsu_ports[1].port_node = scan.kbnode;
+		sunsu_kbd_ms_init(&sunsu_ports[1], 1);
 
-		sunsu_kbd_ms_init();
 		return 0;
 	}
 
@@ -1715,7 +1721,10 @@
 		if (up->su_type == SU_PORT_MS ||
 		    up->su_type == SU_PORT_KBD) {
 #ifdef CONFIG_SERIO
-			serio_unregister_port(&up->serio);
+			if (up->serio) {
+				serio_unregister_port(up->serio);
+				up->serio = NULL;
+			}
 #endif
 		} else if (up->port.type != PORT_UNKNOWN) {
 			uart_remove_one_port(&sunsu_reg, &up->port);
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Thu Jul 29 14:39:26 2004
+++ b/drivers/serial/sunzilog.c	Thu Jul 29 14:39:26 2004
@@ -107,7 +107,7 @@
 	unsigned char			prev_status;
 
 #ifdef CONFIG_SERIO
-	struct serio			serio;
+	struct serio			*serio;
 	int				serio_open;
 #endif
 };
@@ -291,7 +291,7 @@
 		/* Stop-A is handled by drivers/char/keyboard.c now. */
 #ifdef CONFIG_SERIO
 		if (up->serio_open)
-			serio_interrupt(&up->serio, ch, 0, regs);
+			serio_interrupt(up->serio, ch, 0, regs);
 #endif
 	} else if (ZS_IS_MOUSE(up)) {
 		int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -306,7 +306,7 @@
 		case 0:
 #ifdef CONFIG_SERIO
 			if (up->serio_open)
-				serio_interrupt(&up->serio, ch, 0, regs);
+				serio_interrupt(up->serio, ch, 0, regs);
 #endif
 			break;
 		};
@@ -1529,6 +1529,7 @@
 static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
 {
 	int baud, brg;
+	struct serio *serio;
 
 	if (channel == KEYBOARD_LINE) {
 		up->flags |= SUNZILOG_FLAG_CONS_KEYB;
@@ -1547,26 +1548,34 @@
 	sunzilog_convert_to_zs(up, up->cflag, 0, brg);
 
 #ifdef CONFIG_SERIO
-	memset(&up->serio, 0, sizeof(up->serio));
+	up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	if (serio) {
 
-	up->serio.port_data = up;
+		memset(serio, 0, sizeof(serio));
 
-	up->serio.type = SERIO_RS232;
-	if (channel == KEYBOARD_LINE) {
-		up->serio.type |= SERIO_SUNKBD;
-		up->serio.name = "zskbd";
-	} else {
-		up->serio.type |= (SERIO_SUN | (1 << 16));
-		up->serio.name = "zsms";
-	}
-	up->serio.phys = (channel == KEYBOARD_LINE ?
-			  "zs/serio0" : "zs/serio1");
+		serio->port_data = up;
 
-	up->serio.write = sunzilog_serio_write;
-	up->serio.open = sunzilog_serio_open;
-	up->serio.close = sunzilog_serio_close;
+		serio->type = SERIO_RS232;
+		if (channel == KEYBOARD_LINE) {
+			serio->type |= SERIO_SUNKBD;
+			strlcpy(serio->name, "zskbd", sizeof(serio->name));
+		} else {
+			serio->type |= (SERIO_SUN | (1 << 16));
+			strlcpy(serio->name, "zsms", sizeof(serio->name));
+		}
+		strlcpy(serio->phys,
+			(channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+			sizeof(serio->phys));
+
+		serio->write = sunzilog_serio_write;
+		serio->open = sunzilog_serio_open;
+		serio->close = sunzilog_serio_close;
 
-	serio_register_port(&up->serio);
+		serio_register_port(serio);
+	} else {
+		printk(KERN_WARNING "zs%d: not enough memory for serio port\n",
+			channel);
+	}
 #endif
 
 	sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
@@ -1732,10 +1741,15 @@
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		struct uart_sunzilog_port *up = &sunzilog_port_table[i];
 
-		if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
-			continue;
-
-		uart_remove_one_port(&sunzilog_reg, &up->port);
+		if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up)) {
+#ifdef CONFIG_SERIO
+			if (up->serio) {
+				serio_unregister_port(up->serio);
+				up->serio = NULL;
+			}
+#endif
+		} else
+			uart_remove_one_port(&sunzilog_reg, &up->port);
 	}
 
 	uart_unregister_driver(&sunzilog_reg);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:26 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:26 2004
@@ -22,8 +22,9 @@
 struct serio {
 	void *private;
 	void *port_data;
-	char *name;
-	char *phys;
+
+	char name[32];
+	char phys[32];
 
 	unsigned short idbus;
 	unsigned short idvendor;


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

* [PATCH 39/47] allow marking some drivers as manual bind only
  2004-07-29 14:09                                                                           ` [PATCH 38/47] allow users to manually rebind serio ports Vojtech Pavlik
@ 2004-07-29 14:09                                                                             ` Vojtech Pavlik
  2004-07-29 14:09                                                                               ` [PATCH 40/47] Add serio_raw driver Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.34, 2004-06-29 01:30:19-05:00, dtor_core@ameritech.net
  Input: allow marking some drivers (that don't do HW autodetection)
         as manual bind only. Such drivers will only be bound to a
         serio port if user requests it by echoing driver name into
         port's sysfs driver attribute.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


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

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:07 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:07 2004
@@ -92,8 +92,9 @@
 	struct serio_driver *drv;
 
 	list_for_each_entry(drv, &serio_driver_list, node)
-		if (serio_bind_driver(serio, drv))
-			break;
+		if (!drv->manual_bind)
+			if (serio_bind_driver(serio, drv))
+				break;
 }
 
 /*
@@ -494,6 +495,9 @@
 	driver_register(&drv->driver);
 	driver_create_file(&drv->driver, &driver_attr_description);
 
+	if (drv->manual_bind)
+		goto out;
+
 start_over:
 	list_for_each_entry(serio, &serio_list, node) {
 		if (!serio->drv) {
@@ -507,6 +511,7 @@
 		}
 	}
 
+out:
 	up(&serio_sem);
 }
 
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:07 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:07 2004
@@ -55,6 +55,8 @@
 	void *private;
 	char *description;
 
+	int manual_bind;
+
 	void (*write_wakeup)(struct serio *);
 	irqreturn_t (*interrupt)(struct serio *, unsigned char,
 			unsigned int, struct pt_regs *);


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

* [PATCH 33/47] rename serio->driver to serio->port_data
  2004-07-29 14:09                                                               ` [PATCH 32/47] make connect and disconnect methods mandatory for serio Vojtech Pavlik
@ 2004-07-29 14:09                                                                 ` Vojtech Pavlik
  2004-07-29 14:09                                                                   ` [PATCH 34/47] more renames in serio in preparation for sysfs integration Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.28, 2004-06-29 01:26:36-05:00, dtor_core@ameritech.net
  Input: rename serio->driver to serio->port_data in preparation
         to sysfs integration
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/mouse/synaptics.c |    4 ++--
 drivers/input/serio/ambakmi.c   |   22 +++++++++++-----------
 drivers/input/serio/gscps2.c    |    8 ++++----
 drivers/input/serio/i8042.c     |   14 +++++++-------
 drivers/input/serio/maceps2.c   |   36 ++++++++++++++++++------------------
 drivers/input/serio/pcips2.c    |    8 ++++----
 drivers/input/serio/sa1111ps2.c |    8 ++++----
 drivers/input/serio/serport.c   |    6 +++---
 drivers/serial/sunsu.c          |    8 ++++----
 drivers/serial/sunzilog.c       |    8 ++++----
 include/linux/serio.h           |    2 +-
 11 files changed, 62 insertions(+), 62 deletions(-)

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

diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:36 2004
@@ -214,7 +214,7 @@
  ****************************************************************************/
 static int synaptics_pt_write(struct serio *port, unsigned char c)
 {
-	struct psmouse *parent = port->driver;
+	struct psmouse *parent = port->port_data;
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
 	if (psmouse_sliced_command(parent, c))
@@ -273,7 +273,7 @@
 	port->serio.name = "Synaptics pass-through";
 	port->serio.phys = "synaptics-pt/serio0";
 	port->serio.write = synaptics_pt_write;
-	port->serio.driver = psmouse;
+	port->serio.port_data = psmouse;
 
 	port->activate = synaptics_pt_activate;
 }
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/ambakmi.c	Thu Jul 29 14:39:36 2004
@@ -54,7 +54,7 @@
 
 static int amba_kmi_write(struct serio *io, unsigned char val)
 {
-	struct amba_kmi_port *kmi = io->driver;
+	struct amba_kmi_port *kmi = io->port_data;
 	unsigned int timeleft = 10000; /* timeout in 100ms */
 
 	while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
@@ -68,7 +68,7 @@
 
 static int amba_kmi_open(struct serio *io)
 {
-	struct amba_kmi_port *kmi = io->driver;
+	struct amba_kmi_port *kmi = io->port_data;
 	unsigned int divisor;
 	int ret;
 
@@ -105,7 +105,7 @@
 
 static void amba_kmi_close(struct serio *io)
 {
-	struct amba_kmi_port *kmi = io->driver;
+	struct amba_kmi_port *kmi = io->port_data;
 
 	writeb(0, KMICR);
 
@@ -131,15 +131,15 @@
 
 	memset(kmi, 0, sizeof(struct amba_kmi_port));
 
-	kmi->io.type	= SERIO_8042;
-	kmi->io.write	= amba_kmi_write;
-	kmi->io.open	= amba_kmi_open;
-	kmi->io.close	= amba_kmi_close;
-	kmi->io.name	= dev->dev.bus_id;
-	kmi->io.phys	= dev->dev.bus_id;
-	kmi->io.driver	= kmi;
+	kmi->io.type		= SERIO_8042;
+	kmi->io.write		= amba_kmi_write;
+	kmi->io.open		= amba_kmi_open;
+	kmi->io.close		= amba_kmi_close;
+	kmi->io.name		= dev->dev.bus_id;
+	kmi->io.phys		= dev->dev.bus_id;
+	kmi->io.port_data	= kmi;
 
-	kmi->base	= ioremap(dev->res.start, KMI_SIZE);
+	kmi->base		= ioremap(dev->res.start, KMI_SIZE);
 	if (!kmi->base) {
 		ret = -ENOMEM;
 		goto out;
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/gscps2.c	Thu Jul 29 14:39:36 2004
@@ -288,7 +288,7 @@
 
 static int gscps2_write(struct serio *port, unsigned char data)
 {
-	struct gscps2port *ps2port = port->driver;
+	struct gscps2port *ps2port = port->port_data;
 
 	if (!gscps2_writeb_output(ps2port, data)) {
 		printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
@@ -304,7 +304,7 @@
 
 static int gscps2_open(struct serio *port)
 {
-	struct gscps2port *ps2port = port->driver;
+	struct gscps2port *ps2port = port->port_data;
 
 	gscps2_reset(ps2port);
 
@@ -319,7 +319,7 @@
 
 static void gscps2_close(struct serio *port)
 {
-	struct gscps2port *ps2port = port->driver;
+	struct gscps2port *ps2port = port->port_data;
 	gscps2_enable(ps2port, DISABLE);
 }
 
@@ -372,7 +372,7 @@
 		(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
 
 	memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
-	ps2port->port.driver = ps2port;
+	ps2port->port.port_data = ps2port;
 	ps2port->port.name = ps2port->name;
 	ps2port->port.phys = dev->dev.bus_id;
 
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/i8042.c	Thu Jul 29 14:39:36 2004
@@ -223,7 +223,7 @@
 
 static int i8042_aux_write(struct serio *port, unsigned char c)
 {
-	struct i8042_values *values = port->driver;
+	struct i8042_values *values = port->port_data;
 	int retval;
 
 /*
@@ -251,7 +251,7 @@
 
 static int i8042_activate_port(struct serio *port)
 {
-	struct i8042_values *values = port->driver;
+	struct i8042_values *values = port->port_data;
 
 	i8042_flush();
 
@@ -279,7 +279,7 @@
 
 static int i8042_open(struct serio *port)
 {
-	struct i8042_values *values = port->driver;
+	struct i8042_values *values = port->port_data;
 
 	if (values->mux != -1)
 		if (i8042_mux_open++)
@@ -318,7 +318,7 @@
 
 static void i8042_close(struct serio *port)
 {
-	struct i8042_values *values = port->driver;
+	struct i8042_values *values = port->port_data;
 
 	if (values->mux != -1)
 		if (--i8042_mux_open)
@@ -353,7 +353,7 @@
 	.write =	i8042_kbd_write,
 	.open =		i8042_open,
 	.close =	i8042_close,
-	.driver =	&i8042_kbd_values,
+	.port_data =	&i8042_kbd_values,
 	.name =		"i8042 Kbd Port",
 	.phys =		I8042_KBD_PHYS_DESC,
 };
@@ -371,7 +371,7 @@
 	.write =	i8042_aux_write,
 	.open =		i8042_open,
 	.close =	i8042_close,
-	.driver =	&i8042_aux_values,
+	.port_data =	&i8042_aux_values,
 	.name =		"i8042 Aux Port",
 	.phys =		I8042_AUX_PHYS_DESC,
 };
@@ -941,7 +941,7 @@
 	sprintf(i8042_mux_short[index], "AUX%d", index);
 	port->name = i8042_mux_names[index];
 	port->phys = i8042_mux_phys[index];
-	port->driver = values;
+	port->port_data = values;
 	values->name = i8042_mux_short[index];
 	values->mux = index;
 }
diff -Nru a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
--- a/drivers/input/serio/maceps2.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/maceps2.c	Thu Jul 29 14:39:36 2004
@@ -54,7 +54,7 @@
 
 static int maceps2_write(struct serio *dev, unsigned char val)
 {
-	struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
 	unsigned int timeout = MACE_PS2_TIMEOUT;
 
 	do {
@@ -72,7 +72,7 @@
 				     struct pt_regs *regs)
 {
 	struct serio *dev = dev_id;
-	struct mace_ps2port *port = ((struct maceps2_data *)dev->driver)->port;
+	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
 	unsigned int byte;
 
 	if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
@@ -85,7 +85,7 @@
 
 static int maceps2_open(struct serio *dev)
 {
-	struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+	struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
 
 	if (request_irq(data->irq, maceps2_interrupt, 0, "PS/2 port", dev)) {
 		printk(KERN_ERR "Could not allocate PS/2 IRQ\n");
@@ -106,7 +106,7 @@
 
 static void maceps2_close(struct serio *dev)
 {
-	struct maceps2_data *data = (struct maceps2_data *)dev->driver;
+	struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
 
 	mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
 		   data->port->control);
@@ -118,24 +118,24 @@
 
 static struct serio maceps2_port0 =
 {
-	.type	= SERIO_8042,
-	.open	= maceps2_open,
-	.close	= maceps2_close,
-	.write	= maceps2_write,
-	.name	= "MACE PS/2 port0",
-	.phys	= "mace/serio0",
-	.driver = &port0_data,
+	.type		= SERIO_8042,
+	.open		= maceps2_open,
+	.close		= maceps2_close,
+	.write		= maceps2_write,
+	.name		= "MACE PS/2 port0",
+	.phys		= "mace/serio0",
+	.port_data	= &port0_data,
 };
 
 static struct serio maceps2_port1 =
 {
-	.type	= SERIO_8042,
-	.open	= maceps2_open,
-	.close	= maceps2_close,
-	.write	= maceps2_write,
-	.name	= "MACE PS/2 port1",
-	.phys	= "mace/serio1",
-	.driver = &port1_data,
+	.type		= SERIO_8042,
+	.open		= maceps2_open,
+	.close		= maceps2_close,
+	.write		= maceps2_write,
+	.name		= "MACE PS/2 port1",
+	.phys		= "mace/serio1",
+	.port_data	= &port1_data,
 };
 
 static int __init maceps2_init(void)
diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/pcips2.c	Thu Jul 29 14:39:36 2004
@@ -45,7 +45,7 @@
 
 static int pcips2_write(struct serio *io, unsigned char val)
 {
-	struct pcips2_data *ps2if = io->driver;
+	struct pcips2_data *ps2if = io->port_data;
 	unsigned int stat;
 
 	do {
@@ -101,7 +101,7 @@
 
 static int pcips2_open(struct serio *io)
 {
-	struct pcips2_data *ps2if = io->driver;
+	struct pcips2_data *ps2if = io->port_data;
 	int ret, val = 0;
 
 	outb(PS2_CTRL_ENABLE, ps2if->base);
@@ -119,7 +119,7 @@
 
 static void pcips2_close(struct serio *io)
 {
-	struct pcips2_data *ps2if = io->driver;
+	struct pcips2_data *ps2if = io->port_data;
 
 	outb(0, ps2if->base);
 
@@ -155,7 +155,7 @@
 	ps2if->io.close		= pcips2_close;
 	ps2if->io.name		= pci_name(dev);
 	ps2if->io.phys		= dev->dev.bus_id;
-	ps2if->io.driver	= ps2if;
+	ps2if->io.port_data	= ps2if;
 	ps2if->dev		= dev;
 	ps2if->base		= pci_resource_start(dev, 0);
 
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:39:36 2004
@@ -95,7 +95,7 @@
  */
 static int ps2_write(struct serio *io, unsigned char val)
 {
-	struct ps2if *ps2if = io->driver;
+	struct ps2if *ps2if = io->port_data;
 	unsigned long flags;
 	unsigned int head;
 
@@ -122,7 +122,7 @@
 
 static int ps2_open(struct serio *io)
 {
-	struct ps2if *ps2if = io->driver;
+	struct ps2if *ps2if = io->port_data;
 	int ret;
 
 	sa1111_enable_device(ps2if->dev);
@@ -154,7 +154,7 @@
 
 static void ps2_close(struct serio *io)
 {
-	struct ps2if *ps2if = io->driver;
+	struct ps2if *ps2if = io->port_data;
 
 	sa1111_writel(0, ps2if->base + SA1111_PS2CR);
 
@@ -247,7 +247,7 @@
 	ps2if->io.close		= ps2_close;
 	ps2if->io.name		= dev->dev.bus_id;
 	ps2if->io.phys		= dev->dev.bus_id;
-	ps2if->io.driver	= ps2if;
+	ps2if->io.port_data	= ps2if;
 	ps2if->dev		= dev;
 	sa1111_set_drvdata(dev, ps2if);
 
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/input/serio/serport.c	Thu Jul 29 14:39:36 2004
@@ -44,13 +44,13 @@
 
 static int serport_serio_write(struct serio *serio, unsigned char data)
 {
-	struct serport *serport = serio->driver;
+	struct serport *serport = serio->port_data;
 	return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
 }
 
 static void serport_serio_close(struct serio *serio)
 {
-	struct serport *serport = serio->driver;
+	struct serport *serport = serio->port_data;
 
 	serport->serio.type = 0;
 	wake_up_interruptible(&serport->wait);
@@ -83,7 +83,7 @@
 	serport->serio.type = SERIO_RS232;
 	serport->serio.write = serport_serio_write;
 	serport->serio.close = serport_serio_close;
-	serport->serio.driver = serport;
+	serport->serio.port_data = serport;
 
 	init_waitqueue_head(&serport->wait);
 
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/serial/sunsu.c	Thu Jul 29 14:39:36 2004
@@ -994,7 +994,7 @@
 
 static int sunsu_serio_write(struct serio *serio, unsigned char ch)
 {
-	struct uart_sunsu_port *up = serio->driver;
+	struct uart_sunsu_port *up = serio->port_data;
 	unsigned long flags;
 	int lsr;
 
@@ -1014,7 +1014,7 @@
 
 static int sunsu_serio_open(struct serio *serio)
 {
-	struct uart_sunsu_port *up = serio->driver;
+	struct uart_sunsu_port *up = serio->port_data;
 	unsigned long flags;
 	int ret;
 
@@ -1031,7 +1031,7 @@
 
 static void sunsu_serio_close(struct serio *serio)
 {
-	struct uart_sunsu_port *up = serio->driver;
+	struct uart_sunsu_port *up = serio->port_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sunsu_serio_lock, flags);
@@ -1311,7 +1311,7 @@
 #ifdef CONFIG_SERIO
 		memset(&up->serio, 0, sizeof(up->serio));
 
-		up->serio.driver = up;
+		up->serio.port_data = up;
 
 		up->serio.type = SERIO_RS232;
 		if (up->su_type == SU_PORT_KBD) {
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Thu Jul 29 14:39:36 2004
+++ b/drivers/serial/sunzilog.c	Thu Jul 29 14:39:36 2004
@@ -1295,7 +1295,7 @@
 
 static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
 {
-	struct uart_sunzilog_port *up = serio->driver;
+	struct uart_sunzilog_port *up = serio->port_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sunzilog_serio_lock, flags);
@@ -1309,7 +1309,7 @@
 
 static int sunzilog_serio_open(struct serio *serio)
 {
-	struct uart_sunzilog_port *up = serio->driver;
+	struct uart_sunzilog_port *up = serio->port_data;
 	unsigned long flags;
 	int ret;
 
@@ -1326,7 +1326,7 @@
 
 static void sunzilog_serio_close(struct serio *serio)
 {
-	struct uart_sunzilog_port *up = serio->driver;
+	struct uart_sunzilog_port *up = serio->port_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sunzilog_serio_lock, flags);
@@ -1549,7 +1549,7 @@
 #ifdef CONFIG_SERIO
 	memset(&up->serio, 0, sizeof(up->serio));
 
-	up->serio.driver = up;
+	up->serio.port_data = up;
 
 	up->serio.type = SERIO_RS232;
 	if (channel == KEYBOARD_LINE) {
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:36 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:36 2004
@@ -21,7 +21,7 @@
 
 struct serio {
 	void *private;
-	void *driver;
+	void *port_data;
 	char *name;
 	char *phys;
 


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

* [PATCH 36/47] allow serio drivers to create children ports
  2004-07-29 14:09                                                                     ` [PATCH 35/47] switch to dynamic (heap) serio port allocation Vojtech Pavlik
@ 2004-07-29 14:09                                                                       ` Vojtech Pavlik
  2004-07-29 14:09                                                                         ` [PATCH 37/47] serio sysfs integration Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.31, 2004-06-29 01:28:21-05:00, dtor_core@ameritech.net
  Input: allow serio drivers to create children ports and register these
         ports for them in serio core to avoid having recursion in connect
         methods.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/mouse/psmouse-base.c |   75 ++++++++----
 drivers/input/mouse/psmouse.h      |   16 --
 drivers/input/mouse/synaptics.c    |   27 +---
 drivers/input/serio/serio.c        |  215 ++++++++++++++++++++++++++++---------
 include/linux/serio.h              |    4 
 5 files changed, 231 insertions(+), 106 deletions(-)

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

diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:21 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:21 2004
@@ -652,16 +652,15 @@
 
 static void psmouse_disconnect(struct serio *serio)
 {
-	struct psmouse *psmouse = serio->private;
+	struct psmouse *psmouse, *parent;
 
+	psmouse = serio->private;
 	psmouse->state = PSMOUSE_CMD_MODE;
 
-	if (psmouse->ptport) {
-		if (psmouse->ptport->deactivate)
-			psmouse->ptport->deactivate(psmouse);
-		__serio_unregister_port(psmouse->ptport->serio); /* we have serio_sem */
-		kfree(psmouse->ptport);
-		psmouse->ptport = NULL;
+	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) {
+		parent = serio->parent->private;
+		if (parent->pt_deactivate)
+			parent->pt_deactivate(parent);
 	}
 
 	if (psmouse->disconnect)
@@ -680,14 +679,17 @@
  */
 static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
 {
-	struct psmouse *psmouse;
+	struct psmouse *psmouse, *parent = NULL;
 
 	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
 	    (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
 		return;
 
+	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU)
+		parent = serio->parent->private;
+
 	if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL)))
-		return;
+		goto out;
 
 	memset(psmouse, 0, sizeof(struct psmouse));
 
@@ -703,14 +705,14 @@
 	if (serio_open(serio, drv)) {
 		kfree(psmouse);
 		serio->private = NULL;
-		return;
+		goto out;
 	}
 
 	if (psmouse_probe(psmouse) < 0) {
 		serio_close(serio);
 		kfree(psmouse);
 		serio->private = NULL;
-		return;
+		goto out;
 	}
 
 	psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
@@ -739,20 +741,36 @@
 
 	psmouse_initialize(psmouse);
 
-	if (psmouse->ptport) {
-		printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio->name, psmouse->phys);
-		__serio_register_port(psmouse->ptport->serio); /* we have serio_sem */
-		if (psmouse->ptport->activate)
-			psmouse->ptport->activate(psmouse);
-	}
+	if (parent && parent->pt_activate)
+		parent->pt_activate(parent);
 
-	psmouse_activate(psmouse);
+	/*
+	 * OK, the device is ready, we just need to activate it (turn the
+	 * stream mode on). But if mouse has a pass-through port we don't
+	 * want to do it yet to not disturb child detection.
+	 * The child will activate this port when it's ready.
+	 */
+
+	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);
+	} else
+		psmouse_activate(psmouse);
+
+out:
+	/* If this is a pass-through port the parent awaits to be activated */
+	if (parent)
+		psmouse_activate(parent);
 }
 
 
 static int psmouse_reconnect(struct serio *serio)
 {
 	struct psmouse *psmouse = serio->private;
+	struct psmouse *parent = NULL;
 	struct serio_driver *drv = serio->drv;
 
 	if (!drv || !psmouse) {
@@ -779,16 +797,19 @@
 	 */
 	psmouse_initialize(psmouse);
 
-	if (psmouse->ptport) {
-       		if (psmouse_reconnect(psmouse->ptport->serio)) {
-			__serio_unregister_port(psmouse->ptport->serio);
-			__serio_register_port(psmouse->ptport->serio);
-			if (psmouse->ptport->activate)
-				psmouse->ptport->activate(psmouse);
-		}
-	}
+	if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU)
+		parent = serio->parent->private;
+
+	if (parent && parent->pt_activate)
+		parent->pt_activate(parent);
+
+	if (!serio->child)
+		psmouse_activate(psmouse);
+
+	/* If this is a pass-through port the parent waits to be activated */
+	if (parent)
+		psmouse_activate(parent);
 
-	psmouse_activate(psmouse);
 	return 0;
 }
 
diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h	Thu Jul 29 14:39:21 2004
+++ b/drivers/input/mouse/psmouse.h	Thu Jul 29 14:39:21 2004
@@ -34,21 +34,10 @@
 	PSMOUSE_FULL_PACKET
 } psmouse_ret_t;
 
-struct psmouse;
-
-struct psmouse_ptport {
-	struct serio *serio;
-	struct psmouse *parent;
-
-	void (*activate)(struct psmouse *parent);
-	void (*deactivate)(struct psmouse *parent);
-};
-
 struct psmouse {
 	void *private;
 	struct input_dev dev;
 	struct serio *serio;
-	struct psmouse_ptport *ptport;
 	char *vendor;
 	char *name;
 	unsigned char cmdbuf[8];
@@ -66,9 +55,12 @@
 	char phys[32];
 	unsigned long flags;
 
-	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); 
+	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
 	int (*reconnect)(struct psmouse *psmouse);
 	void (*disconnect)(struct psmouse *psmouse);
+
+	void (*pt_activate)(struct psmouse *psmouse);
+	void (*pt_deactivate)(struct psmouse *psmouse);
 };
 
 #define PSMOUSE_PS2		1
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:21 2004
+++ b/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:21 2004
@@ -212,14 +212,14 @@
 /*****************************************************************************
  *	Synaptics pass-through PS/2 port support
  ****************************************************************************/
-static int synaptics_pt_write(struct serio *port, unsigned char c)
+static int synaptics_pt_write(struct serio *serio, unsigned char c)
 {
-	struct psmouse_ptport *ptport = port->port_data;
+	struct psmouse *parent = serio->parent->private;
 	char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
 
-	if (psmouse_sliced_command(ptport->parent, c))
+	if (psmouse_sliced_command(parent, c))
 		return -1;
-	if (psmouse_command(ptport->parent, &rate_param, PSMOUSE_CMD_SETRATE))
+	if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
 		return -1;
 	return 0;
 }
@@ -248,7 +248,7 @@
 
 static void synaptics_pt_activate(struct psmouse *psmouse)
 {
-	struct psmouse *child = psmouse->ptport->serio->private;
+	struct psmouse *child = psmouse->serio->child->private;
 
 	/* adjust the touchpad to child's choice of protocol */
 	if (child && child->type >= PSMOUSE_GENPS) {
@@ -259,30 +259,25 @@
 
 static void synaptics_pt_create(struct psmouse *psmouse)
 {
-	struct psmouse_ptport *port;
 	struct serio *serio;
 
-	port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
 	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-	if (!port || !serio) {
+	if (!serio) {
 		printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
 		return;
 	}
 
-	memset(port, 0, sizeof(struct psmouse_ptport));
 	memset(serio, 0, sizeof(struct serio));
 
 	serio->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;
-	serio->port_data = port;
+	serio->parent = psmouse->serio;
 
-	port->serio = serio;
-	port->parent = psmouse;
-	port->activate = synaptics_pt_activate;
+	psmouse->pt_activate = synaptics_pt_activate;
 
-	psmouse->ptport = port;
+	psmouse->serio->child = serio;
 }
 
 /*****************************************************************************
@@ -477,8 +472,8 @@
 		if (unlikely(priv->pkt_type == SYN_NEWABS))
 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
-		if (psmouse->ptport && psmouse->ptport->serio->drv && synaptics_is_pt_packet(psmouse->packet))
-			synaptics_pass_pt_packet(psmouse->ptport->serio, psmouse->packet);
+		if (psmouse->serio->child && psmouse->serio->child->drv && synaptics_is_pt_packet(psmouse->packet))
+			synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet);
 		else
 			synaptics_process_packet(psmouse);
 
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:21 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:21 2004
@@ -44,10 +44,8 @@
 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);
 EXPORT_SYMBOL(serio_register_driver);
 EXPORT_SYMBOL(serio_unregister_driver);
 EXPORT_SYMBOL(serio_open);
@@ -59,17 +57,28 @@
 static LIST_HEAD(serio_list);
 static LIST_HEAD(serio_driver_list);
 
-/* serio_find_driver() must be called with serio_sem down.  */
+static void serio_find_driver(struct serio *serio);
+static void serio_create_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);
+
+static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
+{
+	drv->connect(serio, drv);
+
+	return serio->drv != NULL;
+}
 
+/* 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 (serio->drv)
+	list_for_each_entry(drv, &serio_driver_list, node)
+		if (serio_bind_driver(serio, drv))
 			break;
-		drv->connect(serio, drv);
-	}
 }
 
 /*
@@ -145,23 +154,22 @@
 
 		switch (event->type) {
 			case SERIO_REGISTER_PORT :
-				__serio_register_port(event->serio);
+				serio_create_port(event->serio);
+				serio_connect_port(event->serio, NULL);
 				break;
 
 			case SERIO_UNREGISTER_PORT :
-				__serio_unregister_port(event->serio);
+				serio_disconnect_port(event->serio);
+				serio_destroy_port(event->serio);
 				break;
 
 			case SERIO_RECONNECT :
-				if (event->serio->drv && event->serio->drv->reconnect)
-					if (event->serio->drv->reconnect(event->serio) == 0)
-						break;
-				/* reconnect failed - fall through to rescan */
+				serio_reconnect_port(event->serio);
+				break;
 
 			case SERIO_RESCAN :
-				if (event->serio->drv)
-					event->serio->drv->disconnect(event->serio);
-				serio_find_driver(event->serio);
+				serio_disconnect_port(event->serio);
+				serio_connect_port(event->serio, NULL);
 				break;
 			default:
 				break;
@@ -216,6 +224,118 @@
  * Serio port operations
  */
 
+static void serio_create_port(struct serio *serio)
+{
+	spin_lock_init(&serio->lock);
+	list_add_tail(&serio->node, &serio_list);
+}
+
+/*
+ * serio_destroy_port() completes deregistration process and removes
+ * port from the system
+ */
+static void serio_destroy_port(struct serio *serio)
+{
+	struct serio_driver *drv = serio->drv;
+	unsigned long flags;
+
+	serio_remove_pending_events(serio);
+	list_del_init(&serio->node);
+
+	if (drv)
+		drv->disconnect(serio);
+
+	if (serio->parent) {
+		spin_lock_irqsave(&serio->parent->lock, flags);
+		serio->parent->child = NULL;
+		spin_unlock_irqrestore(&serio->parent->lock, flags);
+	}
+
+	kfree(serio);
+}
+
+/*
+ * 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
+		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);
+
+		/*
+		 * 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);
+	}
+}
+
+/*
+ *
+ */
+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);
+			/* Ok, old children are now gone, we are done */
+			break;
+		}
+		serio = serio->child;
+	} while (serio);
+}
+
+/*
+ * serio_disconnect_port() unbinds a port from its driver. As a side effect
+ * all child ports are unbound and destroyed.
+ */
+static void serio_disconnect_port(struct serio *serio)
+{
+	struct serio_driver *drv = serio->drv;
+	struct serio *s;
+
+	if (serio->child) {
+		/*
+		 * Children ports should be disconnected and destroyed
+		 * first, staring with the leaf one, since we don't want
+		 * to do recursion
+		 */
+		do {
+			s = serio->child;
+		} while (s->child);
+
+		while (s != serio) {
+			s = s->parent;
+			serio_destroy_port(s->child);
+		}
+	}
+
+	/*
+	 * Ok, no children left, now disconnect this port
+	 */
+	if (drv)
+		drv->disconnect(serio);
+}
+
 void serio_rescan(struct serio *serio)
 {
 	serio_queue_event(serio, SERIO_RESCAN);
@@ -229,7 +349,8 @@
 void serio_register_port(struct serio *serio)
 {
 	down(&serio_sem);
-	__serio_register_port(serio);
+	serio_create_port(serio);
+	serio_connect_port(serio, NULL);
 	up(&serio_sem);
 }
 
@@ -243,22 +364,11 @@
 	serio_queue_event(serio, SERIO_REGISTER_PORT);
 }
 
-/*
- * Should only be called directly if serio_sem has already been taken,
- * for example when unregistering a serio from other input device's
- * connect() function.
- */
-void __serio_register_port(struct serio *serio)
-{
-	spin_lock_init(&serio->lock);
-	list_add_tail(&serio->node, &serio_list);
-	serio_find_driver(serio);
-}
-
 void serio_unregister_port(struct serio *serio)
 {
 	down(&serio_sem);
-	__serio_unregister_port(serio);
+	serio_disconnect_port(serio);
+	serio_destroy_port(serio);
 	up(&serio_sem);
 }
 
@@ -272,32 +382,33 @@
 	serio_queue_event(serio, SERIO_UNREGISTER_PORT);
 }
 
-/*
- * Should only be called directly if serio_sem has already been taken,
- * for example when unregistering a serio from other input device's
- * disconnect() function.
- */
-void __serio_unregister_port(struct serio *serio)
-{
-	serio_remove_pending_events(serio);
-	list_del_init(&serio->node);
-	if (serio->drv)
-		serio->drv->disconnect(serio);
-	kfree(serio);
-}
 
 /*
  * Serio driver operations
  */
 
+
 void serio_register_driver(struct serio_driver *drv)
 {
 	struct serio *serio;
+
 	down(&serio_sem);
+
 	list_add_tail(&drv->node, &serio_driver_list);
-	list_for_each_entry(serio, &serio_list, node)
-		if (!serio->drv)
-			drv->connect(serio, drv);
+
+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;
+		}
+	}
+
 	up(&serio_sem);
 }
 
@@ -306,13 +417,19 @@
 	struct serio *serio;
 
 	down(&serio_sem);
+
 	list_del_init(&drv->node);
 
+start_over:
 	list_for_each_entry(serio, &serio_list, node) {
-		if (serio->drv == drv)
-			drv->disconnect(serio);
-		serio_find_driver(serio);
+		if (serio->drv == drv) {
+			serio_disconnect_port(serio);
+			serio_connect_port(serio, NULL);
+			/* we could've deleted some ports, restart */
+			goto start_over;
+		}
 	}
+
 	up(&serio_sem);
 }
 
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:21 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:21 2004
@@ -40,6 +40,8 @@
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
 
+	struct serio *parent, *child;
+
 	struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */
 
 	struct list_head node;
@@ -68,10 +70,8 @@
 
 void serio_register_port(struct serio *serio);
 void serio_register_port_delayed(struct serio *serio);
-void __serio_register_port(struct serio *serio);
 void serio_unregister_port(struct serio *serio);
 void serio_unregister_port_delayed(struct serio *serio);
-void __serio_unregister_port(struct serio *serio);
 void serio_register_driver(struct serio_driver *drv);
 void serio_unregister_driver(struct serio_driver *drv);
 


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

* [PATCH 41/47] link (some) serio ports to their parent devices
  2004-07-29 14:09                                                                               ` [PATCH 40/47] Add serio_raw driver Vojtech Pavlik
@ 2004-07-29 14:09                                                                                 ` Vojtech Pavlik
  2004-07-29 14:09                                                                                   ` [PATCH 42/47] Fix Kconfig so that the joydump module can be compiled Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.36, 2004-06-29 01:36:29-05:00, dtor_core@ameritech.net
  Input: link serio ports to their parent devices in ambakmi,
         gscps2, pcips2 and sa1111ps2 drivers
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 ambakmi.c   |    1 +
 gscps2.c    |    1 +
 pcips2.c    |    1 +
 sa1111ps2.c |    1 +
 4 files changed, 4 insertions(+)

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

diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	Thu Jul 29 14:38:57 2004
+++ b/drivers/input/serio/ambakmi.c	Thu Jul 29 14:38:57 2004
@@ -141,6 +141,7 @@
 	strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
 	strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
 	io->port_data	= kmi;
+	io->dev.parent	= &dev->dev;
 
 	kmi->io 	= io;
 	kmi->base	= ioremap(dev->res.start, KMI_SIZE);
diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
--- a/drivers/input/serio/gscps2.c	Thu Jul 29 14:38:57 2004
+++ b/drivers/input/serio/gscps2.c	Thu Jul 29 14:38:57 2004
@@ -385,6 +385,7 @@
 	serio->open		= gscps2_open;
 	serio->close		= gscps2_close;
 	serio->port_data	= ps2port;
+	serio->dev.parent	= &dev->dev;
 
 	list_add_tail(&ps2port->node, &ps2port_list);
 
diff -Nru a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
--- a/drivers/input/serio/pcips2.c	Thu Jul 29 14:38:57 2004
+++ b/drivers/input/serio/pcips2.c	Thu Jul 29 14:38:57 2004
@@ -159,6 +159,7 @@
 	strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
 	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
 	serio->port_data	= ps2if;
+	serio->dev.parent	= &dev->dev;
 	ps2if->io		= serio;
 	ps2if->dev		= dev;
 	ps2if->base		= pci_resource_start(dev, 0);
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:38:57 2004
+++ b/drivers/input/serio/sa1111ps2.c	Thu Jul 29 14:38:57 2004
@@ -252,6 +252,7 @@
 	strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
 	strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
 	serio->port_data	= ps2if;
+	serio->dev.parent	= &dev->dev;
 	ps2if->io		= serio;
 	ps2if->dev		= dev;
 	sa1111_set_drvdata(dev, ps2if);


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

* [PATCH 34/47] more renames in serio in preparation for sysfs integration
  2004-07-29 14:09                                                                 ` [PATCH 33/47] rename serio->driver to serio->port_data Vojtech Pavlik
@ 2004-07-29 14:09                                                                   ` Vojtech Pavlik
  2004-07-29 14:09                                                                     ` [PATCH 35/47] switch to dynamic (heap) serio port allocation Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.29, 2004-06-29 01:27:11-05:00, dtor_core@ameritech.net
  Input: more renames in serio in preparations to sysfs integration
         - serio_dev -> serio_driver
         - serio_[un]register_device -> serio_[un]register_driver
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 drivers/input/joystick/iforce/iforce-main.c  |    4 -
 drivers/input/joystick/iforce/iforce-serio.c |    6 +-
 drivers/input/joystick/iforce/iforce.h       |    2 
 drivers/input/joystick/magellan.c            |   10 +--
 drivers/input/joystick/spaceball.c           |   10 +--
 drivers/input/joystick/spaceorb.c            |   10 +--
 drivers/input/joystick/stinger.c             |   10 +--
 drivers/input/joystick/twidjoy.c             |   10 +--
 drivers/input/joystick/warrior.c             |   10 +--
 drivers/input/keyboard/atkbd.c               |   14 ++---
 drivers/input/keyboard/lkkbd.c               |   10 +--
 drivers/input/keyboard/newtonkbd.c           |   10 +--
 drivers/input/keyboard/sunkbd.c              |   10 +--
 drivers/input/keyboard/xtkbd.c               |   10 +--
 drivers/input/mouse/psmouse-base.c           |   14 ++---
 drivers/input/mouse/sermouse.c               |   10 +--
 drivers/input/mouse/synaptics.c              |    2 
 drivers/input/mouse/vsxxxaa.c                |   10 +--
 drivers/input/serio/serio.c                  |   72 +++++++++++++--------------
 drivers/input/serio/serport.c                |    2 
 drivers/input/touchscreen/gunze.c            |   10 +--
 drivers/input/touchscreen/h3600_ts_input.c   |   10 +--
 include/linux/serio.h                        |   22 ++++----
 23 files changed, 139 insertions(+), 139 deletions(-)

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

diff -Nru a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
--- a/drivers/input/joystick/iforce/iforce-main.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/iforce/iforce-main.c	Thu Jul 29 14:39:31 2004
@@ -524,7 +524,7 @@
 	usb_register(&iforce_usb_driver);
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
-	serio_register_device(&iforce_serio_dev);
+	serio_register_driver(&iforce_serio_drv);
 #endif
 	return 0;
 }
@@ -535,7 +535,7 @@
 	usb_deregister(&iforce_usb_driver);
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
-	serio_unregister_device(&iforce_serio_dev);
+	serio_unregister_driver(&iforce_serio_drv);
 #endif
 }
 
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	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/iforce/iforce-serio.c	Thu Jul 29 14:39:31 2004
@@ -124,7 +124,7 @@
 	return IRQ_HANDLED;
 }
 
-static void iforce_serio_connect(struct serio *serio, struct serio_dev *dev)
+static void iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct iforce *iforce;
 	if (serio->type != (SERIO_RS232 | SERIO_IFORCE))
@@ -137,7 +137,7 @@
 	iforce->serio = serio;
 	serio->private = iforce;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(iforce);
 		return;
 	}
@@ -158,7 +158,7 @@
 	kfree(iforce);
 }
 
-struct serio_dev iforce_serio_dev = {
+struct serio_driver iforce_serio_drv = {
 	.write_wakeup =	iforce_serio_write_wakeup,
 	.interrupt =	iforce_serio_irq,
 	.connect =	iforce_serio_connect,
diff -Nru a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
--- a/drivers/input/joystick/iforce/iforce.h	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/iforce/iforce.h	Thu Jul 29 14:39:31 2004
@@ -187,5 +187,5 @@
 int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update);
 
 /* Public variables */
-extern struct serio_dev iforce_serio_dev;
+extern struct serio_driver iforce_serio_drv;
 extern struct usb_driver iforce_usb_driver;
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/magellan.c	Thu Jul 29 14:39:31 2004
@@ -146,7 +146,7 @@
  * it as an input device.
  */
 
-static void magellan_connect(struct serio *serio, struct serio_dev *dev)
+static void magellan_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct magellan *magellan;
 	int i, t;
@@ -184,7 +184,7 @@
 
 	serio->private = magellan;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(magellan);
 		return;
 	}
@@ -199,7 +199,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev magellan_dev = {
+static struct serio_driver magellan_drv = {
 	.interrupt =	magellan_interrupt,
 	.connect =	magellan_connect,
 	.disconnect =	magellan_disconnect,
@@ -211,13 +211,13 @@
 
 int __init magellan_init(void)
 {
-	serio_register_device(&magellan_dev);
+	serio_register_driver(&magellan_drv);
 	return 0;
 }
 
 void __exit magellan_exit(void)
 {
-	serio_unregister_device(&magellan_dev);
+	serio_unregister_driver(&magellan_drv);
 }
 
 module_init(magellan_init);
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/spaceball.c	Thu Jul 29 14:39:31 2004
@@ -201,7 +201,7 @@
  * it as an input device.
  */
 
-static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
+static void spaceball_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct spaceball *spaceball;
 	int i, t, id;
@@ -254,7 +254,7 @@
 
 	serio->private = spaceball;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(spaceball);
 		return;
 	}
@@ -269,7 +269,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev spaceball_dev = {
+static struct serio_driver spaceball_drv = {
 	.interrupt =	spaceball_interrupt,
 	.connect =	spaceball_connect,
 	.disconnect =	spaceball_disconnect,
@@ -281,13 +281,13 @@
 
 int __init spaceball_init(void)
 {
-	serio_register_device(&spaceball_dev);
+	serio_register_driver(&spaceball_drv);
 	return 0;
 }
 
 void __exit spaceball_exit(void)
 {
-	serio_unregister_device(&spaceball_dev);
+	serio_unregister_driver(&spaceball_drv);
 }
 
 module_init(spaceball_init);
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/spaceorb.c	Thu Jul 29 14:39:31 2004
@@ -162,7 +162,7 @@
  * it as an input device.
  */
 
-static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
+static void spaceorb_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct spaceorb *spaceorb;
 	int i, t;
@@ -201,7 +201,7 @@
 
 	serio->private = spaceorb;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(spaceorb);
 		return;
 	}
@@ -213,7 +213,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev spaceorb_dev = {
+static struct serio_driver spaceorb_drv = {
 	.interrupt =	spaceorb_interrupt,
 	.connect =	spaceorb_connect,
 	.disconnect =	spaceorb_disconnect,
@@ -225,13 +225,13 @@
 
 int __init spaceorb_init(void)
 {
-	serio_register_device(&spaceorb_dev);
+	serio_register_driver(&spaceorb_drv);
 	return 0;
 }
 
 void __exit spaceorb_exit(void)
 {
-	serio_unregister_device(&spaceorb_dev);
+	serio_unregister_driver(&spaceorb_drv);
 }
 
 module_init(spaceorb_init);
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/stinger.c	Thu Jul 29 14:39:31 2004
@@ -134,7 +134,7 @@
  * it as an input device.
  */
 
-static void stinger_connect(struct serio *serio, struct serio_dev *dev)
+static void stinger_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct stinger *stinger;
 	int i;
@@ -172,7 +172,7 @@
 	stinger->dev.private = stinger;
 	serio->private = stinger;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(stinger);
 		return;
 	}
@@ -187,7 +187,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev stinger_dev = {
+static struct serio_driver stinger_drv = {
 	.interrupt =	stinger_interrupt,
 	.connect =	stinger_connect,
 	.disconnect =	stinger_disconnect,
@@ -199,13 +199,13 @@
 
 int __init stinger_init(void)
 {
-	serio_register_device(&stinger_dev);
+	serio_register_driver(&stinger_drv);
 	return 0;
 }
 
 void __exit stinger_exit(void)
 {
-	serio_unregister_device(&stinger_dev);
+	serio_unregister_driver(&stinger_drv);
 }
 
 module_init(stinger_init);
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/twidjoy.c	Thu Jul 29 14:39:31 2004
@@ -187,7 +187,7 @@
  * it as an input device.
  */
 
-static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
+static void twidjoy_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct twidjoy_button_spec *bp;
 	struct twidjoy *twidjoy;
@@ -232,7 +232,7 @@
 	twidjoy->dev.private = twidjoy;
 	serio->private = twidjoy;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(twidjoy);
 		return;
 	}
@@ -246,7 +246,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev twidjoy_dev = {
+static struct serio_driver twidjoy_drv = {
 	.interrupt =	twidjoy_interrupt,
 	.connect =	twidjoy_connect,
 	.disconnect =	twidjoy_disconnect,
@@ -258,13 +258,13 @@
 
 int __init twidjoy_init(void)
 {
-	serio_register_device(&twidjoy_dev);
+	serio_register_driver(&twidjoy_drv);
 	return 0;
 }
 
 void __exit twidjoy_exit(void)
 {
-	serio_unregister_device(&twidjoy_dev);
+	serio_unregister_driver(&twidjoy_drv);
 }
 
 module_init(twidjoy_init);
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/joystick/warrior.c	Thu Jul 29 14:39:31 2004
@@ -139,7 +139,7 @@
  * it as an input device.
  */
 
-static void warrior_connect(struct serio *serio, struct serio_dev *dev)
+static void warrior_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct warrior *warrior;
 	int i;
@@ -185,7 +185,7 @@
 
 	serio->private = warrior;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(warrior);
 		return;
 	}
@@ -199,7 +199,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev warrior_dev = {
+static struct serio_driver warrior_drv = {
 	.interrupt =	warrior_interrupt,
 	.connect =	warrior_connect,
 	.disconnect =	warrior_disconnect,
@@ -211,13 +211,13 @@
 
 int __init warrior_init(void)
 {
-	serio_register_device(&warrior_dev);
+	serio_register_driver(&warrior_drv);
 	return 0;
 }
 
 void __exit warrior_exit(void)
 {
-	serio_unregister_device(&warrior_dev);
+	serio_unregister_driver(&warrior_drv);
 }
 
 module_init(warrior_init);
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/keyboard/atkbd.c	Thu Jul 29 14:39:31 2004
@@ -732,7 +732,7 @@
  * to the input module.
  */
 
-static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
+static void atkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct atkbd *atkbd;
 	int i;
@@ -785,7 +785,7 @@
 
 	serio->private = atkbd;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(atkbd);
 		return;
 	}
@@ -861,10 +861,10 @@
 static int atkbd_reconnect(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
-	struct serio_dev *dev = serio->dev;
+	struct serio_driver *drv = serio->drv;
 	unsigned char param[1];
 
-	if (!dev) {
+	if (!drv) {
 		printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
@@ -890,7 +890,7 @@
 	return 0;
 }
 
-static struct serio_dev atkbd_dev = {
+static struct serio_driver atkbd_drv = {
 	.interrupt =	atkbd_interrupt,
 	.connect =	atkbd_connect,
 	.reconnect = 	atkbd_reconnect,
@@ -900,13 +900,13 @@
 
 int __init atkbd_init(void)
 {
-	serio_register_device(&atkbd_dev);
+	serio_register_driver(&atkbd_drv);
 	return 0;
 }
 
 void __exit atkbd_exit(void)
 {
-	serio_unregister_device(&atkbd_dev);
+	serio_unregister_driver(&atkbd_drv);
 }
 
 module_init(atkbd_init);
diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/keyboard/lkkbd.c	Thu Jul 29 14:39:31 2004
@@ -622,7 +622,7 @@
  * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
  */
 static void
-lkkbd_connect (struct serio *serio, struct serio_dev *dev)
+lkkbd_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct lkkbd *lk;
 	int i;
@@ -665,7 +665,7 @@
 
 	serio->private = lk;
 
-	if (serio_open (serio, dev)) {
+	if (serio_open (serio, drv)) {
 		kfree (lk);
 		return;
 	}
@@ -703,7 +703,7 @@
 	kfree (lk);
 }
 
-static struct serio_dev lkkbd_dev = {
+static struct serio_driver lkkbd_drv = {
 	.connect = lkkbd_connect,
 	.disconnect = lkkbd_disconnect,
 	.interrupt = lkkbd_interrupt,
@@ -715,14 +715,14 @@
 int __init
 lkkbd_init (void)
 {
-	serio_register_device (&lkkbd_dev);
+	serio_register_driver(&lkkbd_drv);
 	return 0;
 }
 
 void __exit
 lkkbd_exit (void)
 {
-	serio_unregister_device (&lkkbd_dev);
+	serio_unregister_driver(&lkkbd_drv);
 }
 
 module_init (lkkbd_init);
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/keyboard/newtonkbd.c	Thu Jul 29 14:39:31 2004
@@ -82,7 +82,7 @@
 
 }
 
-void nkbd_connect(struct serio *serio, struct serio_dev *dev)
+void nkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct nkbd *nkbd;
 	int i;
@@ -106,7 +106,7 @@
 	nkbd->dev.private = nkbd;
 	serio->private = nkbd;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(nkbd);
 		return;
 	}
@@ -138,7 +138,7 @@
 	kfree(nkbd);
 }
 
-struct serio_dev nkbd_dev = {
+struct serio_driver nkbd_drv = {
 	.interrupt =	nkbd_interrupt,
 	.connect =	nkbd_connect,
 	.disconnect =	nkbd_disconnect
@@ -146,13 +146,13 @@
 
 int __init nkbd_init(void)
 {
-	serio_register_device(&nkbd_dev);
+	serio_register_driver(&nkbd_drv);
 	return 0;
 }
 
 void __exit nkbd_exit(void)
 {
-	serio_unregister_device(&nkbd_dev);
+	serio_unregister_driver(&nkbd_drv);
 }
 
 module_init(nkbd_init);
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/keyboard/sunkbd.c	Thu Jul 29 14:39:31 2004
@@ -221,7 +221,7 @@
  * sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
  */
 
-static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
+static void sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sunkbd *sunkbd;
 	int i;
@@ -257,7 +257,7 @@
 
 	serio->private = sunkbd;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(sunkbd);
 		return;
 	}
@@ -301,7 +301,7 @@
 	kfree(sunkbd);
 }
 
-static struct serio_dev sunkbd_dev = {
+static struct serio_driver sunkbd_drv = {
 	.interrupt =	sunkbd_interrupt,
 	.connect =	sunkbd_connect,
 	.disconnect =	sunkbd_disconnect
@@ -313,13 +313,13 @@
 
 int __init sunkbd_init(void)
 {
-	serio_register_device(&sunkbd_dev);
+	serio_register_driver(&sunkbd_drv);
 	return 0;
 }
 
 void __exit sunkbd_exit(void)
 {
-	serio_unregister_device(&sunkbd_dev);
+	serio_unregister_driver(&sunkbd_drv);
 }
 
 module_init(sunkbd_init);
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/keyboard/xtkbd.c	Thu Jul 29 14:39:31 2004
@@ -86,7 +86,7 @@
 	return IRQ_HANDLED;
 }
 
-void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
+void xtkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct xtkbd *xtkbd;
 	int i;
@@ -111,7 +111,7 @@
 
 	serio->private = xtkbd;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(xtkbd);
 		return;
 	}
@@ -143,7 +143,7 @@
 	kfree(xtkbd);
 }
 
-struct serio_dev xtkbd_dev = {
+struct serio_driver xtkbd_drv = {
 	.interrupt =	xtkbd_interrupt,
 	.connect =	xtkbd_connect,
 	.disconnect =	xtkbd_disconnect
@@ -151,13 +151,13 @@
 
 int __init xtkbd_init(void)
 {
-	serio_register_device(&xtkbd_dev);
+	serio_register_driver(&xtkbd_drv);
 	return 0;
 }
 
 void __exit xtkbd_exit(void)
 {
-	serio_unregister_device(&xtkbd_dev);
+	serio_unregister_driver(&xtkbd_drv);
 }
 
 module_init(xtkbd_init);
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/mouse/psmouse-base.c	Thu Jul 29 14:39:31 2004
@@ -678,7 +678,7 @@
  * 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_dev *dev)
+static void psmouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct psmouse *psmouse;
 
@@ -700,7 +700,7 @@
 	psmouse->dev.private = psmouse;
 
 	serio->private = psmouse;
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(psmouse);
 		serio->private = NULL;
 		return;
@@ -753,9 +753,9 @@
 static int psmouse_reconnect(struct serio *serio)
 {
 	struct psmouse *psmouse = serio->private;
-	struct serio_dev *dev = serio->dev;
+	struct serio_driver *drv = serio->drv;
 
-	if (!dev || !psmouse) {
+	if (!drv || !psmouse) {
 		printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
 		return -1;
 	}
@@ -793,7 +793,7 @@
 }
 
 
-static struct serio_dev psmouse_dev = {
+static struct serio_driver psmouse_drv = {
 	.interrupt =	psmouse_interrupt,
 	.connect =	psmouse_connect,
 	.reconnect =	psmouse_reconnect,
@@ -818,13 +818,13 @@
 int __init psmouse_init(void)
 {
 	psmouse_parse_proto();
-	serio_register_device(&psmouse_dev);
+	serio_register_driver(&psmouse_drv);
 	return 0;
 }
 
 void __exit psmouse_exit(void)
 {
-	serio_unregister_device(&psmouse_dev);
+	serio_unregister_driver(&psmouse_drv);
 }
 
 module_init(psmouse_init);
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/mouse/sermouse.c	Thu Jul 29 14:39:31 2004
@@ -237,7 +237,7 @@
  * an unhandled serio port is found.
  */
 
-static void sermouse_connect(struct serio *serio, struct serio_dev *dev)
+static void sermouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sermouse *sermouse;
 	unsigned char c;
@@ -279,7 +279,7 @@
 	sermouse->dev.id.product = c;
 	sermouse->dev.id.version = 0x0100;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(sermouse);
 		return;
 	}
@@ -289,7 +289,7 @@
 	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
 }
 
-static struct serio_dev sermouse_dev = {
+static struct serio_driver sermouse_drv = {
 	.interrupt =	sermouse_interrupt,
 	.connect =	sermouse_connect,
 	.disconnect =	sermouse_disconnect
@@ -297,13 +297,13 @@
 
 int __init sermouse_init(void)
 {
-	serio_register_device(&sermouse_dev);
+	serio_register_driver(&sermouse_drv);
 	return 0;
 }
 
 void __exit sermouse_exit(void)
 {
-	serio_unregister_device(&sermouse_dev);
+	serio_unregister_driver(&sermouse_drv);
 }
 
 module_init(sermouse_init);
diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/mouse/synaptics.c	Thu Jul 29 14:39:31 2004
@@ -470,7 +470,7 @@
 		if (unlikely(priv->pkt_type == SYN_NEWABS))
 			priv->pkt_type = synaptics_detect_pkt_type(psmouse);
 
-		if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
+		if (psmouse->ptport && psmouse->ptport->serio.drv && synaptics_is_pt_packet(psmouse->packet))
 			synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
 		else
 			synaptics_process_packet(psmouse);
diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/mouse/vsxxxaa.c	Thu Jul 29 14:39:31 2004
@@ -482,7 +482,7 @@
 }
 
 static void
-vsxxxaa_connect (struct serio *serio, struct serio_dev *dev)
+vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct vsxxxaa *mouse;
 
@@ -524,7 +524,7 @@
 	mouse->dev.id.bustype = BUS_RS232;
 	mouse->serio = serio;
 
-	if (serio_open (serio, dev)) {
+	if (serio_open (serio, drv)) {
 		kfree (mouse);
 		return;
 	}
@@ -540,7 +540,7 @@
 	printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
 }
 
-static struct serio_dev vsxxxaa_dev = {
+static struct serio_driver vsxxxaa_drv = {
 	.connect = vsxxxaa_connect,
 	.interrupt = vsxxxaa_interrupt,
 	.disconnect = vsxxxaa_disconnect,
@@ -549,14 +549,14 @@
 int __init
 vsxxxaa_init (void)
 {
-	serio_register_device (&vsxxxaa_dev);
+	serio_register_driver(&vsxxxaa_drv);
 	return 0;
 }
 
 void __exit
 vsxxxaa_exit (void)
 {
-	serio_unregister_device (&vsxxxaa_dev);
+	serio_unregister_driver(&vsxxxaa_drv);
 }
 
 module_init (vsxxxaa_init);
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:31 2004
@@ -48,27 +48,27 @@
 EXPORT_SYMBOL(serio_unregister_port);
 EXPORT_SYMBOL(serio_unregister_port_delayed);
 EXPORT_SYMBOL(__serio_unregister_port);
-EXPORT_SYMBOL(serio_register_device);
-EXPORT_SYMBOL(serio_unregister_device);
+EXPORT_SYMBOL(serio_register_driver);
+EXPORT_SYMBOL(serio_unregister_driver);
 EXPORT_SYMBOL(serio_open);
 EXPORT_SYMBOL(serio_close);
 EXPORT_SYMBOL(serio_rescan);
 EXPORT_SYMBOL(serio_reconnect);
 
-static DECLARE_MUTEX(serio_sem);				/* protects serio_list and serio_dev_list */
+static DECLARE_MUTEX(serio_sem);	/* protects serio_list and serio_diriver_list */
 static LIST_HEAD(serio_list);
-static LIST_HEAD(serio_dev_list);
+static LIST_HEAD(serio_driver_list);
 
-/* serio_find_dev() must be called with serio_sem down.  */
+/* serio_find_driver() must be called with serio_sem down.  */
 
-static void serio_find_dev(struct serio *serio)
+static void serio_find_driver(struct serio *serio)
 {
-	struct serio_dev *dev;
+	struct serio_driver *drv;
 
-	list_for_each_entry(dev, &serio_dev_list, node) {
-		if (serio->dev)
+	list_for_each_entry(drv, &serio_driver_list, node) {
+		if (serio->drv)
 			break;
-		dev->connect(serio, dev);
+		drv->connect(serio, drv);
 	}
 }
 
@@ -153,15 +153,15 @@
 				break;
 
 			case SERIO_RECONNECT :
-				if (event->serio->dev && event->serio->dev->reconnect)
-					if (event->serio->dev->reconnect(event->serio) == 0)
+				if (event->serio->drv && event->serio->drv->reconnect)
+					if (event->serio->drv->reconnect(event->serio) == 0)
 						break;
 				/* reconnect failed - fall through to rescan */
 
 			case SERIO_RESCAN :
-				if (event->serio->dev)
-					event->serio->dev->disconnect(event->serio);
-				serio_find_dev(event->serio);
+				if (event->serio->drv)
+					event->serio->drv->disconnect(event->serio);
+				serio_find_driver(event->serio);
 				break;
 			default:
 				break;
@@ -252,7 +252,7 @@
 {
 	spin_lock_init(&serio->lock);
 	list_add_tail(&serio->node, &serio_list);
-	serio_find_dev(serio);
+	serio_find_driver(serio);
 }
 
 void serio_unregister_port(struct serio *serio)
@@ -281,58 +281,58 @@
 {
 	serio_remove_pending_events(serio);
 	list_del_init(&serio->node);
-	if (serio->dev)
-		serio->dev->disconnect(serio);
+	if (serio->drv)
+		serio->drv->disconnect(serio);
 }
 
 /*
- * Serio device operations
+ * Serio driver operations
  */
 
-void serio_register_device(struct serio_dev *dev)
+void serio_register_driver(struct serio_driver *drv)
 {
 	struct serio *serio;
 	down(&serio_sem);
-	list_add_tail(&dev->node, &serio_dev_list);
+	list_add_tail(&drv->node, &serio_driver_list);
 	list_for_each_entry(serio, &serio_list, node)
-		if (!serio->dev)
-			dev->connect(serio, dev);
+		if (!serio->drv)
+			drv->connect(serio, drv);
 	up(&serio_sem);
 }
 
-void serio_unregister_device(struct serio_dev *dev)
+void serio_unregister_driver(struct serio_driver *drv)
 {
 	struct serio *serio;
 
 	down(&serio_sem);
-	list_del_init(&dev->node);
+	list_del_init(&drv->node);
 
 	list_for_each_entry(serio, &serio_list, node) {
-		if (serio->dev == dev)
-			dev->disconnect(serio);
-		serio_find_dev(serio);
+		if (serio->drv == drv)
+			drv->disconnect(serio);
+		serio_find_driver(serio);
 	}
 	up(&serio_sem);
 }
 
-/* called from serio_dev->connect/disconnect methods under serio_sem */
-int serio_open(struct serio *serio, struct serio_dev *dev)
+/* called from serio_driver->connect/disconnect methods under serio_sem */
+int serio_open(struct serio *serio, struct serio_driver *drv)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&serio->lock, flags);
-	serio->dev = dev;
+	serio->drv = drv;
 	spin_unlock_irqrestore(&serio->lock, flags);
 	if (serio->open && serio->open(serio)) {
 		spin_lock_irqsave(&serio->lock, flags);
-		serio->dev = NULL;
+		serio->drv = NULL;
 		spin_unlock_irqrestore(&serio->lock, flags);
 		return -1;
 	}
 	return 0;
 }
 
-/* called from serio_dev->connect/disconnect methods under serio_sem */
+/* called from serio_driver->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
 	unsigned long flags;
@@ -340,7 +340,7 @@
 	if (serio->close)
 		serio->close(serio);
 	spin_lock_irqsave(&serio->lock, flags);
-	serio->dev = NULL;
+	serio->drv = NULL;
 	spin_unlock_irqrestore(&serio->lock, flags);
 }
 
@@ -352,8 +352,8 @@
 
 	spin_lock_irqsave(&serio->lock, flags);
 
-        if (likely(serio->dev)) {
-                ret = serio->dev->interrupt(serio, data, dfl, regs);
+        if (likely(serio->drv)) {
+                ret = serio->drv->interrupt(serio, data, dfl, regs);
 	} else {
 		if (!dfl) {
 			if ((serio->type != SERIO_8042 &&
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/serio/serport.c	Thu Jul 29 14:39:31 2004
@@ -170,7 +170,7 @@
 {
 	struct serport *sp = (struct serport *) tty->disc_data;
 
-	serio_dev_write_wakeup(&sp->serio);
+	serio_drv_write_wakeup(&sp->serio);
 }
 
 /*
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/touchscreen/gunze.c	Thu Jul 29 14:39:31 2004
@@ -111,7 +111,7 @@
  * and if yes, registers it as an input device.
  */
 
-static void gunze_connect(struct serio *serio, struct serio_dev *dev)
+static void gunze_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct gunze *gunze;
 
@@ -142,7 +142,7 @@
 	gunze->dev.id.product = 0x0051;
 	gunze->dev.id.version = 0x0100;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
 		kfree(gunze);
 		return;
 	}
@@ -156,7 +156,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev gunze_dev = {
+static struct serio_driver gunze_drv = {
 	.interrupt =	gunze_interrupt,
 	.connect =	gunze_connect,
 	.disconnect =	gunze_disconnect,
@@ -168,13 +168,13 @@
 
 int __init gunze_init(void)
 {
-	serio_register_device(&gunze_dev);
+	serio_register_driver(&gunze_drv);
 	return 0;
 }
 
 void __exit gunze_exit(void)
 {
-	serio_unregister_device(&gunze_dev);
+	serio_unregister_driver(&gunze_drv);
 }
 
 module_init(gunze_init);
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	Thu Jul 29 14:39:31 2004
+++ b/drivers/input/touchscreen/h3600_ts_input.c	Thu Jul 29 14:39:31 2004
@@ -373,7 +373,7 @@
  * new serio device. It looks whether it was registered as a H3600 touchscreen
  * and if yes, registers it as an input device.
  */
-static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
+static void h3600ts_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct h3600_dev *ts;
 
@@ -441,7 +441,7 @@
 	ts->dev.id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
 	ts->dev.id.version = 0x0100;
 
-	if (serio_open(serio, dev)) {
+	if (serio_open(serio, drv)) {
         	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
         	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
 		kfree(ts);
@@ -478,7 +478,7 @@
  * The serio device structure.
  */
 
-static struct serio_dev h3600ts_dev = {
+static struct serio_driver h3600ts_drv = {
 	.interrupt =	h3600ts_interrupt,
 	.connect =	h3600ts_connect,
 	.disconnect =	h3600ts_disconnect,
@@ -490,13 +490,13 @@
 
 static int __init h3600ts_init(void)
 {
-	serio_register_device(&h3600ts_dev);
+	serio_register_driver(&h3600ts_drv);
 	return 0;
 }
 
 static void __exit h3600ts_exit(void)
 {
-	serio_unregister_device(&h3600ts_dev);
+	serio_unregister_driver(&h3600ts_drv);
 }
 
 module_init(h3600ts_init);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Thu Jul 29 14:39:31 2004
+++ b/include/linux/serio.h	Thu Jul 29 14:39:31 2004
@@ -39,19 +39,19 @@
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
 
-	struct serio_dev *dev; /* Accessed from interrupt, writes must be protected by serio_lock */
+	struct serio_driver *drv; /* Accessed from interrupt, writes must be protected by serio_lock */
 
 	struct list_head node;
 };
 
-struct serio_dev {
+struct serio_driver {
 	void *private;
 	char *name;
 
 	void (*write_wakeup)(struct serio *);
 	irqreturn_t (*interrupt)(struct serio *, unsigned char,
 			unsigned int, struct pt_regs *);
-	void (*connect)(struct serio *, struct serio_dev *dev);
+	void (*connect)(struct serio *, struct serio_driver *drv);
 	int  (*reconnect)(struct serio *);
 	void (*disconnect)(struct serio *);
 	void (*cleanup)(struct serio *);
@@ -59,7 +59,7 @@
 	struct list_head node;
 };
 
-int serio_open(struct serio *serio, struct serio_dev *dev);
+int serio_open(struct serio *serio, struct serio_driver *drv);
 void serio_close(struct serio *serio);
 void serio_rescan(struct serio *serio);
 void serio_reconnect(struct serio *serio);
@@ -71,8 +71,8 @@
 void serio_unregister_port(struct serio *serio);
 void serio_unregister_port_delayed(struct serio *serio);
 void __serio_unregister_port(struct serio *serio);
-void serio_register_device(struct serio_dev *dev);
-void serio_unregister_device(struct serio_dev *dev);
+void serio_register_driver(struct serio_driver *drv);
+void serio_unregister_driver(struct serio_driver *drv);
 
 static __inline__ int serio_write(struct serio *serio, unsigned char data)
 {
@@ -82,16 +82,16 @@
 		return -1;
 }
 
-static __inline__ void serio_dev_write_wakeup(struct serio *serio)
+static __inline__ void serio_drv_write_wakeup(struct serio *serio)
 {
-	if (serio->dev && serio->dev->write_wakeup)
-		serio->dev->write_wakeup(serio);
+	if (serio->drv && serio->drv->write_wakeup)
+		serio->drv->write_wakeup(serio);
 }
 
 static __inline__ void serio_cleanup(struct serio *serio)
 {
-	if (serio->dev && serio->dev->cleanup)
-		serio->dev->cleanup(serio);
+	if (serio->drv && serio->drv->cleanup)
+		serio->drv->cleanup(serio);
 }
 
 #endif


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

* [PATCH 38/47] allow users to manually rebind serio ports
  2004-07-29 14:09                                                                         ` [PATCH 37/47] serio sysfs integration Vojtech Pavlik
@ 2004-07-29 14:09                                                                           ` Vojtech Pavlik
  2004-07-29 14:09                                                                             ` [PATCH 39/47] allow marking some drivers as manual bind only Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 14:09 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1757.15.33, 2004-06-29 01:29:39-05:00, dtor_core@ameritech.net
  Input: allow users manually rebind serio ports, like this:
         echo -n "psmouse" > /sys/bus/serio/devices/serio0/driver
         echo -n "atkbd" > /sys/bus/serio/devices/serio1/driver
         echo -n "none" > /sys/bus/serio/devices/serio1/driver
         echo -n "reconnect" > /sys/bus/serio/devices/serio1/driver
         echo -n "rescan" > /sys/bus/serio/devices/serio1/driver
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 serio.c |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletion(-)

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

diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Thu Jul 29 14:39:12 2004
+++ b/drivers/input/serio/serio.c	Thu Jul 29 14:39:12 2004
@@ -250,7 +250,39 @@
 {
 	return sprintf(buf, "%s\n", dev->driver ? dev->driver->name : "(none)");
 }
-static DEVICE_ATTR(driver, S_IRUGO, serio_show_driver, NULL);
+
+static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
+{
+	struct serio *serio = to_serio_port(dev);
+	struct device_driver *drv;
+	struct kobject *k;
+	int retval;
+
+	retval = down_interruptible(&serio_sem);
+	if (retval)
+		return retval;
+
+	retval = count;
+	if (!strncmp(buf, "none", count)) {
+		serio_disconnect_port(serio);
+	} else if (!strncmp(buf, "reconnect", count)) {
+		serio_reconnect_port(serio);
+	} else if (!strncmp(buf, "rescan", count)) {
+		serio_disconnect_port(serio);
+		serio_connect_port(serio, NULL);
+	} else if ((k = kset_find_obj(&serio_bus.drivers, buf)) != NULL) {
+		drv = container_of(k, struct device_driver, kobj);
+		serio_disconnect_port(serio);
+		serio_connect_port(serio, to_serio_driver(drv));
+	} else {
+		retval = -EINVAL;
+	}
+
+	up(&serio_sem);
+
+	return retval;
+}
+static DEVICE_ATTR(driver, S_IWUSR | S_IRUGO, serio_show_driver, serio_rebind_driver);
 
 static void serio_release_port(struct device *dev)
 {


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

* Re: [patches] Input updates
  2004-07-29 14:07 [patches] Input updates Vojtech Pavlik
  2004-07-29 14:09 ` [PATCH 1/47] Add 64-bit compatible ioctls for hiddev Vojtech Pavlik
@ 2004-07-29 16:59 ` Vojtech Pavlik
  2004-07-29 16:59   ` [PATCH 1/2] move input/serio closer to the top of drivers/Makefile so serio_bus is available early Vojtech Pavlik
  1 sibling, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 16:59 UTC (permalink / raw)
  To: torvalds, linux-kernel

On Thu, Jul 29, 2004 at 04:07:28PM +0200, Vojtech Pavlik wrote:
> Hi!
> 
> Again, quite a bunch of patches has accumulated in my tree - now that
> they're well tested through Andrew's mm tree, I'd like to merge them to
> you.
> 
> There still are imperfections in atkbd/psmouse locking, but the races
> are rather hard to hit - and it's still better than before. They should
> be fixed in the next round of patches, however I'd still like to have
> this round of patches in before the next one.
> 
> Please pull from bk://kernel.bkbits.net/vojtech/input

There's two more patches needed for that set, now in the same bk tree,
to make Sun machines with Type4/Type5 keyboards work correctly.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

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

* [PATCH 1/2] move input/serio closer to the top of drivers/Makefile so serio_bus is available early
  2004-07-29 16:59 ` [patches] Input updates Vojtech Pavlik
@ 2004-07-29 16:59   ` Vojtech Pavlik
  2004-07-29 16:59     ` [PATCH 2/2] rearrange code in sunzilog to prevent deadlock Vojtech Pavlik
  0 siblings, 1 reply; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 16:59 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1807.3.2, 2004-07-19 22:34:23-05:00, dtor_core@ameritech.net
  Input: move input/serio closer to the top of drivers/Makefile so
         serio_bus is available early
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 Makefile |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

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

diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Thu Jul 29 18:52:08 2004
+++ b/drivers/Makefile	Thu Jul 29 18:52:08 2004
@@ -15,6 +15,9 @@
 # char/ comes before serial/ etc so that the VT console is the boot-time
 # default.
 obj-y				+= char/
+# we also need input/serio early so serio bus is initialized by the time
+# serial drivers start registering their serio ports
+obj-$(CONFIG_SERIO)		+= input/serio/
 obj-y				+= serial/
 obj-$(CONFIG_PARPORT)		+= parport/
 obj-y				+= base/ block/ misc/ net/ media/
@@ -37,7 +40,6 @@
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB)		+= usb/
 obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
-obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_INPUT)		+= input/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_I2O)		+= message/


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

* [PATCH 2/2] rearrange code in sunzilog to prevent deadlock
  2004-07-29 16:59   ` [PATCH 1/2] move input/serio closer to the top of drivers/Makefile so serio_bus is available early Vojtech Pavlik
@ 2004-07-29 16:59     ` Vojtech Pavlik
  0 siblings, 0 replies; 51+ messages in thread
From: Vojtech Pavlik @ 2004-07-29 16:59 UTC (permalink / raw)
  To: torvalds, vojtech, linux-kernel

You can pull this changeset from:
	bk://kernel.bkbits.net/vojtech/input

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

ChangeSet@1.1807.3.3, 2004-07-19 22:35:13-05:00, dtor_core@ameritech.net
  Input: rearrange code in sunzilog so it registers its serio ports
         only after hardware was fully initialized and with interrupts
         tuned back on, otherwise it deadlocks.
  
  Signed-off-by: Dmitry Torokhov <dtor@mail.ru>


 sunzilog.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

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

diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Thu Jul 29 18:52:03 2004
+++ b/drivers/serial/sunzilog.c	Thu Jul 29 18:52:03 2004
@@ -1529,7 +1529,6 @@
 static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
 {
 	int baud, brg;
-	struct serio *serio;
 
 	if (channel == KEYBOARD_LINE) {
 		up->flags |= SUNZILOG_FLAG_CONS_KEYB;
@@ -1546,8 +1545,15 @@
 	up->curregs[R15] = BRKIE;
 	brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 	sunzilog_convert_to_zs(up, up->cflag, 0, brg);
+	sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
+	__sunzilog_startup(up);
+}
 
 #ifdef CONFIG_SERIO
+static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
+{
+	struct serio *serio;
+
 	up->serio = serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
 
@@ -1576,11 +1582,8 @@
 		printk(KERN_WARNING "zs%d: not enough memory for serio port\n",
 			channel);
 	}
-#endif
-
-	sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
-	__sunzilog_startup(up);
 }
+#endif
 
 static void __init sunzilog_init_hw(void)
 {
@@ -1624,6 +1627,11 @@
 		}
 
 		spin_unlock_irqrestore(&up->port.lock, flags);
+
+#ifdef CONFIG_SERIO
+		if (i == KEYBOARD_LINE || i == MOUSE_LINE)
+			sunzilog_register_serio(up, i);
+#endif
 	}
 }
 


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

end of thread, other threads:[~2004-07-29 18:48 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-29 14:07 [patches] Input updates Vojtech Pavlik
2004-07-29 14:09 ` [PATCH 1/47] Add 64-bit compatible ioctls for hiddev Vojtech Pavlik
2004-07-29 14:09   ` [PATCH 2/47] Fix locking in i8042.c and serio.c Vojtech Pavlik
2004-07-29 14:09     ` [PATCH 3/47] Fix an oops in poll() on uinput Vojtech Pavlik
2004-07-29 14:09       ` [PATCH 4/47] Ensure exclusive access to variables in atkbd.c Vojtech Pavlik
2004-07-29 14:09         ` [PATCH 5/47] Return 0 from uinput poll if device isn't yet created Vojtech Pavlik
2004-07-29 14:09           ` [PATCH 6/47] Explicit variable access rules for psmouse.c Vojtech Pavlik
2004-07-29 14:09             ` [PATCH 7/47] Add reporting of raw scancodes to atkbd.c Vojtech Pavlik
2004-07-29 14:09               ` [PATCH 8/47] Use raw events generated by atkbd in keyboard.c to implement true rawmode for PS/2 keyboards Vojtech Pavlik
2004-07-29 14:09                 ` [PATCH 9/47] Fixes in serio locking Vojtech Pavlik
2004-07-29 14:09                   ` [PATCH 10/47] Disable the AUX LoopBack command in i8042.c on Compaq ProLiant Vojtech Pavlik
2004-07-29 14:09                     ` [PATCH 11/47] Make atkbd.c's atkbd_command() function immune to keys being pressed while running Vojtech Pavlik
2004-07-29 14:09                       ` [PATCH 12/47] More locking improvements (and a fix) for serio Vojtech Pavlik
2004-07-29 14:09                         ` [PATCH 13/47] Add a missing dmi_noloop declaration in i8042.c Vojtech Pavlik
2004-07-29 14:09                           ` [PATCH 14/47] logips2pp - do not call get_model_info 2 times Vojtech Pavlik
2004-07-29 14:09                             ` [PATCH 15/47] Fix compilation breakage when CONFIG_USB_HIDDEV not defined Vojtech Pavlik
2004-07-29 14:09                               ` [PATCH 16/47] Make hardware rawmode optional for AT-keyboards Vojtech Pavlik
2004-07-29 14:09                                 ` [PATCH 17/47] Fix boundary checks for GUSAGE/SUSAGE in hiddev Vojtech Pavlik
2004-07-29 14:09                                   ` [PATCH 18/47] Updates to the tsdev driver (raw protocol, calib ioctls, ...) Vojtech Pavlik
2004-07-29 14:09                                     ` [PATCH 19/47] mousedev - better handle button presses when under load Vojtech Pavlik
2004-07-29 14:09                                       ` [PATCH 20/47] mousedev - implement tapping for touchpads Vojtech Pavlik
2004-07-29 14:09                                         ` [PATCH 21/47] Remove OSB4/Profusion hack in i8042 Vojtech Pavlik
2004-07-29 14:09                                           ` [PATCH 22/47] rearrangements and cleanups in serio.c Vojtech Pavlik
2004-07-29 14:09                                             ` [PATCH 23/47] Fix bad struct hidinput initialization in hid-tmff.c Vojtech Pavlik
2004-07-29 14:09                                               ` [PATCH 24/47] Remove an extra dmi_noloop declaration in i8042.c Vojtech Pavlik
2004-07-29 14:09                                                 ` [PATCH 25/47] Enhancements/fixes for PSX pad support Vojtech Pavlik
2004-07-29 14:09                                                   ` [PATCH 26/47] when probing for ImExPS/2 mice, the ImPS/2 sequence needs to be sent first Vojtech Pavlik
2004-07-29 14:09                                                     ` [PATCH 27/47] Fix array overflows in keyboard.c when KEY_MAX > keycode > NR_KEYS > 128 Vojtech Pavlik
2004-07-29 14:09                                                       ` [PATCH 28/47] Add Dell SB Live! PCI ID to the emu10k1-gp driver Vojtech Pavlik
2004-07-29 14:09                                                         ` [PATCH 29/47] Add Audigy LS PCI ID to emu10k1-gp Vojtech Pavlik
2004-07-29 14:09                                                           ` [PATCH 30/47] Add CodeMercs IOWarrior to hid-core device blacklist Vojtech Pavlik
2004-07-29 14:09                                                             ` [PATCH 31/47] Fix Peter Nelson's e-mail address in gamecon.c Vojtech Pavlik
2004-07-29 14:09                                                               ` [PATCH 32/47] make connect and disconnect methods mandatory for serio Vojtech Pavlik
2004-07-29 14:09                                                                 ` [PATCH 33/47] rename serio->driver to serio->port_data Vojtech Pavlik
2004-07-29 14:09                                                                   ` [PATCH 34/47] more renames in serio in preparation for sysfs integration Vojtech Pavlik
2004-07-29 14:09                                                                     ` [PATCH 35/47] switch to dynamic (heap) serio port allocation Vojtech Pavlik
2004-07-29 14:09                                                                       ` [PATCH 36/47] allow serio drivers to create children ports Vojtech Pavlik
2004-07-29 14:09                                                                         ` [PATCH 37/47] serio sysfs integration Vojtech Pavlik
2004-07-29 14:09                                                                           ` [PATCH 38/47] allow users to manually rebind serio ports Vojtech Pavlik
2004-07-29 14:09                                                                             ` [PATCH 39/47] allow marking some drivers as manual bind only Vojtech Pavlik
2004-07-29 14:09                                                                               ` [PATCH 40/47] Add serio_raw driver Vojtech Pavlik
2004-07-29 14:09                                                                                 ` [PATCH 41/47] link (some) serio ports to their parent devices Vojtech Pavlik
2004-07-29 14:09                                                                                   ` [PATCH 42/47] Fix Kconfig so that the joydump module can be compiled Vojtech Pavlik
2004-07-29 14:09                                                                                     ` [PATCH 43/47] Move Compaq ProLiant DMI handling to i8042.c Vojtech Pavlik
2004-07-29 14:09                                                                                       ` [PATCH 44/47] This patch fixes another disconnect oops in hiddev Vojtech Pavlik
2004-07-29 14:09                                                                                         ` [PATCH 45/47] Re-add PC Speaker support for PPC Vojtech Pavlik
2004-07-29 14:09                                                                                           ` [PATCH 46/47] Fix a missing index in tmdc.c Vojtech Pavlik
2004-07-29 14:09                                                                                             ` [PATCH 47/47] Check the range for HIDIOC?USAGES num_values Vojtech Pavlik
2004-07-29 16:59 ` [patches] Input updates Vojtech Pavlik
2004-07-29 16:59   ` [PATCH 1/2] move input/serio closer to the top of drivers/Makefile so serio_bus is available early Vojtech Pavlik
2004-07-29 16:59     ` [PATCH 2/2] rearrange code in sunzilog to prevent deadlock Vojtech Pavlik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox