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