コード例 #1
0
/* Parse the ISR register for the specific port */
static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
{
    struct channel_t *ch;
    unsigned char isr = 0;
    unsigned long flags;

    /*
     * No need to verify board pointer, it was already
     * verified in the interrupt routine.
     */

    if (port >= brd->nasync)
        return;

    ch = brd->channels[port];
    if (ch->magic != DGNC_CHANNEL_MAGIC)
        return;

    /* Here we try to figure out what caused the interrupt to happen */
    while (1) {
        isr = readb(&ch->ch_cls_uart->isr_fcr);

        /* Bail if no pending interrupt on port */
        if (isr & UART_IIR_NO_INT)
            break;

        /* Receive Interrupt pending */
        if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
            /* Read data from uart -> queue */
            brd->intr_rx++;
            ch->ch_intr_rx++;
            cls_copy_data_from_uart_to_queue(ch);
            dgnc_check_queue_flow_control(ch);
        }

        /* Transmit Hold register empty pending */
        if (isr & UART_IIR_THRI) {
            /* Transfer data (if any) from Write Queue -> UART. */
            spin_lock_irqsave(&ch->ch_lock, flags);
            ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
            brd->intr_tx++;
            ch->ch_intr_tx++;
            spin_unlock_irqrestore(&ch->ch_lock, flags);
            cls_copy_data_from_queue_to_uart(ch);
        }

        /* CTS/RTS change of state */
        if (isr & UART_IIR_CTSRTS) {
            brd->intr_modem++;
            ch->ch_intr_modem++;
            /*
             * Don't need to do anything, the cls_parse_modem
             * below will grab the updated modem signals.
             */
        }

        /* Parse any modem signal changes */
        cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
    }
}
コード例 #2
0
ファイル: dgnc_cls.c プロジェクト: 7799/linux
/* Parse the ISR register for the specific port */
static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
{
	struct channel_t *ch;
	uchar isr = 0;
	ulong lock_flags;

	/*
	 * No need to verify board pointer, it was already
	 * verified in the interrupt routine.
	 */

	if (port > brd->nasync)
		return;

	ch = brd->channels[port];
	if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
		return;

	/* Here we try to figure out what caused the interrupt to happen */
	while (1) {

		isr = readb(&ch->ch_cls_uart->isr_fcr);

		/* Bail if no pending interrupt on port */
		if (isr & UART_IIR_NO_INT)
			break;

		DPR_INTR(("%s:%d port: %x isr: %x\n", __FILE__, __LINE__,
								 port, isr));

		/* Receive Interrupt pending */
		if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
			/* Read data from uart -> queue */
			brd->intr_rx++;
			ch->ch_intr_rx++;
			cls_copy_data_from_uart_to_queue(ch);
			dgnc_check_queue_flow_control(ch);
		}

		/* Transmit Hold register empty pending */
		if (isr & UART_IIR_THRI) {
			/* Transfer data (if any) from Write Queue -> UART. */
			DGNC_LOCK(ch->ch_lock, lock_flags);
			ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
			brd->intr_tx++;
			ch->ch_intr_tx++;
			DGNC_UNLOCK(ch->ch_lock, lock_flags);
			cls_copy_data_from_queue_to_uart(ch);
		}

		/* Received Xoff signal/Special character */
		if (isr & UART_IIR_XOFF)
			/* Empty */

		/* CTS/RTS change of state */
		if (isr & UART_IIR_CTSRTS) {
			brd->intr_modem++;
			ch->ch_intr_modem++;
			/*
			 * Don't need to do anything, the cls_parse_modem
			 * below will grab the updated modem signals.
			 */
		}

		/* Parse any modem signal changes */
		DPR_INTR(("MOD_STAT: sending to parse_modem_sigs\n"));
		cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
	}
}