This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/z2007b/archive/2011/05/19/6432997.aspx
//************************************** ***************
Linux Kernel Lecture Hall (1) cornerstone Driver Model for device drivers (6)
In the previous section, we roughly analyzed how driver_register works. Some details are not in place, but remember one sentence. The first thing we need to build is the first impression of the driver model in our minds. This section describes the creation of the last two protagonists, device and class. After talking about this, a big collection will come. Let the Four Kings (device, class, device_driver, bus) join the stage to pay tribute to you, performance? Want the Four Kings to perform? No problem, but the Four Kings are not only distinguished. The most important thing is that all of them are versatile. To fully understand the skills of the Four Kings, you must not rush to appreciate them in the same way.
Well, let's forget the Four Kings first. First, let's take a look at our beauty device and the Demon class. Sorry to say wrong. The class is actually used to describe the common characteristics of the beauty of the device. This is an example of your favorite and easiest to understand.
You are right, that is to say, you, the guy reading this article, I know that you like Shu Hongqi, Which is sexy and well-formed. Don't admit it. But my taste is different from yours. I like the pure fairy sister like Liu Yifei. Now there are two camps. The sexiness School and the pure school are represented by Shu Qi, Zhong liti, Xiao zemary, and cangjingkong. Representatives of the pure school include Liu Yifei, A Jiao (if you do not admit it, it is not counted), Gao Yuanyuan, and Yang Ming. You and I all know that beauty can be divided into camps. Why does the author of Linux kernel not understand classification? If you still don't understand the benefits of classification, I can only say: Dude, you're too simple!
OK. I will explain that there are two directories under/sys/class:
/Sys/class/sexual beauty,/sys/class/pure beauty
Are you looking for Shu Qi? Search for the/sys/class/sexual beauty.
Are you looking for Liu Yifei? Search for the/sys/class/pure beauty.
Do you understand? Class is mainly used for classification. The devices in the same category have common attributes.
Some comrades said, What should I do if I have a special hobby like the demon? You can create a one-person Demon class and then drop it in.
How to create it? What can I create? Don't worry, brother will teach you immediately.
There are two functions:
Class_register () and device_register (). However, we have always explained how to pick an important function in the previous introduction, not to say that this function is the only function, in the Linux kernel, many functions such as create_class are provided to encapsulate them.
# Define class_register (class )/
({/
Static struct lock_class_key _ key ;/
_ Class_register (class, & __key );/
})
Int _ class_register (struct class * CLs, struct lock_class_key * key)
{
Struct subsys_private * CP;
Int error;
Pr_debug ("device class '% s': Registering/N", CLS-> name );
CP = kzarloc (sizeof (* CP), gfp_kernel );
If (! CP)
Return-enomem;
Klist_init (& CP-> klist_devices, klist_class_dev_get, klist_class_dev_put );
Init_list_head (& CP-> class_interfaces );
Kset_init (& CP-> glue_dirs );
_ Mutex_init (& CP-> class_mutex, "struct class mutex", key );
Error = kobject_set_name (& CP-> subsys. kobj, "% s", CLS-> name );
If (error ){
Kfree (CP );
Return Error;
}
/* Set the default/sys/dev directory for devices of this class */
If (! CLS-> dev_kobj)
CLS-> dev_kobj = sysfs_dev_char_kobj;
# If defined (config_block)
/* Let the block class directory show up in the root of sysfs */
If (! Sysfs_deprecated | CLS! = & Block_class)
CP-> subsys. kobj. kset = class_kset;
# Else
CP-> subsys. kobj. kset = class_kset;
# Endif
CP-> subsys. kobj. ktype = & class_ktype;
CP-> class = CLS;
CLS-> P = CP;
Error = kset_register (& CP-> subsys );
If (error ){
Kfree (CP );
Return Error;
}
Error = add_class_attrs (class_get (CLS ));
Class_put (CLS );
Return Error;
}
It's so easy that I don't want to analyze it anymore. With a responsible attitude towards Comrade Cai cainiao, I 'd like to talk about several key variable initialization points.
If (! CLS-> dev_kobj)
CLS-> dev_kobj = sysfs_dev_char_kobj;
# If defined (config_block)
/* Let the block class directory show up in the root of sysfs */
If (! Sysfs_deprecated | CLS! = & Block_class)
CP-> subsys. kobj. kset = class_kset;
# Else
CP-> subsys. kobj. kset = class_kset;
# Endif
CP-> subsys. kobj. ktype = & class_ktype;
All the right values in this heap except class_ktype are called in driver_init () of/Drivers/base/init. C to initialize and register them.
Next let's take a look at device_register (). If you understand bus_register () and driver_register (). This should not be a big problem. First, define the function:
Int device_register (struct device * Dev)
{
Device_initialize (Dev );
Return device_add (Dev );
}
It is too similar to driver_register. The function name reflects its function properly. Initialize Dev first. And then add it to our family.
Void device_initialize (struct device * Dev)
{
Dev-> kobj. kset = devices_kset;
Kobject_init (& Dev-> kobj, & device_ktype );
Init_list_head (& Dev-> dma_pools );
Mutex_init (& Dev-> mutex );
Lockdep_set_novalidate_class (& Dev-> mutex );
Spin_lock_init (& Dev-> devres_lock );
Init_list_head (& Dev-> devres_head );
Device_pm_init (Dev );
Set_dev_node (Dev,-1 );
}
Int device_add (struct device * Dev)
{
Struct device * parent = NULL;
Struct class_interface * class_intf;
Int error =-einval;
Dev = get_device (Dev );
If (! Dev)
Goto done;
If (! Dev-> P ){
Error = device_private_init (Dev );
If (error)
Goto done;
}
/*
* For statically allocated devices, which shoshould all be converted
* Some day, we need to initialize the name. We prevent reading back
* The name, and force the use of dev_name ()
*/
If (Dev-> init_name ){
Dev_set_name (Dev, "% s", Dev-> init_name );
Dev-> init_name = NULL;
}
If (! Dev_name (Dev )){
Error =-einval;
Goto name_error;
}
Pr_debug ("device: '% s': % s/n", dev_name (Dev), _ FUNC __);
Parent = get_device (Dev-> parent );
Setup_parent (Dev, parent );
/* Use parent numa_node */
If (parent)
Set_dev_node (Dev, dev_to_node (parent ));
/* First, register with generic layer .*/
/* We require the name to be set before, and pass null */
Error = kobject_add (& Dev-> kobj, Dev-> kobj. Parent, null );
If (error)
Goto error;
/* Policy platform of device entry */
If (platform_policy)
Platform_policy (Dev );
Error = device_create_file (Dev, & uevent_attr );
If (error)
Goto attrerror;
If (Major (Dev-> devt )){
Error = device_create_file (Dev, & devt_attr );
If (error)
Goto ueventattrerror;
Error = device_create_sys_dev_entry (Dev );
If (error)
Goto devtattrerror;
Devtmpfs_create_node (Dev );
}
Error = device_add_class_symlinks (Dev );
If (error)
Goto symlinkerror;
Error = device_add_attrs (Dev );
If (error)
Goto attrserror;
Error = bus_add_device (Dev );
If (error)
Goto buserror;
Error = dpm_sysfs_add (Dev );
If (error)
Goto dpmerror;
Device_pm_add (Dev );
/* Sort y clients of device addition. This call must come
* After dpm_sysf_add () and before kobject_uevent ().
*/
If (Dev-> Bus)
Blocking_notifier_call_chain (& Dev-> bus-> P-> bus_notifier,
Bus_policy_add_device, Dev );
Kobject_uevent (& Dev-> kobj, kobj_add );
Bus_probe_device (Dev );
If (parent)
Klist_add_tail (& Dev-> P-> knode_parent,
& Parent-> P-> klist_children );
If (Dev-> class ){
Mutex_lock (& Dev-> class-> P-> class_mutex );
/* Tie the class to the device */
Klist_add_tail (& Dev-> knode_class,
& Dev-> class-> P-> klist_devices );
/* Define y any interfaces that the device is here */
List_for_each_entry (class_intf,
& Dev-> class-> P-> class_interfaces, node)
If (class_intf-> add_dev)
Class_intf-> add_dev (Dev, class_intf );
Mutex_unlock (& Dev-> class-> P-> class_mutex );
}
Done:
Put_device (Dev );
Return Error;
Dpmerror:
Bus_remove_device (Dev );
Buserror:
Device_remove_attrs (Dev );
Attrserror:
Device_remove_class_symlinks (Dev );
Symlinkerror:
If (Major (Dev-> devt ))
Devtmpfs_delete_node (Dev );
If (Major (Dev-> devt ))
Device_remove_sys_dev_entry (Dev );
Devtattrerror:
If (Major (Dev-> devt ))
Device_remove_file (Dev, & devt_attr );
Ueventattrerror:
Device_remove_file (Dev, & uevent_attr );
Attrerror:
Kobject_uevent (& Dev-> kobj, kobj_remove );
Kobject_del (& Dev-> kobj );
Error:
Cleanup_device_parent (Dev );
If (parent)
Put_device (parent );
Name_error:
Kfree (Dev-> P );
Dev-> P = NULL;
Goto done;
}
The function itself cannot find anything to talk about.
However, when registering a device, a device cannot directly belong to a class or a bus. Too winding, instance:
Struct device dev;
Dev. Class = xx;
Dev. Bus = YY;
Device_register (& Dev );
This is not the case. This will lead to repeated creation during the creation of the subsystem link, resulting in registration failure. In fact, we can solve this problem. Create a parent-class device that belongs to a class, point the parent of the child-class device to the address of the parent-class device, and then point the bus of the Child-class device to the address of my bus. This will solve the problem. The next section is the debut of the Four Kings Qi dengtai. Pai_^