Michael Chen
Michael Chen

Reputation: 1

Same device node for different devices: changing the value of one node will affect another - how to fix it?

I have one question about Linux kernel device node ,the nodes example created are in the same class with different devices but the node names are the same. If I change the value of one node, another will be changed also: How to prevent this?

Example:

echo '5' > /sys/class/myclass/mydevice/mydevice 
the value of sys/class/myclass/mydevice1/mydevice will also be changed to 5
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/fs.h>

static char mybuf[100] = "2";
static int major,major1;
static struct class *myclass;

static ssize_t mydevice_show(struct device *dev, struct device_attribute *attr,
        char *buf)
{
    return sprintf(buf, "%s\n", mybuf);
}
static ssize_t mydevice_store(struct device *dev, struct device_attribute *attr,
         const char *buf, size_t count)
{
    sprintf(mybuf, "%s", buf);

    return count;
}
static DEVICE_ATTR(mydevice, 0644, mydevice_show, mydevice_store);

static struct file_operations myfops = {
    .owner = THIS_MODULE,
};

static int __init mydevice_init(void)
{
    int ret;
    struct device *mydevice,*mydevice1;

    major = register_chrdev(0, "mydevice", &myfops);
    if (major < 0) {
        ret = major;
        return ret;
    }
    major1 = register_chrdev(0, "mydevice1", &myfops);
    if (major1 < 0) {
        ret = major1;
        return ret;
    }

    myclass = class_create(THIS_MODULE, "myclass");
    if (IS_ERR(myclass)) {
        ret = -EBUSY;
        goto fail;
    }

    mydevice = device_create(myclass, NULL, MKDEV(major, 0), NULL, "mydevice");
    if (IS_ERR(mydevice)) {
        class_destroy(myclass);
        ret = -EBUSY;
        goto fail;
    }

    mydevice1 = device_create(myclass, NULL, MKDEV(major1, 0), NULL, "mydevice1");
    if (IS_ERR(mydevice1)) {
        class_destroy(myclass);
        ret = -EBUSY;
        goto fail;
    }

    ret = sysfs_create_file(&mydevice->kobj, &dev_attr_mydevice.attr);
    ret = sysfs_create_file(&mydevice1->kobj, &dev_attr_mydevice.attr);
    if (ret < 0)
        return ret;

    return 0;

fail:
    unregister_chrdev(major, "mydevice");
    return ret;
}

static void __exit mydevice_exit(void)
{
    device_destroy(myclass, MKDEV(major, 0));
    device_destroy(myclass, MKDEV(major1, 0));
    class_destroy(myclass);
    unregister_chrdev(major, "mydevice");
    unregister_chrdev(major1, "mydevice1");
}

module_init(mydevice_init);
module_exit(mydevice_exit);

MODULE_DESCRIPTION("A simplest driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("HLY");

Upvotes: 0

Views: 377

Answers (1)

Ian Abbott
Ian Abbott

Reputation: 17403

The devices are sharing the same buffer. To fix it, use a separate buffer for each device. You could use dev_set_drvdata(device, mybuf); and dev_set_drvdata(device1, mybuf1); to set pointers to separate buffers for each device, and use dev_get_drvdata(dev) to get the pointer to the buffer for a device.

Upvotes: 1

Related Questions