evdev: Remove evdev.ko linkage dependency on kbd driver

Move evdev_ev_kbd_event() helper from evdev to kbd.c as otherwise evdev
unconditionally requires all keyboard and console stuff to be compiled
into the kernel. This dependency happens as evdev_ev_kbd_event() helper
references kbdsw global variable defined in kbd.c through use of
kbdd_ioctl() macro.

While here make all keyboard drivers respect evdev_rcpt_mask while setting
typematic rate and LEDs with evdev interface.

Requested by:	Milan Obuch <bsd@dino.sk>
Reviewed by:	hselasky, gonzo
Differential Revision:	https://reviews.freebsd.org/D16614
This commit is contained in:
wulf 2018-08-13 19:05:53 +00:00
parent 51b0af6028
commit dcc01c5e05
7 changed files with 100 additions and 46 deletions

View File

@ -267,8 +267,10 @@ static int typematic_delay(int delay);
static int typematic_rate(int rate);
#ifdef EVDEV_SUPPORT
static evdev_event_t atkbd_ev_event;
static const struct evdev_methods atkbd_evdev_methods = {
.ev_event = evdev_ev_kbd_event,
.ev_event = atkbd_ev_event,
};
#endif
@ -1205,6 +1207,22 @@ atkbd_reset(KBDC kbdc, int flags, int c)
return (0);
}
#ifdef EVDEV_SUPPORT
static void
atkbd_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
int32_t value)
{
keyboard_t *kbd = evdev_get_softc(evdev);
if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD &&
(type == EV_LED || type == EV_REP)) {
mtx_lock(&Giant);
kbd_ev_event(kbd, type, code, value);
mtx_unlock(&Giant);
}
}
#endif
/* local functions */
static int

View File

@ -141,7 +141,6 @@ uint16_t evdev_scancode2key(int *, int);
void evdev_push_mouse_btn(struct evdev_dev *, int);
void evdev_push_leds(struct evdev_dev *, int);
void evdev_push_repeats(struct evdev_dev *, keyboard_t *);
evdev_event_t evdev_ev_kbd_event;
/* Event reporting shortcuts: */
static __inline int

View File

@ -40,8 +40,6 @@
#include <dev/evdev/evdev.h>
#include <dev/evdev/input.h>
#include <dev/kbd/kbdreg.h>
#define NONE KEY_RESERVED
static uint16_t evdev_usb_scancodes[256] = {
@ -299,43 +297,3 @@ evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
}
void
evdev_ev_kbd_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
int32_t value)
{
keyboard_t *kbd = (keyboard_t *)evdev_get_softc(evdev);
int delay[2], leds, oleds;
size_t i;
if (type == EV_LED) {
leds = oleds = KBD_LED_VAL(kbd);
for (i = 0; i < nitems(evdev_led_codes); i++) {
if (evdev_led_codes[i] == code) {
if (value)
leds |= 1 << i;
else
leds &= ~(1 << i);
if (leds != oleds) {
mtx_lock(&Giant);
kbdd_ioctl(kbd, KDSETLED,
(caddr_t)&leds);
mtx_unlock(&Giant);
}
break;
}
}
} else if (type == EV_REP && code == REP_DELAY) {
delay[0] = value;
delay[1] = kbd->kb_delay2;
mtx_lock(&Giant);
kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
mtx_unlock(&Giant);
} else if (type == EV_REP && code == REP_PERIOD) {
delay[0] = kbd->kb_delay1;
delay[1] = value;
mtx_lock(&Giant);
kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
mtx_unlock(&Giant);
}
}

View File

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kbio.h>
#include <dev/evdev/input-event-codes.h>
#include <dev/kbd/kbdreg.h>
#define KBD_INDEX(dev) dev2unit(dev)
@ -1475,3 +1476,41 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate,
}
/* NOT REACHED */
}
void
kbd_ev_event(keyboard_t *kbd, uint16_t type, uint16_t code, int32_t value)
{
int delay[2], led = 0, leds, oleds;
if (type == EV_LED) {
leds = oleds = KBD_LED_VAL(kbd);
switch (code) {
case LED_CAPSL:
led = CLKED;
break;
case LED_NUML:
led = NLKED;
break;
case LED_SCROLLL:
led = SLKED;
break;
}
if (value)
leds |= led;
else
leds &= ~led;
if (leds != oleds)
kbdd_ioctl(kbd, KDSETLED, (caddr_t)&leds);
} else if (type == EV_REP && code == REP_DELAY) {
delay[0] = value;
delay[1] = kbd->kb_delay2;
kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
} else if (type == EV_REP && code == REP_PERIOD) {
delay[0] = kbd->kb_delay1;
delay[1] = value;
kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
}
}

View File

@ -253,6 +253,10 @@ keyboard_t *kbd_get_keyboard(int index);
int kbd_configure(int flags);
/* see `kb_config' above for flag bit definitions */
/* evdev2kbd mappings */
void kbd_ev_event(keyboard_t *kbd, uint16_t type,
uint16_t code, int32_t value);
#ifdef KBD_INSTALL_CDEV
/* virtual keyboard cdev driver functions */

View File

@ -384,8 +384,10 @@ static keyboard_switch_t kbdmuxsw = {
};
#ifdef EVDEV_SUPPORT
static evdev_event_t kbdmux_ev_event;
static const struct evdev_methods kbdmux_evdev_methods = {
.ev_event = evdev_ev_kbd_event,
.ev_event = kbdmux_ev_event,
};
#endif
@ -1390,6 +1392,22 @@ kbdmux_poll(keyboard_t *kbd, int on)
return (0);
}
#ifdef EVDEV_SUPPORT
static void
kbdmux_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
int32_t value)
{
keyboard_t *kbd = evdev_get_softc(evdev);
if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX &&
(type == EV_LED || type == EV_REP)) {
mtx_lock(&Giant);
kbd_ev_event(kbd, type, code, value);
mtx_unlock(&Giant);
}
}
#endif
/*****************************************************************************
*****************************************************************************
** Module

View File

@ -365,8 +365,10 @@ static device_detach_t ukbd_detach;
static device_resume_t ukbd_resume;
#ifdef EVDEV_SUPPORT
static evdev_event_t ukbd_ev_event;
static const struct evdev_methods ukbd_evdev_methods = {
.ev_event = evdev_ev_kbd_event,
.ev_event = ukbd_ev_event,
};
#endif
@ -1472,6 +1474,22 @@ ukbd_resume(device_t dev)
return (0);
}
#ifdef EVDEV_SUPPORT
static void
ukbd_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
int32_t value)
{
keyboard_t *kbd = evdev_get_softc(evdev);
if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD &&
(type == EV_LED || type == EV_REP)) {
mtx_lock(&Giant);
kbd_ev_event(kbd, type, code, value);
mtx_unlock(&Giant);
}
}
#endif
/* early keyboard probe, not supported */
static int
ukbd_configure(int flags)