Re: [PATCH v3 1/3] driver core: add device_enumeration_failure_notify() helper

From: Alan Stern

Date: Mon May 04 2026 - 22:09:40 EST


On Mon, May 04, 2026 at 07:33:07PM +0000, Akshay Gujar wrote:
> Hotpluggable buses may detect that a device is physically present,
> but enumeration can fail early due to protocol-level errors. Such
> failures are currently only visible via kernel log messages, with no
> structured notification to userspace.
>
> Introduce device_enumeration_failure_notify(), a helper in the driver
> core that emits a KOBJ_CHANGE uevent with
>
> DEVICE_ENUMERATION_FAILURE=<dev_name>
>
> This helper is intended for use by bus drivers such as USB and PCI.
>
> Signed-off-by: Akshay Gujar <Akshay.Gujar@xxxxxxxxxx>
> ---
> drivers/base/core.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/device.h | 11 +++++++++++
> 2 files changed, 53 insertions(+)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index bd2ddf2aab50..1ab3b8290840 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -3764,6 +3764,48 @@ int device_add(struct device *dev)
> }
> EXPORT_SYMBOL_GPL(device_add);
>
> +/**
> + * device_enumeration_failure_notify - notify userspace of enumeration failure
> + * @dev: device for which enumeration failed
> + *
> + * Emit a KOBJ_CHANGE uevent with
> + * DEVICE_ENUMERATION_FAILURE=<dev_name>.
> + *
> + * If @dev has not yet emitted its ADD uevent, the event may be sent
> + * from the parent device instead.
> + *
> + * The caller must hold a reference to @dev.
> + */
> +void device_enumeration_failure_notify(struct device *dev)
> +{
> + char *envp[2] = { NULL, NULL };
> + struct device *uevent_dev;
> +
> + if (!dev)
> + return;
> +
> + /*
> + * If enumeration fails before @dev has emitted its ADD uevent, the
> + * device may still be in an early state (e.g. without a bus or class
> + * assigned). Emit the event from the parent device instead, while
> + * including DEVICE_ENUMERATION_FAILURE=<dev_name>.
> + *
> + * The caller holds a reference to @dev, so dev->parent remains valid.
> + */
> + uevent_dev = dev->kobj.state_add_uevent_sent ? dev : dev->parent;
> + if (!uevent_dev)
> + return;
> +
> + envp[0] = kasprintf(GFP_KERNEL, "DEVICE_ENUMERATION_FAILURE=%s",
> + dev_name(dev));
> + if (!envp[0])
> + return;
> +
> + kobject_uevent_env(&uevent_dev->kobj, KOBJ_CHANGE, envp);
> + kfree(envp[0]);
> +}
> +EXPORT_SYMBOL_GPL(device_enumeration_failure_notify);
> +
> /**
> * device_register - register a device with the system.
> * @dev: pointer to the device structure
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 9c8fde6a3d86..b8776cfb6fa0 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -1343,4 +1343,15 @@ static inline bool device_link_test(const struct device_link *link, u32 flags)
> #define MODULE_ALIAS_CHARDEV_MAJOR(major) \
> MODULE_ALIAS("char-major-" __stringify(major) "-*")
>
> +/**
> + * device_enumeration_failure_notify - notify userspace of enumeration failure
> + * @dev: device where enumeration failed
> + *
> + * Emits a KOBJ_CHANGE uevent with
> + * DEVICE_ENUMERATION_FAILURE=<dev_name>.
> + *
> + * See Documentation/ABI/testing/sysfs-uevent.
> + */
> +void device_enumeration_failure_notify(struct device *dev);
> +

I don't think it's very common to include two identical copies of the
same kerneldoc, one for the declaration and one for the definition.
It's wasteful and it violates the DRY ("Don't Repeat Yourself")
principle.

Also, what does "device where enumeration failed" really mean? Does it
refer to the device that would have been added if the enumeration had
succeeded? Or does it refer to the device that is trying to enumerate a
newly detected child? The comment in the
device_enumeration_failure_notify() function above seems to indicate the
former, whereas the code added to the USB subsystem in the 3/3 patch
does the latter.

Alan Stern