i recall asking a question about something like this not that long
ago, but i'm still a bit fuzzy on what happens when you open a
character device file in terms of its "struct cdev*" member.
from <linux/fs.h>:
struct inode {
... snip ...
struct list_head i_devices;
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
};
int i_cindex;
... snip ...
};
so it's easy to see that an inode can hold at most one pointer to
one of a pipe, block dev or char dev structure. but, under normal
circumstances, when is that "i_cdev" field actually set to point to
the appropriate "struct cdev"?
from the discussion in ch 3 of LDD3, if you're writing a module that
represents a character device, you have to set up your driver by
calling, among other things, cdev_init() and cdev_add() and
associating a FOPS structure with your driver, but does any of that
actually set that i_cdev pointer in the inode?
i have to guess that it doesn't since the corresponding special
device file might not even *exist* yet, so i'm assuming that has to be
done in the chrdev_open() routine in fs/char_dev.c:
==========
/*
* Called every time a character special file is opened
*/
static int chrdev_open(struct inode *inode, struct file *filp)
{
struct cdev *p;
struct cdev *new = NULL;
int ret = 0;
spin_lock(&cdev_lock);
p = inode->i_cdev;
if (!p) {
struct kobject *kobj;
int idx;
spin_unlock(&cdev_lock);
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
inode->i_cindex = idx;
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
ret = -ENXIO;
} else if (!cdev_get(p))
...
==========
unless something weird is happening underneath, i'm concluding that,
the *very first time* you try to open that special device file, the
code recognizes that i_cdev has no value, and has to invoke
kobj_lookup() to track down the corresponding kobject in the
system-wide cdev_map, from which you extract the cdev and fill in
inode->i_cdev.
of course, after that's done *once*, it shouldn't have to be done
again as long as that device file and inode exist, is this correct?
rday
--
========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
Have classroom, will lecture.
http://crashcourse.ca Waterloo, Ontario, CANADA
========================================================================
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