Skip to contentSkip to conversation

input: Update AT+PS/2 mouse and keyboard drivers [1/14]

PATCH New Vojtech Pavlik 4 participants 20 messages Feb 12, 2003 – Feb 13, 2003

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 input: Update AT+PS/2 mouse and keyboard drivers [1/14]

Hi!

I'm resending the last batch of changesets, cleaned up and merged from 37 into just 14. They all are re-applied to current 2.5.60 to avoid any need of merges.

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

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

[email protected], 2003-02-12 10:24:25+01:00, [email protected]
input: Update AT+PS/2 mouse and keyboard drivers:
- Fix a possible deadlock with 0xfe resend command (atkbd)
- Make ->ack variables volatile (they're updated from irq)
- Fix the GETID one/two byte command to avoid any races
- Fix Logitech PS2++ extended packet detection
- Use RESET_BAT on reboot to make notebooks happy

 keyboard/atkbd.c |   56 ++++++++++++++++++++++++++++++++-----------------------
 mouse/psmouse.c  |   36 ++++++++++++++++++++++-------------
 2 files changed, 56 insertions(+), 36 deletions(-)

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

drivers/input/keyboard/atkbd.c +33 -23
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
@@ -86,8 +86,7 @@
 #define ATKBD_CMD_SETLEDS	0x10ed
 #define ATKBD_CMD_GSCANSET	0x11f0
 #define ATKBD_CMD_SSCANSET	0x10f0
-#define ATKBD_CMD_GETID		0x01f2
-#define ATKBD_CMD_GETID2	0x0100
+#define ATKBD_CMD_GETID		0x02f2
 #define ATKBD_CMD_ENABLE	0x00f4
 #define ATKBD_CMD_RESET_DIS	0x00f5
 #define ATKBD_CMD_RESET_BAT	0x01ff
@@ -120,12 +119,12 @@
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
 	unsigned char set;
-	unsigned char oldset;
 	unsigned char release;
-	signed char ack;
+	volatile signed char ack;
 	unsigned char emul;
 	unsigned short id;
 	unsigned char write;
+	unsigned char resend;
 };
 
 /*
@@ -142,11 +141,15 @@
 	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
 #endif
 
-	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && atkbd->write) {
+	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
 		printk("atkbd.c: frame/parity error: %02x\n", flags);
 		serio_write(serio, ATKBD_CMD_RESEND);
+		atkbd->resend = 1;
 		return;
 	}
+	
+	if (!flags)
+		atkbd->resend = 0;
 
 	switch (code) {
 		case ATKBD_RET_ACK:
@@ -227,12 +230,15 @@
 
 static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
 {
-	int timeout = 50000; /* 500 msec */
+	int timeout = 500000; /* 500 msec */
 	int send = (command >> 12) & 0xf;
 	int receive = (command >> 8) & 0xf;
 	int i;
 
 	atkbd->cmdcnt = receive;
+
+	if (command == ATKBD_CMD_RESET_BAT)
+		timeout = 2000000; /* 2 sec */
 	
 	if (command & 0xff)
 		if (atkbd_sendbyte(atkbd, command & 0xff))
@@ -242,14 +248,28 @@
 		if (atkbd_sendbyte(atkbd, param[i]))
 			return (atkbd->cmdcnt = 0) - 1;
 
-	while (atkbd->cmdcnt && timeout--) udelay(10);
+	while (atkbd->cmdcnt && timeout--) {
+
+		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_RESET_BAT)
+			timeout = 100000;
+
+		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
+		    atkbd->cmdbuf[1] != 0xab && atkbd->cmdbuf[1] != 0xac) {
+			atkbd->cmdcnt = 0;
+			break;
+		}
+	
+		udelay(1);
+	}
 
 	if (param)
 		for (i = 0; i < receive; i++)
 			param[i] = atkbd->cmdbuf[(receive - 1) - i];
 
-	if (atkbd->cmdcnt) 
-		return (atkbd->cmdcnt = 0) - 1;
+	if (atkbd->cmdcnt) {
+		atkbd->cmdcnt = 0;
+		return -1;
+	}
 
 	return 0;
 }
@@ -303,13 +323,6 @@
 	unsigned char param[2];
 
 /*
- * Remember original scancode set value, so that we can restore it on exit.
- */
-
-	if (atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_GSCANSET))
-		atkbd->oldset = 2;
-
-/*
  * For known special keyboards we can go ahead and set the correct set.
  * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and
  * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards.
@@ -376,8 +389,8 @@
  */
 
 	if (atkbd_reset)
-		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
-			printk(KERN_WARNING "atkbd.c: keyboard reset failed\n");
+		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
+			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
 
 /*
  * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
@@ -401,10 +414,7 @@
 
 	if (param[0] != 0xab && param[0] != 0xac)
 		return -1;
-	atkbd->id = param[0] << 8;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_GETID2))
-		return -1;
-	atkbd->id |= param[0];
+	atkbd->id = (param[0] << 8) | param[1];
 
 /*
  * Set the LEDs to a defined state.
@@ -442,7 +452,7 @@
 static void atkbd_cleanup(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
-	atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_SSCANSET);
+	atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT);
 }
 
 /*
drivers/input/mouse/psmouse.c +23 -13
diff -Nru a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c
@@ -30,8 +30,7 @@
 #define PSMOUSE_CMD_GETINFO	0x03e9
 #define PSMOUSE_CMD_SETSTREAM	0x00ea
 #define PSMOUSE_CMD_POLL	0x03eb	
-#define PSMOUSE_CMD_GETID	0x01f2
-#define PSMOUSE_CMD_GETID2	0x0100
+#define PSMOUSE_CMD_GETID	0x02f2
 #define PSMOUSE_CMD_SETRATE	0x10f3
 #define PSMOUSE_CMD_ENABLE	0x00f4
 #define PSMOUSE_CMD_RESET_DIS	0x00f6
@@ -54,7 +53,7 @@
 	unsigned char model;
 	unsigned long last;
 	char acking;
-	char ack;
+	volatile char ack;
 	char error;
 	char devname[64];
 	char phys[32];
@@ -85,9 +84,9 @@
 
 	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
 
-		if ((packet[0] & 0x40) == 0x40 && (int) packet[1] - (int) ((packet[0] & 0x10) << 4) > 191 ) {
+		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
 
-			switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0)) {
+			switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)) {
 
 			case 1: /* Mouse extra info */
 
@@ -106,10 +105,11 @@
 
 				break;
 
+#ifdef DEBUG
 			default:
-
 				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
-					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0));
+					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
+#endif
 
 			}
 
@@ -248,6 +248,9 @@
 
 	psmouse->cmdcnt = receive;
 
+	if (command == PSMOUSE_CMD_RESET_BAT)
+                timeout = 2000000; /* 2 sec */
+
 	if (command & 0xff)
 		if (psmouse_sendbyte(psmouse, command & 0xff))
 			return (psmouse->cmdcnt = 0) - 1;
@@ -256,7 +259,19 @@
 		if (psmouse_sendbyte(psmouse, param[i]))
 			return (psmouse->cmdcnt = 0) - 1;
 
-	while (psmouse->cmdcnt && timeout--) udelay(1);
+	while (psmouse->cmdcnt && timeout--) {
+	
+		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT)
+			timeout = 100000;
+
+		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID &&
+		    psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) {
+			psmouse->cmdcnt = 0;
+			break;
+		}
+
+		udelay(1);
+	}
 
 	for (i = 0; i < receive; i++)
 		param[i] = psmouse->cmdbuf[(receive - 1) - i];
@@ -497,11 +512,6 @@
 
 	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID))
 		return -1;
-
-	if (param[0] == 0xab || param[0] == 0xac) {
-		psmouse_command(psmouse, param, PSMOUSE_CMD_GETID2);
-		return -1;
-	}
 
 	if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04)
 		return -1;
#1 lore raw

PATCH 1/1 input: Remove include/linux/pc_keyb.h and old PS/2 code [2/14]

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

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

[email protected], 2003-02-12 10:28:17+01:00, [email protected]
input: Remove include/linux/pc_keyb.h and old PS/2 code
from drivers/char/misc.c

 b/drivers/char/misc.c   |    3 -
 include/linux/pc_keyb.h |  130 ------------------------------------------------
 2 files changed, 133 deletions(-)

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

drivers/char/misc.c +0 -3
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
@@ -50,8 +50,6 @@
 #include <linux/tty.h>
 #include <linux/kmod.h>
 
-#include "busmouse.h"
-
 /*
  * Head entry for the doubly linked miscdevice list
  */
@@ -64,7 +62,6 @@
 #define DYNAMIC_MINORS 64 /* like dynamic majors */
 static unsigned char misc_minors[DYNAMIC_MINORS / 8];
 
-extern int psaux_init(void);
 #ifdef CONFIG_SGI_NEWPORT_GFX
 extern void gfx_register(void);
 #endif
include/linux/pc_keyb.h deleted +0 -130

130 lines not on this page · raw message

#2 lore raw

PATCH 1/1 input: Only generate rawmode warnings for keys [3/14]

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

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

[email protected], 2003-02-12 10:31:13+01:00, [email protected]
input: Only generate rawmode warnings if the event we cannot handle
is a real key and not just a button or something.

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

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

drivers/char/keyboard.c +2 -1
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
@@ -1027,7 +1027,8 @@
 
 	if ((raw_mode = (kbd->kbdmode == VC_RAW)))
 		if (emulate_raw(vc, keycode, !down << 7))
