绋嬪簭10-6 linux/kernel/chr_drv/tty_ioctl.c
1 /*
2 * linux/kernel/chr_drv/tty_ioctl.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7 #include <errno.h> // 閿欒鍙峰ご鏂囦欢銆傚寘鍚郴缁熶腑鍚勭鍑洪敊鍙枫€�
8 #include <termios.h> // 缁堢杈撳叆杈撳嚭鍑芥暟澶存枃浠躲€備富瑕佸畾涔夋帶鍒跺紓姝ラ€氫俊鍙g殑缁堢鎺ュ彛銆�
9
10 #include <linux/sched.h> // 璋冨害绋嬪簭澶存枃浠讹紝瀹氫箟浠诲姟缁撴瀯task_struct銆佷换鍔�0鐨勬暟鎹瓑銆�
11 #include <linux/kernel.h> // 鍐呮牳澶存枃浠躲€傚惈鏈変竴浜涘唴鏍稿父鐢ㄥ嚱鏁扮殑鍘熷舰瀹氫箟銆�
12 #include <linux/tty.h> // tty澶存枃浠讹紝瀹氫箟鏈夊叧tty_io銆佷覆琛岄€氫俊鏂归潰鍙傛暟銆佸父鏁般€�
13
14 #include <asm/io.h> // io澶存枃浠躲€傚畾涔夌‖浠剁鍙h緭鍏�/杈撳嚭瀹忔眹缂栬鍙ャ€�
15 #include <asm/segment.h> // 娈垫搷浣滃ご鏂囦欢銆傚畾涔変簡鏈夊叧娈靛瘎瀛樺櫒鎿嶄綔鐨勫祵鍏ュ紡姹囩紪鍑芥暟銆�
16 #include <asm/system.h> // 绯荤粺澶存枃浠躲€傚畾涔夎缃垨淇敼鎻忚堪绗�/涓柇闂ㄧ瓑鐨勫祵鍏ュ紡姹囩紪瀹忋€�
17
// 鏍规嵁杩涚▼缁勫彿pgrp鍙栧緱杩涚▼缁勬墍灞炵殑浼氳瘽鍙枫€傚畾涔夊湪kernel/exit.c锛�161琛屻€�
18 extern int session_of_pgrp(int pgrp);
// 鍚戜娇鐢ㄦ寚瀹�tty缁堢鐨勮繘绋嬬粍涓墍鏈夎繘绋嬪彂閫佷俊鍙枫€傚畾涔夊湪chr_drv/tty_io.c锛�246琛屻€�
19 extern int tty_signal(int sig, struct tty_struct *tty);
20
// 杩欐槸娉㈢壒鐜囧洜瀛愭暟缁勶紙鎴栫О涓洪櫎鏁版暟缁勶級銆傛尝鐗圭巼涓庢尝鐗圭巼鍥犲瓙鐨勫搴斿叧绯诲弬瑙佸垪琛ㄥ悗璇存槑銆�
// 渚嬪娉㈢壒鐜囨槸2400bps鏃讹紝瀵瑰簲鐨勫洜瀛愭槸48锛�0x30锛夛紱9600bps鐨勫洜瀛愭槸12锛�0x1c锛夈€�
21 static unsigned short quotient[] = {
22 0, 2304, 1536, 1047, 857,
23 768, 576, 384, 192, 96,
24 64, 48, 24, 12, 6, 3
25 };
26
//// 淇敼浼犺緭娉㈢壒鐜囥€�
// 鍙傛暟锛�tty - 缁堢瀵瑰簲鐨�tty鏁版嵁缁撴瀯銆�
// 鍦ㄩ櫎鏁伴攣瀛樻爣蹇�DLAB缃綅鎯呭喌涓嬶紝閫氳繃绔彛0x3f8鍜�0x3f9鍚�UART鍒嗗埆鍐欏叆娉㈢壒鐜囧洜瀛愪綆
// 瀛楄妭鍜岄珮瀛楄妭銆傚啓瀹屽悗鍐嶅浣�DLAB浣嶃€傚浜庝覆鍙�2锛岃繖涓や釜绔彛鍒嗗埆鏄�0x2f8鍜�0x2f9銆�
27 static void change_speed(struct tty_struct * tty)
28 {
29 unsigned short port,quot;
30
// 鍑芥暟棣栧厛妫€鏌ュ弬鏁�tty 鎸囧畾鐨勭粓绔槸鍚︽槸涓茶缁堢锛岃嫢涓嶆槸鍒欓€€鍑恒€傚浜庝覆鍙g粓绔殑tty缁�
// 鏋勶紝鍏惰缂撳啿闃熷垪data 瀛楁瀛樻斁鐫€涓茶绔彛鍩哄潃锛�0x3f8鎴�0x2f8锛夛紝鑰屼竴鑸帶鍒跺彴缁堢鐨�
// tty缁撴瀯鐨�read_q.data瀛楁鍊间负0銆傜劧鍚庝粠缁堢termios缁撴瀯鐨勬帶鍒舵ā寮忔爣蹇楅泦涓彇寰楀凡璁�
// 缃殑娉㈢壒鐜囩储寮曞彿锛屽苟鎹浠庢尝鐗圭巼鍥犲瓙鏁扮粍quotient[]涓彇寰楀搴旂殑娉㈢壒鐜囧洜瀛愬€�quot銆�
// CBAUD鏄帶鍒舵ā寮忔爣蹇楅泦涓尝鐗圭巼浣嶅睆钄界爜銆�
31 if (!(port = tty->read_q->data))
32 return;
33 quot = quotient[tty->termios.c_cflag & CBAUD];
// 鎺ョ潃鎶婃尝鐗圭巼鍥犲瓙quot鍐欏叆涓茶绔彛瀵瑰簲UART鑺墖鐨勬尝鐗圭巼鍥犲瓙閿佸瓨鍣ㄤ腑銆傚湪鍐欎箣鍓嶆垜浠�
// 鍏堣鎶婄嚎璺帶鍒跺瘎瀛樺櫒 LCR 鐨勯櫎鏁伴攣瀛樿闂瘮鐗逛綅DLAB锛堜綅7锛夌疆1銆傜劧鍚庢妸 16浣嶇殑娉㈢壒
// 鐜囧洜瀛愪綆楂樺瓧鑺傚垎鍒啓鍏ョ鍙� 0x3f8銆�0x3f9 锛堝垎鍒搴旀尝鐗圭巼鍥犲瓙浣庛€侀珮瀛楄妭閿佸瓨鍣級銆�
// 鏈€鍚庡啀澶嶄綅LCR鐨�DLAB鏍囧織浣嶃€�
34 cli();
35 outb_p(0x80,port+3); /* set DLAB */ // 棣栧厛璁剧疆闄ゆ暟閿佸畾鏍囧織DLAB銆�
36 outb_p(quot & 0xff,port); /* LS of divisor */ // 杈撳嚭鍥犲瓙浣庡瓧鑺傘€�
37 outb_p(quot >> 8,port+1); /* MS of divisor */ // 杈撳嚭鍥犲瓙楂樺瓧鑺傘€�
38 outb(0x03,port+3); /* reset DLAB */ // 澶嶄綅DLAB銆�
39 sti();
40 }
41
//// 鍒锋柊tty缂撳啿闃熷垪銆�
// 鍙傛暟锛�queue - 鎸囧畾鐨勭紦鍐查槦鍒楁寚閽堛€�
// 浠ょ紦鍐查槦鍒楃殑澶存寚閽堢瓑浜庡熬鎸囬拡锛屼粠鑰岃揪鍒版竻绌虹紦鍐插尯鐨勭洰鐨勩€�
42 static void flush(struct tty_queue * queue)
43 {
44 cli();
45 queue->head = queue->tail;
46 sti();
47 }
48
//// 绛夊緟瀛楃鍙戦€佸嚭鍘汇€�
49 static void wait_until_sent(struct tty_struct * tty)
50 {
51 /* do nothing - not implemented */ /* 浠€涔堥兘娌″仛 - 杩樻湭瀹炵幇 */
52 }
53
//// 鍙戦€�BREAK鎺у埗绗︺€�
54 static void send_break(struct tty_struct * tty)
55 {
56 /* do nothing - not implemented */ /* 浠€涔堥兘娌″仛 - 杩樻湭瀹炵幇 */
57 }
58
//// 鍙栫粓绔�termios缁撴瀯淇℃伅銆�
// 鍙傛暟锛�tty - 鎸囧畾缁堢鐨�tty缁撴瀯鎸囬拡锛�termios - 瀛樻斁termios缁撴瀯鐨勭敤鎴风紦鍐插尯銆�
59 static int get_termios(struct tty_struct * tty, struct termios * termios)
60 {
61 int i;
62
// 棣栧厛楠岃瘉鐢ㄦ埛缂撳啿鍖烘寚閽堟墍鎸囧唴瀛樺尯瀹归噺鏄惁瓒冲锛屽涓嶅鍒欏垎閰嶅唴瀛樸€傜劧鍚庡鍒舵寚瀹氱粓绔�
// 鐨�termios缁撴瀯淇℃伅鍒扮敤鎴风紦鍐插尯涓€傛渶鍚庤繑鍥�0銆�
63 verify_area(termios, sizeof (*termios)); // kernel/fork.c锛�24琛屻€�
64 for (i=0 ; i< (sizeof (*termios)) ; i++)
65 put_fs_byte( ((char *)&tty->termios)[i] , i+(char *)termios );
66 return 0;
67 }
68
//// 璁剧疆缁堢termios缁撴瀯淇℃伅銆�
// 鍙傛暟锛�tty - 鎸囧畾缁堢鐨�tty缁撴瀯鎸囬拡锛�termios - 鐢ㄦ埛鏁版嵁鍖�termios缁撴瀯鎸囬拡銆�
69 static int set_termios(struct tty_struct * tty, struct termios * termios,
70 int channel)
71 {
72 int i, retsig;
73
74 /* If we try to set the state of terminal and we're not in the
75 foreground, send a SIGTTOU. If the signal is blocked or
76 ignored, go ahead and perform the operation. POSIX 7.2) */
/* 濡傛灉璇曞浘璁剧疆缁堢鐨勭姸鎬佷絾姝ゆ椂缁堢涓嶅湪鍓嶅彴锛岄偅涔堟垜浠氨闇€瑕佸彂閫�
涓€涓�SIGTTOU淇″彿銆傚鏋滆淇″彿琚繘绋嬪睆钄芥垨鑰呭拷鐣ヤ簡锛屽氨鐩存帴鎵ц
鏈鎿嶄綔銆� POSIX 7.2 */
// 濡傛灉褰撳墠杩涚▼浣跨敤鐨�tty缁堢鐨勮繘绋嬬粍鍙蜂笌杩涚▼鐨勮繘绋嬬粍鍙蜂笉鍚岋紝鍗冲綋鍓嶈繘绋嬬粓绔笉鍦ㄥ墠鍙帮紝
// 琛ㄧず褰撳墠杩涚▼璇曞浘淇敼涓嶅彈鎺у埗鐨勭粓绔殑termios缁撴瀯銆傚洜姝ゆ牴鎹�POSIX鏍囧噯鐨勮姹傝繖閲岄渶
// 瑕佸彂閫�SIGTTOU淇″彿璁╀娇鐢ㄨ繖涓粓绔殑杩涚▼鍏堟殏鏃跺仠姝㈡墽琛岋紝浠ヨ鎴戜滑鍏堜慨鏀�termios缁撴瀯銆�
// 濡傛灉鍙戦€佷俊鍙峰嚱鏁�tty_signal()杩斿洖鍊兼槸ERESTARTSYS鎴�EINTR锛屽垯绛変竴浼氬啀鎵ц鏈鎿嶄綔銆�
77 if ((current->tty == channel) && (tty->pgrp != current->pgrp)) {
78 retsig = tty_signal(SIGTTOU, tty); // chr_drv/tty_io.c锛�246琛屻€�
79 if (retsig == -ERESTARTSYS || retsig == -EINTR)
80 return retsig;
81 }
// 鎺ョ潃鎶婄敤鎴锋暟鎹尯涓�termios缁撴瀯淇℃伅澶嶅埗鍒版寚瀹氱粓绔�tty缁撴瀯鐨�termios缁撴瀯涓€傚洜涓虹敤
// 鎴锋湁鍙兘宸蹭慨鏀逛簡缁堢涓茶鍙d紶杈撴尝鐗圭巼锛屾墍浠ヨ繖閲屽啀鏍规嵁termios缁撴瀯涓殑鎺у埗妯″紡鏍囧織
// c_cflag涓殑娉㈢壒鐜囦俊鎭慨鏀逛覆琛�UART鑺墖鍐呯殑浼犺緭娉㈢壒鐜囥€傛渶鍚庤繑鍥�0銆�
82 for (i=0 ; i< (sizeof (*termios)) ; i++)
83 ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios);
84 change_speed(tty);
85 return 0;
86 }
87
//// 璇诲彇termio缁撴瀯涓殑淇℃伅銆�
// 鍙傛暟锛�tty - 鎸囧畾缁堢鐨�tty缁撴瀯鎸囬拡锛�termio - 淇濆瓨termio缁撴瀯淇℃伅鐨勭敤鎴风紦鍐插尯銆�
88 static int get_termio(struct tty_struct * tty, struct termio * termio)
89 {
90 int i;
91 struct termio tmp_termio;
92
// 棣栧厛楠岃瘉鐢ㄦ埛鐨勭紦鍐插尯鎸囬拡鎵€鎸囧唴瀛樺尯瀹归噺鏄惁瓒冲锛屽涓嶅鍒欏垎閰嶅唴瀛樸€傜劧鍚庡皢termios
// 缁撴瀯鐨勪俊鎭鍒跺埌涓存椂 termio 缁撴瀯涓€傝繖涓や釜缁撴瀯鍩烘湰鐩稿悓锛屼絾杈撳叆銆佽緭鍑恒€佹帶鍒跺拰鏈湴
// 鏍囧織闆嗘暟鎹被鍨嬩笉鍚屻€傚墠鑰呯殑鏄�long锛岃€屽悗鑰呯殑鏄�short銆傚洜姝ゅ厛澶嶅埗鍒颁复鏃�termio缁撴瀯
// 涓洰鐨勬槸涓轰簡杩涜鏁版嵁绫诲瀷杞崲銆�
93 verify_area(termio, sizeof (*termio));
94 tmp_termio.c_iflag = tty->termios.c_iflag;
95 tmp_termio.c_oflag = tty->termios.c_oflag;
96 tmp_termio.c_cflag = tty->termios.c_cflag;
97 tmp_termio.c_lflag = tty->termios.c_lflag;
98 tmp_termio.c_line = tty->termios.c_line;
99 for(i=0 ; i < NCC ; i++)
100 tmp_termio.c_cc[i] = tty->termios.c_cc[i];
// 鏈€鍚庨€愬瓧鑺傚湴鎶婁复鏃�termio缁撴瀯涓殑淇℃伅澶嶅埗鍒扮敤鎴�termio缁撴瀯缂撳啿鍖轰腑銆傚苟杩斿洖0銆�
101 for (i=0 ; i< (sizeof (*termio)) ; i++)
102 put_fs_byte( ((char *)&tmp_termio)[i] , i+(char *)termio );
103 return 0;
104 }
105
106 /*
107 * This only works as the 386 is low-byt-first
108 */
/*
* 涓嬮潰termio璁剧疆鍑芥暟浠呴€傜敤浜庝綆瀛楄妭鍦ㄥ墠鐨�386 CPU銆�
*/
//// 璁剧疆缁堢termio缁撴瀯淇℃伅銆�
// 鍙傛暟锛�tty - 鎸囧畾缁堢鐨�tty缁撴瀯鎸囬拡锛�termio - 鐢ㄦ埛鏁版嵁鍖轰腑termio缁撴瀯銆�
// 灏嗙敤鎴风紦鍐插尯termio鐨勪俊鎭鍒跺埌缁堢鐨�termios缁撴瀯涓€傝繑鍥�0 銆�
109 static int set_termio(struct tty_struct * tty, struct termio * termio,
110 int channel)
111 {
112 int i, retsig;
113 struct termio tmp_termio;
114
// 涓�set_termios()涓€鏍凤紝濡傛灉杩涚▼浣跨敤鐨勭粓绔殑杩涚▼缁勫彿涓庤繘绋嬬殑杩涚▼缁勫彿涓嶅悓锛屽嵆褰撳墠杩�
// 绋嬬粓绔笉鍦ㄥ墠鍙帮紝琛ㄧず褰撳墠杩涚▼璇曞浘淇敼涓嶅彈鎺у埗鐨勭粓绔殑termios缁撴瀯銆傚洜姝ゆ牴鎹�POSIX
// 鏍囧噯鐨勮姹傝繖閲岄渶瑕佸彂閫�SIGTTOU淇″彿璁╀娇鐢ㄨ繖涓粓绔殑杩涚▼鍏堟殏鏃跺仠姝㈡墽琛岋紝浠ヨ鎴戜滑鍏�
// 淇敼termios缁撴瀯銆傚鏋滃彂閫佷俊鍙峰嚱鏁�tty_signal()杩斿洖鍊兼槸ERESTARTSYS鎴�EINTR锛屽垯绛�
// 涓€浼氬啀鎵ц鏈鎿嶄綔銆�
115 if ((current->tty == channel) && (tty->pgrp != current->pgrp)) {
116 retsig = tty_signal(SIGTTOU, tty);
117 if (retsig == -ERESTARTSYS || retsig == -EINTR)
118 return retsig;
119 }
// 鎺ョ潃澶嶅埗鐢ㄦ埛鏁版嵁鍖轰腑termio缁撴瀯淇℃伅鍒颁复鏃�termio缁撴瀯涓€傜劧鍚庡啀灏�termio缁撴瀯鐨勪俊鎭�
// 澶嶅埗鍒�tty鐨� termios 缁撴瀯涓€傝繖鏍峰仛鐨勭洰鐨勬槸涓轰簡瀵瑰叾涓ā寮忔爣蹇楅泦鐨勭被鍨嬭繘琛岃浆鎹紝鍗�
// 浠� termio鐨勭煭鏁存暟绫诲瀷杞崲鎴�termios鐨勯暱鏁存暟绫诲瀷銆備絾涓ょ缁撴瀯鐨�c_line鍜�c_cc[]瀛楁
// 鏄畬鍏ㄧ浉鍚岀殑銆�
120 for (i=0 ; i< (sizeof (*termio)) ; i++)
121 ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio);
122 *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag;
123 *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag;
124 *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag;
125 *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag;
126 tty->termios.c_line = tmp_termio.c_line;
127 for(i=0 ; i < NCC ; i++)
128 tty->termios.c_cc[i] = tmp_termio.c_cc[i];
// 鏈€鍚庡洜涓虹敤鎴锋湁鍙兘宸蹭慨鏀逛簡缁堢涓茶鍙d紶杈撴尝鐗圭巼锛屾墍浠ヨ繖閲屽啀鏍规嵁termios缁撴瀯涓殑鎺у埗
// 妯″紡鏍囧織c_cflag涓殑娉㈢壒鐜囦俊鎭慨鏀逛覆琛�UART鑺墖鍐呯殑浼犺緭娉㈢壒鐜囷紝骞惰繑鍥�0銆�
129 change_speed(tty);
130 return 0;
131 }
132
//// tty缁堢璁惧杈撳叆杈撳嚭鎺у埗鍑芥暟銆�
// 鍙傛暟锛�dev - 璁惧鍙凤紱cmd - ioctl鍛戒护锛�arg - 鎿嶄綔鍙傛暟鎸囬拡銆�
// 璇ュ嚱鏁伴鍏堟牴鎹弬鏁扮粰鍑虹殑璁惧鍙锋壘鍑哄搴旂粓绔殑tty缁撴瀯锛岀劧鍚庢牴鎹帶鍒跺懡浠�cmd鍒嗗埆杩涜
// 澶勭悊銆�
133 int tty_ioctl(int dev, int cmd, int arg)
134 {
135 struct tty_struct * tty;
136 int pgrp;
137
// 棣栧厛鏍规嵁璁惧鍙峰彇寰�tty瀛愯澶囧彿锛屼粠鑰屽彇寰楃粓绔殑tty缁撴瀯銆傝嫢涓昏澶囧彿鏄�5锛堟帶鍒剁粓绔級锛�
// 鍒欒繘绋嬬殑tty瀛楁鍗虫槸tty瀛愯澶囧彿銆傛鏃跺鏋滆繘绋嬬殑tty瀛愯澶囧彿鏄礋鏁帮紝琛ㄦ槑璇ヨ繘绋嬫病鏈�
// 鎺у埗缁堢锛屽嵆涓嶈兘鍙戝嚭璇�ioctl璋冪敤锛屼簬鏄樉绀哄嚭閿欎俊鎭苟鍋滄満銆傚鏋滀富璁惧鍙蜂笉鏄�5鑰屾槸4锛�
// 鎴戜滑灏卞彲浠ヤ粠璁惧鍙蜂腑鍙栧嚭瀛愯澶囧彿銆傚瓙璁惧鍙峰彲浠ユ槸0锛堟帶鍒跺彴缁堢锛夈€�1锛堜覆鍙�1缁堢锛夈€�
// 2锛堜覆鍙�2缁堢锛夈€�
138 if (MAJOR(dev) == 5) {
139 dev=current->tty;
140 if (dev<0)
141 panic("tty_ioctl: dev<0");
142 } else
143 dev=MINOR(dev);
// 鐒跺悗鏍规嵁瀛愯澶囧彿鍜�tty琛紝鎴戜滑鍙彇寰楀搴旂粓绔殑tty缁撴瀯銆備簬鏄tty鎸囧悜瀵瑰簲瀛愯澶�
// 鍙风殑tty缁撴瀯銆傜劧鍚庡啀鏍规嵁鍙傛暟鎻愪緵鐨�ioctl鍛戒护cmd杩涜鍒嗗埆澶勭悊銆�144琛屽悗鍗婇儴鍒嗙敤浜�
// 鏍规嵁瀛愯澶囧彿dev鍦�tty_table[]琛ㄤ腑閫夋嫨瀵瑰簲鐨�tty缁撴瀯銆傚鏋�dev = 0锛岃〃绀烘鍦ㄤ娇鐢�
// 鍓嶅彴缁堢锛屽洜姝ょ洿鎺ヤ娇鐢ㄧ粓绔彿fg_console 浣滀负 tty_table[] 椤圭储寮曞彇 tty缁撴瀯銆傚鏋�
// dev澶т簬0锛岄偅涔堝氨瑕佸垎涓ょ鎯呭喌鑰冭檻锛氣憼 dev 鏄櫄鎷熺粓绔彿锛涒憽 dev 鏄覆琛岀粓绔彿鎴栬€�
// 浼粓绔彿銆傚浜庤櫄鎷熺粓绔叾tty缁撴瀯鍦� tty_table[]涓储寮曢」鏄� dev-1锛�0 -- 63锛夈€傚浜�
// 鍏跺畠绫诲瀷缁堢锛屽垯瀹冧滑鐨� tty缁撴瀯绱㈠紩椤瑰氨鏄� dev銆備緥濡傦紝濡傛灉dev = 64锛岃〃绀烘槸涓€涓覆
// 琛岀粓绔�1锛屽垯鍏�tty 缁撴瀯灏辨槸 ttb_table[dev]銆� 濡傛灉dev = 1锛屽垯瀵瑰簲缁堢鐨�tty缁撴瀯鏄�
// tty_table[0]銆傚弬瑙�tty_io.c绋嬪簭绗�70 -- 73琛屻€�
144 tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console);
145 switch (cmd) {
// 鍙栫浉搴旂粓绔�termios缁撴瀯淇℃伅銆傛鏃跺弬鏁�arg鏄敤鎴风紦鍐插尯鎸囬拡銆�
146 case TCGETS:
147 return get_termios(tty,(struct termios *) arg);
// 鍦ㄨ缃�termios缁撴瀯淇℃伅涔嬪墠锛岄渶瑕佸厛绛夊緟杈撳嚭闃熷垪涓墍鏈夋暟鎹鐞嗗畬姣曪紝骞朵笖鍒锋柊锛堟竻绌猴級
// 杈撳叆闃熷垪銆傚啀鎺ョ潃鎵ц涓嬮潰璁剧疆缁堢termios缁撴瀯鐨勬搷浣溿€�
148 case TCSETSF:
149 flush(tty->read_q); /* fallthrough */ /* 鎺ョ潃缁х画鎵ц */
// 鍦ㄨ缃粓绔�termios鐨勪俊鎭箣鍓嶏紝闇€瑕佸厛绛夊緟杈撳嚭闃熷垪涓墍鏈夋暟鎹鐞嗗畬锛堣€楀敖锛夈€傚浜庝慨鏀�
// 鍙傛暟浼氬奖鍝嶈緭鍑虹殑鎯呭喌锛屽氨闇€瑕佷娇鐢ㄨ繖绉嶅舰寮忋€�
150 case TCSETSW:
151 wait_until_sent(tty); /* fallthrough */
// 璁剧疆鐩稿簲缁堢termios缁撴瀯淇℃伅銆傛鏃跺弬鏁�arg鏄繚瀛�termios缁撴瀯鐨勭敤鎴风紦鍐插尯鎸囬拡銆�
152 case TCSETS:
153 return set_termios(tty,(struct termios *) arg, dev);
// 鍙栫浉搴旂粓绔�termio缁撴瀯涓殑淇℃伅銆傛鏃跺弬鏁�arg鏄敤鎴风紦鍐插尯鎸囬拡銆�
154 case TCGETA:
155 return get_termio(tty,(struct termio *) arg);
// 鍦ㄨ缃�termio 缁撴瀯淇℃伅涔嬪墠锛岄渶瑕佸厛绛夊緟杈撳嚭闃熷垪涓墍鏈夋暟鎹鐞嗗畬姣曪紝骞朵笖鍒锋柊锛堟竻绌猴級
// 杈撳叆闃熷垪銆傚啀鎺ョ潃鎵ц涓嬮潰璁剧疆缁堢termio 缁撴瀯鐨勬搷浣溿€�
156 case TCSETAF:
157 flush(tty->read_q); /* fallthrough */ /* 鎺ョ潃缁х画鎵ц */
// 鍦ㄨ缃粓绔�termios鐨勪俊鎭箣鍓嶏紝闇€瑕佸厛绛夊緟杈撳嚭闃熷垪涓墍鏈夋暟鎹鐞嗗畬锛堣€楀敖锛夈€傚浜庝慨鏀�
// 鍙傛暟浼氬奖鍝嶈緭鍑虹殑鎯呭喌锛屽氨闇€瑕佷娇鐢ㄨ繖绉嶅舰寮忋€�
158 case TCSETAW:
159 wait_until_sent(tty); /* fallthrough */
// 璁剧疆鐩稿簲缁堢termio缁撴瀯淇℃伅銆傛鏃跺弬鏁�arg鏄繚瀛�termio缁撴瀯鐨勭敤鎴风紦鍐插尯鎸囬拡銆�
160 case TCSETA:
161 return set_termio(tty,(struct termio *) arg, dev);
// 濡傛灉鍙傛暟arg鍊兼槸0锛屽垯绛夊緟杈撳嚭闃熷垪澶勭悊瀹屾瘯锛堢┖锛夛紝骞跺彂閫佷竴涓�break銆�
162 case TCSBRK:
163 if (!arg) {
164 wait_until_sent(tty);
165 send_break(tty);
166 }
167 return 0;
// 寮€濮�/鍋滄娴佹帶鍒躲€傚鏋滃弬鏁�arg鏄�TCOOFF锛�Terminal Control Output OFF锛夛紝鍒欐寕璧疯緭鍑猴紱
// 濡傛灉鏄� TCOON锛屽垯鎭㈠鎸傝捣鐨勮緭鍑恒€傚湪鎸傝捣鎴栨仮澶嶈緭鍑哄悓鏃堕渶瑕佹妸鍐欓槦鍒椾腑鐨勫瓧绗﹁緭鍑猴紝浠�
// 鍔犲揩鐢ㄦ埛浜や簰鍝嶅簲閫熷害銆傚鏋�arg鏄�TCIOFF锛�Terminal Control Input ON锛夛紝鍒欐寕璧疯緭鍏ワ紱
// 濡傛灉鏄�TCION锛屽垯閲嶆柊寮€鍚寕璧风殑杈撳叆銆�
168 case TCXONC:
169 switch (arg) {
170 case TCOOFF:
171 tty->stopped = 1; // 鍋滄缁堢杈撳嚭銆�
172 tty->write(tty); // 鍐欑紦鍐查槦鍒楄緭鍑恒€�
173 return 0;
174 case TCOON:
175 tty->stopped = 0; // 鎭㈠缁堢杈撳嚭銆�
176 tty->write(tty);
177 return 0;
// 濡傛灉鍙傛暟arg鏄�TCIOFF锛岃〃绀鸿姹傜粓绔仠姝㈣緭鍏ワ紝浜庢槸鎴戜滑寰€缁堢鍐欓槦鍒椾腑鏀惧叆STOP瀛楃銆�
// 褰撶粓绔敹鍒拌瀛楃鏃跺氨浼氭殏鍋滆緭鍏ャ€傚鏋滃弬鏁版槸TCION锛岃〃绀鸿鍙戦€佷竴涓�START瀛楃锛岃缁�
// 绔仮澶嶄紶杈撱€�
// STOP_CHAR(tty)瀹氫箟涓� ((tty)->termios.c_cc[VSTOP])锛屽嵆鍙栫粓绔�termios缁撴瀯鎺у埗瀛楃鏁�
// 缁勫搴旈」鍊笺€傝嫢鍐呮牳瀹氫箟浜�_POSIX_VDISABLE锛�\0锛夛紝閭d箞褰撴煇涓€椤瑰€肩瓑浜�_POSIX_VDISABLE
// 鐨勫€兼椂锛岃〃绀虹姝娇鐢ㄧ浉搴旂殑鐗规畩瀛楃銆傚洜姝よ繖閲岀洿鎺ュ垽鏂鍊兼槸鍚︿负0 鏉ョ‘瀹氳涓嶈鎶婂仠
// 姝㈡帶鍒跺瓧绗︽斁鍏ョ粓绔啓闃熷垪涓€備互涓嬪悓銆�
178 case TCIOFF:
179 if (STOP_CHAR(tty))
180 PUTCH(STOP_CHAR(tty),tty->write_q);
181 return 0;
182 case TCION:
183 if (START_CHAR(tty))
184 PUTCH(START_CHAR(tty),tty->write_q);
185 return 0;
186 }
187 return -EINVAL; /* not implemented */
// 鍒锋柊宸插啓杈撳嚭浣嗚繕娌℃湁鍙戦€併€佹垨宸叉敹浣嗚繕娌℃湁璇荤殑鏁版嵁銆傚鏋滃弬鏁�arg鏄�0锛屽垯鍒锋柊锛堟竻绌猴級
// 杈撳叆闃熷垪锛涘鏋滄槸1锛屽垯鍒锋柊杈撳嚭闃熷垪锛涘鏋滄槸2锛屽垯鍒锋柊杈撳叆鍜岃緭鍑洪槦鍒椼€�
188 case TCFLSH:
189 if (arg==0)
190 flush(tty->read_q);
191 else if (arg==1)
192 flush(tty->write_q);
193 else if (arg==2) {
194 flush(tty->read_q);
195 flush(tty->write_q);
196 } else
197 return -EINVAL;
198 return 0;
// 璁剧疆缁堢涓茶绾胯矾涓撶敤妯″紡銆�
199 case TIOCEXCL:
200 return -EINVAL; /* not implemented */ /* 鏈疄鐜� */
// 澶嶄綅缁堢涓茶绾胯矾涓撶敤妯″紡銆�
201 case TIOCNXCL:
202 return -EINVAL; /* not implemented */
// 璁剧疆tty涓烘帶鍒剁粓绔€傦紙TIOCNOTTY - 涓嶈鎺у埗缁堢锛夈€�
203 case TIOCSCTTY:
204 return -EINVAL; /* set controlling term NI */ /* 鏈疄鐜� */
// 璇诲彇缁堢杩涚▼缁勫彿锛堝嵆璇诲彇鍓嶅彴杩涚▼缁勫彿锛夈€� 棣栧厛楠岃瘉鐢ㄦ埛缂撳啿鍖洪暱搴︼紝鐒跺悗澶嶅埗缁堢tty
// 鐨�pgrp瀛楁鍒扮敤鎴风紦鍐插尯銆傛鏃跺弬鏁�arg鏄敤鎴风紦鍐插尯鎸囬拡銆�
205 case TIOCGPGRP: // 瀹炵幇搴撳嚱鏁�tcgetpgrp()銆�
206 verify_area((void *) arg,4);
207 put_fs_long(tty->pgrp,(unsigned long *) arg);
208 return 0;
// 璁剧疆缁堢杩涚▼缁勫彿pgrp锛堝嵆璁剧疆鍓嶅彴杩涚▼缁勫彿锛夈€� 姝ゆ椂鍙傛暟arg 鏄敤鎴风紦鍐插尯涓繘绋嬬粍鍙�
// pgrp 鐨勬寚閽堛€傛墽琛岃鍛戒护鐨勫墠鎻愭潯浠舵槸杩涚▼蹇呴』鏈夋帶鍒剁粓绔€� 濡傛灉褰撳墠杩涚▼娌℃湁鎺у埗缁堢锛�
// 鎴栬€�dev 涓嶆槸鍏舵帶鍒剁粓绔紝鎴栬€呮帶鍒剁粓绔幇鍦ㄧ殑纭槸姝e湪澶勭悊鐨勭粓绔�dev锛屼絾杩涚▼鐨勪細璇濆彿
// 涓庤缁堢dev鐨勪細璇濆彿涓嶅悓锛屽垯杩斿洖鏃犵粓绔敊璇俊鎭€�
209 case TIOCSPGRP: // 瀹炵幇搴撳嚱鏁�tcsetpgrp()銆�
210 if ((current->tty < 0) ||
211 (current->tty != dev) ||
212 (tty->session != current->session))
213 return -ENOTTY;
// 鐒跺悗鎴戜滑灏变粠鐢ㄦ埛缂撳啿鍖轰腑鍙栧緱娆茶缃殑杩涚▼缁勫彿锛屽苟瀵硅缁勫彿鐨勬湁鏁堟€ц繘琛岄獙璇併€傚鏋滅粍
// 鍙�pgrp灏忎簬0锛屽垯杩斿洖鏃犳晥缁勫彿閿欒淇℃伅锛涘鏋� pgrp鐨勪細璇濆彿涓庡綋鍓嶈繘绋嬬殑涓嶅悓锛屽垯杩斿洖
// 璁稿彲閿欒淇℃伅銆傚惁鍒欐垜浠彲浠ヨ涓粓绔殑杩涚▼缁勫彿涓�prgp銆傛鏃�prgp鎴愪负鍓嶅彴杩涚▼缁勩€�
214 pgrp=get_fs_long((unsigned long *) arg);
215 if (pgrp < 0)
216 return -EINVAL;
217 if (session_of_pgrp(pgrp) != current->session)
218 return -EPERM;
219 tty->pgrp = pgrp;
220 return 0;
// 杩斿洖杈撳嚭闃熷垪涓繕鏈€佸嚭鐨勫瓧绗︽暟銆傞鍏堥獙璇佺敤鎴风紦鍐插尯闀垮害锛岀劧鍚庡鍒堕槦鍒椾腑瀛楃鏁扮粰鐢ㄦ埛銆�
// 姝ゆ椂鍙傛暟arg鏄敤鎴风紦鍐插尯鎸囬拡銆�
221 case TIOCOUTQ:
222 verify_area((void *) arg,4);
223 put_fs_long(CHARS(tty->write_q),(unsigned long *) arg);
224 return 0;
// 杩斿洖杈撳叆闃熷垪涓繕鏈鍙栫殑瀛楃鏁般€傞鍏堥獙璇佺敤鎴风紦鍐插尯闀垮害锛岀劧鍚庡鍒堕槦鍒椾腑瀛楃鏁扮粰鐢ㄦ埛銆�
// 姝ゆ椂鍙傛暟arg鏄敤鎴风紦鍐插尯鎸囬拡銆�
225 case TIOCINQ:
226 verify_area((void *) arg,4);
227 put_fs_long(CHARS(tty->secondary),
228 (unsigned long *) arg);
229 return 0;
// 妯℃嫙缁堢杈撳叆鎿嶄綔銆傝鍛戒护浠ヤ竴涓寚鍚戝瓧绗︾殑鎸囬拡浣滀负鍙傛暟锛屽苟鍋囪璇ュ瓧绗︽槸鍦ㄧ粓绔笂閿叆鐨勩€�
// 鐢ㄦ埛蹇呴』鍦ㄨ鎺у埗缁堢涓婂叿鏈夎秴绾х敤鎴锋潈闄愭垨鍏锋湁璇昏鍙潈闄愩€�
230 case TIOCSTI:
231 return -EINVAL; /* not implemented */ /* 鏈疄鐜� */
// 璇诲彇缁堢璁惧绐楀彛澶у皬淇℃伅锛堝弬瑙�termios.h涓殑winsize缁撴瀯锛夈€�
232 case TIOCGWINSZ:
233 return -EINVAL; /* not implemented */
// 璁剧疆缁堢璁惧绐楀彛澶у皬淇℃伅锛堝弬瑙�winsize缁撴瀯锛夈€�
234 case TIOCSWINSZ:
235 return -EINVAL; /* not implemented */
// 杩斿洖MODEM鐘舵€佹帶鍒跺紩绾跨殑褰撳墠鐘舵€佹瘮鐗逛綅鏍囧織闆嗭紙鍙傝termios.h涓�185 -- 196琛岋級銆�
236 case TIOCMGET:
237 return -EINVAL; /* not implemented */
// 璁剧疆鍗曚釜modem鐘舵€佹帶鍒跺紩绾跨殑鐘舵€侊紙true鎴�false锛夈€�
238 case TIOCMBIS:
239 return -EINVAL; /* not implemented */
// 澶嶄綅鍗曚釜MODEM鐘舵€佹帶鍒跺紩绾跨殑鐘舵€併€�
240 case TIOCMBIC:
241 return -EINVAL; /* not implemented */
// 璁剧疆MODEM鐘舵€佸紩绾跨殑鐘舵€併€傚鏋滄煇涓€姣旂壒浣嶇疆浣嶏紝鍒�modem瀵瑰簲鐨勭姸鎬佸紩绾垮皢缃负鏈夋晥銆�
242 case TIOCMSET:
243 return -EINVAL; /* not implemented */
// 璇诲彇杞欢杞芥尝妫€娴嬫爣蹇楋紙1 - 寮€鍚紱0 - 鍏抽棴锛夈€�
244 case TIOCGSOFTCAR:
245 return -EINVAL; /* not implemented */
// 璁剧疆杞欢杞芥尝妫€娴嬫爣蹇楋紙1 - 寮€鍚紱0 - 鍏抽棴锛夈€�
246 case TIOCSSOFTCAR:
247 return -EINVAL; /* not implemented */
248 default:
249 return -EINVAL;
250 }
251 }
252