RFC: small syscons and kbd patch

Maksim Yevmenkin maksim.yevmenkin at gmail.com
Tue Dec 2 17:01:15 PST 2008


Dear Hackers,

can someone please review the attached small patch for syscons and
kbd? it should be a no-op mostly. the patch basically does

1) removes bogus layering in syscons, i.e. basically removes sccngetch();
2) implements advisory lock for kbd (based on atomic(9));
3) implements new POLLED flag for kbd;

this is a part of a plan to fix keyboard access races in syscons.

thanks,
max
-------------- next part --------------
Index: sys/dev/syscons/syscons.c
===================================================================
--- sys/dev/syscons/syscons.c	(revision 185319)
+++ sys/dev/syscons/syscons.c	(working copy)
@@ -179,7 +179,6 @@
 static u_int scgetc(sc_softc_t *sc, u_int flags);
 #define SCGETC_CN	1
 #define SCGETC_NONBLOCK	2
-static int sccngetch(int flags);
 static void sccnupdate(scr_stat *scp);
 static scr_stat *alloc_scp(sc_softc_t *sc, int vty);
 static void init_scp(sc_softc_t *sc, int vty, scr_stat *scp);
@@ -1558,12 +1557,6 @@
 static int
 sc_cngetc(struct consdev *cd)
 {
-    return sccngetch(SCGETC_NONBLOCK);
-}
-
-static int
-sccngetch(int flags)
-{
     static struct fkeytab fkey;
     static int fkeycp;
     scr_stat *scp;
@@ -1604,7 +1597,7 @@
     kbdd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
 
     kbdd_poll(scp->sc->kbd, TRUE);
-    c = scgetc(scp->sc, SCGETC_CN | flags);
+    c = scgetc(scp->sc, SCGETC_CN | SCGETC_NONBLOCK);
     kbdd_poll(scp->sc->kbd, FALSE);
 
     scp->kbd_mode = cur_mode;
Index: sys/dev/kbd/kbd.c
===================================================================
--- sys/dev/kbd/kbd.c	(revision 185319)
+++ sys/dev/kbd/kbd.c	(working copy)
@@ -1102,6 +1102,12 @@
 	}
 }
 
+int
+genkbd_lock(keyboard_t *kbd, int on)
+{
+	return (atomic_cmpset_acq_int(&kbd->kb_locked, !!!on, !!on));
+}
+
 #define set_lockkey_state(k, s, l)				\
 	if (!((s) & l ## DOWN)) {				\
 		int i;						\
Index: sys/dev/kbd/kbdreg.h
===================================================================
--- sys/dev/kbd/kbdreg.h	(revision 185319)
+++ sys/dev/kbd/kbdreg.h	(working copy)
@@ -60,7 +60,9 @@
 #define KB_INITIALIZED	(1 << 19)	/* device initialized */
 #define KB_REGISTERED	(1 << 20)	/* device registered to kbdio */
 #define KB_BUSY		(1 << 21)	/* device used by a client */
+#define KB_POLLED	(1 << 22)	/* device is in polled mode */
 	int		kb_active;	/* 0: inactive */
+	int		kb_locked;	/* 0: unlocked */
 	void		*kb_token;	/* id of the current client */
 	keyboard_callback_t kb_callback;/* callback function */
 
@@ -107,6 +109,9 @@
 #define KBD_IS_BUSY(k)		((k)->kb_flags & KB_BUSY)
 #define KBD_BUSY(k)		((k)->kb_flags |= KB_BUSY)
 #define KBD_UNBUSY(k)		((k)->kb_flags &= ~KB_BUSY)
+#define KBD_IS_POLLED(k)	((k)->kb_flags & KB_POLLED)
+#define KBD_POLLED(k)		((k)->kb_flags |= KB_POLLED)
+#define KBD_UNPOLLED(k)		((k)->kb_flags &= ~KB_POLLED)
 #define KBD_IS_ACTIVE(k)	((k)->kb_active)
 #define KBD_ACTIVATE(k)		(++(k)->kb_active)
 #define KBD_DEACTIVATE(k)	(--(k)->kb_active)
@@ -170,7 +175,7 @@
 	(*kbdsw[(kbd)->kb_index]->intr)((kbd), (arg))
 #define kbdd_test_if(kbd)						\
 	(*kbdsw[(kbd)->kb_index]->test_if)((kbd))
-#define kbdd_enable(kbd)							\
+#define kbdd_enable(kbd)						\
 	(*kbdsw[(kbd)->kb_index]->enable)((kbd))
 #define kbdd_disable(kbd)						\
 	(*kbdsw[(kbd)->kb_index]->disable)((kbd))
@@ -194,7 +199,7 @@
 	(*kbdsw[(kbd)->kb_index]->get_state)((kbd), (buf), (len))
 #define kbdd_set_state(kbd, buf, len)					\
 	(*kbdsw[(kbd)->kb_index]->set_state)((kbd), (buf), (len))
-#define kbdd_get_fkeystr(kbd, fkey, len)					\
+#define kbdd_get_fkeystr(kbd, fkey, len)				\
 	(*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
 #define kbdd_poll(kbd, on)						\
 	(*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
@@ -293,6 +298,7 @@
 
 kbd_get_fkeystr_t	genkbd_get_fkeystr;
 kbd_diag_t		genkbd_diag;
+kbd_lock_t		genkbd_lock;
 
 int 	genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg);
 int 	genkbd_keyaction(keyboard_t *kbd, int keycode, int up,


More information about the freebsd-current mailing list