===============================
This article is the original site, welcome to reprint!
Reprint please indicate the source: http://www.cnblogs.com/gdt-a20
===============================
The kernel developer will be the bus, device, drive the three are abstracted from the software idea, cleverly established the relationship between the two, make it more visualization. Combined with the knowledge that we have learned before, in general, the relationship between the three of the bus has two linked list, used to hook equipment and drive, specified its own bus device or driver the final will be connected to the corresponding buses of the two linked list, and the line has its beginning, for Bus_kset, A driver can correspond to several devices, so the driver also has a list of equipment linked to the operation of the device, its own also has a bus hanging contact, used to hook itself to the corresponding buses (each driver only belong to one line), and for device, A device only belongs to a bus, can only have a driver and its corresponding, so for device, are single, a driver hang point, a bus hanging point, device and buses are the same is all have the beginning, device for Devices_kset, Therefore, the registration of device will also appear in the corresponding bus directory and the device total directory. OK, the following is the source code for example analysis of bus,device,driver registration process.
First, the registration of bus
Bus registration is relatively simple, first look at the structure of the bus:
1 struct Bus_type {2 const char *name; Name 3 struct Bus_attribute *bus_attrs; Bus property Set 4 struct Device_attribute *dev_attrs; Device property Set 5 struct Driver_attribute *drv_attrs;
Driver Property Set 6 int (*match) (struct device *dev, struct device_driver);
7 int (*uevent) (struct device *dev, struct kobj_uevent_env);
8 int (*probe) (struct device *dev);
9 int (*remove) (struct device *dev);
Ten void (*shutdown) (struct device *dev);
one int (*suspend) (struct device *dev, pm_message_t State);
Int (*resume) (struct device *dev);
const struct DEV_PM_OPS *pm; struct Bus_type_private *p;
Private member of the bus 15}; 16//One of the key to see private member structure: struct bus_type_private {struct Kset subsys;
Bus embedded Kset, on behalf of its own struct kset *drivers_kset;
struct Kset *devices_kset; struct Klist klist_devices; Contains devices chain list and its operation function struct klist klist_drivers;
Driver chain list and its operation function are struct blocking_notifier_head bus_notifier; unsigned int drivers_autoprobe:1;
The match succeeds automatically initializes the sign struct bus_type *bus; 26};
Whether it is bus,driver, or device its own characteristics are placed in private members, its registration, will apply for and populate the structure, the following specific analysis of the registration process bus, starting from the Bus_register:
1 int bus_register (struct bus_type *bus) 2 {3 int retval;
4 struct bus_type_private *priv; 5 Priv = kzalloc (sizeof (struct bus_type_private), gfp_kernel); Bus_type->bus_type_private is null 6 if (!PRIV)//The function is mainly on its
Set 7 Return-enomem; 8 Priv->bus = bus; Private member's bus return refers to the bus 9 bus->p = priv;
Initializes the bus->p, which is the private property of Blocking_init_notifier_head (&priv->bus_notifier); One retval = Kobject_set_name (&priv->subsys.kobj, "%s", bus->name);
The name of the bus is set, the bus is Kset package if (retval) goto out; //bus_kset is initialized for the total starting endpoint of all bus 15//around the bus embedded kset, and Kset is initialized around 16 Priv->subsys.kobj.kset = Bus_kset; Kobj similar, no parent, you will use Kset kobj, here is Priv->subsys.kobj.ktype = &bus_ktype; The attribute operation level is unified to bus_ktype priv->drivers_autoprobe = 1; Set this flag, when there is a driver registration, automatically match the devices 19///device and initialize with probe, 20//When the device registration is also found driver and will initialize retval = Kset_register (&am P;priv->subsys);
Registers the Kset, creates the directory structure, and the hierarchical relations if (retval) goto out; retval = Bus_create_file (bus, &bus_attr_uevent);
The current bus directory generates Bus_attr_uevent property file (retval) goto bus_uevent_fail; Priv->devices_kset = Kset_create_and_add ("Devices", NULL,///Initialize the devices directory under the bus directory, which cascaded the bus under the equipment, 28 &priv->subsys.kobj);
Still take Kset as prototype (!priv->devices_kset) {retval =-enomem; goto bus_devices_fail; 32} Priv->drivers_kset = Kset_create_and_add ("Drivers", NULL,///Initialize the drivers directory under the bus directory, which cascaded the driver of the equipment under the bus 34
&priv->subsys.kobj); if (!priv->drivers_kSet) {retval =-enomem; Bus_drivers_fail to Klist_init (&priv->klist_devic ES, Klist_devices_get, klist_devices_put); Initialize the operation function member of Klist_devices klist_init (&priv->klist_drivers, NULL, NULL); The operation function of klist_drivers the empty retval = Add_probe_files (bus); Add Bus_attr_drivers_probe and Bus_attr_drivers_autoprobe if (retval)
The property file is goto Bus_probe_files_fail; retval = Bus_add_attrs (bus);
Add default Property file (retval) to Goto Bus_attrs_fail;
Pr_debug ("Bus: '%s ': registered/n", bus->name);
0;
Bus_attrs_fail://Below is error handling remove_probe_files (bus);
Wuyi bus_probe_files_fail:52 Kset_unregister (bus->p->drivers_kset); Bus_drivers_fail: Kset_unregister (Bus->p->devices_kset);
bus_devices_fail:56 bus_remove_file (bus, &bus_attr_uevent);
bus_uevent_fail:58 Kset_unregister (&bus->p->subsys);
Out:60 Kfree (bus->p);
Bus->p = NULL;
The return retval; 63}
This shows that the bus is Kset encapsulation, Bus_register mainly completed its private member Bus_type_private initialization, and initialization of its two directories under the devices and drivers, and its property files, Bus has its own root directory is the bus has a starting point, is Bus_kset, after this registration, the bus directory will appear in our registered bus, and it will have device and driver two subdirectories, representing its driver and device list below.
II. Registration of Driver
Now look at how driver is associated with the bus, first look at the structure of the driver:
1 struct Device_driver {
2 const char *name; Name
3 struct bus_type *bus; It is located in the bus
4 struct module *owner;
5 const char *mod_name; /* Used for built-in modules * *
6 bool suppress_bind_attrs; /*