static irqreturn_t scc_rx_int(int irq, void *data)
{
	unsigned char	ch;
	struct scc_port *port = data;
	struct tty_struct *tty = port->gs.port.tty;
	SCC_ACCESS_INIT(port);

	ch = SCCread_NB(RX_DATA_REG);
	if (!tty) {
		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
		return IRQ_HANDLED;
	}
	tty_insert_flip_char(tty, ch, 0);

	/* Check if another character is already ready; in that case, the
	 * spcond_int() function must be used, because this character may have an
	 * error condition that isn't signalled by the interrupt vector used!
	 */
	if (SCCread(INT_PENDING_REG) &
	    (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
		scc_spcond_int (irq, data);
		return IRQ_HANDLED;
	}

	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);

	tty_flip_buffer_push(tty);
	return IRQ_HANDLED;
}
示例#2
0
static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
{
	unsigned char	ch;
	struct scc_port *port = data;
	struct tty_struct *tty = port->gs.tty;
	SCC_ACCESS_INIT(port);

	ch = SCCread_NB(RX_DATA_REG);
	if (!tty) {
		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
		return;
	}
	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
		*tty->flip.char_buf_ptr = ch;
		*tty->flip.flag_buf_ptr = 0;
		tty->flip.flag_buf_ptr++;
		tty->flip.char_buf_ptr++;
		tty->flip.count++;
	}

	/* Check if another character is already ready; in that case, the
	 * spcond_int() function must be used, because this character may have an
	 * error condition that isn't signalled by the interrupt vector used!
	 */
	if (SCCread(INT_PENDING_REG) &
	    (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
		scc_spcond_int (irq, data, fp);
		return;
	}

	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);

	tty_flip_buffer_push(tty);
}