aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-03-13 18:51:46 -0500
committerKevin O'Connor <kevin@koconnor.net>2010-03-13 18:51:46 -0500
commit6704cf9aa1f7e6bd7405044f222c23459d4b4d93 (patch)
tree49cc2d4267efdea92e112c2cd5eca1328900eeed
parent808939c17f603f3c7ad5abfb882cee55f636867b (diff)
downloadseabios-6704cf9aa1f7e6bd7405044f222c23459d4b4d93.tar.gz
Revert "Rework disabling of ps2 port irqs."
This reverts commit 6f702dd6987b22e9bce472fe61910392af17416a. That patch introduced a regression by enabling mouse interrupts by default. It also appears that disabling interrupts by software alone will not work well with some old DOS programs that hook the keyboard irq.
-rw-r--r--src/biosvar.h30
-rw-r--r--src/kbd.c26
-rw-r--r--src/mouse.c20
-rw-r--r--src/ps2port.c57
4 files changed, 68 insertions, 65 deletions
diff --git a/src/biosvar.h b/src/biosvar.h
index 808793d2..ea2d67d9 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -97,7 +97,7 @@ struct bios_data_area_s {
u8 floppy_media_state[4];
u8 floppy_track[2];
u8 kbd_flag2;
- u8 kbd_flag3;
+ u8 kbd_led;
struct segoff_s user_wait_complete_flag;
u32 user_wait_timeout;
// 40:A0
@@ -123,33 +123,6 @@ struct bios_data_area_s {
#define FMS_DOUBLE_STEPPING (1<<5)
#define FMS_DATA_RATE_MASK (0xc0)
-// Bit definitions for kbd_flag[0123]
-#define KF0_RSHIFT (1<<0)
-#define KF0_LSHIFT (1<<1)
-#define KF0_CTRLACTIVE (1<<2)
-#define KF0_ALTACTIVE (1<<3)
-#define KF0_SCROLLACTIVE (1<<4)
-#define KF0_NUMACTIVE (1<<5)
-#define KF0_CAPSACTIVE (1<<6)
-
-#define KF1_LCTRL (1<<0)
-#define KF1_LALT (1<<1)
-#define KF1_PAUSEACTIVE (1<<3)
-#define KF1_SCROLL (1<<4)
-#define KF1_NUM (1<<5)
-#define KF1_CAPS (1<<6)
-
-#define KF2_LAST_E1 (1<<0)
-#define KF2_LAST_E0 (1<<1)
-#define KF2_RCTRL (1<<2)
-#define KF2_RALT (1<<3)
-#define KF2_101KBD (1<<4)
-
-#define KF3_SCROLL_LED (1<<0)
-#define KF3_NUM_LED (1<<1)
-#define KF3_CAPS_LED (1<<2)
-#define KF3_CMD_PENDING (1<<6)
-
// Accessor functions
#define GET_BDA(var) \
GET_FARVAR(SEG_BDA, ((struct bios_data_area_s *)0)->var)
@@ -243,6 +216,7 @@ struct extended_bios_data_area_s {
u8 other2[0xC4];
// 0x121 - Begin custom storage.
+ u8 ps2ctr;
struct usbkeyinfo usbkey_last;
int RTCusers;
diff --git a/src/kbd.c b/src/kbd.c
index 44dce573..6f3ae15d 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -11,6 +11,28 @@
#include "bregs.h" // struct bregs
#include "ps2port.h" // kbd_command
+// Bit definitions for BDA kbd_flag[012]
+#define KF0_RSHIFT (1<<0)
+#define KF0_LSHIFT (1<<1)
+#define KF0_CTRLACTIVE (1<<2)
+#define KF0_ALTACTIVE (1<<3)
+#define KF0_SCROLLACTIVE (1<<4)
+#define KF0_NUMACTIVE (1<<5)
+#define KF0_CAPSACTIVE (1<<6)
+
+#define KF1_LCTRL (1<<0)
+#define KF1_LALT (1<<1)
+#define KF1_PAUSEACTIVE (1<<3)
+#define KF1_SCROLL (1<<4)
+#define KF1_NUM (1<<5)
+#define KF1_CAPS (1<<6)
+
+#define KF2_LAST_E1 (1<<0)
+#define KF2_LAST_E0 (1<<1)
+#define KF2_RCTRL (1<<2)
+#define KF2_RALT (1<<3)
+#define KF2_101KBD (1<<4)
+
void
kbd_setup(void)
{
@@ -201,7 +223,7 @@ static void
set_leds(void)
{
u8 shift_flags = (GET_BDA(kbd_flag0) >> 4) & 0x07;
- u8 kbd_led = GET_BDA(kbd_flag3);
+ u8 kbd_led = GET_BDA(kbd_led);
u8 led_flags = kbd_led & 0x07;
if (shift_flags == led_flags)
return;
@@ -211,7 +233,7 @@ set_leds(void)
// Error
return;
kbd_led = (kbd_led & ~0x07) | shift_flags;
- SET_BDA(kbd_flag3, kbd_led);
+ SET_BDA(kbd_led, kbd_led);
}
// INT 16h Keyboard Service Entry Point
diff --git a/src/mouse.c b/src/mouse.c
index 3004d786..8389d2a0 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -29,8 +29,13 @@ mouse_setup(void)
#define RET_ENOHANDLER 0x05
static int
-disable_mouse(void)
+disable_mouse(u16 ebda_seg)
{
+ u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
+ ps2ctr |= I8042_CTR_AUXDIS;
+ ps2ctr &= ~I8042_CTR_AUXINT;
+ SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);
+
return aux_command(PSMOUSE_CMD_DISABLE, NULL);
}
@@ -38,7 +43,8 @@ disable_mouse(void)
static void
mouse_15c20000(struct bregs *regs)
{
- int ret = disable_mouse();
+ u16 ebda_seg = get_ebda_seg();
+ int ret = disable_mouse(ebda_seg);
if (ret)
set_code_invalid(regs, RET_ENEEDRESEND);
else
@@ -49,12 +55,18 @@ mouse_15c20000(struct bregs *regs)
static void
mouse_15c20001(struct bregs *regs)
{
- u8 mouse_flags_2 = GET_EBDA(mouse_flag2);
+ u16 ebda_seg = get_ebda_seg();
+ u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
if ((mouse_flags_2 & 0x80) == 0) {
set_code_invalid(regs, RET_ENOHANDLER);
return;
}
+ u8 ps2ctr = GET_EBDA2(ebda_seg, ps2ctr);
+ ps2ctr &= ~I8042_CTR_AUXDIS;
+ ps2ctr |= I8042_CTR_AUXINT;
+ SET_EBDA2(ebda_seg, ps2ctr, ps2ctr);
+
int ret = aux_command(PSMOUSE_CMD_ENABLE, NULL);
if (ret)
set_code_invalid(regs, RET_ENEEDRESEND);
@@ -229,7 +241,7 @@ mouse_15c207(struct bregs *regs)
/* remove handler */
if ((mouse_flags_2 & 0x80) != 0) {
mouse_flags_2 &= ~0x80;
- disable_mouse();
+ disable_mouse(ebda_seg);
}
} else {
/* install handler */
diff --git a/src/ps2port.c b/src/ps2port.c
index 26c55f28..54227457 100644
--- a/src/ps2port.c
+++ b/src/ps2port.c
@@ -151,18 +151,6 @@ process_ps2byte(u8 status, u8 data)
process_key(data);
}
-static void
-process_ps2bytes(void)
-{
- for (;;) {
- u8 status = inb(PORT_PS2_STATUS);
- if (!(status & I8042_STR_OBF))
- return;
- u8 data = inb(PORT_PS2_DATA);
- process_ps2byte(status, data);
- }
-}
-
static int
ps2_recvbyte(int aux, int needack, int timeout)
{
@@ -223,13 +211,22 @@ ps2_sendbyte(int aux, u8 command, int timeout)
static int
ps2_command(int aux, int command, u8 *param)
{
- int ret;
+ int ret2;
int receive = (command >> 8) & 0xf;
int send = (command >> 12) & 0xf;
- // Disable processing of interrupts.
- u8 kbdflag = GET_BDA(kbd_flag3);
- SET_BDA(kbd_flag3, kbdflag | KF3_CMD_PENDING);
+ // Disable interrupts and keyboard/mouse.
+ u8 ps2ctr = GET_EBDA(ps2ctr);
+ u8 newctr = ps2ctr;
+ if (aux)
+ newctr |= I8042_CTR_KBDDIS;
+ else
+ newctr |= I8042_CTR_AUXDIS;
+ newctr &= ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT);
+ dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr);
+ int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
+ if (ret)
+ return ret;
if (command == ATKBD_CMD_RESET_BAT) {
// Reset is special wrt timeouts.
@@ -275,10 +272,10 @@ ps2_command(int aux, int command, u8 *param)
ret = 0;
fail:
- // Restore processing of interrupts.
- if (!(kbdflag & KF3_CMD_PENDING))
- process_ps2bytes();
- SET_BDA(kbd_flag3, kbdflag);
+ // Restore interrupts and keyboard/mouse.
+ ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr);
+ if (ret2)
+ return ret2;
return ret;
}
@@ -311,10 +308,14 @@ aux_command(int command, u8 *param)
static void
process_ps2irq(void)
{
- if (GET_BDA(kbd_flag3) & KF3_CMD_PENDING)
- // PS/2 command in progress - it will handle this event.
+ u8 status = inb(PORT_PS2_STATUS);
+ if (!(status & I8042_STR_OBF)) {
+ dprintf(1, "ps2 irq but no data.\n");
return;
- process_ps2bytes();
+ }
+ u8 data = inb(PORT_PS2_DATA);
+
+ process_ps2byte(status, data);
}
// INT74h : PS/2 mouse hardware interrupt
@@ -403,12 +404,8 @@ keyboard_init(void *data)
if (ret)
return;
- // Mode: scan code convert, enable IRQ 1, enable IRQ 12
- param[0] = I8042_CTR_XLATE | I8042_CTR_KBDINT | I8042_CTR_AUXINT;
- ret = i8042_command(I8042_CMD_CTL_WCTR, param);
- if (ret)
- return;
- CLEARBITS_BDA(kbd_flag3, KF3_CMD_PENDING);
+ // Keyboard Mode: scan code convert, disable mouse, enable IRQ 1
+ SET_EBDA(ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT);
/* Enable keyboard */
ret = kbd_command(ATKBD_CMD_ENABLE, NULL);
@@ -426,8 +423,6 @@ ps2port_setup(void)
return;
dprintf(3, "init ps2port\n");
- // Setup irqs, but disable them until init complete.
- SETBITS_BDA(kbd_flag3, KF3_CMD_PENDING);
enable_hwirq(1, entry_09);
enable_hwirq(12, entry_74);