Fixes#581
Open
FireBurn wants to merge 3 commits into
Open
Conversation
drm-next (Linux 7.1) renamed the global atomic-state object and its
allocator helpers:
struct drm_atomic_state -> struct drm_atomic_commit
drm_atomic_state_alloc/clear/put -> drm_atomic_commit_alloc/clear/put
The atomic-helper vtable callbacks (.atomic_flush/.atomic_update/...) and
the state accessors (drm_atomic_get_{new,old}_*_state()) now take a
struct drm_atomic_commit *. evdi still uses the historical drm_atomic_state
names throughout evdi_modeset.c, so it fails to build against >= 7.1 with
incompatible pointer and function-pointer types.
Alias the old identifiers to the new ones for KERNEL_VERSION(7, 1, 0) and
later. The old names are fully gone from the tree, so these whole-token
macros cannot collide with anything still in the headers.
Signed-off-by: Mike Lothian <mike@fireburn.co.uk>
evdi_platform_drv_usb() is installed with usb_register_notify(), so the USB core delivers it the USB_DEVICE_ADD / USB_DEVICE_REMOVE notifications (see usb_notify_add_device()/usb_notify_remove_device() in drivers/usb/core/notify.c), with the struct usb_device passed in @DaTa. The handler instead compared @action against the bus-notifier constant BUS_NOTIFY_DEL_DEVICE. That enum value happens to equal USB_DEVICE_ADD (1), so the notifier body ran on every USB device *addition* and returned early on every *removal*. As a result evdi never reacted to its parent USB device (the dock) being unplugged. Test the correct USB_DEVICE_REMOVE constant so the handler runs when the parent USB device is removed. Signed-off-by: Mike Lothian <mike@fireburn.co.uk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
When the parent USB device was unplugged the removal notifier detached the evdi platform device from it but never destroyed it. The teardown was gated on: if (pdev->dev.parent == &usb_dev->dev) but evdi platform devices are created with .parent = NULL (see evdi_platform_drv_create_new_device()); the USB relationship is tracked in evdi_platform_device_data::parent, not in dev.parent. The condition was therefore never true, so the DRM device was never unregistered, drm_dev_unplug() never ran, and userspace (Wayland compositors, Xorg) received no hot-unplug uevent and leaked the stale device. Have evdi_platform_device_unlink_if_linked_with() report whether it actually detached the device from this USB parent, and destroy the device when it did. Restrict the destroy to dynamically created devices (i >= evdi_initial_device_count); the statically pre-allocated devices are only detached, preserving their intended lifetime for static-list clients. Signed-off-by: Mike Lothian <mike@fireburn.co.uk> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
EVDI PR notes — drm-next (7.1) build support + USB-unplug teardown fix
PR-ready material for DisplayLink/evdi. Branch
fix-usb-unplug-teardown(in
evdi/, based onorigin/main) carries three clean, signed-off commits:evdi: support the drm_atomic_state -> drm_atomic_commit renameevdi: react to USB_DEVICE_REMOVE in the USB unplug notifierevdi: destroy dynamic devices when their USB parent is removedCommit 1 is first so the tree builds on a 7.1 kernel before the behavioural
commits (bisectable on every kernel; the shim is inert below 7.1).
1. drm-next (Linux 7.1) build support
drm-next renamed the global atomic-state object and its allocator helpers:
The atomic-helper vtable callbacks (
.atomic_flush/.atomic_update/...) and thestate accessors (
drm_atomic_get_{new,old}_*_state()) now take astruct drm_atomic_commit *. evdi still uses the historicaldrm_atomic_statenames throughout
evdi_modeset.c, so against >= 7.1 it fails with incompatiblepointer / function-pointer types.
The commit aliases the old identifiers to the new ones for
KERNEL_VERSION(7, 1, 0)+inevdi_drm_drv.h. Because evdi refers to the structand the three renamed helpers by name everywhere, a handful of whole-token
#defines cascade through the whole module; the old names are gone from thetree, so the macros cannot collide. Authored by Mike Lothian (predates this
work).
2 + 3. USB-unplug teardown
When the dock was physically removed, evdi's USB-removal notifier
(
evdi_platform_drv_usb()) was supposed to unlink and destroy thedynamically-created evdi platform/DRM device. It never did —
drm_dev_unplug()never ran, no
removeuevent was emitted, the DRM node lingered as a ghost, and/sys/module/evdi/refcntclimbed and never fell (reboot required). Waylandcompositors (KWin) and Xorg, which rely on the hot-unplug uevent, were left
holding a stale fd.
Two independent bugs, either alone enough to block teardown — so the path had
never worked:
usb_register_notify(), so the USB core deliversUSB_DEVICE_ADD/USB_DEVICE_REMOVE(drivers/usb/core/notify.c). The handler instead testedaction != BUS_NOTIFY_DEL_DEVICE, andBUS_NOTIFY_DEL_DEVICE == 1 == USB_DEVICE_ADD, so the body ran on every add and returned early on everyremove — it never reacted to an unplug. Fixed by testing
USB_DEVICE_REMOVE.gated on
pdev->dev.parent == &usb_dev->dev, but evdi platform devices arecreated with
.parent = NULL(evdi_platform_drv_create_new_device()); theUSB link lives in
evdi_platform_device_data::parent. The condition was nevertrue. Fixed by making
evdi_platform_device_unlink_if_linked_with()returnbool(did it detach from this parent) and destroying when it did,restricted to dynamic devices (
i >= evdi_initial_device_count) so thestatically pre-allocated pool (for static-device-list clients like Xorg) is
only detached.
Teardown chain restored:
evdi_platform_dev_destroy()→platform_device_unregister()→evdi_platform_device_remove()→evdi_drm_device_remove()→drm_dev_unplug()→ udevremoveuevent.Verification (HW, 2026-06-30)
Dell D6000 dock, kernel
7.1.0-rc5-drm+,initial_device_count=0, KWin/Wayland +DisplayLinkManager driving two heads.
changeuevents;evdi.0/evdi.1and theirdevicesymlinks persisted; refcnt stuck (23 → 23).Detached from parent device→Parent USB removed. Removing evdi.0/evdi.1→Evdi platform_device destroy→Evdi drm_device removed.;udev
remove(not justchange) oncard2/card3+ connectors;/sys/devices/platform/evdi.*gone;/dev/dri/back to the real GPUs;refcnt 23 → 0 (no leak).
module/evdi.kobuilds clean across all three commits (sha verified identical tothe tested module).
checkpatch (
--strict): 0 errors on all threeRemaining items are non-blocking:
LINUX_VERSION_CODE should be avoided— inherent to any kernelversion-compat shim; evdi is an out-of-tree module built on
KERNEL_VERSION()guards throughout.
Co-authored-by:is not a kernel-standard trailer (the kernelrecognises
Co-developed-by:, which needs its own DCO sign-off). Drop thetrailer if a spotless run is wanted.
evdi_platform_device_unlink_if_linked_withsignature — pre-existing upstreamindentation; the patch only changes the return keyword (
void→bool, samewidth), introducing no new misalignment.