/* 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)); } }
/* 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)); } }