Linux Device Driver (18th)-Device Driver Model (iii) Integration

Source: Internet
Author: User

PCI device creation process

 

This part is divided into two parts for learning. One is to refer to the previous articles, analyze the source code of ld1_and sculld, and the other is to refer to ldd3 to learn PCI.

 

Part 1
Ldd_bus declares the ldd_bus_type of a bus_type structure:

Struct bus_type ldd_bus_type = {

. Name = "LDD ",

. Match = ldd_match,

. Uevent = ldd_uevent,

};

The code for adding ldd_bus_type to and detaching from the kernel is as follows:

Static int _ init ldd_bus_init (void)

{

Int ret;

Ret = bus_register (& ldd_bus_type);/* register the bus. After calling this function, ldd_bus_type
The struct will be registered with the kernel. The LDD folder appears in/sys/bus, which contains two directories: devices and drivers */

If (RET)

Return ret;

 

If (bus_create_file (& ldd_bus_type, & bus_attribute_version)/* Add the bus attribute. After adding the attribute, the version attribute file will appear in/sys/bus/LDD.

Printk (kern_notice "unable to create this attribute/N ");

 

Ret = device_register (& ldd_bus);/* registers the bus as a device, because the peripheral controllers of the processor can be considered as peripherals compared with the ARM core, after successful registration, the ldd0 directory appears in the SYS/Device directory.

If (RET)

Printk (kern_notice "unable to register LDD/N ");

Printk (kern_notice "Mount ldw. OK! /Nbus device is ldd0! /Nyou can see me in sys/module/, sys/devices/and sys/bus /!
/N ");

Return ret;

}

 

Static void ldd_bus_exit (void)

{

Device_unregister (& ldd_bus );

Bus_unregister (& ldd_bus_type );

}

 

Module_init (ldd_bus_init );

Module_exit (ldd_bus_exit );

 

The main part of the ldquo module is this, which is very simple. Because this is just a virtual bus, there is no actual driver. The module also exports the registration and logout functions required for loading bus devices and bus drivers. For the actual bus, the read and write routines of the bus should also be exported.


Place the bus device and driver registration function in the ldw.gov.cn module and export it to other bus drivers. This is because the information of the bus structure is required for registering bus devices and drivers, these registration functions are the same for all bus devices and drivers. As long as the bus driver is loaded, other bus drivers can register bus devices and drivers by calling these functions, facilitating the author of bus device drivers and reducing code redundancy.

These registration functions call driver_register, device_register, and
Driver_unregister and device_unregister functions.

 

Ii. sculld module: add the device and driver registration and logout functions based on scull.  

// ******* Add the following code in the declaration phase of the source code to add the device and driver struct *****
Struct sculld_dev * sculld_devices;/* allocated in
Scull_init_module */


/* Device Model stuff */
Static struct
Ldd_driver sculld_driver = {
. Version =
"$ Revision: 1.21-tekkamanninja $ ",
. Module =
This_module,
. Driver =
{// Embed a driver inside
. Name = "sculld ",
},
};
//************************************** ************************

************************ ********
Static ssize_t sculld_show_dev (struct Device
* Ddev,
Struct device_attribute * ATTR, char * BUF)
{
Struct sculld_dev * Dev =
Ddev-> driver_data;
Return print_dev_t (BUF, Dev-> cdev. Dev );
}

static DEVICE_ATTR(dev,
S_IRUGO, sculld_show_dev, NULL);

Static void
Sculld_register_dev (struct sculld_dev * Dev, int index)
{
Sprintf (Dev-> devname,
"Sculld % d", index );
Dev-> ldev. Name =
Dev-> devname;
Dev-> ldev. Driver =
& Sculld_driver;
Dev-> ldev. Dev. driver_data =
Dev;
Register_ldd_device (& Dev-> ldev );
If
(Device_create_file (& Dev-> ldev. Dev, & dev_attr_dev ))

Printk ("unable to create Dev attribute! /N ");
}
//************************************** ***************************

/* Add the registration and logout functions of the device and driver to the initialization functions and clearing functions of the module */
Sculld_register_dev (sculld_devices + I, I );
Register_ldd_driver (& sculld_driver );
Unregister_ldd_device (& sculld_devices [I]. ldev );
Unregister_ldd_driver (& sculld_driver );

After modification, the module can export information to the sysfs file system.

 

 

 

3. Analyze the device and driver registration and cancellation of core functions to understand the general registration and cancellation processes.

(1) Registration of devices

 

The core functions for device registration in the driver are:

int
device_register(struct device *dev)
{
    device_initialize(dev);
    return device_add(dev);
}

In the device_register function, the driver core initializes many members of the device struct and registers the kobject of the device to the kobject core.
(A hot swapping event occurs. When the device core is added or a kobject is deleted, a hot swapping event is generated.) then, the device is added to the device linked list owned by its parent node. After that, all devices can be accessed in the correct order,
And know what it is at the device level.

The device is then added to the linked list of bus-related devices (including all the devices registered with the bus. Then, the driver core traverses the linked list and calls the match function of the bus for each driver.

The match function mainly transmits the driver core to its struct device and struct.
Device_driver is converted to a specific device and driver structure. Check the specific information of the device to determine whether the driver supports the device:

If not, the function returns 0 to the driver core, so that the driver core moves to the next driver in the linked list;

If yes, the function returns 1 to the driver core so that the driver pointer in the struct device is set to point to the driver and calls
The probe function specified in device_driver.

The probe function (again) passes the driver core to its struct device and struct
Device_driver is converted to a specific device and driver struct. Then, it verifies whether the driver supports the device again, increases the reference count of the device, and then calls the probe of the bus driver.
Function:

If the bus probe function considers that it cannot process this device, a negative error value is returned to the driver core, so that the driver core moves to the next device in the linked list;

If the probe function can process the device, initialize the device and return 0 to the driver core. This will add the driver core to the device linked list bound to the specific driver, and
Drivers in the/sys/bus directory
Create a device Symbolic Link (pointing to a device in/sys/devices) in the directory, so that you can know exactly which driver is bound to which device.

(2) device CancellationThe core function for logging out of a device in the driver is:

void
device_unregister(struct device * dev)

In
In the device_unregister function, the driver core will delete the Symbolic Link (if any) of the device to the device, delete the device from its internal device list, and then
In the device structure, the struct kobject pointer is a parameter and kobject_del is called. The kobject_del function causes the hotplug of the user space.
The call indicates that kobject is now deleted from the system, and then all sysfs files and directories created and associated with this kobject are deleted. Kobject_del
The function also removes the reference of the device's own kobject. After that, all sysfs portals associated with the device are removed and the memory associated with the device is released.

(3) Registration of drivers

The core functions for registering the driver in the driver are:

int
driver_register(struct device_driver * drv)

The driver_register function initializes the struct device_driver struct (including a device linked list and its addition/deletion object function and a spin lock ),
Then call the bus_add_driver function.

Bus_add_driver:

(1) Find the bus associated with the driver: If not found, the negative error value is returned immediately;
(2) create a sysfs Driver Based on the driver name and associated bus.
Directory;
(3) obtain the internal locks of the bus, traverse all the devices registered to the bus, and call the match function for these devices,
If the binding process is successful, the binding process remains unchanged. (Similar to the registered device, do not go into details)

(4) logout of the driver

Deleting a driver is a simple process. The core function of canceling a driver in the driver is:

void
driver_unregister(struct device_driver * drv)

Deiver_unregister
The function cleans up the sysfs attributes that are connected to the driver entry in the sysfs tree to complete some basic management work. Then traverse all the devices that belong to the driver and call release for it.
Function (similar to the release function called when a device is deleted from the system ).

After all devices are detached from the driver, the following two functions are usually used in the driver:

Down (& DRV-> unload_sem );
Up (& DRV-> unload_sem );

They are completed before the function is returned to the caller. This is because before the secure return, the code needs to wait for all references to this driver to count as 0.
When a module is detached, it is usually called
The driver_unregister function is used as the exit method.
As long as the driver is referenced by the device and waits for the lock, the module needs to be kept in the memory. This allows the kernel to know when the driver can be safely deleted from the memory.

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.