Messages in this thread Patch in this message | | | Date | Wed, 12 Feb 2003 11:59:54 +0100 | From | Vojtech Pavlik <> | Subject | [patch] 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
===================================================================
ChangeSet@1.1004, 2003-02-12 10:24:25+01:00, vojtech@suse.cz 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(-)
===================================================================
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c --- a/drivers/input/keyboard/atkbd.c Wed Feb 12 11:57:28 2003 +++ b/drivers/input/keyboard/atkbd.c Wed Feb 12 11:57:28 2003 @@ -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); } /* diff -Nru a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c --- a/drivers/input/mouse/psmouse.c Wed Feb 12 11:57:28 2003 +++ b/drivers/input/mouse/psmouse.c Wed Feb 12 11:57:28 2003 @@ -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; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |