예제 #1
0
int __init hvc_init(void)
{
	int i;

	memset(&hvc_driver, 0, sizeof(struct tty_driver));

	hvc_driver.magic = TTY_DRIVER_MAGIC;
	hvc_driver.driver_name = "hvc";
	hvc_driver.name = "hvc/%d";
	hvc_driver.major = HVC_MAJOR;
	hvc_driver.minor_start = HVC_MINOR;
	hvc_driver.num = hvc_count(&hvc_offset);
	if (hvc_driver.num > MAX_NR_HVC_CONSOLES)
		hvc_driver.num = MAX_NR_HVC_CONSOLES;
	hvc_driver.type = TTY_DRIVER_TYPE_SYSTEM;
	hvc_driver.init_termios = tty_std_termios;
	hvc_driver.flags = TTY_DRIVER_REAL_RAW;
	hvc_driver.refcount = &hvc_refcount;
	hvc_driver.table = hvc_table;
	hvc_driver.termios = hvc_termios;
	hvc_driver.termios_locked = hvc_termios_locked;

	hvc_driver.open = hvc_open;
	hvc_driver.close = hvc_close;
	hvc_driver.write = hvc_write;
	hvc_driver.hangup = hvc_hangup;
	hvc_driver.write_room = hvc_write_room;
	hvc_driver.chars_in_buffer = hvc_chars_in_buffer;

	for (i = 0; i < hvc_driver.num; i++) {
		hvc_struct[i].lock = SPIN_LOCK_UNLOCKED;
		hvc_struct[i].index = i;
		tty_register_devfs(&hvc_driver, 0, hvc_driver.minor_start + i);
	}

	if (tty_register_driver(&hvc_driver))
		panic("Couldn't register hvc console driver\n");

	if (hvc_driver.num > 0)
		kernel_thread(khvcd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);

	return 0;
}
예제 #2
0
static int pty_open(struct tty_struct *tty, struct file * filp)
{
	int	retval;
	int	line;
	struct	pty_struct *pty;

	retval = -ENODEV;
	if (!tty || !tty->link)
		goto out;
	line = MINOR(tty->device) - tty->driver.minor_start;
	if ((line < 0) || (line >= NR_PTYS))
		goto out;
	pty = (struct pty_struct *)(tty->driver.driver_state) + line;
	tty->driver_data = pty;

	retval = -EIO;
	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
		goto out;
	if (test_bit(TTY_PTY_LOCK, &tty->link->flags))
		goto out;
	if (tty->link->count != 1)
		goto out;

	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
	wake_up_interruptible(&pty->open_wait);
	set_bit(TTY_THROTTLED, &tty->flags);
	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

	/*  Register a slave for the master  */
	if (tty->driver.major == PTY_MASTER_MAJOR)
		tty_register_devfs(&tty->link->driver,
				   DEVFS_FL_CURRENT_OWNER | DEVFS_FL_WAIT,
				   tty->link->driver.minor_start +
				   MINOR(tty->device)-tty->driver.minor_start);
	retval = 0;
out:
	return retval;
}
예제 #3
0
int __init dz_init(void)
{
	int i;
	long flags;
	struct dz_serial *info;

	/* Setup base handler, and timer table. */
	init_bh(SERIAL_BH, do_serial_bh);

	show_serial_version();

	memset(&serial_driver, 0, sizeof(struct tty_driver));
	serial_driver.magic = TTY_DRIVER_MAGIC;
#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
	serial_driver.name = "ttyS";
#else
	serial_driver.name = "tts/%d";
#endif
	serial_driver.major = TTY_MAJOR;
	serial_driver.minor_start = 64;
	serial_driver.num = DZ_NB_PORT;
	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
	serial_driver.subtype = SERIAL_TYPE_NORMAL;
	serial_driver.init_termios = tty_std_termios;

	serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
	                                     CLOCAL;
	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
	serial_driver.refcount = &serial_refcount;
	serial_driver.table = serial_table;
	serial_driver.termios = serial_termios;
	serial_driver.termios_locked = serial_termios_locked;

	serial_driver.open = dz_open;
	serial_driver.close = dz_close;
	serial_driver.write = dz_write;
	serial_driver.flush_chars = dz_flush_chars;
	serial_driver.write_room = dz_write_room;
	serial_driver.chars_in_buffer = dz_chars_in_buffer;
	serial_driver.flush_buffer = dz_flush_buffer;
	serial_driver.ioctl = dz_ioctl;
	serial_driver.throttle = dz_throttle;
	serial_driver.unthrottle = dz_unthrottle;
	serial_driver.send_xchar = dz_send_xchar;
	serial_driver.set_termios = dz_set_termios;
	serial_driver.stop = dz_stop;
	serial_driver.start = dz_start;
	serial_driver.hangup = dz_hangup;

	/*
	 * The callout device is just like normal device except for
	 * major number and the subtype code.
	 */
	callout_driver = serial_driver;
#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
	callout_driver.name = "cua";
#else
	callout_driver.name = "cua/%d";
#endif
	callout_driver.major = TTYAUX_MAJOR;
	callout_driver.subtype = SERIAL_TYPE_CALLOUT;

	if (tty_register_driver(&serial_driver))
		panic("Couldn't register serial driver");
	if (tty_register_driver(&callout_driver))
		panic("Couldn't register callout driver");
	save_flags(flags);
	cli();

	for (i = 0; i < DZ_NB_PORT; i++) {
		info = &multi[i];
		lines[i] = info;
		info->magic = SERIAL_MAGIC;

		if (mips_machtype == MACH_DS23100 ||
		    mips_machtype == MACH_DS5100)
			info->port = (unsigned long) KN01_DZ11_BASE;
		else
			info->port = (unsigned long) KN02_DZ11_BASE;

		info->line = i;
		info->tty = 0;
		info->close_delay = 50;
		info->closing_wait = 3000;
		info->x_char = 0;
		info->event = 0;
		info->count = 0;
		info->blocked_open = 0;
		info->tqueue.routine = do_softint;
		info->tqueue.data = info;
		info->tqueue_hangup.routine = do_serial_hangup;
		info->tqueue_hangup.data = info;
		info->callout_termios = callout_driver.init_termios;
		info->normal_termios = serial_driver.init_termios;
		init_waitqueue_head(&info->open_wait);
		init_waitqueue_head(&info->close_wait);

		/*
		 * If we are pointing to address zero then punt - not correctly
		 * set up in setup.c to handle this.
		 */
		if (!info->port)
			return 0;

		printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,
		       info->port, dec_interrupt[DEC_IRQ_DZ11]);

		tty_register_devfs(&serial_driver, 0,
				 serial_driver.minor_start + info->line);
		tty_register_devfs(&callout_driver, 0,
				callout_driver.minor_start + info->line);
	}

	/* reset the chip */
#ifndef CONFIG_SERIAL_DEC_CONSOLE
	dz_out(info, DZ_CSR, DZ_CLR);
	while (dz_in(info, DZ_CSR) & DZ_CLR);
	iob();

	/* enable scanning */
	dz_out(info, DZ_CSR, DZ_MSE);
#endif

	/* order matters here... the trick is that flags
	   is updated... in request_irq - to immediatedly obliterate
	   it is unwise. */
	restore_flags(flags);


	if (request_irq(dec_interrupt[DEC_IRQ_DZ11], dz_interrupt,
			SA_INTERRUPT, "DZ", lines[0]))
		panic("Unable to register DZ interrupt");

	return 0;
}