cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

jsm_cls.c (24272B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright 2003 Digi International (www.digi.com)
      4 *	Scott H Kilau <Scott_Kilau at digi dot com>
      5 *
      6 *	NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
      7 *
      8 *	This is shared code between Digi's CVS archive and the
      9 *	Linux Kernel sources.
     10 *	Changing the source just for reformatting needlessly breaks
     11 *	our CVS diff history.
     12 *
     13 *	Send any bug fixes/changes to:  Eng.Linux at digi dot com.
     14 *	Thank you.
     15 *
     16 */
     17
     18#include <linux/delay.h>	/* For udelay */
     19#include <linux/io.h>		/* For read[bwl]/write[bwl] */
     20#include <linux/serial.h>	/* For struct async_serial */
     21#include <linux/serial_reg.h>	/* For the various UART offsets */
     22#include <linux/pci.h>
     23#include <linux/tty.h>
     24
     25#include "jsm.h"	/* Driver main header file */
     26
     27static struct {
     28	unsigned int rate;
     29	unsigned int cflag;
     30} baud_rates[] = {
     31	{ 921600, B921600 },
     32	{ 460800, B460800 },
     33	{ 230400, B230400 },
     34	{ 115200, B115200 },
     35	{  57600, B57600  },
     36	{  38400, B38400  },
     37	{  19200, B19200  },
     38	{   9600, B9600   },
     39	{   4800, B4800   },
     40	{   2400, B2400   },
     41	{   1200, B1200   },
     42	{    600, B600    },
     43	{    300, B300    },
     44	{    200, B200    },
     45	{    150, B150    },
     46	{    134, B134    },
     47	{    110, B110    },
     48	{     75, B75     },
     49	{     50, B50     },
     50};
     51
     52static void cls_set_cts_flow_control(struct jsm_channel *ch)
     53{
     54	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
     55	u8 ier = readb(&ch->ch_cls_uart->ier);
     56	u8 isr_fcr = 0;
     57
     58	/*
     59	 * The Enhanced Register Set may only be accessed when
     60	 * the Line Control Register is set to 0xBFh.
     61	 */
     62	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
     63
     64	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
     65
     66	/* Turn on CTS flow control, turn off IXON flow control */
     67	isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR);
     68	isr_fcr &= ~(UART_EXAR654_EFR_IXON);
     69
     70	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
     71
     72	/* Write old LCR value back out, which turns enhanced access off */
     73	writeb(lcrb, &ch->ch_cls_uart->lcr);
     74
     75	/*
     76	 * Enable interrupts for CTS flow, turn off interrupts for
     77	 * received XOFF chars
     78	 */
     79	ier |= (UART_EXAR654_IER_CTSDSR);
     80	ier &= ~(UART_EXAR654_IER_XOFF);
     81	writeb(ier, &ch->ch_cls_uart->ier);
     82
     83	/* Set the usual FIFO values */
     84	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
     85
     86	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
     87		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
     88		&ch->ch_cls_uart->isr_fcr);
     89
     90	ch->ch_t_tlevel = 16;
     91}
     92
     93static void cls_set_ixon_flow_control(struct jsm_channel *ch)
     94{
     95	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
     96	u8 ier = readb(&ch->ch_cls_uart->ier);
     97	u8 isr_fcr = 0;
     98
     99	/*
    100	 * The Enhanced Register Set may only be accessed when
    101	 * the Line Control Register is set to 0xBFh.
    102	 */
    103	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    104
    105	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    106
    107	/* Turn on IXON flow control, turn off CTS flow control */
    108	isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON);
    109	isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR);
    110
    111	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    112
    113	/* Now set our current start/stop chars while in enhanced mode */
    114	writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
    115	writeb(0, &ch->ch_cls_uart->lsr);
    116	writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
    117	writeb(0, &ch->ch_cls_uart->spr);
    118
    119	/* Write old LCR value back out, which turns enhanced access off */
    120	writeb(lcrb, &ch->ch_cls_uart->lcr);
    121
    122	/*
    123	 * Disable interrupts for CTS flow, turn on interrupts for
    124	 * received XOFF chars
    125	 */
    126	ier &= ~(UART_EXAR654_IER_CTSDSR);
    127	ier |= (UART_EXAR654_IER_XOFF);
    128	writeb(ier, &ch->ch_cls_uart->ier);
    129
    130	/* Set the usual FIFO values */
    131	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
    132
    133	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
    134		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
    135		&ch->ch_cls_uart->isr_fcr);
    136}
    137
    138static void cls_set_no_output_flow_control(struct jsm_channel *ch)
    139{
    140	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
    141	u8 ier = readb(&ch->ch_cls_uart->ier);
    142	u8 isr_fcr = 0;
    143
    144	/*
    145	 * The Enhanced Register Set may only be accessed when
    146	 * the Line Control Register is set to 0xBFh.
    147	 */
    148	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    149
    150	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    151
    152	/* Turn off IXON flow control, turn off CTS flow control */
    153	isr_fcr |= (UART_EXAR654_EFR_ECB);
    154	isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON);
    155
    156	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    157
    158	/* Write old LCR value back out, which turns enhanced access off */
    159	writeb(lcrb, &ch->ch_cls_uart->lcr);
    160
    161	/*
    162	 * Disable interrupts for CTS flow, turn off interrupts for
    163	 * received XOFF chars
    164	 */
    165	ier &= ~(UART_EXAR654_IER_CTSDSR);
    166	ier &= ~(UART_EXAR654_IER_XOFF);
    167	writeb(ier, &ch->ch_cls_uart->ier);
    168
    169	/* Set the usual FIFO values */
    170	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
    171
    172	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
    173		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
    174		&ch->ch_cls_uart->isr_fcr);
    175
    176	ch->ch_r_watermark = 0;
    177	ch->ch_t_tlevel = 16;
    178	ch->ch_r_tlevel = 16;
    179}
    180
    181static void cls_set_rts_flow_control(struct jsm_channel *ch)
    182{
    183	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
    184	u8 ier = readb(&ch->ch_cls_uart->ier);
    185	u8 isr_fcr = 0;
    186
    187	/*
    188	 * The Enhanced Register Set may only be accessed when
    189	 * the Line Control Register is set to 0xBFh.
    190	 */
    191	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    192
    193	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    194
    195	/* Turn on RTS flow control, turn off IXOFF flow control */
    196	isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR);
    197	isr_fcr &= ~(UART_EXAR654_EFR_IXOFF);
    198
    199	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    200
    201	/* Write old LCR value back out, which turns enhanced access off */
    202	writeb(lcrb, &ch->ch_cls_uart->lcr);
    203
    204	/* Enable interrupts for RTS flow */
    205	ier |= (UART_EXAR654_IER_RTSDTR);
    206	writeb(ier, &ch->ch_cls_uart->ier);
    207
    208	/* Set the usual FIFO values */
    209	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
    210
    211	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
    212		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
    213		&ch->ch_cls_uart->isr_fcr);
    214
    215	ch->ch_r_watermark = 4;
    216	ch->ch_r_tlevel = 8;
    217}
    218
    219static void cls_set_ixoff_flow_control(struct jsm_channel *ch)
    220{
    221	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
    222	u8 ier = readb(&ch->ch_cls_uart->ier);
    223	u8 isr_fcr = 0;
    224
    225	/*
    226	 * The Enhanced Register Set may only be accessed when
    227	 * the Line Control Register is set to 0xBFh.
    228	 */
    229	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    230
    231	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    232
    233	/* Turn on IXOFF flow control, turn off RTS flow control */
    234	isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF);
    235	isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR);
    236
    237	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    238
    239	/* Now set our current start/stop chars while in enhanced mode */
    240	writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
    241	writeb(0, &ch->ch_cls_uart->lsr);
    242	writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
    243	writeb(0, &ch->ch_cls_uart->spr);
    244
    245	/* Write old LCR value back out, which turns enhanced access off */
    246	writeb(lcrb, &ch->ch_cls_uart->lcr);
    247
    248	/* Disable interrupts for RTS flow */
    249	ier &= ~(UART_EXAR654_IER_RTSDTR);
    250	writeb(ier, &ch->ch_cls_uart->ier);
    251
    252	/* Set the usual FIFO values */
    253	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
    254
    255	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
    256		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
    257		&ch->ch_cls_uart->isr_fcr);
    258}
    259
    260static void cls_set_no_input_flow_control(struct jsm_channel *ch)
    261{
    262	u8 lcrb = readb(&ch->ch_cls_uart->lcr);
    263	u8 ier = readb(&ch->ch_cls_uart->ier);
    264	u8 isr_fcr = 0;
    265
    266	/*
    267	 * The Enhanced Register Set may only be accessed when
    268	 * the Line Control Register is set to 0xBFh.
    269	 */
    270	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    271
    272	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    273
    274	/* Turn off IXOFF flow control, turn off RTS flow control */
    275	isr_fcr |= (UART_EXAR654_EFR_ECB);
    276	isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF);
    277
    278	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    279
    280	/* Write old LCR value back out, which turns enhanced access off */
    281	writeb(lcrb, &ch->ch_cls_uart->lcr);
    282
    283	/* Disable interrupts for RTS flow */
    284	ier &= ~(UART_EXAR654_IER_RTSDTR);
    285	writeb(ier, &ch->ch_cls_uart->ier);
    286
    287	/* Set the usual FIFO values */
    288	writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
    289
    290	writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
    291		UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
    292		&ch->ch_cls_uart->isr_fcr);
    293
    294	ch->ch_t_tlevel = 16;
    295	ch->ch_r_tlevel = 16;
    296}
    297
    298/*
    299 * cls_clear_break.
    300 * Determines whether its time to shut off break condition.
    301 *
    302 * No locks are assumed to be held when calling this function.
    303 * channel lock is held and released in this function.
    304 */
    305static void cls_clear_break(struct jsm_channel *ch)
    306{
    307	unsigned long lock_flags;
    308
    309	spin_lock_irqsave(&ch->ch_lock, lock_flags);
    310
    311	/* Turn break off, and unset some variables */
    312	if (ch->ch_flags & CH_BREAK_SENDING) {
    313		u8 temp = readb(&ch->ch_cls_uart->lcr);
    314
    315		writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
    316
    317		ch->ch_flags &= ~(CH_BREAK_SENDING);
    318		jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
    319			"clear break Finishing UART_LCR_SBC! finished: %lx\n",
    320			jiffies);
    321	}
    322	spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
    323}
    324
    325static void cls_disable_receiver(struct jsm_channel *ch)
    326{
    327	u8 tmp = readb(&ch->ch_cls_uart->ier);
    328
    329	tmp &= ~(UART_IER_RDI);
    330	writeb(tmp, &ch->ch_cls_uart->ier);
    331}
    332
    333static void cls_enable_receiver(struct jsm_channel *ch)
    334{
    335	u8 tmp = readb(&ch->ch_cls_uart->ier);
    336
    337	tmp |= (UART_IER_RDI);
    338	writeb(tmp, &ch->ch_cls_uart->ier);
    339}
    340
    341/* Make the UART raise any of the output signals we want up */
    342static void cls_assert_modem_signals(struct jsm_channel *ch)
    343{
    344	if (!ch)
    345		return;
    346
    347	writeb(ch->ch_mostat, &ch->ch_cls_uart->mcr);
    348}
    349
    350static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch)
    351{
    352	int qleft = 0;
    353	u8 linestatus;
    354	u8 error_mask = 0;
    355	u16 head;
    356	u16 tail;
    357	unsigned long flags;
    358
    359	if (!ch)
    360		return;
    361
    362	spin_lock_irqsave(&ch->ch_lock, flags);
    363
    364	/* cache head and tail of queue */
    365	head = ch->ch_r_head & RQUEUEMASK;
    366	tail = ch->ch_r_tail & RQUEUEMASK;
    367
    368	ch->ch_cached_lsr = 0;
    369
    370	/* Store how much space we have left in the queue */
    371	qleft = tail - head - 1;
    372	if (qleft < 0)
    373		qleft += RQUEUEMASK + 1;
    374
    375	/*
    376	 * Create a mask to determine whether we should
    377	 * insert the character (if any) into our queue.
    378	 */
    379	if (ch->ch_c_iflag & IGNBRK)
    380		error_mask |= UART_LSR_BI;
    381
    382	while (1) {
    383		/*
    384		 * Grab the linestatus register, we need to
    385		 * check to see if there is any data to read
    386		 */
    387		linestatus = readb(&ch->ch_cls_uart->lsr);
    388
    389		/* Break out if there is no data to fetch */
    390		if (!(linestatus & UART_LSR_DR))
    391			break;
    392
    393		/*
    394		 * Discard character if we are ignoring the error mask
    395		 * which in this case is the break signal.
    396		 */
    397		if (linestatus & error_mask)  {
    398			linestatus = 0;
    399			readb(&ch->ch_cls_uart->txrx);
    400			continue;
    401		}
    402
    403		/*
    404		 * If our queue is full, we have no choice but to drop some
    405		 * data. The assumption is that HWFLOW or SWFLOW should have
    406		 * stopped things way way before we got to this point.
    407		 *
    408		 * I decided that I wanted to ditch the oldest data first,
    409		 * I hope thats okay with everyone? Yes? Good.
    410		 */
    411		while (qleft < 1) {
    412			tail = (tail + 1) & RQUEUEMASK;
    413			ch->ch_r_tail = tail;
    414			ch->ch_err_overrun++;
    415			qleft++;
    416		}
    417
    418		ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
    419								 | UART_LSR_FE);
    420		ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
    421
    422		qleft--;
    423
    424		if (ch->ch_equeue[head] & UART_LSR_PE)
    425			ch->ch_err_parity++;
    426		if (ch->ch_equeue[head] & UART_LSR_BI)
    427			ch->ch_err_break++;
    428		if (ch->ch_equeue[head] & UART_LSR_FE)
    429			ch->ch_err_frame++;
    430
    431		/* Add to, and flip head if needed */
    432		head = (head + 1) & RQUEUEMASK;
    433		ch->ch_rxcount++;
    434	}
    435
    436	/*
    437	 * Write new final heads to channel structure.
    438	 */
    439	ch->ch_r_head = head & RQUEUEMASK;
    440	ch->ch_e_head = head & EQUEUEMASK;
    441
    442	spin_unlock_irqrestore(&ch->ch_lock, flags);
    443}
    444
    445static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch)
    446{
    447	u16 tail;
    448	int n;
    449	int qlen;
    450	u32 len_written = 0;
    451	struct circ_buf *circ;
    452
    453	if (!ch)
    454		return;
    455
    456	circ = &ch->uart_port.state->xmit;
    457
    458	/* No data to write to the UART */
    459	if (uart_circ_empty(circ))
    460		return;
    461
    462	/* If port is "stopped", don't send any data to the UART */
    463	if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_BREAK_SENDING))
    464		return;
    465
    466	/* We have to do it this way, because of the EXAR TXFIFO count bug. */
    467	if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
    468		return;
    469
    470	n = 32;
    471
    472	/* cache tail of queue */
    473	tail = circ->tail & (UART_XMIT_SIZE - 1);
    474	qlen = uart_circ_chars_pending(circ);
    475
    476	/* Find minimum of the FIFO space, versus queue length */
    477	n = min(n, qlen);
    478
    479	while (n > 0) {
    480		writeb(circ->buf[tail], &ch->ch_cls_uart->txrx);
    481		tail = (tail + 1) & (UART_XMIT_SIZE - 1);
    482		n--;
    483		ch->ch_txcount++;
    484		len_written++;
    485	}
    486
    487	/* Update the final tail */
    488	circ->tail = tail & (UART_XMIT_SIZE - 1);
    489
    490	if (len_written > ch->ch_t_tlevel)
    491		ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
    492
    493	if (uart_circ_empty(circ))
    494		uart_write_wakeup(&ch->uart_port);
    495}
    496
    497static void cls_parse_modem(struct jsm_channel *ch, u8 signals)
    498{
    499	u8 msignals = signals;
    500
    501	jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
    502		"neo_parse_modem: port: %d msignals: %x\n",
    503		ch->ch_portnum, msignals);
    504
    505	/*
    506	 * Scrub off lower bits.
    507	 * They signify delta's, which I don't care about
    508	 * Keep DDCD and DDSR though
    509	 */
    510	msignals &= 0xf8;
    511
    512	if (msignals & UART_MSR_DDCD)
    513		uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD);
    514	if (msignals & UART_MSR_DDSR)
    515		uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_CTS);
    516
    517	if (msignals & UART_MSR_DCD)
    518		ch->ch_mistat |= UART_MSR_DCD;
    519	else
    520		ch->ch_mistat &= ~UART_MSR_DCD;
    521
    522	if (msignals & UART_MSR_DSR)
    523		ch->ch_mistat |= UART_MSR_DSR;
    524	else
    525		ch->ch_mistat &= ~UART_MSR_DSR;
    526
    527	if (msignals & UART_MSR_RI)
    528		ch->ch_mistat |= UART_MSR_RI;
    529	else
    530		ch->ch_mistat &= ~UART_MSR_RI;
    531
    532	if (msignals & UART_MSR_CTS)
    533		ch->ch_mistat |= UART_MSR_CTS;
    534	else
    535		ch->ch_mistat &= ~UART_MSR_CTS;
    536
    537	jsm_dbg(MSIGS, &ch->ch_bd->pci_dev,
    538		"Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n",
    539		ch->ch_portnum,
    540		!!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR),
    541		!!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS),
    542		!!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_CTS),
    543		!!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DSR),
    544		!!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_RI),
    545		!!((ch->ch_mistat | ch->ch_mostat) & UART_MSR_DCD));
    546}
    547
    548/* Parse the ISR register for the specific port */
    549static inline void cls_parse_isr(struct jsm_board *brd, uint port)
    550{
    551	struct jsm_channel *ch;
    552	u8 isr = 0;
    553	unsigned long flags;
    554
    555	/*
    556	 * No need to verify board pointer, it was already
    557	 * verified in the interrupt routine.
    558	 */
    559
    560	if (port >= brd->nasync)
    561		return;
    562
    563	ch = brd->channels[port];
    564	if (!ch)
    565		return;
    566
    567	/* Here we try to figure out what caused the interrupt to happen */
    568	while (1) {
    569		isr = readb(&ch->ch_cls_uart->isr_fcr);
    570
    571		/* Bail if no pending interrupt on port */
    572		if (isr & UART_IIR_NO_INT)
    573			break;
    574
    575		/* Receive Interrupt pending */
    576		if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
    577			/* Read data from uart -> queue */
    578			cls_copy_data_from_uart_to_queue(ch);
    579			jsm_check_queue_flow_control(ch);
    580		}
    581
    582		/* Transmit Hold register empty pending */
    583		if (isr & UART_IIR_THRI) {
    584			/* Transfer data (if any) from Write Queue -> UART. */
    585			spin_lock_irqsave(&ch->ch_lock, flags);
    586			ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
    587			spin_unlock_irqrestore(&ch->ch_lock, flags);
    588			cls_copy_data_from_queue_to_uart(ch);
    589		}
    590
    591		/*
    592		 * CTS/RTS change of state:
    593		 * Don't need to do anything, the cls_parse_modem
    594		 * below will grab the updated modem signals.
    595		 */
    596
    597		/* Parse any modem signal changes */
    598		cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
    599	}
    600}
    601
    602/* Channel lock MUST be held before calling this function! */
    603static void cls_flush_uart_write(struct jsm_channel *ch)
    604{
    605	u8 tmp = 0;
    606	u8 i = 0;
    607
    608	if (!ch)
    609		return;
    610
    611	writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
    612						&ch->ch_cls_uart->isr_fcr);
    613
    614	for (i = 0; i < 10; i++) {
    615		/* Check to see if the UART feels it completely flushed FIFO */
    616		tmp = readb(&ch->ch_cls_uart->isr_fcr);
    617		if (tmp & UART_FCR_CLEAR_XMIT) {
    618			jsm_dbg(IOCTL, &ch->ch_bd->pci_dev,
    619				"Still flushing TX UART... i: %d\n", i);
    620			udelay(10);
    621		} else
    622			break;
    623	}
    624
    625	ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
    626}
    627
    628/* Channel lock MUST be held before calling this function! */
    629static void cls_flush_uart_read(struct jsm_channel *ch)
    630{
    631	if (!ch)
    632		return;
    633
    634	/*
    635	 * For complete POSIX compatibility, we should be purging the
    636	 * read FIFO in the UART here.
    637	 *
    638	 * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
    639	 * incorrectly flushes write data as well as just basically trashing the
    640	 * FIFO.
    641	 *
    642	 * Presumably, this is a bug in this UART.
    643	 */
    644
    645	udelay(10);
    646}
    647
    648static void cls_send_start_character(struct jsm_channel *ch)
    649{
    650	if (!ch)
    651		return;
    652
    653	if (ch->ch_startc != __DISABLED_CHAR) {
    654		ch->ch_xon_sends++;
    655		writeb(ch->ch_startc, &ch->ch_cls_uart->txrx);
    656	}
    657}
    658
    659static void cls_send_stop_character(struct jsm_channel *ch)
    660{
    661	if (!ch)
    662		return;
    663
    664	if (ch->ch_stopc != __DISABLED_CHAR) {
    665		ch->ch_xoff_sends++;
    666		writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx);
    667	}
    668}
    669
    670/*
    671 * cls_param()
    672 * Send any/all changes to the line to the UART.
    673 */
    674static void cls_param(struct jsm_channel *ch)
    675{
    676	u8 lcr = 0;
    677	u8 uart_lcr = 0;
    678	u8 ier = 0;
    679	u32 baud = 9600;
    680	int quot = 0;
    681	struct jsm_board *bd;
    682	int i;
    683	unsigned int cflag;
    684
    685	bd = ch->ch_bd;
    686	if (!bd)
    687		return;
    688
    689	/*
    690	 * If baud rate is zero, flush queues, and set mval to drop DTR.
    691	 */
    692	if ((ch->ch_c_cflag & CBAUD) == B0) {
    693		ch->ch_r_head = 0;
    694		ch->ch_r_tail = 0;
    695		ch->ch_e_head = 0;
    696		ch->ch_e_tail = 0;
    697
    698		cls_flush_uart_write(ch);
    699		cls_flush_uart_read(ch);
    700
    701		/* The baudrate is B0 so all modem lines are to be dropped. */
    702		ch->ch_flags |= (CH_BAUD0);
    703		ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
    704		cls_assert_modem_signals(ch);
    705		return;
    706	}
    707
    708	cflag = C_BAUD(ch->uart_port.state->port.tty);
    709	baud = 9600;
    710	for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
    711		if (baud_rates[i].cflag == cflag) {
    712			baud = baud_rates[i].rate;
    713			break;
    714		}
    715	}
    716
    717	if (ch->ch_flags & CH_BAUD0)
    718		ch->ch_flags &= ~(CH_BAUD0);
    719
    720	if (ch->ch_c_cflag & PARENB)
    721		lcr |= UART_LCR_PARITY;
    722
    723	if (!(ch->ch_c_cflag & PARODD))
    724		lcr |= UART_LCR_EPAR;
    725
    726	if (ch->ch_c_cflag & CMSPAR)
    727		lcr |= UART_LCR_SPAR;
    728
    729	if (ch->ch_c_cflag & CSTOPB)
    730		lcr |= UART_LCR_STOP;
    731
    732	lcr |= UART_LCR_WLEN(tty_get_char_size(ch->ch_c_cflag));
    733
    734	ier = readb(&ch->ch_cls_uart->ier);
    735	uart_lcr = readb(&ch->ch_cls_uart->lcr);
    736
    737	quot = ch->ch_bd->bd_dividend / baud;
    738
    739	if (quot != 0) {
    740		writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr);
    741		writeb((quot & 0xff), &ch->ch_cls_uart->txrx);
    742		writeb((quot >> 8), &ch->ch_cls_uart->ier);
    743		writeb(lcr, &ch->ch_cls_uart->lcr);
    744	}
    745
    746	if (uart_lcr != lcr)
    747		writeb(lcr, &ch->ch_cls_uart->lcr);
    748
    749	if (ch->ch_c_cflag & CREAD)
    750		ier |= (UART_IER_RDI | UART_IER_RLSI);
    751
    752	ier |= (UART_IER_THRI | UART_IER_MSI);
    753
    754	writeb(ier, &ch->ch_cls_uart->ier);
    755
    756	if (ch->ch_c_cflag & CRTSCTS)
    757		cls_set_cts_flow_control(ch);
    758	else if (ch->ch_c_iflag & IXON) {
    759		/*
    760		 * If start/stop is set to disable,
    761		 * then we should disable flow control.
    762		 */
    763		if ((ch->ch_startc == __DISABLED_CHAR) ||
    764			(ch->ch_stopc == __DISABLED_CHAR))
    765			cls_set_no_output_flow_control(ch);
    766		else
    767			cls_set_ixon_flow_control(ch);
    768	} else
    769		cls_set_no_output_flow_control(ch);
    770
    771	if (ch->ch_c_cflag & CRTSCTS)
    772		cls_set_rts_flow_control(ch);
    773	else if (ch->ch_c_iflag & IXOFF) {
    774		/*
    775		 * If start/stop is set to disable,
    776		 * then we should disable flow control.
    777		 */
    778		if ((ch->ch_startc == __DISABLED_CHAR) ||
    779			(ch->ch_stopc == __DISABLED_CHAR))
    780			cls_set_no_input_flow_control(ch);
    781		else
    782			cls_set_ixoff_flow_control(ch);
    783	} else
    784		cls_set_no_input_flow_control(ch);
    785
    786	cls_assert_modem_signals(ch);
    787
    788	/* get current status of the modem signals now */
    789	cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
    790}
    791
    792/*
    793 * cls_intr()
    794 *
    795 * Classic specific interrupt handler.
    796 */
    797static irqreturn_t cls_intr(int irq, void *voidbrd)
    798{
    799	struct jsm_board *brd = voidbrd;
    800	unsigned long lock_flags;
    801	unsigned char uart_poll;
    802	uint i = 0;
    803
    804	/* Lock out the slow poller from running on this board. */
    805	spin_lock_irqsave(&brd->bd_intr_lock, lock_flags);
    806
    807	/*
    808	 * Check the board's global interrupt offset to see if we
    809	 * acctually do have an interrupt pending on us.
    810	 */
    811	uart_poll = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET);
    812
    813	jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n",
    814		__FILE__, __LINE__, uart_poll);
    815
    816	if (!uart_poll) {
    817		jsm_dbg(INTR, &brd->pci_dev,
    818			"Kernel interrupted to me, but no pending interrupts...\n");
    819		spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
    820		return IRQ_NONE;
    821	}
    822
    823	/* At this point, we have at least SOMETHING to service, dig further. */
    824
    825	/* Parse each port to find out what caused the interrupt */
    826	for (i = 0; i < brd->nasync; i++)
    827		cls_parse_isr(brd, i);
    828
    829	spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags);
    830
    831	return IRQ_HANDLED;
    832}
    833
    834/* Inits UART */
    835static void cls_uart_init(struct jsm_channel *ch)
    836{
    837	unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
    838	unsigned char isr_fcr = 0;
    839
    840	writeb(0, &ch->ch_cls_uart->ier);
    841
    842	/*
    843	 * The Enhanced Register Set may only be accessed when
    844	 * the Line Control Register is set to 0xBFh.
    845	 */
    846	writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
    847
    848	isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
    849
    850	/* Turn on Enhanced/Extended controls */
    851	isr_fcr |= (UART_EXAR654_EFR_ECB);
    852
    853	writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
    854
    855	/* Write old LCR value back out, which turns enhanced access off */
    856	writeb(lcrb, &ch->ch_cls_uart->lcr);
    857
    858	/* Clear out UART and FIFO */
    859	readb(&ch->ch_cls_uart->txrx);
    860
    861	writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT),
    862						 &ch->ch_cls_uart->isr_fcr);
    863	udelay(10);
    864
    865	ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
    866
    867	readb(&ch->ch_cls_uart->lsr);
    868	readb(&ch->ch_cls_uart->msr);
    869}
    870
    871/*
    872 * Turns off UART.
    873 */
    874static void cls_uart_off(struct jsm_channel *ch)
    875{
    876	/* Stop all interrupts from accurring. */
    877	writeb(0, &ch->ch_cls_uart->ier);
    878}
    879
    880/*
    881 * cls_get_uarts_bytes_left.
    882 * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
    883 *
    884 * The channel lock MUST be held by the calling function.
    885 */
    886static u32 cls_get_uart_bytes_left(struct jsm_channel *ch)
    887{
    888	u8 left = 0;
    889	u8 lsr = readb(&ch->ch_cls_uart->lsr);
    890
    891	/* Determine whether the Transmitter is empty or not */
    892	if (!(lsr & UART_LSR_TEMT))
    893		left = 1;
    894	else {
    895		ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
    896		left = 0;
    897	}
    898
    899	return left;
    900}
    901
    902/*
    903 * cls_send_break.
    904 * Starts sending a break thru the UART.
    905 *
    906 * The channel lock MUST be held by the calling function.
    907 */
    908static void cls_send_break(struct jsm_channel *ch)
    909{
    910	/* Tell the UART to start sending the break */
    911	if (!(ch->ch_flags & CH_BREAK_SENDING)) {
    912		u8 temp = readb(&ch->ch_cls_uart->lcr);
    913
    914		writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr);
    915		ch->ch_flags |= (CH_BREAK_SENDING);
    916	}
    917}
    918
    919/*
    920 * cls_send_immediate_char.
    921 * Sends a specific character as soon as possible to the UART,
    922 * jumping over any bytes that might be in the write queue.
    923 *
    924 * The channel lock MUST be held by the calling function.
    925 */
    926static void cls_send_immediate_char(struct jsm_channel *ch, unsigned char c)
    927{
    928	writeb(c, &ch->ch_cls_uart->txrx);
    929}
    930
    931struct board_ops jsm_cls_ops = {
    932	.intr =				cls_intr,
    933	.uart_init =			cls_uart_init,
    934	.uart_off =			cls_uart_off,
    935	.param =			cls_param,
    936	.assert_modem_signals =		cls_assert_modem_signals,
    937	.flush_uart_write =		cls_flush_uart_write,
    938	.flush_uart_read =		cls_flush_uart_read,
    939	.disable_receiver =		cls_disable_receiver,
    940	.enable_receiver =		cls_enable_receiver,
    941	.send_break =			cls_send_break,
    942	.clear_break =			cls_clear_break,
    943	.send_start_character =		cls_send_start_character,
    944	.send_stop_character =		cls_send_stop_character,
    945	.copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
    946	.get_uart_bytes_left =		cls_get_uart_bytes_left,
    947	.send_immediate_char =		cls_send_immediate_char
    948};
    949