lkml.org 
[lkml]   [2003]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    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/
    \
     
     \ /
      Last update: 2005-03-22 13:33    [W:0.036 / U:29.804 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site