2 * cyclades cyclom-y serial driver
3 * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
5 * Copyright (c) 1993 Andrew Herbert.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name Andrew Herbert may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include "opt_compat.h"
43 * Temporary compile-time configuration options.
45 #define RxFifoThreshold (CD1400_RX_FIFO_SIZE / 2)
46 /* Number of chars in the receiver FIFO before an
47 * an interrupt is generated. Should depend on
48 * line speed. Needs to be about 6 on a 486DX33
49 * for 4 active ports at 115200 bps. Why doesn't
52 #define PollMode /* Use polling-based irq service routine, not the
53 * hardware svcack lines. Must be defined for
54 * Cyclom-16Y boards. Less efficient for Cyclom-8Ys,
55 * and stops 4 * 115200 bps from working.
57 #undef Smarts /* Enable slightly more CD1400 intelligence. Mainly
58 * the output CR/LF processing, plus we can avoid a
59 * few checks usually done in ttyinput().
61 * XXX not fully implemented, and not particularly
64 #undef CyDebug /* Include debugging code (not very expensive). */
66 /* These will go away. */
70 #include <sys/param.h>
71 #include <sys/systm.h>
74 #include <sys/fcntl.h>
75 #include <sys/interrupt.h>
76 #include <sys/kernel.h>
78 #include <sys/malloc.h>
79 #include <sys/mutex.h>
80 #include <sys/serial.h>
81 #include <sys/syslog.h>
84 #include <machine/psl.h>
86 #include <dev/ic/cd1400.h>
88 #include <dev/cy/cyreg.h>
89 #include <dev/cy/cyvar.h>
91 #define NCY 10 /* KLUDGE */
93 #define NPORTS (NCY * CY_MAX_PORTS)
95 #define CY_MAX_PORTS (CD1400_NO_OF_CHANNELS * CY_MAX_CD1400s)
97 /* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
98 #define CD1400_xIVR_CHAN_SHIFT 3
99 #define CD1400_xIVR_CHAN 0x1F
102 * ETC states. com->etc may also contain a hardware ETC command value,
103 * meaning that execution of that command is pending.
105 #define ETC_NONE 0 /* we depend on bzero() setting this */
106 #define ETC_BREAK_STARTING 1
107 #define ETC_BREAK_STARTED 2
108 #define ETC_BREAK_ENDING 3
109 #define ETC_BREAK_ENDED 4
111 #define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
115 * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
116 * than the other bits so that they can be tested as a group without masking
119 * The following com and tty flags correspond closely:
120 * CS_BUSY = TS_BUSY (maintained by cystart(), cypoll() and
122 * CS_TTGO = ~TS_TTSTOP (maintained by cyparam() and cystart())
123 * CS_CTS_OFLOW = CCTS_OFLOW (maintained by cyparam())
124 * CS_RTS_IFLOW = CRTS_IFLOW (maintained by cyparam())
125 * TS_FLUSH is not used.
126 * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
127 * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
129 #define CS_BUSY 0x80 /* output in progress */
130 #define CS_TTGO 0x40 /* output not stopped by XOFF */
131 #define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
132 #define CS_CHECKMSR 1 /* check of MSR scheduled */
133 #define CS_CTS_OFLOW 2 /* use CTS output flow control */
134 #define CS_ODONE 4 /* output completed */
135 #define CS_RTS_IFLOW 8 /* use RTS input flow control */
136 #define CSE_ODONE 1 /* output transmitted */
138 static char const * const error_desc
[] = {
141 #define CE_INTERRUPT_BUF_OVERFLOW 1
142 "interrupt-level buffer overflow",
143 #define CE_TTY_BUF_OVERFLOW 2
144 "tty-level buffer overflow",
148 #define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
151 #define COM_LOCK() mtx_lock_spin(&cy_lock)
152 #define COM_UNLOCK() mtx_unlock_spin(&cy_lock)
158 /* types. XXX - should be elsewhere */
159 typedef u_char bool_t
; /* boolean */
161 /* queue of linear buffers */
163 u_char
*l_head
; /* next char to process */
164 u_char
*l_tail
; /* one past the last char to process */
165 struct lbq
*l_next
; /* next in queue */
166 bool_t l_queued
; /* nonzero if queued */
169 /* com device structure */
171 u_char state
; /* miscellaneous flag bits */
172 u_char etc
; /* pending Embedded Transmit Command */
173 u_char extra_state
; /* more flag bits, separate for order trick */
174 u_char gfrcr_image
; /* copy of value read from GFRCR */
175 u_char mcr_dtr
; /* MCR bit that is wired to DTR */
176 u_char mcr_image
; /* copy of value written to MCR */
177 u_char mcr_rts
; /* MCR bit that is wired to RTS */
178 int unit
; /* unit number */
181 * The high level of the driver never reads status registers directly
182 * because there would be too many side effects to handle conveniently.
183 * Instead, it reads copies of the registers stored here by the
186 u_char last_modem_status
; /* last MSR read by intr handler */
187 u_char prev_modem_status
; /* last MSR handled by high level */
189 u_char
*ibuf
; /* start of input buffer */
190 u_char
*ibufend
; /* end of input buffer */
191 u_char
*ibufold
; /* old input buffer, to be freed */
192 u_char
*ihighwater
; /* threshold in input buffer */
193 u_char
*iptr
; /* next free spot in input buffer */
194 int ibufsize
; /* size of ibuf (not include error bytes) */
195 int ierroff
; /* offset of error bytes in ibuf */
197 struct lbq obufq
; /* head of queue of output buffers */
198 struct lbq obufs
[2]; /* output buffers */
200 int cy_align
; /* index for register alignment */
201 cy_addr cy_iobase
; /* base address of this port's cyclom */
202 cy_addr iobase
; /* base address of this port's cd1400 */
203 int mcr_rts_reg
; /* cd1400 reg number of reg holding mcr_rts */
205 struct tty
*tp
; /* cross reference */
207 u_long bytes_in
; /* statistics */
209 u_int delta_error_counts
[CE_NTYPES
];
210 u_long error_counts
[CE_NTYPES
];
212 u_int recv_exception
; /* exception chars received */
213 u_int mdm
; /* modem signal changes */
215 u_int start_count
; /* no. of calls to cystart() */
216 u_int start_real
; /* no. of calls that did something */
218 u_char car
; /* CD1400 CAR shadow (if first unit in cd) */
219 u_char channel_control
;/* CD1400 CCR control command shadow */
220 u_char cor
[3]; /* CD1400 COR1-3 shadows */
221 u_char intr_enable
; /* CD1400 SRER shadow */
224 * Data area for output buffers. Someday we should build the output
225 * buffer queue without copying data.
231 devclass_t cy_devclass
;
232 char cy_driver_name
[] = "cy";
234 static void cd1400_channel_cmd(struct com_s
*com
, int cmd
);
235 static void cd1400_channel_cmd_wait(struct com_s
*com
);
236 static void cd_etc(struct com_s
*com
, int etc
);
237 static int cd_getreg(struct com_s
*com
, int reg
);
238 static void cd_setreg(struct com_s
*com
, int reg
, int val
);
239 static void cyinput(struct com_s
*com
);
240 static int cyparam(struct tty
*tp
, struct termios
*t
);
241 static void cypoll(void *arg
);
242 static void cysettimeout(void);
243 static int cysetwater(struct com_s
*com
, speed_t speed
);
244 static int cyspeed(speed_t speed
, u_long cy_clock
, int *prescaler_io
);
245 static void cystart(struct tty
*tp
);
246 static void comstop(struct tty
*tp
, int rw
);
247 static timeout_t cywakeup
;
248 static void disc_optim(struct tty
*tp
, struct termios
*t
,
251 static t_break_t cybreak
;
252 static t_modem_t cymodem
;
253 static t_open_t cyopen
;
254 static t_close_t cyclose
;
257 void cystatus(int unit
);
260 static struct mtx cy_lock
;
261 static int cy_inited
;
263 /* table and macro for fast conversion from a unit number to its com struct */
264 static struct com_s
*p_cy_addr
[NPORTS
];
265 #define cy_addr(unit) (p_cy_addr[unit])
267 static u_int cy_events
; /* input chars + weighted output completions */
268 static void *cy_fast_ih
;
269 static void *cy_slow_ih
;
270 static int cy_timeout
;
271 static int cy_timeouts_until_log
;
272 static struct callout_handle cy_timeout_handle
273 = CALLOUT_HANDLE_INITIALIZER(&cy_timeout_handle
);
276 static u_int cd_inbs
;
277 static u_int cy_inbs
;
278 static u_int cd_outbs
;
279 static u_int cy_outbs
;
280 static u_int cy_svrr_probes
;
281 static u_int cy_timeouts
;
284 static int cy_chip_offset
[] = {
285 0x0000, 0x0400, 0x0800, 0x0c00, 0x0200, 0x0600, 0x0a00, 0x0e00,
287 static int cy_nr_cd1400s
[NCY
];
288 static int cy_total_devices
;
289 #undef RxFifoThreshold
290 static int volatile RxFifoThreshold
= (CD1400_RX_FIFO_SIZE
/ 2);
293 cy_units(cy_addr cy_iobase
, int cy_align
)
296 u_char firmware_version
;
300 for (cyu
= 0; cyu
< CY_MAX_CD1400s
; ++cyu
) {
301 iobase
= cy_iobase
+ (cy_chip_offset
[cyu
] << cy_align
);
303 /* wait for chip to become ready for new command */
304 for (i
= 0; i
< 10; i
++) {
306 if (!cd_inb(iobase
, CD1400_CCR
, cy_align
))
310 /* clear the GFRCR register */
311 cd_outb(iobase
, CD1400_GFRCR
, cy_align
, 0);
313 /* issue a reset command */
314 cd_outb(iobase
, CD1400_CCR
, cy_align
,
315 CD1400_CCR_CMDRESET
| CD1400_CCR_FULLRESET
);
317 /* XXX bogus initialization to avoid a gcc bug/warning. */
318 firmware_version
= 0;
320 /* wait for the CD1400 to initialize itself */
321 for (i
= 0; i
< 200; i
++) {
324 /* retrieve firmware version */
325 firmware_version
= cd_inb(iobase
, CD1400_GFRCR
,
327 if ((firmware_version
& 0xf0) == 0x40)
332 * Anything in the 0x40-0x4F range is fine.
333 * If one CD1400 is bad then we don't support higher
334 * numbered good ones on this board.
336 if ((firmware_version
& 0xf0) != 0x40)
343 cyattach_common(cy_addr cy_iobase
, int cy_align
)
347 u_char firmware_version
;
353 while (cy_inited
!= 2)
354 if (atomic_cmpset_int(&cy_inited
, 0, 1)) {
355 mtx_init(&cy_lock
, cy_driver_name
, NULL
, MTX_SPIN
);
356 atomic_store_rel_int(&cy_inited
, 2);
359 adapter
= cy_total_devices
;
360 if ((u_int
)adapter
>= NCY
) {
362 "cy%d: can't attach adapter: insufficient cy devices configured\n",
366 ncyu
= cy_units(cy_iobase
, cy_align
);
369 cy_nr_cd1400s
[adapter
] = ncyu
;
372 unit
= adapter
* CY_MAX_PORTS
;
373 for (cyu
= 0; cyu
< ncyu
; ++cyu
) {
376 iobase
= (cy_addr
) (cy_iobase
377 + (cy_chip_offset
[cyu
] << cy_align
));
378 firmware_version
= cd_inb(iobase
, CD1400_GFRCR
, cy_align
);
380 /* Set up a receive timeout period of than 1+ ms. */
381 cd_outb(iobase
, CD1400_PPR
, cy_align
,
382 howmany(CY_CLOCK(firmware_version
)
383 / CD1400_PPR_PRESCALER
, 1000));
385 for (cdu
= 0; cdu
< CD1400_NO_OF_CHANNELS
; ++cdu
, ++unit
) {
389 com
= malloc(sizeof *com
, M_DEVBUF
, M_NOWAIT
| M_ZERO
);
393 com
->gfrcr_image
= firmware_version
;
394 if (CY_RTS_DTR_SWAPPED(firmware_version
)) {
395 com
->mcr_dtr
= CD1400_MSVR1_RTS
;
396 com
->mcr_rts
= CD1400_MSVR2_DTR
;
397 com
->mcr_rts_reg
= CD1400_MSVR2
;
399 com
->mcr_dtr
= CD1400_MSVR2_DTR
;
400 com
->mcr_rts
= CD1400_MSVR1_RTS
;
401 com
->mcr_rts_reg
= CD1400_MSVR1
;
403 com
->obufs
[0].l_head
= com
->obuf1
;
404 com
->obufs
[1].l_head
= com
->obuf2
;
406 com
->cy_align
= cy_align
;
407 com
->cy_iobase
= cy_iobase
;
408 com
->iobase
= iobase
;
409 com
->car
= ~CD1400_CAR_CHAN
;
411 tp
= com
->tp
= ttyalloc();
413 tp
->t_close
= cyclose
;
414 tp
->t_oproc
= cystart
;
415 tp
->t_stop
= comstop
;
416 tp
->t_param
= cyparam
;
417 tp
->t_break
= cybreak
;
418 tp
->t_modem
= cymodem
;
421 if (cysetwater(com
, tp
->t_init_in
.c_ispeed
) != 0) {
430 if (cy_fast_ih
== NULL
) {
431 swi_add(&tty_intr_event
, "cy", cypoll
, NULL
, SWI_TTY
, 0,
433 swi_add(&clk_intr_event
, "cy", cypoll
, NULL
, SWI_CLOCK
, 0,
436 ttycreate(tp
, TS_CALLOUT
, "c%r%r",
437 adapter
, unit
% CY_MAX_PORTS
);
441 /* ensure an edge for the next interrupt */
442 cy_outb(cy_iobase
, CY_CLEAR_INTR
, cy_align
, 0);
444 return (cy_addr(adapter
* CY_MAX_PORTS
));
448 cyopen(struct tty
*tp
, struct cdev
*dev
)
456 * We jump to this label after all non-interrupted sleeps to pick
457 * up any changes of the device state.
460 /* Encode per-board unit in LIVR for access in intr routines. */
461 cd_setreg(com
, CD1400_LIVR
,
462 (com
->unit
& CD1400_xIVR_CHAN
) << CD1400_xIVR_CHAN_SHIFT
);
465 * Flush fifos. This requires a full channel reset which
466 * also disables the transmitter and receiver. Recover
469 cd1400_channel_cmd(com
,
470 CD1400_CCR_CMDRESET
| CD1400_CCR_CHANRESET
);
471 cd1400_channel_cmd(com
, com
->channel_control
);
475 com
->prev_modem_status
= com
->last_modem_status
476 = cd_getreg(com
, CD1400_MSVR2
);
477 cd_setreg(com
, CD1400_SRER
,
479 = CD1400_SRER_MDMCH
| CD1400_SRER_RXDATA
);
488 cyclose(struct tty
*tp
)
497 iobase
= com
->iobase
;
503 cd_setreg(com
, CD1400_COR2
, com
->cor
[1] &= ~CD1400_COR2_ETC
);
506 cd_etc(com
, CD1400_ETC_STOPBREAK
);
507 cd1400_channel_cmd(com
, CD1400_CCR_CMDRESET
| CD1400_CCR_FTF
);
512 cd_setreg(com
, CD1400_SRER
, com
->intr_enable
= 0);
516 if ((tp
->t_cflag
& HUPCL
)
518 * XXX we will miss any carrier drop between here and the
519 * next open. Perhaps we should watch DCD even when the
520 * port is closed; it is not sufficient to check it at
521 * the next open because it might go up and down while
522 * we're not watching.
525 && !(com
->prev_modem_status
& CD1400_MSVR2_CD
)
526 && !(tp
->t_init_in
.c_cflag
& CLOCAL
))
527 || !(tp
->t_state
& TS_ISOPEN
)) {
528 (void)cymodem(tp
, 0, SER_DTR
);
530 /* Disable receiver (leave transmitter enabled). */
531 com
->channel_control
= CD1400_CCR_CMDCHANCTL
534 cd1400_channel_cmd(com
, com
->channel_control
);
539 tp
->t_actout
= FALSE
;
540 wakeup(&tp
->t_actout
);
541 wakeup(TSA_CARR_ON(tp
)); /* restart any wopeners */
547 * a) needs to be called with COM_LOCK() held, and
548 * b) needs to return with COM_LOCK() held.
551 cyinput(struct com_s
*com
)
561 if (!(tp
->t_state
& TS_ISOPEN
)) {
562 cy_events
-= (com
->iptr
- com
->ibuf
);
563 com
->iptr
= com
->ibuf
;
566 if (tp
->t_state
& TS_CAN_BYPASS_L_RINT
) {
568 * Avoid the grotesquely inefficient lineswitch routine
569 * (ttyinput) in "raw" mode. It usually takes about 450
570 * instructions (that's without canonical processing or echo!).
571 * slinput is reasonably fast (usually 40 instructions plus
577 * This may look odd, but it is using save-and-enable
578 * semantics instead of the save-and-disable semantics
579 * that are used everywhere else.
583 incc
= com
->iptr
- buf
;
584 if (tp
->t_rawq
.c_cc
+ incc
> tp
->t_ihiwat
585 && (com
->state
& CS_RTS_IFLOW
586 || tp
->t_iflag
& IXOFF
)
587 && !(tp
->t_state
& TS_TBLOCK
))
589 com
->delta_error_counts
[CE_TTY_BUF_OVERFLOW
]
590 += b_to_q((char *)buf
, incc
, &tp
->t_rawq
);
596 if (tp
->t_state
& TS_TTSTOP
597 && (tp
->t_iflag
& IXANY
598 || tp
->t_cc
[VSTART
] == tp
->t_cc
[VSTOP
])) {
599 tp
->t_state
&= ~TS_TTSTOP
;
600 tp
->t_lflag
&= ~FLUSHO
;
605 } while (buf
< com
->iptr
);
609 * This may look odd, but it is using save-and-enable
610 * semantics instead of the save-and-disable semantics
611 * that are used everywhere else.
615 line_status
= buf
[com
->ierroff
];
618 & (CD1400_RDSR_BREAK
| CD1400_RDSR_FE
| CD1400_RDSR_OE
| CD1400_RDSR_PE
)) {
619 if (line_status
& CD1400_RDSR_BREAK
)
621 if (line_status
& CD1400_RDSR_FE
)
623 if (line_status
& CD1400_RDSR_OE
)
625 if (line_status
& CD1400_RDSR_PE
)
628 ttyld_rint(tp
, recv_data
);
631 } while (buf
< com
->iptr
);
633 cy_events
-= (com
->iptr
- com
->ibuf
);
634 com
->iptr
= com
->ibuf
;
637 * There is now room for another low-level buffer full of input,
638 * so enable RTS if it is now disabled and there is room in the
641 if ((com
->state
& CS_RTS_IFLOW
) && !(com
->mcr_image
& com
->mcr_rts
) &&
642 !(tp
->t_state
& TS_TBLOCK
))
643 cd_setreg(com
, com
->mcr_rts_reg
,
644 com
->mcr_image
|= com
->mcr_rts
);
650 struct com_s
*basecom
;
659 COM_LOCK(); /* XXX could this be placed down lower in the loop? */
661 basecom
= (struct com_s
*)vcom
;
662 baseu
= basecom
->unit
;
663 cy_align
= basecom
->cy_align
;
664 cy_iobase
= basecom
->cy_iobase
;
665 unit
= baseu
/ CY_MAX_PORTS
;
667 /* check each CD1400 in turn */
668 for (cyu
= 0; cyu
< cy_nr_cd1400s
[unit
]; ++cyu
) {
669 iobase
= (cy_addr
) (cy_iobase
670 + (cy_chip_offset
[cyu
] << cy_align
));
671 /* poll to see if it has any work */
672 status
= cd_inb(iobase
, CD1400_SVRR
, cy_align
);
674 continue; // XXX - FILTER_STRAY?
678 /* service requests as appropriate, giving priority to RX */
679 if (status
& CD1400_SVRR_RXRDY
) {
691 save_rir
= cd_inb(iobase
, CD1400_RIR
, cy_align
);
693 /* enter rx service */
694 cd_outb(iobase
, CD1400_CAR
, cy_align
, save_rir
);
695 cy_addr(baseu
+ cyu
* CD1400_NO_OF_CHANNELS
)->car
696 = save_rir
& CD1400_CAR_CHAN
;
698 serv_type
= cd_inb(iobase
, CD1400_RIVR
, cy_align
);
700 + ((serv_type
>> CD1400_xIVR_CHAN_SHIFT
)
701 & CD1400_xIVR_CHAN
));
703 /* ack receive service */
704 serv_type
= cy_inb(iobase
, CY8_SVCACKR
, cy_align
);
706 com
= cy_addr(baseu
+
707 + ((serv_type
>> CD1400_xIVR_CHAN_SHIFT
)
708 & CD1400_xIVR_CHAN
));
711 if (serv_type
& CD1400_RIVR_EXCEPTION
) {
712 ++com
->recv_exception
;
713 line_status
= cd_inb(iobase
, CD1400_RDSR
, cy_align
);
714 /* break/unnattached error bits or real input? */
715 recv_data
= cd_inb(iobase
, CD1400_RDSR
, cy_align
);
717 if (line_status
& CD1400_RDSR_SPECIAL
718 && com
->tp
->t_hotchar
!= 0)
719 swi_sched(cy_fast_ih
, 0);
722 #if 1 /* XXX "intelligent" PFO error handling would break O error handling */
723 if (line_status
& (CD1400_RDSR_PE
|CD1400_RDSR_FE
|CD1400_RDSR_BREAK
)) {
725 Don't store PE if IGNPAR and BI if IGNBRK,
726 this hack allows "raw" tty optimization
727 works even if IGN* is set.
730 || !(com
->tp
->t_state
& TS_ISOPEN
)
731 || ((line_status
& (CD1400_RDSR_PE
|CD1400_RDSR_FE
))
732 && (com
->tp
->t_iflag
& IGNPAR
))
733 || ((line_status
& CD1400_RDSR_BREAK
)
734 && (com
->tp
->t_iflag
& IGNBRK
)))
736 if ( (line_status
& (CD1400_RDSR_PE
|CD1400_RDSR_FE
))
737 && (com
->tp
->t_state
& TS_CAN_BYPASS_L_RINT
)
738 && ((line_status
& CD1400_RDSR_FE
)
739 || ((line_status
& CD1400_RDSR_PE
)
740 && (com
->tp
->t_iflag
& INPCK
))))
746 if (com
->tp
->t_hotchar
!= 0 && recv_data
== com
->tp
->t_hotchar
)
747 swi_sched(cy_fast_ih
, 0);
750 if (ioptr
>= com
->ibufend
)
751 CE_RECORD(com
, CE_INTERRUPT_BUF_OVERFLOW
);
753 if (com
->tp
!= NULL
&& com
->tp
->t_do_timestamp
)
754 microtime(&com
->tp
->t_timestamp
);
756 ioptr
[0] = recv_data
;
757 ioptr
[com
->ierroff
] = line_status
;
759 if (ioptr
== com
->ihighwater
760 && com
->state
& CS_RTS_IFLOW
)
761 cd_outb(iobase
, com
->mcr_rts_reg
,
765 if (line_status
& CD1400_RDSR_OE
)
766 CE_RECORD(com
, CE_OVERRUN
);
772 count
= cd_inb(iobase
, CD1400_RDCR
, cy_align
);
775 com
->bytes_in
+= count
;
777 ifree
= com
->ibufend
- ioptr
;
782 if (com
->tp
!= NULL
&& com
->tp
->t_do_timestamp
)
783 microtime(&com
->tp
->t_timestamp
);
785 recv_data
= cd_inb(iobase
,
789 if (com
->tp
->t_hotchar
!= 0
791 == com
->tp
->t_hotchar
)
792 swi_sched(cy_fast_ih
,
795 ioptr
[0] = recv_data
;
796 ioptr
[com
->ierroff
] = 0;
798 } while (--ifree
!= 0);
800 com
->delta_error_counts
801 [CE_INTERRUPT_BUF_OVERFLOW
] += count
;
803 recv_data
= cd_inb(iobase
, CD1400_RDSR
,
806 if (com
->tp
->t_hotchar
!= 0
807 && recv_data
== com
->tp
->t_hotchar
)
808 swi_sched(cy_fast_ih
, 0);
810 } while (--count
!= 0);
812 if (com
->tp
!= NULL
&& com
->tp
->t_do_timestamp
)
813 microtime(&com
->tp
->t_timestamp
);
814 if (ioptr
<= com
->ihighwater
815 && ioptr
+ count
> com
->ihighwater
816 && com
->state
& CS_RTS_IFLOW
)
817 cd_outb(iobase
, com
->mcr_rts_reg
,
823 recv_data
= cd_inb(iobase
, CD1400_RDSR
,
826 if (com
->tp
->t_hotchar
!= 0
827 && recv_data
== com
->tp
->t_hotchar
)
828 swi_sched(cy_fast_ih
, 0);
830 ioptr
[0] = recv_data
;
831 ioptr
[com
->ierroff
] = 0;
833 } while (--count
!= 0);
839 /* terminate service context */
841 cd_outb(iobase
, CD1400_RIR
, cy_align
,
843 & ~(CD1400_RIR_RDIREQ
| CD1400_RIR_RBUSY
));
845 cd_outb(iobase
, CD1400_EOSRR
, cy_align
, 0);
848 if (status
& CD1400_SVRR_MDMCH
) {
858 save_mir
= cd_inb(iobase
, CD1400_MIR
, cy_align
);
860 /* enter modem service */
861 cd_outb(iobase
, CD1400_CAR
, cy_align
, save_mir
);
862 cy_addr(baseu
+ cyu
* CD1400_NO_OF_CHANNELS
)->car
863 = save_mir
& CD1400_CAR_CHAN
;
865 com
= cy_addr(baseu
+ cyu
* CD1400_NO_OF_CHANNELS
866 + (save_mir
& CD1400_MIR_CHAN
));
868 /* ack modem service */
869 vector
= cy_inb(iobase
, CY8_SVCACKM
, cy_align
);
872 + ((vector
>> CD1400_xIVR_CHAN_SHIFT
)
873 & CD1400_xIVR_CHAN
));
876 modem_status
= cd_inb(iobase
, CD1400_MSVR2
, cy_align
);
877 if (modem_status
!= com
->last_modem_status
) {
879 * Schedule high level to handle DCD changes. Note
880 * that we don't use the delta bits anywhere. Some
881 * UARTs mess them up, and it's easy to remember the
882 * previous bits and calculate the delta.
884 com
->last_modem_status
= modem_status
;
885 if (!(com
->state
& CS_CHECKMSR
)) {
886 cy_events
+= LOTS_OF_EVENTS
;
887 com
->state
|= CS_CHECKMSR
;
888 swi_sched(cy_fast_ih
, 0);
891 #ifdef SOFT_CTS_OFLOW
892 /* handle CTS change immediately for crisp flow ctl */
893 if (com
->state
& CS_CTS_OFLOW
) {
894 if (modem_status
& CD1400_MSVR2_CTS
) {
895 com
->state
|= CS_ODEVREADY
;
896 if (com
->state
>= (CS_BUSY
| CS_TTGO
898 && !(com
->intr_enable
899 & CD1400_SRER_TXRDY
))
900 cd_outb(iobase
, CD1400_SRER
,
904 & ~CD1400_SRER_TXMPTY
905 | CD1400_SRER_TXRDY
);
907 com
->state
&= ~CS_ODEVREADY
;
910 cd_outb(iobase
, CD1400_SRER
,
915 | CD1400_SRER_TXMPTY
);
921 /* terminate service context */
923 cd_outb(iobase
, CD1400_MIR
, cy_align
,
925 & ~(CD1400_MIR_RDIREQ
| CD1400_MIR_RBUSY
));
927 cd_outb(iobase
, CD1400_EOSRR
, cy_align
, 0);
930 if (status
& CD1400_SVRR_TXRDY
) {
939 save_tir
= cd_inb(iobase
, CD1400_TIR
, cy_align
);
941 /* enter tx service */
942 cd_outb(iobase
, CD1400_CAR
, cy_align
, save_tir
);
943 cy_addr(baseu
+ cyu
* CD1400_NO_OF_CHANNELS
)->car
944 = save_tir
& CD1400_CAR_CHAN
;
947 + cyu
* CD1400_NO_OF_CHANNELS
948 + (save_tir
& CD1400_TIR_CHAN
));
950 /* ack transmit service */
951 vector
= cy_inb(iobase
, CY8_SVCACKT
, cy_align
);
954 + ((vector
>> CD1400_xIVR_CHAN_SHIFT
)
955 & CD1400_xIVR_CHAN
));
958 if (com
->etc
!= ETC_NONE
) {
959 if (com
->intr_enable
& CD1400_SRER_TXRDY
) {
961 * Here due to sloppy SRER_TXRDY
962 * enabling. Ignore. Come back when
965 cd_outb(iobase
, CD1400_SRER
, cy_align
,
968 & ~CD1400_SRER_TXRDY
)
969 | CD1400_SRER_TXMPTY
);
970 goto terminate_tx_service
;
973 case CD1400_ETC_SENDBREAK
:
974 case CD1400_ETC_STOPBREAK
:
976 * Start the command. Come back on
977 * next tx empty interrupt, hopefully
978 * after command has been executed.
980 cd_outb(iobase
, CD1400_COR2
, cy_align
,
981 com
->cor
[1] |= CD1400_COR2_ETC
);
982 cd_outb(iobase
, CD1400_TDR
, cy_align
,
984 cd_outb(iobase
, CD1400_TDR
, cy_align
,
986 if (com
->etc
== CD1400_ETC_SENDBREAK
)
987 com
->etc
= ETC_BREAK_STARTING
;
989 com
->etc
= ETC_BREAK_ENDING
;
990 goto terminate_tx_service
;
991 case ETC_BREAK_STARTING
:
993 * BREAK is now on. Continue with
994 * SRER_TXMPTY processing, hopefully
997 com
->etc
= ETC_BREAK_STARTED
;
999 case ETC_BREAK_STARTED
:
1001 * Came back due to sloppy SRER_TXMPTY
1002 * enabling. Hope again.
1005 case ETC_BREAK_ENDING
:
1007 * BREAK is now off. Continue with
1008 * SRER_TXMPTY processing and don't
1009 * come back. The SWI handler will
1010 * restart tx interrupts if necessary.
1012 cd_outb(iobase
, CD1400_COR2
, cy_align
,
1014 &= ~CD1400_COR2_ETC
);
1015 com
->etc
= ETC_BREAK_ENDED
;
1016 if (!(com
->state
& CS_ODONE
)) {
1017 cy_events
+= LOTS_OF_EVENTS
;
1018 com
->state
|= CS_ODONE
;
1019 swi_sched(cy_fast_ih
, 0);
1022 case ETC_BREAK_ENDED
:
1024 * Shouldn't get here. Hope again.
1029 if (com
->intr_enable
& CD1400_SRER_TXMPTY
) {
1030 if (!(com
->extra_state
& CSE_ODONE
)) {
1031 cy_events
+= LOTS_OF_EVENTS
;
1032 com
->extra_state
|= CSE_ODONE
;
1033 swi_sched(cy_fast_ih
, 0);
1035 cd_outb(iobase
, CD1400_SRER
, cy_align
,
1037 &= ~CD1400_SRER_TXMPTY
);
1038 goto terminate_tx_service
;
1040 if (com
->state
>= (CS_BUSY
| CS_TTGO
| CS_ODEVREADY
)) {
1044 ioptr
= com
->obufq
.l_head
;
1045 ocount
= com
->obufq
.l_tail
- ioptr
;
1046 if (ocount
> CD1400_TX_FIFO_SIZE
)
1047 ocount
= CD1400_TX_FIFO_SIZE
;
1048 com
->bytes_out
+= ocount
;
1050 cd_outb(iobase
, CD1400_TDR
, cy_align
,
1052 while (--ocount
!= 0);
1053 com
->obufq
.l_head
= ioptr
;
1054 if (ioptr
>= com
->obufq
.l_tail
) {
1057 qp
= com
->obufq
.l_next
;
1058 qp
->l_queued
= FALSE
;
1061 com
->obufq
.l_head
= qp
->l_head
;
1062 com
->obufq
.l_tail
= qp
->l_tail
;
1063 com
->obufq
.l_next
= qp
;
1065 /* output just completed */
1066 com
->state
&= ~CS_BUSY
;
1069 * The setting of CSE_ODONE may be
1070 * stale here. We currently only
1071 * use it when CS_BUSY is set, and
1072 * fixing it when we clear CS_BUSY
1075 if (com
->extra_state
& CSE_ODONE
) {
1076 cy_events
-= LOTS_OF_EVENTS
;
1077 com
->extra_state
&= ~CSE_ODONE
;
1080 cd_outb(iobase
, CD1400_SRER
, cy_align
,
1083 & ~CD1400_SRER_TXRDY
)
1084 | CD1400_SRER_TXMPTY
);
1086 if (!(com
->state
& CS_ODONE
)) {
1087 cy_events
+= LOTS_OF_EVENTS
;
1088 com
->state
|= CS_ODONE
;
1090 /* handle at high level ASAP */
1091 swi_sched(cy_fast_ih
, 0);
1096 /* terminate service context */
1097 terminate_tx_service
:
1099 cd_outb(iobase
, CD1400_TIR
, cy_align
,
1101 & ~(CD1400_TIR_RDIREQ
| CD1400_TIR_RBUSY
));
1103 cd_outb(iobase
, CD1400_EOSRR
, cy_align
, 0);
1108 /* ensure an edge for the next interrupt */
1109 cy_outb(cy_iobase
, CY_CLEAR_INTR
, cy_align
, 0);
1111 swi_sched(cy_slow_ih
, SWI_DELAY
);
1114 return (FILTER_HANDLED
);
1118 cybreak(struct tty
*tp
, int sig
)
1124 cd_etc(com
, CD1400_ETC_SENDBREAK
);
1126 cd_etc(com
, CD1400_ETC_STOPBREAK
);
1140 for (unit
= 0; unit
< NPORTS
; ++unit
) {
1145 com
= cy_addr(unit
);
1151 * XXX forget any events related to closed devices
1152 * (actually never opened devices) so that we don't
1157 incc
= com
->iptr
- com
->ibuf
;
1158 com
->iptr
= com
->ibuf
;
1159 if (com
->state
& CS_CHECKMSR
) {
1160 incc
+= LOTS_OF_EVENTS
;
1161 com
->state
&= ~CS_CHECKMSR
;
1168 "cy%d: %d events for device with no tp\n",
1172 if (com
->iptr
!= com
->ibuf
) {
1179 if (com
->state
& CS_CHECKMSR
) {
1180 u_char delta_modem_status
;
1185 delta_modem_status
= com
->last_modem_status
1186 ^ com
->prev_modem_status
;
1187 com
->prev_modem_status
= com
->last_modem_status
;
1188 cy_events
-= LOTS_OF_EVENTS
;
1189 com
->state
&= ~CS_CHECKMSR
;
1192 if (delta_modem_status
& CD1400_MSVR2_CD
)
1194 com
->prev_modem_status
& CD1400_MSVR2_CD
);
1196 if (com
->extra_state
& CSE_ODONE
) {
1199 cy_events
-= LOTS_OF_EVENTS
;
1200 com
->extra_state
&= ~CSE_ODONE
;
1203 if (!(com
->state
& CS_BUSY
)) {
1204 tp
->t_state
&= ~TS_BUSY
;
1207 if (com
->etc
!= ETC_NONE
) {
1208 if (com
->etc
== ETC_BREAK_ENDED
)
1209 com
->etc
= ETC_NONE
;
1213 if (com
->state
& CS_ODONE
) {
1216 cy_events
-= LOTS_OF_EVENTS
;
1217 com
->state
&= ~CS_ODONE
;
1225 if (cy_events
>= LOTS_OF_EVENTS
)
1230 cyparam(struct tty
*tp
, struct termios
*t
)
1248 /* check requested parameters */
1249 cy_clock
= CY_CLOCK(com
->gfrcr_image
);
1250 idivisor
= cyspeed(t
->c_ispeed
, cy_clock
, &iprescaler
);
1253 odivisor
= cyspeed(t
->c_ospeed
!= 0 ? t
->c_ospeed
: tp
->t_ospeed
,
1254 cy_clock
, &oprescaler
);
1258 /* parameters are OK, convert them to the com struct and the device */
1260 if (t
->c_ospeed
== 0)
1261 (void)cymodem(tp
, 0, SER_DTR
);
1263 (void)cymodem(tp
, SER_DTR
, 0);
1265 (void) cysetwater(com
, t
->c_ispeed
);
1267 /* XXX we don't actually change the speed atomically. */
1269 cd_setreg(com
, CD1400_RBPR
, idivisor
);
1270 cd_setreg(com
, CD1400_RCOR
, iprescaler
);
1271 cd_setreg(com
, CD1400_TBPR
, odivisor
);
1272 cd_setreg(com
, CD1400_TCOR
, oprescaler
);
1277 * transmitter enable (always set)
1280 opt
= CD1400_CCR_CMDCHANCTL
| CD1400_CCR_XMTEN
1281 | (cflag
& CREAD
? CD1400_CCR_RCVEN
: CD1400_CCR_RCVDIS
);
1282 if (opt
!= com
->channel_control
) {
1283 com
->channel_control
= opt
;
1284 cd1400_channel_cmd(com
, opt
);
1288 /* set special chars */
1289 /* XXX if one is _POSIX_VDISABLE, can't use some others */
1290 if (t
->c_cc
[VSTOP
] != _POSIX_VDISABLE
)
1291 cd_setreg(com
, CD1400_SCHR1
, t
->c_cc
[VSTOP
]);
1292 if (t
->c_cc
[VSTART
] != _POSIX_VDISABLE
)
1293 cd_setreg(com
, CD1400_SCHR2
, t
->c_cc
[VSTART
]);
1294 if (t
->c_cc
[VINTR
] != _POSIX_VDISABLE
)
1295 cd_setreg(com
, CD1400_SCHR3
, t
->c_cc
[VINTR
]);
1296 if (t
->c_cc
[VSUSP
] != _POSIX_VDISABLE
)
1297 cd_setreg(com
, CD1400_SCHR4
, t
->c_cc
[VSUSP
]);
1301 * set channel option register 1 -
1308 if (cflag
& PARENB
) {
1310 opt
|= CD1400_COR1_PARODD
;
1311 opt
|= CD1400_COR1_PARNORMAL
;
1314 if (!(iflag
& INPCK
))
1315 opt
|= CD1400_COR1_NOINPCK
;
1318 if (cflag
& CSTOPB
) {
1320 opt
|= CD1400_COR1_STOP2
;
1323 switch (cflag
& CSIZE
) {
1326 opt
|= CD1400_COR1_CS5
;
1330 opt
|= CD1400_COR1_CS6
;
1334 opt
|= CD1400_COR1_CS7
;
1338 opt
|= CD1400_COR1_CS8
;
1342 if (opt
!= com
->cor
[0]) {
1343 cor_change
|= CD1400_CCR_COR1
;
1344 cd_setreg(com
, CD1400_COR1
, com
->cor
[0] = opt
);
1348 * Set receive time-out period, normally to max(one char time, 5 ms).
1350 itimeout
= (1000 * bits
+ t
->c_ispeed
- 1) / t
->c_ispeed
;
1356 if (itimeout
< MIN_RTP
)
1358 if (!(t
->c_lflag
& ICANON
) && t
->c_cc
[VMIN
] != 0 && t
->c_cc
[VTIME
] != 0
1359 && t
->c_cc
[VTIME
] * 10 > itimeout
)
1360 itimeout
= t
->c_cc
[VTIME
] * 10;
1363 cd_setreg(com
, CD1400_RTPR
, itimeout
);
1366 * set channel option register 2 -
1372 opt
|= CD1400_COR2_IXANY
;
1374 opt
|= CD1400_COR2_IXOFF
;
1376 #ifndef SOFT_CTS_OFLOW
1377 if (cflag
& CCTS_OFLOW
)
1378 opt
|= CD1400_COR2_CCTS_OFLOW
;
1382 if (opt
!= com
->cor
[1]) {
1383 cor_change
|= CD1400_CCR_COR2
;
1384 cd_setreg(com
, CD1400_COR2
, com
->cor
[1] = opt
);
1390 * set channel option register 3 -
1391 * receiver FIFO interrupt threshold
1394 opt
= RxFifoThreshold
;
1396 if (t
->c_lflag
& ICANON
)
1397 opt
|= CD1400_COR3_SCD34
; /* detect INTR & SUSP chars */
1399 /* detect and transparently handle START and STOP chars */
1400 opt
|= CD1400_COR3_FCT
| CD1400_COR3_SCD12
;
1402 if (opt
!= com
->cor
[2]) {
1403 cor_change
|= CD1400_CCR_COR3
;
1404 cd_setreg(com
, CD1400_COR3
, com
->cor
[2] = opt
);
1407 /* notify the CD1400 if COR1-3 have changed */
1409 cd1400_channel_cmd(com
, CD1400_CCR_CMDCORCHG
| cor_change
);
1412 * set channel option register 4 -
1415 * received exception processing
1419 opt
|= CD1400_COR4_IGNCR
;
1422 * we need a new ttyinput() for this, as we don't want to
1423 * have ICRNL && INLCR being done in both layers, or to have
1424 * synchronisation problems
1427 opt
|= CD1400_COR4_ICRNL
;
1429 opt
|= CD1400_COR4_INLCR
;
1432 opt
|= CD1400_COR4_IGNBRK
| CD1400_COR4_NOBRKINT
;
1434 * The `-ignbrk -brkint parmrk' case is not handled by the hardware,
1435 * so only tell the hardware about -brkint if -parmrk.
1437 if (!(iflag
& (BRKINT
| PARMRK
)))
1438 opt
|= CD1400_COR4_NOBRKINT
;
1440 /* XXX using this "intelligence" breaks reporting of overruns. */
1442 opt
|= CD1400_COR4_PFO_DISCARD
;
1445 opt
|= CD1400_COR4_PFO_ESC
;
1447 opt
|= CD1400_COR4_PFO_NUL
;
1450 opt
|= CD1400_COR4_PFO_EXCEPTION
;
1452 cd_setreg(com
, CD1400_COR4
, opt
);
1455 * set channel option register 5 -
1459 opt
|= CD1400_COR5_ISTRIP
;
1460 if (t
->c_iflag
& IEXTEN
)
1461 /* enable LNEXT (e.g. ctrl-v quoting) handling */
1462 opt
|= CD1400_COR5_LNEXT
;
1464 if (t
->c_oflag
& ONLCR
)
1465 opt
|= CD1400_COR5_ONLCR
;
1466 if (t
->c_oflag
& OCRNL
)
1467 opt
|= CD1400_COR5_OCRNL
;
1469 cd_setreg(com
, CD1400_COR5
, opt
);
1472 * We always generate modem status change interrupts for CD changes.
1473 * Among other things, this is necessary to track TS_CARR_ON for
1474 * pstat to print even when the driver doesn't care. CD changes
1475 * should be rare so interrupts for them are not worth extra code to
1476 * avoid. We avoid interrupts for other modem status changes (except
1477 * for CTS changes when SOFT_CTS_OFLOW is configured) since this is
1478 * simplest and best.
1482 * set modem change option register 1
1483 * generate modem interrupts on which 1 -> 0 input transitions
1484 * also controls auto-DTR output flow-control, which we don't use
1486 opt
= CD1400_MCOR1_CDzd
;
1487 #ifdef SOFT_CTS_OFLOW
1488 if (cflag
& CCTS_OFLOW
)
1489 opt
|= CD1400_MCOR1_CTSzd
;
1491 cd_setreg(com
, CD1400_MCOR1
, opt
);
1494 * set modem change option register 2
1495 * generate modem interrupts on specific 0 -> 1 input transitions
1497 opt
= CD1400_MCOR2_CDod
;
1498 #ifdef SOFT_CTS_OFLOW
1499 if (cflag
& CCTS_OFLOW
)
1500 opt
|= CD1400_MCOR2_CTSod
;
1502 cd_setreg(com
, CD1400_MCOR2
, opt
);
1505 * XXX should have done this long ago, but there is too much state
1506 * to change all atomically.
1511 com
->state
&= ~CS_TTGO
;
1512 if (!(tp
->t_state
& TS_TTSTOP
))
1513 com
->state
|= CS_TTGO
;
1514 if (cflag
& CRTS_IFLOW
) {
1515 com
->state
|= CS_RTS_IFLOW
;
1517 * If CS_RTS_IFLOW just changed from off to on, the change
1518 * needs to be propagated to CD1400_MSVR1_RTS. This isn't urgent,
1519 * so do it later by calling cystart() instead of repeating
1520 * a lot of code from cystart() here.
1522 } else if (com
->state
& CS_RTS_IFLOW
) {
1523 com
->state
&= ~CS_RTS_IFLOW
;
1525 * CS_RTS_IFLOW just changed from on to off. Force CD1400_MSVR1_RTS
1526 * on here, since cystart() won't do it later.
1528 cd_setreg(com
, com
->mcr_rts_reg
,
1529 com
->mcr_image
|= com
->mcr_rts
);
1533 * Set up state to handle output flow control.
1534 * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
1535 * Now has 10+ msec latency, while CTS flow has 50- usec latency.
1537 com
->state
|= CS_ODEVREADY
;
1538 #ifdef SOFT_CTS_OFLOW
1539 com
->state
&= ~CS_CTS_OFLOW
;
1540 if (cflag
& CCTS_OFLOW
) {
1541 com
->state
|= CS_CTS_OFLOW
;
1542 if (!(com
->last_modem_status
& CD1400_MSVR2_CTS
))
1543 com
->state
&= ~CS_ODEVREADY
;
1546 /* XXX shouldn't call functions while intrs are disabled. */
1547 disc_optim(tp
, t
, com
);
1550 * Recover from fiddling with CS_TTGO. We used to call cyintr1()
1551 * unconditionally, but that defeated the careful discarding of
1552 * stale input in cyopen().
1554 if (com
->state
>= (CS_BUSY
| CS_TTGO
))
1557 if (com
->state
>= (CS_BUSY
| CS_TTGO
| CS_ODEVREADY
)) {
1558 if (!(com
->intr_enable
& CD1400_SRER_TXRDY
))
1559 cd_setreg(com
, CD1400_SRER
,
1561 = (com
->intr_enable
& ~CD1400_SRER_TXMPTY
)
1562 | CD1400_SRER_TXRDY
);
1564 if (com
->intr_enable
& CD1400_SRER_TXRDY
)
1565 cd_setreg(com
, CD1400_SRER
,
1567 = (com
->intr_enable
& ~CD1400_SRER_TXRDY
)
1568 | CD1400_SRER_TXMPTY
);
1575 if (com
->ibufold
!= NULL
) {
1576 free(com
->ibufold
, M_DEVBUF
);
1577 com
->ibufold
= NULL
;
1583 cysetwater(struct com_s
*com
, speed_t speed
)
1591 * Make the buffer size large enough to handle a softtty interrupt
1592 * latency of about 2 ticks without loss of throughput or data
1593 * (about 3 ticks if input flow control is not used or not honoured,
1594 * but a bit less for CS5-CS7 modes).
1596 cp4ticks
= speed
/ 10 / hz
* 4;
1597 for (ibufsize
= 128; ibufsize
< cp4ticks
;)
1599 if (ibufsize
== com
->ibufsize
) {
1604 * Allocate input buffer. The extra factor of 2 in the size is
1605 * to allow for an error byte for each input byte.
1607 ibuf
= malloc(2 * ibufsize
, M_DEVBUF
, M_NOWAIT
);
1612 /* Initialize non-critical variables. */
1613 com
->ibufold
= com
->ibuf
;
1614 com
->ibufsize
= ibufsize
;
1617 tp
->t_ififosize
= 2 * ibufsize
;
1618 tp
->t_ispeedwat
= (speed_t
)-1;
1619 tp
->t_ospeedwat
= (speed_t
)-1;
1623 * Read current input buffer, if any. Continue with interrupts
1628 if (com
->iptr
!= com
->ibuf
)
1632 * Initialize critical variables, including input buffer watermarks.
1633 * The external device is asked to stop sending when the buffer
1634 * exactly reaches high water, or when the high level requests it.
1635 * The high level is notified immediately (rather than at a later
1636 * clock tick) when this watermark is reached.
1637 * The buffer size is chosen so the watermark should almost never
1639 * The low watermark is invisibly 0 since the buffer is always
1640 * emptied all at once.
1642 com
->iptr
= com
->ibuf
= ibuf
;
1643 com
->ibufend
= ibuf
+ ibufsize
;
1644 com
->ierroff
= ibufsize
;
1645 com
->ihighwater
= ibuf
+ 3 * ibufsize
/ 4;
1653 cystart(struct tty
*tp
)
1671 if (tp
->t_state
& TS_TTSTOP
) {
1672 com
->state
&= ~CS_TTGO
;
1673 if (com
->intr_enable
& CD1400_SRER_TXRDY
)
1674 cd_setreg(com
, CD1400_SRER
,
1676 = (com
->intr_enable
& ~CD1400_SRER_TXRDY
)
1677 | CD1400_SRER_TXMPTY
);
1679 com
->state
|= CS_TTGO
;
1680 if (com
->state
>= (CS_BUSY
| CS_TTGO
| CS_ODEVREADY
)
1681 && !(com
->intr_enable
& CD1400_SRER_TXRDY
))
1682 cd_setreg(com
, CD1400_SRER
,
1684 = (com
->intr_enable
& ~CD1400_SRER_TXMPTY
)
1685 | CD1400_SRER_TXRDY
);
1687 if (tp
->t_state
& TS_TBLOCK
) {
1688 if (com
->mcr_image
& com
->mcr_rts
&& com
->state
& CS_RTS_IFLOW
)
1690 outb(com
->modem_ctl_port
, com
->mcr_image
&= ~CD1400_MSVR1_RTS
);
1692 cd_setreg(com
, com
->mcr_rts_reg
,
1693 com
->mcr_image
&= ~com
->mcr_rts
);
1696 if (!(com
->mcr_image
& com
->mcr_rts
)
1697 && com
->iptr
< com
->ihighwater
1698 && com
->state
& CS_RTS_IFLOW
)
1700 outb(com
->modem_ctl_port
, com
->mcr_image
|= CD1400_MSVR1_RTS
);
1702 cd_setreg(com
, com
->mcr_rts_reg
,
1703 com
->mcr_image
|= com
->mcr_rts
);
1708 if (tp
->t_state
& (TS_TIMEOUT
| TS_TTSTOP
)) {
1713 if (tp
->t_outq
.c_cc
!= 0) {
1717 if (!com
->obufs
[0].l_queued
) {
1721 com
->obufs
[0].l_tail
1722 = com
->obuf1
+ q_to_b(&tp
->t_outq
, com
->obuf1
,
1724 com
->obufs
[0].l_next
= NULL
;
1725 com
->obufs
[0].l_queued
= TRUE
;
1728 if (com
->state
& CS_BUSY
) {
1729 qp
= com
->obufq
.l_next
;
1730 while ((next
= qp
->l_next
) != NULL
)
1732 qp
->l_next
= &com
->obufs
[0];
1734 com
->obufq
.l_head
= com
->obufs
[0].l_head
;
1735 com
->obufq
.l_tail
= com
->obufs
[0].l_tail
;
1736 com
->obufq
.l_next
= &com
->obufs
[0];
1737 com
->state
|= CS_BUSY
;
1738 if (com
->state
>= (CS_BUSY
| CS_TTGO
1740 cd_setreg(com
, CD1400_SRER
,
1743 & ~CD1400_SRER_TXMPTY
)
1744 | CD1400_SRER_TXRDY
);
1749 if (tp
->t_outq
.c_cc
!= 0 && !com
->obufs
[1].l_queued
) {
1753 com
->obufs
[1].l_tail
1754 = com
->obuf2
+ q_to_b(&tp
->t_outq
, com
->obuf2
,
1756 com
->obufs
[1].l_next
= NULL
;
1757 com
->obufs
[1].l_queued
= TRUE
;
1760 if (com
->state
& CS_BUSY
) {
1761 qp
= com
->obufq
.l_next
;
1762 while ((next
= qp
->l_next
) != NULL
)
1764 qp
->l_next
= &com
->obufs
[1];
1766 com
->obufq
.l_head
= com
->obufs
[1].l_head
;
1767 com
->obufq
.l_tail
= com
->obufs
[1].l_tail
;
1768 com
->obufq
.l_next
= &com
->obufs
[1];
1769 com
->state
|= CS_BUSY
;
1770 if (com
->state
>= (CS_BUSY
| CS_TTGO
1772 cd_setreg(com
, CD1400_SRER
,
1775 & ~CD1400_SRER_TXMPTY
)
1776 | CD1400_SRER_TXRDY
);
1781 tp
->t_state
|= TS_BUSY
;
1790 if (com
->state
>= (CS_BUSY
| CS_TTGO
))
1791 cyintr1(com
); /* fake interrupt to start output */
1800 comstop(struct tty
*tp
, int rw
)
1810 com
->obufs
[0].l_queued
= FALSE
;
1811 com
->obufs
[1].l_queued
= FALSE
;
1812 if (com
->extra_state
& CSE_ODONE
) {
1813 cy_events
-= LOTS_OF_EVENTS
;
1814 com
->extra_state
&= ~CSE_ODONE
;
1815 if (com
->etc
!= ETC_NONE
) {
1816 if (com
->etc
== ETC_BREAK_ENDED
)
1817 com
->etc
= ETC_NONE
;
1821 com
->tp
->t_state
&= ~TS_BUSY
;
1822 if (com
->state
& CS_ODONE
)
1823 cy_events
-= LOTS_OF_EVENTS
;
1824 com
->state
&= ~(CS_ODONE
| CS_BUSY
);
1827 /* XXX no way to reset only input fifo. */
1828 cy_events
-= (com
->iptr
- com
->ibuf
);
1829 com
->iptr
= com
->ibuf
;
1835 if (rw
& FWRITE
&& com
->etc
== ETC_NONE
)
1836 cd1400_channel_cmd(com
, CD1400_CCR_CMDRESET
| CD1400_CCR_FTF
);
1841 cymodem(struct tty
*tp
, int sigon
, int sigoff
)
1848 if (sigon
== 0 && sigoff
== 0) {
1850 mcr
= com
->mcr_image
;
1851 if (mcr
& com
->mcr_dtr
)
1853 if (mcr
& com
->mcr_rts
)
1854 /* XXX wired on for Cyclom-8Ys */
1858 * We must read the modem status from the hardware because
1859 * we don't generate modem status change interrupts for all
1860 * changes, so com->prev_modem_status is not guaranteed to
1861 * be up to date. This is safe, unlike for sio, because
1862 * reading the status register doesn't clear pending modem
1863 * status change interrupts.
1865 msr
= cd_getreg(com
, CD1400_MSVR2
);
1867 if (msr
& CD1400_MSVR2_CTS
)
1869 if (msr
& CD1400_MSVR2_CD
)
1871 if (msr
& CD1400_MSVR2_DSR
)
1873 if (msr
& CD1400_MSVR2_RI
)
1874 /* XXX not connected except for Cyclom-16Y? */
1878 mcr
= com
->mcr_image
;
1879 if (sigon
& SER_DTR
)
1880 mcr
|= com
->mcr_dtr
;
1881 if (sigoff
& SER_DTR
)
1882 mcr
&= ~com
->mcr_dtr
;
1883 if (sigon
& SER_RTS
)
1884 mcr
|= com
->mcr_rts
;
1885 if (sigoff
& SER_RTS
)
1886 mcr
&= ~com
->mcr_rts
;
1889 com
->mcr_image
= mcr
;
1890 cd_setreg(com
, CD1400_MSVR1
, mcr
);
1891 cd_setreg(com
, CD1400_MSVR2
, mcr
);
1905 * Set our timeout period to 1 second if no polled devices are open.
1906 * Otherwise set it to max(1/200, 1/hz).
1907 * Enable timeouts iff some device is open.
1909 untimeout(cywakeup
, (void *)NULL
, cy_timeout_handle
);
1912 for (unit
= 0; unit
< NPORTS
; ++unit
) {
1913 com
= cy_addr(unit
);
1914 if (com
!= NULL
&& com
->tp
!= NULL
1915 && com
->tp
->t_state
& TS_ISOPEN
) {
1920 cy_timeouts_until_log
= hz
/ cy_timeout
;
1921 cy_timeout_handle
= timeout(cywakeup
, (void *)NULL
,
1924 /* Flush error messages, if any. */
1925 cy_timeouts_until_log
= 1;
1926 cywakeup((void *)NULL
);
1927 untimeout(cywakeup
, (void *)NULL
, cy_timeout_handle
);
1932 cywakeup(void *chan
)
1937 cy_timeout_handle
= timeout(cywakeup
, (void *)NULL
, cy_timeout
);
1940 * Check for and log errors, but not too often.
1942 if (--cy_timeouts_until_log
> 0)
1944 cy_timeouts_until_log
= hz
/ cy_timeout
;
1945 for (unit
= 0; unit
< NPORTS
; ++unit
) {
1948 com
= cy_addr(unit
);
1951 for (errnum
= 0; errnum
< CE_NTYPES
; ++errnum
) {
1957 delta
= com
->delta_error_counts
[errnum
];
1958 com
->delta_error_counts
[errnum
] = 0;
1963 total
= com
->error_counts
[errnum
] += delta
;
1964 log(LOG_ERR
, "cy%d: %u more %s%s (total %lu)\n",
1965 unit
, delta
, error_desc
[errnum
],
1966 delta
== 1 ? "" : "s", total
);
1972 disc_optim(struct tty
*tp
, struct termios
*t
, struct com_s
*com
)
1974 #ifndef SOFT_HOTCHAR
1979 #ifndef SOFT_HOTCHAR
1980 opt
= com
->cor
[2] & ~CD1400_COR3_SCD34
;
1981 if (com
->tp
->t_hotchar
!= 0) {
1982 cd_setreg(com
, CD1400_SCHR3
, com
->tp
->t_hotchar
);
1983 cd_setreg(com
, CD1400_SCHR4
, com
->tp
->t_hotchar
);
1984 opt
|= CD1400_COR3_SCD34
;
1986 if (opt
!= com
->cor
[2]) {
1987 cd_setreg(com
, CD1400_COR3
, com
->cor
[2] = opt
);
1988 cd1400_channel_cmd(com
, CD1400_CCR_CMDCORCHG
| CD1400_CCR_COR3
);
1994 /* standard line discipline input routine */
1996 cyinput(int c
, struct tty
*tp
)
1998 /* XXX duplicate ttyinput(), but without the IXOFF/IXON/ISTRIP/IPARMRK
1999 * bits, as they are done by the CD1400. Hardly worth the effort,
2000 * given that high-throughput session are raw anyhow.
2006 cyspeed(speed_t speed
, u_long cy_clock
, int *prescaler_io
)
2016 if (speed
< 0 || speed
> 150000)
2019 /* determine which prescaler to use */
2020 for (prescaler_unit
= 4, prescaler
= 2048; prescaler_unit
;
2021 prescaler_unit
--, prescaler
>>= 2) {
2022 if (cy_clock
/ prescaler
/ speed
> 63)
2026 divider
= (cy_clock
/ prescaler
* 2 / speed
+ 1) / 2; /* round off */
2029 actual
= cy_clock
/prescaler
/divider
;
2031 /* 10 times error in percent: */
2032 error
= ((actual
- (long)speed
) * 2000 / (long)speed
+ 1) / 2;
2034 /* 3.0% max error tolerance */
2035 if (error
< -30 || error
> 30)
2038 *prescaler_io
= prescaler_unit
;
2043 cd1400_channel_cmd(struct com_s
*com
, int cmd
)
2045 cd1400_channel_cmd_wait(com
);
2046 cd_setreg(com
, CD1400_CCR
, cmd
);
2047 cd1400_channel_cmd_wait(com
);
2051 cd1400_channel_cmd_wait(struct com_s
*com
)
2053 struct timeval start
;
2057 if (cd_getreg(com
, CD1400_CCR
) == 0)
2061 if (cd_getreg(com
, CD1400_CCR
) == 0)
2064 usec
= 1000000 * (tv
.tv_sec
- start
.tv_sec
) +
2065 tv
.tv_usec
- start
.tv_usec
;
2068 "cy%d: channel command timeout (%ld usec)\n",
2076 cd_etc(struct com_s
*com
, int etc
)
2080 * We can't change the hardware's ETC state while there are any
2081 * characters in the tx fifo, since those characters would be
2082 * interpreted as commands! Unputting characters from the fifo
2083 * is difficult, so we wait up to 12 character times for the fifo
2084 * to drain. The command will be delayed for up to 2 character
2085 * times for the tx to become empty. Unputting characters from
2086 * the tx holding and shift registers is impossible, so we wait
2087 * for the tx to become empty so that the command is sure to be
2088 * executed soon after we issue it.
2092 if (com
->etc
== etc
)
2094 if ((etc
== CD1400_ETC_SENDBREAK
2095 && (com
->etc
== ETC_BREAK_STARTING
2096 || com
->etc
== ETC_BREAK_STARTED
))
2097 || (etc
== CD1400_ETC_STOPBREAK
2098 && (com
->etc
== ETC_BREAK_ENDING
|| com
->etc
== ETC_BREAK_ENDED
2099 || com
->etc
== ETC_NONE
))) {
2105 cd_setreg(com
, CD1400_SRER
,
2107 = (com
->intr_enable
& ~CD1400_SRER_TXRDY
) | CD1400_SRER_TXMPTY
);
2111 while (com
->etc
== etc
2112 && tsleep(&com
->etc
, TTIPRI
| PCATCH
, "cyetc", 0) == 0)
2117 cd_getreg(struct com_s
*com
, int reg
)
2119 struct com_s
*basecom
;
2128 basecom
= cy_addr(com
->unit
& ~(CD1400_NO_OF_CHANNELS
- 1));
2129 car
= com
->unit
& CD1400_CAR_CHAN
;
2130 cy_align
= com
->cy_align
;
2131 iobase
= com
->iobase
;
2135 if (!mtx_owned(&cy_lock
)) {
2140 if (basecom
->car
!= car
)
2141 cd_outb(iobase
, CD1400_CAR
, cy_align
, basecom
->car
= car
);
2142 val
= cd_inb(iobase
, reg
, cy_align
);
2152 cd_setreg(struct com_s
*com
, int reg
, int val
)
2154 struct com_s
*basecom
;
2162 basecom
= cy_addr(com
->unit
& ~(CD1400_NO_OF_CHANNELS
- 1));
2163 car
= com
->unit
& CD1400_CAR_CHAN
;
2164 cy_align
= com
->cy_align
;
2165 iobase
= com
->iobase
;
2169 if (!mtx_owned(&cy_lock
)) {
2174 if (basecom
->car
!= car
)
2175 cd_outb(iobase
, CD1400_CAR
, cy_align
, basecom
->car
= car
);
2176 cd_outb(iobase
, reg
, cy_align
, val
);
2194 com
= cy_addr(unit
);
2195 printf("info for channel %d\n", unit
);
2196 printf("------------------\n");
2197 printf("total cyclom service probes:\t%d\n", cy_svrr_probes
);
2198 printf("calls to upper layer:\t\t%d\n", cy_timeouts
);
2201 iobase
= com
->iobase
;
2203 printf("cd1400 base address:\\tt%p\n", iobase
);
2204 printf("saved channel_control:\t\t0x%02x\n", com
->channel_control
);
2205 printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
2206 com
->cor
[0], com
->cor
[1], com
->cor
[2]);
2207 printf("service request enable reg:\t0x%02x (0x%02x cached)\n",
2208 cd_getreg(com
, CD1400_SRER
), com
->intr_enable
);
2209 printf("service request register:\t0x%02x\n",
2210 cd_inb(iobase
, CD1400_SVRR
, com
->cy_align
));
2211 printf("modem status:\t\t\t0x%02x (0x%02x cached)\n",
2212 cd_getreg(com
, CD1400_MSVR2
), com
->prev_modem_status
);
2213 printf("rx/tx/mdm interrupt registers:\t0x%02x 0x%02x 0x%02x\n",
2214 cd_inb(iobase
, CD1400_RIR
, com
->cy_align
),
2215 cd_inb(iobase
, CD1400_TIR
, com
->cy_align
),
2216 cd_inb(iobase
, CD1400_MIR
, com
->cy_align
));
2218 printf("com state:\t\t\t0x%02x\n", com
->state
);
2219 printf("calls to cystart():\t\t%d (%d useful)\n",
2220 com
->start_count
, com
->start_real
);
2221 printf("rx buffer chars free:\t\t%d\n", com
->iptr
- com
->ibuf
);
2223 if (com
->obufs
[0].l_queued
)
2224 ocount
+= com
->obufs
[0].l_tail
- com
->obufs
[0].l_head
;
2225 if (com
->obufs
[1].l_queued
)
2226 ocount
+= com
->obufs
[1].l_tail
- com
->obufs
[1].l_head
;
2227 printf("tx buffer chars:\t\t%u\n", ocount
);
2228 printf("received chars:\t\t\t%d\n", com
->bytes_in
);
2229 printf("received exceptions:\t\t%d\n", com
->recv_exception
);
2230 printf("modem signal deltas:\t\t%d\n", com
->mdm
);
2231 printf("transmitted chars:\t\t%d\n", com
->bytes_out
);
2235 printf("tty state:\t\t\t0x%08x\n", tp
->t_state
);
2237 "upper layer queue lengths:\t%d raw, %d canon, %d output\n",
2238 tp
->t_rawq
.c_cc
, tp
->t_canq
.c_cc
, tp
->t_outq
.c_cc
);
2240 printf("tty state:\t\t\tclosed\n");
2242 #endif /* CyDebug */