uhidev(9): Make uhidev state opaque.

This makes the API simpler and clearer and gives us more latitude to
fix bugs in the state management without breaking the ABI.

XXX kernel ABI change to signature of uhidev_get_report_desc and
uhidev_open, and to struct uhidev_attach_arg, requires bump for
uhidev driver modules
This commit is contained in:
riastradh 2022-03-28 12:44:17 +00:00
parent 043c0ba21a
commit 0b6c2425fd
9 changed files with 207 additions and 234 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $ */
/* $NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $ */
/*-
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@ -146,7 +146,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.28 2022/03/28 12:43:12 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.29 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -301,7 +301,7 @@ static void geyser34_initialize(struct uatp_softc *);
static int geyser34_finalize(struct uatp_softc *);
static void geyser34_deferred_reset(struct uatp_softc *);
static void geyser34_reset_task(void *);
static void uatp_intr(struct uhidev *, void *, unsigned int);
static void uatp_intr(void *, void *, unsigned int);
static bool base_sample_softc_flag(const struct uatp_softc *, const uint8_t *);
static bool base_sample_input_flag(const struct uatp_softc *, const uint8_t *);
static void read_sample_1(uint8_t *, uint8_t *, const uint8_t *);
@ -486,7 +486,8 @@ static const struct uatp_knobs default_knobs = {
};
struct uatp_softc {
struct uhidev sc_hdev; /* uhidev(9) parent. */
device_t sc_dev;
struct uhidev *sc_hdev; /* uhidev(9) parent. */
struct usbd_device *sc_udev; /* USB device. */
device_t sc_wsmousedev; /* Attached wsmouse device. */
const struct uatp_parameters *sc_parameters;
@ -691,7 +692,7 @@ find_uatp_descriptor(const struct uhidev_attach_arg *uha)
static device_t
uatp_dev(const struct uatp_softc *sc)
{
return sc->sc_hdev.sc_dev;
return sc->sc_dev;
}
static uint8_t *
@ -931,12 +932,8 @@ uatp_attach(device_t parent, device_t self, void *aux)
int report_size, input_size;
struct wsmousedev_attach_args a;
/* Set up uhidev state. (Why doesn't uhidev do most of this?) */
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = uatp_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
sc->sc_udev = uha->uiaa->uiaa_device;
/* Identify ourselves to dmesg. */
@ -948,7 +945,7 @@ uatp_attach(device_t parent, device_t self, void *aux)
"vendor 0x%04x, product 0x%04x, report id %d\n",
(unsigned int)uha->uiaa->uiaa_vendor,
(unsigned int)uha->uiaa->uiaa_product,
(int)uha->reportid);
uha->reportid);
uhidev_get_report_desc(uha->parent, &report_descriptor, &report_size);
input_size = hid_report_size(report_descriptor, report_size, hid_input,
@ -1251,8 +1248,8 @@ uatp_enable(void *v)
tap_enable(sc);
uatp_clear_position(sc);
DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_open(%p)\n", &sc->sc_hdev));
return uhidev_open(&sc->sc_hdev);
DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_open(%p)\n", sc->sc_hdev));
return uhidev_open(sc->sc_hdev, &uatp_intr, sc);
}
static void
@ -1270,8 +1267,8 @@ uatp_disable(void *v)
tap_disable(sc);
sc->sc_status &=~ UATP_ENABLED;
DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_close(%p)\n", &sc->sc_hdev));
uhidev_close(&sc->sc_hdev);
DPRINTF(sc, UATP_DEBUG_MISC, ("uhidev_close(%p)\n", sc->sc_hdev));
uhidev_close(sc->sc_hdev);
}
static int
@ -1399,15 +1396,15 @@ geyser34_reset_task(void *arg)
/* Interrupt handler */
static void
uatp_intr(struct uhidev *addr, void *ibuf, unsigned int len)
uatp_intr(void *cookie, void *ibuf, unsigned int len)
{
struct uatp_softc *sc = (struct uatp_softc *)addr;
struct uatp_softc *sc = cookie;
uint8_t *input;
int dx, dy, dz, dw;
uint32_t buttons;
DPRINTF(sc, UATP_DEBUG_INTR, ("softc %p, ibuf %p, len %u\n",
addr, ibuf, len));
sc, ibuf, len));
/*
* Some devices break packets up into chunks, so we accumulate

View File

@ -1,4 +1,4 @@
/* $NetBSD: ucycom.c,v 1.54 2022/03/28 12:43:30 riastradh Exp $ */
/* $NetBSD: ucycom.c,v 1.55 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.54 2022/03/28 12:43:30 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.55 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -117,7 +117,8 @@ int ucycomdebug = 20;
#define UCYCOM_ORESET 0x08
struct ucycom_softc {
struct uhidev sc_hdev;
device_t sc_dev;
struct uhidev *sc_hdev;
struct usbd_device *sc_udev;
struct usb_task sc_task;
@ -176,7 +177,7 @@ Static int ucycomparam(struct tty *, struct termios *);
Static void ucycomstart(struct tty *);
Static void ucycomstarttask(void *);
Static void ucycomwritecb(struct usbd_xfer *, void *, usbd_status);
Static void ucycom_intr(struct uhidev *, void *, u_int);
Static void ucycom_intr(void *, void *, u_int);
Static int ucycom_configure(struct ucycom_softc *, uint32_t, uint8_t);
Static void tiocm_to_ucycom(struct ucycom_softc *, u_long, int);
Static int ucycom_to_tiocm(struct ucycom_softc *);
@ -222,10 +223,8 @@ ucycom_attach(device_t parent, device_t self, void *aux)
int size, repid;
void *desc;
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = ucycom_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
sc->sc_udev = uha->uiaa->uiaa_device;
sc->sc_init_state = UCYCOM_INIT_NONE;
@ -280,7 +279,7 @@ ucycom_detach(device_t self, int flags)
mutex_spin_exit(&tty_lock);
}
/* Wait for processes to go away. */
usb_detach_waitold(sc->sc_hdev.sc_dev);
usb_detach_waitold(sc->sc_dev);
splx(s);
/* locate the major number */
@ -358,7 +357,7 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l)
return EIO;
if (sc->sc_init_state != UCYCOM_INIT_INITED)
return ENXIO;
if (!device_is_active(sc->sc_hdev.sc_dev))
if (!device_is_active(sc->sc_dev))
return ENXIO;
tp = sc->sc_tty;
@ -375,7 +374,7 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l)
tp->t_dev = dev;
err = uhidev_open(&sc->sc_hdev);
err = uhidev_open(sc->sc_hdev, &ucycom_intr, sc);
if (err) {
/* Any cleanup? */
splx(s);
@ -617,7 +616,7 @@ ucycomstarttask(void *cookie)
usbd_status err;
/* What can we do on error? */
err = uhidev_write_async(&sc->sc_hdev, sc->sc_obuf, sc->sc_olen, 0,
err = uhidev_write_async(sc->sc_hdev, sc->sc_obuf, sc->sc_olen, 0,
USBD_NO_TIMEOUT, ucycomwritecb, sc);
#ifdef UCYCOM_DEBUG
@ -942,7 +941,7 @@ ucycom_configure(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg)
report[2] = (baud >> 16) & 0xff;
report[3] = (baud >> 24) & 0xff;
report[4] = cfg;
err = uhidev_set_report(&sc->sc_hdev, UHID_FEATURE_REPORT,
err = uhidev_set_report(sc->sc_hdev, UHID_FEATURE_REPORT,
report, sc->sc_flen);
if (err != 0) {
DPRINTF(("%s\n", usbd_errstr(err)));
@ -959,9 +958,9 @@ ucycom_configure(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg)
}
Static void
ucycom_intr(struct uhidev *addr, void *ibuf, u_int len)
ucycom_intr(void *cookie, void *ibuf, u_int len)
{
struct ucycom_softc *sc = (struct ucycom_softc *)addr;
struct ucycom_softc *sc = cookie;
struct tty *tp = sc->sc_tty;
int (*rint)(int , struct tty *) = tp->t_linesw->l_rint;
uint8_t *cp = ibuf;
@ -1005,8 +1004,7 @@ ucycom_intr(struct uhidev *addr, void *ibuf, u_int len)
DPRINTFN(7,("ucycom_intr: char=0x%02x\n", *cp));
if ((*rint)(*cp++, tp) == -1) {
/* XXX what should we do? */
aprint_error_dev(sc->sc_hdev.sc_dev,
"lost a character\n");
aprint_error_dev(sc->sc_dev, "lost a character\n");
break;
}
}
@ -1124,7 +1122,7 @@ ucycom_set_status(struct ucycom_softc *sc)
memset(sc->sc_obuf, 0, sc->sc_olen);
sc->sc_obuf[0] = sc->sc_mcr;
err = uhidev_write(&sc->sc_hdev, sc->sc_obuf, sc->sc_olen);
err = uhidev_write(sc->sc_hdev, sc->sc_obuf, sc->sc_olen);
if (err) {
DPRINTF(("ucycom_set_status: err=%d\n", err));
}
@ -1137,7 +1135,7 @@ ucycom_get_cfg(struct ucycom_softc *sc)
int err, cfg, baud;
uint8_t report[5];
err = uhidev_get_report(&sc->sc_hdev, UHID_FEATURE_REPORT,
err = uhidev_get_report(sc->sc_hdev, UHID_FEATURE_REPORT,
report, sc->sc_flen);
if (err) {
DPRINTF(("%s: failed\n", __func__));
@ -1163,7 +1161,7 @@ ucycom_cleanup(struct ucycom_softc *sc)
obuf = sc->sc_obuf;
sc->sc_obuf = NULL;
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
if (obuf != NULL)
kmem_free(obuf, sc->sc_olen);

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhid.c,v 1.122 2022/03/28 12:43:12 riastradh Exp $ */
/* $NetBSD: uhid.c,v 1.123 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.122 2022/03/28 12:43:12 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.123 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@ -85,8 +85,10 @@ int uhiddebug = 0;
#endif
struct uhid_softc {
struct uhidev sc_hdev;
device_t sc_dev;
struct uhidev *sc_hdev;
struct usbd_device *sc_udev;
uint8_t sc_report_id;
kmutex_t sc_lock;
kcondvar_t sc_cv;
@ -144,7 +146,7 @@ const struct cdevsw uhid_cdevsw = {
.d_flag = D_OTHER
};
static void uhid_intr(struct uhidev *, void *, u_int);
static void uhid_intr(void *, void *, u_int);
static int uhid_match(device_t, cfdata_t, void *);
static void uhid_attach(device_t, device_t, void *);
@ -176,13 +178,12 @@ uhid_attach(device_t parent, device_t self, void *aux)
int size, repid;
void *desc;
sc->sc_hdev.sc_dev = self;
selinit(&sc->sc_rsel);
sc->sc_hdev.sc_intr = uhid_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
sc->sc_udev = uha->uiaa->uiaa_device;
sc->sc_report_id = uha->reportid;
selinit(&sc->sc_rsel);
uhidev_get_report_desc(uha->parent, &desc, &size);
repid = uha->reportid;
@ -232,9 +233,9 @@ uhid_detach(device_t self, int flags)
}
static void
uhid_intr(struct uhidev *addr, void *data, u_int len)
uhid_intr(void *cookie, void *data, u_int len)
{
struct uhid_softc *sc = (struct uhid_softc *)addr;
struct uhid_softc *sc = cookie;
#ifdef UHID_DEBUG
if (uhiddebug > 5) {
@ -306,7 +307,7 @@ uhidopen(dev_t dev, int flag, int mode, struct lwp *l)
mutex_exit(&proc_lock);
/* Open the uhidev -- after this point we can get interrupts. */
error = uhidev_open(&sc->sc_hdev);
error = uhidev_open(sc->sc_hdev, &uhid_intr, sc);
if (error)
goto fail1;
@ -354,7 +355,7 @@ uhidcancel(dev_t dev, int flag, int mode, struct lwp *l)
cv_broadcast(&sc->sc_cv);
mutex_exit(&sc->sc_lock);
uhidev_stop(&sc->sc_hdev);
uhidev_stop(sc->sc_hdev);
return 0;
}
@ -379,7 +380,7 @@ uhidclose(dev_t dev, int flag, int mode, struct lwp *l)
mutex_exit(&sc->sc_lock);
/* Prevent further interrupts. */
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
/* Hang up all select/poll. */
selnotify(&sc->sc_rsel, POLLHUP, 0);
@ -422,10 +423,10 @@ uhidread(dev_t dev, struct uio *uio, int flag)
DPRINTFN(1, ("uhidread\n"));
if (atomic_load_relaxed(&sc->sc_state) & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
extra = sc->sc_hdev.sc_report_id != 0;
extra = sc->sc_report_id != 0;
if (sc->sc_isize + extra > sizeof(buffer))
return ENOBUFS;
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
err = uhidev_get_report(sc->sc_hdev, UHID_INPUT_REPORT,
buffer, sc->sc_isize + extra);
if (err)
return EIO;
@ -489,7 +490,7 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
if (uhiddebug > 5) {
uint32_t i;
DPRINTF(("%s: outdata[%d] =", device_xname(sc->sc_hdev.sc_dev),
DPRINTF(("%s: outdata[%d] =", device_xname(sc->sc_dev),
error));
for (i = 0; i < size; i++)
DPRINTF((" %02x", sc->sc_obuf[i]));
@ -498,13 +499,13 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
#endif
if (!error) {
if (sc->sc_raw)
err = uhidev_write(&sc->sc_hdev, sc->sc_obuf, size);
err = uhidev_write(sc->sc_hdev, sc->sc_obuf, size);
else
err = uhidev_set_report(&sc->sc_hdev,
err = uhidev_set_report(sc->sc_hdev,
UHID_OUTPUT_REPORT, sc->sc_obuf, size);
if (err) {
DPRINTF(("%s: err = %d\n",
device_xname(sc->sc_hdev.sc_dev), err));
device_xname(sc->sc_dev), err));
error = EIO;
}
}
@ -581,7 +582,7 @@ uhidioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
break;
case USB_GET_REPORT_DESC:
uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
uhidev_get_report_desc(sc->sc_hdev, &desc, &size);
rd = (struct usb_ctl_report_desc *)addr;
size = uimin(size, sizeof(rd->ucrd_data));
rd->ucrd_size = size;
@ -590,10 +591,10 @@ uhidioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
case USB_SET_IMMED:
if (*(int *)addr) {
extra = sc->sc_hdev.sc_report_id != 0;
extra = sc->sc_report_id != 0;
if (sc->sc_isize + extra > sizeof(buffer))
return ENOBUFS;
err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
err = uhidev_get_report(sc->sc_hdev, UHID_INPUT_REPORT,
buffer, sc->sc_isize + extra);
if (err)
return EOPNOTSUPP;
@ -618,10 +619,10 @@ uhidioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
default:
return EINVAL;
}
extra = sc->sc_hdev.sc_report_id != 0;
extra = sc->sc_report_id != 0;
if (size + extra > sizeof(re->ucr_data))
return ENOBUFS;
err = uhidev_get_report(&sc->sc_hdev, re->ucr_report,
err = uhidev_get_report(sc->sc_hdev, re->ucr_report,
re->ucr_data, size + extra);
if (extra)
memmove(re->ucr_data, re->ucr_data+1, size);
@ -646,14 +647,14 @@ uhidioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
}
if (size > sizeof(re->ucr_data))
return ENOBUFS;
err = uhidev_set_report(&sc->sc_hdev, re->ucr_report,
err = uhidev_set_report(sc->sc_hdev, re->ucr_report,
re->ucr_data, size);
if (err)
return EIO;
break;
case USB_GET_REPORT_ID:
*(int *)addr = sc->sc_hdev.sc_report_id;
*(int *)addr = sc->sc_report_id;
break;
case USB_GET_DEVICE_DESC:

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhidev.c,v 1.89 2022/03/28 12:44:06 riastradh Exp $ */
/* $NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.89 2022/03/28 12:44:06 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -88,7 +88,18 @@ struct uhidev_softc {
void *sc_repdesc;
u_int sc_nrepid;
device_t *sc_subdevs;
struct uhidev {
struct uhidev_softc *sc_parent;
device_t sc_dev;
void (*sc_intr)(void *, void *, u_int);
void *sc_cookie;
krndsource_t sc_rndsource;
int sc_in_rep_size;
uint8_t sc_report_id;
uint8_t sc_state;
#define UHIDEV_OPEN 0x01 /* device is open */
#define UHIDEV_STOPPED 0x02 /* xfers are stopped */
} *sc_subdevs;
kmutex_t sc_lock;
kcondvar_t sc_cv;
@ -169,7 +180,6 @@ uhidev_attach(device_t parent, device_t self, void *aux)
usb_endpoint_descriptor_t *ed;
struct uhidev_attach_arg uha;
device_t dev;
struct uhidev *csc;
int maxinpktsize, size, nrepid, repid, repsz;
int *repsizes;
int i;
@ -405,40 +415,35 @@ uhidev_attach(device_t parent, device_t self, void *aux)
DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));
uha.parent = sc;
for (repid = 0; repid < nrepid; repid++) {
struct uhidev *scd = &sc->sc_subdevs[repid];
scd->sc_parent = sc;
scd->sc_report_id = repid;
scd->sc_in_rep_size = repsizes[repid];
DPRINTF(("uhidev_match: try repid=%d\n", repid));
if (hid_report_size(desc, size, hid_input, repid) == 0 &&
hid_report_size(desc, size, hid_output, repid) == 0 &&
hid_report_size(desc, size, hid_feature, repid) == 0) {
; /* already NULL in sc->sc_subdevs[repid] */
} else {
uha.parent = scd;
uha.reportid = repid;
locs[UHIDBUSCF_REPORTID] = repid;
dev = config_found(self, &uha, uhidevprint,
CFARGS(.submatch = config_stdsubmatch,
.locators = locs));
sc->sc_subdevs[repid] = dev;
if (dev != NULL) {
csc = device_private(dev);
csc->sc_in_rep_size = repsizes[repid];
#ifdef DIAGNOSTIC
DPRINTF(("uhidev_match: repid=%d dev=%p\n",
repid, dev));
if (csc->sc_intr == NULL) {
kmem_free(repsizes,
nrepid * sizeof(*repsizes));
aprint_error_dev(self,
"sc_intr == NULL\n");
return;
}
#endif
rnd_attach_source(&csc->rnd_source,
device_xname(dev),
RND_TYPE_TTY,
RND_FLAG_DEFAULT);
}
sc->sc_subdevs[repid].sc_dev = dev;
if (dev == NULL)
continue;
/*
* XXXSMP -- could be detached in the middle of
* sleeping for allocation in rnd_attach_source
*/
rnd_attach_source(&scd->sc_rndsource,
device_xname(dev), RND_TYPE_TTY, RND_FLAG_DEFAULT);
}
}
kmem_free(repsizes, nrepid * sizeof(*repsizes));
@ -495,19 +500,26 @@ uhidev_childdet(device_t self, device_t child)
struct uhidev_softc *sc = device_private(self);
for (i = 0; i < sc->sc_nrepid; i++) {
if (sc->sc_subdevs[i] == child)
if (sc->sc_subdevs[i].sc_dev == child)
break;
}
KASSERT(i < sc->sc_nrepid);
sc->sc_subdevs[i] = NULL;
sc->sc_subdevs[i].sc_dev = NULL;
/*
* XXXSMP -- could be reattached in the middle of sleeping for
* lock on sources to delete this in rnd_attach_source
*
* (Actually this can't happen right now because there's no
* rescan method, but if there were, it could.)
*/
rnd_detach_source(&sc->sc_subdevs[i].sc_rndsource);
}
static int
uhidev_detach(device_t self, int flags)
{
struct uhidev_softc *sc = device_private(self);
int i, rv;
struct uhidev *csc;
int rv;
DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
@ -524,28 +536,12 @@ uhidev_detach(device_t self, int flags)
* DETACH_FORCE and the children will not have the option of
* refusing detachment.
*/
for (i = 0; i < sc->sc_nrepid; i++) {
if (sc->sc_subdevs[i] == NULL)
continue;
/*
* XXX rnd_detach_source should go in uhidev_childdet,
* but the struct krndsource lives in the child's
* softc, which is gone by the time of childdet. The
* parent uhidev_softc should be changed to allocate
* the struct krndsource, not the child.
*/
csc = device_private(sc->sc_subdevs[i]);
rnd_detach_source(&csc->rnd_source);
rv = config_detach(sc->sc_subdevs[i], flags);
if (rv) {
rnd_attach_source(&csc->rnd_source,
device_xname(sc->sc_dev),
RND_TYPE_TTY, RND_FLAG_DEFAULT);
mutex_enter(&sc->sc_lock);
sc->sc_dying = 0;
mutex_exit(&sc->sc_lock);
return rv;
}
rv = config_detach_children(self, flags);
if (rv) {
mutex_enter(&sc->sc_lock);
sc->sc_dying = 0;
mutex_exit(&sc->sc_lock);
return rv;
}
KASSERTMSG(sc->sc_refcnt == 0,
@ -579,7 +575,6 @@ static void
uhidev_intr(struct usbd_xfer *xfer, void *addr, usbd_status status)
{
struct uhidev_softc *sc = addr;
device_t cdev;
struct uhidev *scd;
u_char *p;
u_int rep;
@ -618,12 +613,9 @@ uhidev_intr(struct usbd_xfer *xfer, void *addr, usbd_status status)
printf("uhidev_intr: bad repid %d\n", rep);
return;
}
cdev = sc->sc_subdevs[rep];
if (!cdev)
return;
scd = device_private(cdev);
scd = &sc->sc_subdevs[rep];
DPRINTFN(5,("uhidev_intr: rep=%d, scd=%p state=%#x\n",
rep, scd, scd ? scd->sc_state : 0));
rep, scd, scd->sc_state));
if (!(atomic_load_acquire(&scd->sc_state) & UHIDEV_OPEN))
return;
#ifdef UHIDEV_DEBUG
@ -637,13 +629,15 @@ uhidev_intr(struct usbd_xfer *xfer, void *addr, usbd_status status)
device_xname(sc->sc_dev)));
return;
}
rnd_add_uint32(&scd->rnd_source, (uintptr_t)(sc->sc_ibuf));
scd->sc_intr(scd, p, cc);
rnd_add_uint32(&scd->sc_rndsource, (uintptr_t)(sc->sc_ibuf));
scd->sc_intr(scd->sc_cookie, p, cc);
}
void
uhidev_get_report_desc(struct uhidev_softc *sc, void **desc, int *size)
uhidev_get_report_desc(struct uhidev *scd, void **desc, int *size)
{
struct uhidev_softc *sc = scd->sc_parent;
*desc = sc->sc_repdesc;
*size = sc->sc_repdesc_size;
}
@ -904,7 +898,8 @@ uhidev_close_pipes(struct uhidev_softc *sc)
}
int
uhidev_open(struct uhidev *scd)
uhidev_open(struct uhidev *scd, void (*intr)(void *, void *, u_int),
void *cookie)
{
struct uhidev_softc *sc = scd->sc_parent;
int error;
@ -923,6 +918,8 @@ uhidev_open(struct uhidev *scd)
error = EBUSY;
goto out;
}
scd->sc_intr = intr;
scd->sc_cookie = cookie;
atomic_store_release(&scd->sc_state, scd->sc_state | UHIDEV_OPEN);
/* Open the pipes which are shared by all report ids. */
@ -1067,9 +1064,19 @@ uhidev_close(struct uhidev *scd)
* We must drop the lock while doing this, because
* uhidev_write_callback takes the lock in softint context and
* it could deadlock with the xcall softint.
*
* It is safe to drop the lock now before zeroing sc_intr and
* sc_cookie because the driver is obligated not to reopen
* until after uhidev_close returns.
*/
mutex_exit(&sc->sc_lock);
xc_barrier(XC_HIGHPRI);
mutex_enter(&sc->sc_lock);
KASSERT((scd->sc_state & UHIDEV_OPEN) == 0);
scd->sc_intr = NULL;
scd->sc_cookie = NULL;
mutex_exit(&sc->sc_lock);
}
usbd_status

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhidev.h,v 1.25 2022/03/28 12:43:39 riastradh Exp $ */
/* $NetBSD: uhidev.h,v 1.26 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -33,34 +33,18 @@
#ifndef _DEV_USB_UHIDEV_H_
#define _DEV_USB_UHIDEV_H_
#include <sys/device.h>
#include <sys/rndsource.h>
#include <dev/usb/usbdi.h>
struct uhidev_softc;
struct uhidev {
device_t sc_dev; /* base device */
struct uhidev_softc *sc_parent;
uByte sc_report_id;
uint8_t sc_state; /* read/written under sc_parent->sc_lock */
#define UHIDEV_OPEN 0x01 /* device is open */
#define UHIDEV_STOPPED 0x02 /* xfers are stopped */
int sc_in_rep_size;
void (*sc_intr)(struct uhidev *, void *, u_int);
krndsource_t rnd_source;
};
struct uhidev;
struct uhidev_attach_arg {
struct usbif_attach_arg *uiaa;
struct uhidev_softc *parent;
struct uhidev *parent;
int reportid;
int reportsize;
};
void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
int uhidev_open(struct uhidev *);
void uhidev_get_report_desc(struct uhidev *, void **, int *);
int uhidev_open(struct uhidev *, void (*)(void *, void *, unsigned), void *);
void uhidev_stop(struct uhidev *);
void uhidev_close(struct uhidev *);
usbd_status uhidev_set_report(struct uhidev *, int, void *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ukbd.c,v 1.158 2022/03/28 12:43:12 riastradh Exp $ */
/* $NetBSD: ukbd.c,v 1.159 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.158 2022/03/28 12:43:12 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.159 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@ -235,9 +235,11 @@ Static const uint8_t ukbd_trtab[256] = {
#define KEY_ERROR 0x01
struct ukbd_softc {
struct uhidev sc_hdev;
device_t sc_dev;
struct uhidev *sc_hdev;
struct usbd_device *sc_udev;
struct usbd_interface *sc_iface;
int sc_report_id;
struct ukbd_data sc_ndata;
struct ukbd_data sc_odata;
@ -340,7 +342,7 @@ const struct wskbd_consops ukbd_consops = {
Static const char *ukbd_parse_desc(struct ukbd_softc *);
Static void ukbd_intr(struct uhidev *, void *, u_int);
Static void ukbd_intr(void *, void *, u_int);
Static void ukbd_decode(struct ukbd_softc *, struct ukbd_data *);
Static void ukbd_delayed_decode(void *);
@ -408,12 +410,11 @@ ukbd_attach(device_t parent, device_t self, void *aux)
const char *parseerr;
struct wskbddev_attach_args a;
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = ukbd_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
sc->sc_udev = uha->uiaa->uiaa_device;
sc->sc_iface = uha->uiaa->uiaa_iface;
sc->sc_report_id = uha->reportid;
sc->sc_flags = 0;
aprint_naive("\n");
@ -514,7 +515,7 @@ ukbd_enable(void *v, int on)
/* Should only be called to change state */
if ((sc->sc_flags & FLAG_ENABLED) != 0 && on != 0) {
#ifdef DIAGNOSTIC
aprint_error_dev(sc->sc_hdev.sc_dev, "bad call on=%d\n", on);
aprint_error_dev(sc->sc_dev, "bad call on=%d\n", on);
#endif
return EBUSY;
}
@ -522,10 +523,10 @@ ukbd_enable(void *v, int on)
DPRINTF(("%s: sc=%p on=%d\n", __func__, sc, on));
if (on) {
sc->sc_flags |= FLAG_ENABLED;
return uhidev_open(&sc->sc_hdev);
return uhidev_open(sc->sc_hdev, &ukbd_intr, sc);
} else {
sc->sc_flags &= ~FLAG_ENABLED;
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
return 0;
}
}
@ -573,7 +574,7 @@ ukbd_detach(device_t self, int flags)
* XXX console, if there are any other keyboards.
*/
printf("%s: was console keyboard\n",
device_xname(sc->sc_hdev.sc_dev));
device_xname(sc->sc_dev));
wskbd_cndetach();
ukbd_is_console = 1;
}
@ -587,8 +588,8 @@ ukbd_detach(device_t self, int flags)
USB_TASKQ_DRIVER, NULL);
/* The console keyboard does not get a disable call, so check pipe. */
if (sc->sc_hdev.sc_state & UHIDEV_OPEN)
uhidev_close(&sc->sc_hdev);
if (sc->sc_flags & FLAG_ENABLED)
uhidev_close(sc->sc_hdev);
return rv;
}
@ -608,8 +609,7 @@ ukbd_translate_keycodes(struct ukbd_softc *sc, struct ukbd_data *ud,
for (tp = tab; tp->from; tp++)
if (tp->from == i) {
if (tp->to & IS_PMF) {
pmf_event_inject(
sc->sc_hdev.sc_dev,
pmf_event_inject(sc->sc_dev,
tp->to & 0xff);
} else
setbit(ud->keys, tp->to);
@ -641,9 +641,9 @@ ukbd_translate_modifier(struct ukbd_softc *sc, uint16_t key)
}
void
ukbd_intr(struct uhidev *addr, void *ibuf, u_int len)
ukbd_intr(void *cookie, void *ibuf, u_int len)
{
struct ukbd_softc *sc = (struct ukbd_softc *)addr;
struct ukbd_softc *sc = cookie;
struct ukbd_data *ud = &sc->sc_ndata;
int i;
@ -768,7 +768,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
*/
if (ukbdtrace) {
struct ukbdtraceinfo *p = &ukbdtracedata[ukbdtraceindex];
p->unit = device_unit(sc->sc_hdev.sc_dev);
p->unit = device_unit(sc->sc_dev);
microtime(&p->tv);
p->ud = *ud;
if (++ukbdtraceindex >= UKBDTRACESIZE)
@ -923,7 +923,7 @@ ukbd_set_leds_task(void *v)
if ((leds & WSKBD_LED_CAPS) && sc->sc_capsloc.size == 1)
res |= 1 << sc->sc_capsloc.pos;
uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT, &res, 1);
uhidev_set_report(sc->sc_hdev, UHID_OUTPUT_REPORT, &res, 1);
}
#if defined(WSDISPLAY_COMPAT_RAWKBD) && defined(UKBD_REPEAT)
@ -1059,7 +1059,7 @@ ukbd_parse_desc(struct ukbd_softc *sc)
void *desc;
int ikey;
uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
uhidev_get_report_desc(sc->sc_hdev, &desc, &size);
ikey = 0;
sc->sc_nkeycode = 0;
d = hid_start_parse(desc, size, hid_input);
@ -1077,7 +1077,7 @@ ukbd_parse_desc(struct ukbd_softc *sc)
if (h.kind != hid_input || (h.flags & HIO_CONST) ||
HID_GET_USAGE_PAGE(h.usage) != HUP_KEYBOARD ||
h.report_ID != sc->sc_hdev.sc_report_id)
h.report_ID != sc->sc_report_id)
continue;
DPRINTF(("%s: ikey=%d usage=%#x flags=%#x pos=%d size=%d "
"cnt=%d\n", __func__, ikey, h.usage, h.flags, h.loc.pos,
@ -1120,13 +1120,13 @@ ukbd_parse_desc(struct ukbd_softc *sc)
hid_end_parse(d);
hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_NUM_LOCK),
sc->sc_hdev.sc_report_id, hid_output, &sc->sc_numloc, NULL);
sc->sc_report_id, hid_output, &sc->sc_numloc, NULL);
hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_CAPS_LOCK),
sc->sc_hdev.sc_report_id, hid_output, &sc->sc_capsloc, NULL);
sc->sc_report_id, hid_output, &sc->sc_capsloc, NULL);
hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_SCROLL_LOCK),
sc->sc_hdev.sc_report_id, hid_output, &sc->sc_scroloc, NULL);
sc->sc_report_id, hid_output, &sc->sc_scroloc, NULL);
hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_COMPOSE),
sc->sc_hdev.sc_report_id, hid_output, &sc->sc_compose, NULL);
sc->sc_report_id, hid_output, &sc->sc_compose, NULL);
return NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ums.c,v 1.102 2022/03/28 12:43:12 riastradh Exp $ */
/* $NetBSD: ums.c,v 1.103 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 1998, 2017 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.102 2022/03/28 12:43:12 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.103 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -75,7 +75,7 @@ int umsdebug = 0;
#define UMSUNIT(s) (minor(s))
struct ums_softc {
struct uhidev sc_hdev;
struct uhidev *sc_hdev;
struct usbd_device *sc_udev;
struct hidms sc_ms;
@ -85,7 +85,7 @@ struct ums_softc {
char sc_dying;
};
Static void ums_intr(struct uhidev *, void *, u_int);
Static void ums_intr(void *, void *, u_int);
Static int ums_enable(void *);
Static void ums_disable(void *);
@ -146,10 +146,7 @@ ums_attach(device_t parent, device_t self, void *aux)
aprint_naive("\n");
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = ums_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_hdev = uha->parent;
sc->sc_udev = uha->uiaa->uiaa_device;
quirks = usbd_get_quirks(sc->sc_udev)->uq_flags;
@ -218,7 +215,7 @@ ums_attach(device_t parent, device_t self, void *aux)
while (hid_get_item(d, &item)) {
if (item.kind != hid_input
|| HID_GET_USAGE_PAGE(item.usage) != HUP_GENERIC_DESKTOP
|| item.report_ID != sc->sc_hdev.sc_report_id)
|| item.report_ID != uha->reportid)
continue;
if (HID_GET_USAGE(item.usage) == HUG_X) {
sc->sc_ms.sc_calibcoords.minx = item.logical_minimum;
@ -238,7 +235,7 @@ ums_attach(device_t parent, device_t self, void *aux)
hidms_attach(self, &sc->sc_ms, &ums_accessops);
if (sc->sc_alwayson) {
error = uhidev_open(&sc->sc_hdev);
error = uhidev_open(sc->sc_hdev, &ums_intr, sc);
if (error != 0) {
aprint_error_dev(self,
"WARNING: couldn't open always-on device\n");
@ -279,7 +276,7 @@ ums_detach(device_t self, int flags)
DPRINTF(("ums_detach: sc=%p flags=%d\n", sc, flags));
if (sc->sc_alwayson)
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
/* No need to do reference counting of ums, wsmouse has all the goo. */
if (sc->sc_ms.hidms_wsmousedev != NULL)
@ -291,9 +288,9 @@ ums_detach(device_t self, int flags)
}
Static void
ums_intr(struct uhidev *addr, void *ibuf, u_int len)
ums_intr(void *cookie, void *ibuf, u_int len)
{
struct ums_softc *sc = (struct ums_softc *)addr;
struct ums_softc *sc = cookie;
if (sc->sc_enabled)
hidms_intr(&sc->sc_ms, ibuf, len);
@ -317,7 +314,7 @@ ums_enable(void *v)
sc->sc_ms.hidms_buttons = 0;
if (!sc->sc_alwayson) {
error = uhidev_open(&sc->sc_hdev);
error = uhidev_open(sc->sc_hdev, &ums_intr, sc);
if (error)
sc->sc_enabled = 0;
}
@ -341,7 +338,7 @@ ums_disable(void *v)
if (sc->sc_enabled) {
sc->sc_enabled = 0;
if (!sc->sc_alwayson)
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uthum.c,v 1.22 2022/03/28 12:43:12 riastradh Exp $ */
/* $NetBSD: uthum.c,v 1.23 2022/03/28 12:44:17 riastradh Exp $ */
/* $OpenBSD: uthum.c,v 1.6 2010/01/03 18:43:02 deraadt Exp $ */
/*
@ -22,7 +22,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.22 2022/03/28 12:43:12 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.23 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -74,7 +74,8 @@ static const uint8_t cmd_end[8] =
#define UTHUM_TYPE_TEMPER 2
struct uthum_softc {
struct uhidev sc_hdev;
device_t sc_dev;
struct uhidev * sc_hdev;
struct usbd_device * sc_udev;
u_char sc_dying;
uint16_t sc_flag;
@ -109,7 +110,6 @@ static int uthum_temper_temp(uint8_t, uint8_t);
static int uthum_sht1x_temp(uint8_t, uint8_t);
static int uthum_sht1x_rh(unsigned int, int);
static void uthum_intr(struct uhidev *, void *, u_int);
static void uthum_refresh(struct sysmon_envsys *, envsys_data_t *);
@ -134,11 +134,9 @@ uthum_attach(device_t parent, device_t self, void *aux)
int size, repid;
void *desc;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
sc->sc_udev = dev;
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = uthum_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_num_sensors = 0;
aprint_normal("\n");
@ -149,8 +147,7 @@ uthum_attach(device_t parent, device_t self, void *aux)
sc->sc_olen = hid_report_size(desc, size, hid_output, repid);
sc->sc_flen = hid_report_size(desc, size, hid_feature, repid);
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
sc->sc_hdev.sc_dev);
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
if (sc->sc_flen < 32) {
/* not sensor interface, just attach */
@ -230,8 +227,7 @@ uthum_detach(device_t self, int flags)
if (sc->sc_sme != NULL)
sysmon_envsys_unregister(sc->sc_sme);
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
sc->sc_hdev.sc_dev);
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
return rv;
}
@ -249,12 +245,6 @@ uthum_activate(device_t self, enum devact act)
return 0;
}
static void
uthum_intr(struct uhidev *addr, void *ibuf, u_int len)
{
/* do nothing */
}
static int
uthum_read_data(struct uthum_softc *sc, uint8_t target_cmd, uint8_t *buf,
size_t len, int need_delay)
@ -272,24 +262,24 @@ uthum_read_data(struct uthum_softc *sc, uint8_t target_cmd, uint8_t *buf,
/* issue query */
memset(cmdbuf, 0, sizeof(cmdbuf));
memcpy(cmdbuf, cmd_start, sizeof(cmd_start));
if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
if (uhidev_set_report(sc->sc_hdev, UHID_OUTPUT_REPORT,
cmdbuf, olen))
return EIO;
memset(cmdbuf, 0, sizeof(cmdbuf));
cmdbuf[0] = target_cmd;
if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
if (uhidev_set_report(sc->sc_hdev, UHID_OUTPUT_REPORT,
cmdbuf, olen))
return EIO;
memset(cmdbuf, 0, sizeof(cmdbuf));
for (i = 0; i < 7; i++) {
if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
if (uhidev_set_report(sc->sc_hdev, UHID_OUTPUT_REPORT,
cmdbuf, olen))
return EIO;
}
memcpy(cmdbuf, cmd_end, sizeof(cmd_end));
if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
if (uhidev_set_report(sc->sc_hdev, UHID_OUTPUT_REPORT,
cmdbuf, olen))
return EIO;
@ -299,7 +289,7 @@ uthum_read_data(struct uthum_softc *sc, uint8_t target_cmd, uint8_t *buf,
/* get answer */
flen = uimin(sc->sc_flen, sizeof(report));
if (uhidev_get_report(&sc->sc_hdev, UHID_FEATURE_REPORT,
if (uhidev_get_report(sc->sc_hdev, UHID_FEATURE_REPORT,
report, flen))
return EIO;
memcpy(buf, report, len);

View File

@ -1,4 +1,4 @@
/* $NetBSD: uts.c,v 1.14 2021/08/07 16:19:17 thorpej Exp $ */
/* $NetBSD: uts.c,v 1.15 2022/03/28 12:44:17 riastradh Exp $ */
/*
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.14 2021/08/07 16:19:17 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.15 2022/03/28 12:44:17 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -72,7 +72,8 @@ int utsdebug = 0;
struct uts_softc {
struct uhidev sc_hdev;
device_t sc_dev;
struct uhidev *sc_hdev;
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
struct hid_location sc_loc_btn;
@ -92,7 +93,7 @@ struct uts_softc {
#define TSCREEN_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
Static void uts_intr(struct uhidev *, void *, u_int);
Static void uts_intr(void *, void *, u_int);
Static int uts_enable(void *);
Static void uts_disable(void *);
@ -146,10 +147,8 @@ uts_attach(device_t parent, device_t self, void *aux)
aprint_normal("\n");
sc->sc_hdev.sc_dev = self;
sc->sc_hdev.sc_intr = uts_intr;
sc->sc_hdev.sc_parent = uha->parent;
sc->sc_hdev.sc_report_id = uha->reportid;
sc->sc_dev = self;
sc->sc_hdev = uha->parent;
uhidev_get_report_desc(uha->parent, &desc, &size);
@ -159,7 +158,7 @@ uts_attach(device_t parent, device_t self, void *aux)
/* requires HID usage Generic_Desktop:X */
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
uha->reportid, hid_input, &sc->sc_loc_x, &flags)) {
aprint_error_dev(sc->sc_hdev.sc_dev,
aprint_error_dev(sc->sc_dev,
"touchscreen has no X report\n");
return;
}
@ -170,7 +169,7 @@ uts_attach(device_t parent, device_t self, void *aux)
case HIO_RELATIVE:
break;
default:
aprint_error_dev(sc->sc_hdev.sc_dev,
aprint_error_dev(sc->sc_dev,
"X report 0x%04x not supported\n", flags);
return;
}
@ -178,7 +177,7 @@ uts_attach(device_t parent, device_t self, void *aux)
/* requires HID usage Generic_Desktop:Y */
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
uha->reportid, hid_input, &sc->sc_loc_y, &flags)) {
aprint_error_dev(sc->sc_hdev.sc_dev,
aprint_error_dev(sc->sc_dev,
"touchscreen has no Y report\n");
return;
}
@ -189,15 +188,15 @@ uts_attach(device_t parent, device_t self, void *aux)
case HIO_RELATIVE:
break;
default:
aprint_error_dev(sc->sc_hdev.sc_dev,
aprint_error_dev(sc->sc_dev,
"Y report 0x%04x not supported\n", flags);
return;
}
/* requires HID usage Digitizer:Tip_Switch */
if (!hid_locate(desc, size, HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH),
uha->reportid, hid_input, &sc->sc_loc_btn, 0)) {
aprint_error_dev(sc->sc_hdev.sc_dev,
uha->reportid, hid_input, &sc->sc_loc_btn, 0)) {
aprint_error_dev(sc->sc_dev,
"touchscreen has no tip switch report\n");
return;
}
@ -211,10 +210,10 @@ uts_attach(device_t parent, device_t self, void *aux)
* ELAN touchscreens error out here but still return
* valid data
*/
aprint_debug_dev(sc->sc_hdev.sc_dev,
aprint_debug_dev(sc->sc_dev,
"ELAN touchscreen found, working around bug.\n");
} else {
aprint_error_dev(sc->sc_hdev.sc_dev,
aprint_error_dev(sc->sc_dev,
"touchscreen has no range report\n");
return;
}
@ -247,7 +246,7 @@ uts_attach(device_t parent, device_t self, void *aux)
while (hid_get_item(d, &item)) {
if (item.kind != hid_input
|| HID_GET_USAGE_PAGE(item.usage) != HUP_GENERIC_DESKTOP
|| item.report_ID != sc->sc_hdev.sc_report_id)
|| item.report_ID != uha->reportid)
continue;
if (HID_GET_USAGE(item.usage) == HUG_X) {
sc->sc_calibcoords.minx = item.logical_minimum;
@ -322,7 +321,7 @@ uts_enable(void *v)
sc->sc_enabled = 1;
sc->sc_buttons = 0;
return uhidev_open(&sc->sc_hdev);
return uhidev_open(sc->sc_hdev, &uts_intr, sc);
}
Static void
@ -339,7 +338,7 @@ uts_disable(void *v)
#endif
sc->sc_enabled = 0;
uhidev_close(&sc->sc_hdev);
uhidev_close(sc->sc_hdev);
}
Static int
@ -363,9 +362,9 @@ uts_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
}
Static void
uts_intr(struct uhidev *addr, void *ibuf, u_int len)
uts_intr(void *cookie, void *ibuf, u_int len)
{
struct uts_softc *sc = (struct uts_softc *)addr;
struct uts_softc *sc = cookie;
int dx, dy, dz;
uint32_t buttons = 0;
int flags, s;