</pre><pre name="code" class="cpp">
-
-
-
-
-
-
-
-
-
-
- static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
- {
- int i;
- struct inode *inode = file->f_path.dentry->d_inode;
- struct tty_struct *tty = file_tty(file);
- struct tty_ldisc *ld;
-
- if (tty_paranoia_check(tty, inode, "tty_read"))
- return -EIO;
- if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
- return -EIO;
-
-
-
- ld = tty_ldisc_ref_wait(tty);
- if (ld->ops->read)
- i = (ld->ops->read)(tty, file, buf, count);
- else
- i = -EIO;
- tty_ldisc_deref(ld);
- if (i > 0)
- inode->i_atime = current_fs_time(inode->i_sb);
- return i;
- }
-
-
-
-
-
-
- static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,unsigned char __user *buf, size_t nr)
- {
- unsigned char __user *b = buf;
-
-
-
- uncopied = copy_from_read_buf(tty, &b, &nr);
- uncopied += copy_from_read_buf(tty, &b, &nr);
- }
-
-
- static int copy_from_read_buf(struct tty_struct *tty,unsigned char __user **b,size_t *nr)
- {
-
-
-
- if (n) {
- retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
- n -= retval;
- tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n);
- spin_lock_irqsave(&tty->read_lock, flags);
- tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt -= n;
-
- if (L_EXTPROC(tty) && tty->icanon && n == 1) {
- if (!tty->read_cnt && (*b)[n-1] == EOF_CHAR(tty))
- n--;
- }
- spin_unlock_irqrestore(&tty->read_lock, flags);
- *b += n;
- *nr -= n;
- }
- return retval;
- }
-
-
-
-
-
-
- static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
- {
- struct s3c24xx_uart_port *ourport = dev_id;
- struct uart_port *port = &ourport->port;
- struct tty_struct *tty = port->state->port.tty;
- unsigned int ufcon, ch, flag, ufstat, uerstat;
- int max_count = 64;
-
- while (max_count-- > 0) {
-
- ufcon = rd_regl(port, S3C2410_UFCON);
-
- ufstat = rd_regl(port, S3C2410_UFSTAT);
-
-
- if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
- break;
-
-
- uerstat = rd_regl(port, S3C2410_UERSTAT);
-
- ch = rd_regb(port, S3C2410_URXH);
-
-
- if (port->flags & UPF_CONS_FLOW) {
- int txe = s3c24xx_serial_txempty_nofifo(port);
-
- if (rx_enabled(port)) {
- if (!txe) {
- rx_enabled(port) = 0;
- continue;
- }
- } else {
- if (txe) {
- ufcon |= S3C2410_UFCON_RESETRX;
- wr_regl(port, S3C2410_UFCON, ufcon);
- rx_enabled(port) = 1;
- goto out;
- }
- continue;
- }
- }
-
-
-
- flag = TTY_NORMAL;
- port->icount.rx++;
-
- if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) {
- dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n",
- ch, uerstat);
-
-
- if (uerstat & S3C2410_UERSTAT_BREAK) {
- dbg("break!\n");
- port->icount.brk++;
- if (uart_handle_break(port))
- goto ignore_char;
- }
-
- if (uerstat & S3C2410_UERSTAT_FRAME)
- port->icount.frame++;
- if (uerstat & S3C2410_UERSTAT_OVERRUN)
- port->icount.overrun++;
-
- uerstat &= port->read_status_mask;
-
- if (uerstat & S3C2410_UERSTAT_BREAK)
- flag = TTY_BREAK;
- else if (uerstat & S3C2410_UERSTAT_PARITY)
- flag = TTY_PARITY;
- else if (uerstat & (S3C2410_UERSTAT_FRAME |
- S3C2410_UERSTAT_OVERRUN))
- flag = TTY_FRAME;
- }
-
- if (uart_handle_sysrq_char(port, ch))
- goto ignore_char;
-
-
- uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN,
- ch, flag);
- }
-
-
- tty_flip_buffer_push(tty);
- }
-
- static inline int tty_insert_flip_char(struct tty_struct *tty,unsigned char ch, char flag)
- {
- struct tty_buffer *tb = tty->buf.tail;
- if (tb && tb->used < tb->size) {
- tb->flag_buf_ptr[tb->used] = flag;
- tb->char_buf_ptr[tb->used++] = ch;
- return 1;
- }
- return tty_insert_flip_string_flags(tty, &ch, &flag, 1);
- }
-
- static void flush_to_ldisc(struct work_struct *work)
- {
- char_buf = head->char_buf_ptr + head->read;
- flag_buf = head->flag_buf_ptr + head->read;
- head->read += count;
- spin_unlock_irqrestore(&tty->buf.lock, flags);
- disc->ops->receive_buf(tty, char_buf,
- flag_buf, count);
- }
-
- static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,char *fp, int count)
- {
-
- if (tty->real_raw) {
- spin_lock_irqsave(&tty->read_lock, cpuflags);
- i = min(N_TTY_BUF_SIZE - tty->read_cnt,
- N_TTY_BUF_SIZE - tty->read_head);
- i = min(count, i);
- memcpy(tty->read_buf + tty->read_head, cp, i);
- tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt += i;
- cp += i;
- count -= i;
-
- i = min(N_TTY_BUF_SIZE - tty->read_cnt,
- N_TTY_BUF_SIZE - tty->read_head);
- i = min(count, i);
- memcpy(tty->read_buf + tty->read_head, cp, i);
- tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
- tty->read_cnt += i;
- spin_unlock_irqrestore(&tty->read_lock, cpuflags);
- }
- }