Page MenuHomeFreeBSD

D10263.diff
No OneTemporary

D10263.diff

Index: sys/dev/atkbdc/atkbd.c
===================================================================
--- sys/dev/atkbdc/atkbd.c
+++ sys/dev/atkbdc/atkbd.c
@@ -161,7 +161,6 @@
{
atkbd_state_t *state;
keyboard_t *kbd;
- int s;
/*
* The original text of the following comments are extracted
@@ -188,19 +187,9 @@
*
* The keyboard apparently unwedges the irq in most cases.
*/
- s = spltty();
kbd = (keyboard_t *)arg;
- if (kbdd_lock(kbd, TRUE)) {
- /*
- * We have seen the lock flag is not set. Let's reset
- * the flag early, otherwise the LED update routine fails
- * which may want the lock during the interrupt routine.
- */
- kbdd_lock(kbd, FALSE);
- if (kbdd_check_char(kbd))
- kbdd_intr(kbd, NULL);
- }
- splx(s);
+ if (kbdd_check_char(kbd))
+ kbdd_intr(kbd, NULL);
state = (atkbd_state_t *)kbd->kb_data;
callout_reset(&state->ks_timer, hz / 10, atkbd_timeout, arg);
}
@@ -572,16 +561,15 @@
atkbd_test_if(keyboard_t *kbd)
{
int error;
- int s;
error = 0;
+ kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc);
empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10);
- s = spltty();
if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc))
error = EIO;
else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0)
error = EIO;
- splx(s);
+ kbdc_unlock(((atkbd_state_t *)kbd->kb_data)->kbdc);
return error;
}
@@ -619,10 +607,12 @@
{
int c;
+ kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc);
if (wait)
c = read_kbd_data(((atkbd_state_t *)kbd->kb_data)->kbdc);
else
c = read_kbd_data_no_wait(((atkbd_state_t *)kbd->kb_data)->kbdc);
+ kbdc_unlock(((atkbd_state_t *)kbd->kb_data)->kbdc);
if (c != -1)
++kbd->kb_count;
return (KBD_IS_ACTIVE(kbd) ? c : -1);
@@ -658,15 +648,19 @@
}
/* see if there is something in the keyboard port */
+ kbdc_lock(state->kbdc);
if (wait) {
do {
scancode = read_kbd_data(state->kbdc);
} while (scancode == -1);
} else {
scancode = read_kbd_data_no_wait(state->kbdc);
- if (scancode == -1)
+ if (scancode == -1) {
+ kbdc_unlock(state->kbdc);
return NOKEY;
+ }
}
+ kbdc_unlock(state->kbdc);
++kbd->kb_count;
#if KBDIO_DEBUG >= 10
@@ -1086,7 +1080,7 @@
static int
atkbd_lock(keyboard_t *kbd, int lock)
{
- return kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc, lock);
+ return (1);
}
/* clear the internal state of the keyboard */
@@ -1163,17 +1157,21 @@
* disabling the interrupts doesn't cause real problems but the
* responsiveness is a bit better when they are turned off.
*/
+ kbdc_lock(kbdc);
send_kbd_command(kbdc, KBDC_DISABLE_KBD);
set_controller_command_byte(kbdc,
KBD_AUX_CONTROL_BITS | KBD_KBD_CONTROL_BITS | KBD_TRANSLATION,
KBD_DISABLE_AUX_PORT | KBD_DISABLE_KBD_INT | KBD_ENABLE_KBD_PORT);
send_kbd_command(kbdc, KBDC_ENABLE_KBD);
+ kbdc_unlock(kbdc);
#endif
}
static int
atkbd_reset(KBDC kbdc, int flags, int c)
{
+ kbdc_lock_assert(kbdc);
+
/* reset keyboard hardware */
if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
/*
@@ -1225,6 +1223,8 @@
static int
setup_kbd_port(KBDC kbdc, int port, int intr)
{
+ kbdc_lock_assert(kbdc);
+
if (!set_controller_command_byte(kbdc,
KBD_KBD_CONTROL_BITS,
((port) ? KBD_ENABLE_KBD_PORT : KBD_DISABLE_KBD_PORT)
@@ -1236,6 +1236,8 @@
static int
get_kbd_echo(KBDC kbdc)
{
+ kbdc_lock_assert(kbdc);
+
/* enable the keyboard port, but disable the keyboard intr. */
if (setup_kbd_port(kbdc, TRUE, FALSE))
/* CONTROLLER ERROR: there is very little we can do... */
@@ -1273,10 +1275,7 @@
int c;
int m;
- if (!kbdc_lock(kbdc, TRUE)) {
- /* driver error? */
- return ENXIO;
- }
+ kbdc_lock(kbdc);
/* temporarily block data transmission from the keyboard */
write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
@@ -1290,7 +1289,7 @@
if (c == -1) {
/* CONTROLLER ERROR */
kbdc_set_device_mask(kbdc, m);
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return ENXIO;
}
@@ -1327,7 +1326,7 @@
}
#endif
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return (HAS_QUIRK(kbdc, KBDC_QUIRK_IGNORE_PROBE_RESULT) ? 0 : err);
}
@@ -1338,10 +1337,7 @@
int id;
int c;
- if (!kbdc_lock(kbdc, TRUE)) {
- /* driver error? */
- return EIO;
- }
+ kbdc_lock(kbdc);
/* temporarily block data transmission from the keyboard */
write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
@@ -1351,7 +1347,7 @@
c = get_controller_command_byte(kbdc);
if (c == -1) {
/* CONTROLLER ERROR */
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
printf("atkbd: unable to get the current command byte value.\n");
return EIO;
}
@@ -1367,13 +1363,13 @@
if (setup_kbd_port(kbdc, TRUE, FALSE)) {
/* CONTROLLER ERROR: there is very little we can do... */
printf("atkbd: unable to set the command byte.\n");
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return EIO;
}
if (HAS_QUIRK(kbdc, KBDC_QUIRK_RESET_AFTER_PROBE) &&
atkbd_reset(kbdc, flags, c)) {
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return EIO;
}
@@ -1423,7 +1419,7 @@
if (!HAS_QUIRK(kbdc, KBDC_QUIRK_RESET_AFTER_PROBE) &&
atkbd_reset(kbdc, flags, c)) {
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return EIO;
}
@@ -1445,7 +1441,7 @@
*/
set_controller_command_byte(kbdc, ALLOW_DISABLE_KBD(kbdc)
? 0xff : KBD_KBD_CONTROL_BITS, c);
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
printf("atkbd: unable to set the XT keyboard mode.\n");
return EIO;
}
@@ -1483,26 +1479,20 @@
set_controller_command_byte(kbdc, ALLOW_DISABLE_KBD(kbdc)
? 0xff : (KBD_KBD_CONTROL_BITS | KBD_TRANSLATION |
KBD_OVERRIDE_KBD_LOCK), c);
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
printf("atkbd: unable to enable the keyboard port and intr.\n");
return EIO;
}
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return 0;
}
static int
write_kbd(KBDC kbdc, int command, int data)
{
- int s;
-
/* prevent the timeout routine from polling the keyboard */
- if (!kbdc_lock(kbdc, TRUE))
- return EBUSY;
-
- /* disable the keyboard and mouse interrupt */
- s = spltty();
+ kbdc_lock(kbdc);
#if 0
c = get_controller_command_byte(kbdc);
if ((c == -1)
@@ -1511,18 +1501,9 @@
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
| KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR */
- kbdc_lock(kbdc, FALSE);
- splx(s);
+ kbdc_unlock(kbdc);
return EIO;
}
- /*
- * Now that the keyboard controller is told not to generate
- * the keyboard and mouse interrupts, call `splx()' to allow
- * the other tty interrupts. The clock interrupt may also occur,
- * but the timeout routine (`scrn_timer()') will be blocked
- * by the lock flag set via `kbdc_lock()'
- */
- splx(s);
#endif
if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK)
send_kbd_command(kbdc, KBDC_ENABLE_KBD);
@@ -1532,10 +1513,8 @@
c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
/* CONTROLLER ERROR */
}
-#else
- splx(s);
#endif
- kbdc_lock(kbdc, FALSE);
+ kbdc_unlock(kbdc);
return 0;
}
@@ -1545,6 +1524,8 @@
{
int id1, id2;
+ kbdc_lock_assert(kbdc);
+
empty_both_buffers(kbdc, 10);
id1 = id2 = -1;
if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) != KBD_ACK)
Index: sys/dev/atkbdc/atkbdc.c
===================================================================
--- sys/dev/atkbdc/atkbdc.c
+++ sys/dev/atkbdc/atkbdc.c
@@ -43,6 +43,8 @@
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
#if defined(__amd64__)
#include <machine/clock.h>
@@ -291,7 +293,7 @@
if (sc->ioh0 == 0) { /* XXX */
sc->command_byte = -1;
sc->command_mask = 0;
- sc->lock = FALSE;
+ mtx_init(&sc->lock, "atkbdc lock", NULL, MTX_DEF);
sc->kbd.head = sc->kbd.tail = 0;
sc->aux.head = sc->aux.tail = 0;
#if KBDIO_DEBUG >= 2
@@ -349,56 +351,6 @@
return NULL;
}
-/*
- * I/O access arbitration in `kbdio'
- *
- * The `kbdio' module uses a simplistic convention to arbitrate
- * I/O access to the controller/keyboard/mouse. The convention requires
- * close cooperation of the calling device driver.
- *
- * The device drivers which utilize the `kbdio' module are assumed to
- * have the following set of routines.
- * a. An interrupt handler (the bottom half of the driver).
- * b. Timeout routines which may briefly poll the keyboard controller.
- * c. Routines outside interrupt context (the top half of the driver).
- * They should follow the rules below:
- * 1. The interrupt handler may assume that it always has full access
- * to the controller/keyboard/mouse.
- * 2. The other routines must issue `spltty()' if they wish to
- * prevent the interrupt handler from accessing
- * the controller/keyboard/mouse.
- * 3. The timeout routines and the top half routines of the device driver
- * arbitrate I/O access by observing the lock flag in `kbdio'.
- * The flag is manipulated via `kbdc_lock()'; when one wants to
- * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
- * the call returns with TRUE. Otherwise the caller must back off.
- * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
- * is finished. This mechanism does not prevent the interrupt
- * handler from being invoked at any time and carrying out I/O.
- * Therefore, `spltty()' must be strategically placed in the device
- * driver code. Also note that the timeout routine may interrupt
- * `kbdc_lock()' called by the top half of the driver, but this
- * interruption is OK so long as the timeout routine observes
- * rule 4 below.
- * 4. The interrupt and timeout routines should not extend I/O operation
- * across more than one interrupt or timeout; they must complete any
- * necessary I/O operation within one invocation of the routine.
- * This means that if the timeout routine acquires the lock flag,
- * it must reset the flag to FALSE before it returns.
- */
-
-/* set/reset polling lock */
-int
-kbdc_lock(KBDC p, int lock)
-{
- int prevlock;
-
- prevlock = kbdcp(p)->lock;
- kbdcp(p)->lock = lock;
-
- return (prevlock != lock);
-}
-
/* check if any data is waiting to be processed */
int
kbdc_data_ready(KBDC p)
@@ -607,6 +559,8 @@
int
write_controller_command(KBDC p, int c)
{
+ kbdc_lock_assert(p);
+
if (!wait_while_controller_busy(kbdcp(p)))
return FALSE;
write_command(kbdcp(p), c);
@@ -617,6 +571,8 @@
int
write_controller_data(KBDC p, int c)
{
+ kbdc_lock_assert(p);
+
if (!wait_while_controller_busy(kbdcp(p)))
return FALSE;
write_data(kbdcp(p), c);
@@ -627,6 +583,8 @@
int
write_kbd_command(KBDC p, int c)
{
+ kbdc_lock_assert(p);
+
if (!wait_while_controller_busy(kbdcp(p)))
return FALSE;
write_data(kbdcp(p), c);
@@ -637,6 +595,8 @@
int
write_aux_command(KBDC p, int c)
{
+ kbdc_lock_assert(p);
+
if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
return FALSE;
return write_controller_data(p, c);
@@ -649,6 +609,8 @@
int retry = KBD_MAXRETRY;
int res = -1;
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
if (!write_kbd_command(p, c))
continue;
@@ -666,6 +628,8 @@
int retry = KBD_MAXRETRY;
int res = -1;
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
if (!write_aux_command(p, c))
continue;
@@ -693,6 +657,8 @@
int retry;
int res = -1;
+ kbdc_lock_assert(p);
+
for (retry = KBD_MAXRETRY; retry > 0; --retry) {
if (!write_kbd_command(p, c))
continue;
@@ -722,6 +688,8 @@
int retry;
int res = -1;
+ kbdc_lock_assert(p);
+
for (retry = KBD_MAXRETRY; retry > 0; --retry) {
if (!write_aux_command(p, c))
continue;
@@ -752,6 +720,8 @@
int
read_controller_data(KBDC p)
{
+ kbdc_lock_assert(p);
+
if (availq(&kbdcp(p)->kbd))
return removeq(&kbdcp(p)->kbd);
if (availq(&kbdcp(p)->aux))
@@ -779,6 +749,8 @@
}
#endif
+ kbdc_lock_assert(p);
+
if (availq(&kbdcp(p)->kbd))
return removeq(&kbdcp(p)->kbd);
if (!wait_for_kbd_data(kbdcp(p)))
@@ -804,6 +776,8 @@
}
#endif
+ kbdc_lock_assert(p);
+
if (availq(&kbdcp(p)->kbd))
return removeq(&kbdcp(p)->kbd);
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
@@ -823,6 +797,8 @@
int
read_aux_data(KBDC p)
{
+ kbdc_lock_assert(p);
+
if (availq(&kbdcp(p)->aux))
return removeq(&kbdcp(p)->aux);
if (!wait_for_aux_data(kbdcp(p)))
@@ -838,6 +814,8 @@
{
int f;
+ kbdc_lock_assert(p);
+
if (availq(&kbdcp(p)->aux))
return removeq(&kbdcp(p)->aux);
f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
@@ -866,6 +844,8 @@
#endif
int delta = 2;
+ kbdc_lock_assert(p);
+
for (t = wait; t > 0; ) {
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
DELAY(KBDD_DELAYTIME);
@@ -905,6 +885,8 @@
#endif
int delta = 2;
+ kbdc_lock_assert(p);
+
for (t = wait; t > 0; ) {
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
DELAY(KBDD_DELAYTIME);
@@ -944,6 +926,8 @@
#endif
int delta = 2;
+ kbdc_lock_assert(p);
+
for (t = wait; t > 0; ) {
if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
DELAY(KBDD_DELAYTIME);
@@ -991,6 +975,8 @@
int again = KBD_MAXWAIT;
int c = KBD_RESEND; /* keep the compiler happy */
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
empty_both_buffers(p, 10);
if (!write_kbd_command(p, KBDC_RESET_KBD))
@@ -1029,6 +1015,8 @@
int again = KBD_MAXWAIT;
int c = PSM_RESEND; /* keep the compiler happy */
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
empty_both_buffers(p, 10);
if (!write_aux_command(p, PSMC_RESET_DEV))
@@ -1077,6 +1065,8 @@
int again = KBD_MAXWAIT;
int c = KBD_DIAG_FAIL;
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
empty_both_buffers(p, 10);
if (write_controller_command(p, KBDC_DIAGNOSE))
@@ -1105,6 +1095,8 @@
int again = KBD_MAXWAIT;
int c = -1;
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
empty_both_buffers(p, 10);
if (write_controller_command(p, KBDC_TEST_KBD_PORT))
@@ -1131,6 +1123,8 @@
int again = KBD_MAXWAIT;
int c = -1;
+ kbdc_lock_assert(p);
+
while (retry-- > 0) {
empty_both_buffers(p, 10);
if (write_controller_command(p, KBDC_TEST_AUX_PORT))
@@ -1167,6 +1161,8 @@
int
get_controller_command_byte(KBDC p)
{
+ kbdc_lock_assert(p);
+
if (kbdcp(p)->command_byte != -1)
return kbdcp(p)->command_byte;
if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
@@ -1179,6 +1175,8 @@
int
set_controller_command_byte(KBDC p, int mask, int command)
{
+ kbdc_lock_assert(p);
+
if (get_controller_command_byte(p) == -1)
return FALSE;
Index: sys/dev/atkbdc/atkbdcreg.h
===================================================================
--- sys/dev/atkbdc/atkbdcreg.h
+++ sys/dev/atkbdc/atkbdcreg.h
@@ -198,7 +198,7 @@
bus_space_handle_t ioh1;
int command_byte; /* current command byte value */
int command_mask; /* command byte mask bits for kbd/aux devices */
- int lock; /* FIXME: XXX not quite a semaphore... */
+ struct mtx lock;
kqueue kbd; /* keyboard data queue */
kqueue aux; /* auxiliary data queue */
int retry;
@@ -221,6 +221,28 @@
#define KBDC_RID_KBD 0
#define KBDC_RID_AUX 1
+/* inlined functions */
+static __inline void
+kbdc_lock(KBDC kbdc)
+{
+
+ mtx_lock(&((atkbdc_softc_t *)kbdc)->lock);
+}
+
+static __inline void
+kbdc_unlock(KBDC kbdc)
+{
+
+ mtx_unlock(&((atkbdc_softc_t *)kbdc)->lock);
+}
+
+static __inline void
+kbdc_lock_assert(KBDC kbdc)
+{
+
+ mtx_assert(&((atkbdc_softc_t *)kbdc)->lock, MA_OWNED);
+}
+
/* function prototypes */
atkbdc_softc_t *atkbdc_get_softc(int unit);
@@ -230,7 +252,6 @@
int atkbdc_configure(void);
KBDC atkbdc_open(int unit);
-int kbdc_lock(KBDC kbdc, int lock);
int kbdc_data_ready(KBDC kbdc);
int write_controller_command(KBDC kbdc,int c);
Index: sys/dev/atkbdc/psm.c
===================================================================
--- sys/dev/atkbdc/psm.c
+++ sys/dev/atkbdc/psm.c
@@ -681,6 +681,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
res = send_aux_command(kbdc, PSMC_ENABLE_DEV);
VLOG(2, (LOG_DEBUG, "psm: ENABLE_DEV return code:%04x\n", res));
@@ -692,6 +694,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
res = send_aux_command(kbdc, PSMC_DISABLE_DEV);
VLOG(2, (LOG_DEBUG, "psm: DISABLE_DEV return code:%04x\n", res));
@@ -705,6 +709,8 @@
int res;
int i;
+ kbdc_lock_assert(kbdc);
+
switch (flag) {
case 0:
default:
@@ -739,6 +745,8 @@
int res;
int id;
+ kbdc_lock_assert(kbdc);
+
empty_aux_buffer(kbdc, 5);
res = send_aux_command(kbdc, PSMC_SEND_DEV_ID);
VLOG(2, (LOG_DEBUG, "psm: SEND_DEV_ID return code:%04x\n", res));
@@ -759,6 +767,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
res = send_aux_command_and_data(kbdc, PSMC_SET_SAMPLING_RATE, rate);
VLOG(2, (LOG_DEBUG, "psm: SET_SAMPLING_RATE (%d) %04x\n", rate, res));
@@ -770,6 +780,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
switch (scale) {
case 1:
default:
@@ -792,6 +804,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
res = send_aux_command_and_data(kbdc, PSMC_SET_RESOLUTION, val);
VLOG(2, (LOG_DEBUG, "psm: SET_RESOLUTION (%d) %04x\n", val, res));
@@ -807,6 +821,8 @@
{
int res;
+ kbdc_lock_assert(kbdc);
+
res = send_aux_command(kbdc, PSMC_SET_STREAM_MODE);
VLOG(2, (LOG_DEBUG, "psm: SET_STREAM_MODE return code:%04x\n", res));
@@ -819,6 +835,8 @@
int c = 2; /* assume two buttons by default */
int status[3];
+ kbdc_lock_assert(kbdc);
+
/*
* NOTE: a special sequence to obtain Logitech Mouse specific
* information: set resolution to 25 ppi, set scaling to 1:1, set
@@ -896,6 +914,8 @@
static void
recover_from_error(KBDC kbdc)
{
+ kbdc_lock_assert(kbdc);
+
/* discard anything left in the output buffer */
empty_both_buffers(kbdc, 10);
@@ -921,6 +941,8 @@
static int
restore_controller(KBDC kbdc, int command_byte)
{
+ kbdc_lock_assert(kbdc);
+
empty_both_buffers(kbdc, 10);
if (!set_controller_command_byte(kbdc, 0xff, command_byte)) {
@@ -948,6 +970,8 @@
int stat[3];
int i;
+ kbdc_lock_assert(kbdc);
+
switch((i = test_aux_port(kbdc))) {
case 1: /* ignore these errors */
case 2:
@@ -1031,6 +1055,8 @@
{
int stat[3];
+ kbdc_lock_assert(sc->kbdc);
+
/*
* FIXME: Synaptics TouchPad seems to go back to Relative Mode with
* no obvious reason. Thus we check the current mode and restore the
@@ -1136,8 +1162,7 @@
int s;
/* don't let anybody mess with the aux device */
- if (!kbdc_lock(sc->kbdc, TRUE))
- return (EIO);
+ kbdc_lock(sc->kbdc);
s = spltty();
/* block our watchdog timer */
@@ -1158,7 +1183,7 @@
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR */
splx(s);
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
log(LOG_ERR,
"psm%d: unable to set the command byte (reinitialize).\n",
sc->unit);
@@ -1214,7 +1239,7 @@
}
}
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
return (err);
}
@@ -1259,7 +1284,7 @@
if (bootverbose) \
--verbose; \
kbdc_set_device_mask(sc->kbdc, mask); \
- kbdc_lock(sc->kbdc, FALSE); \
+ kbdc_unlock(sc->kbdc); \
return (v); \
} while (0)
@@ -1306,12 +1331,7 @@
device_set_desc(dev, "PS/2 Mouse");
- if (!kbdc_lock(sc->kbdc, TRUE)) {
- printf("psm%d: unable to lock the controller.\n", unit);
- if (bootverbose)
- --verbose;
- return (ENXIO);
- }
+ kbdc_lock(sc->kbdc);
/*
* NOTE: two bits in the command byte controls the operation of the
@@ -1572,7 +1592,7 @@
/* done */
kbdc_set_device_mask(sc->kbdc, mask | KBD_AUX_CONTROL_BITS);
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
return (0);
}
@@ -1674,7 +1694,6 @@
struct psm_softc *sc;
int command_byte;
int err;
- int s;
/* Get device data */
sc = dev->si_drv1;
@@ -1715,11 +1734,9 @@
sc->pkterrors = 0;
/* don't let timeout routines in the keyboard driver to poll the kbdc */
- if (!kbdc_lock(sc->kbdc, TRUE))
- return (EIO);
+ kbdc_lock(sc->kbdc);
/* save the current controller command byte */
- s = spltty();
command_byte = get_controller_command_byte(sc->kbdc);
/* enable the aux port and temporalily disable the keyboard */
@@ -1728,21 +1745,12 @@
KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT |
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* CONTROLLER ERROR; do you know how to get out of this? */
- kbdc_lock(sc->kbdc, FALSE);
- splx(s);
+ kbdc_unlock(sc->kbdc);
log(LOG_ERR,
"psm%d: unable to set the command byte (psmopen).\n",
sc->unit);
return (EIO);
}
- /*
- * Now that the keyboard controller is told not to generate
- * the keyboard and mouse interrupts, call `splx()' to allow
- * the other tty interrupts. The clock interrupt may also occur,
- * but timeout routines will be blocked by the poll flag set
- * via `kbdc_lock()'
- */
- splx(s);
/* enable the mouse device */
err = doopen(sc, command_byte);
@@ -1750,7 +1758,7 @@
/* done */
if (err == 0)
sc->state |= PSM_OPEN;
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
return (err);
}
@@ -1760,18 +1768,14 @@
struct psm_softc *sc = dev->si_drv1;
int stat[3];
int command_byte;
- int s;
/* don't let timeout routines in the keyboard driver to poll the kbdc */
- if (!kbdc_lock(sc->kbdc, TRUE))
- return (EIO);
+ kbdc_lock(sc->kbdc);
/* save the current controller command byte */
- s = spltty();
command_byte = get_controller_command_byte(sc->kbdc);
if (command_byte == -1) {
- kbdc_lock(sc->kbdc, FALSE);
- splx(s);
+ kbdc_unlock(sc->kbdc);
return (EIO);
}
@@ -1790,7 +1794,6 @@
* so long as the mouse will accept the DISABLE command.
*/
}
- splx(s);
/* stop the watchdog timer */
callout_stop(&sc->callout);
@@ -1842,7 +1845,7 @@
/* close is almost always successful */
sc->state &= ~PSM_OPEN;
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
return (0);
}
@@ -1972,8 +1975,7 @@
{
int s;
- if (!kbdc_lock(sc->kbdc, TRUE))
- return (EIO);
+ kbdc_lock(sc->kbdc);
s = spltty();
*c = get_controller_command_byte(sc->kbdc);
@@ -1983,7 +1985,7 @@
KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
/* this is CONTROLLER ERROR */
splx(s);
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
return (EIO);
}
@@ -1996,8 +1998,8 @@
* output buffer; throw it away. Note that the second argument
* to `empty_aux_buffer()' is zero, so that the call will just
* flush the internal queue.
- * `psmintr()' will be invoked after `splx()' if an interrupt is
- * pending; it will see no data and returns immediately.
+ * `psmintr()' will be invoked after `kbdc_unlock()' if an interrupt
+ * is pending; it will see no data and returns immediately.
*/
empty_aux_buffer(sc->kbdc, 0); /* flush the queue */
read_aux_data_no_wait(sc->kbdc); /* throw away data if any */
@@ -2052,7 +2054,7 @@
error = EIO;
}
- kbdc_lock(sc->kbdc, FALSE);
+ kbdc_unlock(sc->kbdc);
return (error);
}
@@ -2075,14 +2077,17 @@
error = uiomove(buf, l, uio);
if (error)
break;
+ kbdc_lock(sc->kbdc);
for (i = 0; i < l; i++) {
VLOG(4, (LOG_DEBUG, "psm: cmd 0x%x\n", buf[i]));
if (!write_aux_command(sc->kbdc, buf[i])) {
+ kbdc_unlock(sc->kbdc);
VLOG(2, (LOG_DEBUG,
"psm: cmd 0x%x failed.\n", buf[i]));
return (reinitialize(sc, FALSE));
}
}
+ kbdc_unlock(sc->kbdc);
}
return (error);
@@ -2425,10 +2430,9 @@
sc = (struct psm_softc *)arg;
s = spltty();
- if (sc->watchdog && kbdc_lock(sc->kbdc, TRUE)) {
+ if (sc->watchdog) {
VLOG(4, (LOG_DEBUG, "psm%d: lost interrupt?\n", sc->unit));
psmintr(sc);
- kbdc_lock(sc->kbdc, FALSE);
}
sc->watchdog = TRUE;
splx(s);
@@ -2480,6 +2484,17 @@
SYSCTL_INT(_hw_psm, OID_AUTO, elantech_support, CTLFLAG_RDTUN,
&elantech_support, 0, "Enable support for Elantech touchpads");
+static int
+psm_read_aux_data(KBDC kbdc)
+{
+ int c;
+
+ kbdc_lock(kbdc);
+ c = read_aux_data_no_wait(kbdc);
+ kbdc_unlock(kbdc);
+ return (c);
+}
+
static void
psmintr(void *arg)
{
@@ -2490,7 +2505,7 @@
/* read until there is nothing to read */
- while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
+ while((c = psm_read_aux_data(sc->kbdc)) != -1) {
pb = &sc->pqueue[sc->pqueue_end];
/* discard the byte if the device is not open */
@@ -2574,8 +2589,10 @@
VLOG(3, (LOG_DEBUG,
"psmintr: re-enable the mouse.\n"));
pb->inputbytes = 0;
+ kbdc_lock(sc->kbdc);
disable_aux_dev(sc->kbdc);
enable_aux_dev(sc->kbdc);
+ kbdc_unlock(sc->kbdc);
} else {
VLOG(3, (LOG_DEBUG,
"psmintr: discard a byte (%d)\n",
@@ -5717,8 +5734,10 @@
if (arg == PROBE) {
/* Create sysctl tree. */
+ kbdc_unlock(sc->kbdc);
synaptics_sysctl_create_tree(sc, "synaptics",
"Synaptics TouchPad");
+ kbdc_lock(sc->kbdc);
sc->hw.buttons = buttons;
}
@@ -5991,7 +6010,9 @@
synaptics_passthrough_off(sc);
if (arg == PROBE) {
+ kbdc_unlock(sc->kbdc);
trackpoint_sysctl_create_tree(sc);
+ kbdc_lock(sc->kbdc);
/*
* Don't overwrite hwid and buttons when we are
* a guest device.
@@ -6360,7 +6381,9 @@
sc->hw.buttons = 3;
/* Initialize synaptics movement smoother */
+ kbdc_unlock(sc->kbdc);
elantech_init_synaptics(sc);
+ kbdc_lock(sc->kbdc);
for (id = 0; id < ELANTECH_MAX_FINGERS; id++)
PSM_FINGER_RESET(sc->elanaction.fingers[id]);

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 18, 1:08 PM (13 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27709930
Default Alt Text
D10263.diff (25 KB)

Event Timeline