-			printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
+			if (keycode < BTN_MISC)
+				printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
 
 #ifdef CONFIG_MAGIC_SYSRQ	       /* Handle the SysRq Hack */
 	if (keycode == KEY_SYSRQ && !rep) {
#3 lore raw

PATCH 1/1 input: Let newly connected keyboards pickup the LED state. [4/14]

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

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

[email protected], 2003-02-12 10:35:04+01:00, [email protected]
input: Let newly connected keyboards pickup the LED state.

 keyboard.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

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

drivers/char/keyboard.c +20 -3
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
@@ -894,9 +894,9 @@
  * Aside from timing (which isn't really that important for
  * keyboard interrupts as they happen often), using the software
  * interrupt routines for this thing allows us to easily mask
- * this when we don't want any of the above to happen. Not yet
- * used, but this allows for easy and efficient race-condition
- * prevention later on.
+ * this when we don't want any of the above to happen.
+ * This allows for easy and efficient race-condition prevention
+ * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ...
  */
 
 static void kbd_bh(unsigned long dummy)
@@ -918,6 +918,22 @@
 
 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
 
+/*
+ * This allows a newly plugged keyboard to pick the LED state.
+ */
+void kbd_refresh_leds(struct input_handle *handle)
+{
+	unsigned char leds = ledstate;
+
+	tasklet_disable(&keyboard_tasklet);
+	if (leds != 0xff) {
+		input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+		input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
+		input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+	}
+	tasklet_enable(&keyboard_tasklet);
+}
+
 #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)
 
 static unsigned short x86_keycodes[256] =
@@ -1160,6 +1176,7 @@
 	handle->name = kbd_name;
 
 	input_open_device(handle);
+	kbd_refresh_leds(handle);
 
 	return handle;
 }
#4 lore raw

PATCH 1/1 input: Get rid of kbd_pt_regs [5/14]

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

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

[email protected], 2003-02-12 10:41:07+01:00, [email protected]
input: Get rid of the kbd_pt_regs variable, and instead pass the
value all the way from an interrupt handler to keyboard.c that can display it.

 arch/sparc64/kernel/irq.c                      |    3 
 drivers/acorn/char/keyb_arc.c                  |    1 
 drivers/char/ec3104_keyb.c                     |    2 
 drivers/char/keyboard.c                        |  118 ++++++++++++-------------
 drivers/input/joystick/amijoy.c                |    2 
 drivers/input/joystick/iforce/iforce-packets.c |    5 -
 drivers/input/joystick/iforce/iforce-serio.c   |    4 
 drivers/input/joystick/iforce/iforce-usb.c     |   15 +--
 drivers/input/joystick/iforce/iforce.h         |    2 
 drivers/input/joystick/magellan.c              |    8 +
 drivers/input/joystick/spaceball.c             |    8 +
 drivers/input/joystick/spaceorb.c              |    8 +
 drivers/input/joystick/stinger.c               |    8 +
 drivers/input/joystick/twidjoy.c               |    8 +
 drivers/input/joystick/warrior.c               |   10 +-
 drivers/input/keyboard/amikbd.c                |    2 
 drivers/input/keyboard/atkbd.c                 |    3 
 drivers/input/keyboard/newtonkbd.c             |    8 +
 drivers/input/keyboard/sunkbd.c                |    3 
 drivers/input/keyboard/xtkbd.c                 |    3 
 drivers/input/misc/gsc_ps2.c                   |   13 +-
 drivers/input/mouse/amimouse.c                 |    2 
 drivers/input/mouse/inport.c                   |    2 
 drivers/input/mouse/logibm.c                   |    1 
 drivers/input/mouse/pc110pad.c                 |    1 
 drivers/input/mouse/psmouse.c                  |    8 +
 drivers/input/mouse/rpcmouse.c                 |    2 
 drivers/input/mouse/sermouse.c                 |   14 +-
 drivers/input/serio/ambakmi.c                  |    6 -
 drivers/input/serio/ct82c710.c                 |    2 
 drivers/input/serio/i8042.c                    |   16 +--
 drivers/input/serio/parkbd.c                   |    2 
 drivers/input/serio/q40kbd.c                   |    3 
 drivers/input/serio/rpckbd.c                   |    5 -
 drivers/input/serio/sa1111ps2.c                |    6 -
 drivers/input/serio/serio.c                    |    4 
 drivers/input/serio/serport.c                  |    5 -
 drivers/input/touchscreen/gunze.c              |    7 -
 drivers/input/touchscreen/h3600_ts_input.c     |    6 +
 drivers/macintosh/adbhid.c                     |   22 ++--
 drivers/serial/sunsu.c                         |    4 
 drivers/serial/sunzilog.c                      |    4 
 drivers/usb/input/aiptek.c                     |    2 
 drivers/usb/input/hid-core.c                   |   22 ++--
 drivers/usb/input/hid-input.c                  |    4 
 drivers/usb/input/hid.h                        |    4 
 drivers/usb/input/hiddev.c                     |    2 
 drivers/usb/input/powermate.c                  |    1 
 drivers/usb/input/usbkbd.c                     |    2 
 drivers/usb/input/usbmouse.c                   |    1 
 drivers/usb/input/wacom.c                      |    7 +
 drivers/usb/input/xpad.c                       |    6 -
 include/asm-sparc/system.h                     |    2 
 include/asm-sparc64/system.h                   |    2 
 include/linux/hiddev.h                         |    4 
 include/linux/input.h                          |    5 -
 include/linux/serio.h                          |   11 +-
 57 files changed, 242 insertions(+), 189 deletions(-)

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

arch/sparc64/kernel/irq.c +0 -3
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
@@ -740,9 +740,6 @@
 	irq_enter();
 	kstat_cpu(cpu).irqs[irq]++;
 
-	if (irq == 9)
-		kbd_pt_regs = regs;
-
 	/* Sliiiick... */
 #ifndef CONFIG_SMP
 	bp = ((irq != 0) ?
drivers/acorn/char/keyb_arc.c +0 -1
diff -Nru a/drivers/acorn/char/keyb_arc.c b/drivers/acorn/char/keyb_arc.c
@@ -406,7 +406,6 @@
 
 static void a5kkbd_rx(int irq, void *dev_id, struct pt_regs *regs)
 {
-	kbd_pt_regs = regs;
 	if (handle_rawcode(ioc_readb(IOC_KARTRX)))
 		tasklet_schedule(&keyboard_tasklet);
 }
drivers/char/ec3104_keyb.c +0 -2
diff -Nru a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
@@ -376,8 +376,6 @@
 	struct e5_struct *k = &ec3104_keyb;
 	u8 msr, lsr;
 
-	kbd_pt_regs = regs;
-
 	msr = ctrl_inb(EC3104_SER4_MSR);
 	
 	if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) {
drivers/char/keyboard.c +59 -59

390 lines not on this page · raw message

drivers/input/joystick/amijoy.c +2 -0
diff -Nru a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
@@ -64,6 +64,8 @@
 				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
 			}
 
+			input_regs(amijoy_dev + i, fp);
+
 			input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
 
 			input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
drivers/input/joystick/iforce/iforce-packets.c +4 -1
diff -Nru a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
@@ -151,7 +151,7 @@
 	return -1;
 }
 
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &iforce->dev;
 	int i;
@@ -181,6 +181,8 @@
 		case 0x01:	/* joystick position data */
 		case 0x03:	/* wheel position data */
 
+			input_regs(dev, regs);
+
 			if (HI(cmd) == 1) {
 				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
 				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
@@ -219,6 +221,7 @@
 			break;
 
 		case 0x02:	/* status report */
+			input_regs(dev, regs);
 			input_report_key(dev, BTN_DEAD, data[0] & 0x02);
 			input_sync(dev);
 
drivers/input/joystick/iforce/iforce-serio.c +2 -2
diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
@@ -78,7 +78,7 @@
 	iforce_serial_xmit((struct iforce *)serio->private);
 }
 
-static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
+static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct iforce* iforce = serio->private;
 
@@ -115,7 +115,7 @@
 	}
 
 	if (iforce->idx == iforce->len) {
-		iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
+		iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs);
 		iforce->pkt = 0;
 		iforce->id  = 0;
 		iforce->len = 0;
drivers/input/joystick/iforce/iforce-usb.c +9 -6
diff -Nru a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
@@ -74,7 +74,7 @@
 	spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 }
 
-static void iforce_usb_irq(struct urb *urb)
+static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 	int status;
@@ -96,7 +96,7 @@
 	}
 
 	iforce_process_packet(iforce,
-		(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
+		(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
 
 exit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
@@ -105,7 +105,7 @@
 		     __FUNCTION__, status);
 }
 
-static void iforce_usb_out(struct urb *urb)
+static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 
@@ -120,7 +120,7 @@
 		wake_up(&iforce->wait);
 }
 
-static void iforce_usb_ctrl(struct urb *urb)
+static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 	if (urb->status) return;
@@ -133,11 +133,14 @@
 				const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
+	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *epirq, *epout;
 	struct iforce *iforce;
 
-	epirq = intf->altsetting[0].endpoint + 0;
-	epout = intf->altsetting[0].endpoint + 1;
+	interface = &intf->altsetting[intf->act_altsetting];
+
+	epirq = &interface->endpoint[0].desc;
+	epout = &interface->endpoint[1].desc;
 
 	if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
 		goto fail;
drivers/input/joystick/iforce/iforce.h +1 -1
diff -Nru a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
@@ -176,7 +176,7 @@
 
 /* iforce-packets.c */
 int iforce_control_playback(struct iforce*, u16 id, unsigned int);
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs);
 int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
 void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
 int iforce_get_id_packet(struct iforce *iforce, char *packet);
drivers/input/joystick/magellan.c +5 -3
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
@@ -81,7 +81,7 @@
 	return 0;
 }
 
