Driving Me Nuts - Device Classes

More necessary instructions for making your new device driver play nice in the 2.6 kernel.

This function looks almost like the i2c_adapter class registration code, with two exceptions. First, the class_dev.dev field is set to be either the adapter's parent device or the adapter's device. This is done because some i2c adapters do not have a real parent in the global kernel device tree, as they live on a bus that has not been converted to the kernel driver model (like ISA) or they do not really live on a bus at all (like some i2c embedded controllers). When an i2c adapter does not have a place in the kernel device tree, it is assigned to the legacy bus. The legacy bus, located at /sys/devices/legacy, is used for these kinds of devices.

The second thing that is different with this class device is the line:

class_device_create_file (&i2c_dev->class_dev, &class_device_attr_dev);

The class_device_create_file function is used to create a file in the class device's directory. The filename and attributes are defined with the CLASS_DEVICE_ATTR macro as:

static ssize_t
show_dev(struct class_device *class_dev, char *buf)
   struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
   return sprintf(buf, "%04x\n",
                  MKDEV(I2C_MAJOR, i2c_dev->minor));

The CLASS_DEVICE_ATTR macro is itself defined as:

#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
struct class_device_attribute                       \
class_device_attr_##_name = { 	                    \
    .attr  = {.name = __stringify(_name),           \
              .mode = _mode },                      \
    .show  = _show,                                 \
    .store = _store,                                \

The arguments within the CLASS_DEVICE_ATTR macro are:

  • _name: both the name of the file to be created in sysfs and part of the variable name that describes this whole attribute.

  • _mode: the file access mode with which the file is created. Use the standard access macros to specify the proper value.

  • _show: points to a function that is called when the file is read from. This function must have the following return value and parameters. This variable does not have to be set if the file is not to be read from.

    show (struct class_device *class_dev, char *buf);

  • _store: points to a function that is called when the file is written to. This function must have the following return value and paramaters. This variable does not have to be set if the file is not to be written to.

    store (struct device *dev, const char *buf,
           size_t count);

Almost all driver model structures have an ATTR() macro that declares a file within the sysfs tree.

In this example, a file named dev is created when the class_device_create_file function is called. This file is created to be read-only by any user. If the file is read from, the show_dev function is called by the driver core. The show_dev function fills in the buffer passed to it with the information it wants to give the user. In this case, the major and minor number for this specific device are passed to the user. All class devices using a major and minor number should have a dev file within their sysfs class device directory.

The class_device_remove_file function can be used to remove any files created by the class_device_create_file function. But it is not necessary to remove manually any file created if the device is about to be removed. When devices are removed from sysfs, all files created in their directories are removed automatically by the sysfs core. So, when the i2c-dev class device is removed from the system, all that is needed is the following:

static void
i2c_remove_class_device(int minor)
    struct i2c_dev *i2c_dev = NULL;
    struct list_head *tmp;
    int found = 0;

    list_for_each (tmp, &i2c_dev_list) {
        i2c_dev = list_entry(tmp, struct i2c_dev,
        if (i2c_dev->minor == minor) {
            found = 1;
    if (found) {
    } else {



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Re: Device Classes

Anonymous's picture

Cool description of sysfs, i wonder if it is possible to describe how a user-space app (kde, gnome, etc) could use it to some benefit for it

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState