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