summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_conf.h6
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_drv.c4
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_ext.c11
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_hdr.h11
-rw-r--r--sys/arch/i386/isa/pcvt/pcvt_kbd.c93
5 files changed, 78 insertions, 47 deletions
diff --git a/sys/arch/i386/isa/pcvt/pcvt_conf.h b/sys/arch/i386/isa/pcvt/pcvt_conf.h
index fac999d95b3..f63b751ef0f 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_conf.h
+++ b/sys/arch/i386/isa/pcvt/pcvt_conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_conf.h,v 1.12 1998/06/25 00:40:24 millert Exp $ */
+/* $OpenBSD: pcvt_conf.h,v 1.13 1998/06/30 20:51:07 millert Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -204,10 +204,10 @@
/* it is unlikely that anybody wants to change anything below */
#if !defined PCVT_NO_LED_UPDATE /* ---------- DEFAULT: OFF ------------ */
-# define PCVT_NO_LED_UPDATE 0 /* On some (Notebook?) keyboards it is */
+# define PCVT_NO_LED_UPDATE 0 /* On some keyboard controllers it is */
#elif PCVT_NO_LED_UPDATE != 0 /* not possible to update the LED's */
# undef PCVT_NO_LED_UPDATE /* without hanging the keyboard after- */
-# define PCVT_NO_LED_UPDATE 1 /* wards. If you experience Problems */
+# define PCVT_NO_LED_UPDATE 1 /* wards. If you experience problems */
#endif /* like this, try to enable this option */
#if !defined PCVT_PORTIO_DELAY /* ---------- DEFAULT: ON ------------- */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_drv.c b/sys/arch/i386/isa/pcvt/pcvt_drv.c
index a9cb747e479..2c60c066b9b 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_drv.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_drv.c,v 1.20 1998/06/25 00:40:25 millert Exp $ */
+/* $OpenBSD: pcvt_drv.c,v 1.21 1998/06/30 20:51:08 millert Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -800,7 +800,7 @@ pccngetc(Dev_t dev)
register u_char *cp;
#ifdef XSERVER
- if (vs[minor(dev)].kbd_state == K_RAW)
+ if (dev != NODEV && vs[minor(dev)].kbd_state == K_RAW)
return 0;
#endif /* XSERVER */
diff --git a/sys/arch/i386/isa/pcvt/pcvt_ext.c b/sys/arch/i386/isa/pcvt/pcvt_ext.c
index 5a512bec0c4..eed6cbee866 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_ext.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_ext.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_ext.c,v 1.14 1998/06/25 00:40:26 millert Exp $ */
+/* $OpenBSD: pcvt_ext.c,v 1.15 1998/06/30 20:51:09 millert Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -2773,14 +2773,19 @@ usl_vt_ioctl(Dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return (error == ERESTART) ? PCVT_ERESTART : error;
case KDENABIO:
- /* grant the process IO access; only allowed if euid == 0 */
+ /*
+ * grant the process IO access; only allowed if euid == 0
+ * and securelevel <= 1. XXX -- this is a fairly serious
+ * hole, but if closed at securelevel 1, would require
+ * options INSECURE in order to use X at all.
+ */
{
#if defined(COMPAT_10) || defined(COMPAT_11)
struct trapframe *fp = (struct trapframe *)p->p_md.md_regs;
#endif
- if (suser(p->p_ucred, &p->p_acflag) != 0)
+ if (suser(p->p_ucred, &p->p_acflag) || securelevel > 1)
return (EPERM);
#if defined(COMPAT_10) || defined(COMPAT_11)
diff --git a/sys/arch/i386/isa/pcvt/pcvt_hdr.h b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
index 8f8a118f477..3fabcc4428a 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_hdr.h
+++ b/sys/arch/i386/isa/pcvt/pcvt_hdr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_hdr.h,v 1.19 1998/06/25 00:40:28 millert Exp $ */
+/* $OpenBSD: pcvt_hdr.h,v 1.20 1998/06/30 20:51:11 millert Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -862,11 +862,8 @@ int switch_page = -1; /* which page to switch to */
#if PCVT_SCREENSAVER
u_char reset_screen_saver = 1; /* reset the saver next time */
u_char scrnsv_active = 0; /* active flag */
-#endif /* PCVT_SCREENSAVER */
-
-#if XSERVER || PCVT_SCREENSAVER
unsigned scrnsv_timeout = 0; /* initially off */
-#endif /* XSERVER || PCVT_SCREENSAVER */
+#endif /* PCVT_SCREENSAVER */
#if PCVT_BACKUP_FONTS
u_char *saved_charsets[NVGAFONTS] = {0}; /* backup copy of fonts */
@@ -999,9 +996,9 @@ extern u_char sgr_tab_color[];
extern u_char sgr_tab_mono[];
extern u_char sgr_tab_imono[];
-#if defined(XSERVER) || PCVT_SCREENSAVER
+#if PCVT_SCREENSAVER
extern unsigned scrnsv_timeout;
-#endif /* XSERVER || PCVT_SCREENSAVER */
+#endif /* PCVT_SCREENSAVER */
#if PCVT_BACKUP_FONTS
extern u_char *saved_charsets[NVGAFONTS];
diff --git a/sys/arch/i386/isa/pcvt/pcvt_kbd.c b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
index ac92fecbb52..630f27f64cc 100644
--- a/sys/arch/i386/isa/pcvt/pcvt_kbd.c
+++ b/sys/arch/i386/isa/pcvt/pcvt_kbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcvt_kbd.c,v 1.15 1998/06/25 00:40:29 millert Exp $ */
+/* $OpenBSD: pcvt_kbd.c,v 1.16 1998/06/30 20:51:12 millert Exp $ */
/*
* Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch.
@@ -78,6 +78,8 @@
#include "pcvt_hdr.h" /* global include */
+#define LEDSTATE_UPDATE_PENDING (1 << 3)
+
static void fkey1(void), fkey2(void), fkey3(void), fkey4(void);
static void fkey5(void), fkey6(void), fkey7(void), fkey8(void);
static void fkey9(void), fkey10(void), fkey11(void), fkey12(void);
@@ -106,7 +108,9 @@ static int rmkeydef ( int key );
static int setkeydef ( struct kbd_ovlkey *data );
static u_char * xlatkey2ascii( U_short key );
-static int ledstate = 0; /* keyboard led's */
+#if !PCVT_NO_LED_UPDATE
+static int ledstate = LEDSTATE_UPDATE_PENDING; /* keyboard led's */
+#endif
static int tpmrate = KBD_TPD500|KBD_TPM100;
static u_char altkpflag = 0;
static u_short altkpval = 0;
@@ -165,7 +169,7 @@ do_vgapage(int page)
/*
* This code from Lon Willett enclosed in #if PCVT_UPDLED_LOSES_INTR is
- * abled because it crashes FreeBSD 1.1.5.1 at boot time.
+ * disabled because it crashes FreeBSD 1.1.5.1 at boot time.
* The cause is obviously that the timeout queue is not yet initialized
* timeout is called from here the first time.
* Anyway it is a pointer in the right direction so it is included for
@@ -224,24 +228,60 @@ update_led(void)
/* Don't update LED's unless necessary. */
- int new_ledstate = ((vsp->scroll_lock) |
- (vsp->num_lock * 2) |
- (vsp->caps_lock * 4));
+ int opri, new_ledstate, response1, response2;
+
+ opri = spltty();
+ new_ledstate = ((vsp->scroll_lock) |
+ (vsp->num_lock * 2) |
+ (vsp->caps_lock * 4));
if (new_ledstate != ledstate)
{
- if(kbd_cmd(KEYB_C_LEDS) != 0)
+ ledstate = LEDSTATE_UPDATE_PENDING;
+
+ if (kbd_cmd(KEYB_C_LEDS) != 0)
{
printf("Keyboard LED command timeout\n");
+ splx(opri);
return;
}
- if(kbd_cmd(new_ledstate) != 0) {
+ /*
+ * For some keyboards or keyboard controllers, it is an
+ * error to issue a command without waiting long enough
+ * for an ACK for the previous command. The keyboard
+ * gets confused, and responds with KEYB_R_RESEND, but
+ * we ignore that. Wait for the ACK here. The busy
+ * waiting doesn't matter much, since we lose anyway by
+ * busy waiting to send the command.
+ *
+ * XXX actually wait for any response, since we can't
+ * handle normal scancodes here.
+ *
+ * XXX all this should be interrupt driven. Issue only
+ * one command at a time wait for a ACK before proceeding.
+ * Retry after a timeout or on receipt of a KEYB_R_RESEND.
+ * KEYB_R_RESENDs seem to be guaranteed by working
+ * keyboard controllers with broken (or disconnected)
+ * keyboards. There is another code for keyboard
+ * reconnects. The keyboard hardware is very simple and
+ * well designed :-).
+ */
+ response1 = kbd_response();
+
+ if (kbd_cmd(new_ledstate) != 0) {
printf("Keyboard LED data timeout\n");
+ splx(opri);
return;
}
+ response2 = kbd_response();
- ledstate = new_ledstate;
+ if (response1 == KEYB_R_ACK && response2 == KEYB_R_ACK)
+ ledstate = new_ledstate;
+ else
+ printf(
+ "Keyboard LED command not ACKed (responses %#x %#x)\n",
+ response1, response2);
#if PCVT_UPDLED_LOSES_INTR
if (lost_intr_timeout_queued)
@@ -252,6 +292,7 @@ update_led(void)
#endif /* PCVT_UPDLED_LOSES_INTR */
}
+ splx(opri);
#endif /* !PCVT_NO_LED_UPDATE */
}
@@ -432,7 +473,6 @@ void doreset(void)
printf("pcvt: doreset() - timeout for keyboard reset command\n");
/* Wait for the first response to reset and handle retries */
-
while((response = kbd_response()) != KEYB_R_ACK)
{
if(response < 0)
@@ -533,12 +573,8 @@ query_kbd_id:
r_entry:
if((response = kbd_response()) == KEYB_R_MF2ID1)
{
- if((response = kbd_response()) == KEYB_R_MF2ID2)
- {
- keyboard_type = KB_MFII;
- }
- else if(response == KEYB_R_RESEND)
- {
+ switch ((response = kbd_response())) {
+ case KEYB_R_RESEND:
/*
* Let's give other priority levels
* a chance instead of blocking at
@@ -546,24 +582,17 @@ r_entry:
*/
splx(opri);
goto query_kbd_id;
- }
- else if(response == KEYB_R_MF2ID2HP)
- {
- keyboard_type = KB_MFII;
- }
- else if(response == KEYB_R_MF2ID2TP)
- {
- keyboard_type = KB_MFII;
- }
- else if(response == KEYB_R_MF2ID2TP2)
- {
+
+ case KEYB_R_MF2ID2:
+ case KEYB_R_MF2ID2HP:
+ case KEYB_R_MF2ID2TP:
+ case KEYB_R_MF2ID2TP2:
keyboard_type = KB_MFII;
- }
- else
- {
- printf("\npcvt: doreset() - kbdid, response 2 = [%d]\n",
- response);
+ break;
+ default:
+ printf("\npcvt: doreset() - kbdid, response 2 = [%d]\n", response);
keyboard_type = KB_UNKNOWN;
+ break;
}
}
else if(response == KEYB_R_ACK)