git: c0ec1e0e60ca - main - apple_bce: fix C_CONNECT_STATUS during port reset
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Sep 2026 19:48:33 UTC
The branch main has been updated by seuros:
URL: https://cgit.FreeBSD.org/src/commit/?id=c0ec1e0e60caf513e4cfa42b995631f19d376a26
commit c0ec1e0e60caf513e4cfa42b995631f19d376a26
Author: Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-06 19:16:33 +0000
Commit: Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-06 19:47:44 +0000
apple_bce: fix C_CONNECT_STATUS during port reset
Only set the port change bit when the corresponding status bit
actually transitioned, instead of unconditionally flagging
C_CONNECT_STATUS on every port change event. Also clear any
flaky C_CONNECT_STATUS that the port change taskqueue may have
set while the bus lock was dropped during a successful port reset.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D58875
---
sys/dev/apple_bce/apple_bce_vhci.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/sys/dev/apple_bce/apple_bce_vhci.c b/sys/dev/apple_bce/apple_bce_vhci.c
index 7056f8e2fb97..56d519e715c1 100644
--- a/sys/dev/apple_bce/apple_bce_vhci.c
+++ b/sys/dev/apple_bce/apple_bce_vhci.c
@@ -1007,8 +1007,12 @@ bce_vhci_port_chg_task(void *arg, int pending __unused)
USB_BUS_LOCK(&vhci->sc_bus);
if (error == 0) {
+ uint16_t changed, old_status;
+
port_status = (uint32_t)reply.param2;
+ old_status = vhci->sc_port_status[port];
+
vhci->sc_port_status[port] = 0;
if (vhci->sc_port_power[port])
vhci->sc_port_status[port] |=
@@ -1025,8 +1029,24 @@ bce_vhci_port_chg_task(void *arg, int pending __unused)
if (port_status & BCE_VHCI_PORT_OVERCURRENT)
vhci->sc_port_status[port] |=
UPS_OVERCURRENT_INDICATOR;
+
+ changed = old_status ^ vhci->sc_port_status[port];
+
+ if (changed & UPS_CURRENT_CONNECT_STATUS)
+ vhci->sc_port_change[port] |=
+ UPS_C_CONNECT_STATUS;
+ if (changed & UPS_PORT_ENABLED)
+ vhci->sc_port_change[port] |=
+ UPS_C_PORT_ENABLED;
+ if (changed & UPS_SUSPEND)
+ vhci->sc_port_change[port] |=
+ UPS_C_SUSPEND;
+ if (changed & UPS_OVERCURRENT_INDICATOR)
+ vhci->sc_port_change[port] |=
+ UPS_C_OVERCURRENT_INDICATOR;
+ } else {
+ vhci->sc_port_change[port] |= UPS_C_CONNECT_STATUS;
}
- vhci->sc_port_change[port] |= UPS_C_CONNECT_STATUS;
USB_BUS_UNLOCK(&vhci->sc_bus);
}
@@ -4107,6 +4127,8 @@ bce_vhci_roothub_exec(struct usb_device *udev,
UPS_HIGH_SPEED;
vhci->sc_port_change[index - 1] |=
UPS_C_PORT_RESET;
+ vhci->sc_port_change[index - 1] &=
+ ~UPS_C_CONNECT_STATUS;
} else {
device_printf(vhci->sc_dev,
"port %d reset failed: %d\n",