-static void magellan_process_packet(struct magellan* magellan)
+static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
 {
 	struct input_dev *dev = &magellan->dev;
 	unsigned char *data = magellan->data;
@@ -89,6 +89,8 @@
 
 	if (!magellan->idx) return;
 
+	input_regs(dev, regs);
+
 	switch (magellan->data[0]) {
 
 		case 'd':				/* Axis data */
@@ -111,12 +113,12 @@
 	input_sync(dev);
 }
 
-static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct magellan* magellan = serio->private;
 
 	if (data == '\r') {
-		magellan_process_packet(magellan);
+		magellan_process_packet(magellan, regs);
 		magellan->idx = 0;
 	} else {
 		if (magellan->idx < MAGELLAN_MAX_LENGTH)
drivers/input/joystick/spaceball.c +5 -3
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
@@ -81,7 +81,7 @@
  * SpaceBall.
  */
 
-static void spaceball_process_packet(struct spaceball* spaceball)
+static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
 {
 	struct input_dev *dev = &spaceball->dev;
 	unsigned char *data = spaceball->data;
@@ -89,6 +89,8 @@
 
 	if (spaceball->idx < 2) return;
 
+	input_regs(dev, regs);
+
 	switch (spaceball->data[0]) {
 
 		case 'D':					/* Ball data */
@@ -147,13 +149,13 @@
  * can occur in the axis values.
  */
 
-static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct spaceball *spaceball = serio->private;
 
 	switch (data) {
 		case 0xd:
-			spaceball_process_packet(spaceball);
+			spaceball_process_packet(spaceball, regs);
 			spaceball->idx = 0;
 			spaceball->escape = 0;
 			return;
drivers/input/joystick/spaceorb.c +5 -3
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
@@ -74,7 +74,7 @@
  * SpaceOrb.
  */
 
-static void spaceorb_process_packet(struct spaceorb *spaceorb)
+static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
 {
 	struct input_dev *dev = &spaceorb->dev;
 	unsigned char *data = spaceorb->data;
@@ -86,6 +86,8 @@
 	for (i = 0; i < spaceorb->idx; i++) c ^= data[i];
 	if (c) return;
 
+	input_regs(dev, regs);
+
 	switch (data[0]) {
 
 		case 'R':				/* Reset packet */
@@ -128,12 +130,12 @@
 	input_sync(dev);
 }
 
-static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct spaceorb* spaceorb = serio->private;
 
 	if (~data & 0x80) {
-		if (spaceorb->idx) spaceorb_process_packet(spaceorb);
+		if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs);
 		spaceorb->idx = 0;
 	}
 	if (spaceorb->idx < SPACEORB_MAX_LENGTH)
drivers/input/joystick/stinger.c +5 -3
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
@@ -64,13 +64,15 @@
  * Stinger. It updates the data accordingly.
  */
 
-static void stinger_process_packet(struct stinger *stinger)
+static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
 {
 	struct input_dev *dev = &stinger->dev;
 	unsigned char *data = stinger->data;
 
 	if (!stinger->idx) return;
 
+	input_regs(dev, regs);
+
 	input_report_key(dev, BTN_A,	  ((data[0] & 0x20) >> 5));
 	input_report_key(dev, BTN_B,	  ((data[0] & 0x10) >> 4));
 	input_report_key(dev, BTN_C,	  ((data[0] & 0x08) >> 3));
@@ -96,7 +98,7 @@
  * packet processing routine.
  */
 
-static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct stinger* stinger = serio->private;
 
@@ -106,7 +108,7 @@
 		stinger->data[stinger->idx++] = data;
 
 	if (stinger->idx == 4) {
-		stinger_process_packet(stinger);
+		stinger_process_packet(stinger, regs);
 		stinger->idx = 0;
 	}
 
drivers/input/joystick/twidjoy.c +5 -3
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
@@ -101,7 +101,7 @@
  * Twiddler. It updates the data accordingly.
  */
 
-static void twidjoy_process_packet(struct twidjoy *twidjoy)
+static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
 {
 	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
 		struct input_dev *dev = &twidjoy->dev;
@@ -111,6 +111,8 @@
 
 		button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
 
+		input_regs(dev, regs);
+
 		for (bp = twidjoy_buttons; bp->bitmask; bp++) {
 			int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
 			int i;
@@ -140,7 +142,7 @@
  * packet processing routine.
  */
 
-static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs)
 {
 	struct twidjoy *twidjoy = serio->private;
 
@@ -157,7 +159,7 @@
 		twidjoy->data[twidjoy->idx++] = data;
 
 	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
-		twidjoy_process_packet(twidjoy);
+		twidjoy_process_packet(twidjoy, regs);
 		twidjoy->idx = 0;
 	}
 
drivers/input/joystick/warrior.c +6 -4
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
@@ -63,13 +63,15 @@
  * Warrior. It updates the data accordingly.
  */
 
-static void warrior_process_packet(struct warrior *warrior)
+static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
 {
 	struct input_dev *dev = &warrior->dev;
 	unsigned char *data = warrior->data;
 
 	if (!warrior->idx) return;
 
+	input_regs(dev, regs);
+
 	switch ((data[0] >> 4) & 7) {
 		case 1:					/* Button data */
 			input_report_key(dev, BTN_TRIGGER,  data[3]       & 1);
@@ -97,12 +99,12 @@
  * packet processing routine.
  */
 
-static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct warrior* warrior = serio->private;
 
 	if (data & 0x80) {
-		if (warrior->idx) warrior_process_packet(warrior);
+		if (warrior->idx) warrior_process_packet(warrior, regs);
 		warrior->idx = 0;
 		warrior->len = warrior_lengths[(data >> 4) & 7];
 	}
@@ -111,7 +113,7 @@
 		warrior->data[warrior->idx++] = data;
 
 	if (warrior->idx == warrior->len) {
-		if (warrior->idx) warrior_process_packet(warrior);	
+		if (warrior->idx) warrior_process_packet(warrior, regs);	
 		warrior->idx = 0;
 		warrior->len = 0;
 	}
drivers/input/keyboard/amikbd.c +2 -0
diff -Nru a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
@@ -87,6 +87,8 @@
 
 		scancode = amikbd_keycode[scancode];
 
+		input_regs(&amikbd_dev, fp);
+
 		if (scancode == KEY_CAPSLOCK) {	/* CapsLock is a toggle switch key on Amiga */
 			input_report_key(&amikbd_dev, scancode, 1);
 			input_report_key(&amikbd_dev, scancode, 0);
drivers/input/keyboard/atkbd.c +2 -1
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
@@ -132,7 +132,7 @@
  * the keyboard into events.
  */
 
-static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct atkbd *atkbd = serio->private;
 	int code = data;
@@ -193,6 +193,7 @@
 				atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
 			break;
 		default:
+			input_regs(&atkbd->dev, regs);
 			input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
 			input_sync(&atkbd->dev);
 	}
drivers/input/keyboard/newtonkbd.c +5 -3
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
@@ -62,18 +62,20 @@
 	char phys[32];
 };
 
-void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct nkbd *nkbd = serio->private;
 
 	/* invalid scan codes are probably the init sequence, so we ignore them */
-	if (nkbd->keycode[data & NKBD_KEY])
+	if (nkbd->keycode[data & NKBD_KEY]) {
+		input_regs(&nkbd->dev, regs);
 		input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+		input_sync(&nkbd->dev);
+	}
 
 	else if (data == 0xe7) /* end of init sequence */
 		printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
 
-	input_sync(&nkbd->dev);
 }
 
 void nkbd_connect(struct serio *serio, struct serio_dev *dev)
drivers/input/keyboard/sunkbd.c +2 -1
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
@@ -89,7 +89,7 @@
  * is received.
  */
 
-static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct sunkbd* sunkbd = serio->private;
 
@@ -119,6 +119,7 @@
 
 		default:
 			if (sunkbd->keycode[data & SUNKBD_KEY]) {
+				input_regs(&sunkbd->dev, regs);
                                 input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
 				input_sync(&sunkbd->dev);
                         } else {
drivers/input/keyboard/xtkbd.c +2 -1
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
@@ -63,7 +63,7 @@
 	char phys[32];
 };
 
-void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct xtkbd *xtkbd = serio->private;
 
@@ -74,6 +74,7 @@
 		default:
 
 			if (xtkbd->keycode[data & XTKBD_KEY]) {
+				input_regs(&xtkbd->dev, regs);
 				input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
 				input_sync(&xtkbd->dev);
 			} else {
drivers/input/misc/gsc_ps2.c +8 -5
diff -Nru a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c
@@ -305,7 +305,7 @@
  * Receives a keyboard scancode, analyses it and sends it to the input layer.
  */
 
-static void gscps2_kbd_docode(void)
+static void gscps2_kbd_docode(struct pt_regs *regs)
 {
 	int scancode = gscps2_readb_input(hpkeyb.addr);
 	DPRINTK("rel=%d scancode=%d, esc=%d ", hpkeyb.released, scancode, hpkeyb.escaped);
@@ -341,6 +341,7 @@
 		default:
 			hpkeyb.scancode = scancode;
 			DPRINTK("sent=%d, rel=%d\n",hpkeyb.scancode, hpkeyb.released);
+			input_regs(regs);
 			input_report_key(&hpkeyb.dev, hpkeyb_keycode[hpkeyb.scancode], !hpkeyb.released);
 			input_sync(&hpkeyb.dev);
 			if (hpkeyb.escaped)
@@ -359,7 +360,7 @@
  * correct events to the input layer.
  */
 
-static void gscps2_mouse_docode(void)
+static void gscps2_mouse_docode(struct pt_regs *regs)
 {
 	int xrel, yrel;
 
@@ -368,7 +369,7 @@
 		hpmouse.nbread--;
 
 	/* stolen from psmouse.c */
-	if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/20)) {
+	if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/2)) {
 		printk(KERN_DEBUG "%s:%d : Lost mouse synchronization, throwing %d bytes away.\n", __FILE__, __LINE__,
 				hpmouse.nbread);
 		hpmouse.nbread = 0;
@@ -387,6 +388,8 @@
 		if ((hpmouse.bytes[PACKET_CTRL] & (MOUSE_XOVFLOW | MOUSE_YOVFLOW)))
 			DPRINTK("Mouse: position overflow\n");
 		
+		input_regs(regs);
+
 		input_report_key(&hpmouse.dev, BTN_LEFT, hpmouse.bytes[PACKET_CTRL] & MOUSE_LEFTBTN);
 		input_report_key(&hpmouse.dev, BTN_MIDDLE, hpmouse.bytes[PACKET_CTRL] & MOUSE_MIDBTN);
 		input_report_key(&hpmouse.dev, BTN_RIGHT, hpmouse.bytes[PACKET_CTRL] & MOUSE_RIGHTBTN);
@@ -421,11 +424,11 @@
 {
 	/* process mouse actions */
 	while (gscps2_readb_status(hpmouse.addr) & GSC_STAT_RBNE)
-		gscps2_mouse_docode();
+		gscps2_mouse_docode(reg);
 	
 	/* process keyboard scancode */
 	while (gscps2_readb_status(hpkeyb.addr) & GSC_STAT_RBNE)
-		gscps2_kbd_docode();
+		gscps2_kbd_docode(reg);
 }
 
 
drivers/input/mouse/amimouse.c +2 -0
diff -Nru a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
@@ -63,6 +63,8 @@
 
 	potgor = custom.potgor;
 
+	input_regs(&amimouse_dev, fp);
+
 	input_report_rel(&amimouse_dev, REL_X, dx);
 	input_report_rel(&amimouse_dev, REL_Y, dy);
 
drivers/input/mouse/inport.c +2 -0
diff -Nru a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
@@ -131,6 +131,8 @@
 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 	outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
 
+	input_regs(&inport_dev, regs);
+
 	outb(INPORT_REG_X, INPORT_CONTROL_PORT);
 	input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
 
drivers/input/mouse/logibm.c +1 -0
diff -Nru a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
@@ -130,6 +130,7 @@
 	dy |= (buttons & 0xf) << 4;
 	buttons = ~buttons >> 5;
 
+	input_regs(&logibm_dev, regs);
 	input_report_rel(&logibm_dev, REL_X, dx);
 	input_report_rel(&logibm_dev, REL_Y, dy);
 	input_report_key(&logibm_dev, BTN_RIGHT,  buttons & 1);
drivers/input/mouse/pc110pad.c +1 -0
diff -Nru a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
@@ -73,6 +73,7 @@
 
 	if (pc110pad_count < 3) return;
 	
+	input_regs(&pc110pad_dev, regs);
 	input_report_key(&pc110pad_dev, BTN_TOUCH,
 		pc110pad_data[0] & 0x01);
 	input_report_abs(&pc110pad_dev, ABS_X,
drivers/input/mouse/psmouse.c +5 -3
diff -Nru a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c
@@ -73,11 +73,13 @@
  * reports relevant events to the input module.
  */
 
-static void psmouse_process_packet(struct psmouse *psmouse)
+static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	struct input_dev *dev = &psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
+	input_regs(dev, regs);
+
 /*
  * The PS2++ protocol is a little bit complex
  */
@@ -165,7 +167,7 @@
  * packets or passing them to the command routine as command output.
  */
 
-static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct psmouse *psmouse = serio->private;
 
@@ -201,7 +203,7 @@
 	psmouse->packet[psmouse->pktcnt++] = data;
 
 	if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
-		psmouse_process_packet(psmouse);
+		psmouse_process_packet(psmouse, regs);
 		psmouse->pktcnt = 0;
 		return;
 	}
drivers/input/mouse/rpcmouse.c +2 -0
diff -Nru a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
@@ -64,6 +64,8 @@
 	rpcmouse_lastx = x;
 	rpcmouse_lasty = y;
 
+	input_regs(dev, regs);
+
 	input_report_rel(dev, REL_X, dx);
 	input_report_rel(dev, REL_Y, -dy);
 
drivers/input/mouse/sermouse.c +9 -5
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
@@ -60,11 +60,13 @@
  * second, which is as good as a PS/2 or USB mouse.
  */
 
-static void sermouse_process_msc(struct sermouse *sermouse, signed char data)
+static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &sermouse->dev;
 	signed char *buf = sermouse->buf;
 
+	input_regs(dev, regs);
+
 	switch (sermouse->count) {
 
 		case 0:
@@ -101,13 +103,15 @@
  * standard 3-byte packets and 1200 bps.
  */
 
-static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
+static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &sermouse->dev;
 	signed char *buf = sermouse->buf;
 
 	if (data & 0x40) sermouse->count = 0;
 
+	input_regs(dev, regs);
+
 	switch (sermouse->count) {
 
 		case 0:
@@ -200,7 +204,7 @@
  * packets or passing them to the command routine as command output.
  */
 
-static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct sermouse *sermouse = serio->private;
 
@@ -208,9 +212,9 @@
 	sermouse->last = jiffies;
 
 	if (sermouse->type > SERIO_SUN)
-		sermouse_process_ms(sermouse, data);
+		sermouse_process_ms(sermouse, data, regs);
 	else
-		sermouse_process_msc(sermouse, data);
+		sermouse_process_msc(sermouse, data, regs);
 }
 
 /*
drivers/input/serio/ambakmi.c +1 -5
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
@@ -23,8 +23,6 @@
 #include <asm/irq.h>
 #include <asm/hardware/amba_kmi.h>
 
-extern struct pt_regs *kbd_pt_regs;
-
 #define KMI_BASE	(kmi->base)
 
 struct amba_kmi_port {
@@ -42,10 +40,8 @@
 	struct amba_kmi_port *kmi = dev_id;
 	unsigned int status = __raw_readb(KMIIR);
 
-	kbd_pt_regs = regs;
-
 	while (status & KMIIR_RXINTR) {
-		serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0);
+		serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0, regs);
 		status = __raw_readb(KMIIR);
 	}
 }
drivers/input/serio/ct82c710.c +1 -1
diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
@@ -156,7 +156,7 @@
 
 static void ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
 {
-	serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0);
+	serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0, regs);
 }
 
 /*
drivers/input/serio/i8042.c +5 -11
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
@@ -62,8 +62,6 @@
 static unsigned char i8042_mux_open;
 struct timer_list i8042_timer;
 
-extern struct pt_regs *kbd_pt_regs;
-
 static unsigned long i8042_unxlate_seen[256 / BITS_PER_LONG];
 static unsigned char i8042_unxlate_table[128] = {
 	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
@@ -345,10 +343,6 @@
 	} buffer[I8042_BUFFER_SIZE];
 	int i, j = 0;
 
-#ifdef CONFIG_VT
-	kbd_pt_regs = regs;
-#endif
-
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	while (j < I8042_BUFFER_SIZE && 
@@ -381,7 +375,7 @@
 				dfl & SERIO_PARITY ? ", bad parity" : "",
 				dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-			serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl);
+			serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
 			continue;
 		}
 
@@ -391,7 +385,7 @@
 			dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
 		if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) {
-			serio_interrupt(&i8042_aux_port, data, dfl);
+			serio_interrupt(&i8042_aux_port, data, dfl, regs);
 			continue;
 		}
 
@@ -399,7 +393,7 @@
 			continue;
 
 		if (i8042_direct) {
-			serio_interrupt(&i8042_kbd_port, data, dfl);
+			serio_interrupt(&i8042_kbd_port, data, dfl, regs);
 			continue;
 		}
 
@@ -408,7 +402,7 @@
 			if (index == 0xaa || index == 0xb6)
 				set_bit(index, i8042_unxlate_seen);
 			if (test_and_clear_bit(index, i8042_unxlate_seen)) {
-				serio_interrupt(&i8042_kbd_port, 0xf0, dfl);
+				serio_interrupt(&i8042_kbd_port, 0xf0, dfl, regs);
 				data = i8042_unxlate_table[data & 0x7f];
 			}
 		} else {
@@ -418,7 +412,7 @@
 
 		i8042_last_e0 = (data == 0xe0);
 
-		serio_interrupt(&i8042_kbd_port, data, dfl);
+		serio_interrupt(&i8042_kbd_port, data, dfl, regs);
 	}
 
 }
drivers/input/serio/parkbd.c +1 -1
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
@@ -136,7 +136,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);
+			serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
 	}
 
 	parkbd_last = jiffies;
drivers/input/serio/q40kbd.c +1 -2
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
@@ -69,8 +69,7 @@
 static void q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
-		if (q40kbd_port.dev)
-                         q40kbd_port.dev->interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0);
+		serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
 }
drivers/input/serio/rpckbd.c +1 -4
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
@@ -44,8 +44,6 @@
 MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-extern struct pt_regs *kbd_pt_regs;
-
 static int rpckbd_write(struct serio *port, unsigned char val)
 {
 	while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -60,12 +58,11 @@
 {
 	struct serio *port = dev_id;
 	unsigned int byte;
-	kbd_pt_regs = regs;
 
 	while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
 		byte = iomd_readb(IOMD_KARTRX);
 
-		serio_interrupt(port, byte, 0);
+		serio_interrupt(port, byte, 0, regs);
 	}
 }
 
drivers/input/serio/sa1111ps2.c +1 -5
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
@@ -24,8 +24,6 @@
 
 #include <asm/hardware/sa1111.h>
 
-extern struct pt_regs *kbd_pt_regs;
-
 struct ps2if {
 	struct serio		io;
 	struct sa1111_dev	*dev;
@@ -47,8 +45,6 @@
 	struct ps2if *ps2if = dev_id;
 	unsigned int scancode, flag, status;
 
-	kbd_pt_regs = regs;
-
 	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
 	while (status & PS2STAT_RXF) {
 		if (status & PS2STAT_STP)
@@ -62,7 +58,7 @@
 		if (hweight8(scancode) & 1)
 			flag ^= SERIO_PARITY;
 
-		serio_interrupt(&ps2if->io, scancode, flag);
+		serio_interrupt(&ps2if->io, scancode, flag, regs);
 
                	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
         }
drivers/input/serio/serio.c +2 -2
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
@@ -135,10 +135,10 @@
 	wake_up(&serio_wait);
 }
 
-void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {       
         if (serio->dev && serio->dev->interrupt) 
-                serio->dev->interrupt(serio, data, flags);
+                serio->dev->interrupt(serio, data, flags, regs);
 	else 
 		if (!flags)
 			serio_rescan(serio);
drivers/input/serio/serport.c +4 -1
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
@@ -114,6 +114,9 @@
  * serport_ldisc_receive() is called by the low level tty driver when characters
  * are ready for us. We forward the characters, one by one to the 'interrupt'
  * routine.
+ *
+ * FIXME: We should get pt_regs from the tty layer and forward them to
+ *	  serio_interrupt here.
  */
 
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
@@ -121,7 +124,7 @@
 	struct serport *serport = (struct serport*) tty->disc_data;
 	int i;
 	for (i = 0; i < count; i++)
-		serio_interrupt(&serport->serio, cp[i], 0);
+		serio_interrupt(&serport->serio, cp[i], 0, NULL);
 }
 
 /*
drivers/input/touchscreen/gunze.c +4 -3
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
@@ -60,7 +60,7 @@
 	char phys[32];
 };
 
-static void gunze_process_packet(struct gunze* gunze)
+static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
 {
 	struct input_dev *dev = &gunze->dev;
 
@@ -71,18 +71,19 @@
 		return;
 	}
 
+	input_regs(dev, regs);
 	input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10) * 4);
 	input_report_abs(dev, ABS_Y, 3072 - simple_strtoul(gunze->data + 6, NULL, 10) * 3);
 	input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T');
 	input_sync(dev);
 }
 
-static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct gunze* gunze = serio->private;
 
 	if (data == '\r') {
-		gunze_process_packet(gunze);
+		gunze_process_packet(gunze, regs);
 		gunze->idx = 0;
 	} else {
 		if (gunze->idx < GUNZE_MAX_LENGTH)
drivers/input/touchscreen/h3600_ts_input.c +5 -1
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
@@ -108,6 +108,7 @@
         int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
 
+	input_regs(dev, regs);
 	input_report_key(dev, KEY_ENTER, down);
 	input_sync(dev);
 }
@@ -121,6 +122,7 @@
 	 * This interrupt is only called when we release the key. So we have 
 	 * to fake a key press.
 	 */ 	
+	input_regs(dev, regs);
 	input_report_key(dev, KEY_SUSPEND, 1);
 	input_report_key(dev, KEY_SUSPEND, down); 	
 	input_sync(dev);
@@ -183,11 +185,13 @@
  * packets. Some packets coming from serial are not touchscreen related. In
  * this case we send them off to be processed elsewhere. 
  */
-static void h3600ts_process_packet(struct h3600_dev *ts)
+static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
         struct input_dev *dev = &ts->dev;
 	static int touched = 0;
 	int key, down = 0;
+
+	input_regs(dev, regs);
 
         switch (ts->event) {
                 /*
drivers/macintosh/adbhid.c +13 -9
diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
@@ -52,8 +52,6 @@
 #define KEYB_LEDREG	2	/* register # for leds on ADB keyboard */
 #define MOUSE_DATAREG	0	/* reg# for movement/button codes from mouse */
 
-extern struct pt_regs *kbd_pt_regs;
-
 static int adb_message_handler(struct notifier_block *, unsigned long, void *);
 static struct notifier_block adbhid_adb_notifier = {
 	.notifier_call	= adb_message_handler,
@@ -136,14 +134,13 @@
 	/* first check this is from register 0 */
 	if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
 		return;		/* ignore it */
-	kbd_pt_regs = regs;
-	adbhid_input_keycode(id, data[1], 0);
+	adbhid_input_keycode(id, data[1], 0, regs);
 	if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
-		adbhid_input_keycode(id, data[2], 0);
+		adbhid_input_keycode(id, data[2], 0, regs);
 }
 
 static void
-adbhid_input_keycode(int id, int keycode, int repeat)
+adbhid_input_keycode(int id, int keycode, int repeat, pt_regs *regs)
 {
 	int up_flag;
 
@@ -152,21 +149,24 @@
 
 	switch (keycode) {
 	case 0x39: /* Generate down/up events for CapsLock everytime. */
+		input_regs(&adbhid[id]->input, regs);
 		input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 1);
 		input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 0);
+		input_sync(&adbhid[id]->input);
 		return;
 	case 0x3f: /* ignore Powerbook Fn key */
 		return;
 	}
 
-	if (adbhid[id]->keycode[keycode])
+	if (adbhid[id]->keycode[keycode]) {
+		input_regs(&adbhid[id]->input, regs);
 		input_report_key(&adbhid[id]->input,
 				 adbhid[id]->keycode[keycode], !up_flag);
-	else
+		input_sync(&adbhid[id]->input);
+	} else
 		printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
 		       up_flag ? "released" : "pressed");
 
-	input_sync(&adbhid[id]->input);
 }
 
 static void
@@ -253,6 +253,8 @@
                 break;
 	}
 
+	input_regs(&adbhid[id]->input, regs);
+
 	input_report_key(&adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
 	input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
 
@@ -276,6 +278,8 @@
 		printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
 		return;
 	}
+
+	input_regs(&adbhid[id]->input, regs);
 
 	switch (adbhid[id]->original_handler_id) {
 	default:
drivers/serial/sunsu.c +2 -2
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
@@ -527,7 +527,7 @@
 			}
 			kbd_pt_regs = regs;
 #ifdef CONFIG_SERIO
-			serio_interrupt(&up->serio, ch, 0);
+			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);
@@ -541,7 +541,7 @@
 
 			case 0:
 #ifdef CONFIG_SERIO
-				serio_interrupt(&up->serio, ch, 0);
+				serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 				break;
 			};
drivers/serial/sunzilog.c +2 -2
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
@@ -303,7 +303,7 @@
 		}
 		kbd_pt_regs = regs;
 #ifdef CONFIG_SERIO
-		serio_interrupt(&up->serio, ch, 0);
+		serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 	} else if (ZS_IS_MOUSE(up)) {
 		int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -317,7 +317,7 @@
 
 		case 0:
 #ifdef CONFIG_SERIO
-			serio_interrupt(&up->serio, ch, 0);
+			serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 			break;
 		};
drivers/usb/input/aiptek.c +2 -0
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
@@ -155,6 +155,8 @@
 		dbg("received unknown report #%d", data[0]);
 	}
 
