Page MenuHomeFreeBSD

D1802.id3691.diff
No OneTemporary

D1802.id3691.diff

Index: sys/dev/atkbdc/atkbd.c
===================================================================
--- sys/dev/atkbdc/atkbd.c
+++ sys/dev/atkbdc/atkbd.c
@@ -431,7 +431,7 @@
}
if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
- if (KBD_HAS_DEVICE(kbd)
+ if (!KBD_HAS_DEVICE(kbd)
&& init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
&& (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
kbd_unregister(kbd);
@@ -443,6 +443,7 @@
delay[0] = kbd->kb_delay1;
delay[1] = kbd->kb_delay2;
atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
+ KBD_FOUND_DEVICE(kbd);
KBD_INIT_DONE(kbd);
}
if (!KBD_IS_CONFIGURED(kbd)) {
@@ -1200,25 +1201,26 @@
*/
int err;
int c;
- int m;
if (!kbdc_lock(kbdc, TRUE)) {
/* driver error? */
return ENXIO;
}
- /* temporarily block data transmission from the keyboard */
+ /*
+ * XXX block data transmission from the keyboard. This can cause
+ * the keyboard to stop sending keystrokes even when re-enabled
+ * under certain circumstances if not followed by a full reset.
+ */
write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
/* flush any noise in the buffer */
empty_both_buffers(kbdc, 100);
/* save the current keyboard controller command byte */
- m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS;
c = get_controller_command_byte(kbdc);
if (c == -1) {
/* CONTROLLER ERROR */
- kbdc_set_device_mask(kbdc, m);
kbdc_lock(kbdc, FALSE);
return ENXIO;
}
@@ -1243,15 +1245,11 @@
* to the system later. It is NOT recommended to hot-plug
* the AT keyboard, but many people do so...
*/
- kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
setup_kbd_port(kbdc, TRUE, TRUE);
#if 0
- if (err == 0) {
- kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
- } else {
+ if (err) {
/* try to restore the command byte as before */
- set_controller_command_byte(kbdc, 0xff, c);
- kbdc_set_device_mask(kbdc, m);
+ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c);
}
#endif
@@ -1271,7 +1269,11 @@
return EIO;
}
- /* temporarily block data transmission from the keyboard */
+ /*
+ * XXX block data transmission from the keyboard. This can cause
+ * the keyboard to stop sending keystrokes even when re-enabled
+ * under certain circumstances if not followed by a full reset.
+ */
write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
/* save the current controller command byte */
@@ -1299,13 +1301,42 @@
return EIO;
}
+ codeset = -1;
+
+ /* reset keyboard hardware */
+ if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
+ /*
+ * KEYBOARD ERROR
+ * Keyboard reset may fail either because the keyboard
+ * doen't exist, or because the keyboard doesn't pass
+ * the self-test, or the keyboard controller on the
+ * motherboard and the keyboard somehow fail to shake hands.
+ * It is just possible, particularly in the last case,
+ * that the keyboard controller may be left in a hung state.
+ * test_controller() and test_kbd_port() appear to bring
+ * the keyboard controller back (I don't know why and how,
+ * though.)
+ */
+ empty_both_buffers(kbdc, 10);
+ test_controller(kbdc);
+ test_kbd_port(kbdc);
+ /*
+ * We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above).
+ */
+ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c);
+ kbdc_lock(kbdc, FALSE);
+ if (bootverbose)
+ printf("atkbd: failed to reset the keyboard.\n");
+ return EIO;
+ }
+
/*
* Check if we have an XT keyboard before we attempt to reset it.
* The procedure assumes that the keyboard and the controller have
* been set up properly by BIOS and have not been messed up
* during the boot process.
*/
- codeset = -1;
if (flags & KB_CONF_ALT_SCANCODESET)
/* the user says there is a XT keyboard */
codeset = 1;
@@ -1343,34 +1374,6 @@
if (bootverbose)
printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type);
- /* reset keyboard hardware */
- if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
- /*
- * KEYBOARD ERROR
- * Keyboard reset may fail either because the keyboard
- * doen't exist, or because the keyboard doesn't pass
- * the self-test, or the keyboard controller on the
- * motherboard and the keyboard somehow fail to shake hands.
- * It is just possible, particularly in the last case,
- * that the keyboard controller may be left in a hung state.
- * test_controller() and test_kbd_port() appear to bring
- * the keyboard controller back (I don't know why and how,
- * though.)
- */
- empty_both_buffers(kbdc, 10);
- test_controller(kbdc);
- test_kbd_port(kbdc);
- /*
- * We could disable the keyboard port and interrupt... but,
- * the keyboard may still exist (see above).
- */
- set_controller_command_byte(kbdc, 0xff, c);
- kbdc_lock(kbdc, FALSE);
- if (bootverbose)
- printf("atkbd: failed to reset the keyboard.\n");
- return EIO;
- }
-
/*
* Allow us to set the XT_KEYBD flag so that keyboards
* such as those on the IBM ThinkPad laptop computers can be used
@@ -1387,7 +1390,7 @@
* The XT kbd isn't usable unless the proper scan
* code set is selected.
*/
- set_controller_command_byte(kbdc, 0xff, c);
+ set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c);
kbdc_lock(kbdc, FALSE);
printf("atkbd: unable to set the XT keyboard mode.\n");
return EIO;
@@ -1402,6 +1405,16 @@
c |= KBD_TRANSLATION;
#endif
+ /*
+ * Some keyboards require a SETLEDS command to be sent after
+ * the reset command before they will send keystrokes to us
+ * (Acer C720).
+ */
+ if (send_kbd_command_and_data(kbdc, KBDC_SET_LEDS, 0) != KBD_ACK) {
+ printf("atkbd: setleds failed\n");
+ }
+ send_kbd_command(kbdc, KBDC_ENABLE_KBD);
+
/* enable the keyboard port and intr. */
if (!set_controller_command_byte(kbdc,
KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
@@ -1412,7 +1425,9 @@
* This is serious; we are left with the disabled
* keyboard intr.
*/
- set_controller_command_byte(kbdc, 0xff, c);
+ set_controller_command_byte(kbdc,
+ KBD_KBD_CONTROL_BITS | KBD_TRANSLATION |
+ KBD_OVERRIDE_KBD_LOCK, c);
kbdc_lock(kbdc, FALSE);
printf("atkbd: unable to enable the keyboard port and intr.\n");
return EIO;
@@ -1434,12 +1449,16 @@
/* disable the keyboard and mouse interrupt */
s = spltty();
#if 0
+ /*
+ * XXX NOTE: We can't just disable the KBD port any more, even
+ * temporarily, without blowing up some BIOS emulations
+ * if not followed by a full reset.
+ */
c = get_controller_command_byte(kbdc);
if ((c == -1)
|| !set_controller_command_byte(kbdc,
- kbdc_get_device_mask(kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ KBD_KBD_CONTROL_BITS,
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
/* CONTROLLER ERROR */
kbdc_lock(kbdc, FALSE);
splx(s);
@@ -1458,8 +1477,7 @@
send_kbd_command(kbdc, KBDC_ENABLE_KBD);
#if 0
/* restore the interrupts */
- if (!set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc),
- c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
+ if (!set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c)) {
/* CONTROLLER ERROR */
}
#else
Index: sys/dev/atkbdc/atkbdc.c
===================================================================
--- sys/dev/atkbdc/atkbdc.c
+++ sys/dev/atkbdc/atkbdc.c
@@ -1115,19 +1115,6 @@
}
int
-kbdc_get_device_mask(KBDC p)
-{
- return kbdcp(p)->command_mask;
-}
-
-void
-kbdc_set_device_mask(KBDC p, int mask)
-{
- kbdcp(p)->command_mask =
- mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS);
-}
-
-int
get_controller_command_byte(KBDC p)
{
if (kbdcp(p)->command_byte != -1)
Index: sys/dev/atkbdc/atkbdcreg.h
===================================================================
--- sys/dev/atkbdc/atkbdcreg.h
+++ sys/dev/atkbdc/atkbdcreg.h
@@ -255,9 +255,6 @@
int test_kbd_port(KBDC kbdc);
int test_aux_port(KBDC kbdc);
-int kbdc_get_device_mask(KBDC kbdc);
-void kbdc_set_device_mask(KBDC kbdc, int mask);
-
int get_controller_command_byte(KBDC kbdc);
int set_controller_command_byte(KBDC kbdc, int command, int flag);
Index: sys/dev/atkbdc/psm.c
===================================================================
--- sys/dev/atkbdc/psm.c
+++ sys/dev/atkbdc/psm.c
@@ -993,8 +993,7 @@
/* enable the aux port and interrupt */
if (!set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- (command_byte & KBD_KBD_CONTROL_BITS) |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT)) {
/* CONTROLLER ERROR */
disable_aux_dev(sc->kbdc);
@@ -1037,8 +1036,7 @@
/* enable the aux port but disable the aux interrupt and the keyboard */
if ((c == -1) || !set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR */
splx(s);
@@ -1088,8 +1086,7 @@
} else {
/* restore the keyboard port and disable the aux port */
if (!set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- (c & KBD_KBD_CONTROL_BITS) |
+ KBD_AUX_CONTROL_BITS,
KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR */
log(LOG_ERR, "psm%d: failed to disable the aux port "
@@ -1142,7 +1139,9 @@
#define endprobe(v) do { \
if (bootverbose) \
--verbose; \
- kbdc_set_device_mask(sc->kbdc, mask); \
+ set_controller_command_byte(sc->kbdc, \
+ KBD_AUX_CONTROL_BITS, KBD_DISABLE_AUX_PORT | \
+ KBD_DISABLE_AUX_INT); \
kbdc_lock(sc->kbdc, FALSE); \
return (v); \
} while (0)
@@ -1154,7 +1153,6 @@
struct psm_softc *sc = device_get_softc(dev);
int stat[3];
int command_byte;
- int mask;
int rid;
int i;
@@ -1207,7 +1205,6 @@
empty_both_buffers(sc->kbdc, 10);
/* save the current command byte; it will be used later */
- mask = kbdc_get_device_mask(sc->kbdc) & ~KBD_AUX_CONTROL_BITS;
command_byte = get_controller_command_byte(sc->kbdc);
if (verbose)
printf("psm%d: current command byte:%04x\n", unit,
@@ -1220,21 +1217,28 @@
}
/*
- * disable the keyboard port while probing the aux port, which must be
- * enabled during this routine
+ * NOTE: We cannot mess with the keyboard port, do NOT disable it
+ * while we are probing the aux port during this routine.
+ * Disabling the keyboard port will break some things
+ * (Acer c720)... probably related to BIOS emulation of the
+ * i8042.
*/
if (!set_controller_command_byte(sc->kbdc,
- KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS,
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/*
* this is CONTROLLER ERROR; I don't know how to recover
* from this error...
*/
- restore_controller(sc->kbdc, command_byte);
printf("psm%d: unable to set the command byte.\n", unit);
endprobe(ENXIO);
}
+
+ /*
+ * NOTE: Linux doesn't send discrete aux port enablement commands,
+ * it is unclear whether this is needed or helps or hinders
+ * bios emulators.
+ */
write_controller_command(sc->kbdc, KBDC_ENABLE_AUX_PORT);
/*
@@ -1270,7 +1274,6 @@
recover_from_error(sc->kbdc);
if (sc->config & PSM_CONFIG_IGNPORTERROR)
break;
- restore_controller(sc->kbdc, command_byte);
if (verbose)
printf("psm%d: the aux port is not functioning (%d).\n",
unit, i);
@@ -1293,7 +1296,6 @@
*/
if (!reset_aux_dev(sc->kbdc)) {
recover_from_error(sc->kbdc);
- restore_controller(sc->kbdc, command_byte);
if (verbose)
printf("psm%d: failed to reset the aux "
"device.\n", unit);
@@ -1315,7 +1317,6 @@
if (!enable_aux_dev(sc->kbdc) || !disable_aux_dev(sc->kbdc)) {
/* MOUSE ERROR */
recover_from_error(sc->kbdc);
- restore_controller(sc->kbdc, command_byte);
if (verbose)
printf("psm%d: failed to enable the aux device.\n",
unit);
@@ -1337,7 +1338,6 @@
/* verify the device is a mouse */
sc->hw.hwid = get_aux_id(sc->kbdc);
if (!is_a_mouse(sc->hw.hwid)) {
- restore_controller(sc->kbdc, command_byte);
if (verbose)
printf("psm%d: unknown device type (%d).\n", unit,
sc->hw.hwid);
@@ -1436,20 +1436,17 @@
/* disable the aux port for now... */
if (!set_controller_command_byte(sc->kbdc,
- KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS,
- (command_byte & KBD_KBD_CONTROL_BITS) |
+ KBD_AUX_CONTROL_BITS,
KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/*
* this is CONTROLLER ERROR; I don't know the proper way to
* recover from this error...
*/
- restore_controller(sc->kbdc, command_byte);
printf("psm%d: unable to set the command byte.\n", unit);
endprobe(ENXIO);
}
/* done */
- kbdc_set_device_mask(sc->kbdc, mask | KBD_AUX_CONTROL_BITS);
kbdc_lock(sc->kbdc, FALSE);
return (0);
}
@@ -1596,8 +1593,7 @@
/* enable the aux port and temporalily disable the keyboard */
if (command_byte == -1 || !set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR; do you know how to get out of this? */
kbdc_lock(sc->kbdc, FALSE);
@@ -1649,8 +1645,7 @@
/* disable the aux interrupt and temporalily disable the keyboard */
if (!set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
log(LOG_ERR,
"psm%d: failed to disable the aux int (psmclose).\n",
@@ -1691,8 +1686,7 @@
}
if (!set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- (command_byte & KBD_KBD_CONTROL_BITS) |
+ KBD_AUX_CONTROL_BITS,
KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/*
* CONTROLLER ERROR;
@@ -1850,8 +1844,7 @@
s = spltty();
*c = get_controller_command_byte(sc->kbdc);
if ((*c == -1) || !set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
+ KBD_AUX_CONTROL_BITS,
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* this is CONTROLLER ERROR */
splx(s);
@@ -1914,8 +1907,8 @@
/* restore ports and interrupt */
if (!set_controller_command_byte(sc->kbdc,
- kbdc_get_device_mask(sc->kbdc),
- c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
+ KBD_AUX_CONTROL_BITS,
+ c & (KBD_AUX_CONTROL_BITS))) {
/*
* CONTROLLER ERROR; this is serious, we may have
* been left with the inaccessible keyboard and

File Metadata

Mime Type
text/plain
Expires
Sat, Aug 22, 7:12 PM (46 m, 14 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37104097
Default Alt Text
D1802.id3691.diff (14 KB)

Event Timeline