Page 1 of 1
different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 9:27 am
by Bietje
Hi,
Until to now, my keyboard 'driver' worked fine. Now I hacked some keyboard led support code, and at first it seemed to work like a charm. On Bochs and 4 of the 5 computers I tested it on, it worked. On that particular PC (Acer aspire M7811, if you want to know) the leds didn't do anything. The led lights just kept in their standard bios setting (numlock on).
Now you may wonder, what code do you use?
This:
Code: Select all
#define OL_KBC_STATUS_REGISTER 0x64
#define OL_KBC_OUTPUT_BUFFER 0x60
#define OL_KBC_COMMAND_PORT 0x64
#define OL_KBC_DATA_PORT 0x60
static void
toggle_kb_leds(uint8_t status)
{
while((inb(OL_KBC_STATUS_REGISTER) & 0x2) != 0);
outb(OL_KBC_DATA_PORT, 0xed);
while((inb(OL_KBC_STATUS_REGISTER) & 0x2) != 0);
outb(OL_KBC_DATA_PORT, status);
}
I toggle the status byte according to the pressed key:
Code: Select all
#define OL_SCROLL_LED 0x1
#define OL_NUM_LED 0x2
#define OL_CAPS_LED 0x4
status ^= oneofabovedefs
That is pretty much it, I hope any of you has seen this before and/or knows how to fix it. Ohh yes, before I forgot, I did check the scan codes which came in on the not-working PC and they are correct and same as on any other PC. I have also tested with another keyboard, but that didn't fix anything either.
Greets,
Bietje
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 10:07 am
by jnc100
Is it a USB keyboard? If so then you may not have enabled usb keyboard support in that particular computer's bios or its emulation may not include support for changing the leds.
Regards,
John.
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 10:10 am
by Bietje
Hmm yes, it is an usb keyboard.. I'll dive into the bios..
edit: I don't see anything about the keyboard emulation.
Only if the usb controller should be enabled or not..
Are there any other method's of enabling keyboard leds (haven't found them on the wiki or around the forum yet..)
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 10:48 am
by jnc100
There is normally some option along the line of 'enable legacy USB [keyboard] support' which essentially emulates a PS/2 keyboard controller. Your code seems correct for setting the LEDs so I can only assume it is an issue with the PS/2 emulation in your bios on the new machine. Unfortunately the only other way of setting the LEDs (that I know of) is to write an entire USB stack and then use the functions in the HID specifications on
http://www.usb.org.
Regards,
John.
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 11:27 am
by Bietje
I have an option 'USB legacy support' which was already enabled... :/
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 11:55 am
by Brendan
Hi,
For PS/2 keyboards, the code seems fine if everything works as expected, but I wouldn't assume everything will always work as expected.
The correct way is to send the "SET LEDS" command (0xED), then wait for the keyboard to respond with "ACK". If the keyboard responds with "RESEND" then you have to send the "SET LEDS" command again (and maybe if you get "RESEND" 3 times in a row you should assume the keyboard doesn't support the command). If the keyboard responds with "RESEND" and you ignore it and send the data byte, then the keyboard will think the data byte is a new command (and if the data byte happens to correspond to a valid command then you get unexpected results).
Only if the keyboard responds with "ACK" should you send the data byte; and after sending the data byte you should wait for the keyboard to send "ACK" again (if the keyboard responds to the data byte with "RESEND" then I'd probably resend the "SET LEDS" command again). Of course you should probably also handle a "BAT" response at any step too (e.g. abort the current command and re-initialise the keyboard fully).
You'd also want time-outs everywhere. For example, the "while((inb(OL_KBC_STATUS_REGISTER) & 0x2) != 0);" should be replaced with something that won't lock up the computer forever if the "input buffer full" flag never becomes clear. Most people would have an "int send_byte(uint8_t byte)" function that handles the timeout (and returns an error if the byte wasn't sent).
For USB keyboards, the "PS/2 emulation" stuff in many BIOSs is seriously dodgy. At a minimum I'd disable this emulation (in any/all USB controllers) before attempting to detect if there's any real PS/2 devices connected to the real PS/2 controller (or doing anything else involving the PS/2 controller).
Cheers,
Brendan
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 12:01 pm
by Bietje
Thank you brendan, that cleared things up. I will search the wiki/internet for the "ack" and "respond" byte. I remember somewhere that the ack byte has a value of 0xfa.
Greets,
Bietje
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 12:41 pm
by Brendan
Hi,
Bietje wrote:Thank you brendan, that cleared things up. I will search the wiki/internet for the "ack" and "respond" byte. I remember somewhere that the ack byte has a value of 0xfa.
Taken from "ports.lst" (part of the full "Ralph Brown's Interrupt List" files):
Code: Select all
(Table P0390)
Values for keyboard special codes:
00h (MF2 in codeset2&3 or AT keyboards) keydetection/overrun error
00h (mouse) ID
AAh BAT completion code (sent after errorfree Basic Assurance Test)
ABh first byte of general MF2 keyboard ID
EEh Echo command return
F0h keyboard break code
FAh Acknowledge (all general commands except Resend and Echo)
FAh (mouse) Acknowledge (all commands except commands ECh,F2h,FFh)
FCh (MF2) BAT Failure Code (error in second half of the power on self test)
FDh (AT-keyboard) BAT Failure Code (error in the second half of the
power-on self test)
FEh Resend: CPU to controller should resend last keyboard-command
FEh (mouse) CPU to controller should resend last mouse-command
FFh (MF2 in codeset1) keydetection/overrun error
Note: keyboard stops scanning and waits for next command after returning
code FCh or FDh
SeeAlso: PORT 0060h-R
Note: Doing a PS/2 driver properly (e.g. including full initialisation, controller self testing, "PS/2 device" detection, etc) takes a surprising amount of work; and a lot of the information you'll find will be "half-assed" (e.g. making huge assumptions about the state the controller and any devices attached to it were left in, etc). To simplify things, I'd separate "controller source code" from "device source code", so that the code for a keyboard or mouse (or bar code scanner, or...) can rely on the "controller code" without caring about lower level details (e.g. IO ports, IRQs, etc). The controller itself is mostly a chip that handles one or two ("PS/2" and not RS232) serial ports (which is why I don't call it a "keyboard controller").
Cheers,
Brendan
Re: different behavior of the kbc (kb leds)
Posted: Sun Aug 14, 2011 5:38 pm
by Bietje
Thank you for the design tip about the ps/2 controller. I will certainly do something with it. I have actually already started to write a controller. Before I did that I tested out some things first. That PC doesn't seem to recognize the 0xed command or something. It just returns ALWAYS with the resend byte.
Now are it just the LED lights. So if I can't get them to work its not a drama at all, it will come at a much later stadium, when I have an USB stack.
Ohh, and by the way for those who search for this problem later.. this is also a nice reference for ps/2 controllers:
http://homepages.cwi.nl/~aeb/linux/kbd/scancodes.html