+	input_regs(dev, regs);
+
 	proximity = data[5] & 0x01;
 	input_report_key(dev, BTN_TOOL_PEN, proximity);
 
drivers/usb/input/hid-core.c +11 -11
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
@@ -773,13 +773,13 @@
 	return -1;
 }
 
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
+static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	hid_dump_input(usage, value);
 	if (hid->claimed & HID_CLAIMED_INPUT)
-		hidinput_hid_event(hid, field, usage, value);
+		hidinput_hid_event(hid, field, usage, value, regs);
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
-		hiddev_hid_event(hid, field, usage, value);
+		hiddev_hid_event(hid, field, usage, value, regs);
 }
 
 /*
@@ -788,7 +788,7 @@
  * reporting to the layer).
  */
 
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data)
+static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs)
 {
 	unsigned n;
 	unsigned count = field->report_count;
@@ -818,25 +818,25 @@
 			} else {
 				if (value[n] == field->value[n]) continue;
 			}	
-			hid_process_event(hid, field, &field->usage[n], value[n]);
+			hid_process_event(hid, field, &field->usage[n], value[n], regs);
 			continue;
 		}
 
 		if (field->value[n] >= min && field->value[n] <= max
 			&& field->usage[field->value[n] - min].hid
 			&& search(value, field->value[n], count))
