📄 con3215.c
字号:
for (i = 0; i < count; i++) if (str[i] == '\t' || str[i] == '\n') break; raw3215_write(raw, str, 0, i); count -= i; str += i; if (count > 0) { raw3215_putchar(raw, *str); count--; str++; } }}kdev_t con3215_device(struct console *c){ return MKDEV(TTY_MAJOR, c->index + 64 );}/* * panic() calls console_unblank before the system enters a * disabled, endless loop. */void con3215_unblank(void){ raw3215_info *raw; unsigned long flags; raw = raw3215[0]; /* console 3215 is the first one */ s390irq_spin_lock_irqsave(raw->irq, flags); raw3215_make_room(raw, RAW3215_BUFFER_SIZE); s390irq_spin_unlock_irqrestore(raw->irq, flags);}static int __init con3215_consetup(struct console *co, char *options){ return 0;}/* * The console structure for the 3215 console */static struct console con3215 = { name: "ttyS", index: 0, write: con3215_write, device: con3215_device, unblank: con3215_unblank, setup: con3215_consetup, flags: CON_PRINTBUFFER,};#endif/* * tty3215_open * * This routine is called whenever a 3215 tty is opened. */static int tty3215_open(struct tty_struct *tty, struct file * filp){ raw3215_info *raw; int retval, line; line = MINOR(tty->device) - tty->driver.minor_start; if ((line < 0) || (line >= NR_3215)) return -ENODEV; raw = raw3215[line]; if (raw == NULL) { raw = kmalloc(sizeof(raw3215_info) + RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA); if (raw == NULL) return -ENOMEM; raw->irq = raw3215_find_dev(line); if (raw->irq == -1) { kfree(raw); return -ENODEV; } raw->inbuf = (char *) raw + sizeof(raw3215_info); memset(raw, 0, sizeof(raw3215_info)); raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL|GFP_DMA); if (raw->buffer == NULL) { kfree(raw); return -ENOMEM; } raw->tqueue.routine = raw3215_softint; raw->tqueue.data = raw; init_waitqueue_head(&raw->empty_wait); raw3215[line] = raw; } tty->driver_data = raw; raw->tty = tty; tty->low_latency = 0; /* don't use bottom half for pushing chars */ /* * Start up 3215 device */ retval = raw3215_startup(raw); if (retval) return retval; return 0;}/* * tty3215_close() * * This routine is called when the 3215 tty is closed. We wait * for the remaining request to be completed. Then we clean up. */static void tty3215_close(struct tty_struct *tty, struct file * filp){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; if (raw == NULL || tty->count > 1) return; tty->closing = 1; /* Shutdown the terminal */ raw3215_shutdown(raw); tty->closing = 0; raw->tty = NULL;}/* * Returns the amount of free space in the output buffer. */static int tty3215_write_room(struct tty_struct *tty){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; /* Subtract TAB_STOP_SIZE to allow for a tab, 8 <<< 64K */ if ((RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE) >= 0) return RAW3215_BUFFER_SIZE - raw->count - TAB_STOP_SIZE; else return 0;}/* * String write routine for 3215 ttys */static int tty3215_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count){ raw3215_info *raw; int ret = 0; if (!tty) return 0; raw = (raw3215_info *) tty->driver_data; ret = raw3215_write(raw, buf, from_user, count); return ret;}/* * Put character routine for 3215 ttys */static void tty3215_put_char(struct tty_struct *tty, unsigned char ch){ raw3215_info *raw; if (!tty) return; raw = (raw3215_info *) tty->driver_data; raw3215_putchar(raw, ch);}static void tty3215_flush_chars(struct tty_struct *tty){}/* * Returns the number of characters in the output buffer */static int tty3215_chars_in_buffer(struct tty_struct *tty){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; return raw->count;}static void tty3215_flush_buffer(struct tty_struct *tty){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; raw3215_flush_buffer(raw); tty_wakeup(tty);}/* * Currently we don't have any io controls for 3215 ttys */static int tty3215_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg){ if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; switch (cmd) { default: return -ENOIOCTLCMD; } return 0;}/* * Disable reading from a 3215 tty */static void tty3215_throttle(struct tty_struct * tty){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; raw->flags |= RAW3215_THROTTLED;}/* * Enable reading from a 3215 tty */static void tty3215_unthrottle(struct tty_struct * tty){ raw3215_info *raw; unsigned long flags; raw = (raw3215_info *) tty->driver_data; if (raw->flags & RAW3215_THROTTLED) { s390irq_spin_lock_irqsave(raw->irq, flags); raw->flags &= ~RAW3215_THROTTLED; raw3215_try_io(raw); s390irq_spin_unlock_irqrestore(raw->irq, flags); }}/* * Disable writing to a 3215 tty */static void tty3215_stop(struct tty_struct *tty){ raw3215_info *raw; raw = (raw3215_info *) tty->driver_data; raw->flags |= RAW3215_STOPPED;}/* * Enable writing to a 3215 tty */static void tty3215_start(struct tty_struct *tty){ raw3215_info *raw; unsigned long flags; raw = (raw3215_info *) tty->driver_data; if (raw->flags & RAW3215_STOPPED) { s390irq_spin_lock_irqsave(raw->irq, flags); raw->flags &= ~RAW3215_STOPPED; raw3215_try_io(raw); s390irq_spin_unlock_irqrestore(raw->irq, flags); }}/* * 3215 console initialization code called from console_init(). * NOTE: This is called before kmalloc is available. */void __init con3215_init(void){ raw3215_info *raw; raw3215_req *req; int irq; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return; irq = raw3215_find_dev(0); /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0); cpcmd("TERM AUTOCR OFF", NULL, 0); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = (raw3215_req *) alloc_bootmem_low(sizeof(raw3215_req)); req->next = raw3215_freelist; raw3215_freelist = req; } ctrlchar_init();#ifdef CONFIG_TN3215_CONSOLE raw3215[0] = raw = (raw3215_info *) alloc_bootmem_low(sizeof(raw3215_info)); memset(raw, 0, sizeof(raw3215_info)); raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE); raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); /* Find the first console */ raw->irq = raw3215_find_dev(0); raw->flags |= RAW3215_FIXED; raw->tqueue.routine = raw3215_softint; raw->tqueue.data = raw; init_waitqueue_head(&raw->empty_wait); /* Request the console irq */ if ( raw3215_startup(raw) != 0 ) raw->irq = -1; if (raw->irq != -1) { register_console(&con3215); } else { free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE); free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE); free_bootmem((unsigned long) raw, sizeof(raw3215_info)); raw3215[0] = NULL; printk("Couldn't find a 3215 console device\n"); }#endif}/* * 3215 tty registration code called from tty_init(). * Most kernel services (incl. kmalloc) are available at this poimt. */void __init tty3215_init(void){ /* Don't bother registering the tty if we already skipped the console */ if (!CONSOLE_IS_3215) return; /* * Initialize the tty_driver structure * Entries in tty3215_driver that are NOT initialized: * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc */ memset(&tty3215_driver, 0, sizeof(struct tty_driver)); tty3215_driver.magic = TTY_DRIVER_MAGIC; tty3215_driver.driver_name = "tty3215"; tty3215_driver.name = "ttyS"; tty3215_driver.name_base = 0; tty3215_driver.major = TTY_MAJOR; tty3215_driver.minor_start = 64; tty3215_driver.num = NR_3215; tty3215_driver.type = TTY_DRIVER_TYPE_SYSTEM; tty3215_driver.subtype = SYSTEM_TYPE_TTY; tty3215_driver.init_termios = tty_std_termios; tty3215_driver.init_termios.c_iflag = IGNBRK | IGNPAR; tty3215_driver.init_termios.c_oflag = ONLCR | XTABS; tty3215_driver.init_termios.c_lflag = ISIG; tty3215_driver.flags = TTY_DRIVER_REAL_RAW; tty3215_driver.refcount = &tty3215_refcount; tty3215_driver.table = tty3215_table; tty3215_driver.termios = tty3215_termios; tty3215_driver.termios_locked = tty3215_termios_locked; tty3215_driver.open = tty3215_open; tty3215_driver.close = tty3215_close; tty3215_driver.write = tty3215_write; tty3215_driver.put_char = tty3215_put_char; tty3215_driver.flush_chars = tty3215_flush_chars; tty3215_driver.write_room = tty3215_write_room; tty3215_driver.chars_in_buffer = tty3215_chars_in_buffer; tty3215_driver.flush_buffer = tty3215_flush_buffer; tty3215_driver.ioctl = tty3215_ioctl; tty3215_driver.throttle = tty3215_throttle; tty3215_driver.unthrottle = tty3215_unthrottle; tty3215_driver.send_xchar = NULL; tty3215_driver.set_termios = NULL; tty3215_driver.stop = tty3215_stop; tty3215_driver.start = tty3215_start; tty3215_driver.hangup = NULL; tty3215_driver.break_ctl = NULL; tty3215_driver.wait_until_sent = NULL; tty3215_driver.read_proc = NULL; if (tty_register_driver(&tty3215_driver)) panic("Couldn't register tty3215 driver\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -