Issue
I register bus, driver and device, and I want to register a class, then I initialize device's class before register device, that emit a error: "don't try to register things with the same name in the same directory". I think the code is OK, and if I not to initialize device's class, that is OK, and it works well. But now I want to create a class to go for it. Can you give me some suggestions?
The code is this:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/device/driver.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
static struct class test_class = {
.name = "mytest_class",
.owner = THIS_MODULE,
};
static int bus_match(struct device *dev, struct device_driver *drv)
{
printk(KERN_INFO"In %s \n", __func__);
//match by driver name and device name
return (strcmp(dev_name(dev), drv->name) == 0);
}
static int bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
int ret=1;
printk(KERN_INFO "%s hotplug\n", dev_name(dev));
ret = add_uevent_var(env, "THIS_TEST=%s", dev_name(dev));
if(ret)
{
return ret;
}
return add_uevent_var(env, "EVENT=%s", "change");
}
static int bus_probe(struct device *dev)
{
return dev->driver->probe(dev);
return 0;
}
static void bus_remove(struct device *dev)
{
dev->driver->remove(dev);
}
struct bus_type bus_test =
{
.name = "bus-test",
.match = bus_match,
.uevent= bus_uevent,
.probe = bus_probe,
.remove= bus_remove,
};
EXPORT_SYMBOL(bus_test);
static int driver_probe(struct device *dev)
{
printk(KERN_INFO "driver probe!\n");
return 0;
}
static int driver_remove(struct device *dev)
{
printk(KERN_INFO "driver remove!\n");
return 0;
}
static struct device_driver driver_test=
{
.name = "driver_test",
.bus = &bus_test,
.probe = driver_probe,
.remove = driver_remove,
};
static void dev_test_release(struct device *dev)
{
printk(KERN_INFO "device release!\n");
}
static struct device dev_test = {
.init_name = "driver_test",
.bus = &bus_test,
.release = dev_test_release,
};
static int __init init_driver_test(void)
{
int ret = 0;
printk(KERN_INFO "init module!\n");
ret = bus_register(&bus_test);
if (ret) {
printk(KERN_ERR "bus register error!\n");
return ret;
}
ret = class_register(&test_class);
if (ret) {
printk(KERN_ERR "class register error!\n");
return ret;
}
dev_test.class = &test_class,
dev_test.devt=MKDEV(100, 1);
ret = device_register(&dev_test);
if(ret)
{
printk(KERN_ERR "device register error!\n");
return ret;
}
ret = driver_register(&driver_test);
if (ret) {
printk(KERN_ERR "driver register error!\n");
return ret;
}
return ret;
}
static void __exit exit_driver_test(void)
{
driver_unregister(&driver_test);
device_unregister(&dev_test);
class_unregister(&test_class);
bus_unregister(&bus_test);
printk(KERN_INFO "exit module!\n");
}
module_init(init_driver_test);
module_exit(exit_driver_test);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NoError");
MODULE_DESCRIPTION("driver test");
I built it as module, and insmod it, it's falied, the error is:
# insmod driver_test.ko
[ 48.663393] driver_test: loading out-of-tree module taints kernel.
[ 48.669891] driver_test: module verification failed: signature and/or required key missing - tainting kernel
[ 48.680389] init module!
[ 48.683167] Driver 'driver_test' needs updating - please use bus_type methods
[ 48.690549] sysfs: cannot create duplicate filename '/devices/virtual/rapidio_port/driver_test/subsystem'
[ 48.700176] CPU: 3 PID: 326 Comm: insmod Tainted: G OE 6.0.11 #3
[ 48.707511] Hardware name: OrangePi Zero2 (DT)
[ 48.711961] Call trace:
[ 48.714412] dump_backtrace+0xd8/0x120
[ 48.718192] show_stack+0x18/0x50
[ 48.721524] dump_stack_lvl+0x68/0x84
[ 48.725201] dump_stack+0x18/0x34
[ 48.728526] sysfs_warn_dup+0x60/0x80
[ 48.732207] sysfs_do_create_link_sd+0x138/0x140
[ 48.736839] sysfs_create_link+0x30/0x50
[ 48.740777] bus_add_device+0xf0/0x140
[ 48.744542] device_add+0x33c/0x8b0
[ 48.748043] device_register+0x20/0x30
[ 48.751804] init_driver_test+0x98/0x1000 [mdev_hotplug]
[ 48.757143] do_one_initcall+0x50/0x1c0
[ 48.760990] do_init_module+0x44/0x1d0
[ 48.764757] load_module+0x194c/0x1d50
[ 48.768521] __do_sys_finit_module+0xac/0x130
[ 48.772893] __arm64_sys_finit_module+0x20/0x30
[ 48.777439] invoke_syscall+0x48/0x120
[ 48.781203] el0_svc_common.constprop.0+0x44/0x100
[ 48.786008] do_el0_svc+0x30/0xd0
[ 48.789336] el0_svc+0x2c/0x90
[ 48.792408] el0t_64_sync_handler+0xbc/0x140
[ 48.796695] el0t_64_sync+0x18c/0x190
[ 48.800461] driver_test hotplug
[ 48.803709] device register error!
[ 48.838788] init module!
[ 48.841389] sysfs: cannot create duplicate filename '/bus/bus-test'
[ 48.847754] CPU: 3 PID: 326 Comm: insmod Tainted: G OE 6.0.11 #3
[ 48.855077] Hardware name: OrangePi Zero2 (DT)
[ 48.859524] Call trace:
[ 48.861974] dump_backtrace+0xd8/0x120
[ 48.865753] show_stack+0x18/0x50
[ 48.869083] dump_stack_lvl+0x68/0x84
[ 48.872760] dump_stack+0x18/0x34
[ 48.876085] sysfs_warn_dup+0x60/0x80
[ 48.879765] sysfs_create_dir_ns+0xec/0x110
[ 48.883963] kobject_add_internal+0xbc/0x3a0
[ 48.888251] kset_register+0x58/0x90
[ 48.891840] bus_register+0xc4/0x320
[ 48.895432] init_driver_test+0x2c/0x1000 [mdev_hotplug]
[ 48.900769] do_one_initcall+0x50/0x1c0
[ 48.904616] do_init_module+0x44/0x1d0
[ 48.908382] load_module+0x194c/0x1d50
[ 48.912147] __do_sys_init_module+0x20c/0x250
[ 48.916519] __arm64_sys_init_module+0x1c/0x30
[ 48.920977] invoke_syscall+0x48/0x120
[ 48.924742] el0_svc_common.constprop.0+0x44/0x100
[ 48.929546] do_el0_svc+0x30/0xd0
[ 48.932874] el0_svc+0x2c/0x90
[ 48.935946] el0t_64_sync_handler+0xbc/0x140
[ 48.940232] el0t_64_sync+0x18c/0x190
[ 48.943965] kobject_add_internal failed for bus-test with -EEXIST, don't try to register things with the same name in the same directory.
[ 48.956343] bus register error!
#
I think the code is ok, and it will create symlink in /sys/class
for /sys/devices
. But it's failed.
I looked at some source code in linux kernel, but that is all using class_create
and device_create
, I had tried it and it's ok, but the device_create
is not initializing device bus, so, the device will not match the driver.
Solution
This is a good top, the class is top level, and class is like a box which contains all device that are same kind.
Answered By - LiShanwen Answer Checked By - Marilyn (WPSolving Volunteer)