tty_ioctl.c ( File view )

  • By 2010-08-31
  • View(s):24
  • Download(s):2
  • Point(s): 1
			/*
* linux/kernel/chr_drv/tty_ioctl.c
*
* (C) 1991 Linus Torvalds
*/

#include <errno.h>		// 错误号头文件。包含系统中各种出错号。(Linus 从minix 中引进的)。
#include <termios.h>		// 终端输入输出函数头文件。主要定义控制异步通信口的终端接口。

#include <linux/sched.h>	// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,
// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。
#include <linux/kernel.h>	// 内核头文件。含有一些内核常用函数的原形定义。
#include <linux/tty.h>		// tty 头文件,定义了有关tty_io,串行通信方面的参数、常数。

#include <asm/io.h>		// io 头文件。定义硬件端口输入/输出宏汇编语句。
#include <asm/segment.h>	// 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。
#include <asm/system.h>		// 系统头文件。定义了设置或修改描述符/中断门等的嵌入式汇编宏。

// 这是波特率因子数组(或称为除数数组)。波特率与波特率因子的对应关系参见列表后的说明。
static unsigned short quotient[] = {

  0, 2304, 1536, 1047, 857,
  768, 576, 384, 192, 96,
  64, 48, 24, 12, 6, 3

};

//// 修改传输速率。
// 参数:tty - 终端对应的tty 数据结构。
// 在除数锁存标志DLAB(线路控制寄存器位7)置位情况下,通过端口0x3f8 和0x3f9 向UART 分别写入
// 波特率因子低字节和高字节。
static void
change_speed (struct tty_struct *tty)
{

  unsigned short port, quot;

// 对于串口终端,其tty 结构的读缓冲队列data 字段存放的是串行端口号(0x3f8 或0x2f8)。
  if (!(port = tty->read_q.data))
    return;
// 从tty 的termios 结构控制模式标志集中取得设置的波特率索引号,据此从波特率因子数组中取得
// 对应的波特率因子值。CBAUD 是控制模式标志集中波特率位屏蔽码。
  quot = quotient[tty->termios.c_cflag & CBAUD];
  cli ();			// 关中断。
  outb_p (0x80, port + 3);	/* set DLAB */// 首先设置除数锁定标志DLAB。
  outb_p (quot & 0xff, port);	/* LS of divisor */// 输出因子低字节。
  outb_p (quot >> 8, port + 1);	/* MS of divisor */// 输出因子高字节。
  outb (0x03, port + 3);	/* reset DLAB */// 复位DLAB。
  sti ();			// 开中断。

}

//// 刷新tty 缓冲队列。
// 参数:gueue - 指定的缓冲队列指针。
// 令缓冲队列的头指针等于尾指针,从而达到清空缓冲区(零字符)的目的。
static void
flush (struct tty_queue *queue)
{

  cli ();
  queue->head = queue->tail;
  sti ();

}

//// 等待字符发送出去。
static void
wait_until_sent (struct tty_struct *tty)
{

/* do nothing - not implemented *//* 什么都没做 - 还未实现 */

}

//// 发送BREAK 控制符。
static void
send_break (struct tty_struct *tty)
{

/* do nothing - not implemented *//* 什么都没做 - 还未实现 */

}

//// 取终端termios 结构信息。
// 参数:tty - 指定终端的tty 结构指针;termios - 用户数据区termios 结构缓冲区指针。
// 返回0 。
static int
get_termios (struct tty_struct *tty, struct termios *termios)
{

  int i;

// 首先验证一下用户的缓冲区指针所指内存区是否足够,如不够则分配内存。
  verify_area (termios, sizeof (*termios));
// 复制指定tty 结构中的termios 结构信息到用户 termios 结构缓冲区。
  for (i = 0; i < (sizeof (*termios)); i++)
    put_fs_byte (((char *) &tty->termios)[i], i + (char *) termios);
  return 0;

}

//// 设置终端termios 结构信息。
// 参数:tty - 指定终端的tty 结构指针;termios - 用户数据区termios 结构指针。
// 返回0 。
static int
set_termios (struct tty_struct *tty, struct termios *termios)
{

  int i;

// 首先复制用户数据区中termios 结构信息到指定tty 结构中。
  for (i = 0; i < (sizeof (*termios)); i++)
    ((char *) &tty->termios)[i] = get_fs_byte (i + (char *) termios);
// 用户有可能已修改了tty 的串行口传输波特率,所以根据termios 结构中的控制模式标志c_cflag
// 修改串行芯片UART 的传输波特率。
  change_speed (tty);
  return 0;

}

