Search Linux Wireless

Re: [PATCH] wifi: brcmfmac: avoid calling platform_driver_unregister() more than once

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/14/25 12:22 PM, Arend van Spriel wrote:

When the platform_driver_probe() fails it means that brcmfmac_pdata will
be NULL so it provides the same info as the returned error. So the
net result is the same and no platform_driver_unregister() will be called.
I'm not sure whether the following model is 100% accurate against the real
driver, but it always crashes (in platform_driver_unregister() explicitly
called from module init function) when non-zero (say, -ENOMEM) is returned
from probe (e.g. t_platform_driver_probe()) function:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>

static struct platform_device t_platform_device = {
	.name = "testdev",
};

struct t_driver_data {
	int dummy;
} *t_pdata = NULL, driver_data = { .dummy = 1 };

static void t_platform_driver_remove(struct platform_device *pd)
{
	printk(KERN_ERR "remove platform device@%p\n", pd);
}

static struct platform_driver t_pd = {
	.remove = t_platform_driver_remove,
	.driver = {
		.name = "testdev",
	}
};

static int t_platform_driver_probe(struct platform_device *pd)
{
	printk(KERN_ERR "probe platform device@%p\n", pd);
	t_pdata = &driver_data;
	return 0;
}

static int t_always_error(void)
{
	return -ENODATA;
}

static int __init
t_platform_driver_init(void)
{
	int err;

	err = platform_device_register(&t_platform_device);
	if (err) {
		printk(KERN_ERR "unable to register platform device\n");
		return err;
	}

	err = platform_driver_probe(&t_pd, t_platform_driver_probe);

	if (err == -ENODEV)
		printk(KERN_ERR "No platform data");

	err = t_always_error();

	if (err) {
		if (t_pdata) {
			printk(KERN_ERR "going to unregister platform driver@%p\n", &t_pd);
			platform_driver_unregister(&t_pd);
		}
		platform_device_unregister(&t_platform_device);
	}
	return err;
}

static void __exit
t_platform_driver_exit(void)
{
	if (t_pdata)
		platform_driver_unregister(&t_pd);

	platform_device_unregister(&t_platform_device);
}

module_init(t_platform_driver_init);
module_exit(t_platform_driver_exit);
MODULE_LICENSE("GPL");

Dmitry




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux