绋嬪簭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