From owner-dev-commits-src-main@freebsd.org Wed Dec 23 22:29:38 2020 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 0156E4CD5A5; Wed, 23 Dec 2020 22:29:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4D1SYs6c6Tz4ZGM; Wed, 23 Dec 2020 22:29:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D508525678; Wed, 23 Dec 2020 22:29:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 0BNMTbaJ083109; Wed, 23 Dec 2020 22:29:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 0BNMTbFZ083108; Wed, 23 Dec 2020 22:29:37 GMT (envelope-from git) Date: Wed, 23 Dec 2020 22:29:37 GMT Message-Id: <202012232229.0BNMTbFZ083108@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Vladimir Kondratyev Subject: git: 7eae6aab7d79 - wmt(4): Fetch and parse HID report descriptor only one time MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7eae6aab7d79eea0f30cd1a0be145404867c0a2f Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "Commit messages for the main branch of the src repository." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Dec 2020 22:29:38 -0000 The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=7eae6aab7d79eea0f30cd1a0be145404867c0a2f commit 7eae6aab7d79eea0f30cd1a0be145404867c0a2f Author: Vladimir Kondratyev AuthorDate: 2020-12-23 22:18:18 +0000 Commit: Vladimir Kondratyev CommitDate: 2020-12-23 22:21:53 +0000 wmt(4): Fetch and parse HID report descriptor only one time Do it at probe stage and reuse results during attach. Obtained from: sysutils/iichid --- sys/dev/usb/input/wmt.c | 110 +++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 71 deletions(-) diff --git a/sys/dev/usb/input/wmt.c b/sys/dev/usb/input/wmt.c index 3d4663693f5f..b3fbd8c82a13 100644 --- a/sys/dev/usb/input/wmt.c +++ b/sys/dev/usb/input/wmt.c @@ -185,9 +185,10 @@ struct wmt_absinfo { int32_t res; }; -struct wmt_softc -{ +struct wmt_softc { device_t dev; + bool supported; + struct mtx mtx; struct wmt_absinfo ai[WMT_N_USAGES]; struct hid_location locs[MAX_MT_SLOTS][WMT_N_USAGES]; @@ -260,6 +261,7 @@ static int wmt_probe(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); + struct wmt_softc *sc = device_get_softc(dev); void *d_ptr; uint16_t d_len; int err; @@ -278,11 +280,20 @@ wmt_probe(device_t dev) if (err) return (ENXIO); - if (wmt_hid_parse(NULL, d_ptr, d_len)) + /* Check if report descriptor belongs to a HID multitouch device */ + if (!sc->supported) + sc->supported = wmt_hid_parse(sc, d_ptr, d_len); + if (sc->supported) err = BUS_PROBE_DEFAULT; else err = ENXIO; + /* Check HID report length */ + if (sc->supported && (sc->isize <= 0 || sc->isize > WMT_BSIZE)) { + DPRINTF("Input size invalid or too large: %d\n", sc->isize); + err = ENXIO; + } + free(d_ptr, M_TEMP); return (err); } @@ -292,36 +303,12 @@ wmt_attach(device_t dev) { struct usb_attach_arg *uaa = device_get_ivars(dev); struct wmt_softc *sc = device_get_softc(dev); - void *d_ptr; - uint16_t d_len; size_t i; int err; - bool hid_ok; device_set_usb_desc(dev); sc->dev = dev; - /* Get HID descriptor */ - err = usbd_req_get_hid_desc(uaa->device, NULL, - &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex); - if (err) { - DPRINTF("usbd_req_get_hid_desc error=%s\n", usbd_errstr(err)); - return (ENXIO); - } - - hid_ok = wmt_hid_parse(sc, d_ptr, d_len); - free(d_ptr, M_TEMP); - if (!hid_ok) { - DPRINTF("multi-touch HID descriptor not found\n"); - return (ENXIO); - } - - /* Check HID report length */ - if (sc->isize <= 0 || sc->isize > WMT_BSIZE) { - DPRINTF("Input size invalid or too large: %d\n", sc->isize); - return (ENXIO); - } - /* Fetch and parse "Contact count maximum" feature report */ if (sc->cont_max_rlen > 0 && sc->cont_max_rlen <= WMT_BSIZE) { err = usbd_req_get_report(uaa->device, NULL, sc->buf, @@ -373,6 +360,18 @@ wmt_attach(device_t dev) if (err) goto detach; + /* Announce information about the touch device */ + device_printf(sc->dev, + "%d contacts and [%s%s%s%s%s]. Report range [%d:%d] - [%d:%d]\n", + (int)sc->ai[WMT_SLOT].max + 1, + USAGE_SUPPORTED(sc->caps, WMT_IN_RANGE) ? "R" : "", + USAGE_SUPPORTED(sc->caps, WMT_CONFIDENCE) ? "C" : "", + USAGE_SUPPORTED(sc->caps, WMT_WIDTH) ? "W" : "", + USAGE_SUPPORTED(sc->caps, WMT_HEIGHT) ? "H" : "", + USAGE_SUPPORTED(sc->caps, WMT_PRESSURE) ? "P" : "", + (int)sc->ai[WMT_X].min, (int)sc->ai[WMT_Y].min, + (int)sc->ai[WMT_X].max, (int)sc->ai[WMT_Y].max); + return (0); detach: @@ -648,11 +647,8 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) struct hid_data *hd; size_t i; size_t cont = 0; - uint32_t caps = 0; int32_t cont_count_max = 0; uint8_t report_id = 0; - uint8_t cont_max_rid = 0; - uint8_t thqa_cert_rid = 0; bool touch_coll = false; bool finger_coll = false; bool cont_count_found = false; @@ -678,15 +674,14 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) case hid_feature: if (hi.collevel == 1 && touch_coll && hi.usage == HID_USAGE2(HUP_MICROSOFT, HUMS_THQA_CERT)) { - thqa_cert_rid = hi.report_ID; + sc->thqa_cert_rid = hi.report_ID; break; } if (hi.collevel == 1 && touch_coll && hi.usage == HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACT_MAX)) { cont_count_max = hi.logical_maximum; - cont_max_rid = hi.report_ID; - if (sc != NULL) - sc->cont_max_loc = hi.loc; + sc->cont_max_rid = hi.report_ID; + sc->cont_max_loc = hi.loc; } break; default: @@ -696,7 +691,7 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) hid_end_parse(hd); /* Maximum contact count is required usage */ - if (cont_max_rid == 0) + if (sc->cont_max_rid == 0) return (false); touch_coll = false; @@ -735,8 +730,7 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) if (hi.collevel == 1 && hi.usage == HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTCOUNT)) { cont_count_found = true; - if (sc != NULL) - sc->cont_count_loc = hi.loc; + sc->cont_count_loc = hi.loc; break; } /* Scan time is required but clobbered by evdev */ @@ -748,8 +742,6 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) if (!finger_coll || hi.collevel != 2) break; - if (sc == NULL && cont > 0) - break; if (cont >= MAX_MT_SLOTS) { DPRINTF("Finger %zu ignored\n", cont); break; @@ -757,12 +749,6 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) for (i = 0; i < WMT_N_USAGES; i++) { if (hi.usage == wmt_hid_map[i].usage) { - if (sc == NULL) { - if (USAGE_SUPPORTED(caps, i)) - continue; - caps |= 1 << i; - break; - } /* * HUG_X usage is an array mapped to * both ABS_MT_POSITION and ABS_MT_TOOL @@ -779,7 +765,7 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) */ if (cont > 0) break; - caps |= 1 << i; + sc->caps |= 1 << i; sc->ai[i] = (struct wmt_absinfo) { .max = hi.logical_maximum, .min = hi.logical_minimum, @@ -799,14 +785,10 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) if (!cont_count_found || !scan_time_found || cont == 0) return (false); for (i = 0; i < WMT_N_USAGES; i++) { - if (wmt_hid_map[i].required && !USAGE_SUPPORTED(caps, i)) + if (wmt_hid_map[i].required && !USAGE_SUPPORTED(sc->caps, i)) return (false); } - /* Stop probing here */ - if (sc == NULL) - return (true); - /* * According to specifications 'Contact Count Maximum' should be read * from Feature Report rather than from HID descriptor. Set sane @@ -827,9 +809,9 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) }; /* Report touch orientation if both width and height are supported */ - if (USAGE_SUPPORTED(caps, WMT_WIDTH) && - USAGE_SUPPORTED(caps, WMT_HEIGHT)) { - caps |= (1 << WMT_ORIENTATION); + if (USAGE_SUPPORTED(sc->caps, WMT_WIDTH) && + USAGE_SUPPORTED(sc->caps, WMT_HEIGHT)) { + sc->caps |= 1 << WMT_ORIENTATION; sc->ai[WMT_ORIENTATION].max = 1; } @@ -837,28 +819,14 @@ wmt_hid_parse(struct wmt_softc *sc, const void *d_ptr, uint16_t d_len) sc->report_len = wmt_hid_report_size(d_ptr, d_len, hid_input, report_id); sc->cont_max_rlen = wmt_hid_report_size(d_ptr, d_len, hid_feature, - cont_max_rid); - if (thqa_cert_rid > 0) + sc->cont_max_rid); + if (sc->thqa_cert_rid > 0) sc->thqa_cert_rlen = wmt_hid_report_size(d_ptr, d_len, - hid_feature, thqa_cert_rid); + hid_feature, sc->thqa_cert_rid); sc->report_id = report_id; - sc->caps = caps; sc->nconts_per_report = cont; - sc->cont_max_rid = cont_max_rid; - sc->thqa_cert_rid = thqa_cert_rid; - /* Announce information about the touch device */ - device_printf(sc->dev, - "%d contacts and [%s%s%s%s%s]. Report range [%d:%d] - [%d:%d]\n", - (int)cont_count_max, - USAGE_SUPPORTED(sc->caps, WMT_IN_RANGE) ? "R" : "", - USAGE_SUPPORTED(sc->caps, WMT_CONFIDENCE) ? "C" : "", - USAGE_SUPPORTED(sc->caps, WMT_WIDTH) ? "W" : "", - USAGE_SUPPORTED(sc->caps, WMT_HEIGHT) ? "H" : "", - USAGE_SUPPORTED(sc->caps, WMT_PRESSURE) ? "P" : "", - (int)sc->ai[WMT_X].min, (int)sc->ai[WMT_Y].min, - (int)sc->ai[WMT_X].max, (int)sc->ai[WMT_Y].max); return (true); }