Browse Source

[hkbd] Port to hidbus and attach to build.

No KDB and LEDs support yet
master
Vladimir Kondratyev 7 months ago
parent
commit
6402fe08e0
7 changed files with 247 additions and 354 deletions
  1. +2
    -0
      Makefile
  2. +9
    -0
      hid.c
  3. +4
    -0
      hid.h
  4. +25
    -18
      hidbus.c
  5. +25
    -1
      hidbus.h
  6. +182
    -324
      hkbd.c
  7. +0
    -11
      usbhid.c

+ 2
- 0
Makefile View File

@@ -9,7 +9,9 @@ SRCS += hid_debug.h hid_debug.c
SRCS += usbdevs.h usbhid.c
SRCS += acpi_if.h bus_if.h device_if.h iicbus_if.h
SRCS += opt_acpi.h opt_usb.h opt_evdev.h
SRCS += opt_kbd.h opt_ukbd.h hkbd.c
CFLAGS += -DHID_DEBUG
CFLAGS += -DEVDEV_SUPPORT
#CFLAGS += -DHAVE_ACPI_IICBUS
#CFLAGS += -DHAVE_IG4_POLLING


+ 9
- 0
hid.c View File

@@ -33,7 +33,10 @@
*/

#include <sys/param.h>
#include <sys/kdb.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/proc.h>

#include "hid.h"

@@ -115,5 +118,11 @@ hid_tlc_locate(const void *desc, hid_size_t size, int32_t u, enum hid_kind k,
return (0);
}

int
hid_in_polling_mode(void)
{
return (HID_IN_POLLING_MODE_VALUE());
}

MODULE_DEPEND(hid, usb, 1, 1, 1);
MODULE_VERSION(hid, 1);

+ 4
- 0
hid.h View File

@@ -40,6 +40,9 @@
SYSCTL_DECL(_hw_hid);
#endif

#define HID_IN_POLLING_MODE_FUNC() hid_in_polling_mode()
#define HID_IN_POLLING_MODE_VALUE() (SCHEDULER_STOPPED() || kdb_active)

/*
* Walk through all HID items hi belonging Top Level Collection #tidx
*/
@@ -75,5 +78,6 @@ int hid_tlc_locate(const void *desc, hid_size_t size, int32_t u,
enum hid_kind k, uint8_t tlc_index, uint8_t index,
struct hid_location *loc, uint32_t *flags, uint8_t *id,
struct hid_absinfo *ai);
int hid_in_polling_mode(void);

#endif /* _HID_H_ */

+ 25
- 18
hidbus.c View File

@@ -53,7 +53,8 @@ static device_detach_t hidbus_detach;

struct hidbus_softc {
device_t dev;
struct mtx lock;
struct mtx *lock;
struct mtx mtx;

STAILQ_HEAD(, hidbus_ivars) tlcs;
};
@@ -72,26 +73,21 @@ hidbus_add_child(device_t dev, u_int order, const char *name, int unit)
tlc = malloc(sizeof(struct hidbus_ivars), M_DEVBUF, M_WAITOK | M_ZERO);
tlc->child = child;
device_set_ivars(child, tlc);
mtx_lock(&sc->lock);
mtx_lock(sc->lock);
STAILQ_INSERT_TAIL(&sc->tlcs, tlc, link);
mtx_unlock(&sc->lock);
mtx_unlock(sc->lock);

return (child);
}

static int
hidbus_enumerate_children(device_t dev)
hidbus_enumerate_children(device_t dev, void* data, uint16_t len)
{
struct hid_data *hd;
struct hid_item hi;
device_t child;
void *data;
uint16_t len;
uint8_t index = 0;

if (HID_GET_REPORT_DESCR(device_get_parent(dev), &data, &len) != 0)
return (ENXIO);

/* Add a child for each top level collection */
hd = hid_start_parse(data, len, 1 << hid_input);
while (hid_get_item(hd, &hi)) {
@@ -130,15 +126,26 @@ static int
hidbus_attach(device_t dev)
{
struct hidbus_softc *sc = device_get_softc(dev);
void *d_ptr;
uint16_t d_len;
int error;

sc->dev = dev;
STAILQ_INIT(&sc->tlcs);

mtx_init(&sc->lock, "hidbus lock", NULL, MTX_DEF);
HID_INTR_SETUP(device_get_parent(dev), &sc->lock, hidbus_intr, sc);
if (HID_GET_REPORT_DESCR(device_get_parent(dev), &d_ptr, &d_len) != 0)
return (ENXIO);

mtx_init(&sc->mtx, "hidbus lock", NULL, MTX_DEF);
if (hid_is_keyboard(d_ptr, d_len))
sc->lock = HID_SYSCONS_MTX;
else
sc->lock = &sc->mtx;


HID_INTR_SETUP(device_get_parent(dev), sc->lock, hidbus_intr, sc);

error = hidbus_enumerate_children(dev);
error = hidbus_enumerate_children(dev, d_ptr, d_len);
if (error != 0) {
hidbus_detach(dev);
return (ENXIO);
@@ -160,7 +167,7 @@ hidbus_detach(device_t dev)
device_delete_children(dev);

HID_INTR_UNSETUP(device_get_parent(dev));
mtx_destroy(&sc->lock);
mtx_destroy(&sc->mtx);

return (0);
}
@@ -173,9 +180,9 @@ hidbus_child_deleted(device_t bus, device_t child)

KASSERT(!sc->open, ("Child device is running"));

mtx_lock(&sc->lock);
mtx_lock(sc->lock);
STAILQ_REMOVE(&sc->tlcs, tlc, hidbus_ivars, link);
mtx_unlock(&sc->lock);
mtx_unlock(sc->lock);
free(tlc, M_DEVBUF);
}

@@ -258,7 +265,7 @@ hidbus_get_lock(device_t child)
{
struct hidbus_softc *sc = device_get_softc(device_get_parent(child));

return (&sc->lock);
return (sc->lock);
}

void
@@ -267,7 +274,7 @@ hidbus_intr(void *context, void *buf, uint16_t len)
struct hidbus_softc *sc = context;
struct hidbus_ivars *tlc;

mtx_assert(&sc->lock, MA_OWNED);
mtx_assert(sc->lock, MA_OWNED);

/*
* Broadcast input report to all subscribers.
@@ -290,7 +297,7 @@ hidbus_set_xfer(device_t child, uint8_t xfer)
struct hidbus_ivars *tlc;
uint8_t dev_xfer = 0, old_dev_xfer = 0;

mtx_assert(&sc->lock, MA_OWNED);
mtx_assert(sc->lock, MA_OWNED);
KASSERT((xfer & ~HID_XFER_ALL) == 0, ("Bad xfer mask"));

STAILQ_FOREACH(tlc, &sc->tlcs, link)

+ 25
- 1
hidbus.h View File

@@ -139,9 +139,33 @@ struct hid_device_id {
#define HID_GET_DRIVER_INFO(did) \
(did)->driver_info

/*
* General purpose locking wrappers to ease supporting
* HID polled mode:
*/
#define HID_SYSCONS_MTX (&Giant)
#ifdef INVARIANTS
#define HID_MTX_ASSERT(_m, _t) do { \
if (!HID_IN_POLLING_MODE_FUNC()) \
mtx_assert(_m, _t); \
} while (0)
#else
#define HID_MTX_ASSERT(_m, _t) do { } while (0)
#endif

#define HID_MTX_LOCK(_m) do { \
if (!HID_IN_POLLING_MODE_FUNC()) \
mtx_lock(_m); \
} while (0)

#define HID_MTX_UNLOCK(_m) do { \
if (!HID_IN_POLLING_MODE_FUNC()) \
mtx_unlock(_m); \
} while (0)

const struct hid_device_id *hidbus_lookup_id(device_t,
const struct hid_device_id *, size_t);
int hidbus_lookup_driver_info(device_t,
int hidbus_lookup_driver_info(device_t,
const struct hid_device_id *, size_t);
struct mtx * hidbus_get_lock(device_t);
int hidbus_set_xfer(device_t, uint8_t);

+ 182
- 324
hkbd.c
File diff suppressed because it is too large
View File


+ 0
- 11
usbhid.c View File

@@ -563,17 +563,6 @@ uhid_probe(device_t dev)
if (usb_test_quirk(uaa, UQ_HID_IGNORE))
return (ENXIO);

/*
* Don't attach to mouse and keyboard devices, hence then no
* "nomatch" event is generated and then ums and ukbd won't
* attach properly when loaded.
*/
if ((uaa->info.bInterfaceClass == UICLASS_HID) &&
(uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) &&
(((uaa->info.bInterfaceProtocol == UIPROTO_BOOT_KEYBOARD) &&
!usb_test_quirk(uaa, UQ_KBD_IGNORE))))
return (ENXIO);

return (BUS_PROBE_GENERIC);
}


Loading…
Cancel
Save