06-打开与关闭函数
14.3.2 打开与关闭函数
当用户对tty 驱动所分配的设备节点进行open()系统调用时,tty_driver所拥有的tty_operations中的open()成员函数将被tty核心调用。tty 驱动必须设置open()成员,否则,-ENODEV将被返回给调用open()的用户。
open()成员函数的第1个参数为一个指向分配给这个设备的tty_struct结构体的指针,第2个参数为文件指针。
tty_struct结构体被tty核心用来保存当前tty端口的状态,它的大多数成员只被tty核心使用。tty_struct中的几个重要成员如下。
(1)flags标示tty设备的当前状态,包括TTY_THROTTLED、TTY_IO_ERROR、TTYOTHER CLOSED、TTY_EXCLUSIVE、TTY_DEBUG、TTY_DO_WRITE_WAKEUP、TTYPUSH、TTY CLOSING、TTY_DONT_FLIP、TTY_HW_COOK_OUT、TTY_HW_COOK_IN、TTY_PTY_LOCK、TTY_NO_WRITE_SPLIT等。
(2)ldisc为给tty设备的线路规程。
(3)write_wait、read_wait为给tty写/读函数的等待队列,tty驱动应当在合适的时机唤醒对应的等待队列。
(4)termios为指向tty设备的当前termios设置的指针。
(5)stopped:1指示是否停止tty设备,tty驱动可以设置这个值;hw_stopped:1指示是否tty设备已经被停止,tty驱动可以设置这个值;flow_stopped:1指示是否tty设备数据流停止。
(6)driver_data、disc_data为数据指针,用于存储tty驱动和线路规程的“私有”数据。
驱动中可以定义一个设备相关的结构体,并在open()函数中将其赋值给tty_struct的driver_data成员,如代码清单14.5。
代码清单14.5 在tty驱动打开函数中赋值tty.struct的driver.data成员
1 / 设备“私有”数据结构体 /
2 struct xxx_tty {
3 struct tty_struct tty; / tty_struct指针 */
4 int open_count; / 打开次数 /
5 struct semaphore sem; / 结构体锁定信号量 /
6 intxmit_buf; / 传输缓冲区 /
7 ...
8 }
9
10 / 打开函数 /
11 static int xxx_open(struct tty_struct tty, struct file file)
12 {
13 struct xxx_tty *xxx;
14
15 / 分配xxx_tty /
16 xxx = kmalloc(sizeof(*xxx), GFP_KERNEL);
17 if (!xxx)
18 return - ENOMEM;
19 / 初始化xxx_tty中的成员 /
20 init_MUTEX(&xxx->sem);
21 xxx->open_count = 0;
22 ...
23 / 让tty struct中的driver data指向 xxx_ tty /
24 tty->driver_ data = xxx;
25 xxx->tty = tty;
26 ...
27 return 0;
28 }
在用户对前面使用open()系统调用而创建的文件句柄进行close()系统调用时,tty_driver所拥有的tty_operations中的close()成员函数将被tty核心调用。