]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/dgnc/dgnc_cls.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / dgnc / dgnc_cls.c
CommitLineData
0b99d589
LL
1/*
2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
5ca46fd4 9 *
0b99d589 10 * This program is distributed in the hope that it will be useful,
5ca46fd4
LL
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
0b99d589 13 * PURPOSE. See the GNU General Public License for more details.
0b99d589
LL
14 */
15
16#include <linux/kernel.h>
0b99d589
LL
17#include <linux/sched.h> /* For jiffies, task states */
18#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
19#include <linux/delay.h> /* For udelay */
4a75ffa8 20#include <linux/io.h> /* For read[bwl]/write[bwl] */
0b99d589
LL
21#include <linux/serial.h> /* For struct async_serial */
22#include <linux/serial_reg.h> /* For the various UART offsets */
23#include <linux/pci.h>
24
25#include "dgnc_driver.h" /* Driver main header file */
26#include "dgnc_cls.h"
27#include "dgnc_tty.h"
0b99d589 28
03425f55 29static inline void cls_parse_isr(struct dgnc_board *brd, uint port);
0b99d589
LL
30static inline void cls_clear_break(struct channel_t *ch, int force);
31static inline void cls_set_cts_flow_control(struct channel_t *ch);
32static inline void cls_set_rts_flow_control(struct channel_t *ch);
33static inline void cls_set_ixon_flow_control(struct channel_t *ch);
34static inline void cls_set_ixoff_flow_control(struct channel_t *ch);
35static inline void cls_set_no_output_flow_control(struct channel_t *ch);
36static inline void cls_set_no_input_flow_control(struct channel_t *ch);
446393e9 37static void cls_parse_modem(struct channel_t *ch, unsigned char signals);
0b99d589 38static void cls_tasklet(unsigned long data);
03425f55 39static void cls_vpd(struct dgnc_board *brd);
0b99d589
LL
40static void cls_uart_init(struct channel_t *ch);
41static void cls_uart_off(struct channel_t *ch);
42static int cls_drain(struct tty_struct *tty, uint seconds);
43static void cls_param(struct tty_struct *tty);
44static void cls_assert_modem_signals(struct channel_t *ch);
45static void cls_flush_uart_write(struct channel_t *ch);
46static void cls_flush_uart_read(struct channel_t *ch);
47static void cls_disable_receiver(struct channel_t *ch);
48static void cls_enable_receiver(struct channel_t *ch);
49static void cls_send_break(struct channel_t *ch, int msecs);
50static void cls_send_start_character(struct channel_t *ch);
51static void cls_send_stop_character(struct channel_t *ch);
52static void cls_copy_data_from_uart_to_queue(struct channel_t *ch);
53static void cls_copy_data_from_queue_to_uart(struct channel_t *ch);
54static uint cls_get_uart_bytes_left(struct channel_t *ch);
55static void cls_send_immediate_char(struct channel_t *ch, unsigned char);
56static irqreturn_t cls_intr(int irq, void *voidbrd);
57
58struct board_ops dgnc_cls_ops = {
59 .tasklet = cls_tasklet,
60 .intr = cls_intr,
61 .uart_init = cls_uart_init,
62 .uart_off = cls_uart_off,
63 .drain = cls_drain,
64 .param = cls_param,
65 .vpd = cls_vpd,
66 .assert_modem_signals = cls_assert_modem_signals,
67 .flush_uart_write = cls_flush_uart_write,
68 .flush_uart_read = cls_flush_uart_read,
69 .disable_receiver = cls_disable_receiver,
70 .enable_receiver = cls_enable_receiver,
71 .send_break = cls_send_break,
72 .send_start_character = cls_send_start_character,
73 .send_stop_character = cls_send_stop_character,
74 .copy_data_from_queue_to_uart = cls_copy_data_from_queue_to_uart,
75 .get_uart_bytes_left = cls_get_uart_bytes_left,
76 .send_immediate_char = cls_send_immediate_char
77};
78
0b99d589
LL
79static inline void cls_set_cts_flow_control(struct channel_t *ch)
80{
446393e9
EA
81 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
82 unsigned char ier = readb(&ch->ch_cls_uart->ier);
83 unsigned char isr_fcr = 0;
0b99d589 84
0b99d589
LL
85 /*
86 * The Enhanced Register Set may only be accessed when
87 * the Line Control Register is set to 0xBFh.
88 */
89 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
90
91 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 92
0b99d589
LL
93 /* Turn on CTS flow control, turn off IXON flow control */
94 isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_CTSDSR);
95 isr_fcr &= ~(UART_EXAR654_EFR_IXON);
96
97 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
98
99 /* Write old LCR value back out, which turns enhanced access off */
100 writeb(lcrb, &ch->ch_cls_uart->lcr);
101
cb3714a6 102 /*
103 * Enable interrupts for CTS flow, turn off interrupts for
104 * received XOFF chars
105 */
0b99d589
LL
106 ier |= (UART_EXAR654_IER_CTSDSR);
107 ier &= ~(UART_EXAR654_IER_XOFF);
108 writeb(ier, &ch->ch_cls_uart->ier);
109
110 /* Set the usual FIFO values */
111 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
112
113 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
114 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
115 &ch->ch_cls_uart->isr_fcr);
116
117 ch->ch_t_tlevel = 16;
0b99d589
LL
118}
119
0b99d589
LL
120static inline void cls_set_ixon_flow_control(struct channel_t *ch)
121{
446393e9
EA
122 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
123 unsigned char ier = readb(&ch->ch_cls_uart->ier);
124 unsigned char isr_fcr = 0;
0b99d589 125
0b99d589
LL
126 /*
127 * The Enhanced Register Set may only be accessed when
128 * the Line Control Register is set to 0xBFh.
129 */
130 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
131
132 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 133
0b99d589
LL
134 /* Turn on IXON flow control, turn off CTS flow control */
135 isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXON);
136 isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR);
137
138 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
139
140 /* Now set our current start/stop chars while in enhanced mode */
141 writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
142 writeb(0, &ch->ch_cls_uart->lsr);
143 writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
144 writeb(0, &ch->ch_cls_uart->spr);
145
146 /* Write old LCR value back out, which turns enhanced access off */
147 writeb(lcrb, &ch->ch_cls_uart->lcr);
148
cb3714a6 149 /*
150 * Disable interrupts for CTS flow, turn on interrupts for
151 * received XOFF chars
152 */
0b99d589
LL
153 ier &= ~(UART_EXAR654_IER_CTSDSR);
154 ier |= (UART_EXAR654_IER_XOFF);
155 writeb(ier, &ch->ch_cls_uart->ier);
156
157 /* Set the usual FIFO values */
158 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
159
160 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
161 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
162 &ch->ch_cls_uart->isr_fcr);
0b99d589
LL
163}
164
0b99d589
LL
165static inline void cls_set_no_output_flow_control(struct channel_t *ch)
166{
446393e9
EA
167 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
168 unsigned char ier = readb(&ch->ch_cls_uart->ier);
169 unsigned char isr_fcr = 0;
0b99d589 170
0b99d589
LL
171 /*
172 * The Enhanced Register Set may only be accessed when
173 * the Line Control Register is set to 0xBFh.
174 */
175 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
176
177 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 178
0b99d589
LL
179 /* Turn off IXON flow control, turn off CTS flow control */
180 isr_fcr |= (UART_EXAR654_EFR_ECB);
181 isr_fcr &= ~(UART_EXAR654_EFR_CTSDSR | UART_EXAR654_EFR_IXON);
182
183 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
184
185 /* Write old LCR value back out, which turns enhanced access off */
186 writeb(lcrb, &ch->ch_cls_uart->lcr);
187
cb3714a6 188 /*
189 * Disable interrupts for CTS flow, turn off interrupts for
190 * received XOFF chars
191 */
0b99d589
LL
192 ier &= ~(UART_EXAR654_IER_CTSDSR);
193 ier &= ~(UART_EXAR654_IER_XOFF);
194 writeb(ier, &ch->ch_cls_uart->ier);
195
196 /* Set the usual FIFO values */
197 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
198
199 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
200 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
201 &ch->ch_cls_uart->isr_fcr);
202
203 ch->ch_r_watermark = 0;
cb3714a6 204 ch->ch_t_tlevel = 16;
205 ch->ch_r_tlevel = 16;
0b99d589
LL
206}
207
0b99d589
LL
208static inline void cls_set_rts_flow_control(struct channel_t *ch)
209{
446393e9
EA
210 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
211 unsigned char ier = readb(&ch->ch_cls_uart->ier);
212 unsigned char isr_fcr = 0;
0b99d589 213
0b99d589
LL
214 /*
215 * The Enhanced Register Set may only be accessed when
216 * the Line Control Register is set to 0xBFh.
217 */
218 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
219
220 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 221
0b99d589
LL
222 /* Turn on RTS flow control, turn off IXOFF flow control */
223 isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_RTSDTR);
224 isr_fcr &= ~(UART_EXAR654_EFR_IXOFF);
225
226 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
227
228 /* Write old LCR value back out, which turns enhanced access off */
229 writeb(lcrb, &ch->ch_cls_uart->lcr);
230
231 /* Enable interrupts for RTS flow */
232 ier |= (UART_EXAR654_IER_RTSDTR);
233 writeb(ier, &ch->ch_cls_uart->ier);
234
235 /* Set the usual FIFO values */
236 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
237
238 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_56 |
239 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
240 &ch->ch_cls_uart->isr_fcr);
241
0b99d589
LL
242 ch->ch_r_watermark = 4;
243 ch->ch_r_tlevel = 8;
0b99d589
LL
244}
245
0b99d589
LL
246static inline void cls_set_ixoff_flow_control(struct channel_t *ch)
247{
446393e9
EA
248 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
249 unsigned char ier = readb(&ch->ch_cls_uart->ier);
250 unsigned char isr_fcr = 0;
0b99d589 251
0b99d589
LL
252 /*
253 * The Enhanced Register Set may only be accessed when
254 * the Line Control Register is set to 0xBFh.
255 */
256 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
257
258 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 259
0b99d589
LL
260 /* Turn on IXOFF flow control, turn off RTS flow control */
261 isr_fcr |= (UART_EXAR654_EFR_ECB | UART_EXAR654_EFR_IXOFF);
262 isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR);
263
264 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
265
266 /* Now set our current start/stop chars while in enhanced mode */
267 writeb(ch->ch_startc, &ch->ch_cls_uart->mcr);
268 writeb(0, &ch->ch_cls_uart->lsr);
269 writeb(ch->ch_stopc, &ch->ch_cls_uart->msr);
270 writeb(0, &ch->ch_cls_uart->spr);
271
272 /* Write old LCR value back out, which turns enhanced access off */
273 writeb(lcrb, &ch->ch_cls_uart->lcr);
274
275 /* Disable interrupts for RTS flow */
276 ier &= ~(UART_EXAR654_IER_RTSDTR);
277 writeb(ier, &ch->ch_cls_uart->ier);
278
279 /* Set the usual FIFO values */
280 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
281
282 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
283 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
284 &ch->ch_cls_uart->isr_fcr);
0b99d589
LL
285}
286
0b99d589
LL
287static inline void cls_set_no_input_flow_control(struct channel_t *ch)
288{
446393e9
EA
289 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
290 unsigned char ier = readb(&ch->ch_cls_uart->ier);
291 unsigned char isr_fcr = 0;
0b99d589 292
0b99d589
LL
293 /*
294 * The Enhanced Register Set may only be accessed when
295 * the Line Control Register is set to 0xBFh.
296 */
297 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
298
299 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 300
0b99d589
LL
301 /* Turn off IXOFF flow control, turn off RTS flow control */
302 isr_fcr |= (UART_EXAR654_EFR_ECB);
303 isr_fcr &= ~(UART_EXAR654_EFR_RTSDTR | UART_EXAR654_EFR_IXOFF);
304
305 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
306
307 /* Write old LCR value back out, which turns enhanced access off */
308 writeb(lcrb, &ch->ch_cls_uart->lcr);
309
310 /* Disable interrupts for RTS flow */
311 ier &= ~(UART_EXAR654_IER_RTSDTR);
312 writeb(ier, &ch->ch_cls_uart->ier);
313
314 /* Set the usual FIFO values */
315 writeb((UART_FCR_ENABLE_FIFO), &ch->ch_cls_uart->isr_fcr);
316
317 writeb((UART_FCR_ENABLE_FIFO | UART_16654_FCR_RXTRIGGER_16 |
318 UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR),
319 &ch->ch_cls_uart->isr_fcr);
320
cb3714a6 321 ch->ch_t_tlevel = 16;
322 ch->ch_r_tlevel = 16;
0b99d589
LL
323}
324
0b99d589
LL
325/*
326 * cls_clear_break.
327 * Determines whether its time to shut off break condition.
328 *
329 * No locks are assumed to be held when calling this function.
330 * channel lock is held and released in this function.
331 */
332static inline void cls_clear_break(struct channel_t *ch, int force)
333{
707505b5 334 unsigned long flags;
0b99d589
LL
335
336 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
337 return;
338
707505b5 339 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589
LL
340
341 /* Bail if we aren't currently sending a break. */
342 if (!ch->ch_stop_sending_break) {
707505b5 343 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
344 return;
345 }
346
347 /* Turn break off, and unset some variables */
348 if (ch->ch_flags & CH_BREAK_SENDING) {
f0dcc9fa 349 if (time_after(jiffies, ch->ch_stop_sending_break) || force) {
446393e9 350 unsigned char temp = readb(&ch->ch_cls_uart->lcr);
8aa5d0d8 351
cb3714a6 352 writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
0b99d589
LL
353 ch->ch_flags &= ~(CH_BREAK_SENDING);
354 ch->ch_stop_sending_break = 0;
0b99d589
LL
355 }
356 }
707505b5 357 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
358}
359
0b99d589 360/* Parse the ISR register for the specific port */
03425f55 361static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
0b99d589
LL
362{
363 struct channel_t *ch;
446393e9 364 unsigned char isr = 0;
707505b5 365 unsigned long flags;
0b99d589
LL
366
367 /*
368 * No need to verify board pointer, it was already
369 * verified in the interrupt routine.
370 */
371
4bef52f3 372 if (port >= brd->nasync)
0b99d589
LL
373 return;
374
375 ch = brd->channels[port];
071494d8 376 if (ch->magic != DGNC_CHANNEL_MAGIC)
0b99d589
LL
377 return;
378
379 /* Here we try to figure out what caused the interrupt to happen */
380 while (1) {
0b99d589
LL
381 isr = readb(&ch->ch_cls_uart->isr_fcr);
382
383 /* Bail if no pending interrupt on port */
3d47910b 384 if (isr & UART_IIR_NO_INT)
0b99d589 385 break;
0b99d589 386
0b99d589
LL
387 /* Receive Interrupt pending */
388 if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) {
389 /* Read data from uart -> queue */
390 brd->intr_rx++;
391 ch->ch_intr_rx++;
392 cls_copy_data_from_uart_to_queue(ch);
393 dgnc_check_queue_flow_control(ch);
394 }
395
396 /* Transmit Hold register empty pending */
397 if (isr & UART_IIR_THRI) {
398 /* Transfer data (if any) from Write Queue -> UART. */
707505b5 399 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589
LL
400 ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
401 brd->intr_tx++;
402 ch->ch_intr_tx++;
707505b5 403 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
404 cls_copy_data_from_queue_to_uart(ch);
405 }
406
0b99d589
LL
407 /* CTS/RTS change of state */
408 if (isr & UART_IIR_CTSRTS) {
409 brd->intr_modem++;
410 ch->ch_intr_modem++;
411 /*
412 * Don't need to do anything, the cls_parse_modem
413 * below will grab the updated modem signals.
414 */
415 }
416
417 /* Parse any modem signal changes */
0b99d589
LL
418 cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
419 }
420}
421
0b99d589
LL
422/*
423 * cls_param()
424 * Send any/all changes to the line to the UART.
425 */
426static void cls_param(struct tty_struct *tty)
427{
446393e9
EA
428 unsigned char lcr = 0;
429 unsigned char uart_lcr = 0;
430 unsigned char ier = 0;
431 unsigned char uart_ier = 0;
cb3714a6 432 uint baud = 9600;
0b99d589 433 int quot = 0;
cb3714a6 434 struct dgnc_board *bd;
0b99d589 435 struct channel_t *ch;
cb3714a6 436 struct un_t *un;
0b99d589 437
3d47910b 438 if (!tty || tty->magic != TTY_MAGIC)
0b99d589 439 return;
0b99d589 440
6f418259 441 un = (struct un_t *)tty->driver_data;
3d47910b 442 if (!un || un->magic != DGNC_UNIT_MAGIC)
0b99d589 443 return;
0b99d589 444
5ca46fd4 445 ch = un->un_ch;
3d47910b 446 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
0b99d589 447 return;
0b99d589
LL
448
449 bd = ch->ch_bd;
3d47910b 450 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
0b99d589 451 return;
0b99d589 452
0b99d589
LL
453 /*
454 * If baud rate is zero, flush queues, and set mval to drop DTR.
455 */
456 if ((ch->ch_c_cflag & (CBAUD)) == 0) {
587abd7b
SL
457 ch->ch_r_head = 0;
458 ch->ch_r_tail = 0;
459 ch->ch_e_head = 0;
460 ch->ch_e_tail = 0;
461 ch->ch_w_head = 0;
462 ch->ch_w_tail = 0;
0b99d589
LL
463
464 cls_flush_uart_write(ch);
cb3714a6 465 cls_flush_uart_read(ch);
0b99d589
LL
466
467 /* The baudrate is B0 so all modem lines are to be dropped. */
468 ch->ch_flags |= (CH_BAUD0);
469 ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR);
470 cls_assert_modem_signals(ch);
471 ch->ch_old_baud = 0;
472 return;
473 } else if (ch->ch_custom_speed) {
0b99d589
LL
474 baud = ch->ch_custom_speed;
475 /* Handle transition from B0 */
476 if (ch->ch_flags & CH_BAUD0) {
477 ch->ch_flags &= ~(CH_BAUD0);
478
479 /*
480 * Bring back up RTS and DTR...
481 * Also handle RTS or DTR toggle if set.
482 */
483 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
484 ch->ch_mostat |= (UART_MCR_RTS);
485 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
486 ch->ch_mostat |= (UART_MCR_DTR);
487 }
488
489 } else {
490 int iindex = 0;
491 int jindex = 0;
492
493 ulong bauds[4][16] = {
494 { /* slowbaud */
495 0, 50, 75, 110,
496 134, 150, 200, 300,
497 600, 1200, 1800, 2400,
498 4800, 9600, 19200, 38400 },
499 { /* slowbaud & CBAUDEX */
500 0, 57600, 115200, 230400,
501 460800, 150, 200, 921600,
502 600, 1200, 1800, 2400,
503 4800, 9600, 19200, 38400 },
504 { /* fastbaud */
505 0, 57600, 76800, 115200,
506 131657, 153600, 230400, 460800,
507 921600, 1200, 1800, 2400,
508 4800, 9600, 19200, 38400 },
509 { /* fastbaud & CBAUDEX */
510 0, 57600, 115200, 230400,
511 460800, 150, 200, 921600,
512 600, 1200, 1800, 2400,
513 4800, 9600, 19200, 38400 }
514 };
515
cb3714a6 516 /*
517 * Only use the TXPrint baud rate if the terminal
518 * unit is NOT open
519 */
520 if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
e352d3f1 521 (un->un_type == DGNC_PRINT))
0b99d589
LL
522 baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
523 else
524 baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
525
526 if (ch->ch_c_cflag & CBAUDEX)
527 iindex = 1;
528
529 if (ch->ch_digi.digi_flags & DIGI_FAST)
530 iindex += 2;
531
532 jindex = baud;
533
cb3714a6 534 if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) &&
e352d3f1 535 (jindex < 16)) {
5ca46fd4 536 baud = bauds[iindex][jindex];
0b99d589 537 } else {
0b99d589
LL
538 baud = 0;
539 }
540
541 if (baud == 0)
542 baud = 9600;
543
544 /* Handle transition from B0 */
545 if (ch->ch_flags & CH_BAUD0) {
546 ch->ch_flags &= ~(CH_BAUD0);
547
548 /*
549 * Bring back up RTS and DTR...
550 * Also handle RTS or DTR toggle if set.
551 */
552 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
553 ch->ch_mostat |= (UART_MCR_RTS);
554 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
555 ch->ch_mostat |= (UART_MCR_DTR);
556 }
557 }
558
cb3714a6 559 if (ch->ch_c_cflag & PARENB)
0b99d589 560 lcr |= UART_LCR_PARITY;
0b99d589 561
cb3714a6 562 if (!(ch->ch_c_cflag & PARODD))
0b99d589 563 lcr |= UART_LCR_EPAR;
0b99d589
LL
564
565 /*
566 * Not all platforms support mark/space parity,
567 * so this will hide behind an ifdef.
568 */
569#ifdef CMSPAR
570 if (ch->ch_c_cflag & CMSPAR)
5ca46fd4 571 lcr |= UART_LCR_SPAR;
0b99d589
LL
572#endif
573
574 if (ch->ch_c_cflag & CSTOPB)
575 lcr |= UART_LCR_STOP;
576
577 switch (ch->ch_c_cflag & CSIZE) {
578 case CS5:
579 lcr |= UART_LCR_WLEN5;
580 break;
581 case CS6:
582 lcr |= UART_LCR_WLEN6;
583 break;
584 case CS7:
585 lcr |= UART_LCR_WLEN7;
586 break;
587 case CS8:
588 default:
589 lcr |= UART_LCR_WLEN8;
590 break;
591 }
592
587abd7b
SL
593 uart_ier = readb(&ch->ch_cls_uart->ier);
594 ier = uart_ier;
0b99d589
LL
595 uart_lcr = readb(&ch->ch_cls_uart->lcr);
596
597 if (baud == 0)
598 baud = 9600;
599
600 quot = ch->ch_bd->bd_dividend / baud;
601
602 if (quot != 0 && ch->ch_old_baud != baud) {
603 ch->ch_old_baud = baud;
604 writeb(UART_LCR_DLAB, &ch->ch_cls_uart->lcr);
605 writeb((quot & 0xff), &ch->ch_cls_uart->txrx);
606 writeb((quot >> 8), &ch->ch_cls_uart->ier);
607 writeb(lcr, &ch->ch_cls_uart->lcr);
cb3714a6 608 }
0b99d589
LL
609
610 if (uart_lcr != lcr)
611 writeb(lcr, &ch->ch_cls_uart->lcr);
612
cb3714a6 613 if (ch->ch_c_cflag & CREAD)
0b99d589 614 ier |= (UART_IER_RDI | UART_IER_RLSI);
cb3714a6 615 else
0b99d589 616 ier &= ~(UART_IER_RDI | UART_IER_RLSI);
0b99d589
LL
617
618 /*
619 * Have the UART interrupt on modem signal changes ONLY when
620 * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
621 */
cb3714a6 622 if ((ch->ch_digi.digi_flags & CTSPACE) ||
c76d294f
CM
623 (ch->ch_digi.digi_flags & RTSPACE) ||
624 (ch->ch_c_cflag & CRTSCTS) ||
625 !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
626 !(ch->ch_c_cflag & CLOCAL))
627 ier |= UART_IER_MSI;
cb3714a6 628 else
c76d294f 629 ier &= ~UART_IER_MSI;
0b99d589
LL
630
631 ier |= UART_IER_THRI;
632
633 if (ier != uart_ier)
634 writeb(ier, &ch->ch_cls_uart->ier);
635
636 if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
637 cls_set_cts_flow_control(ch);
cb3714a6 638 } else if (ch->ch_c_iflag & IXON) {
639 /*
640 * If start/stop is set to disable, then we should
641 * disable flow control
642 */
643 if ((ch->ch_startc == _POSIX_VDISABLE) ||
e352d3f1 644 (ch->ch_stopc == _POSIX_VDISABLE))
0b99d589
LL
645 cls_set_no_output_flow_control(ch);
646 else
647 cls_set_ixon_flow_control(ch);
cb3714a6 648 } else {
0b99d589
LL
649 cls_set_no_output_flow_control(ch);
650 }
651
652 if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
653 cls_set_rts_flow_control(ch);
cb3714a6 654 } else if (ch->ch_c_iflag & IXOFF) {
655 /*
656 * If start/stop is set to disable, then we should disable
657 * flow control
658 */
659 if ((ch->ch_startc == _POSIX_VDISABLE) ||
e352d3f1 660 (ch->ch_stopc == _POSIX_VDISABLE))
0b99d589
LL
661 cls_set_no_input_flow_control(ch);
662 else
663 cls_set_ixoff_flow_control(ch);
cb3714a6 664 } else {
0b99d589
LL
665 cls_set_no_input_flow_control(ch);
666 }
667
668 cls_assert_modem_signals(ch);
669
670 /* Get current status of the modem signals now */
671 cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr));
672}
673
0b99d589
LL
674/*
675 * Our board poller function.
676 */
677static void cls_tasklet(unsigned long data)
678{
6f418259 679 struct dgnc_board *bd = (struct dgnc_board *)data;
0b99d589 680 struct channel_t *ch;
707505b5 681 unsigned long flags;
0b99d589
LL
682 int i;
683 int state = 0;
684 int ports = 0;
685
1f26adc9 686 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
0b99d589 687 return;
0b99d589
LL
688
689 /* Cache a couple board values */
707505b5 690 spin_lock_irqsave(&bd->bd_lock, flags);
0b99d589
LL
691 state = bd->state;
692 ports = bd->nasync;
707505b5 693 spin_unlock_irqrestore(&bd->bd_lock, flags);
0b99d589
LL
694
695 /*
696 * Do NOT allow the interrupt routine to read the intr registers
697 * Until we release this lock.
698 */
707505b5 699 spin_lock_irqsave(&bd->bd_intr_lock, flags);
0b99d589
LL
700
701 /*
702 * If board is ready, parse deeper to see if there is anything to do.
703 */
704 if ((state == BOARD_READY) && (ports > 0)) {
0b99d589
LL
705 /* Loop on each port */
706 for (i = 0; i < ports; i++) {
707 ch = bd->channels[i];
0b99d589
LL
708
709 /*
710 * NOTE: Remember you CANNOT hold any channel
711 * locks when calling input.
712 * During input processing, its possible we
713 * will call ld, which might do callbacks back
714 * into us.
715 */
716 dgnc_input(ch);
717
718 /*
719 * Channel lock is grabbed and then released
720 * inside this routine.
721 */
722 cls_copy_data_from_queue_to_uart(ch);
723 dgnc_wakeup_writes(ch);
724
725 /*
726 * Check carrier function.
727 */
728 dgnc_carrier(ch);
729
730 /*
731 * The timing check of turning off the break is done
732 * inside clear_break()
733 */
734 if (ch->ch_stop_sending_break)
735 cls_clear_break(ch, 0);
736 }
737 }
738
707505b5 739 spin_unlock_irqrestore(&bd->bd_intr_lock, flags);
0b99d589
LL
740}
741
0b99d589
LL
742/*
743 * cls_intr()
744 *
745 * Classic specific interrupt handler.
746 */
747static irqreturn_t cls_intr(int irq, void *voidbrd)
748{
fc33bd29 749 struct dgnc_board *brd = voidbrd;
0b99d589 750 uint i = 0;
446393e9 751 unsigned char poll_reg;
707505b5 752 unsigned long flags;
0b99d589 753
0b99d589 754 /*
1f26adc9
RD
755 * Check to make sure it didn't receive interrupt with a null board
756 * associated or a board pointer that wasn't ours.
0b99d589 757 */
1f26adc9 758 if (!brd || brd->magic != DGNC_BOARD_MAGIC)
0b99d589 759 return IRQ_NONE;
0b99d589 760
707505b5 761 spin_lock_irqsave(&brd->bd_intr_lock, flags);
0b99d589
LL
762
763 brd->intr_count++;
764
765 /*
5ca46fd4 766 * Check the board's global interrupt offset to see if we
0b99d589
LL
767 * we actually do have an interrupt pending for us.
768 */
769 poll_reg = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET);
770
771 /* If 0, no interrupts pending */
772 if (!poll_reg) {
707505b5 773 spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
0b99d589
LL
774 return IRQ_NONE;
775 }
776
0b99d589 777 /* Parse each port to find out what caused the interrupt */
cb3714a6 778 for (i = 0; i < brd->nasync; i++)
0b99d589 779 cls_parse_isr(brd, i);
0b99d589
LL
780
781 /*
782 * Schedule tasklet to more in-depth servicing at a better time.
783 */
784 tasklet_schedule(&brd->helper_tasklet);
785
707505b5 786 spin_unlock_irqrestore(&brd->bd_intr_lock, flags);
0b99d589 787
0b99d589
LL
788 return IRQ_HANDLED;
789}
790
0b99d589
LL
791static void cls_disable_receiver(struct channel_t *ch)
792{
446393e9 793 unsigned char tmp = readb(&ch->ch_cls_uart->ier);
8aa5d0d8 794
0b99d589
LL
795 tmp &= ~(UART_IER_RDI);
796 writeb(tmp, &ch->ch_cls_uart->ier);
797}
798
0b99d589
LL
799static void cls_enable_receiver(struct channel_t *ch)
800{
446393e9 801 unsigned char tmp = readb(&ch->ch_cls_uart->ier);
8aa5d0d8 802
0b99d589
LL
803 tmp |= (UART_IER_RDI);
804 writeb(tmp, &ch->ch_cls_uart->ier);
805}
806
0b99d589
LL
807static void cls_copy_data_from_uart_to_queue(struct channel_t *ch)
808{
cb3714a6 809 int qleft = 0;
446393e9
EA
810 unsigned char linestatus = 0;
811 unsigned char error_mask = 0;
0b99d589
LL
812 ushort head;
813 ushort tail;
707505b5 814 unsigned long flags;
0b99d589
LL
815
816 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
817 return;
818
707505b5 819 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589
LL
820
821 /* cache head and tail of queue */
822 head = ch->ch_r_head;
823 tail = ch->ch_r_tail;
824
825 /* Store how much space we have left in the queue */
0b7ceaa6 826 qleft = tail - head - 1;
cb3714a6 827 if (qleft < 0)
0b99d589
LL
828 qleft += RQUEUEMASK + 1;
829
830 /*
831 * Create a mask to determine whether we should
832 * insert the character (if any) into our queue.
833 */
834 if (ch->ch_c_iflag & IGNBRK)
835 error_mask |= UART_LSR_BI;
836
837 while (1) {
838 linestatus = readb(&ch->ch_cls_uart->lsr);
839
840 if (!(linestatus & (UART_LSR_DR)))
841 break;
842
843 /*
844 * Discard character if we are ignoring the error mask.
845 */
846 if (linestatus & error_mask) {
0b99d589 847 linestatus = 0;
2d9920ec 848 readb(&ch->ch_cls_uart->txrx);
0b99d589
LL
849 continue;
850 }
851
852 /*
cb3714a6 853 * If our queue is full, we have no choice but to drop some
854 * data. The assumption is that HWFLOW or SWFLOW should have
855 * stopped things way way before we got to this point.
0b99d589
LL
856 *
857 * I decided that I wanted to ditch the oldest data first,
858 * I hope thats okay with everyone? Yes? Good.
859 */
860 while (qleft < 1) {
587abd7b
SL
861 tail = (tail + 1) & RQUEUEMASK;
862 ch->ch_r_tail = tail;
0b99d589
LL
863 ch->ch_err_overrun++;
864 qleft++;
865 }
866
cb3714a6 867 ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE
868 | UART_LSR_FE);
0b99d589 869 ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx);
0b99d589
LL
870
871 qleft--;
872
0b99d589
LL
873 if (ch->ch_equeue[head] & UART_LSR_PE)
874 ch->ch_err_parity++;
875 if (ch->ch_equeue[head] & UART_LSR_BI)
876 ch->ch_err_break++;
877 if (ch->ch_equeue[head] & UART_LSR_FE)
878 ch->ch_err_frame++;
879
880 /* Add to, and flip head if needed */
881 head = (head + 1) & RQUEUEMASK;
882 ch->ch_rxcount++;
883 }
884
885 /*
886 * Write new final heads to channel structure.
887 */
888 ch->ch_r_head = head & RQUEUEMASK;
889 ch->ch_e_head = head & EQUEUEMASK;
890
707505b5 891 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
892}
893
0b99d589
LL
894/*
895 * This function basically goes to sleep for secs, or until
896 * it gets signalled that the port has fully drained.
897 */
898static int cls_drain(struct tty_struct *tty, uint seconds)
899{
707505b5 900 unsigned long flags;
0b99d589 901 struct channel_t *ch;
cb3714a6 902 struct un_t *un;
0b99d589 903
cb3714a6 904 if (!tty || tty->magic != TTY_MAGIC)
8f90ef80 905 return -ENXIO;
0b99d589 906
6f418259 907 un = (struct un_t *)tty->driver_data;
cb3714a6 908 if (!un || un->magic != DGNC_UNIT_MAGIC)
8f90ef80 909 return -ENXIO;
0b99d589 910
5ca46fd4 911 ch = un->un_ch;
cb3714a6 912 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
8f90ef80 913 return -ENXIO;
0b99d589 914
707505b5 915 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589 916 un->un_flags |= UN_EMPTY;
707505b5 917 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
918
919 /*
920 * NOTE: Do something with time passed in.
921 */
0b99d589
LL
922
923 /* If ret is non-zero, user ctrl-c'ed us */
0b99d589 924
ca5dd0b8
HS
925 return wait_event_interruptible(un->un_flags_wait,
926 ((un->un_flags & UN_EMPTY) == 0));
0b99d589 927}
5ca46fd4 928
0b99d589
LL
929/* Channel lock MUST be held before calling this function! */
930static void cls_flush_uart_write(struct channel_t *ch)
931{
cb3714a6 932 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
0b99d589 933 return;
0b99d589 934
cb3714a6 935 writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT),
e352d3f1 936 &ch->ch_cls_uart->isr_fcr);
6e411751 937 usleep_range(10, 20);
0b99d589
LL
938
939 ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
940}
941
0b99d589
LL
942/* Channel lock MUST be held before calling this function! */
943static void cls_flush_uart_read(struct channel_t *ch)
944{
cb3714a6 945 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
0b99d589 946 return;
0b99d589
LL
947
948 /*
949 * For complete POSIX compatibility, we should be purging the
950 * read FIFO in the UART here.
5ca46fd4 951 *
83f053de
SL
952 * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
953 * incorrectly flushes write data as well as just basically trashing the
954 * FIFO.
0b99d589 955 *
83f053de 956 * Presumably, this is a bug in this UART.
0b99d589 957 */
645b0314 958
0b99d589
LL
959 udelay(10);
960}
961
0b99d589
LL
962static void cls_copy_data_from_queue_to_uart(struct channel_t *ch)
963{
964 ushort head;
965 ushort tail;
966 int n;
967 int qlen;
968 uint len_written = 0;
707505b5 969 unsigned long flags;
0b99d589
LL
970
971 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
972 return;
973
707505b5 974 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589
LL
975
976 /* No data to write to the UART */
f6a14cf0
QL
977 if (ch->ch_w_tail == ch->ch_w_head)
978 goto exit_unlock;
0b99d589
LL
979
980 /* If port is "stopped", don't send any data to the UART */
cb3714a6 981 if ((ch->ch_flags & CH_FORCED_STOP) ||
e352d3f1 982 (ch->ch_flags & CH_BREAK_SENDING))
f6a14cf0 983 goto exit_unlock;
0b99d589 984
f6a14cf0
QL
985 if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM)))
986 goto exit_unlock;
0b99d589
LL
987
988 n = 32;
989
cb3714a6 990 /* cache head and tail of queue */
991 head = ch->ch_w_head & WQUEUEMASK;
992 tail = ch->ch_w_tail & WQUEUEMASK;
993 qlen = (head - tail) & WQUEUEMASK;
0b99d589
LL
994
995 /* Find minimum of the FIFO space, versus queue length */
996 n = min(n, qlen);
997
998 while (n > 0) {
0b99d589
LL
999 /*
1000 * If RTS Toggle mode is on, turn on RTS now if not already set,
cb3714a6 1001 * and make sure we get an event when the data transfer has
1002 * completed.
0b99d589
LL
1003 */
1004 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
1005 if (!(ch->ch_mostat & UART_MCR_RTS)) {
1006 ch->ch_mostat |= (UART_MCR_RTS);
1007 cls_assert_modem_signals(ch);
1008 }
1009 ch->ch_tun.un_flags |= (UN_EMPTY);
1010 }
1011
1012 /*
1013 * If DTR Toggle mode is on, turn on DTR now if not already set,
cb3714a6 1014 * and make sure we get an event when the data transfer has
1015 * completed.
0b99d589
LL
1016 */
1017 if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
1018 if (!(ch->ch_mostat & UART_MCR_DTR)) {
1019 ch->ch_mostat |= (UART_MCR_DTR);
1020 cls_assert_modem_signals(ch);
1021 }
1022 ch->ch_tun.un_flags |= (UN_EMPTY);
1023 }
1024 writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx);
0b99d589
LL
1025 ch->ch_w_tail++;
1026 ch->ch_w_tail &= WQUEUEMASK;
1027 ch->ch_txcount++;
1028 len_written++;
1029 n--;
1030 }
1031
1032 if (len_written > 0)
1033 ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
1034
f6a14cf0 1035exit_unlock:
707505b5 1036 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
1037}
1038
446393e9 1039static void cls_parse_modem(struct channel_t *ch, unsigned char signals)
0b99d589 1040{
446393e9 1041 unsigned char msignals = signals;
707505b5 1042 unsigned long flags;
0b99d589
LL
1043
1044 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1045 return;
1046
0b99d589
LL
1047 /*
1048 * Do altpin switching. Altpin switches DCD and DSR.
1049 * This prolly breaks DSRPACE, so we should be more clever here.
1050 */
707505b5 1051 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589 1052 if (ch->ch_digi.digi_flags & DIGI_ALTPIN) {
446393e9 1053 unsigned char mswap = signals;
8aa5d0d8 1054
0b99d589
LL
1055 if (mswap & UART_MSR_DDCD) {
1056 msignals &= ~UART_MSR_DDCD;
1057 msignals |= UART_MSR_DDSR;
1058 }
1059 if (mswap & UART_MSR_DDSR) {
1060 msignals &= ~UART_MSR_DDSR;
1061 msignals |= UART_MSR_DDCD;
1062 }
1063 if (mswap & UART_MSR_DCD) {
1064 msignals &= ~UART_MSR_DCD;
1065 msignals |= UART_MSR_DSR;
1066 }
1067 if (mswap & UART_MSR_DSR) {
1068 msignals &= ~UART_MSR_DSR;
1069 msignals |= UART_MSR_DCD;
1070 }
1071 }
707505b5 1072 spin_unlock_irqrestore(&ch->ch_lock, flags);
5ca46fd4 1073
cb3714a6 1074 /*
1075 * Scrub off lower bits. They signify delta's, which I don't
1076 * care about
1077 */
0b99d589
LL
1078 signals &= 0xf0;
1079
707505b5 1080 spin_lock_irqsave(&ch->ch_lock, flags);
0b99d589
LL
1081 if (msignals & UART_MSR_DCD)
1082 ch->ch_mistat |= UART_MSR_DCD;
1083 else
1084 ch->ch_mistat &= ~UART_MSR_DCD;
1085
1086 if (msignals & UART_MSR_DSR)
1087 ch->ch_mistat |= UART_MSR_DSR;
1088 else
1089 ch->ch_mistat &= ~UART_MSR_DSR;
1090
1091 if (msignals & UART_MSR_RI)
1092 ch->ch_mistat |= UART_MSR_RI;
1093 else
1094 ch->ch_mistat &= ~UART_MSR_RI;
1095
1096 if (msignals & UART_MSR_CTS)
1097 ch->ch_mistat |= UART_MSR_CTS;
1098 else
1099 ch->ch_mistat &= ~UART_MSR_CTS;
707505b5 1100 spin_unlock_irqrestore(&ch->ch_lock, flags);
0b99d589
LL
1101}
1102
0b99d589
LL
1103/* Make the UART raise any of the output signals we want up */
1104static void cls_assert_modem_signals(struct channel_t *ch)
1105{
446393e9 1106 unsigned char out;
0b99d589
LL
1107
1108 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1109 return;
1110
1111 out = ch->ch_mostat;
1112
1113 if (ch->ch_flags & CH_LOOPBACK)
1114 out |= UART_MCR_LOOP;
1115
cb3714a6 1116 writeb(out, &ch->ch_cls_uart->mcr);
0b99d589
LL
1117
1118 /* Give time for the UART to actually drop the signals */
1119 udelay(10);
1120}
1121
0b99d589
LL
1122static void cls_send_start_character(struct channel_t *ch)
1123{
1124 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1125 return;
1126
1127 if (ch->ch_startc != _POSIX_VDISABLE) {
1128 ch->ch_xon_sends++;
1129 writeb(ch->ch_startc, &ch->ch_cls_uart->txrx);
cb3714a6 1130 }
0b99d589
LL
1131}
1132
0b99d589
LL
1133static void cls_send_stop_character(struct channel_t *ch)
1134{
1135 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1136 return;
1137
1138 if (ch->ch_stopc != _POSIX_VDISABLE) {
1139 ch->ch_xoff_sends++;
1140 writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx);
cb3714a6 1141 }
0b99d589
LL
1142}
1143
0b99d589
LL
1144/* Inits UART */
1145static void cls_uart_init(struct channel_t *ch)
1146{
446393e9
EA
1147 unsigned char lcrb = readb(&ch->ch_cls_uart->lcr);
1148 unsigned char isr_fcr = 0;
0b99d589
LL
1149
1150 writeb(0, &ch->ch_cls_uart->ier);
1151
1152 /*
1153 * The Enhanced Register Set may only be accessed when
1154 * the Line Control Register is set to 0xBFh.
1155 */
1156 writeb(UART_EXAR654_ENHANCED_REGISTER_SET, &ch->ch_cls_uart->lcr);
1157
1158 isr_fcr = readb(&ch->ch_cls_uart->isr_fcr);
5ca46fd4 1159
0b99d589
LL
1160 /* Turn on Enhanced/Extended controls */
1161 isr_fcr |= (UART_EXAR654_EFR_ECB);
1162
1163 writeb(isr_fcr, &ch->ch_cls_uart->isr_fcr);
1164
1165 /* Write old LCR value back out, which turns enhanced access off */
1166 writeb(lcrb, &ch->ch_cls_uart->lcr);
1167
cb3714a6 1168 /* Clear out UART and FIFO */
0b99d589
LL
1169 readb(&ch->ch_cls_uart->txrx);
1170
ea753f2a 1171 writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
e352d3f1 1172 &ch->ch_cls_uart->isr_fcr);
0b99d589
LL
1173 udelay(10);
1174
1175 ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
1176
1177 readb(&ch->ch_cls_uart->lsr);
1178 readb(&ch->ch_cls_uart->msr);
1179}
1180
0b99d589
LL
1181/*
1182 * Turns off UART.
1183 */
1184static void cls_uart_off(struct channel_t *ch)
1185{
1186 writeb(0, &ch->ch_cls_uart->ier);
1187}
1188
0b99d589
LL
1189/*
1190 * cls_get_uarts_bytes_left.
1191 * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
1192 *
1193 * The channel lock MUST be held by the calling function.
1194 */
1195static uint cls_get_uart_bytes_left(struct channel_t *ch)
1196{
446393e9
EA
1197 unsigned char left = 0;
1198 unsigned char lsr = 0;
0b99d589
LL
1199
1200 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1201 return 0;
1202
1203 lsr = readb(&ch->ch_cls_uart->lsr);
1204
1205 /* Determine whether the Transmitter is empty or not */
1206 if (!(lsr & UART_LSR_TEMT)) {
3d47910b 1207 if (ch->ch_flags & CH_TX_FIFO_EMPTY)
0b99d589 1208 tasklet_schedule(&ch->ch_bd->helper_tasklet);
0b99d589 1209 left = 1;
cb3714a6 1210 } else {
0b99d589
LL
1211 ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
1212 left = 0;
1213 }
1214
1215 return left;
1216}
1217
0b99d589
LL
1218/*
1219 * cls_send_break.
1220 * Starts sending a break thru the UART.
1221 *
1222 * The channel lock MUST be held by the calling function.
1223 */
1224static void cls_send_break(struct channel_t *ch, int msecs)
1225{
1226 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1227 return;
1228
1229 /*
1230 * If we receive a time of 0, this means turn off the break.
1231 */
1232 if (msecs == 0) {
1233 /* Turn break off, and unset some variables */
1234 if (ch->ch_flags & CH_BREAK_SENDING) {
446393e9 1235 unsigned char temp = readb(&ch->ch_cls_uart->lcr);
8aa5d0d8 1236
0b99d589
LL
1237 writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr);
1238 ch->ch_flags &= ~(CH_BREAK_SENDING);
1239 ch->ch_stop_sending_break = 0;
0b99d589
LL
1240 }
1241 return;
cb3714a6 1242 }
0b99d589
LL
1243
1244 /*
1245 * Set the time we should stop sending the break.
1246 * If we are already sending a break, toss away the existing
1247 * time to stop, and use this new value instead.
1248 */
1249 ch->ch_stop_sending_break = jiffies + dgnc_jiffies_from_ms(msecs);
1250
1251 /* Tell the UART to start sending the break */
1252 if (!(ch->ch_flags & CH_BREAK_SENDING)) {
446393e9 1253 unsigned char temp = readb(&ch->ch_cls_uart->lcr);
8aa5d0d8 1254
0b99d589
LL
1255 writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr);
1256 ch->ch_flags |= (CH_BREAK_SENDING);
0b99d589
LL
1257 }
1258}
1259
0b99d589
LL
1260/*
1261 * cls_send_immediate_char.
1262 * Sends a specific character as soon as possible to the UART,
1263 * jumping over any bytes that might be in the write queue.
1264 *
1265 * The channel lock MUST be held by the calling function.
1266 */
1267static void cls_send_immediate_char(struct channel_t *ch, unsigned char c)
1268{
1269 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1270 return;
1271
1272 writeb(c, &ch->ch_cls_uart->txrx);
1273}
1274
03425f55 1275static void cls_vpd(struct dgnc_board *brd)
0b99d589 1276{
cb3714a6 1277 ulong vpdbase; /* Start of io base of the card */
1278 u8 __iomem *re_map_vpdbase;/* Remapped memory of the card */
0b99d589
LL
1279 int i = 0;
1280
0b99d589
LL
1281 vpdbase = pci_resource_start(brd->pdev, 3);
1282
1283 /* No VPD */
1284 if (!vpdbase)
1285 return;
1286
1287 re_map_vpdbase = ioremap(vpdbase, 0x400);
1288
1289 if (!re_map_vpdbase)
1290 return;
1291
cb3714a6 1292 /* Store the VPD into our buffer */
1293 for (i = 0; i < 0x40; i++) {
0b99d589 1294 brd->vpd[i] = readb(re_map_vpdbase + i);
cb3714a6 1295 pr_info("%x ", brd->vpd[i]);
1296 }
1297 pr_info("\n");
0b99d589 1298
e24bb0ed 1299 iounmap(re_map_vpdbase);
0b99d589 1300}