2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
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)
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.
16 #include <linux/kernel.h>
17 #include <linux/sched.h> /* For jiffies, task states */
18 #include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
19 #include <linux/delay.h> /* For udelay */
20 #include <linux/io.h> /* For read[bwl]/write[bwl] */
21 #include <linux/serial.h> /* For struct async_serial */
22 #include <linux/serial_reg.h> /* For the various UART offsets */
23 #include <linux/pci.h>
25 #include "dgnc_driver.h" /* Driver main header file */
29 static inline void cls_set_cts_flow_control(struct channel_t
*ch
)
31 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
32 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
33 unsigned char isr_fcr
= 0;
36 * The Enhanced Register Set may only be accessed when
37 * the Line Control Register is set to 0xBFh.
39 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
41 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
43 /* Turn on CTS flow control, turn off IXON flow control */
44 isr_fcr
|= (UART_EXAR654_EFR_ECB
| UART_EXAR654_EFR_CTSDSR
);
45 isr_fcr
&= ~(UART_EXAR654_EFR_IXON
);
47 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
49 /* Write old LCR value back out, which turns enhanced access off */
50 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
53 * Enable interrupts for CTS flow, turn off interrupts for
56 ier
|= (UART_EXAR654_IER_CTSDSR
);
57 ier
&= ~(UART_EXAR654_IER_XOFF
);
58 writeb(ier
, &ch
->ch_cls_uart
->ier
);
60 /* Set the usual FIFO values */
61 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
63 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_56
|
64 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
65 &ch
->ch_cls_uart
->isr_fcr
);
70 static inline void cls_set_ixon_flow_control(struct channel_t
*ch
)
72 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
73 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
74 unsigned char isr_fcr
= 0;
77 * The Enhanced Register Set may only be accessed when
78 * the Line Control Register is set to 0xBFh.
80 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
82 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
84 /* Turn on IXON flow control, turn off CTS flow control */
85 isr_fcr
|= (UART_EXAR654_EFR_ECB
| UART_EXAR654_EFR_IXON
);
86 isr_fcr
&= ~(UART_EXAR654_EFR_CTSDSR
);
88 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
90 /* Now set our current start/stop chars while in enhanced mode */
91 writeb(ch
->ch_startc
, &ch
->ch_cls_uart
->mcr
);
92 writeb(0, &ch
->ch_cls_uart
->lsr
);
93 writeb(ch
->ch_stopc
, &ch
->ch_cls_uart
->msr
);
94 writeb(0, &ch
->ch_cls_uart
->spr
);
96 /* Write old LCR value back out, which turns enhanced access off */
97 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
100 * Disable interrupts for CTS flow, turn on interrupts for
101 * received XOFF chars
103 ier
&= ~(UART_EXAR654_IER_CTSDSR
);
104 ier
|= (UART_EXAR654_IER_XOFF
);
105 writeb(ier
, &ch
->ch_cls_uart
->ier
);
107 /* Set the usual FIFO values */
108 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
110 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_16
|
111 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
112 &ch
->ch_cls_uart
->isr_fcr
);
115 static inline void cls_set_no_output_flow_control(struct channel_t
*ch
)
117 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
118 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
119 unsigned char isr_fcr
= 0;
122 * The Enhanced Register Set may only be accessed when
123 * the Line Control Register is set to 0xBFh.
125 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
127 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
129 /* Turn off IXON flow control, turn off CTS flow control */
130 isr_fcr
|= (UART_EXAR654_EFR_ECB
);
131 isr_fcr
&= ~(UART_EXAR654_EFR_CTSDSR
| UART_EXAR654_EFR_IXON
);
133 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
135 /* Write old LCR value back out, which turns enhanced access off */
136 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
139 * Disable interrupts for CTS flow, turn off interrupts for
140 * received XOFF chars
142 ier
&= ~(UART_EXAR654_IER_CTSDSR
);
143 ier
&= ~(UART_EXAR654_IER_XOFF
);
144 writeb(ier
, &ch
->ch_cls_uart
->ier
);
146 /* Set the usual FIFO values */
147 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
149 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_16
|
150 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
151 &ch
->ch_cls_uart
->isr_fcr
);
153 ch
->ch_r_watermark
= 0;
154 ch
->ch_t_tlevel
= 16;
155 ch
->ch_r_tlevel
= 16;
158 static inline void cls_set_rts_flow_control(struct channel_t
*ch
)
160 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
161 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
162 unsigned char isr_fcr
= 0;
165 * The Enhanced Register Set may only be accessed when
166 * the Line Control Register is set to 0xBFh.
168 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
170 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
172 /* Turn on RTS flow control, turn off IXOFF flow control */
173 isr_fcr
|= (UART_EXAR654_EFR_ECB
| UART_EXAR654_EFR_RTSDTR
);
174 isr_fcr
&= ~(UART_EXAR654_EFR_IXOFF
);
176 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
178 /* Write old LCR value back out, which turns enhanced access off */
179 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
181 /* Enable interrupts for RTS flow */
182 ier
|= (UART_EXAR654_IER_RTSDTR
);
183 writeb(ier
, &ch
->ch_cls_uart
->ier
);
185 /* Set the usual FIFO values */
186 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
188 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_56
|
189 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
190 &ch
->ch_cls_uart
->isr_fcr
);
192 ch
->ch_r_watermark
= 4;
196 static inline void cls_set_ixoff_flow_control(struct channel_t
*ch
)
198 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
199 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
200 unsigned char isr_fcr
= 0;
203 * The Enhanced Register Set may only be accessed when
204 * the Line Control Register is set to 0xBFh.
206 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
208 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
210 /* Turn on IXOFF flow control, turn off RTS flow control */
211 isr_fcr
|= (UART_EXAR654_EFR_ECB
| UART_EXAR654_EFR_IXOFF
);
212 isr_fcr
&= ~(UART_EXAR654_EFR_RTSDTR
);
214 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
216 /* Now set our current start/stop chars while in enhanced mode */
217 writeb(ch
->ch_startc
, &ch
->ch_cls_uart
->mcr
);
218 writeb(0, &ch
->ch_cls_uart
->lsr
);
219 writeb(ch
->ch_stopc
, &ch
->ch_cls_uart
->msr
);
220 writeb(0, &ch
->ch_cls_uart
->spr
);
222 /* Write old LCR value back out, which turns enhanced access off */
223 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
225 /* Disable interrupts for RTS flow */
226 ier
&= ~(UART_EXAR654_IER_RTSDTR
);
227 writeb(ier
, &ch
->ch_cls_uart
->ier
);
229 /* Set the usual FIFO values */
230 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
232 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_16
|
233 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
234 &ch
->ch_cls_uart
->isr_fcr
);
237 static inline void cls_set_no_input_flow_control(struct channel_t
*ch
)
239 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
240 unsigned char ier
= readb(&ch
->ch_cls_uart
->ier
);
241 unsigned char isr_fcr
= 0;
244 * The Enhanced Register Set may only be accessed when
245 * the Line Control Register is set to 0xBFh.
247 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
249 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
251 /* Turn off IXOFF flow control, turn off RTS flow control */
252 isr_fcr
|= (UART_EXAR654_EFR_ECB
);
253 isr_fcr
&= ~(UART_EXAR654_EFR_RTSDTR
| UART_EXAR654_EFR_IXOFF
);
255 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
257 /* Write old LCR value back out, which turns enhanced access off */
258 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
260 /* Disable interrupts for RTS flow */
261 ier
&= ~(UART_EXAR654_IER_RTSDTR
);
262 writeb(ier
, &ch
->ch_cls_uart
->ier
);
264 /* Set the usual FIFO values */
265 writeb((UART_FCR_ENABLE_FIFO
), &ch
->ch_cls_uart
->isr_fcr
);
267 writeb((UART_FCR_ENABLE_FIFO
| UART_16654_FCR_RXTRIGGER_16
|
268 UART_16654_FCR_TXTRIGGER_16
| UART_FCR_CLEAR_RCVR
),
269 &ch
->ch_cls_uart
->isr_fcr
);
271 ch
->ch_t_tlevel
= 16;
272 ch
->ch_r_tlevel
= 16;
277 * Determines whether its time to shut off break condition.
279 * No locks are assumed to be held when calling this function.
280 * channel lock is held and released in this function.
282 static inline void cls_clear_break(struct channel_t
*ch
, int force
)
286 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
289 spin_lock_irqsave(&ch
->ch_lock
, flags
);
291 /* Bail if we aren't currently sending a break. */
292 if (!ch
->ch_stop_sending_break
) {
293 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
297 /* Turn break off, and unset some variables */
298 if (ch
->ch_flags
& CH_BREAK_SENDING
) {
299 if (time_after(jiffies
, ch
->ch_stop_sending_break
) || force
) {
300 unsigned char temp
= readb(&ch
->ch_cls_uart
->lcr
);
302 writeb((temp
& ~UART_LCR_SBC
), &ch
->ch_cls_uart
->lcr
);
303 ch
->ch_flags
&= ~(CH_BREAK_SENDING
);
304 ch
->ch_stop_sending_break
= 0;
307 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
310 static void cls_copy_data_from_uart_to_queue(struct channel_t
*ch
)
313 unsigned char linestatus
= 0;
314 unsigned char error_mask
= 0;
319 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
322 spin_lock_irqsave(&ch
->ch_lock
, flags
);
324 /* cache head and tail of queue */
325 head
= ch
->ch_r_head
;
326 tail
= ch
->ch_r_tail
;
328 /* Store how much space we have left in the queue */
329 qleft
= tail
- head
- 1;
331 qleft
+= RQUEUEMASK
+ 1;
334 * Create a mask to determine whether we should
335 * insert the character (if any) into our queue.
337 if (ch
->ch_c_iflag
& IGNBRK
)
338 error_mask
|= UART_LSR_BI
;
341 linestatus
= readb(&ch
->ch_cls_uart
->lsr
);
343 if (!(linestatus
& (UART_LSR_DR
)))
347 * Discard character if we are ignoring the error mask.
349 if (linestatus
& error_mask
) {
351 readb(&ch
->ch_cls_uart
->txrx
);
356 * If our queue is full, we have no choice but to drop some
357 * data. The assumption is that HWFLOW or SWFLOW should have
358 * stopped things way way before we got to this point.
360 * I decided that I wanted to ditch the oldest data first,
361 * I hope thats okay with everyone? Yes? Good.
364 tail
= (tail
+ 1) & RQUEUEMASK
;
365 ch
->ch_r_tail
= tail
;
366 ch
->ch_err_overrun
++;
370 ch
->ch_equeue
[head
] = linestatus
& (UART_LSR_BI
| UART_LSR_PE
372 ch
->ch_rqueue
[head
] = readb(&ch
->ch_cls_uart
->txrx
);
376 if (ch
->ch_equeue
[head
] & UART_LSR_PE
)
378 if (ch
->ch_equeue
[head
] & UART_LSR_BI
)
380 if (ch
->ch_equeue
[head
] & UART_LSR_FE
)
383 /* Add to, and flip head if needed */
384 head
= (head
+ 1) & RQUEUEMASK
;
389 * Write new final heads to channel structure.
391 ch
->ch_r_head
= head
& RQUEUEMASK
;
392 ch
->ch_e_head
= head
& EQUEUEMASK
;
394 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
397 /* Make the UART raise any of the output signals we want up */
398 static void cls_assert_modem_signals(struct channel_t
*ch
)
402 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
407 if (ch
->ch_flags
& CH_LOOPBACK
)
408 out
|= UART_MCR_LOOP
;
410 writeb(out
, &ch
->ch_cls_uart
->mcr
);
412 /* Give time for the UART to actually drop the signals */
416 static void cls_copy_data_from_queue_to_uart(struct channel_t
*ch
)
422 uint len_written
= 0;
425 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
428 spin_lock_irqsave(&ch
->ch_lock
, flags
);
430 /* No data to write to the UART */
431 if (ch
->ch_w_tail
== ch
->ch_w_head
)
434 /* If port is "stopped", don't send any data to the UART */
435 if ((ch
->ch_flags
& CH_FORCED_STOP
) ||
436 (ch
->ch_flags
& CH_BREAK_SENDING
))
439 if (!(ch
->ch_flags
& (CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
)))
444 /* cache head and tail of queue */
445 head
= ch
->ch_w_head
& WQUEUEMASK
;
446 tail
= ch
->ch_w_tail
& WQUEUEMASK
;
447 qlen
= (head
- tail
) & WQUEUEMASK
;
449 /* Find minimum of the FIFO space, versus queue length */
454 * If RTS Toggle mode is on, turn on RTS now if not already set,
455 * and make sure we get an event when the data transfer has
458 if (ch
->ch_digi
.digi_flags
& DIGI_RTS_TOGGLE
) {
459 if (!(ch
->ch_mostat
& UART_MCR_RTS
)) {
460 ch
->ch_mostat
|= (UART_MCR_RTS
);
461 cls_assert_modem_signals(ch
);
463 ch
->ch_tun
.un_flags
|= (UN_EMPTY
);
467 * If DTR Toggle mode is on, turn on DTR now if not already set,
468 * and make sure we get an event when the data transfer has
471 if (ch
->ch_digi
.digi_flags
& DIGI_DTR_TOGGLE
) {
472 if (!(ch
->ch_mostat
& UART_MCR_DTR
)) {
473 ch
->ch_mostat
|= (UART_MCR_DTR
);
474 cls_assert_modem_signals(ch
);
476 ch
->ch_tun
.un_flags
|= (UN_EMPTY
);
478 writeb(ch
->ch_wqueue
[ch
->ch_w_tail
], &ch
->ch_cls_uart
->txrx
);
480 ch
->ch_w_tail
&= WQUEUEMASK
;
487 ch
->ch_flags
&= ~(CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
);
490 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
493 static void cls_parse_modem(struct channel_t
*ch
, unsigned char signals
)
495 unsigned char msignals
= signals
;
498 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
502 * Do altpin switching. Altpin switches DCD and DSR.
503 * This prolly breaks DSRPACE, so we should be more clever here.
505 spin_lock_irqsave(&ch
->ch_lock
, flags
);
506 if (ch
->ch_digi
.digi_flags
& DIGI_ALTPIN
) {
507 unsigned char mswap
= signals
;
509 if (mswap
& UART_MSR_DDCD
) {
510 msignals
&= ~UART_MSR_DDCD
;
511 msignals
|= UART_MSR_DDSR
;
513 if (mswap
& UART_MSR_DDSR
) {
514 msignals
&= ~UART_MSR_DDSR
;
515 msignals
|= UART_MSR_DDCD
;
517 if (mswap
& UART_MSR_DCD
) {
518 msignals
&= ~UART_MSR_DCD
;
519 msignals
|= UART_MSR_DSR
;
521 if (mswap
& UART_MSR_DSR
) {
522 msignals
&= ~UART_MSR_DSR
;
523 msignals
|= UART_MSR_DCD
;
526 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
529 * Scrub off lower bits. They signify delta's, which I don't
534 spin_lock_irqsave(&ch
->ch_lock
, flags
);
535 if (msignals
& UART_MSR_DCD
)
536 ch
->ch_mistat
|= UART_MSR_DCD
;
538 ch
->ch_mistat
&= ~UART_MSR_DCD
;
540 if (msignals
& UART_MSR_DSR
)
541 ch
->ch_mistat
|= UART_MSR_DSR
;
543 ch
->ch_mistat
&= ~UART_MSR_DSR
;
545 if (msignals
& UART_MSR_RI
)
546 ch
->ch_mistat
|= UART_MSR_RI
;
548 ch
->ch_mistat
&= ~UART_MSR_RI
;
550 if (msignals
& UART_MSR_CTS
)
551 ch
->ch_mistat
|= UART_MSR_CTS
;
553 ch
->ch_mistat
&= ~UART_MSR_CTS
;
554 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
557 /* Parse the ISR register for the specific port */
558 static inline void cls_parse_isr(struct dgnc_board
*brd
, uint port
)
560 struct channel_t
*ch
;
561 unsigned char isr
= 0;
565 * No need to verify board pointer, it was already
566 * verified in the interrupt routine.
569 if (port
>= brd
->nasync
)
572 ch
= brd
->channels
[port
];
573 if (ch
->magic
!= DGNC_CHANNEL_MAGIC
)
576 /* Here we try to figure out what caused the interrupt to happen */
578 isr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
580 /* Bail if no pending interrupt on port */
581 if (isr
& UART_IIR_NO_INT
)
584 /* Receive Interrupt pending */
585 if (isr
& (UART_IIR_RDI
| UART_IIR_RDI_TIMEOUT
)) {
586 /* Read data from uart -> queue */
587 cls_copy_data_from_uart_to_queue(ch
);
588 dgnc_check_queue_flow_control(ch
);
591 /* Transmit Hold register empty pending */
592 if (isr
& UART_IIR_THRI
) {
593 /* Transfer data (if any) from Write Queue -> UART. */
594 spin_lock_irqsave(&ch
->ch_lock
, flags
);
595 ch
->ch_flags
|= (CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
);
596 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
597 cls_copy_data_from_queue_to_uart(ch
);
600 /* Parse any modem signal changes */
601 cls_parse_modem(ch
, readb(&ch
->ch_cls_uart
->msr
));
605 /* Channel lock MUST be held before calling this function! */
606 static void cls_flush_uart_write(struct channel_t
*ch
)
608 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
611 writeb((UART_FCR_ENABLE_FIFO
| UART_FCR_CLEAR_XMIT
),
612 &ch
->ch_cls_uart
->isr_fcr
);
613 usleep_range(10, 20);
615 ch
->ch_flags
|= (CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
);
618 /* Channel lock MUST be held before calling this function! */
619 static void cls_flush_uart_read(struct channel_t
*ch
)
621 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
625 * For complete POSIX compatibility, we should be purging the
626 * read FIFO in the UART here.
628 * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
629 * incorrectly flushes write data as well as just basically trashing the
632 * Presumably, this is a bug in this UART.
640 * Send any/all changes to the line to the UART.
642 static void cls_param(struct tty_struct
*tty
)
644 unsigned char lcr
= 0;
645 unsigned char uart_lcr
= 0;
646 unsigned char ier
= 0;
647 unsigned char uart_ier
= 0;
650 struct dgnc_board
*bd
;
651 struct channel_t
*ch
;
654 if (!tty
|| tty
->magic
!= TTY_MAGIC
)
657 un
= (struct un_t
*)tty
->driver_data
;
658 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
662 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
666 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
670 * If baud rate is zero, flush queues, and set mval to drop DTR.
672 if ((ch
->ch_c_cflag
& (CBAUD
)) == 0) {
680 cls_flush_uart_write(ch
);
681 cls_flush_uart_read(ch
);
683 /* The baudrate is B0 so all modem lines are to be dropped. */
684 ch
->ch_flags
|= (CH_BAUD0
);
685 ch
->ch_mostat
&= ~(UART_MCR_RTS
| UART_MCR_DTR
);
686 cls_assert_modem_signals(ch
);
689 } else if (ch
->ch_custom_speed
) {
690 baud
= ch
->ch_custom_speed
;
691 /* Handle transition from B0 */
692 if (ch
->ch_flags
& CH_BAUD0
) {
693 ch
->ch_flags
&= ~(CH_BAUD0
);
696 * Bring back up RTS and DTR...
697 * Also handle RTS or DTR toggle if set.
699 if (!(ch
->ch_digi
.digi_flags
& DIGI_RTS_TOGGLE
))
700 ch
->ch_mostat
|= (UART_MCR_RTS
);
701 if (!(ch
->ch_digi
.digi_flags
& DIGI_DTR_TOGGLE
))
702 ch
->ch_mostat
|= (UART_MCR_DTR
);
709 ulong bauds
[4][16] = {
713 600, 1200, 1800, 2400,
714 4800, 9600, 19200, 38400 },
715 { /* slowbaud & CBAUDEX */
716 0, 57600, 115200, 230400,
717 460800, 150, 200, 921600,
718 600, 1200, 1800, 2400,
719 4800, 9600, 19200, 38400 },
721 0, 57600, 76800, 115200,
722 131657, 153600, 230400, 460800,
723 921600, 1200, 1800, 2400,
724 4800, 9600, 19200, 38400 },
725 { /* fastbaud & CBAUDEX */
726 0, 57600, 115200, 230400,
727 460800, 150, 200, 921600,
728 600, 1200, 1800, 2400,
729 4800, 9600, 19200, 38400 }
733 * Only use the TXPrint baud rate if the terminal
736 if (!(ch
->ch_tun
.un_flags
& UN_ISOPEN
) &&
737 (un
->un_type
== DGNC_PRINT
))
738 baud
= C_BAUD(ch
->ch_pun
.un_tty
) & 0xff;
740 baud
= C_BAUD(ch
->ch_tun
.un_tty
) & 0xff;
742 if (ch
->ch_c_cflag
& CBAUDEX
)
745 if (ch
->ch_digi
.digi_flags
& DIGI_FAST
)
750 if ((iindex
>= 0) && (iindex
< 4) && (jindex
>= 0) &&
752 baud
= bauds
[iindex
][jindex
];
760 /* Handle transition from B0 */
761 if (ch
->ch_flags
& CH_BAUD0
) {
762 ch
->ch_flags
&= ~(CH_BAUD0
);
765 * Bring back up RTS and DTR...
766 * Also handle RTS or DTR toggle if set.
768 if (!(ch
->ch_digi
.digi_flags
& DIGI_RTS_TOGGLE
))
769 ch
->ch_mostat
|= (UART_MCR_RTS
);
770 if (!(ch
->ch_digi
.digi_flags
& DIGI_DTR_TOGGLE
))
771 ch
->ch_mostat
|= (UART_MCR_DTR
);
775 if (ch
->ch_c_cflag
& PARENB
)
776 lcr
|= UART_LCR_PARITY
;
778 if (!(ch
->ch_c_cflag
& PARODD
))
779 lcr
|= UART_LCR_EPAR
;
782 * Not all platforms support mark/space parity,
783 * so this will hide behind an ifdef.
786 if (ch
->ch_c_cflag
& CMSPAR
)
787 lcr
|= UART_LCR_SPAR
;
790 if (ch
->ch_c_cflag
& CSTOPB
)
791 lcr
|= UART_LCR_STOP
;
793 switch (ch
->ch_c_cflag
& CSIZE
) {
795 lcr
|= UART_LCR_WLEN5
;
798 lcr
|= UART_LCR_WLEN6
;
801 lcr
|= UART_LCR_WLEN7
;
805 lcr
|= UART_LCR_WLEN8
;
809 uart_ier
= readb(&ch
->ch_cls_uart
->ier
);
811 uart_lcr
= readb(&ch
->ch_cls_uart
->lcr
);
816 quot
= ch
->ch_bd
->bd_dividend
/ baud
;
818 if (quot
!= 0 && ch
->ch_old_baud
!= baud
) {
819 ch
->ch_old_baud
= baud
;
820 writeb(UART_LCR_DLAB
, &ch
->ch_cls_uart
->lcr
);
821 writeb((quot
& 0xff), &ch
->ch_cls_uart
->txrx
);
822 writeb((quot
>> 8), &ch
->ch_cls_uart
->ier
);
823 writeb(lcr
, &ch
->ch_cls_uart
->lcr
);
827 writeb(lcr
, &ch
->ch_cls_uart
->lcr
);
829 if (ch
->ch_c_cflag
& CREAD
)
830 ier
|= (UART_IER_RDI
| UART_IER_RLSI
);
832 ier
&= ~(UART_IER_RDI
| UART_IER_RLSI
);
835 * Have the UART interrupt on modem signal changes ONLY when
836 * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set.
838 if ((ch
->ch_digi
.digi_flags
& CTSPACE
) ||
839 (ch
->ch_digi
.digi_flags
& RTSPACE
) ||
840 (ch
->ch_c_cflag
& CRTSCTS
) ||
841 !(ch
->ch_digi
.digi_flags
& DIGI_FORCEDCD
) ||
842 !(ch
->ch_c_cflag
& CLOCAL
))
845 ier
&= ~UART_IER_MSI
;
847 ier
|= UART_IER_THRI
;
850 writeb(ier
, &ch
->ch_cls_uart
->ier
);
852 if (ch
->ch_digi
.digi_flags
& CTSPACE
|| ch
->ch_c_cflag
& CRTSCTS
) {
853 cls_set_cts_flow_control(ch
);
854 } else if (ch
->ch_c_iflag
& IXON
) {
856 * If start/stop is set to disable, then we should
857 * disable flow control
859 if ((ch
->ch_startc
== _POSIX_VDISABLE
) ||
860 (ch
->ch_stopc
== _POSIX_VDISABLE
))
861 cls_set_no_output_flow_control(ch
);
863 cls_set_ixon_flow_control(ch
);
865 cls_set_no_output_flow_control(ch
);
868 if (ch
->ch_digi
.digi_flags
& RTSPACE
|| ch
->ch_c_cflag
& CRTSCTS
) {
869 cls_set_rts_flow_control(ch
);
870 } else if (ch
->ch_c_iflag
& IXOFF
) {
872 * If start/stop is set to disable, then we should disable
875 if ((ch
->ch_startc
== _POSIX_VDISABLE
) ||
876 (ch
->ch_stopc
== _POSIX_VDISABLE
))
877 cls_set_no_input_flow_control(ch
);
879 cls_set_ixoff_flow_control(ch
);
881 cls_set_no_input_flow_control(ch
);
884 cls_assert_modem_signals(ch
);
886 /* Get current status of the modem signals now */
887 cls_parse_modem(ch
, readb(&ch
->ch_cls_uart
->msr
));
891 * Our board poller function.
893 static void cls_tasklet(unsigned long data
)
895 struct dgnc_board
*bd
= (struct dgnc_board
*)data
;
896 struct channel_t
*ch
;
902 if (!bd
|| bd
->magic
!= DGNC_BOARD_MAGIC
)
905 /* Cache a couple board values */
906 spin_lock_irqsave(&bd
->bd_lock
, flags
);
909 spin_unlock_irqrestore(&bd
->bd_lock
, flags
);
912 * Do NOT allow the interrupt routine to read the intr registers
913 * Until we release this lock.
915 spin_lock_irqsave(&bd
->bd_intr_lock
, flags
);
918 * If board is ready, parse deeper to see if there is anything to do.
920 if ((state
== BOARD_READY
) && (ports
> 0)) {
921 /* Loop on each port */
922 for (i
= 0; i
< ports
; i
++) {
923 ch
= bd
->channels
[i
];
926 * NOTE: Remember you CANNOT hold any channel
927 * locks when calling input.
928 * During input processing, its possible we
929 * will call ld, which might do callbacks back
935 * Channel lock is grabbed and then released
936 * inside this routine.
938 cls_copy_data_from_queue_to_uart(ch
);
939 dgnc_wakeup_writes(ch
);
942 * Check carrier function.
947 * The timing check of turning off the break is done
948 * inside clear_break()
950 if (ch
->ch_stop_sending_break
)
951 cls_clear_break(ch
, 0);
955 spin_unlock_irqrestore(&bd
->bd_intr_lock
, flags
);
961 * Classic specific interrupt handler.
963 static irqreturn_t
cls_intr(int irq
, void *voidbrd
)
965 struct dgnc_board
*brd
= voidbrd
;
967 unsigned char poll_reg
;
971 * Check to make sure it didn't receive interrupt with a null board
972 * associated or a board pointer that wasn't ours.
974 if (!brd
|| brd
->magic
!= DGNC_BOARD_MAGIC
)
977 spin_lock_irqsave(&brd
->bd_intr_lock
, flags
);
980 * Check the board's global interrupt offset to see if we
981 * we actually do have an interrupt pending for us.
983 poll_reg
= readb(brd
->re_map_membase
+ UART_CLASSIC_POLL_ADDR_OFFSET
);
985 /* If 0, no interrupts pending */
987 spin_unlock_irqrestore(&brd
->bd_intr_lock
, flags
);
991 /* Parse each port to find out what caused the interrupt */
992 for (i
= 0; i
< brd
->nasync
; i
++)
993 cls_parse_isr(brd
, i
);
996 * Schedule tasklet to more in-depth servicing at a better time.
998 tasklet_schedule(&brd
->helper_tasklet
);
1000 spin_unlock_irqrestore(&brd
->bd_intr_lock
, flags
);
1005 static void cls_disable_receiver(struct channel_t
*ch
)
1007 unsigned char tmp
= readb(&ch
->ch_cls_uart
->ier
);
1009 tmp
&= ~(UART_IER_RDI
);
1010 writeb(tmp
, &ch
->ch_cls_uart
->ier
);
1013 static void cls_enable_receiver(struct channel_t
*ch
)
1015 unsigned char tmp
= readb(&ch
->ch_cls_uart
->ier
);
1017 tmp
|= (UART_IER_RDI
);
1018 writeb(tmp
, &ch
->ch_cls_uart
->ier
);
1022 * This function basically goes to sleep for secs, or until
1023 * it gets signalled that the port has fully drained.
1025 static int cls_drain(struct tty_struct
*tty
, uint seconds
)
1027 unsigned long flags
;
1028 struct channel_t
*ch
;
1031 if (!tty
|| tty
->magic
!= TTY_MAGIC
)
1034 un
= (struct un_t
*)tty
->driver_data
;
1035 if (!un
|| un
->magic
!= DGNC_UNIT_MAGIC
)
1039 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1042 spin_lock_irqsave(&ch
->ch_lock
, flags
);
1043 un
->un_flags
|= UN_EMPTY
;
1044 spin_unlock_irqrestore(&ch
->ch_lock
, flags
);
1047 * NOTE: Do something with time passed in.
1050 /* If ret is non-zero, user ctrl-c'ed us */
1052 return wait_event_interruptible(un
->un_flags_wait
,
1053 ((un
->un_flags
& UN_EMPTY
) == 0));
1056 static void cls_send_start_character(struct channel_t
*ch
)
1058 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1061 if (ch
->ch_startc
!= _POSIX_VDISABLE
) {
1063 writeb(ch
->ch_startc
, &ch
->ch_cls_uart
->txrx
);
1067 static void cls_send_stop_character(struct channel_t
*ch
)
1069 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1072 if (ch
->ch_stopc
!= _POSIX_VDISABLE
) {
1073 ch
->ch_xoff_sends
++;
1074 writeb(ch
->ch_stopc
, &ch
->ch_cls_uart
->txrx
);
1079 static void cls_uart_init(struct channel_t
*ch
)
1081 unsigned char lcrb
= readb(&ch
->ch_cls_uart
->lcr
);
1082 unsigned char isr_fcr
= 0;
1084 writeb(0, &ch
->ch_cls_uart
->ier
);
1087 * The Enhanced Register Set may only be accessed when
1088 * the Line Control Register is set to 0xBFh.
1090 writeb(UART_EXAR654_ENHANCED_REGISTER_SET
, &ch
->ch_cls_uart
->lcr
);
1092 isr_fcr
= readb(&ch
->ch_cls_uart
->isr_fcr
);
1094 /* Turn on Enhanced/Extended controls */
1095 isr_fcr
|= (UART_EXAR654_EFR_ECB
);
1097 writeb(isr_fcr
, &ch
->ch_cls_uart
->isr_fcr
);
1099 /* Write old LCR value back out, which turns enhanced access off */
1100 writeb(lcrb
, &ch
->ch_cls_uart
->lcr
);
1102 /* Clear out UART and FIFO */
1103 readb(&ch
->ch_cls_uart
->txrx
);
1105 writeb(UART_FCR_ENABLE_FIFO
| UART_FCR_CLEAR_RCVR
| UART_FCR_CLEAR_XMIT
,
1106 &ch
->ch_cls_uart
->isr_fcr
);
1109 ch
->ch_flags
|= (CH_FIFO_ENABLED
| CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
);
1111 readb(&ch
->ch_cls_uart
->lsr
);
1112 readb(&ch
->ch_cls_uart
->msr
);
1118 static void cls_uart_off(struct channel_t
*ch
)
1120 writeb(0, &ch
->ch_cls_uart
->ier
);
1124 * cls_get_uarts_bytes_left.
1125 * Returns 0 is nothing left in the FIFO, returns 1 otherwise.
1127 * The channel lock MUST be held by the calling function.
1129 static uint
cls_get_uart_bytes_left(struct channel_t
*ch
)
1131 unsigned char left
= 0;
1132 unsigned char lsr
= 0;
1134 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1137 lsr
= readb(&ch
->ch_cls_uart
->lsr
);
1139 /* Determine whether the Transmitter is empty or not */
1140 if (!(lsr
& UART_LSR_TEMT
)) {
1141 if (ch
->ch_flags
& CH_TX_FIFO_EMPTY
)
1142 tasklet_schedule(&ch
->ch_bd
->helper_tasklet
);
1145 ch
->ch_flags
|= (CH_TX_FIFO_EMPTY
| CH_TX_FIFO_LWM
);
1154 * Starts sending a break thru the UART.
1156 * The channel lock MUST be held by the calling function.
1158 static void cls_send_break(struct channel_t
*ch
, int msecs
)
1160 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1164 * If we receive a time of 0, this means turn off the break.
1167 /* Turn break off, and unset some variables */
1168 if (ch
->ch_flags
& CH_BREAK_SENDING
) {
1169 unsigned char temp
= readb(&ch
->ch_cls_uart
->lcr
);
1171 writeb((temp
& ~UART_LCR_SBC
), &ch
->ch_cls_uart
->lcr
);
1172 ch
->ch_flags
&= ~(CH_BREAK_SENDING
);
1173 ch
->ch_stop_sending_break
= 0;
1179 * Set the time we should stop sending the break.
1180 * If we are already sending a break, toss away the existing
1181 * time to stop, and use this new value instead.
1183 ch
->ch_stop_sending_break
= jiffies
+ dgnc_jiffies_from_ms(msecs
);
1185 /* Tell the UART to start sending the break */
1186 if (!(ch
->ch_flags
& CH_BREAK_SENDING
)) {
1187 unsigned char temp
= readb(&ch
->ch_cls_uart
->lcr
);
1189 writeb((temp
| UART_LCR_SBC
), &ch
->ch_cls_uart
->lcr
);
1190 ch
->ch_flags
|= (CH_BREAK_SENDING
);
1195 * cls_send_immediate_char.
1196 * Sends a specific character as soon as possible to the UART,
1197 * jumping over any bytes that might be in the write queue.
1199 * The channel lock MUST be held by the calling function.
1201 static void cls_send_immediate_char(struct channel_t
*ch
, unsigned char c
)
1203 if (!ch
|| ch
->magic
!= DGNC_CHANNEL_MAGIC
)
1206 writeb(c
, &ch
->ch_cls_uart
->txrx
);
1209 static void cls_vpd(struct dgnc_board
*brd
)
1211 ulong vpdbase
; /* Start of io base of the card */
1212 u8 __iomem
*re_map_vpdbase
;/* Remapped memory of the card */
1215 vpdbase
= pci_resource_start(brd
->pdev
, 3);
1221 re_map_vpdbase
= ioremap(vpdbase
, 0x400);
1223 if (!re_map_vpdbase
)
1226 /* Store the VPD into our buffer */
1227 for (i
= 0; i
< 0x40; i
++) {
1228 brd
->vpd
[i
] = readb(re_map_vpdbase
+ i
);
1229 pr_info("%x ", brd
->vpd
[i
]);
1233 iounmap(re_map_vpdbase
);
1236 struct board_ops dgnc_cls_ops
= {
1237 .tasklet
= cls_tasklet
,
1239 .uart_init
= cls_uart_init
,
1240 .uart_off
= cls_uart_off
,
1244 .assert_modem_signals
= cls_assert_modem_signals
,
1245 .flush_uart_write
= cls_flush_uart_write
,
1246 .flush_uart_read
= cls_flush_uart_read
,
1247 .disable_receiver
= cls_disable_receiver
,
1248 .enable_receiver
= cls_enable_receiver
,
1249 .send_break
= cls_send_break
,
1250 .send_start_character
= cls_send_start_character
,
1251 .send_stop_character
= cls_send_stop_character
,
1252 .copy_data_from_queue_to_uart
= cls_copy_data_from_queue_to_uart
,
1253 .get_uart_bytes_left
= cls_get_uart_bytes_left
,
1254 .send_immediate_char
= cls_send_immediate_char