//// 读取termio 结构中的信息。
// 参数:tty - 指定终端的tty 结构指针;termio - 用户数据区termio 结构缓冲区指针。
// 返回0。
static int
get_termio (struct tty_struct *tty, struct termio *termio)
{

  int i;
  struct termio tmp_termio;

// 首先验证一下用户的缓冲区指针所指内存区是否足够,如不够则分配内存。
  verify_area (termio, sizeof (*termio));
// 将termios 结构的信息复制到termio 结构中。目的是为了其中模式标志集的类型进行转换,也即
// 从termios 的长整数类型转换为termio 的短整数类型。
  tmp_termio.c_iflag = tty->termios.c_iflag;
  tmp_termio.c_oflag = tty->termios.c_oflag;
  tmp_termio.c_cflag = tty->termios.c_cflag;
  tmp_termio.c_lflag = tty->termios.c_lflag;
// 两种结构的c_line 和c_cc[]字段是完全相同的。
  tmp_termio.c_line = tty->termios.c_line;
  for (i = 0; i < NCC; i++)
    tmp_termio.c_cc[i] = tty->termios.c_cc[i];
// 最后复制指定tty 结构中的termio 结构信息到用户 termio 结构缓冲区。
  for (i = 0; i < (sizeof (*termio)); i++)
    put_fs_byte (((char *) &tmp_termio)[i], i + (char *) termio);
  return 0;

}

/*
* This only works as the 386 is low-byt-first
*/
/*
* 下面的termio 设置函数仅在386 低字节在前的方式下可用。
*/
//// 设置终端termio 结构信息。
// 参数:tty - 指定终端的tty 结构指针;termio - 用户数据区termio 结构指针。
// 将用户缓冲区termio 的信息复制到终端的termios 结构中。返回0 。
static int
set_termio (struct tty_struct *tty, struct termio *termio)
{

  int i;
  struct termio tmp_termio;

// 首先复制用户数据区中termio 结构信息到临时termio 结构中。
  for (i = 0; i < (sizeof (*termio)); i++)
    ((char *) &tmp_termio)[i] = get_fs_byte (i + (char *) termio);
// 再将termio 结构的信息复制到tty 的termios 结构中。目的是为了其中模式标志集的类型进行转换,
// 也即从termio 的短整数类型转换成termios 的长整数类型。
  *(unsigned short *) &tty->termios.c_iflag = tmp_termio.c_iflag;
  *(unsigned short *) &tty->termios.c_oflag = tmp_termio.c_oflag;
  *(unsigned short *) &tty->termios.c_cflag = tmp_termio.c_cflag;
  *(unsigned short *) &tty->termios.c_lflag = tmp_termio.c_lflag;
// 两种结构的c_line 和c_cc[]字段是完全相同的。
  tty->termios.c_line = tmp_termio.c_line;
  for (i = 0; i < NCC; i++)
    tty->termios.c_cc[i] = tmp_termio.c_cc[i];
// 用户可能已修改了tty 的串行口传输波特率,所以根据termios 结构中的控制模式标志集c_cflag
// 修改串行芯片UART 的传输波特率。
  change_speed (tty);
  return 0;

}

