[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CACF_UwqpzNJWm0=zJh=1N_9p1Q6YjmU+DSofB_OOySkdWC_AxA@mail.gmail.com>
Date: Tue, 22 Jul 2025 01:18:25 +0200
From: Marco Tormento <mtormento80@...il.com>
To: Alan Stern <stern@...land.harvard.edu>
Cc: gregkh@...uxfoundation.org, linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] USB: hub: Move typec deattach before children
disconnections in usb_disconnect()
On Mon, 21 Jul 2025 at 03:21, Alan Stern <stern@...land.harvard.edu> wrote:
> I'm not a typec expert; in fact I know practically nothing about it.
> Nevertheless, this sounds strange. The recursive usb_disconnect() calls
> should affect the connectors to the monitor's children and the monitor's
> own ports, not the connector or port on the monitor's parent hub.
What you wrote makes total sense, let me add some detail though.
When I plug the monitor to the thunderbolt port, 3 usb hubs pop up, but only 2
are backed by XHCI Host Controllers: usb3 and usb4.
usb 3-1 instead is using usb3 and it has 3 devices connected to it: mouse,
keyboard and a mysterious billboard device:
xhci_hcd 0000:3c:00.0: xHCI Host Controller
xhci_hcd 0000:3c:00.0: new USB bus registered, assigned bus number 3
xhci_hcd 0000:3c:00.0: hcc params 0x200077c1 hci version 0x110 quirks
0x0000000200009810
xhci_hcd 0000:3c:00.0: xHCI Host Controller
xhci_hcd 0000:3c:00.0: new USB bus registered, assigned bus number 4
xhci_hcd 0000:3c:00.0: Host supports USB 3.1 Enhanced SuperSpeed
usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.15
usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb3: Product: xHCI Host Controller
usb usb3: Manufacturer: Linux 6.15.7-arch1-1-mentor xhci-hcd
usb usb3: SerialNumber: 0000:3c:00.0
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 2 ports detected
usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.15
usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb4: Product: xHCI Host Controller
usb usb4: Manufacturer: Linux 6.15.7-arch1-1-mentor xhci-hcd
usb usb4: SerialNumber: 0000:3c:00.0
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
typec port0: bound usb3-port1 (ops connector_ops [usbcore])
typec port0: bound usb4-port1 (ops connector_ops [usbcore])
typec port1: bound usb3-port2 (ops connector_ops [usbcore])
typec port1: bound usb4-port2 (ops connector_ops [usbcore])
usb 3-1: new high-speed USB device number 2 using xhci_hcd
usb 3-1: New USB device found, idVendor=0bda, idProduct=5411, bcdDevice= 1.36
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 3-1: Product: 4-Port USB 2.0 Hub
usb 3-1: Manufacturer: Generic
hub 3-1:1.0: USB hub found
hub 3-1:1.0: 3 ports detected
usb 3-1.3: new full-speed USB device number 3 using xhci_hcd
usb 3-1.3: not running at top speed; connect to a high speed hub
usb 3-1.3: New USB device found, idVendor=0bda, idProduct=5400, bcdDevice= 1.07
usb 3-1.3: New USB device strings: Mfr=17, Product=18, SerialNumber=19
usb 3-1.3: Product: BillBoard Device
usb 3-1.3: Manufacturer: Realtek
usb 3-1.3: SerialNumber: 123456789ABCDEFGH
usb 3-1.2: new full-speed USB device number 4 using xhci_hcd
usb 3-1.2: New USB device found, idVendor=0951, idProduct=16e6, bcdDevice=21.08
usb 3-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 3-1.2: Product: HyperX Alloy Origins Core
usb 3-1.2: Manufacturer: Kingston
usb 3-1.1: new full-speed USB device number 5 using xhci_hcd
usb 3-1.1: New USB device found, idVendor=1a7c, idProduct=0197, bcdDevice= 1.06
usb 3-1.1: New USB device strings: Mfr=1, Product=3, SerialNumber=0
usb 3-1.1: Product: Evoluent VerticalMouse D
usb 3-1.1: Manufacturer: Kingsis Peripherals
When I unplug the monitor though, usb 3-1 is not processed as part of
hub_disconnect_children() of usb3 hub, as I would expect.
It is processed on its own (added some debugging log to some functions):
usb 3-1: [usb_disconnect] debugging
usb 3-1: [usb_disconnect] USB disconnect, device number 2
usb 3-1: [hub_disconnect_children] debugging hub_disconnect_children()
usb 3-1: [hub_disconnect_children] disconnecting child 0
usb 3-1.1: [usb_disconnect] debugging
usb 3-1.1: [usb_disconnect] USB disconnect, device number 5
usb 3-1.1: [hub_disconnect_children] debugging hub_disconnect_children()
usb 3-1.1: [usb_disconnect] unregistering device
usbhid 3-1.1:1.0: [usb_unbind_interface] debugging
usb 3-1.1: [usb_disconnect] parent found
usb 3-1.1: [usb_disconnect] removing port 3-1-port1 from hub 3-1:1.0: 0
usb 3-1.1: [usb_disconnect] done with the device
usb 3-1: [hub_disconnect_children] disconnecting child 1
usb 3-1.2: [usb_disconnect] debugging
usb 3-1.2: [usb_disconnect] USB disconnect, device number 4
usb 3-1.2: [hub_disconnect_children] debugging hub_disconnect_children()
usb 3-1.2: [usb_disconnect] unregistering device
usbhid 3-1.2:1.0: [usb_unbind_interface] debugging
xhci_hcd 0000:3c:00.0: remove, state 4
usb usb4: [usb_disconnect] debugging
usb usb4: [usb_disconnect] USB disconnect, device number 1
usb usb4: [hub_disconnect_children] debugging hub_disconnect_children()
usb usb4: [usb_disconnect] unregistering device
hub 4-0:1.0: [usb_unbind_interface] debugging
usb usb4: [hub_disconnect] debugging
usb usb4-port2: [usb_hub_remove_port_device] debugging: port 1
typec port1: [connector_unbind] unbinding connector from usb4-port2
typec port1: [connector_unbind] unbinding connector from usb3-port2
usb usb4-port1: [usb_hub_remove_port_device] debugging: port 0
typec port0: [connector_unbind] unbinding connector from usb4-port1
typec port0: [connector_unbind] unbinding connector from usb3-port1
usb usb4: [usb_disconnect] done with the device
xhci_hcd 0000:3c:00.0: USB bus 4 deregistered
xhci_hcd 0000:3c:00.0: xHCI host controller not responding, assume dead
xhci_hcd 0000:3c:00.0: remove, state 1
usb usb3: [usb_disconnect] debugging
usb usb3: [usb_disconnect] USB disconnect, device number 1
typec port1-partner: [typec_unregister_partner] debugging
typec port1-partner: [typec_unregister_partner] unregistering from port: port1
usbhid 3-1.2:1.1: [usb_unbind_interface] debugging
usbhid 3-1.2:1.2: [usb_unbind_interface] debugging
usb 3-1.2: [usb_disconnect] parent found
usb 3-1.2: [usb_disconnect] removing port 3-1-port2 from hub 3-1:1.0: 1
usb 3-1.2: [usb_disconnect] done with the device
usb 3-1: [hub_disconnect_children] disconnecting child 2
usb 3-1.3: [usb_disconnect] debugging
usb 3-1.3: [usb_disconnect] USB disconnect, device number 3
usb 3-1.3: [hub_disconnect_children] debugging hub_disconnect_children()
usb 3-1.3: [usb_disconnect] unregistering device
usb 3-1.3: [usb_disconnect] parent found
usb 3-1.3: [usb_disconnect] removing port 3-1-port3 from hub 3-1:1.0: 2
usb 3-1.3: [usb_disconnect] done with the device
usb 3-1: [usb_disconnect] unregistering device
hub 3-1:1.0: [usb_unbind_interface] debugging
usb 3-1: [hub_disconnect] debugging
usb 3-1-port3: [usb_hub_remove_port_device] debugging: port 2
usb 3-1-port2: [usb_hub_remove_port_device] debugging: port 1
usb 3-1-port1: [usb_hub_remove_port_device] debugging: port 0
usb 3-1: [usb_disconnect] parent found
usb 3-1: [usb_disconnect] removing port usb3-port1 from hub 3-0:1.0: 0
usb 3-1: [usb_disconnect] done with the device
usb usb3: [hub_disconnect_children] debugging hub_disconnect_children()
usb usb3: [usb_disconnect] unregistering device
hub 3-0:1.0: [usb_unbind_interface] debugging
usb usb3: [hub_disconnect] debugging
usb usb3-port2: [usb_hub_remove_port_device] debugging: port 1
usb usb3-port1: [usb_hub_remove_port_device] debugging: port 0
usb usb3: [usb_disconnect] done with the device
xhci_hcd 0000:3c:00.0: Host halt failed, -19
xhci_hcd 0000:3c:00.0: Host not accessible, reset failed.
xhci_hcd 0000:3c:00.0: USB bus 3 deregistered
As you can see typec port connectors are unbound during usb4 usb_disconnect(),
so when usb 3-1 tries to typec_deattach() after it disconnected all its children
the connector is not there anymore and type_partner_deattach() is not invoked.
Maybe usb 3-1 should be disconnected as a child of usb3, but even in that case
we would still end up in the same situation because it's usb4 disconnection that
is doing the unbinding.
Since there's no dependency between usb3 and usb4 they can be
disconnected in any order and it's just a matter of luck as it is right now.
Hope things make a little bit more sense now.
Marco Tormento
Powered by blists - more mailing lists