-				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0);
+				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs);
 
 		if (value[n] >= min && value[n] <= max
 			&& field->usage[value[n] - min].hid
 			&& search(field->value, value[n], count))
-				hid_process_event(hid, field, &field->usage[value[n] - min], 1);
+				hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs);
 	}
 
 	memcpy(field->value, value, count * sizeof(__s32));
 }
 
-static int hid_input_report(int type, struct urb *urb)
+static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs)
 {
 	struct hid_device *hid = urb->context;
 	struct hid_report_enum *report_enum = hid->report_enum + type;
@@ -886,7 +886,7 @@
 		hiddev_report_event(hid, report);
 
 	for (n = 0; n < report->maxfield; n++)
-		hid_input_field(hid, report->field[n], data);
+		hid_input_field(hid, report->field[n], data, regs);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
@@ -905,7 +905,7 @@
 
 	switch (urb->status) {
 	case 0:			/* success */
-		hid_input_report(HID_INPUT_REPORT, urb);
+		hid_input_report(HID_INPUT_REPORT, urb, regs);
 		break;
 	case -ECONNRESET:	/* unlink */
 	case -ENOENT:
@@ -1130,7 +1130,7 @@
 	spin_lock_irqsave(&hid->ctrllock, flags);
 
 	if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) 
-		hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb);
+		hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs);
 
 	hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
drivers/usb/input/hid-input.c +3 -1
diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
@@ -380,10 +380,12 @@
 	}
 }
 
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
+void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	struct input_dev *input = &hid->input;
 	int *quirks = &hid->quirks;
+
+	input_regs(input, regs);
 
 	if (usage->hat_min != usage->hat_max) {
 		value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
drivers/usb/input/hid.h +2 -2
diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
@@ -420,13 +420,13 @@
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
+extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
 extern int hidinput_connect(struct hid_device *);
 extern void hidinput_disconnect(struct hid_device *);
 #else
 #define IS_INPUT_APPLICATION(a) (0)
-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
+static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
 static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
 static inline void hidinput_disconnect(struct hid_device *hid) { }
drivers/usb/input/hiddev.c +1 -1
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
@@ -180,7 +180,7 @@
  * the interrupt pipe
  */
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value)
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	unsigned type = field->report_type;
 	struct hiddev_usage_ref uref;
drivers/usb/input/powermate.c +1 -0
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
@@ -96,6 +96,7 @@
 	}
 
 	/* handle updates to device state */
+	input_regs(&pm->input, regs);
 	input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
 	input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
 	input_sync(&pm->input);
drivers/usb/input/usbkbd.c +2 -0
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
@@ -99,6 +99,8 @@
 		goto resubmit;
 	}
 
+	input_regs(&kbd->dev, regs);
+
 	for (i = 0; i < 8; i++)
 		input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 
drivers/usb/input/usbmouse.c +1 -0
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
@@ -76,6 +76,7 @@
 		goto resubmit;
 	}
 
+	input_regs(dev, regs);
 
 	input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
 	input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
drivers/usb/input/wacom.c +7 -0
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
@@ -129,6 +129,8 @@
 		dbg("received unknown report #%d", data[0]);
 
 	prox = data[1] & 0x40;
