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