Hi Kent,

On 14/01/13(Mon) 10:05, Kent Fritz wrote:
> On Fri, Jan 11, 2013 at 5:29 PM, Stefan Sperling <s...@openbsd.org> wrote:
> > I see. So this is happening during pms_probe() which runs before the
> > protocol is selected. Maybe fix it like this? I think the code should
> > cope with hardware that returns unrecognizable garbage. But I don't
> > know very much about PS/2.
> >
> > Thanks for pinning down the problem!
> >
> > Index: pckbc.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/ic/pckbc.c,v
> > retrieving revision 1.31
> > diff -u -p -r1.31 pckbc.c
> > --- pckbc.c     17 Oct 2012 19:16:10 -0000      1.31
> > +++ pckbc.c     12 Jan 2013 01:25:41 -0000
> > @@ -620,6 +620,11 @@ pckbc_poll_cmd1(struct pckbc_internal *t
> >  #ifdef PCKBCDEBUG
> >                 printf("pckbc_cmd: lost 0x%x\n", c);
> >  #endif
> > +               /* Don't retry cmd forever. */
> > +               if (cmd->retries++ >= 5) {
> > +                       cmd->status = EIO;
> > +                       return;
> > +               }
> >         }
> >
> >         while (cmd->responseidx < cmd->responselen) {
> 
> That patch works fine.  Tested on i386 on nT-i1250.  Thanks for
> pointing me in the right direction!

Could you try the diff below and tell me if it also fix your problem? I
believe it's better to handle the bat failure core (0xfc) like we
already do with the bat completion code rather than exiting for any
value..

M.

Index: pckbc.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ic/pckbc.c,v
retrieving revision 1.31
diff -u -p -r1.31 pckbc.c
--- pckbc.c     17 Oct 2012 19:16:10 -0000      1.31
+++ pckbc.c     11 Feb 2013 10:24:49 -0000
@@ -48,6 +48,12 @@
 #include <dev/pckbc/pckbdvar.h>
 #endif
 
+#ifdef PCKBCDEBUG
+#define DPRINTF(x...)  do { printf(x); } while (0);
+#else
+#define DPRINTF(x...)
+#endif
+
 /* descriptor for one device command */
 struct pckbc_devcmd {
        TAILQ_ENTRY(pckbc_devcmd) next;
@@ -102,9 +108,10 @@ int pckbcintr_internal(struct pckbc_inte
 
 const char *pckbc_slot_names[] = { "kbd", "aux" };
 
-#define KBC_DEVCMD_ACK 0xfa
-#define KBC_DEVCMD_RESEND 0xfe
-#define KBC_DEVCMD_BAT 0xaa
+#define KBC_DEVCMD_ACK         0xfa
+#define KBC_DEVCMD_RESEND      0xfe
+#define KBC_DEVCMD_BAT_DONE    0xaa
+#define KBC_DEVCMD_BAT_FAIL    0xfc
 
 #define        KBD_DELAY       DELAY(8)
 
@@ -587,39 +594,32 @@ pckbc_poll_cmd1(struct pckbc_internal *t
                                break;
                }
 
-               if (c == KBC_DEVCMD_ACK) {
+               switch (c) {
+               case KBC_DEVCMD_ACK:
                        cmd->cmdidx++;
                        continue;
-               }
                /*
                 * Some legacy free PCs keep returning Basic Assurance Test
                 * (BAT) instead of something usable, so fail gracefully.
                 */
-               if (c == KBC_DEVCMD_RESEND || c == KBC_DEVCMD_BAT) {
-#ifdef PCKBCDEBUG
-                       printf("pckbc_cmd: %s\n",
+               case KBC_DEVCMD_RESEND:
+               case KBC_DEVCMD_BAT_DONE:
+               case KBC_DEVCMD_BAT_FAIL:
+                       DPRINTF("pckbc_cmd: %s\n",
                            c == KBC_DEVCMD_RESEND ? "RESEND": "BAT");
-#endif
                        if (cmd->retries++ < 5)
                                continue;
-                       else {
-#ifdef PCKBCDEBUG
-                               printf("pckbc: cmd failed\n");
-#endif
-                               cmd->status = ENXIO;
-                               return;
-                       }
-               }
-               if (c == -1) {
-#ifdef PCKBCDEBUG
-                       printf("pckbc_cmd: timeout\n");
-#endif
+
+                       DPRINTF("pckbc_cmd: cmd failed\n");
+                       cmd->status = ENXIO;
+                       return;
+               case -1:
+                       DPRINTF("pckbc_cmd: timeout\n");
                        cmd->status = EIO;
                        return;
+               default:
+                       DPRINTF("pckbc_cmd: lost 0x%x\n", c);
                }
-#ifdef PCKBCDEBUG
-               printf("pckbc_cmd: lost 0x%x\n", c);
-#endif
        }
 
        while (cmd->responseidx < cmd->responselen) {

Reply via email to