From nobody Tue Jul 29 06:22:21 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4brlcs5zq6z61p20; Tue, 29 Jul 2025 06:22:21 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4brlcs5LmLz4NSj; Tue, 29 Jul 2025 06:22:21 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753770141; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+DSA0WTtzH6VBiFLzzffaoCqLC3paFpDEJFQgOqL8ug=; b=TV9AySxJWtPkGU0/xcCwxZv1ygN6oRpJoR6Ip7y/lkY6SLh7IknM8e3Ja1vQUv9FFxb5k1 hw9qdW+Uv+u7GPCIl1bmatjtHmkDeVwRxzsfnHTToj6KXDi3sjfnHzccNbFh3GGGfN5XkD gRPPQ8eko3Kl7nF7Xp1RqB4rqxNQtkSW8bPNHCTBnH/xG27I/PTqp/sOWwyFRL/fErUlek upk2A5u0quU9dq+0y2RwLX1Mym7+DnHA3zh8AHuCll6rRY5yobqi8F6dVY+/qpvmK+UgR0 N3E5L8lseBCyBs/oYiOWlu6XeYvgrmNtOrCMzVlgilfsqK1FpQEzZGxd7QPiQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753770141; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=+DSA0WTtzH6VBiFLzzffaoCqLC3paFpDEJFQgOqL8ug=; b=gyxv2eSxb6XzG34SKqQ0MDpOGFeTFnnaZEaEvtz06EAx8XAlDaJ9OcBvY6LXWbNDBFDT96 yhKt/MAIK7iX1+w7z13lND7oaHmO5ptMiJa0chSyhTwJKBJanFvH6ZoLYXCB5Cv6oLv0da 8cal3H5InfmNJNb7ZRWYCT4iKicvgsY9ymdA2xmZcO1h8pEKhGr6jsXgrNiFbyv5wfpWEp 7Lg7TjM01o91a2Y7m1ZdZGcVdTLTwf6j+rAIAOzVtg2gd1Wd+dj/GnPKGuHxr6wbeCFTG8 BM8q9lbwh06z5lxzhWWG7tC3PGCuDHLoHyfpRZp4X2Nd7CHVrkHUl16FhcrdxQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1753770141; a=rsa-sha256; cv=none; b=AnxN0uxylPN1EMEgC8TJtGLqpBXAVJ7Tv19uIlMzjwVi/mHPNvlq6cVywH+IAkSxNcK5gj Ji0pyufxnXJh7l0BAqypBVoRy07vNrTRMvorFwD+kW1QibBxyDqcD9qEzdf7hqlOsqnp2t Jf/pHbZcAilAmbWjjWJbMZqv9pUS2ldhv2qocVQyAWBLb6Ii7kTKZq6EIk4t6nL9PvMyZ5 0Qin59j256kTAxch8/Zx21iD+4ZvaUEaAgD29wJM47s+sZj9WcoV+VSaKDZnr8IZD+Mfhz W6rH0M3n1wGTczUH0HWxVqeFVzUjRy5eoZvVJSNlQLrtHAPHvcGZRrKKjPaxEA== 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 4brlcs4v3jz3vF; Tue, 29 Jul 2025 06:22:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 56T6MLNY012830; Tue, 29 Jul 2025 06:22:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 56T6MLh3012827; Tue, 29 Jul 2025 06:22:21 GMT (envelope-from git) Date: Tue, 29 Jul 2025 06:22:21 GMT Message-Id: <202507290622.56T6MLh3012827@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Poul-Henning Kamp Subject: git: 36027361f9cf - main - =?utf-8?Q?iichid: Stop using split I=C2=B2C bus transactions?= List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: phk X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 36027361f9cfb76013153a032286eccda1512359 Auto-Submitted: auto-generated The branch main has been updated by phk: URL: https://cgit.FreeBSD.org/src/commit/?id=36027361f9cfb76013153a032286eccda1512359 commit 36027361f9cfb76013153a032286eccda1512359 Author: Poul-Henning Kamp AuthorDate: 2025-07-29 06:17:43 +0000 Commit: Poul-Henning Kamp CommitDate: 2025-07-29 06:17:43 +0000 iichid: Stop using split I²C bus transactions Read IIC-HID reports as a single I²C transaction, instead of reading first the two byte length field, holding the bus, and then the rest of the report in a separate transaction. While technically legal, I²C bus split transactions are not universally supported, and in particular the "Snapdragon Elite" ARM CPU does not seem to support them. It is also not obvious that they are beneficial in this case, given the overhead of controller setup, interrupts and tear-down. Reviewed by: wulf Differential Revision: https://reviews.freebsd.org/D51302 --- sys/dev/iicbus/iichid.c | 74 ++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/sys/dev/iicbus/iichid.c b/sys/dev/iicbus/iichid.c index 9c0324a24685..3f1d7a0cefba 100644 --- a/sys/dev/iicbus/iichid.c +++ b/sys/dev/iicbus/iichid.c @@ -275,62 +275,36 @@ iichid_cmd_read(struct iichid_softc* sc, void *buf, iichid_size_t maxlen, * 6.1.3 - Retrieval of Input Reports * DEVICE returns the length (2 Bytes) and the entire Input Report. */ - uint8_t actbuf[2] = { 0, 0 }; - /* Read actual input report length. */ + + memset(buf, 0xaa, 2); // In case nothing gets read struct iic_msg msgs[] = { - { sc->addr, IIC_M_RD | IIC_M_NOSTOP, sizeof(actbuf), actbuf }, + { sc->addr, IIC_M_RD, maxlen, buf }, }; - uint16_t actlen; int error; error = iicbus_transfer(sc->dev, msgs, nitems(msgs)); if (error != 0) return (error); - actlen = actbuf[0] | actbuf[1] << 8; -#ifdef IICHID_SAMPLING - if ((actlen == 0 && sc->sampling_rate_slow < 0) || - (maxlen == 0 && sc->sampling_rate_slow >= 0)) { -#else + DPRINTFN(sc, 5, "%*D\n", msgs[0].len, msgs[0].buf, " "); + + uint16_t actlen = le16dec(buf); + if (actlen == 0) { -#endif - /* Read and discard reset command response. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, - le16toh(sc->desc.wMaxInputLength) - 2, sc->intr_buf }; - actlen = 0; if (!sc->reset_acked) { mtx_lock(&sc->mtx); sc->reset_acked = true; wakeup(&sc->reset_acked); mtx_unlock(&sc->mtx); } -#ifdef IICHID_SAMPLING - } else if ((actlen <= 2 || actlen == 0xFFFF) && - sc->sampling_rate_slow >= 0) { - /* Read and discard 1 byte to send I2C STOP condition. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, 1, actbuf }; - actlen = 0; -#endif - } else { - actlen -= 2; - if (actlen > maxlen) { - DPRINTF(sc, "input report too big. requested=%d " - "received=%d\n", maxlen, actlen); - actlen = maxlen; - } - /* Read input report itself. */ - msgs[0] = (struct iic_msg) - { sc->addr, IIC_M_RD | IIC_M_NOSTART, actlen, buf }; } - error = iicbus_transfer(sc->dev, msgs, 1); - if (error == 0 && actual_len != NULL) + if (actlen <= 2 || actlen > maxlen) { + actlen = 0; + } + if (actual_len != NULL) { *actual_len = actlen; - - DPRINTFN(sc, 5, - "%*D - %*D\n", 2, actbuf, " ", msgs[0].len, msgs[0].buf, " "); + } return (error); } @@ -566,7 +540,7 @@ iichid_sampling_task(void *context, int pending) error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual); if (error == 0) { if (actual > 0) { - sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); sc->missing_samples = 0; if (sc->dup_size != actual || memcmp(sc->dup_buf, sc->intr_buf, actual) != 0) { @@ -577,7 +551,7 @@ iichid_sampling_task(void *context, int pending) ++sc->dup_samples; } else { if (++sc->missing_samples == 1) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, 0); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, 0); sc->dup_samples = 0; } } else @@ -632,7 +606,7 @@ iichid_intr(void *context) if (error == 0) { if (sc->power_on && sc->open) { if (actual != 0) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); else DPRINTF(sc, "no data received\n"); @@ -842,11 +816,12 @@ iichid_intr_setup(device_t dev, device_t child __unused, hid_intr_t intr, sc = device_get_softc(dev); /* - * Do not rely on wMaxInputLength, as some devices may set it to - * a wrong length. Find the longest input report in report descriptor. + * Do not rely just on wMaxInputLength, as some devices (which?) + * may set it to a wrong length. Also find the longest input report + * in report descriptor, and add two for the length field. */ - rdesc->rdsize = - MAX(rdesc->isize, le16toh(sc->desc.wMaxInputLength) - 2); + rdesc->rdsize = 2 + + MAX(rdesc->isize, le16toh(sc->desc.wMaxInputLength)); /* Write and get/set_report sizes are limited by I2C-HID protocol. */ rdesc->grsize = rdesc->srsize = IICHID_SIZE_MAX; rdesc->wrsize = IICHID_SIZE_MAX; @@ -919,7 +894,7 @@ iichid_intr_poll(device_t dev, device_t child __unused) sc = device_get_softc(dev); error = iichid_cmd_read(sc, sc->intr_buf, sc->intr_bufsize, &actual); if (error == 0 && actual != 0) - sc->intr_handler(sc->intr_ctx, sc->intr_buf, actual); + sc->intr_handler(sc->intr_ctx, sc->intr_buf + 2, actual); } /* @@ -946,6 +921,7 @@ iichid_read(device_t dev, device_t child __unused, void *buf, { struct iichid_softc *sc; device_t parent; + uint8_t *tmpbuf; int error; if (maxlen > IICHID_SIZE_MAX) @@ -954,8 +930,12 @@ iichid_read(device_t dev, device_t child __unused, void *buf, parent = device_get_parent(sc->dev); error = iicbus_request_bus(parent, sc->dev, IIC_WAIT); if (error == 0) { - error = iichid_cmd_read(sc, buf, maxlen, actlen); + tmpbuf = malloc(maxlen + 2, M_DEVBUF, M_WAITOK | M_ZERO); + error = iichid_cmd_read(sc, tmpbuf, maxlen + 2, actlen); iicbus_release_bus(parent, sc->dev); + if (*actlen > 0) + memcpy(buf, tmpbuf + 2, *actlen); + free(tmpbuf, M_DEVBUF); } return (iic2errno(error)); }