Return to BSD News archive
Newsgroups: comp.unix.bsd Path: sserve!manuel.anu.edu.au!munnari.oz.au!network.ucsd.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!rpi!newsserver.pixel.kodak.com!psinntp!psinntp!l5next!scotty From: scotty@gagetalker.com (Scott Turner) Subject: Yet another pass at pc_probe Message-ID: <1992Oct8.121604.809@gagetalker.com> Sender: scotty@gagetalker.com Organization: L5 Computing Date: Thu, 8 Oct 1992 12:16:04 GMT Lines: 91 OK, my '486 50MHz EISA system has a dirty secret, it has one of those chintzy keyboard controllers. After installing the beta patch kit I was left with an unbootable system (the wd patches had to be backed out.) but alas I had been a bad boy and not made a floppy... So rather than just use that DELAY() patch I decided to figure out what the hell was going on. The pc_probe code isn't reseting the a20. That is only done in the bootstrap. The probe code is just trying to reset the keyboard controller. Alas the original code uses general purpose routines for issuing the commands. These general purpose routines read the keyboard controller and return the value. Two things seem to go wrong, first, when reloading the keyboard commands it appears you aren't supposed to be reading the keyboard chip (at least with the chintzy chips :) and the while loop was kinda awkward since it ignored the value that came back from issuing the reset command. I know this is bad with chintzy chips because I was getting false "keyboard unplugged" messages on my screen with the DELAY() patch. And finally, the bootstrap code doesn't insist on a particular value be returned after the command is acknowledged. It just waits for the keyboard chip to have a value and then reads it. So without further delay I present my wack at pc_probe.c: *** pccons.c.orig Thu Oct 8 04:54:35 1992 --- pccons.c Thu Oct 8 04:55:05 1992 *************** *** 181,201 **** int again = 0; /* Enable interrupts and keyboard controller */ ! kbc_8042cmd(K_LDCMDBYTE); ! outb(KBOUTP, CMDBYTE); /* Start keyboard stuff RESET */ ! kbd_cmd(KBC_RESET); ! while((c = inb(KBDATAP)) != KBR_ACK) { if ((c == KBR_RESEND) || (c == KBR_OVERRUN)) { if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); - kbd_cmd(KBC_RESET); again = 1; } } /* pick up keyboard reset return code */ ! while((c = inb(KBDATAP)) != KBR_RSTDONE); return 1; } --- 169,189 ---- int again = 0; /* Enable interrupts and keyboard controller */ ! while (inb(KBSTATP)&KBS_IBF); outb(KBSTATP,K_LDCMDBYTE); ! while (inb(KBSTATP)&KBS_IBF); outb(KBDATAP,CMDBYTE); /* Start keyboard stuff RESET */ ! while((c = kbd_cmd(KBC_RESET)) != KBR_ACK) { if ((c == KBR_RESEND) || (c == KBR_OVERRUN)) { if(!again)printf("KEYBOARD disconnected: RECONNECT \n"); again = 1; } } /* pick up keyboard reset return code */ ! while (inb(KBSTATP)&KBS_IBF); ! (void) inb(KBDATAP); ! return 1; } Also, it's past 5am so I'm not going to touch it, but if I'm not mistaken the following line is also in error: if ((c == KBR_RESEND) || (c == KBR_OVERRUN)) { I think KBR_RESEND and KBR_OVERRUN #define's are the same. So either this test needs to be simplified, or one of the #define's is wrong. Scotty