ttyUSB串口设备节点生成过程

来源:互联网 发布:微博软件加人软件 编辑:程序博客网 时间:2024/04/20 02:09
struct bus_type usb_serial_bus_type  虚拟的 usb_serial 总线struct usb_driver usb_serial_driver模块初始化函数:usb_serial_init    struct tty_driver *usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);        bus_register(&usb_serial_bus_type);             注册虚拟总线        usb_serial_tty_driver       设置tty_driver, 操作函数 serial_ops        tty_register_driver(usb_serial_tty_driver);     注册 tty_driver        usb_register(&usb_serial_driver);               注册一个USB接口驱动 usb_serial_driver        struct usb_driver option_driverstruct usb_serial_driver * const serial_driversstruct usb_serial_driver option_1port_device    option模块初始化函数module_usb_serial_driver(option_driver, serial_drivers);    usb_serial_register_drivers(option_driver, serial_drivers)        saved_id_table = option_driver->id_table;        option_driver->id_table = NULL;                   这里把id_table临时保存一下,下面注册的时候,即使有设备,也不会匹配到        usb_register(option_driver);                      注册一个USB接口驱动 option_driver 这里会将 option_driver->drvwrap.for_devices = 0; 表示这是个接口驱动                usb_serial_register(option_1port_device);                   注册一个 struct usb_serial_driver            list_add(&driver->driver_list, &usb_serial_driver_list);        这里会将 option_1port_device 添加到 usb_serial_driver_list 链表                    option_driver->id_table = saved_id_table;           再把id_table取回来        driver_attach(&option_driver->drvwrap.driver);      在USB虚拟总线匹配USB接口,如果有USB接口匹配到,会调用 option_driver 的probe函数如果一个USB设备插入,最终USB接口和接口设备匹配,那么就会匹配到 option_driver 驱动,然后执行它的probe函数:usb_serial_probe    struct usb_serial_driver *type = search_serial_device(interface);           这里在链表里找驱动,找到的是 option_1port_device    struct usb_serial *serial = create_serial(dev, interface, type);            创建一个 usb_serial serial 的type指针就指向了 option_1port_device    type->probe(serial, id);                                                    执行 option_1port_device 的probe函数 option_probe        这里注册了一个 struct usb_wwan_intf_private 结构体        读取接口的信息,设置 usb_serial    port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);                 分配对应的 usb_serial_port 结构体    serial->port[i] = port;                                                     usb_serial_port 放入 usb_serial 中    port->dev.bus = &usb_serial_bus_type;                                       port 设备注册的虚拟总线    device_add(&port->dev);                                                     向系统中加入中port,这个设备会挂在 usb_serial_bus_type 虚拟总线的设备列表,并执行匹配函数 usb_serial_device_match        usb_serial_device_match            driver = to_usb_serial_driver(drv);             这是取得drv嵌入的 struct usb_serial_driver 结构            if (driver == port->serial->type)               如果这个驱动和serial的type是一个驱动,那么匹配成功,前面看到了驱动的设置,                                                            所以这里匹配成功的是 option_1port_device 驱动,                                                            匹配成功后优先执行 usb_serial_bus_type 的probe函数 usb_serial_device_probe                    usb_serial_device_probe            port = to_usb_serial_port(dev);                 从dev找到 usb_serial_port            driver = port->serial->type;                    取得serial对应的驱动,也就是 option_1port_device            driver->port_probe(port);                       如果有 port_probe 函数,就执行,这里没有就不执行            minor = port->number;            tty_register_device(usb_serial_tty_driver, minor, dev);     注册tty设备          
再来看tty驱动的注册和设备注册usb_serial_init    struct tty_driver *usb_serial_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS);    tty_set_operations(usb_serial_tty_driver, &serial_ops);    tty_register_driver(usb_serial_tty_driver);        cdev_init(&driver->cdev, &tty_fops);        cdev_add(&driver->cdev, dev, driver->num);          注册一个字符型设备        list_add(&driver->tty_drivers, &tty_drivers);       将 usb_serial_tty_driver 驱动加入到 tty_drivers 链表        再看设备插入后 usb_serial_probe -> device_add -> usb_serial_device_probe -> tty_register_device(usb_serial_tty_driver, minor, dev) 添加设备tty_register_device(usb_serial_tty_driver, minor, dev)      这里的参数 dev 代表的是 struct usb_serial_port    dev = MKDEV(driver->major, driver->minor_start) + index;        取得设备的设备号,这里的主设备号就是 usb_serial_tty_driver 驱动的主设备号    tty_line_name(driver, index, name);            device_create(tty_class, device, dev, NULL, name);      创建设备节点如果 open 一个设备节点,首先会调用到 tty_fops 中的open函数tty_open(struct inode *inode, struct file *filp)    struct tty_driver *driver = tty_lookup_driver(device, filp, &noctty, &index);        struct tty_driver *driver = get_tty_driver(device, index);        struct tty_struct *tty = tty_init_dev(driver, index);        tty = alloc_tty_struct();        initialize_tty_struct(tty, driver, idx);            tty->driver = driver;            tty->ops = driver->ops;                         这里就得到了 usb_serial_tty_driver 驱动中的ops,也就是 tty_fops        tty_ldisc_setup(tty, tty->link);                retval = tty->ops->open(tty, filp);                     这里就执行了 tty_fops 中的open函数
0 0
原创粉丝点击