📄 aurora.c
字号:
} port->session = current->session; port->pgrp = current->pgrp;#ifdef AURORA_DEBUG printk("aurora_open: end\n");#endif return 0;}static void aurora_close(struct tty_struct * tty, struct file * filp){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; unsigned long flags; unsigned long timeout; unsigned char chip; #ifdef AURORA_DEBUG printk("aurora_close: start\n");#endif if (!port || aurora_paranoia_check(port, tty->device, "close")) return; chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); if (tty_hung_up_p(filp)) { restore_flags(flags); return; } bp = port_Board(port); if ((tty->count == 1) && (port->count != 1)) { printk(KERN_DEBUG "aurora%d: aurora_close: bad port count; " "tty->count is 1, port count is %d\n", board_No(bp), port->count); port->count = 1; } if (--port->count < 0) { printk(KERN_DEBUG "aurora%d: aurora_close: bad port " "count for tty%d: %d\n", board_No(bp), port_No(port), port->count); port->count = 0; } if (port->count) { restore_flags(flags); return; } port->flags |= ASYNC_CLOSING; /* Save the termios structure, since this port may have * separate termios for callout and dialin. */ if (port->flags & ASYNC_NORMAL_ACTIVE) port->normal_termios = *tty->termios;/* if (port->flags & ASYNC_CALLOUT_ACTIVE) port->callout_termios = *tty->termios;*/ /* Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE){#ifdef AURORA_DEBUG printk("aurora_close: waiting to flush...\n");#endif tty_wait_until_sent(tty, port->closing_wait); } /* At this point we stop accepting input. To do this, we * disable the receive line status interrupts, and tell the * interrupt driver to stop checking the data ready bit in the * line status register. */ port->SRER &= ~SRER_RXD; if (port->flags & ASYNC_INITIALIZED) { port->SRER &= ~SRER_TXRDY; port->SRER |= SRER_TXEMPTY; sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]); /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially * important if there is a transmit FIFO! */ timeout = jiffies+HZ; while(port->SRER & SRER_TXEMPTY) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(port->timeout); if (time_after(jiffies, timeout)) break; } }#ifdef AURORA_DEBUG printk("aurora_close: shutdown_port\n");#endif aurora_shutdown_port(bp, port); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); tty->closing = 0; port->event = 0; port->tty = 0; if (port->blocked_open) { if (port->close_delay) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(port->close_delay); } wake_up_interruptible(&port->open_wait); } port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| ASYNC_CLOSING); wake_up_interruptible(&port->close_wait); restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_close: end\n");#endif}static int aurora_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; int c, total = 0; unsigned long flags; unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_write: start %d\n",count);#endif if (aurora_paranoia_check(port, tty->device, "aurora_write")) return 0; chip = AURORA_CD180(port_No(port)); bp = port_Board(port); if (!tty || !port->xmit_buf || !tmp_buf) return 0; if (from_user) down(&tmp_buf_sem); save_flags(flags); while (1) { cli(); c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); if (c <= 0) break; if (from_user) { copy_from_user(tmp_buf, buf, c); c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c); } else memcpy(port->xmit_buf + port->xmit_head, buf, c); port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); port->xmit_cnt += c; restore_flags(flags); buf += c; count -= c; total += c; } if (from_user) up(&tmp_buf_sem); if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && !(port->SRER & SRER_TXRDY)) { port->SRER |= SRER_TXRDY; sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]); } restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_write: end %d\n",total);#endif return total;}static void aurora_put_char(struct tty_struct * tty, unsigned char ch){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; unsigned long flags;#ifdef AURORA_DEBUG printk("aurora_put_char: start %c\n",ch);#endif if (aurora_paranoia_check(port, tty->device, "aurora_put_char")) return; if (!tty || !port->xmit_buf) return; save_flags(flags); cli(); if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { restore_flags(flags); return; } port->xmit_buf[port->xmit_head++] = ch; port->xmit_head &= SERIAL_XMIT_SIZE - 1; port->xmit_cnt++; restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_put_char: end\n");#endif}static void aurora_flush_chars(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; unsigned long flags; unsigned char chip;/*#ifdef AURORA_DEBUG printk("aurora_flush_chars: start\n");#endif*/ if (aurora_paranoia_check(port, tty->device, "aurora_flush_chars")) return; chip = AURORA_CD180(port_No(port)); if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf) return; save_flags(flags); cli(); port->SRER |= SRER_TXRDY; sbus_writeb(port_No(port) & 7, &port_Board(port)->r[chip]->r[CD180_CAR]); udelay(1); sbus_writeb(port->SRER, &port_Board(port)->r[chip]->r[CD180_SRER]); restore_flags(flags);/*#ifdef AURORA_DEBUG printk("aurora_flush_chars: end\n");#endif*/}static int aurora_write_room(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; int ret;#ifdef AURORA_DEBUG printk("aurora_write_room: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_write_room")) return 0; ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; if (ret < 0) ret = 0;#ifdef AURORA_DEBUG printk("aurora_write_room: end\n");#endif return ret;}static int aurora_chars_in_buffer(struct tty_struct *tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; if (aurora_paranoia_check(port, tty->device, "aurora_chars_in_buffer")) return 0; return port->xmit_cnt;}static void aurora_flush_buffer(struct tty_struct *tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; unsigned long flags;#ifdef AURORA_DEBUG printk("aurora_flush_buffer: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_flush_buffer")) return; save_flags(flags); cli(); port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; restore_flags(flags); wake_up_interruptible(&tty->write_wait); if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty);#ifdef AURORA_DEBUG printk("aurora_flush_buffer: end\n");#endif}static int aurora_get_modem_info(struct Aurora_port * port, unsigned int *value){ struct Aurora_board * bp; unsigned char status,chip; unsigned int result; unsigned long flags;#ifdef AURORA_DEBUG printk("aurora_get_modem_info: start\n");#endif chip = AURORA_CD180(port_No(port)); bp = port_Board(port); save_flags(flags); cli(); sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); status = sbus_readb(&bp->r[chip]->r[CD180_MSVR]); result = 0/*bp->r[chip]->r[AURORA_RI] & (1u << port_No(port)) ? 0 : TIOCM_RNG*/; restore_flags(flags); result |= ((status & bp->RTS) ? TIOCM_RTS : 0) | ((status & bp->DTR) ? TIOCM_DTR : 0) | ((status & MSVR_CD) ? TIOCM_CAR : 0) | ((status & MSVR_DSR) ? TIOCM_DSR : 0) | ((status & MSVR_CTS) ? TIOCM_CTS : 0); put_user(result,(unsigned long *) value);#ifdef AURORA_DEBUG printk("aurora_get_modem_info: end\n");#endif return 0;}static int aurora_set_modem_info(struct Aurora_port * port, unsigned int cmd, unsigned int *value){ int error; unsigned int arg; unsigned long flags; struct Aurora_board *bp = port_Board(port); unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_set_modem_info: start\n");#endif error = get_user(arg, value); if (error) return error; chip = AURORA_CD180(port_No(port)); switch (cmd) { case TIOCMBIS: if (arg & TIOCM_RTS) port->MSVR |= bp->RTS; if (arg & TIOCM_DTR) port->MSVR |= bp->DTR; break; case TIOCMBIC: if (arg & TIOCM_RTS) port->MSVR &= ~bp->RTS; if (arg & TIOCM_DTR) port->MSVR &= ~bp->DTR; break; case TIOCMSET: port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | bp->RTS) : (port->MSVR & ~bp->RTS); port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | bp->RTS) : (port->MSVR & ~bp->RTS); break; default: return -EINVAL; }; save_flags(flags); cli(); sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]); restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_set_modem_info: end\n");#endif return 0;}static void aurora_send_break(struct Aurora_port * port, unsigned long length){ struct Aurora_board *bp = port_Board(port); unsigned long flags; unsigned char chip; #ifdef AURORA_DEBUG printk("aurora_send_break: start\n");#endif chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); port->break_length = AURORA_TPS / HZ * length; port->COR2 |= COR2_ETC; port->SRER |= SRER_TXRDY; sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]); sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]); aurora_wait_CCR(bp->r[chip]); sbus_writeb(CCR_CORCHG2, &bp->r[chip]->r[CD180_CCR]); aurora_wait_CCR(bp->r[chip]); restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_send_break: end\n");#endif}static int aurora_set_serial_info(struct Aurora_port * port, struct serial_struct * newinfo){ struct serial_struct tmp; struct Aurora_board *bp = port_Board(port); int change_speed; unsigned long flags; int error;#ifdef AURORA_DEBUG printk("aurora_set_serial_info: start\n");#endif error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp)); if (error) return error; copy_from_user(&tmp, newinfo, sizeof(tmp)); #if 0 if ((tmp.irq != bp->irq) || (tmp.port != bp->base) || (tmp.type != PORT_CIRRUS) || (tmp.baud_base != (bp->oscfreq + CD180_TPC/2) / CD180_TPC) || (tmp.custom_divisor != 0) || (tmp.xmit_fifo_size != CD180_NFIFO) || (tmp.flags & ~AURORA_LEGAL_FLAGS)) return -EINVAL;#endif change_speed = ((port->flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); if (!suser()) { if ((tmp.close_delay != port->close_delay) || (tmp.closing_wait != port->closing_wait) || ((tmp.flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) return -EPERM; port->flags = ((port->flags & ~ASYNC_USR_MASK) | (tmp.flags & ASYNC_USR_MASK)); } else { port->flags = ((port->flags & ~ASYNC_FLAGS) | (tmp.flags & ASYNC_FLAGS)); port->close_delay = tmp.close_delay; port->closing_wait = tmp.closing_wait; } if (change_speed) { save_flags(flags); cli(); aurora_change_speed(bp, port); restore_flags(flags); }#ifdef AURORA_DEBUG printk("aurora_set_serial_info: end\n");#endif return 0;}extern int aurora_get_serial_info(struct Aurora_port * port, struct serial_struct * retinfo){ struct serial_struct tmp; struct Aurora_board *bp = port_Board(port); int error; #ifdef AURORA_DEBUG printk("aurora_get_serial_info: start\n");#endif error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)); if (error) return error; memset(&tmp, 0, sizeof(tmp));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -