Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142228141
D10263.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
D10263.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D10263: psm(4), evdev support part 1: atkbdc access locking
Attached
Detach File
Event Timeline
Log In to Comment