+
+	input_regs(dev, regs);
 	
 	input_report_key(dev, BTN_TOOL_PEN, prox);
 	
@@ -179,6 +181,7 @@
 		goto exit;
 	}
 
+	input_regs(dev, regs);
 	input_report_key(dev, BTN_TOOL_PEN, 1);
 	input_report_abs(dev, ABS_X, data[2] << 8 | data[1]);
 	input_report_abs(dev, ABS_Y, data[4] << 8 | data[3]);
@@ -223,6 +226,8 @@
 	x = data[2] | ((__u32)data[3] << 8);
 	y = data[4] | ((__u32)data[5] << 8);
 
+	input_regs(dev, regs);
+
 	switch ((data[1] >> 5) & 3) {
 
 		case 0:	/* Pen */
@@ -293,6 +298,8 @@
 
 	if (data[0] != 2)
 		dbg("received unknown report #%d", data[0]);
+
+	input_regs(dev, regs);
 
 	/* tool number */
 	idx = data[1] & 0x01;
drivers/usb/input/xpad.c +4 -2
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
@@ -124,9 +124,11 @@
  *	 http://euc.jp/periphs/xbox-controller.ja.html
  */
 
-static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
+static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &xpad->dev;
+
+	input_regs(dev, regs);
 	
 	/* left stick */
 	input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
@@ -183,7 +185,7 @@
 		goto exit;
 	}
 	
-	xpad_process_packet(xpad, 0, xpad->idata);
+	xpad_process_packet(xpad, 0, xpad->idata, regs);
 
 exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
include/asm-sparc/system.h +0 -2
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
@@ -62,8 +62,6 @@
 	return serial_console ? 0 : 1;
 }
 
-extern struct pt_regs *kbd_pt_regs;
-
 /* When a context switch happens we must flush all user windows so that
  * the windows of the current process are flushed onto its stack. This
  * way the windows are all clean for the next process and the stack
include/asm-sparc64/system.h +0 -2
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
@@ -131,8 +131,6 @@
 	return serial_console ? 0 : 1;
 }
 
-extern struct pt_regs *kbd_pt_regs;
-
 extern void synchronize_user_stack(void);
 
 extern void __flushw_user(void);
include/linux/hiddev.h +2 -2
diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
@@ -204,7 +204,7 @@
 int hiddev_connect(struct hid_device *);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value);
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs);
 void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
 int __init hiddev_init(void);
 void __exit hiddev_exit(void);
@@ -212,7 +212,7 @@
 static inline int hiddev_connect(struct hid_device *hid) { return -1; }
 static inline void hiddev_disconnect(struct hid_device *hid) { }
 static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value) { }
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
 static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hiddev_init(void) { return 0; }
 static inline void hiddev_exit(void) { }
include/linux/input.h +4 -1
diff -Nru a/include/linux/input.h b/include/linux/input.h
@@ -774,6 +774,7 @@
 	struct timer_list timer;
 
 	struct pm_dev *pm_dev;
+	struct pt_regs *regs;
 	int state;
 
 	int sync;
@@ -899,12 +900,14 @@
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 
-#define input_sync(a)		input_event(a, EV_SYN, SYN_REPORT, 0)
 #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
 #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
 #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
 #define input_report_ff(a,b,c)	input_event(a, EV_FF, b, c)
 #define input_report_ff_status(a,b,c)	input_event(a, EV_FF_STATUS, b, c)
+
+#define input_regs(a,b)		do { (a)->regs = (b); } while (0)
+#define input_sync(a)		do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
 
 extern struct device_class input_devclass;
 
include/linux/serio.h +8 -3
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
@@ -10,10 +10,13 @@
  */
 
 #include <linux/ioctl.h>
-#include <linux/list.h>
 
 #define SPIOCSTYPE	_IOW('q', 0x01, unsigned long)
 
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+
 struct serio;
 
 struct serio {
@@ -47,7 +50,7 @@
 	char *name;
 
 	void (*write_wakeup)(struct serio *);
-	void (*interrupt)(struct serio *, unsigned char, unsigned int);
+	void (*interrupt)(struct serio *, unsigned char, unsigned int, struct pt_regs *);
 	void (*connect)(struct serio *, struct serio_dev *dev);
 	void (*disconnect)(struct serio *);
 	void (*cleanup)(struct serio *);
@@ -58,7 +61,7 @@
 int serio_open(struct serio *serio, struct serio_dev *dev);
 void serio_close(struct serio *serio);
 void serio_rescan(struct serio *serio);
-void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags);
+void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
 
 void serio_register_port(struct serio *serio);
 void serio_unregister_port(struct serio *serio);
@@ -84,6 +87,8 @@
 	if (serio->dev && serio->dev->cleanup)
 		serio->dev->cleanup(serio);
 }
+
+#endif
 
 /*
  * bit masks for use in "interrupt" flags (3rd argument)
#5 lore raw

PATCH 1/1 input: Support for NEC PC-9800 beeper and support for Kana Lock [6/14]

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

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

[email protected], 2003-02-12 10:49:26+01:00, [email protected]
input: Support for NEC PC-9800 beeper and support for Kana Lock LED.

 drivers/char/keyboard.c     |   12 ++---
 drivers/input/misc/98spkr.c |   95 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/input/misc/Kconfig  |    4 +
 drivers/input/misc/Makefile |    1 
 include/linux/kbd_kern.h    |    5 +-
 include/linux/keyboard.h    |    1 
 6 files changed, 110 insertions(+), 8 deletions(-)

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

drivers/char/keyboard.c +6 -6
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
@@ -48,21 +48,21 @@
  * Exported functions/variables
  */
 
-#ifndef KBD_DEFMODE
 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
-#endif
 
-#ifndef KBD_DEFLEDS
 /*
  * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off.
+ * This seems a good reason to start with NumLock off. On PC9800 however there
+ * is no NumLock key and everyone expects the keypad to be used for numbers.
  */
+
+#ifdef CONFIG_X86_PC9800
+#define KBD_DEFLEDS (1 << VC_NUMLOCK)
+#else
 #define KBD_DEFLEDS 0
 #endif
 
-#ifndef KBD_DEFLOCK
 #define KBD_DEFLOCK 0
-#endif
 
 void compute_shiftstate(void);
 
drivers/input/misc/98spkr.c new file +95 -0

95 lines not on this page · raw message

drivers/input/misc/Kconfig +4 -0
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
@@ -44,6 +44,10 @@
 	tristate "M68k Beeper support"
 	depends on M68K && INPUT && INPUT_MISC
 
+config INPUT_98SPKR
+	tristate "PC-9800 Speaker support"
+	depends on X86_PC9800 && INPUT && INPUT_MISC
+
 config INPUT_UINPUT
 	tristate "User level driver support"
 	depends on INPUT && INPUT_MISC
drivers/input/misc/Makefile +1 -0
diff -Nru a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
@@ -7,5 +7,6 @@
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
+obj-$(CONFIG_INPUT_98SPKR)		+= 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_GSC)			+= gsc_ps2.o
include/linux/kbd_kern.h +3 -2
diff -Nru a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
@@ -43,11 +43,12 @@
 #define LED_SHOW_IOCTL 1        /* only change leds upon ioctl */
 #define LED_SHOW_MEM 2          /* `heartbeat': peek into memory */
 
-	unsigned char ledflagstate:3;	/* flags, not lights */
-	unsigned char default_ledflagstate:3;
+	unsigned char ledflagstate:4;	/* flags, not lights */
+	unsigned char default_ledflagstate:4;
 #define VC_SCROLLOCK	0	/* scroll-lock mode */
 #define VC_NUMLOCK	1	/* numeric lock mode */
 #define VC_CAPSLOCK	2	/* capslock mode */
+#define VC_KANALOCK	3	/* kanalock mode */
 
 	unsigned char kbdmode:2;	/* one 2-bit value */
 #define VC_XLATE	0	/* translate keycodes using keymap */
include/linux/keyboard.h +1 -0
diff -Nru a/include/linux/keyboard.h b/include/linux/keyboard.h
@@ -9,6 +9,7 @@
 #define KG_ALT		3
 #define KG_ALTGR	1
 #define KG_SHIFTL	4
+#define KG_KANASHIFT	4
 #define KG_SHIFTR	5
 #define KG_CTRLL	6
 #define KG_CTRLR	7
#6 lore raw

PATCH 1/1 input: HID update [7/14]

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

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

[email protected], 2003-02-12 10:55:13+01:00, [email protected]
input: HID update
- Fix a bad #define for HID_QUIRK_BADPAD
- Set absfuzz and absflat for joysticks/gamepads only
- Add TangTop quirk

 hid-core.c  |    6 ++++++
 hid-input.c |    9 +++++++--
 hid.h       |    2 +-
 3 files changed, 14 insertions(+), 3 deletions(-)

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

drivers/usb/input/hid-core.c +6 -0
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
@@ -1327,6 +1327,9 @@
 #define USB_VENDOR_ID_ONTRAK		0x0a07
 #define USB_DEVICE_ID_ONTRAK_ADU100	0x0064
 
+#define USB_VENDOR_ID_TANGTOP          0x0d3d
+#define USB_DEVICE_ID_TANGTOP_USBPS2   0x0001
+
 struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1368,6 +1371,7 @@
 	{ 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_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 	{ 0, 0 }
 };
 
@@ -1533,6 +1537,8 @@
 	kfree(buf);
 
 	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
+	if (!hid->urbctrl)
+		goto fail;
 	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
 			     hid->ctrlbuf, 1, hid_ctrl, hid);
 	hid->urbctrl->setup_dma = hid->cr_dma;
drivers/usb/input/hid-input.c +7 -2
diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
@@ -364,8 +364,13 @@
 		
 		input->absmin[usage->code] = a;
 		input->absmax[usage->code] = b;
