/*
* linux/kernel/serial.c
*
* (C) 1991 Linus Torvalds
*/

/*
* serial.c
*
* This module implements the rs232 io functions
* void rs_write(struct tty_struct * queue);
* void rs_init(void);
* and all interrupts pertaining to serial IO.
*/
/*
* serial.c
* óʵrs232 
* void rs_write(struct tty_struct *queue);
* void rs_init(void);
* Լ봫IO йϵжϴ
*/

#include <linux/tty.h>		// tty ͷļйtty_ioͨŷĲ
#include <linux/sched.h>	// ȳͷļṹtask_structʼ0 ݣ
// һЩйúͻȡǶʽຯ䡣
#include <asm/system.h>		// βͷļйضμĴǶʽຯ
#include <asm/io.h>		// io ͷļӲ˿/䡣

#define WAKEUP_CHARS (TTY_BUF_SIZE/4)	// дкWAKEUP_CHARS ַʱͿʼ͡

extern void rs1_interrupt (void);	// п1 жϴ(rs_io.s, 34)
extern void rs2_interrupt (void);	// п2 жϴ(rs_io.s, 38)

//// ʼж˿
// port: 1 - 0x3F82 - 0x2F8
static void
init (int port)
{
  outb_p (0x80, port + 3);	/* set DLAB of line control reg */
/* ·ƼĴDLAB λ(λ7) */
  outb_p (0x30, port);		/* LS of divisor (48 -> 2400 bps */
/* Ͳӵֽڣ0x30->2400bps */
  outb_p (0x00, port + 1);	/* MS of divisor */
/* ͲӸֽڣ0x00 */
  outb_p (0x03, port + 3);	/* reset DLAB */
/* λDLAB λλΪ8 λ */
  outb_p (0x0b, port + 4);	/* set DTR,RTS, OUT_2 */
/* DTRRTSû2 */
  outb_p (0x0d, port + 1);	/* enable all intrs but writes */
/* д(дֿ)⣬жԴж */
  (void) inb (port);		/* read data port to reset things (?) */
/* ݿڣԽиλ(?) */
}

//// ʼжϳʹнӿڡ
void
rs_init (void)
{
  set_intr_gate (0x24, rs1_interrupt);	// ôп1 ж(ӲIRQ4 ź)
  set_intr_gate (0x23, rs2_interrupt);	// ôп2 ж(ӲIRQ3 ź)
  init (tty_table[1].read_q.data);	// ʼп1(.data Ƕ˿ں)
  init (tty_table[2].read_q.data);	// ʼп2
  outb (inb_p (0x21) & 0xE7, 0x21);	// 8259A оƬIRQ3IRQ4 жź
}

/*
* This routine gets called when tty_write has put something into
* the write_queue. It must check wheter the queue is empty, and
* set the interrupt register accordingly
*
* void _rs_write(struct tty_struct * tty);
*/
/*
* tty_write()ѽݷ(д)ʱӳ򡣱
* дǷΪգӦжϼĴ
*/
//// ݷ
// ʵֻǿзͱּĴѿжϱ־UART ݷͳȥжźš
void
rs_write (struct tty_struct *tty)
{
  cli ();			// жϡ
// двգ0x3f9(0x2f9) ȶȡжĴݣϷͱּĴ
// ж־λ1дظüĴ
  if (!EMPTY (tty->write_q))
    outb (inb_p (tty->write_q.data + 1) | 0x02, tty->write_q.data + 1);
  sti ();			// жϡ
}