//// tty 终端设备的ioctl 函数。
// 参数:dev - 设备号;cmd - ioctl 命令;arg - 操作参数指针。
int
tty_ioctl (int dev, int cmd, int arg)
{

  struct tty_struct *tty;
// 首先取tty 的子设备号。如果主设备号是5(tty 终端),则进程的tty 字段即是子设备号;如果进程
// 的tty 子设备号是负数,表明该进程没有控制终端,也即不能发出该ioctl 调用,出错死机。
  if (MAJOR (dev) == 5)
    {

      dev = current->tty;
      if (dev < 0)
	panic ("tty_ioctl: dev<0");
// 否则直接从设备号中取出子设备号。
    
}
  else
    dev = MINOR (dev);
// 子设备号可以是0(控制台终端)、1(串口1 终端)、2(串口2 终端)。
// 让tty 指向对应子设备号的tty 结构。
  tty = dev + tty_table;
// 根据tty 的ioctl 命令进行分别处理。
  switch (cmd)
    {

    case TCGETS:
//取相应终端termios 结构中的信息。
      return get_termios (tty, (struct termios *) arg);
    case TCSETSF:
// 在设置termios 的信息之前,需要先等待输出队列中所有数据处理完,并且刷新(清空)输入队列。
// 再设置。
      flush (&tty->read_q);	/* fallthrough */
    case TCSETSW:
// 在设置终端termios 的信息之前,需要先等待输出队列中所有数据处理完(耗尽)。对于修改参数
// 会影响输出的情况,就需要使用这种形式。
      wait_until_sent (tty);	/* fallthrough */
    case TCSETS:
// 设置相应终端termios 结构中的信息。
      return set_termios (tty, (struct termios *) arg);
    case TCGETA:
// 取相应终端termio 结构中的信息。
      return get_termio (tty, (struct termio *) arg);
    case TCSETAF:
// 在设置termio 的信息之前,需要先等待输出队列中所有数据处理完,并且刷新(清空)输入队列。
// 再设置。
      flush (&tty->read_q);	/* fallthrough */
    case TCSETAW:
// 在设置终端termio 的信息之前,需要先等待输出队列中所有数据处理完(耗尽)。对于修改参数
// 会影响输出的情况,就需要使用这种形式。
      wait_until_sent (tty);	/* fallthrough *//* 继续执行 */
    case TCSETA:
// 设置相应终端termio 结构中的信息。
      return set_termio (tty, (struct termio *) arg);
    case TCSBRK:
// 等待输出队列处理完毕(空),如果参数值是0,则发送一个break。
      if (!arg)
	{

	  wait_until_sent (tty);
	  send_break (tty);
	
}
      return 0;
    case TCXONC:
// 开始/停止控制。如果参数值是0,则挂起输出;如果是1,则重新开启挂起的输出;如果是2,则挂起
// 输入;如果是3,则重新开启挂起的输入。
      return -EINVAL;		/* not implemented *//* 未实现 */
    case TCFLSH:
//刷新已写输出但还没发送或已收但还没有读数据。如果参数是0,则刷新(清空)输入队列;如果是1,
// 则刷新输出队列;如果是2,则刷新输入和输出队列。
      if (arg == 0)
	flush (&tty->read_q);
      else if (arg == 1)
	flush (&tty->write_q);
      else if (arg == 2)
	{

	  flush (&tty->read_q);
	  flush (&tty->write_q);
	
}
      else
	return -EINVAL;
      return 0;
    case TIOCEXCL:
// 设置终端串行线路专用模式。
      return -EINVAL;		/* not implemented *//* 未实现 */
    case TIOC
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
linux0.00 B0% 04-10-07
<boot>0.00 B04-10-07 15:01
bootsect.s12.49 kB08-01-04 21:38
head.s13.22 kB08-01-04 21:38
setup.s12.42 kB08-01-04 21:38
<fs>0.00 B04-10-07 15:01
bitmap.c8.46 kB02-09-04 13:12
block_dev.c3.95 kB02-09-04 13:12
buffer.c17.71 kB02-09-04 13:12
char_dev.c4.09 kB02-09-04 13:12
exec.c18.90 kB02-09-04 13:12
fcntl.c3.33 kB02-09-04 13:12
file_dev.c4.82 kB02-09-04 13:12
file_table.c209.00 B02-09-04 13:12
inode.c14.92 kB02-09-04 13:12
ioctl.c1.94 kB02-09-04 13:12
Makefile6.80 kB08-01-04 21:45
namei.c37.20 kB02-09-04 13:12
open.c10.00 kB02-09-04 13:12
pipe.c5.42 kB02-09-04 13:12
read_write.c5.86 kB02-09-04 13:12
stat.c2.69 kB02-09-04 13:12
super.c13.57 kB02-09-04 13:12
truncate.c2.46 kB02-09-04 13:12
<include>0.00 B04-10-07 15:01
a.out.h8.22 kB02-09-04 13:14
<asm>0.00 B04-10-07 15:01
io.h772.00 B02-09-04 13:14
memory.h1.03 kB08-01-04 22:13
segment.h2.50 kB02-09-04 13:14
system.h4.08 kB02-09-04 13:14
const.h589.00 B02-09-04 13:14
ctype.h1.68 kB02-09-04 13:14
errno.h2.30 kB02-09-04 13:14
fcntl.h3.30 kB02-09-04 13:14
<linux>0.00 B04-10-07 15:01
config.h2.16 kB02-09-04 13:14
fs.h9.72 kB02-09-04 13:14
hdreg.h2.94 kB02-09-04 13:14
head.h760.00 B02-09-04 13:14
kernel.h1.44 kB02-09-04 13:14
mm.h473.00 B02-09-04 13:14
sched.h13.25 kB02-09-04 13:14
sys.h5.41 kB02-09-04 13:14
tty.h3.93 kB02-09-04 13:14
signal.h4.01 kB02-09-04 13:14
stdarg.h1.77 kB02-09-04 13:14
stddef.h378.00 B02-09-04 13:14
string.h21.75 kB02-09-04 13:14
<sys>0.00 B04-10-07 15:01
stat.h2.37 kB02-09-04 13:14
times.h377.00 B02-09-04 13:14
types.h1.10 kB02-09-04 13:14
utsname.h423.00 B02-09-04 13:14
wait.h1.48 kB02-09-04 13:14
termios.h13.58 kB02-09-04 13:14
time.h1.81 kB02-09-04 13:14
unistd.h9.21 kB02-09-04 13:14
utime.h392.00 B02-09-04 13:14
<init>0.00 B04-10-07 15:01
main.c12.52 kB02-09-04 13:12
<kernel>0.00 B04-10-07 15:01
asm.s5.10 kB08-01-04 22:48
<blk_drv>0.00 B04-10-07 15:01
blk.h5.69 kB02-09-04 13:14
floppy.c23.49 kB02-09-04 13:12
hd.c17.14 kB02-09-04 13:12
ll_rw_blk.c7.59 kB02-09-04 13:12
Makefile4.25 kB08-01-04 22:53
ramdisk.c6.13 kB02-09-04 13:12
<chr_drv>0.00 B04-10-07 15:01
console.c30.91 kB02-09-04 13:12
keyboard.S21.04 kB08-01-04 22:59
Makefile4.81 kB08-01-04 22:59
rs_io.s5.75 kB08-01-04 22:59
serial.c2.91 kB02-09-04 13:12
tty_io.c18.40 kB02-09-04 13:12
tty_ioctl.c10.70 kB02-09-04 13:12
exit.c8.08 kB02-09-04 13:12
fork.c6.78 kB15-07-07 22:10
<math>0.00 B04-10-07 15:01
Makefile3.21 kB08-01-04 23:01
math_emulate.c2.08 kB02-09-04 13:12
mktime.c2.72 kB02-09-04 13:12
panic.c952.00 B02-09-04 13:12
printk.c1.75 kB02-09-04 13:12
sched.c18.57 kB16-07-07 21:23
signal.c5.61 kB02-09-04 13:12
sys.c7.62 kB02-09-04 13:12
system_call.s12.53 kB08-01-04 22:48
traps.c8.29 kB04-10-07 14:57
vsprintf.c9.96 kB02-09-04 13:12
<lib>0.00 B04-10-07 15:01
close.c397.00 B02-09-04 13:12
ctype.c1.72 kB02-09-04 13:12
dup.c401.00 B02-09-04 13:12
errno.c66.00 B02-09-04 13:12
execve.c607.00 B02-09-04 13:12
Makefile4.83 kB08-01-04 22:30
malloc.c13.50 kB02-09-04 13:12
open.c1.22 kB02-09-04 13:12
setsid.c382.00 B02-09-04 13:12
string.c199.00 B02-09-04 13:12
wait.c774.00 B02-09-04 13:12
write.c545.00 B02-09-04 13:12
_exit.c616.00 B02-09-04 13:12
Makefile8.58 kB08-01-04 22:21
<mm>0.00 B04-10-07 15:01
Makefile2.91 kB08-01-04 22:34
memory.c25.10 kB02-09-04 13:12
page.s842.00 B08-01-04 22:34
<tools>0.00 B04-10-07 15:01
build.c8.12 kB02-09-04 13:12
...
Sponsored links

tty_ioctl.c (286.77 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D