1 /* $NetBSD: sbjcn.c,v 1.23 2009/11/21 17:40:28 rmind Exp $ */
5 * Broadcom Corporation. All rights reserved.
7 * This software is furnished under license and may be used and copied only
8 * in accordance with the following terms and conditions. Subject to these
9 * conditions, you may download, copy, install, use, modify and distribute
10 * modified or unmodified copies of this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
13 * 1) Any source code used, modified or distributed must reproduce and
14 * retain this copyright notice and list of conditions as they appear in
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Broadcom Corporation. The "Broadcom Corporation" name may not be
19 * used to endorse or promote products derived from this software
20 * without the prior written permission of Broadcom Corporation.
22 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
25 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
26 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
27 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 /* from: $NetBSD: com.c,v 1.172 2000/05/03 19:19:04 thorpej Exp */
38 * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
39 * All rights reserved.
41 * This code is derived from software contributed to The NetBSD Foundation
42 * by Charles M. Hannum.
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
53 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63 * POSSIBILITY OF SUCH DAMAGE.
67 * Copyright (c) 1991 The Regents of the University of California.
68 * All rights reserved.
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. Neither the name of the University nor the names of its contributors
79 * may be used to endorse or promote products derived from this software
80 * without specific prior written permission.
82 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
83 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
85 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
86 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
87 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
88 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
89 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
90 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
91 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
94 * @(#)com.c 7.5 (Berkeley) 5/16/91
98 * `sbjcn' driver, supports console over SiByte SB-1250 JTAG.
100 * Accesses a section of JTAG memory space to mimic a console,
101 * if there's a matching program outside to communicate with.
102 * If nobody is there, things will be very quiet.
105 #include <sys/cdefs.h>
106 __KERNEL_RCSID(0, "$NetBSD: sbjcn.c,v 1.23 2009/11/21 17:40:28 rmind Exp $");
112 #include <sys/param.h>
113 #include <sys/systm.h>
114 #include <sys/ioctl.h>
115 #include <sys/select.h>
117 #include <sys/proc.h>
118 #include <sys/conf.h>
119 #include <sys/file.h>
121 #include <sys/kernel.h>
122 #include <sys/syslog.h>
123 #include <sys/types.h>
124 #include <sys/device.h>
125 #include <sys/malloc.h>
126 #include <sys/vnode.h>
127 #include <sys/kauth.h>
129 #include <sbmips/dev/sbscd/sbscdvar.h>
130 #include <sbmips/dev/sbscd/sbjcnvar.h>
131 #include <dev/cons.h>
132 #include <machine/locore.h>
134 void sbjcn_attach_channel(struct sbjcn_softc
*sc
, int chan
, int intr
);
135 static void sbjcncn_grabdword(struct sbjcn_channel
*ch
);
136 static char sbjcncn_nextbyte(struct sbjcn_channel
*ch
);
137 static void sbjcn_cngrabdword(void);
139 #if defined(DDB) || defined(KGDB)
140 static void sbjcn_enable_debugport(struct sbjcn_channel
*ch
);
142 void sbjcn_config(struct sbjcn_channel
*ch
);
143 void sbjcn_shutdown(struct sbjcn_channel
*ch
);
144 int sbjcn_speed(long, long *);
145 static int cflag2modes(tcflag_t
, u_char
*, u_char
*);
146 int sbjcn_param(struct tty
*, struct termios
*);
147 void sbjcn_start(struct tty
*);
148 int sbjcn_hwiflow(struct tty
*, int);
150 void sbjcn_loadchannelregs(struct sbjcn_channel
*);
151 void sbjcn_dohwiflow(struct sbjcn_channel
*);
152 void sbjcn_break(struct sbjcn_channel
*, int);
153 void sbjcn_modem(struct sbjcn_channel
*, int);
154 void tiocm_to_sbjcn(struct sbjcn_channel
*, int, int);
155 int sbjcn_to_tiocm(struct sbjcn_channel
*);
156 void sbjcn_iflush(struct sbjcn_channel
*);
158 int sbjcn_init(u_long addr
, int chan
, int rate
, tcflag_t cflag
);
159 int sbjcn_common_getc(u_long addr
, int chan
);
160 void sbjcn_common_putc(u_long addr
, int chan
, int c
);
162 int sbjcn_cngetc(dev_t dev
);
163 void sbjcn_cnputc(dev_t dev
, int c
);
164 void sbjcn_cnpollc(dev_t dev
, int on
);
166 extern struct cfdriver sbjcn_cd
;
168 dev_type_open(sbjcnopen
);
169 dev_type_close(sbjcnclose
);
170 dev_type_read(sbjcnread
);
171 dev_type_write(sbjcnwrite
);
172 dev_type_ioctl(sbjcnioctl
);
173 dev_type_stop(sbjcnstop
);
174 dev_type_tty(sbjcntty
);
176 const struct cdevsw sbjcn_cdevsw
= {
177 sbjcnopen
, sbjcnclose
, sbjcnread
, sbjcnwrite
, sbjcnioctl
,
178 sbjcnstop
, sbjcntty
, nopoll
, nommap
, ttykqfilter
, D_TTY
181 #define integrate static inline
182 integrate
void sbjcn_rxsoft(struct sbjcn_channel
*, struct tty
*);
183 integrate
void sbjcn_txsoft(struct sbjcn_channel
*, struct tty
*);
184 integrate
void sbjcn_stsoft(struct sbjcn_channel
*, struct tty
*);
185 integrate
void sbjcn_schedrx(struct sbjcn_channel
*);
186 integrate
void sbjcn_recv(struct sbjcn_channel
*ch
);
187 void sbjcn_diag(void *);
188 void sbjcn_callout(void *);
191 * Make this an option variable one can patch.
192 * But be warned: this must be a power of 2!
194 u_int sbjcn_rbuf_size
= SBJCN_RING_SIZE
;
196 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
197 u_int sbjcn_rbuf_hiwat
= (SBJCN_RING_SIZE
* 1) / 4;
198 u_int sbjcn_rbuf_lowat
= (SBJCN_RING_SIZE
* 3) / 4;
200 static int sbjcn_cons_present
;
201 static int sbjcn_cons_attached
;
202 static u_long sbjcn_cons_addr
;
203 static int sbjcn_cons_chan
;
204 static int sbjcn_cons_rate
;
205 static tcflag_t sbjcn_cons_cflag
;
206 static int sbjcn_cons_waiting_input
;
207 static uint64_t sbjcn_cons_input_buf
;
210 #include <sys/kgdb.h>
212 static int sbjcn_kgdb_present
;
213 static int sbjcn_kgdb_attached
;
214 static u_long sbjcn_kgdb_addr
;
215 static int sbjcn_kgdb_chan
;
217 int sbjcn_kgdb_getc(void *);
218 void sbjcn_kgdb_putc(void *, int);
221 static int sbjcn_match(struct device
*, struct cfdata
*, void *);
222 static void sbjcn_attach(struct device
*, struct device
*, void *);
224 CFATTACH_DECL(sbjcn
, sizeof(struct sbjcn_softc
),
225 sbjcn_match
, sbjcn_attach
, NULL
, NULL
);
227 #define READ_REG(rp) (mips3_ld((volatile uint64_t *)(rp)))
228 #define WRITE_REG(rp, val) (mips3_sd((volatile uint64_t *)(rp), (val)))
230 #define JTAG_CONS_CONTROL 0x00
231 #define JTAG_CONS_INPUT 0x20
232 #define JTAG_CONS_OUTPUT 0x40
233 #define JTAG_CONS_MAGICNUM 0x50FABEEF12349873
235 #define jtag_input_len(data) (((data) >> 56) & 0xFF)
239 sbjcn_match(struct device
*parent
, struct cfdata
*match
, void *aux
)
241 struct sbscd_attach_args
*sap
= aux
;
243 if (sap
->sa_locs
.sa_type
!= SBSCD_DEVTYPE_JTAGCONS
)
250 sbjcn_attach(struct device
*parent
, struct device
*self
, void *aux
)
252 struct sbjcn_softc
*sc
= (struct sbjcn_softc
*)self
;
253 struct sbscd_attach_args
*sap
= aux
;
255 sc
->sc_addr
= sap
->sa_base
+ sap
->sa_locs
.sa_offset
;
258 sbjcn_attach_channel(sc
, 0, sap
->sa_locs
.sa_intr
[0]);
262 sbjcn_attach_channel(struct sbjcn_softc
*sc
, int chan
, int intr
)
264 struct sbjcn_channel
*ch
= &sc
->sc_channels
[chan
];
271 chan_addr
= sc
->sc_addr
+ (0x100 * chan
);
272 ch
->ch_base
= (void *)MIPS_PHYS_TO_KSEG1(chan_addr
);
274 (void *)MIPS_PHYS_TO_KSEG1(sc
->sc_addr
+ JTAG_CONS_INPUT
);
276 (void *)MIPS_PHYS_TO_KSEG1(sc
->sc_addr
+ JTAG_CONS_OUTPUT
);
278 (void *)MIPS_PHYS_TO_KSEG1(sc
->sc_addr
+ JTAG_CONS_CONTROL
);
279 ch
->ch_waiting_input
= 0;
281 ch
->ch_i_dcd
= ch
->ch_i_dcd_pin
= 0 /* XXXCGD */;
282 ch
->ch_i_cts
= ch
->ch_i_cts_pin
= 0 /* XXXCGD */;
283 ch
->ch_i_dsr
= ch
->ch_i_dsr_pin
= 0 /* XXXCGD */;
284 ch
->ch_i_ri
= ch
->ch_i_ri_pin
= 0 /* XXXCGD */;
286 ch
->ch_i_dcd
| ch
->ch_i_cts
| ch
->ch_i_dsr
| ch
->ch_i_ri
;
287 ch
->ch_o_dtr
= ch
->ch_o_dtr_pin
= 0 /* XXXCGD */;
288 ch
->ch_o_rts
= ch
->ch_o_rts_pin
= 0 /* XXXCGD */;
289 ch
->ch_o_mask
= ch
->ch_o_dtr
| ch
->ch_o_rts
;
291 callout_init(&ch
->ch_diag_callout
, 0);
292 callout_init(&ch
->ch_callout
, 0);
294 /* Disable interrupts before configuring the device. */
297 if (sbjcn_cons_present
&&
298 sbjcn_cons_addr
== chan_addr
&& sbjcn_cons_chan
== chan
) {
299 sbjcn_cons_attached
= 1;
301 /* Make sure the console is always "hardwired". */
302 delay(1000); /* wait for output to finish */
303 SET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
);
304 SET(ch
->ch_swflags
, TIOCFLAG_SOFTCAR
);
308 tp
->t_oproc
= sbjcn_start
;
309 tp
->t_param
= sbjcn_param
;
310 tp
->t_hwiflow
= sbjcn_hwiflow
;
313 ch
->ch_rbuf
= malloc(sbjcn_rbuf_size
<< 1, M_DEVBUF
, M_NOWAIT
);
314 if (ch
->ch_rbuf
== NULL
) {
315 printf("%s: channel %d: unable to allocate ring buffer\n",
316 sc
->sc_dev
.dv_xname
, chan
);
319 ch
->ch_ebuf
= ch
->ch_rbuf
+ (sbjcn_rbuf_size
<< 1);
323 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
)) {
326 /* locate the major number */
327 maj
= cdevsw_lookup_major(&sbjcn_cdevsw
);
329 cn_tab
->cn_dev
= makedev(maj
,
330 (device_unit(&sc
->sc_dev
) << 1) + chan
);
332 printf("%s: channel %d: console\n", sc
->sc_dev
.dv_xname
, chan
);
337 * Allow kgdb to "take over" this port. If this is
338 * the kgdb device, it has exclusive use.
340 if (sbjcn_kgdb_present
&&
341 sbjcn_kgdb_addr
== chan_addr
&& sbjcn_kgdb_chan
== chan
) {
342 sbjcn_kgdb_attached
= 1;
344 SET(ch
->ch_hwflags
, SBJCN_HW_KGDB
);
345 printf("%s: channel %d: kgdb\n", sc
->sc_dev
.dv_xname
, chan
);
351 callout_reset(&ch
->ch_callout
, hz
/10, sbjcn_callout
, ch
);
353 SET(ch
->ch_hwflags
, SBJCN_HW_DEV_OK
);
357 sbjcn_speed(long speed
, long *brcp
)
359 #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
362 int frequency
= 100000000;
364 *brcp
= divrnd(frequency
/ 20, speed
) - 1;
368 x
= divrnd(frequency
/ 20, speed
);
371 err
= divrnd(((quad_t
)frequency
) * 1000 / 20, speed
* x
) - 1000;
374 if (err
> SBJCN_TOLERANCE
)
383 void sbjcn_status(struct sbjcn_channel
*, char *);
385 int sbjcn_debug
= 1 /* XXXCGD */;
388 sbjcn_status(struct sbjcn_channel
*ch
, char *str
)
390 struct sbjcn_softc
*sc
= ch
->ch_sc
;
391 struct tty
*tp
= ch
->ch_tty
;
393 printf("%s: chan %d: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n",
394 sc
->sc_dev
.dv_xname
, ch
->ch_num
, str
,
395 ISSET(tp
->t_cflag
, CLOCAL
) ? "+" : "-",
396 ISSET(ch
->ch_iports
, ch
->ch_i_dcd
) ? "+" : "-",
397 ISSET(tp
->t_state
, TS_CARR_ON
) ? "+" : "-",
398 ISSET(ch
->ch_oports
, ch
->ch_o_dtr
) ? "+" : "-",
399 ch
->ch_tx_stopped
? "+" : "-");
401 printf("%s: chan %d: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n",
402 sc
->sc_dev
.dv_xname
, ch
->ch_num
, str
,
403 ISSET(tp
->t_cflag
, CRTSCTS
) ? "+" : "-",
404 ISSET(ch
->ch_iports
, ch
->ch_i_cts
) ? "+" : "-",
405 ISSET(tp
->t_state
, TS_TTSTOP
) ? "+" : "-",
406 ISSET(ch
->ch_oports
, ch
->ch_o_rts
) ? "+" : "-",
411 #if defined(DDB) || defined(KGDB)
413 sbjcn_enable_debugport(struct sbjcn_channel
*ch
)
417 /* Turn on line break interrupt, set carrier. */
421 SET(ch
->ch_oports
, ch
->ch_o_dtr
| ch
->ch_o_rts
);
428 sbjcn_config(struct sbjcn_channel
*ch
)
431 /* Disable interrupts before configuring the device. */
435 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
))
436 sbjcn_enable_debugport(ch
);
441 * Allow kgdb to "take over" this port. If this is
442 * the kgdb device, it has exclusive use.
444 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_KGDB
))
445 sbjcn_enable_debugport(ch
);
450 sbjcn_shutdown(struct sbjcn_channel
*ch
)
452 struct tty
*tp
= ch
->ch_tty
;
457 /* If we were asserting flow control, then deassert it. */
458 SET(ch
->ch_rx_flags
, RX_IBUF_BLOCKED
);
461 /* Clear any break condition set with TIOCSBRK. */
465 * Hang up if necessary. Wait a bit, so the other side has time to
466 * notice even if we immediately open the port again.
468 if (ISSET(tp
->t_cflag
, HUPCL
)) {
470 (void) tsleep(ch
, TTIPRI
, ttclos
, hz
);
473 /* Turn off interrupts. */
475 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
))
476 ch
->ch_imr
= 0x04; /* interrupt on break */
485 sbjcnopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
487 int chan
= SBJCN_CHAN(dev
);
488 struct sbjcn_softc
*sc
;
489 struct sbjcn_channel
*ch
;
494 sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
498 ch
= &sc
->sc_channels
[chan
];
499 if (!ISSET(ch
->ch_hwflags
, SBJCN_HW_DEV_OK
) || ch
->ch_rbuf
== NULL
)
504 * If this is the kgdb port, no other use is permitted.
506 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_KGDB
))
512 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
518 * Do the following iff this is a first open.
520 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
527 /* Turn on receive, break, and status change interrupts. */
530 /* Fetch the current modem control status, needed later. */
532 ch
->ch_iports_delta
= 0;
536 * Initialize the termios status to the defaults. Add in the
537 * sticky bits from TIOCSFLAGS.
540 if (ISSET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
)) {
541 t
.c_ospeed
= sbjcn_cons_rate
;
542 t
.c_cflag
= sbjcn_cons_cflag
;
544 t
.c_ospeed
= TTYDEF_SPEED
;
545 t
.c_cflag
= TTYDEF_CFLAG
;
547 if (ISSET(ch
->ch_swflags
, TIOCFLAG_CLOCAL
))
548 SET(t
.c_cflag
, CLOCAL
);
549 if (ISSET(ch
->ch_swflags
, TIOCFLAG_CRTSCTS
))
550 SET(t
.c_cflag
, CRTSCTS
);
551 if (ISSET(ch
->ch_swflags
, TIOCFLAG_MDMBUF
))
552 SET(t
.c_cflag
, MDMBUF
);
553 /* Make sure sbjcn_param() will do something. */
555 (void) sbjcn_param(tp
, &t
);
556 tp
->t_iflag
= TTYDEF_IFLAG
;
557 tp
->t_oflag
= TTYDEF_OFLAG
;
558 tp
->t_lflag
= TTYDEF_LFLAG
;
565 * Turn on DTR. We must always do this, even if carrier is not
566 * present, because otherwise we'd have to use TIOCSDTR
567 * immediately after setting CLOCAL, which applications do not
568 * expect. We always assert DTR while the device is open
569 * unless explicitly requested to deassert it.
573 /* Clear the input ring, and unblock. */
574 ch
->ch_rbput
= ch
->ch_rbget
= ch
->ch_rbuf
;
575 ch
->ch_rbavail
= sbjcn_rbuf_size
;
577 CLR(ch
->ch_rx_flags
, RX_ANY_BLOCK
);
582 sbjcn_status(ch
, "sbjcnopen ");
590 error
= ttyopen(tp
, SBJCN_DIALOUT(dev
), ISSET(flag
, O_NONBLOCK
));
594 error
= (*tp
->t_linesw
->l_open
)(dev
, tp
);
601 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
603 * We failed to open the device, and nobody else had it opened.
604 * Clean up the state as appropriate.
613 sbjcnclose(dev_t dev
, int flag
, int mode
, struct proc
*p
)
615 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
616 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(dev
)];
617 struct tty
*tp
= ch
->ch_tty
;
619 /* XXX This is for cons.c. */
620 if (!ISSET(tp
->t_state
, TS_ISOPEN
))
623 (*tp
->t_linesw
->l_close
)(tp
, flag
);
626 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
628 * Although we got a last close, the device may still be in
629 * use; e.g. if this was the dialout node, and there are still
630 * processes waiting for carrier on the non-dialout node.
639 sbjcnread(dev_t dev
, struct uio
*uio
, int flag
)
641 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
642 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(dev
)];
643 struct tty
*tp
= ch
->ch_tty
;
645 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
649 sbjcnwrite(dev_t dev
, struct uio
*uio
, int flag
)
651 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
652 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(dev
)];
653 struct tty
*tp
= ch
->ch_tty
;
655 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
661 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
662 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(dev
)];
663 struct tty
*tp
= ch
->ch_tty
;
669 sbjcnioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
671 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(dev
));
672 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(dev
)];
673 struct tty
*tp
= ch
->ch_tty
;
677 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, p
);
681 error
= ttioctl(tp
, cmd
, data
, flag
, p
);
707 *(int *)data
= ch
->ch_swflags
;
711 error
= kauth_authorize_device_tty(l
->l_cred
,
712 KAUTH_DEVICE_TTY_PRIVSET
, tp
);
715 ch
->ch_swflags
= *(int *)data
;
721 tiocm_to_sbjcn(ch
, cmd
, *(int *)data
);
725 *(int *)data
= sbjcn_to_tiocm(ch
);
737 sbjcn_status(ch
, "sbjcn_ioctl ");
744 sbjcn_schedrx(struct sbjcn_channel
*ch
)
749 /* Next callout will detect this flag. */
753 sbjcn_break(struct sbjcn_channel
*ch
, int onoff
)
755 /* XXXKW do something? */
759 sbjcn_modem(struct sbjcn_channel
*ch
, int onoff
)
762 if (ch
->ch_o_dtr
== 0)
766 SET(ch
->ch_oports
, ch
->ch_o_dtr
);
768 CLR(ch
->ch_oports
, ch
->ch_o_dtr
);
770 if (!ch
->ch_heldchange
) {
771 if (ch
->ch_tx_busy
) {
772 ch
->ch_heldtbc
= ch
->ch_tbc
;
774 ch
->ch_heldchange
= 1;
776 sbjcn_loadchannelregs(ch
);
781 tiocm_to_sbjcn(struct sbjcn_channel
*ch
, int how
, int ttybits
)
786 if (ISSET(ttybits
, TIOCM_DTR
))
787 SET(bits
, ch
->ch_o_dtr
);
788 if (ISSET(ttybits
, TIOCM_RTS
))
789 SET(bits
, ch
->ch_o_rts
);
793 CLR(ch
->ch_oports
, bits
);
797 SET(ch
->ch_oports
, bits
);
801 ch
->ch_oports
= bits
;
805 if (!ch
->ch_heldchange
) {
806 if (ch
->ch_tx_busy
) {
807 ch
->ch_heldtbc
= ch
->ch_tbc
;
809 ch
->ch_heldchange
= 1;
811 sbjcn_loadchannelregs(ch
);
816 sbjcn_to_tiocm(struct sbjcn_channel
*ch
)
821 hwbits
= ch
->ch_oports
;
822 if (ISSET(hwbits
, ch
->ch_o_dtr
))
823 SET(ttybits
, TIOCM_DTR
);
824 if (ISSET(hwbits
, ch
->ch_o_rts
))
825 SET(ttybits
, TIOCM_RTS
);
827 hwbits
= ch
->ch_iports
;
828 if (ISSET(hwbits
, ch
->ch_i_dcd
))
829 SET(ttybits
, TIOCM_CD
);
830 if (ISSET(hwbits
, ch
->ch_i_cts
))
831 SET(ttybits
, TIOCM_CTS
);
832 if (ISSET(hwbits
, ch
->ch_i_dsr
))
833 SET(ttybits
, TIOCM_DSR
);
834 if (ISSET(hwbits
, ch
->ch_i_ri
))
835 SET(ttybits
, TIOCM_RI
);
838 SET(ttybits
, TIOCM_LE
);
844 cflag2modes(tcflag_t cflag
, u_char
*mode1p
, u_char
*mode2p
)
852 switch (ISSET(cflag
, CSIZE
)) {
854 mode1
|= 2; /* XXX */
858 /* FALLTHRU for sanity */
860 mode1
|= 3; /* XXX */
863 if (!ISSET(cflag
, PARENB
))
867 if (ISSET(cflag
, PARODD
))
871 if (ISSET(cflag
, CSTOPB
))
872 mode2
|= 1 << 3; /* two stop bits XXX not std */
874 if (ISSET(cflag
, CRTSCTS
)) {
885 sbjcn_param(struct tty
*tp
, struct termios
*t
)
887 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(tp
->t_dev
));
888 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(tp
->t_dev
)];
893 /* XXX reset to console parameters if console? */
898 /* Check requested parameters. */
899 if (sbjcn_speed(t
->c_ospeed
, &brc
) < 0)
901 if (t
->c_ispeed
&& t
->c_ispeed
!= t
->c_ospeed
)
905 * For the console, always force CLOCAL and !HUPCL, so that the port
908 if (ISSET(ch
->ch_swflags
, TIOCFLAG_SOFTCAR
) ||
909 ISSET(ch
->ch_hwflags
, SBJCN_HW_CONSOLE
)) {
910 SET(t
->c_cflag
, CLOCAL
);
911 CLR(t
->c_cflag
, HUPCL
);
915 * If there were no changes, don't do anything. This avoids dropping
916 * input and improves performance when all we did was frob things like
919 if (tp
->t_ospeed
== t
->c_ospeed
&&
920 tp
->t_cflag
== t
->c_cflag
)
923 if (cflag2modes(t
->c_cflag
, &mode1
, &mode2
) < 0)
928 ch
->ch_mode1
= mode1
;
929 ch
->ch_mode2
= mode2
;
932 * If we're not in a mode that assumes a connection is present, then
933 * ignore carrier changes.
935 if (ISSET(t
->c_cflag
, CLOCAL
| MDMBUF
))
938 ch
->ch_i_dcd
= ch
->ch_i_dcd_pin
;
940 * Set the flow control pins depending on the current flow control
943 if (ISSET(t
->c_cflag
, CRTSCTS
)) {
944 ch
->ch_o_dtr
= ch
->ch_o_dtr_pin
;
945 ch
->ch_o_rts
= ch
->ch_o_rts_pin
;
946 ch
->ch_i_cts
= ch
->ch_i_cts_pin
;
947 /* hw controle enable bits in mod regs set by cflag2modes */
948 } else if (ISSET(t
->c_cflag
, MDMBUF
)) {
950 * For DTR/DCD flow control, make sure we don't toggle DTR for
954 ch
->ch_o_rts
= ch
->ch_o_dtr_pin
;
955 ch
->ch_i_cts
= ch
->ch_i_dcd_pin
;
958 * If no flow control, then always set RTS. This will make
959 * the other side happy if it mistakenly thinks we're doing
960 * RTS/CTS flow control.
962 ch
->ch_o_dtr
= ch
->ch_o_dtr_pin
| ch
->ch_o_rts_pin
;
965 if (ISSET(ch
->ch_oports
, ch
->ch_o_dtr_pin
))
966 SET(ch
->ch_oports
, ch
->ch_o_rts_pin
);
968 CLR(ch
->ch_oports
, ch
->ch_o_rts_pin
);
970 /* XXX maybe mask the ports which generate intrs? */
974 /* XXX maybe set fifo-full receive mode if RTSCTS and high speed? */
976 /* And copy to tty. */
978 tp
->t_ospeed
= t
->c_ospeed
;
979 tp
->t_cflag
= t
->c_cflag
;
981 if (!ch
->ch_heldchange
) {
982 if (ch
->ch_tx_busy
) {
983 ch
->ch_heldtbc
= ch
->ch_tbc
;
985 ch
->ch_heldchange
= 1;
987 sbjcn_loadchannelregs(ch
);
990 if (!ISSET(t
->c_cflag
, CHWFLOW
)) {
991 /* Disable the high water mark. */
994 if (ISSET(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
)) {
995 CLR(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
);
998 if (ISSET(ch
->ch_rx_flags
, RX_TTY_BLOCKED
|RX_IBUF_BLOCKED
)) {
999 CLR(ch
->ch_rx_flags
, RX_TTY_BLOCKED
|RX_IBUF_BLOCKED
);
1000 sbjcn_dohwiflow(ch
);
1003 ch
->ch_r_hiwat
= sbjcn_rbuf_hiwat
;
1004 ch
->ch_r_lowat
= sbjcn_rbuf_lowat
;
1010 * Update the tty layer's idea of the carrier bit, in case we changed
1011 * CLOCAL or MDMBUF. We don't hang up here; we only do that by
1014 (void) (*tp
->t_linesw
->l_modem
)(tp
,
1015 ISSET(ch
->ch_iports
, ch
->ch_i_dcd
));
1019 sbjcn_status(ch
, "sbjcnparam ");
1022 if (!ISSET(t
->c_cflag
, CHWFLOW
)) {
1023 if (ch
->ch_tx_stopped
) {
1024 ch
->ch_tx_stopped
= 0;
1033 sbjcn_iflush(struct sbjcn_channel
*ch
)
1039 /* flush any pending I/O */
1040 while (((reg
= READ_REG(ch
->ch_input_reg
)) != 0) && --timo
)
1045 printf("%s: sbjcn_iflush timeout %02x\n",
1046 ch
->ch_sc
->sc_dev
.dv_xname
, reg
);
1051 sbjcn_loadchannelregs(struct sbjcn_channel
*ch
)
1056 sbjcn_hwiflow(struct tty
*tp
, int block
)
1058 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(tp
->t_dev
));
1059 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(tp
->t_dev
)];
1062 if (ch
->ch_o_rts
== 0)
1067 if (!ISSET(ch
->ch_rx_flags
, RX_TTY_BLOCKED
)) {
1068 SET(ch
->ch_rx_flags
, RX_TTY_BLOCKED
);
1069 sbjcn_dohwiflow(ch
);
1072 if (ISSET(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
)) {
1073 CLR(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
);
1076 if (ISSET(ch
->ch_rx_flags
, RX_TTY_BLOCKED
)) {
1077 CLR(ch
->ch_rx_flags
, RX_TTY_BLOCKED
);
1078 sbjcn_dohwiflow(ch
);
1086 * (un)block input via hw flowcontrol
1089 sbjcn_dohwiflow(struct sbjcn_channel
*ch
)
1092 if (ch
->ch_o_rts
== 0)
1095 if (ISSET(ch
->ch_rx_flags
, RX_ANY_BLOCK
)) {
1096 CLR(ch
->ch_oports
, ch
->ch_o_rts
);
1097 CLR(ch
->ch_oports_active
, ch
->ch_o_rts
);
1099 SET(ch
->ch_oports
, ch
->ch_o_rts
);
1100 SET(ch
->ch_oports_active
, ch
->ch_o_rts
);
1105 sbjcn_start(struct tty
*tp
)
1107 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(tp
->t_dev
));
1108 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(tp
->t_dev
)];
1112 if (ISSET(tp
->t_state
, TS_BUSY
| TS_TIMEOUT
| TS_TTSTOP
))
1114 if (ch
->ch_tx_stopped
)
1119 /* Grab the first contiguous region of buffer space. */
1124 tba
= tp
->t_outq
.c_cf
;
1125 tbc
= ndqb(&tp
->t_outq
, 0);
1133 SET(tp
->t_state
, TS_BUSY
);
1136 /* Output the first chunk of the contiguous buffer. */
1138 while (ch
->ch_tbc
) {
1142 bytes
= (ch
->ch_tbc
> 7) ? 7 : ch
->ch_tbc
;
1144 for (i
=0; i
<bytes
; i
++) {
1146 data
|= *ch
->ch_tba
++;
1149 data
<<= 56-(bytes
<<3);
1150 ch
->ch_tbc
-= bytes
;
1151 WRITE_REG(ch
->ch_output_reg
, data
);
1162 * Stop output on a line.
1165 sbjcnstop(struct tty
*tp
, int flag
)
1167 struct sbjcn_softc
*sc
= device_lookup_private(&sbjcn_cd
, SBJCN_UNIT(tp
->t_dev
));
1168 struct sbjcn_channel
*ch
= &sc
->sc_channels
[SBJCN_CHAN(tp
->t_dev
)];
1172 if (ISSET(tp
->t_state
, TS_BUSY
)) {
1173 /* Stop transmitting at the next chunk. */
1176 if (!ISSET(tp
->t_state
, TS_TTSTOP
))
1177 SET(tp
->t_state
, TS_FLUSH
);
1183 sbjcn_diag(void *arg
)
1185 struct sbjcn_channel
*ch
= arg
;
1186 struct sbjcn_softc
*sc
= ch
->ch_sc
;
1187 int overflows
, floods
;
1191 overflows
= ch
->ch_overflows
;
1192 ch
->ch_overflows
= 0;
1193 floods
= ch
->ch_floods
;
1198 log(LOG_WARNING
, "%s: channel %d: %d fifo overflow%s, %d ibuf flood%s\n",
1199 sc
->sc_dev
.dv_xname
, ch
->ch_num
,
1200 overflows
, overflows
== 1 ? "" : "s",
1201 floods
, floods
== 1 ? "" : "s");
1205 sbjcn_rxsoft(struct sbjcn_channel
*ch
, struct tty
*tp
)
1207 int (*rint
)(int c
, struct tty
*tp
) = tp
->t_linesw
->l_rint
;
1216 scc
= cc
= sbjcn_rbuf_size
- ch
->ch_rbavail
;
1218 if (cc
== sbjcn_rbuf_size
) {
1220 if (ch
->ch_errors
++ == 0)
1221 callout_reset(&ch
->ch_diag_callout
, 60 * hz
,
1228 if (ISSET(sr
, 0xf0)) {
1229 if (ISSET(sr
, 0x10)) {
1231 if (ch
->ch_errors
++ == 0)
1232 callout_reset(&ch
->ch_diag_callout
,
1233 60 * hz
, sbjcn_diag
, ch
);
1235 if (ISSET(sr
, 0xc0))
1237 if (ISSET(sr
, 0x20))
1240 if ((*rint
)(code
, tp
) == -1) {
1242 * The line discipline's buffer is out of space.
1244 if (!ISSET(ch
->ch_rx_flags
, RX_TTY_BLOCKED
)) {
1246 * We're either not using flow control, or the
1247 * line discipline didn't tell us to block for
1248 * some reason. Either way, we have no way to
1249 * know when there's more space available, so
1250 * just drop the rest of the data.
1254 get
-= sbjcn_rbuf_size
<< 1;
1258 * Don't schedule any more receive processing
1259 * until the line discipline tells us there's
1260 * space available (through comhwiflow()).
1261 * Leave the rest of the data in the input
1264 SET(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
);
1277 cc
= ch
->ch_rbavail
+= scc
- cc
;
1278 /* Buffers should be ok again, release possible block. */
1279 if (cc
>= ch
->ch_r_lowat
) {
1280 if (ISSET(ch
->ch_rx_flags
, RX_IBUF_OVERFLOWED
)) {
1281 CLR(ch
->ch_rx_flags
, RX_IBUF_OVERFLOWED
);
1282 SET(ch
->ch_imr
, 0x02);
1284 if (ISSET(ch
->ch_rx_flags
, RX_IBUF_BLOCKED
)) {
1285 CLR(ch
->ch_rx_flags
, RX_IBUF_BLOCKED
);
1286 sbjcn_dohwiflow(ch
);
1294 sbjcn_txsoft(struct sbjcn_channel
*ch
, struct tty
*tp
)
1297 CLR(tp
->t_state
, TS_BUSY
);
1298 if (ISSET(tp
->t_state
, TS_FLUSH
))
1299 CLR(tp
->t_state
, TS_FLUSH
);
1301 ndflush(&tp
->t_outq
, (int)(ch
->ch_tba
- tp
->t_outq
.c_cf
));
1302 (*tp
->t_linesw
->l_start
)(tp
);
1306 sbjcn_stsoft(struct sbjcn_channel
*ch
, struct tty
*tp
)
1308 u_char iports
, delta
;
1312 iports
= ch
->ch_iports
;
1313 delta
= ch
->ch_iports_delta
;
1314 ch
->ch_iports_delta
= 0;
1317 if (ISSET(delta
, ch
->ch_i_dcd
)) {
1319 * Inform the tty layer that carrier detect changed.
1321 (void) (*tp
->t_linesw
->l_modem
)(tp
,
1322 ISSET(iports
, ch
->ch_i_dcd
));
1325 if (ISSET(delta
, ch
->ch_i_cts
)) {
1326 /* Block or unblock output according to flow control. */
1327 if (ISSET(iports
, ch
->ch_i_cts
)) {
1328 ch
->ch_tx_stopped
= 0;
1329 (*tp
->t_linesw
->l_start
)(tp
);
1331 ch
->ch_tx_stopped
= 1;
1337 sbjcn_status(ch
, "sbjcn_stsoft");
1342 sbjcn_recv(struct sbjcn_channel
*ch
)
1349 cc
= ch
->ch_rbavail
;
1351 /* XXX process break */
1353 sbjcncn_grabdword(ch
);
1354 if (ch
->ch_waiting_input
) {
1355 if (!ISSET(ch
->ch_rx_flags
, RX_IBUF_OVERFLOWED
)) {
1357 put
[0] = sbjcncn_nextbyte(ch
);
1358 put
[1] = 1; /* XXXKW ? */
1364 if (!ch
->ch_waiting_input
)
1369 * Current string of incoming characters ended
1370 * because no more data was available or we
1371 * ran out of space. Schedule a receive event
1372 * if any data was received. If we're out of
1373 * space, turn off receive interrupts.
1376 ch
->ch_rbavail
= cc
;
1377 if (!ISSET(ch
->ch_rx_flags
, RX_TTY_OVERFLOWED
))
1378 ch
->ch_rx_ready
= 1;
1381 * See if we are in danger of overflowing a
1382 * buffer. If so, use hardware flow control
1383 * to ease the pressure.
1385 if (!ISSET(ch
->ch_rx_flags
, RX_IBUF_BLOCKED
) &&
1386 cc
< ch
->ch_r_hiwat
) {
1387 SET(ch
->ch_rx_flags
, RX_IBUF_BLOCKED
);
1388 sbjcn_dohwiflow(ch
);
1392 * If we're out of space, disable receive
1393 * interrupts until the queue has drained
1397 SET(ch
->ch_rx_flags
,
1398 RX_IBUF_OVERFLOWED
);
1399 CLR(ch
->ch_imr
, 0x02);
1403 CLR(ch
->ch_imr
, 0x02);
1409 * If we've delayed a parameter change, do it now, and restart
1412 if (ch
->ch_heldchange
) {
1413 sbjcn_loadchannelregs(ch
);
1414 ch
->ch_heldchange
= 0;
1415 ch
->ch_tbc
= ch
->ch_heldtbc
;
1421 sbjcn_callout(void *arg
)
1423 struct sbjcn_channel
*ch
= arg
;
1424 struct tty
*tp
= ch
->ch_tty
;
1429 /* XXX check receive */
1430 if (ch
->ch_rx_ready
) {
1431 ch
->ch_rx_ready
= 0;
1432 sbjcn_rxsoft(ch
, tp
);
1435 /* XXX check transmit */
1436 if (ch
->ch_tx_done
) {
1438 sbjcn_txsoft(ch
, tp
);
1441 callout_reset(&ch
->ch_callout
, hz
/10, sbjcn_callout
, ch
);
1444 static char sbjcncn_nextbyte(struct sbjcn_channel
*ch
)
1448 sbjcncn_grabdword(ch
);
1449 c
= (ch
->ch_input_buf
>> 56) & 0xff;
1450 ch
->ch_input_buf
<<= 8;
1451 ch
->ch_waiting_input
--;
1455 static void sbjcncn_grabdword(struct sbjcn_channel
*ch
)
1459 if (ch
->ch_waiting_input
)
1462 inbuf
= READ_REG(ch
->ch_input_reg
);
1463 ch
->ch_waiting_input
= jtag_input_len(inbuf
);
1464 ch
->ch_input_buf
= inbuf
<< 8;
1468 * Initialize UART for use as console or KGDB line.
1471 sbjcn_init(u_long addr
, int chan
, int rate
, tcflag_t cflag
)
1473 /* XXXKW Anything to do here? */
1478 * Following are all routines needed for sbjcn to act as console
1481 sbjcn_cnattach(u_long addr
, int chan
, int rate
, tcflag_t cflag
)
1485 static struct consdev sbjcn_cons
= {
1486 NULL
, NULL
, sbjcn_cngetc
, sbjcn_cnputc
, sbjcn_cnpollc
, NULL
,
1490 res
= sbjcn_init(addr
, chan
, rate
, cflag
);
1494 cn_tab
= &sbjcn_cons
;
1496 sbjcn_cons_present
= 1;
1497 sbjcn_cons_addr
= addr
;
1498 sbjcn_cons_waiting_input
= 0;
1499 sbjcn_cons_chan
= chan
;
1500 sbjcn_cons_rate
= rate
;
1501 sbjcn_cons_cflag
= cflag
;
1503 /* Wait for sign of life from the other end */
1504 while ((ctrl_val
= READ_REG(MIPS_PHYS_TO_KSEG1(sbjcn_cons_addr
+ JTAG_CONS_CONTROL
))) == 0)
1507 return (ctrl_val
!= JTAG_CONS_MAGICNUM
);
1511 sbjcn_cngetc(dev_t dev
)
1515 while (sbjcn_cons_waiting_input
== 0)
1516 sbjcn_cngrabdword();
1518 c
= (sbjcn_cons_input_buf
>> 56) & 0xff;
1519 sbjcn_cons_input_buf
<<= 8;
1520 sbjcn_cons_waiting_input
--;
1526 * Console kernel output character routine.
1529 sbjcn_cnputc(dev_t dev
, int c
)
1533 outbuf
= (1LL << 56) | (((uint64_t)c
) << 48);
1534 WRITE_REG(MIPS_PHYS_TO_KSEG1(sbjcn_cons_addr
+ JTAG_CONS_OUTPUT
), outbuf
);
1538 sbjcn_cnpollc(dev_t dev
, int on
)
1543 static void sbjcn_cngrabdword(void)
1547 if (sbjcn_cons_waiting_input
)
1550 inbuf
= READ_REG(MIPS_PHYS_TO_KSEG1(sbjcn_cons_addr
+ JTAG_CONS_INPUT
));
1551 sbjcn_cons_waiting_input
= jtag_input_len(inbuf
);
1552 sbjcn_cons_input_buf
= inbuf
<< 8;
1557 sbjcn_kgdb_attach(u_long addr
, int chan
, int rate
, tcflag_t cflag
)
1561 if (!sbjcn_cons_present
&&
1562 sbjcn_cons_addr
== addr
&& sbjcn_cons_chan
== chan
)
1563 return (EBUSY
); /* cannot share with console */
1565 res
= sbjcn_init(addr
, chan
, rate
, cflag
);
1569 kgdb_attach(sbjcn_kgdb_getc
, sbjcn_kgdb_putc
, NULL
);
1570 kgdb_dev
= 123; /* unneeded, only to satisfy some tests */
1573 sbjcn_kgdb_present
= 1;
1574 /* XXX sbjcn_init wants addr, but we need the offset addr */
1575 sbjcn_kgdb_addr
= addr
+ (chan
* 0x100);
1576 sbjcn_kgdb_chan
= chan
;
1583 sbjcn_kgdb_getc(void *arg
)
1586 return (sbjcn_common_getc(sbjcn_kgdb_addr
, sbjcn_kgdb_chan
));
1591 sbjcn_kgdb_putc(void *arg
, int c
)
1594 sbjcn_common_putc(sbjcn_kgdb_addr
, sbjcn_kgdb_chan
, c
);
1599 * helper function to identify the sbjcn channels used by
1600 * console or KGDB (and not yet autoconf attached)
1603 sbjcn_is_console(u_long addr
, int chan
)
1606 if (sbjcn_cons_present
&& !sbjcn_cons_attached
&&
1607 sbjcn_cons_addr
== addr
&& sbjcn_cons_chan
== chan
)
1610 if (sbjcn_kgdb_present
&& !sbjcn_kgdb_attached
&&
1611 sbjcn_kgdb_addr
== addr
&& sbjcn_kgdb_chan
== chan
)