LWN.net Logo

Driver core finally changing

June 21, 2006

This article was contributed by Greg Kroah-Hartman.

Back in November of last year, I wrote a list of the steps that were going to happen for the future of the kernel driver core. Finally, some of the steps that were described there have been implemented.

Making struct class_device go away

In the -mm kernel tree, there is a small patch that allows almost all users within the kernel of the struct class_device structure to convert over to use a struct device structure instead. This patch changes the struct device structure by adding the following fields:
struct device_attribute *devt_attr;
struct list_head        node;
struct class            *class;
dev_t                   devt;

The first two fields, devt_attr and node are used internally by the driver core code, and should not be touched by anything else. The other two fields class and devt are what is used by any code wishing to convert to the struct device structure.

If the field class is set by someone, before the struct device is registered, the driver core assumes that this struct device is associated with the specified struct class. This means that the device is added to the list of all devices attached to that class, and a symlink is created in the class's directory in sysfs, showing that it is present.

If the field devt is set, then a file named dev is created in the sysfs directory for the device, containing the major and minor number of the device. This is what programs like udev use in order to properly set up the /dev tree dynamically depending on what devices are present in the system.

As an example of what the sysfs changes are when these fields are set, look at the usb_device class code that has been converted to use this new interface in the latest -mm release.

The /sys/class/usb_device directory in the 2.6.17 kernel release looked something like this for most systems:

$ tree /sys/class/usb_device/
/sys/class/usb_device/
|-- usbdev1.1
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:1d.7/usb1
|   `-- uevent
|-- usbdev2.1
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:1d.0/usb2
|   `-- uevent
|-- usbdev3.1
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:1d.1/usb3
|   `-- uevent
|-- usbdev4.1
|   |-- dev
|   |-- device -> ../../../devices/pci0000:00/0000:00:1d.2/usb4
|   `-- uevent
`-- usbdev4.3
    |-- dev
    |-- device -> ../../../devices/pci0000:00/0000:00:1d.2/usb4/4-1
    `-- uevent
But now, converted over to use the struct device structure instead of struct class_device, it looks like:
/sys/class/usb_device/
|-- usbdev1.1 -> ../../../devices/pci0000:00/0000:00:1d.7/usb1/usbdev1.1
|-- usbdev2.1 -> ../../../devices/pci0000:00/0000:00:1d.0/usb2/usbdev2.1
|-- usbdev3.1 -> ../../../devices/pci0000:00/0000:00:1d.1/usb3/usbdev3.1
|-- usbdev4.1 -> ../../../devices/pci0000:00/0000:00:1d.2/usb4/usbdev4.1
`-- usbdev4.3 -> ../../../devices/pci0000:00/0000:00:1d.2/usb4/4-1/usbdev4.3
What this has accomplished is to move the USB device structure that used to be sitting out in the class directory, into the device tree itself in sysfs, providing a unified device tree, without needing to look in two different locations in sysfs to find the information.

Helper functions

In order to make the transition to converting existing kernel code to use the struct device structure instead of the struct class_device structure, two new functions have been introduced into the driver core:
struct device *device_create(struct class *cls, struct device *parent,
                             dev_t devt, char *fmt, ...)
                             __attribute__((format(printf,4,5)));
void device_destroy(struct class *cls, dev_t devt);

The function device_create, works almost identically to the existing kernel function, class_device_create. It dynamically creates a struct device structure, with all of the specified information, and registers it with the driver core and sysfs.

The other new function, device_destroy, is used to remove any struct device structures that were created with a call to device_create earlier. It is almost identical to the existing function, class_device_destroy

An example of how simple it is to convert existing code can be seen in the patch that does the conversion for the usb_device class code.

Slowly over time, all users of struct class_device will be converted over to using struct device and then, struct class_device will be removed from the kernel. And hopefully, the other tasks outlined in that original article , will also get accomplished.


(Log in to post comments)

Copyright © 2006, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds