Browse Source

[hidbus] Add intr_poll method to HID interrupt interface

And implement it for both IIC and USB backends. Not tested with IIC.
master
Vladimir Kondratyev 7 months ago
parent
commit
53abbcb32d
6 changed files with 52 additions and 10 deletions
  1. +8
    -0
      hid_if.m
  2. +8
    -0
      hidbus.c
  3. +1
    -0
      hidbus.h
  4. +1
    -3
      hkbd.c
  5. +17
    -2
      iichid.c
  6. +17
    -5
      usbhid.c

+ 8
- 0
hid_if.m View File

@@ -73,6 +73,14 @@ METHOD int intr_stop {
device_t dev;
};

#
# The following function gets called from the HID keyboard driver
# when the system has paniced.
#
METHOD void intr_poll {
device_t dev;
};

# HID interface

#

+ 8
- 0
hidbus.c View File

@@ -318,6 +318,14 @@ hidbus_set_xfer(device_t child, uint8_t xfer)
return (HID_INTR_STOP(device_get_parent(bus)));
}

void
hidbus_intr_poll(device_t child)
{
device_t bus = device_get_parent(child);

HID_INTR_POLL(device_get_parent(bus));
}

/*
* HID interface
*/

+ 1
- 0
hidbus.h View File

@@ -169,6 +169,7 @@ 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);
void hidbus_intr_poll(device_t);

/* hidbus HID interface */
int hid_get_report_descr(device_t, void **, uint16_t *);

+ 1
- 3
hkbd.c View File

@@ -456,9 +456,7 @@ hkbd_do_poll(struct hkbd_softc *sc, uint8_t wait)

while (sc->sc_inputs == 0) {

#ifdef NOT_YET
usbd_transfer_poll(sc->sc_xfer, HKBD_N_TRANSFER);
#endif
hidbus_intr_poll(sc->sc_dev);

/* Delay-optimised support for repetition of keys */
if (hkbd_any_key_pressed(sc)) {

+ 17
- 2
iichid.c View File

@@ -281,7 +281,8 @@ iichid_cmd_read(struct iichid_softc* sc, void *buf, uint16_t maxlen,
int how = do_poll ? IIC_DONTWAIT : IIC_WAIT;
int error;

if (iicbus_request_bus(parent, sc->dev, how) != 0)
if (!HID_IN_POLLING_MODE_FUNC() &&
iicbus_request_bus(parent, sc->dev, how) != 0)
return (IIC_EBUSBSY);

error = iicbus_transfer(sc->dev, msgs, nitems(msgs));
@@ -312,7 +313,8 @@ iichid_cmd_read(struct iichid_softc* sc, void *buf, uint16_t maxlen,

/* DPRINTF(sc, "%*D - %*D\n", 2, actbuf, " ", actlen, buf, " "); */
out:
iicbus_release_bus(parent, sc->dev);
if (!HID_IN_POLLING_MODE_FUNC())
iicbus_release_bus(parent, sc->dev);
return (error);
}

@@ -831,6 +833,18 @@ iichid_intr_stop(device_t dev)
return (0);
}

static void
iichid_intr_poll(device_t dev)
{
struct iichid_softc* sc = device_get_softc(dev);
uint16_t actual = 0;
int error;

error = iichid_cmd_read(sc, sc->ibuf, sc->isize, &actual, false);
if (error == 0 && actual > (sc->iid != 0 ? 1 : 0) && sc->open)
sc->intr_handler(sc->intr_context, sc->ibuf, actual);
}

/*
* HID interface
*/
@@ -1303,6 +1317,7 @@ static device_method_t iichid_methods[] = {
DEVMETHOD(hid_intr_unsetup, iichid_intr_unsetup),
DEVMETHOD(hid_intr_start, iichid_intr_start),
DEVMETHOD(hid_intr_stop, iichid_intr_stop),
DEVMETHOD(hid_intr_poll, iichid_intr_poll),

/* HID interface */
DEVMETHOD(hid_get_report_descr, iichid_get_report_desc),

+ 17
- 5
usbhid.c View File

@@ -181,7 +181,8 @@ tr_setup:
}
sc->sc_tr_error = EIO;
tr_exit:
wakeup(sc);
if (!HID_IN_POLLING_MODE_FUNC())
wakeup(sc);
return;
}
}
@@ -303,7 +304,8 @@ uhid_write_callback(struct usb_xfer *xfer, usb_error_t error)
DPRINTFN(1, "error=%s\n", usbd_errstr(error));
sc->sc_tr_error = EIO;
tr_exit:
wakeup(sc);
if (!HID_IN_POLLING_MODE_FUNC())
wakeup(sc);
return;
}
}
@@ -438,6 +440,14 @@ usbhid_intr_stop(device_t dev)
return (0);
}

static void
usbhid_intr_poll(device_t dev)
{
struct uhid_softc* sc = device_get_softc(dev);

usbd_transfer_poll(sc->sc_xfer, UHID_N_TRANSFER);
}

/*
* HID interface
*/
@@ -465,7 +475,7 @@ usbhid_write(device_t dev, void *buf, uint16_t len)
struct uhid_softc* sc = device_get_softc(dev);
int error = 0;

mtx_lock(sc->sc_intr_mtx);
HID_MTX_LOCK(sc->sc_intr_mtx);
sc->sc_tr_buf = buf;
sc->sc_tr_len = len;

@@ -474,7 +484,8 @@ usbhid_write(device_t dev, void *buf, uint16_t len)
else
usbd_transfer_start(sc->sc_xfer[UHID_INTR_DT_WR]);

if (msleep_sbt(sc, sc->sc_intr_mtx, 0, "uhid wr",
if (!HID_IN_POLLING_MODE_FUNC() &&
msleep_sbt(sc, sc->sc_intr_mtx, 0, "uhid wr",
SBT_1MS * USB_DEFAULT_TIMEOUT, 0, C_HARDCLOCK) == EWOULDBLOCK) {
DPRINTF("USB write timed out\n");
usbd_transfer_stop(sc->sc_xfer[UHID_CTRL_DT_WR]);
@@ -483,7 +494,7 @@ usbhid_write(device_t dev, void *buf, uint16_t len)
} else
error = sc->sc_tr_error;

mtx_unlock(sc->sc_intr_mtx);
HID_MTX_UNLOCK(sc->sc_intr_mtx);

return (error);
}
@@ -753,6 +764,7 @@ static device_method_t usbhid_methods[] = {
DEVMETHOD(hid_intr_unsetup, usbhid_intr_unsetup),
DEVMETHOD(hid_intr_start, usbhid_intr_start),
DEVMETHOD(hid_intr_stop, usbhid_intr_stop),
DEVMETHOD(hid_intr_poll, usbhid_intr_poll),

/* HID interface */
DEVMETHOD(hid_get_report_descr, usbhid_get_report_desc),

Loading…
Cancel
Save