DF-5334 / fix.diff
--- a/sys/bus/u4b/net/usb_ethernet.c 2026-10-03 00:29:42.632025953 +0000 +++ b/sys/bus/u4b/net/usb_ethernet.c 2026-10-03 00:29:47.275967257 +0000 @@ -269,6 +269,17 @@ { struct ifnet *ifp; + /* + * Never attached: the calling driver's attach failed before + * uether_ifattach() ran, so ue_lock and ue_tq were never set up + * and the embedded arpcom/ifnet was never if_attach()ed. On + * DragonFly uether_getifp() returns the address of the embedded + * ifnet and can never return NULL, so guard on ue_lock instead + * (uether_ifattach() refuses to run when it is NULL). + */ + if (ue->ue_lock == NULL) + return; + /* wait for any post attach or other command to complete */ usb_proc_drain(&ue->ue_tq); --- a/sys/bus/u4b/net/if_cdce.c 2026-10-03 00:29:42.632025953 +0000 +++ b/sys/bus/u4b/net/if_cdce.c 2026-10-03 00:29:53.895883585 +0000 @@ -608,7 +608,7 @@ } } else { device_printf(dev, "no data interface found\n"); - goto detach; + goto detach_usb; } } @@ -660,7 +660,7 @@ if (error || (i == 32)) { device_printf(dev, "No valid alternate " "setting found\n"); - goto detach; + goto detach_usb; } ued = usbd_find_descriptor @@ -727,6 +727,18 @@ } return (0); /* success */ +detach_usb: + /* + * Attach failed before uether_ifattach(): the usb_ether was never + * initialised, so only tear down what may have been set up. Do + * NOT call cdce_detach() here - uether_ifdetach() would try to + * lock through the NULL ue_lock and to detach the never-attached + * embedded ifnet. + */ + usbd_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER); + lockuninit(&sc->sc_lock); + return (ENXIO); /* failure */ + detach: cdce_detach(dev); return (ENXIO); /* failure */ |