-		input->absfuzz[usage->code] = (b - a) >> 8;
-		input->absflat[usage->code] = (b - a) >> 4;
+		input->absfuzz[usage->code] = 0;
+		input->absflat[usage->code] = 0;
+
+		if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) {
+			input->absfuzz[usage->code] = (b - a) >> 8;
+			input->absflat[usage->code] = (b - a) >> 4;
+		}
 	}
 
 	if (usage->hat_min != usage->hat_max) {
drivers/usb/input/hid.h +1 -1
diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
@@ -206,7 +206,7 @@
 #define HID_QUIRK_IGNORE	0x04
 #define HID_QUIRK_NOGET		0x08
 #define HID_QUIRK_HIDDEV	0x10
-#define HID_QUIRK_BADPAD        0x12
+#define HID_QUIRK_BADPAD        0x20
 
 /*
  * This is the global enviroment of the parser. This information is
#7 lore raw

PATCH 1/1 input: joydev/mousedev update [8/14]

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

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

[email protected], 2003-02-12 11:02:12+01:00, [email protected]
input.c: joydev/mousedev update
- relax requirements on devices, joydev now allows joysticks without buttons to work with throttles and pedals, mousedev allows a separate mouse wheel
- remove a stray semicolon in joydev

 joydev.c   |   17 +++++++++--------
 mousedev.c |    6 +++++-
 2 files changed, 14 insertions(+), 9 deletions(-)

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

drivers/input/joydev.c +9 -8
diff -Nru a/drivers/input/joydev.c b/drivers/input/joydev.c
@@ -340,7 +340,7 @@
 		case JSIOCSBTNMAP:
 			if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
 				return -EFAULT;
-			for (i = 0; i < joydev->nkey; i++); {
+			for (i = 0; i < joydev->nkey; i++) {
 				if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
 				joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
 			}
@@ -377,7 +377,8 @@
 	struct joydev *joydev;
 	int i, j, t, minor;
 
-        if (test_bit(BTN_TOUCH, dev->keybit))
+	/* Avoid tablets */
+        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return NULL;
 
 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@@ -463,18 +464,18 @@
 
 static struct input_device_id joydev_ids[] = {
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_X) },
 	},
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_WHEEL) },
 	},
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_THROTTLE) },
 	},
 	{ }, 	/* Terminating entry */
drivers/input/mousedev.c +5 -1
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
@@ -454,7 +454,11 @@
 		.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
 		.relbit = { BIT(REL_X) | BIT(REL_Y) },
 	},	/* A mouse like device, at least one button, two relative axes */
-
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
+		.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
+		.relbit = { BIT(REL_WHEEL) },
+	},	/* A separate scrollwheel */
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
 		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
#8 lore raw

PATCH 1/1 input: Give preferential treatment to gameport at 0x201 [9/14]

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

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

[email protected], 2003-02-12 11:03:11+01:00, [email protected]
input: Give preferential treatment to gameport at 0x201, and use
the odd addresses for access.

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

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

drivers/input/gameport/ns558.c +4 -4
diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
@@ -46,7 +46,7 @@
 #define NS558_ISA	1
 #define NS558_PNP	2
 
-static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209,
+static int ns558_isa_portlist[] = { 0x201, 0x200, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209,
 				    0x20b, 0x20c, 0x20e, 0x20f, 0x211, 0x219, 0x101, 0 };
 
 struct ns558 {
@@ -140,7 +140,7 @@
 	
 	port->type = NS558_ISA;
 	port->size = (1 << i);
-	port->gameport.io = io & (-1 << i);
+	port->gameport.io = io;
 	port->gameport.phys = port->phys;
 	port->gameport.name = port->name;
 	port->gameport.id.bustype = BUS_ISA;
@@ -148,7 +148,7 @@
 	sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i));
 	sprintf(port->name, "NS558 ISA");
 
-	request_region(port->gameport.io, (1 << i), "ns558-isa");
+	request_region(io & (-1 << i), (1 << i), "ns558-isa");
 
 	gameport_register_port(&port->gameport);
 
@@ -275,7 +275,7 @@
 				/* fall through */
 #endif
 			case NS558_ISA:
-				release_region(port->gameport.io, port->size);
+				release_region(port->gameport.io & ~(port->size - 1), port->size);
 				break;
 		
 			default:
#9 lore raw

PATCH 1/1 input: Add support for ThrustMaster ForceFeedback [10/14]

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

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

[email protected], 2003-02-12 11:05:06+01:00, [email protected]
input: Add support for ThrustMaster ForceFeedback USB HID devices.

 Kconfig      |   12 +
 Makefile     |    3 
 fixp-arith.h |   12 -
 hid-ff.c     |    4 
 hid-tmff.c   |  461 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 484 insertions(+), 8 deletions(-)

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

drivers/usb/input/Kconfig +10 -2
diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
@@ -49,7 +49,7 @@
 	  If unsure, say N.
 
 config HID_PID
-	bool "PID Devices"
+	bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
 	depends on HID_FF
 	help
 	  Say Y here if you have a PID-compliant joystick and wish to enable force
@@ -67,6 +67,15 @@
 	  Note: if you say N here, this device will still be supported, but without
 	  force feedback.
 
+config THRUSTMASTER_FF
+	bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
+	depends on HID_FF && EXPERIMENTAL
+	help
+	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
+	  and want to enable force feedback support for it.
+	  Note: if you say N here, this device will still be supported, but without
+	  force feedback.
+
 config USB_HIDDEV
 	bool "/dev/hiddev raw HID device support"
 	depends on USB_HID
@@ -80,7 +89,6 @@
 	  This driver requires CONFIG_USB_HID.
 
 	  If unsure, say Y.
-
 
 menu "USB HID Boot Protocol drivers"
 	depends on USB!=n && USB_HID!=y
drivers/usb/input/Makefile +3 -0
diff -Nru a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
@@ -19,6 +19,9 @@
 ifeq ($(CONFIG_LOGITECH_FF),y)
 	hid-objs	+= hid-lgff.o
 endif
+ifeq ($(CONFIG_THRUSTMASTER_FF),y)
+	hid-objs	+= hid-tmff.o
+endif
 ifeq ($(CONFIG_HID_FF),y)
 	hid-objs	+= hid-ff.o
 endif
drivers/usb/input/fixp-arith.h +6 -6
diff -Nru a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h
@@ -38,7 +38,7 @@
 #define FRAC_MASK ((1<<FRAC_N)-1)
 
 // Not to be used directly. Use fixp_{cos,sin}
-fixp_t cos_table[45] = {
+static fixp_t cos_table[45] = {
 	0x0100,	0x00FF,	0x00FF,	0x00FE,	0x00FD,	0x00FC,	0x00FA,	0x00F8,
 	0x00F6,	0x00F3,	0x00F0,	0x00ED,	0x00E9,	0x00E6,	0x00E2,	0x00DD,
 	0x00D9,	0x00D4,	0x00CF,	0x00C9,	0x00C4,	0x00BE,	0x00B8,	0x00B1,
@@ -49,7 +49,7 @@
 
 
 /* a: 123 -> 123.0 */
-inline fixp_t fixp_new(s16 a)
+static inline fixp_t fixp_new(s16 a)
 {
 	return a<<FRAC_N;
 }
@@ -58,12 +58,12 @@
       0x8000 -> 1.0
       0x0000 -> 0.0
 */
-inline fixp_t fixp_new16(s16 a)
+static inline fixp_t fixp_new16(s16 a)
 {
 	return ((s32)a)>>(16-FRAC_N);
 }
 
-inline fixp_t fixp_cos(unsigned int degrees)
+static inline fixp_t fixp_cos(unsigned int degrees)
 {
 	int quadrant = (degrees / 90) & 3;
 	unsigned int i = degrees % 90;
@@ -77,12 +77,12 @@
 	return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
 }
 
-inline fixp_t fixp_sin(unsigned int degrees)
+static inline fixp_t fixp_sin(unsigned int degrees)
 {
 	return -fixp_cos(degrees + 90);
 }
 
-inline fixp_t fixp_mult(fixp_t a, fixp_t b)
+static inline fixp_t fixp_mult(fixp_t a, fixp_t b)
 {
 	return ((s32)(a*b))>>FRAC_N;
 }
drivers/usb/input/hid-ff.c +4 -0
diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
@@ -38,6 +38,7 @@
 extern int hid_lgff_init(struct hid_device* hid);
 extern int hid_lg3d_init(struct hid_device* hid);
 extern int hid_pid_init(struct hid_device* hid);
+extern int hid_tmff_init(struct hid_device* hid);
 
 /*
  * This table contains pointers to initializers. To add support for new
@@ -56,6 +57,9 @@
 #endif
 #ifdef CONFIG_HID_PID
 	{0x45e, 0x001b, hid_pid_init},
+#endif
+#ifdef CONFIG_THRUSTMASTER_FF
+	{0x44f, 0xb304, hid_tmff_init},
 #endif
 	{0, 0, NULL} /* Terminating entry */
 };
drivers/usb/input/hid-tmff.c new file +461 -0

461 lines not on this page · raw message

#10 lore raw

PATCH 1/1 input: PowerMate driver update [11/14]

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

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

[email protected], 2003-02-12 11:06:34+01:00, [email protected]
input: PowerMate driver update
- work around an undocumented firmware bug
- fix handling of LED brightness

 powermate.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

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

drivers/usb/input/powermate.c +14 -10
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
@@ -1,9 +1,9 @@
 /*
  * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial.
  *
- * v1.0, (c)2002 William R Sowerbutts <[email protected]>
+ * v1.1, (c)2002 William R Sowerbutts <[email protected]>
  *
- * This device is a stainless steel knob which connects over USB. It can measure
+ * This device is a anodised aluminium knob which connects over USB. It can measure
  * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with
  * a spring for automatic release. The base contains a pair of LEDs which illuminate
  * the translucent base. It rotates without limit and reports its relative rotation
@@ -15,13 +15,17 @@
  * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
  * the host. If it counts more than 7 clicks before it is polled, it will wrap back
  * to zero and start counting again. This was at quite high speed, however, almost
- * certainly faster than the human hand could turn it.
+ * certainly faster than the human hand could turn it. Griffin say that it loses a
+ * pulse or two on a direction change; the granularity is so fine that I never
+ * noticed this in practice.
  *
  * The device's microcontroller can be programmed to set the LED to either a constant
  * intensity, or to a rhythmic pulsing. Several patterns and speeds are available.
  *
  * Griffin were very happy to provide documentation and free hardware for development.
  *
+ * Some userspace tools are available on the web: http://sowerbutts.com/powermate/
+ *
  */
 
 #include <linux/kernel.h>
@@ -116,11 +120,7 @@
 	if (pm->config->status == -EINPROGRESS) 
 		return; /* an update is already in progress; it'll issue this update when it completes */
 
-	if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
-		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
-		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
-		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
-	}else if (pm->requires_update & UPDATE_PULSE_ASLEEP){
+	if (pm->requires_update & UPDATE_PULSE_ASLEEP){
 		pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP );
 		pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 );
 		pm->requires_update &= ~UPDATE_PULSE_ASLEEP;
