From nobody Tue Sep 08 00:21:15 2026 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 4hf4Nq40Wpz6r3Q6 for ; Tue, 08 Sep 2026 00:21:15 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hf4Nq1l65z3y1V for ; Tue, 08 Sep 2026 00:21:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788826875; 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=RrAgTFsfXdoDbMglGTH94ZjU77qTqIVLhg2U5c8nHis=; b=WqdrjTeLpeh0C0kB8TJ9WxkqBa4PHBQPXRFBs+xMmT2C2LAurqcya558uHQcIQUaQVo3Lh rOP/+IoK5SCD7cavMRJW+F+RI/OZ/qAGqW/8SxYVc9BO+2DUPTQ0OABAsynd/xzTrJnV5v /yXlDlqbau1bcjFukmwWFyb7pvv9H8n4uA+TcVlqfpJ07ol/7zxMz7Rr8+DuWW9nm+7Y7f 9bQuCwonm93+YFrGe5+bOeysBzjzdvYAjEgo+ZEQv6JwQbetl1DNJE+a94D23qDB5EtiZh 429l4zA8UGUJmwK3Fp6CNrDIqwX812cJ2RJi7XT2qKiAO6rZhHHQRkj+iEYhZw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788826875; a=rsa-sha256; cv=none; b=PdIqCXTd9c7oVHDJef+kHmIO2dihchXG1umDD8wHQ+KleiwuRh04XMzuMcg18nubO1yqwL DFBXIvLxtdTmPd3JORmz1t71/Wm73MiVGLvnw0/MCi64ozKgN8x8rsL7cxyD6Juhj70UO5 pGa7Tk3GKZL4XUWo+wQ4rzCFPee21JwaMtKPrbAWTpqtqhj+3fcSEsh52qkUv4vFMRsyZi zzaBm7lPaKUwTau+cFqhPpyjGtYfj+rYY2w+ah/mi4YG5O935a1XHBcxZ8UU0/tJGhY5ok gZ2x+5dbxQogVMg7CafYABJgfQXjpc84esQ59pS4ZMlI8Jgx4mFEtih8/oFu0Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788826875; 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=RrAgTFsfXdoDbMglGTH94ZjU77qTqIVLhg2U5c8nHis=; b=uZJz9K58o58Q1ifJlWGdkhbqEgifdVJS/zZktU41k6ynXOMSwBj3GZepDE+g05PrOuwQm5 P1AYwZzoA3wdYS6234EQO6ows0m94lmx049vu/UNdLckaIcWOKBO3G8GR1MXE6SdSjasXv /6pyd5DnVdOBlUWh43G0JljYdxGBDmEKEX4lCrfyT2wfmkGdB5PohWg/Es1iP+iO7rOeB5 5vqazsAuHwVfoec6Hno17VQ0gUTewlKXx3+edmuzoTy7OVilw85gRdHlE56bRQX+XBil5+ RV16gPCgVz0M7ZP6qMj39M24ZVE3/t/ThJEHsupM6M6wmTs/RYujudn+pyWiMA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hf4Nq0BtHzhcG for ; Tue, 08 Sep 2026 00:21:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 36280 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 08 Sep 2026 00:21:15 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Abdelkader Boudih Subject: git: a14a81016b14 - main - bce_vhci: fix duplicate endpoint queue registration, ratelimit failure logging 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 List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: seuros X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a14a81016b14b54a9cd660bb76ef505c6f70dd73 Auto-Submitted: auto-generated Date: Tue, 08 Sep 2026 00:21:15 +0000 Message-Id: <6a9f54fb.36280.2a4b6724@gitrepo.freebsd.org> The branch main has been updated by seuros: URL: https://cgit.FreeBSD.org/src/commit/?id=a14a81016b14b54a9cd660bb76ef505c6f70dd73 commit a14a81016b14b54a9cd660bb76ef505c6f70dd73 Author: Abdelkader Boudih AuthorDate: 2026-09-08 00:19:36 +0000 Commit: Abdelkader Boudih CommitDate: 2026-09-08 00:19:36 +0000 bce_vhci: fix duplicate endpoint queue registration, ratelimit failure logging bce_vhci_endpoint_create() was registering both the IN and OUT submission queues on every call, regardless of which direction the endpoint actually needed. The per-stage firmware registration failures weren't rate-limited, so a stuck registration will spam the console. Tested on: MacBookPro15,2 Macmini8,1 MacBookPro15,3 MacBookPro16,2 Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D58831 --- sys/dev/apple_bce/apple_bce_vhci.c | 220 ++++++++++++++++++++++--------------- sys/dev/apple_bce/apple_bce_vhci.h | 2 + 2 files changed, 135 insertions(+), 87 deletions(-) diff --git a/sys/dev/apple_bce/apple_bce_vhci.c b/sys/dev/apple_bce/apple_bce_vhci.c index e8bef8566cd6..e91ba8b37dc8 100644 --- a/sys/dev/apple_bce/apple_bce_vhci.c +++ b/sys/dev/apple_bce/apple_bce_vhci.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -195,12 +196,7 @@ static int bce_vhci_cmd_execute(struct bce_vhci_softc *vhci, struct bce_vhci_message *req, struct bce_vhci_message *reply, int timeout_ticks); -/* - * Convert USB endpoint address to tq[] index. - * ep0 (0x00) maps to index 0. For other endpoints, IN and OUT get - * separate slots: OUT 0x01 -> 1, IN 0x81 -> 2, OUT 0x02 -> 3, etc. - * Maximum index is 30 (ep 0x8F), fits in BCE_VHCI_MAX_ENDPOINTS (32). - */ +/* Convert USB endpoint address to tq[] index -- EP0 shared, others per-direction. */ static inline uint8_t bce_vhci_ep_index(uint8_t ep_addr) { @@ -1185,12 +1181,12 @@ bce_vhci_create_task(void *arg, int pending __unused) usbd_transfer_done(xfer, USB_ERR_STALLED); USB_BUS_UNLOCK(&vhci->sc_bus); - device_printf(vhci->sc_dev, - "create_task: ep create " - "failed: dev=%d ep=0x%02x " - "err=%d\n", - dev->fw_dev_id, ep_addr, - ep_err); + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "endpoint create failed: " + "dev=%d ep=0x%02x err=%d\n", + dev->fw_dev_id, ep_addr, ep_err); continue; } @@ -1980,12 +1976,20 @@ bce_vhci_endpoint_create(struct bce_vhci_softc *vhci, char name[0x20]; uint32_t status; int error, cq_qid, out_qid, in_qid, i; - uint8_t ep_idx; + uint8_t ep_idx, ep_num; + int want_out, want_in; ep_idx = bce_vhci_ep_index(ep_addr); if (ep_idx >= BCE_VHCI_MAX_ENDPOINTS) return (EINVAL); + /* EP0 needs both SQs; other endpoints only need their own direction's. */ + ep_num = ep_addr & 0x0F; + want_out = (ep_num == 0) || ((ep_addr & 0x80) == 0); + want_in = (ep_num == 0) || ((ep_addr & 0x80) != 0); + out_qid = -1; + in_qid = -1; + tq = &dev->tq[ep_idx]; if (tq->active) return (EEXIST); @@ -2069,6 +2073,12 @@ bce_vhci_endpoint_create(struct bce_vhci_softc *vhci, cfg.vector_or_cq = 4; status = bce_cmd_register_queue(sc->sc_cmd_cmdq, sc, &cfg, NULL, 0); if (status != 0) { + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "failed to register CQ dev=%d ep=0x%02x " + "qid=%d: %u\n", + dev->fw_dev_id, ep_addr, cq_qid, status); error = EIO; goto fail_cq; } @@ -2088,74 +2098,92 @@ bce_vhci_endpoint_create(struct bce_vhci_softc *vhci, if (inserted == 0) { sc->sc_queues[cq_qid] = NULL; mtx_unlock(&sc->sc_queues_lock); - device_printf(vhci->sc_dev, - "CQ list full, cannot add endpoint CQ\n"); + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "CQ list full, cannot add endpoint " + "CQ\n"); error = ENOSPC; goto fail_cq_reg; } } mtx_unlock(&sc->sc_queues_lock); - /* Allocate OUT SQ (host -> device) */ - out_qid = bce_vhci_alloc_qid(vhci); - if (out_qid < 0) { - error = ENOSPC; - goto fail_cq_reg; - } - tq->sq_out = bce_alloc_sq(sc, out_qid, - sizeof(struct bce_qe_submission), BCE_VHCI_TQ_EL, - bce_vhci_tq_completion, tq); - if (tq->sq_out == NULL) { - error = ENOMEM; - goto fail_sq_out_alloc; - } + /* Allocate OUT SQ (host -> device), only if this direction needs it */ + if (want_out) { + out_qid = bce_vhci_alloc_qid(vhci); + if (out_qid < 0) { + error = ENOSPC; + goto fail_cq_reg; + } + tq->sq_out = bce_alloc_sq(sc, out_qid, + sizeof(struct bce_qe_submission), BCE_VHCI_TQ_EL, + bce_vhci_tq_completion, tq); + if (tq->sq_out == NULL) { + error = ENOMEM; + goto fail_sq_out_alloc; + } - snprintf(name, sizeof(name), "VHC1-%d-%02x", - dev->fw_dev_id, ep_addr & 0x0F); - bce_get_sq_memcfg(tq->sq_out, tq->cq, &cfg); - status = bce_cmd_register_queue(sc->sc_cmd_cmdq, sc, &cfg, name, 1); - if (status != 0) { - device_printf(vhci->sc_dev, - "failed to register OUT SQ '%s': %u\n", name, status); - error = EIO; - goto fail_sq_out; + snprintf(name, sizeof(name), "VHC1-%d-%02x", + dev->fw_dev_id, ep_addr & 0x0F); + bce_get_sq_memcfg(tq->sq_out, tq->cq, &cfg); + status = bce_cmd_register_queue(sc->sc_cmd_cmdq, sc, &cfg, + name, 1); + if (status != 0) { + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "failed to register OUT SQ '%s' " + "qid=%d cq_qid=%d: %u\n", name, + out_qid, cq_qid, status); + error = EIO; + goto fail_sq_out; + } + + mtx_lock(&sc->sc_queues_lock); + sc->sc_queues[out_qid] = tq->sq_out; + sc->sc_int_sq_list[out_qid] = tq->sq_out; + mtx_unlock(&sc->sc_queues_lock); } - mtx_lock(&sc->sc_queues_lock); - sc->sc_queues[out_qid] = tq->sq_out; - sc->sc_int_sq_list[out_qid] = tq->sq_out; - mtx_unlock(&sc->sc_queues_lock); + /* Allocate IN SQ (device -> host), only if this direction needs it */ + if (want_in) { + in_qid = bce_vhci_alloc_qid(vhci); + if (in_qid < 0) { + error = ENOSPC; + goto fail_sq_out_reg; + } + tq->sq_in = bce_alloc_sq(sc, in_qid, + sizeof(struct bce_qe_submission), BCE_VHCI_TQ_EL, + bce_vhci_tq_completion, tq); + if (tq->sq_in == NULL) { + error = ENOMEM; + goto fail_sq_in_alloc; + } - /* Allocate IN SQ (device -> host) */ - in_qid = bce_vhci_alloc_qid(vhci); - if (in_qid < 0) { - error = ENOSPC; - goto fail_sq_out_reg; - } - tq->sq_in = bce_alloc_sq(sc, in_qid, - sizeof(struct bce_qe_submission), BCE_VHCI_TQ_EL, - bce_vhci_tq_completion, tq); - if (tq->sq_in == NULL) { - error = ENOMEM; - goto fail_sq_in_alloc; - } + snprintf(name, sizeof(name), "VHC1-%d-%02x", + dev->fw_dev_id, ep_addr | 0x80); + bce_get_sq_memcfg(tq->sq_in, tq->cq, &cfg); + status = bce_cmd_register_queue(sc->sc_cmd_cmdq, sc, &cfg, + name, 0); + if (status != 0) { + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "failed to register IN SQ '%s' " + "qid=%d cq_qid=%d out_qid=%d: %u\n", + name, in_qid, cq_qid, out_qid, + status); + error = EIO; + goto fail_sq_in; + } - snprintf(name, sizeof(name), "VHC1-%d-%02x", - dev->fw_dev_id, ep_addr | 0x80); - bce_get_sq_memcfg(tq->sq_in, tq->cq, &cfg); - status = bce_cmd_register_queue(sc->sc_cmd_cmdq, sc, &cfg, name, 0); - if (status != 0) { - device_printf(vhci->sc_dev, - "failed to register IN SQ '%s': %u\n", name, status); - error = EIO; - goto fail_sq_in; + mtx_lock(&sc->sc_queues_lock); + sc->sc_queues[in_qid] = tq->sq_in; + sc->sc_int_sq_list[in_qid] = tq->sq_in; + mtx_unlock(&sc->sc_queues_lock); } - mtx_lock(&sc->sc_queues_lock); - sc->sc_queues[in_qid] = tq->sq_in; - sc->sc_int_sq_list[in_qid] = tq->sq_in; - mtx_unlock(&sc->sc_queues_lock); - /* Tell firmware to create the endpoint */ memset(&cmd, 0, sizeof(cmd)); cmd.cmd = BCE_VHCI_CMD_ENDPOINT_CREATE; @@ -2183,9 +2211,12 @@ bce_vhci_endpoint_create(struct bce_vhci_softc *vhci, error = bce_vhci_cmd_execute(vhci, &cmd, &reply, BCE_VHCI_CMD_TIMEOUT_SHORT); if (error != 0) { - device_printf(vhci->sc_dev, - "ENDPOINT_CREATE(dev=%d, ep=0x%02x) failed: %d\n", - dev->fw_dev_id, ep_addr, error); + if (ppsratecheck(&tq->create_fail_lastprint, + &tq->create_fail_pps, 1)) + device_printf(vhci->sc_dev, + "ENDPOINT_CREATE(dev=%d, ep=0x%02x) " + "failed: %d\n", + dev->fw_dev_id, ep_addr, error); goto fail_sq_in_reg; } @@ -2199,27 +2230,37 @@ bce_vhci_endpoint_create(struct bce_vhci_softc *vhci, return (0); fail_sq_in_reg: - bce_cmd_unregister_queue(sc->sc_cmd_cmdq, sc, in_qid); - mtx_lock(&sc->sc_queues_lock); - sc->sc_queues[in_qid] = NULL; - sc->sc_int_sq_list[in_qid] = NULL; - mtx_unlock(&sc->sc_queues_lock); + if (want_in) { + bce_cmd_unregister_queue(sc->sc_cmd_cmdq, sc, in_qid); + mtx_lock(&sc->sc_queues_lock); + sc->sc_queues[in_qid] = NULL; + sc->sc_int_sq_list[in_qid] = NULL; + mtx_unlock(&sc->sc_queues_lock); + } fail_sq_in: - bce_free_sq(sc, tq->sq_in); - tq->sq_in = NULL; + if (want_in) { + bce_free_sq(sc, tq->sq_in); + tq->sq_in = NULL; + } fail_sq_in_alloc: - bce_vhci_free_qid(vhci, in_qid); + if (in_qid >= 0) + bce_vhci_free_qid(vhci, in_qid); fail_sq_out_reg: - bce_cmd_unregister_queue(sc->sc_cmd_cmdq, sc, out_qid); - mtx_lock(&sc->sc_queues_lock); - sc->sc_queues[out_qid] = NULL; - sc->sc_int_sq_list[out_qid] = NULL; - mtx_unlock(&sc->sc_queues_lock); + if (want_out) { + bce_cmd_unregister_queue(sc->sc_cmd_cmdq, sc, out_qid); + mtx_lock(&sc->sc_queues_lock); + sc->sc_queues[out_qid] = NULL; + sc->sc_int_sq_list[out_qid] = NULL; + mtx_unlock(&sc->sc_queues_lock); + } fail_sq_out: - bce_free_sq(sc, tq->sq_out); - tq->sq_out = NULL; + if (want_out) { + bce_free_sq(sc, tq->sq_out); + tq->sq_out = NULL; + } fail_sq_out_alloc: - bce_vhci_free_qid(vhci, out_qid); + if (out_qid >= 0) + bce_vhci_free_qid(vhci, out_qid); fail_cq_reg: bce_cmd_unregister_queue(sc->sc_cmd_cmdq, sc, cq_qid); mtx_lock(&sc->sc_queues_lock); @@ -2436,6 +2477,11 @@ bce_vhci_device_create(struct bce_vhci_softc *vhci, uint8_t port) "device created: port=%d fw_dev_id=%d\n", port, fw_dev_id); dev = &vhci->sc_devs[fw_dev_id]; + if (dev->allocated != 0) + device_printf(vhci->sc_dev, + "device created: fw_dev_id=%d reused while still " + "marked allocated (old port=%d, new port=%d)\n", + fw_dev_id, dev->port, port); memset(dev, 0, sizeof(*dev)); dev->allocated = 1; dev->fw_dev_id = fw_dev_id; diff --git a/sys/dev/apple_bce/apple_bce_vhci.h b/sys/dev/apple_bce/apple_bce_vhci.h index c85dd326b277..71cba4a5fd32 100644 --- a/sys/dev/apple_bce/apple_bce_vhci.h +++ b/sys/dev/apple_bce/apple_bce_vhci.h @@ -207,6 +207,8 @@ struct bce_vhci_transfer_queue { int create_pending; /* Deferred ep create */ struct usb_endpoint_descriptor *create_edesc; struct usb_xfer *create_xfer; /* Deferred xfer */ + struct timeval create_fail_lastprint; + int create_fail_pps; /* DMA buffer for data transfer */ bus_dma_tag_t dma_tag;