Module Name: src Committed By: riastradh Date: Mon Mar 28 12:44:17 UTC 2022
Modified Files: src/sys/dev/usb: uatp.c ucycom.c uhid.c uhidev.c uhidev.h ukbd.c ums.c uthum.c uts.c Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/dev/usb/uatp.c cvs rdiff -u -r1.54 -r1.55 src/sys/dev/usb/ucycom.c cvs rdiff -u -r1.122 -r1.123 src/sys/dev/usb/uhid.c cvs rdiff -u -r1.89 -r1.90 src/sys/dev/usb/uhidev.c cvs rdiff -u -r1.25 -r1.26 src/sys/dev/usb/uhidev.h cvs rdiff -u -r1.158 -r1.159 src/sys/dev/usb/ukbd.c cvs rdiff -u -r1.102 -r1.103 src/sys/dev/usb/ums.c cvs rdiff -u -r1.22 -r1.23 src/sys/dev/usb/uthum.c cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/uts.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/uatp.c diff -u src/sys/dev/usb/uatp.c:1.28 src/sys/dev/usb/uatp.c:1.29 --- src/sys/dev/usb/uatp.c:1.28 Mon Mar 28 12:43:12 2022 +++ src/sys/dev/usb/uatp.c Mon Mar 28 12:44:17 2022 @@ -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 u 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_k }; 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 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 se 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 se "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 Index: src/sys/dev/usb/ucycom.c diff -u src/sys/dev/usb/ucycom.c:1.54 src/sys/dev/usb/ucycom.c:1.55 --- src/sys/dev/usb/ucycom.c:1.54 Mon Mar 28 12:43:30 2022 +++ src/sys/dev/usb/ucycom.c Mon Mar 28 12:44:17 2022 @@ -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 *, str 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 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 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 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 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 } 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 *i 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 *s 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); Index: src/sys/dev/usb/uhid.c diff -u src/sys/dev/usb/uhid.c:1.122 src/sys/dev/usb/uhid.c:1.123 --- src/sys/dev/usb/uhid.c:1.122 Mon Mar 28 12:43:12 2022 +++ src/sys/dev/usb/uhid.c Mon Mar 28 12:44:17 2022 @@ -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 se 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, 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 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, 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 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, in 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, in #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 *a 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 *a 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 *a 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 *a } 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: Index: src/sys/dev/usb/uhidev.c diff -u src/sys/dev/usb/uhidev.c:1.89 src/sys/dev/usb/uhidev.c:1.90 --- src/sys/dev/usb/uhidev.c:1.89 Mon Mar 28 12:44:06 2022 +++ src/sys/dev/usb/uhidev.c Mon Mar 28 12:44:17 2022 @@ -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 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 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 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 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 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 * } 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 Index: src/sys/dev/usb/uhidev.h diff -u src/sys/dev/usb/uhidev.h:1.25 src/sys/dev/usb/uhidev.h:1.26 --- src/sys/dev/usb/uhidev.h:1.25 Mon Mar 28 12:43:39 2022 +++ src/sys/dev/usb/uhidev.h Mon Mar 28 12:44:17 2022 @@ -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); Index: src/sys/dev/usb/ukbd.c diff -u src/sys/dev/usb/ukbd.c:1.158 src/sys/dev/usb/ukbd.c:1.159 --- src/sys/dev/usb/ukbd.c:1.158 Mon Mar 28 12:43:12 2022 +++ src/sys/dev/usb/ukbd.c Mon Mar 28 12:44:17 2022 @@ -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 se 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_soft 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_soft } 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, struc */ 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; } Index: src/sys/dev/usb/ums.c diff -u src/sys/dev/usb/ums.c:1.102 src/sys/dev/usb/ums.c:1.103 --- src/sys/dev/usb/ums.c:1.102 Mon Mar 28 12:43:12 2022 +++ src/sys/dev/usb/ums.c Mon Mar 28 12:44:17 2022 @@ -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 sel 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 sel 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 sel 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); } } Index: src/sys/dev/usb/uthum.c diff -u src/sys/dev/usb/uthum.c:1.22 src/sys/dev/usb/uthum.c:1.23 --- src/sys/dev/usb/uthum.c:1.22 Mon Mar 28 12:43:12 2022 +++ src/sys/dev/usb/uthum.c Mon Mar 28 12:44:17 2022 @@ -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, ui 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 s 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 s 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 devac 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, /* 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, /* 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); Index: src/sys/dev/usb/uts.c diff -u src/sys/dev/usb/uts.c:1.14 src/sys/dev/usb/uts.c:1.15 --- src/sys/dev/usb/uts.c:1.14 Sat Aug 7 16:19:17 2021 +++ src/sys/dev/usb/uts.c Mon Mar 28 12:44:17 2022 @@ -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 sel 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 sel /* 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 sel 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 sel /* 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 sel 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 sel * 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 sel 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 *dat } 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;