接Linux USB 主机端 驱动程序(2.6.28)
那一节的内容,说到了调用usb_register_dev函数向usbcore层(/drivers/usb/file.c)注册了static struct usb_class_driver skel_class = {
.name = "skel%d",
.fops = &skel_fops,
.minor_base = USB_SKEL_MINOR_BASE,
}; 结构体,该结构体中定义了操作的fop类型函数指针,这些函数指针都被存到了usbcore层中的数组结构体中:
static const struct file_operations *usb_minors[MAX_USB_MINORS];
那usbcore在什么时候通过何种方式调用了上面usb_minors的函数的呢,首先:寻找file.c发现了usbcore是字符型驱动:
int usb_major_init(void)
{
int error;
error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
if (error)
printk(KERN_ERR "Unable to get major %d for usb devices\n",
USB_MAJOR);
return error;
}
通过
static const struct file_operations usb_fops = {
.owner = THIS_MODULE,
.open = usb_open,
};
找到了
static int usb_open(struct inode * inode, struct file * file)
{
int minor = iminor(inode);
const struct file_operations *c;
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
lock_kernel();
down_read(&minor_rwsem);
c = usb_minors[minor];
if (!c || !(new_fops = fops_get(c)))
goto done;
old_fops = file->f_op;
file->f_op = new_fops;
/* Curiouser and curiouser... NULL ->open() as "no device" ? */
if (file->f_op->open)
err = file->f_op->open(inode,file);
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
done:
up_read(&minor_rwsem);
unlock_kernel();
return err;
}
分析usb_open知道通过该函数实现了usbminors与具体的设备操作的skel_class中的fops关联,这样实现了对于usbcore层字符串设备的读写转换到usb-skeleton.c中的skel_read函数。
关于skel_read怎样实现,以及usb_core与之上层的关系如何,后续之