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",

Reply via email to