@@ -160,6 +160,10 @@
 		pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
 		pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
 		pm->requires_update &= ~UPDATE_PULSE_MODE;
+	}else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
+		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
+		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
+		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
 	}else{
 		printk(KERN_ERR "powermate: unknown update required");
 		pm->requires_update = 0; /* fudge the bug */
@@ -220,11 +224,11 @@
 	}
 	if (pulse_asleep != pm->pulse_asleep){
 		pm->pulse_asleep = pulse_asleep;
-		pm->requires_update |= UPDATE_PULSE_ASLEEP;
+		pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
 	}
 	if (pulse_awake != pm->pulse_awake){
 		pm->pulse_awake = pulse_awake;
-		pm->requires_update |= UPDATE_PULSE_AWAKE;
+		pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
 	}
 	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
 		pm->pulse_speed = pulse_speed;
#11 lore raw

PATCH 1/1 input: Resurrect usb_set_report for Aiptek and Wacom tablets [12/14]

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

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

[email protected], 2003-02-12 11:07:29+01:00, [email protected]
input: Resurrect usb_set_report for Aiptek and Wacom tablets.

 aiptek.c |   29 +++++++++++++++++------------
 wacom.c  |   14 ++++++++++++--
 2 files changed, 29 insertions(+), 14 deletions(-)

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

drivers/usb/input/aiptek.c +17 -12
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
@@ -224,13 +224,18 @@
 		usb_unlink_urb(aiptek->irq);
 }
 
-/* 
- * FIXME, either remove this call, or talk the maintainer into 
- * adding usb_set_report back into the core.
- */
-#if 0
+#define USB_REQ_SET_REPORT	0x09
+static int
+usb_set_report(struct usb_device *dev, struct usb_host_interface *inter, unsigned char type,
+		unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		(type << 8) + id, inter->desc.bInterfaceNumber, buf, size, HZ);
+}
+
 static void
-aiptek_command(struct usb_device *dev, unsigned int ifnum,
+aiptek_command(struct usb_device *dev, struct usb_host_interface *inter,
 	       unsigned char command, unsigned char data)
 {
 	__u8 buf[3];
@@ -239,17 +244,17 @@
 	buf[1] = command;
 	buf[2] = data;
 
-	if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) {
+	if (usb_set_report(dev, inter, 3, 2, buf, 3) != 3) {
 		dbg("aiptek_command: 0x%x 0x%x\n", command, data);
 	}
 }
-#endif
 
 static int 
 aiptek_probe(struct usb_interface *intf,
 	     const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev (intf);
+	struct usb_host_interface *interface = intf->altsetting + 0;
 	struct usb_endpoint_descriptor *endpoint;
 	struct aiptek *aiptek;
 
@@ -271,11 +276,11 @@
 		return -ENOMEM;
 	}
 
-	// Resolution500LPI
-//	aiptek_command(dev, ifnum, 0x18, 0x04);
+	/* Resolution500LPI */
+	aiptek_command(dev, interface, 0x18, 0x04);
 
-	// SwitchToTablet
-//	aiptek_command(dev, ifnum, 0x10, 0x01);
+	/* SwitchToTablet */
+	aiptek_command(dev, interface, 0x10, 0x01);
 
 	aiptek->features = aiptek_features + id->driver_info;
 
drivers/usb/input/wacom.c +12 -2
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
@@ -102,6 +102,17 @@
 	char phys[32];
 };
 
+#define USB_REQ_SET_REPORT	0x09
+static int usb_set_report(struct usb_interface *intf, unsigned char type,
+				unsigned char id, void *buf, int size)
+{
+        return usb_control_msg(interface_to_usbdev(intf),
+		usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+                USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
+		buf, size, HZ);
+}
+
 static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
@@ -488,6 +499,7 @@
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_endpoint_descriptor *endpoint;
+	char rep_data[2] = {0x02, 0x02};
 	struct wacom *wacom;
 	char path[64];
 
@@ -582,11 +594,9 @@
 
 	input_register_device(&wacom->dev);
 
-#if 0	/* Missing usb_set_report() */
 	usb_set_report(intf, 3, 2, rep_data, 2);
 	usb_set_report(intf, 3, 5, rep_data, 0);
 	usb_set_report(intf, 3, 6, rep_data, 0);
-#endif
 
 	printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
 
#12 lore raw

PATCH 1/1 input: Add two new serio type #defines [13/14]

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

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

[email protected], 2003-02-12 11:08:24+01:00, [email protected]
input: Add two new serio type #defines

 serio.h |    2 ++
 1 files changed, 2 insertions(+)

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

include/linux/serio.h +2 -0
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
@@ -127,6 +127,8 @@
 #define SERIO_TWIDKBD	0x23
 #define SERIO_TWIDJOY	0x24
 #define SERIO_HIL	0x25
+#define SERIO_SNES232	0x26
+#define SERIO_SEMTECH	0x27
 
 #define SERIO_ID	0xff00UL
 #define SERIO_EXTRA	0xff0000UL
#13 lore raw

PATCH 1/1 input: sunkbd.c - fix reading beyond end of keycode array [14/14]

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

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

[email protected], 2003-02-12 11:09:03+01:00, [email protected]
input: sunkbd.c - fix reading beyond end of keycode array.

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

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

drivers/input/keyboard/sunkbd.c +1 -1
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
@@ -268,7 +268,7 @@
 	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
 
 	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
-	for (i = 0; i < 255; i++)
+	for (i = 0; i < 127; i++)
 		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
 	clear_bit(0, sunkbd->dev.keybit);
 
#14 lore raw

Re: [patch] input: sunkbd.c - fix reading beyond end of keycode array [14/14]

On Wed, 12 Feb 2003 12:07:57 +0100
Vojtech Pavlik <[email protected]> wrote:

| diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
| --- a/drivers/input/keyboard/sunkbd.c	Wed Feb 12 11:56:22 2003
| +++ b/drivers/input/keyboard/sunkbd.c	Wed Feb 12 11:56:22 2003
| @@ -268,7 +268,7 @@
|  	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
|  
|  	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
| -	for (i = 0; i < 255; i++)
| +	for (i = 0; i < 127; i++)
|  		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
|  	clear_bit(0, sunkbd->dev.keybit);
|  

If sunkbd has a valid keycode 127, that new loop test won't handle it, so it should/could be:
| + for (i = 0; i < 128; i++)

--
~Randy

#15 lore raw

Re: [patch] input: sunkbd.c - fix reading beyond end of keycode array [14/14]

Quoted 17 lines · Randy.Dunlap

On Wed, 12 Feb 2003 12:07:57 +0100
Vojtech Pavlik <[email protected]> wrote:

| diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
| --- a/drivers/input/keyboard/sunkbd.c	Wed Feb 12 11:56:22 2003
| +++ b/drivers/input/keyboard/sunkbd.c	Wed Feb 12 11:56:22 2003
| @@ -268,7 +268,7 @@
|  	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
|  
|  	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
| -	for (i = 0; i < 255; i++)
| +	for (i = 0; i < 127; i++)
|  		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
|  	clear_bit(0, sunkbd->dev.keybit);
|  
Quoted 3 lines

If sunkbd has a valid keycode 127, that new loop test won't handle it, so it should/could be:
| + for (i = 0; i < 128; i++)

You're right. It doesn't, though.

Signature · 2 lines
Vojtech Pavlik
SuSE Labs
#16 lore raw

Re: [patch] input: Get rid of kbd_pt_regs [5/14]

In reply to Vojtech Pavlik

One idea about kbd_pt_regs. Only one function, fn_show_ptregs, uses kbd_pt_regs. Instaed of passing reg data around wouldn't be better to just remove fn_show_ptregs from the FN_HANDLERS and call it independently inside of kbd_keycode instead.

#17 lore raw

Re: [patch] input: Get rid of kbd_pt_regs [5/14]

Quoted 4 lines · James Simmons

One idea about kbd_pt_regs. Only one function, fn_show_ptregs, uses kbd_pt_regs. Instaed of passing reg data around wouldn't be better to just remove fn_show_ptregs from the FN_HANDLERS and call it independently inside of kbd_keycode instead.

I'm not sure if that's really a nicer solution.

Signature · 2 lines
Vojtech Pavlik
SuSE Labs
#18 lore raw

Re: [patch] input: Get rid of kbd_pt_regs [5/14]

Quoted 7 lines
Quoted 5 lines

One idea about kbd_pt_regs. Only one function, fn_show_ptregs, uses kbd_pt_regs. Instaed of passing reg data around wouldn't be better to just remove fn_show_ptregs from the FN_HANDLERS and call it independently inside of kbd_keycode instead.

I'm not sure if that's really a nicer solution.

Actually why do we have this function in keyboard.c when we have sysrq_handle_showregs in sysrq.c? Both do the same thing.

#19 lore raw

Re: [patch] input: Get rid of kbd_pt_regs [5/14]

Quoted 3 lines · James Simmons

Actually why do we have this function in keyboard.c when we have sysrq_handle_showregs in sysrq.c? Both do the same thing.

Because I still use the old approach, and I want that keyboard thing to work on all kernels, regardless of whether they have sysrq compiled in or not.

Linus