📄 aurora.c
字号:
tmp.type = PORT_CIRRUS; tmp.line = port - aurora_port; tmp.port = 0; tmp.irq = bp->irq; tmp.flags = port->flags; tmp.baud_base = (bp->oscfreq + CD180_TPC/2) / CD180_TPC; tmp.close_delay = port->close_delay * HZ/100; tmp.closing_wait = port->closing_wait * HZ/100; tmp.xmit_fifo_size = CD180_NFIFO; copy_to_user(retinfo, &tmp, sizeof(tmp));#ifdef AURORA_DEBUGprintk("aurora_get_serial_info: end\n");#endif return 0;}static int aurora_ioctl(struct tty_struct * tty, struct file * filp, unsigned int cmd, unsigned long arg) { struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; int error; int retval;#ifdef AURORA_DEBUG printk("aurora_ioctl: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_ioctl")) return -ENODEV; switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); if (!arg) aurora_send_break(port, HZ/4); /* 1/4 second */ return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); aurora_send_break(port, arg ? arg*(HZ/10) : HZ/4); return 0; case TIOCGSOFTCAR: error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long)); if (error) return error; put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); return 0; case TIOCSSOFTCAR: retval = get_user(arg,(unsigned long *) arg); if (retval) return retval; tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); return 0; case TIOCMGET: error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned int)); if (error) return error; return aurora_get_modem_info(port, (unsigned int *) arg); case TIOCMBIS: case TIOCMBIC: case TIOCMSET: return aurora_set_modem_info(port, cmd, (unsigned int *) arg); case TIOCGSERIAL: return aurora_get_serial_info(port, (struct serial_struct *) arg); case TIOCSSERIAL: return aurora_set_serial_info(port, (struct serial_struct *) arg); default: return -ENOIOCTLCMD; };#ifdef AURORA_DEBUG printk("aurora_ioctl: end\n");#endif return 0;}static void aurora_throttle(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; unsigned long flags; unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_throttle: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_throttle")) return; bp = port_Board(port); chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); port->MSVR &= ~bp->RTS; sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); if (I_IXOFF(tty)) { aurora_wait_CCR(bp->r[chip]); sbus_writeb(CCR_SSCH2, &bp->r[chip]->r[CD180_CCR]); aurora_wait_CCR(bp->r[chip]); } sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]); restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_throttle: end\n");#endif}static void aurora_unthrottle(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; unsigned long flags; unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_unthrottle: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_unthrottle")) return; bp = port_Board(port); chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); port->MSVR |= bp->RTS; sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]); udelay(1); if (I_IXOFF(tty)) { aurora_wait_CCR(bp->r[chip]); sbus_writeb(CCR_SSCH1, &bp->r[chip]->r[CD180_CCR]); aurora_wait_CCR(bp->r[chip]); } sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]); restore_flags(flags);#ifdef AURORA_DEBUG printk("aurora_unthrottle: end\n");#endif}static void aurora_stop(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; unsigned long flags; unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_stop: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_stop")) return; bp = port_Board(port); chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); 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_stop: end\n");#endif}static void aurora_start(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; unsigned long flags; unsigned char chip;#ifdef AURORA_DEBUG printk("aurora_start: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_start")) return; bp = port_Board(port); chip = AURORA_CD180(port_No(port)); save_flags(flags); cli(); if (port->xmit_cnt && port->xmit_buf && !(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_start: end\n");#endif}/* * This routine is called from the scheduler tqueue when the interrupt * routine has signalled that a hangup has occurred. The path of * hangup processing is: * * serial interrupt routine -> (scheduler tqueue) -> * do_aurora_hangup() -> tty->hangup() -> aurora_hangup() * */static void do_aurora_hangup(void *private_){ struct Aurora_port *port = (struct Aurora_port *) private_; struct tty_struct *tty;#ifdef AURORA_DEBUG printk("do_aurora_hangup: start\n");#endif tty = port->tty; if (tty != NULL) { tty_hangup(tty); /* FIXME: module removal race - AKPM */#ifdef AURORA_DEBUG printk("do_aurora_hangup: end\n");#endif } MOD_DEC_USE_COUNT;}static void aurora_hangup(struct tty_struct * tty){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; struct Aurora_board *bp; #ifdef AURORA_DEBUG printk("aurora_hangup: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_hangup")) return; bp = port_Board(port); aurora_shutdown_port(bp, port); port->event = 0; port->count = 0; port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); port->tty = 0; wake_up_interruptible(&port->open_wait);#ifdef AURORA_DEBUG printk("aurora_hangup: end\n");#endif}static void aurora_set_termios(struct tty_struct * tty, struct termios * old_termios){ struct Aurora_port *port = (struct Aurora_port *) tty->driver_data; unsigned long flags;#ifdef AURORA_DEBUG printk("aurora_set_termios: start\n");#endif if (aurora_paranoia_check(port, tty->device, "aurora_set_termios")) return; if (tty->termios->c_cflag == old_termios->c_cflag && tty->termios->c_iflag == old_termios->c_iflag) return; save_flags(flags); cli(); aurora_change_speed(port_Board(port), port); restore_flags(flags); if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; aurora_start(tty); }#ifdef AURORA_DEBUG printk("aurora_set_termios: end\n");#endif}static void do_aurora_bh(void){ run_task_queue(&tq_aurora);}static void do_softint(void *private_){ struct Aurora_port *port = (struct Aurora_port *) private_; struct tty_struct *tty;#ifdef AURORA_DEBUG printk("do_softint: start\n");#endif tty = port->tty; if (tty == NULL) return; if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) { if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); wake_up_interruptible(&tty->write_wait); }#ifdef AURORA_DEBUG printk("do_softint: end\n");#endif}static int aurora_init_drivers(void){ int error; int i;#ifdef AURORA_DEBUG printk("aurora_init_drivers: start\n");#endif tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL); if (tmp_buf == NULL) { printk(KERN_ERR "aurora: Couldn't get free page.\n"); return 1; } init_bh(AURORA_BH, do_aurora_bh);/* memset(IRQ_to_board, 0, sizeof(IRQ_to_board));*/ memset(&aurora_driver, 0, sizeof(aurora_driver)); aurora_driver.magic = TTY_DRIVER_MAGIC; aurora_driver.name = "ttyA"; aurora_driver.major = AURORA_MAJOR; aurora_driver.num = AURORA_TNPORTS; aurora_driver.type = TTY_DRIVER_TYPE_SERIAL; aurora_driver.subtype = AURORA_TYPE_NORMAL; aurora_driver.init_termios = tty_std_termios; aurora_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; aurora_driver.flags = TTY_DRIVER_REAL_RAW; aurora_driver.refcount = &aurora_refcount; aurora_driver.table = aurora_table; aurora_driver.termios = aurora_termios; aurora_driver.termios_locked = aurora_termios_locked; aurora_driver.open = aurora_open; aurora_driver.close = aurora_close; aurora_driver.write = aurora_write; aurora_driver.put_char = aurora_put_char; aurora_driver.flush_chars = aurora_flush_chars; aurora_driver.write_room = aurora_write_room; aurora_driver.chars_in_buffer = aurora_chars_in_buffer; aurora_driver.flush_buffer = aurora_flush_buffer; aurora_driver.ioctl = aurora_ioctl; aurora_driver.throttle = aurora_throttle; aurora_driver.unthrottle = aurora_unthrottle; aurora_driver.set_termios = aurora_set_termios; aurora_driver.stop = aurora_stop; aurora_driver.start = aurora_start; aurora_driver.hangup = aurora_hangup; error = tty_register_driver(&aurora_driver); if (error) { free_page((unsigned long) tmp_buf); printk(KERN_ERR "aurora: Couldn't register aurora driver, error = %d\n", error); return 1; } memset(aurora_port, 0, sizeof(aurora_port)); for (i = 0; i < AURORA_TNPORTS; i++) { aurora_port[i].normal_termios = aurora_driver.init_termios; aurora_port[i].magic = AURORA_MAGIC; aurora_port[i].tqueue.routine = do_softint; aurora_port[i].tqueue.data = &aurora_port[i]; aurora_port[i].tqueue_hangup.routine = do_aurora_hangup; aurora_port[i].tqueue_hangup.data = &aurora_port[i]; aurora_port[i].close_delay = 50 * HZ/100; aurora_port[i].closing_wait = 3000 * HZ/100; init_waitqueue_head(&aurora_port[i].open_wait); init_waitqueue_head(&aurora_port[i].close_wait); }#ifdef AURORA_DEBUG printk("aurora_init_drivers: end\n");#endif return 0;}static void aurora_release_drivers(void){#ifdef AURORA_DEBUG printk("aurora_release_drivers: start\n");#endif free_page((unsigned long)tmp_buf); tty_unregister_driver(&aurora_driver);#ifdef AURORA_DEBUG printk("aurora_release_drivers: end\n");#endif}/* * Called at boot time. * * You can specify IO base for up to RC_NBOARD cards, * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. * Note that there will be no probing at default * addresses in this case. * */void __init aurora_setup(char *str, int *ints){ int i; for(i=0;(i<ints[0])&&(i<4);i++) { if (ints[i+1]) irqs[i]=ints[i+1]; }}static int __init aurora_real_init(void){ int found; int i; printk(KERN_INFO "aurora: Driver starting.\n"); if(aurora_init_drivers()) return -EIO; found = aurora_probe(); if(!found) { aurora_release_drivers(); printk(KERN_INFO "aurora: No Aurora Multiport boards detected.\n"); return -EIO; } else { printk(KERN_INFO "aurora: %d boards found.\n", found); } for (i = 0; i < found; i++) { int ret = aurora_setup_board(&aurora_board[i]); if (ret) {#ifdef AURORA_DEBUG printk(KERN_ERR "aurora_init: error aurora_setup_board ret %d\n", ret);#endif return ret; } } return 0;}int irq = 0;int irq1 = 0;int irq2 = 0;int irq3 = 0;MODULE_PARM(irq , "i");MODULE_PARM(irq1, "i");MODULE_PARM(irq2, "i");MODULE_PARM(irq3, "i");static int __init aurora_init(void) { if (irq ) irqs[0]=irq ; if (irq1) irqs[1]=irq1; if (irq2) irqs[2]=irq2; if (irq3) irqs[3]=irq3; return aurora_real_init();} static void __exit aurora_cleanup(void){ int i; #ifdef AURORA_DEBUGprintk("cleanup_module: aurora_release_drivers\n");#endif; aurora_release_drivers(); for (i = 0; i < AURORA_NBOARD; i++) if (aurora_board[i].flags & AURORA_BOARD_PRESENT) { aurora_shutdown_board(&aurora_board[i]); aurora_release_io_range(&aurora_board[i]); }}module_init(aurora_init);module_exit(aurora_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -