The branch main has been updated by seuros: URL: https://cgit.FreeBSD.org/src/commit/?id=c0ec1e0e60caf513e4cfa42b995631f19d376a26
commit c0ec1e0e60caf513e4cfa42b995631f19d376a26 Author: Abdelkader Boudih <[email protected]> AuthorDate: 2026-09-06 19:16:33 +0000 Commit: Abdelkader Boudih <[email protected]> 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",
