Reason to pass data using struct inode and struct file in Linux device driver programming

I'm a frog dragon picture I'm a frog dragon · Sep 9, 2011 · Viewed 8.6k times · Source

I'm studying Chapter 3.5 of Linux Device Drivers, 3rd edition. This section introduces a method to retrieve a custom structure we defined ourselves from struct inode *inode in the open function:

int scull_open(struct inode *inode, struct file *filp)
{
    struct scull_dev *dev;

    dev = container_of(inode->i_cdev, struct scull_dev, cdev);
    filp->private_data = dev; /* for other methods */

    }
    return 0;          
}

From my understanding, while the device is opened, the struct inode *inode representing the device is passed to scull_open. Then, the custom structure dev is extracted and passed to filp->private_data so that other methods such as scull_read can use it:

ssize_t scull_read(struct file *filp, char _ _user *buf, size_t count,
                loff_t *f_pos)
{
    struct scull_dev *dev = filp->private_data; 
    /* other codes that uses *dev   */
}

This seems fine to me until I realized that we already had a struct scull_dev *dev during initialization in scull_setup_cdev here.

I'm rather confused since I thought we can make struct scull_dev *dev a global variable, then scull_read and other methods will eventually have access to it without going through all the passing using inode and file.

My question is, why don't we just make it a global variable?

Can anyone provide some practical examples of using this method to pass data ?

Answer

rodrigo picture rodrigo · Dec 28, 2013

The main reason is so that your driver can manage more than one device. For example, you can create (mknod) several devices /dev/scull1, /dev/scull2, /dev/scull3... and then each of these will have a different scull_dev associated with it.

With a global variable you are limited to one. And even if your driver only supports one such device, there is little reason not to design the code future proof.