[Solved] Strange reboot when testing PS/2 mouse driver
Posted: Wed Apr 04, 2007 11:26 am
Ok, so I wrote a better keyboard/mouse driver..
The first problem was that if driver does proper init on keyboard, my computer's BIOS thinks it should disable USB legacy support..
Fine.
So I plug my keyboard (and mouse) into the PS/2 port, and try again... BANG. Reboot. Unplugging the PS/2 mouse, everything works fine (once the mouse driver timeouts, which takes a while), but ... like... why does it reboot?
Once again, this obvious works in Bochs. And I suspect it's not a tripple-fault, because there isn't much of anything that could cause CPU exceptions in the code.. so obviously my system thinks it's time to reboot...
Can anybody spot anything strange/invalid/not-good-idea in this code:
The macros relevant are KBD_write_cmd (write to controller), KBD_write_aux (write to aux by prefixing), KBD_read (read from 0x60) and KBD_wait_ack (poll for ACK).
All return -1 on error..
This is the first reboot problem I've had for a while (I get panic's all the time, but almost never any reboots) I'm fairly sure it's the driver code upsetting my mobo somehow..
The first problem was that if driver does proper init on keyboard, my computer's BIOS thinks it should disable USB legacy support..
Fine.
So I plug my keyboard (and mouse) into the PS/2 port, and try again... BANG. Reboot. Unplugging the PS/2 mouse, everything works fine (once the mouse driver timeouts, which takes a while), but ... like... why does it reboot?
Once again, this obvious works in Bochs. And I suspect it's not a tripple-fault, because there isn't much of anything that could cause CPU exceptions in the code.. so obviously my system thinks it's time to reboot...
Can anybody spot anything strange/invalid/not-good-idea in this code:
Code: Select all
static int console_mouse_init() {
printk(" - PS/2 mouse: enable");
// enable PS/2 mouse
if(KBD_write_cmd(0xE8)) return -1;
printk(" interface");
// enable it's interrupt reporting
{
// fetch command word
if(KBD_write_cmd(0x20)) return -1;
int cb = KBD_read();
if(cb < 0) return -1;
// set bit1 (aux interrupt),
// clear bit5 (aux clock inhibit)
// store the resulting new command word
if(KBD_write_cmd(0x60)) return -1;
if(KBD_write((cb |= 0x2) & ~0x20)) return -1;
}
printk(" defaults");
// Send set defaults
if(KBD_write_aux(0xF6) || KBD_wait_ack()) return -1;
printk(" data");
// Enable data reporting
if(KBD_write_aux(0xF4) || KBD_wait_ack()) return -1;
// TODO: detect IMPS/2, with or without 5 buttons
console_mouse_imps2 = 0;
printk(".\n");
return 0;
}
All return -1 on error..
Code: Select all
int KBD_wait_write() {
unsigned int timeout = 100000;
unsigned char c;
while(--timeout) {
c = in8_p(0x64);
if(!(c & 2)) {
return 0;
}
}
return -1;
}
int KBD_write(unsigned char byte) {
if(!KBD_wait_write()) {
out8_p(0x60, byte);
return 0;
}
else return -1;
}
int KBD_write_cmd(unsigned char byte) {
if(!KBD_wait_write()) {
out8_p(0x64, byte);
return 0;
}
else return -1;
}
int KBD_write_aux(unsigned char byte) {
if(KBD_write_cmd(0xD4) || KBD_write(byte)) return -1;
else return 0;
}
// return unsigned char if success, -1 if fails
int KBD_read() {
unsigned int timeout = 100000;
unsigned char c;
while(--timeout) {
c = in8_p(0x64);
if(c & 1) {
c = in8_p(0x60);
return (unsigned) c;
}
}
return -1;
}
int KBD_wait_ack() {
unsigned int timeout = 100000;
while(--timeout) {
unsigned char c = KBD_read();
if(c == 0xFA) return 0; // got ack, we're happy
if(!c) {
// if we get 0, spend some time and retry
int i;
for(i = 0; i < 1000; i++) iodelay();
continue;
} else {
printk("console_input: 0x%2x while expecting ACK\n", c);
return -1;
}
}
return -1;
}