Ejemplo n.º 1
0
/*
 * Open a tty line.  Note that this can be called multiple times, so ->open can
 * be >1.  Only set up the tty struct if this is a "new" open, e.g. ->open was
 * zero
 */
static int duart_open(struct tty_struct *tty, struct file *filp)
{
	uart_state_t *us;
	unsigned int line = tty->index;
	unsigned long flags;

	if ((line >= tty->driver->num) || !sb1250_duart_present[line])
		return -ENODEV;

#ifdef DUART_SPEW
	printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n",
	       current->pid, current->comm, tty, tty->read_wait,
	       tty->write_wait);
#endif

	us = uart_states + line;
	tty->driver_data = us;

	spin_lock_irqsave(&open_lock, flags);
	if (!us->open) {
		us->tty = tty;
		us->tty->termios->c_cflag = us->last_cflags;
	}
	us->open++;
	us->flags &= ~TX_INTEN;
	duart_unmask_ints(line, M_DUART_IMR_RX);
	spin_unlock_irqrestore(&open_lock, flags);

	return 0;
}
Ejemplo n.º 2
0
/*
 * Open a tty line.  Note that this can be called multiple times, so ->open can
 * be >1.  Only set up the tty struct if this is a "new" open, e.g. ->open was
 * zero
 */
static int duart_open(struct tty_struct *tty, struct file *filp)
{
	uart_state_t *us;
	unsigned int line = MINOR(tty->device) - tty->driver.minor_start;
	unsigned long flags;

	MOD_INC_USE_COUNT;

	if ((line < 0) || (line >= DUART_MAX_LINE) || !sb1250_duart_present[line]) {
		MOD_DEC_USE_COUNT;
		return -ENODEV;
	}

#ifdef DUART_SPEW
	printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n",
	       current->pid, current->comm, tty, tty->read_wait,
	       tty->write_wait);
#endif

	us = uart_states + line;
	tty->driver_data = us;

	spin_lock_irqsave(&open_lock, flags);
	if (!us->open) {
		us->tty = tty;
		us->tty->termios->c_cflag = us->last_cflags;
	}
	us->open++;
	us->flags &= ~TX_INTEN;
	duart_unmask_ints(line, M_DUART_IMR_RX);
	spin_unlock_irqrestore(&open_lock, flags);

	return 0;
}
Ejemplo n.º 3
0
/*
 * Buffer up to count characters from buf to be written.  If we don't have
 * other characters buffered, enable the tx interrupt to start sending
 */
static int duart_write(struct tty_struct * tty, int from_user,
	const unsigned char *buf, int count)
{
	uart_state_t *us;
	int c, t, total = 0;
	unsigned long flags;

	if (!tty) return 0;

	us = tty->driver_data;
	if (!us) return 0;

#ifdef DUART_SPEW
	printk("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm);
#endif

	spin_lock_irqsave(&us->outp_lock, flags);

	for (;;) {
		c = count;

		t = SERIAL_XMIT_SIZE - us->outp_tail;
		if (t < c) c = t;

		t = SERIAL_XMIT_SIZE - 1 - us->outp_count;
		if (t < c) c = t;

		if (c <= 0) break;

		if (from_user) {
			spin_unlock_irqrestore(&us->outp_lock, flags);
			if (copy_from_user(us->outp_buf + us->outp_tail, buf, c)) {
				return -EFAULT;
			}
			spin_lock_irqsave(&us->outp_lock, flags);
		} else {
			memcpy(us->outp_buf + us->outp_tail, buf, c);
		}

		us->outp_count += c;
		us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1);
		buf += c;
		count -= c;
		total += c;
	}

	spin_unlock_irqrestore(&us->outp_lock, flags);

	if (us->outp_count && !tty->stopped && 
	    !tty->hw_stopped && !(us->flags & TX_INTEN)) {
		us->flags |= TX_INTEN;
		duart_unmask_ints(us->line, M_DUART_IMR_TX);
	}

	return total;
}
Ejemplo n.º 4
0
/* XXXKW locking? */
static void duart_start(struct tty_struct *tty)
{
	uart_state_t *us = (uart_state_t *) tty->driver_data;

#ifdef DUART_SPEW
	printk("duart_start called\n");
#endif

	if (us->outp_count && !(us->flags & TX_INTEN)) {
		us->flags |= TX_INTEN;
		duart_unmask_ints(us->line, M_DUART_IMR_TX);
	}
}
Ejemplo n.º 5
0
static void duart_flush_chars(struct tty_struct * tty)
{
	uart_state_t *port;

	if (!tty) return;

	port = tty->driver_data;

	if (!port) return;

	if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) {
		return;
	}

	port->flags |= TX_INTEN;
	duart_unmask_ints(port->line, M_DUART_IMR_TX);
}