txcom.c revision 1.3.2.2 1 1.3.2.2 wrstuden /* $NetBSD: txcom.c,v 1.3.2.2 1999/12/27 18:32:13 wrstuden Exp $ */
2 1.3.2.2 wrstuden
3 1.3.2.2 wrstuden /*
4 1.3.2.2 wrstuden * Copyright (c) 1999, by UCHIYAMA Yasushi
5 1.3.2.2 wrstuden * All rights reserved.
6 1.3.2.2 wrstuden *
7 1.3.2.2 wrstuden * Redistribution and use in source and binary forms, with or without
8 1.3.2.2 wrstuden * modification, are permitted provided that the following conditions
9 1.3.2.2 wrstuden * are met:
10 1.3.2.2 wrstuden * 1. Redistributions of source code must retain the above copyright
11 1.3.2.2 wrstuden * notice, this list of conditions and the following disclaimer.
12 1.3.2.2 wrstuden * 2. The name of the developer may NOT be used to endorse or promote products
13 1.3.2.2 wrstuden * derived from this software without specific prior written permission.
14 1.3.2.2 wrstuden *
15 1.3.2.2 wrstuden * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.3.2.2 wrstuden * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.3.2.2 wrstuden * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.3.2.2 wrstuden * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.3.2.2 wrstuden * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.3.2.2 wrstuden * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.3.2.2 wrstuden * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.3.2.2 wrstuden * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.3.2.2 wrstuden * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.3.2.2 wrstuden * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.3.2.2 wrstuden * SUCH DAMAGE.
26 1.3.2.2 wrstuden *
27 1.3.2.2 wrstuden */
28 1.3.2.2 wrstuden #include "opt_tx39_debug.h"
29 1.3.2.2 wrstuden #include "opt_tx39uartdebug.h"
30 1.3.2.2 wrstuden
31 1.3.2.2 wrstuden #include <sys/param.h>
32 1.3.2.2 wrstuden #include <sys/systm.h>
33 1.3.2.2 wrstuden #include <sys/device.h>
34 1.3.2.2 wrstuden
35 1.3.2.2 wrstuden #include <sys/proc.h> /* tsleep/wakeup */
36 1.3.2.2 wrstuden
37 1.3.2.2 wrstuden #include <sys/ioctl.h>
38 1.3.2.2 wrstuden #include <sys/select.h>
39 1.3.2.2 wrstuden #include <sys/file.h>
40 1.3.2.2 wrstuden
41 1.3.2.2 wrstuden #include <sys/tty.h>
42 1.3.2.2 wrstuden #include <sys/conf.h>
43 1.3.2.2 wrstuden #include <dev/cons.h> /* consdev */
44 1.3.2.2 wrstuden
45 1.3.2.2 wrstuden #include <machine/bus.h>
46 1.3.2.2 wrstuden
47 1.3.2.2 wrstuden #include <hpcmips/tx/tx39var.h>
48 1.3.2.2 wrstuden #include <hpcmips/tx/tx39icureg.h>
49 1.3.2.2 wrstuden #include <hpcmips/tx/tx39uartvar.h>
50 1.3.2.2 wrstuden #include <hpcmips/tx/tx39uartreg.h>
51 1.3.2.2 wrstuden
52 1.3.2.2 wrstuden #include <hpcmips/tx/tx39clockreg.h> /* XXX */
53 1.3.2.2 wrstuden
54 1.3.2.2 wrstuden #define SET(t, f) (t) |= (f)
55 1.3.2.2 wrstuden #define CLR(t, f) (t) &= ~(f)
56 1.3.2.2 wrstuden #define ISSET(t, f) ((t) & (f))
57 1.3.2.2 wrstuden
58 1.3.2.2 wrstuden #ifdef TX39UARTDEBUG
59 1.3.2.2 wrstuden #define DPRINTF(arg) printf arg
60 1.3.2.2 wrstuden #else
61 1.3.2.2 wrstuden #define DPRINTF(arg)
62 1.3.2.2 wrstuden #endif
63 1.3.2.2 wrstuden
64 1.3.2.2 wrstuden #define MAXBUF 16
65 1.3.2.2 wrstuden struct txcom_buf {
66 1.3.2.2 wrstuden int b_cnt;
67 1.3.2.2 wrstuden int b_in;
68 1.3.2.2 wrstuden int b_out;
69 1.3.2.2 wrstuden char b_buf[MAXBUF];
70 1.3.2.2 wrstuden };
71 1.3.2.2 wrstuden
72 1.3.2.2 wrstuden #define TXCOM_HW_CONSOLE 0x40
73 1.3.2.2 wrstuden struct txcom_softc {
74 1.3.2.2 wrstuden struct device sc_dev;
75 1.3.2.2 wrstuden struct tty *sc_tty;
76 1.3.2.2 wrstuden tx_chipset_tag_t sc_tc;
77 1.3.2.2 wrstuden int sc_slot; /* UARTA or UARTB */
78 1.3.2.2 wrstuden int sc_cflag;
79 1.3.2.2 wrstuden int sc_speed;
80 1.3.2.2 wrstuden struct txcom_buf *sc_rxbuf;
81 1.3.2.2 wrstuden struct txcom_buf *sc_txbuf;
82 1.3.2.2 wrstuden char **sc_msg;
83 1.3.2.2 wrstuden int sc_hwflags;
84 1.3.2.2 wrstuden u_int8_t *sc_tba; /* transmit buffer address */
85 1.3.2.2 wrstuden int sc_tbc, sc_heldtbc; /* transmit byte count */
86 1.3.2.2 wrstuden u_int8_t sc_rbuf; /* XXX */
87 1.3.2.2 wrstuden
88 1.3.2.2 wrstuden };
89 1.3.2.2 wrstuden volatile int com_softrxintr_scheduled;
90 1.3.2.2 wrstuden
91 1.3.2.2 wrstuden extern struct cfdriver txcom_cd;
92 1.3.2.2 wrstuden
93 1.3.2.2 wrstuden int txcom_match __P((struct device*, struct cfdata*, void*));
94 1.3.2.2 wrstuden void txcom_attach __P((struct device*, struct device*, void*));
95 1.3.2.2 wrstuden int txcom_txintr __P((void*));
96 1.3.2.2 wrstuden int txcom_a_rxintr __P((void*));
97 1.3.2.2 wrstuden int txcom_b_rxintr __P((void*));
98 1.3.2.2 wrstuden void txcom_rxsoft __P((void*));
99 1.3.2.2 wrstuden
100 1.3.2.2 wrstuden int txcom_cngetc __P((dev_t));
101 1.3.2.2 wrstuden void txcom_cnputc __P((dev_t, int));
102 1.3.2.2 wrstuden void txcom_cnpollc __P((dev_t, int));
103 1.3.2.2 wrstuden
104 1.3.2.2 wrstuden void txcomstart __P((struct tty*));
105 1.3.2.2 wrstuden int txcomparam __P((struct tty*, struct termios*));
106 1.3.2.2 wrstuden cdev_decl(txcom);
107 1.3.2.2 wrstuden
108 1.3.2.2 wrstuden /* Serial console */
109 1.3.2.2 wrstuden static struct consdev txcomcons = {
110 1.3.2.2 wrstuden NULL, NULL, txcom_cngetc, txcom_cnputc,
111 1.3.2.2 wrstuden txcom_cnpollc, NODEV, CN_NORMAL
112 1.3.2.2 wrstuden };
113 1.3.2.2 wrstuden static struct txcom_softc cn_sc;
114 1.3.2.2 wrstuden
115 1.3.2.2 wrstuden struct cfattach txcom_ca = {
116 1.3.2.2 wrstuden sizeof(struct txcom_softc), txcom_match, txcom_attach
117 1.3.2.2 wrstuden };
118 1.3.2.2 wrstuden
119 1.3.2.2 wrstuden int txcom_enable __P((struct txcom_softc*));
120 1.3.2.2 wrstuden void txcom_disable __P((struct txcom_softc*));
121 1.3.2.2 wrstuden void txcom_setmode __P((struct txcom_softc*));
122 1.3.2.2 wrstuden void txcom_setbaudrate __P((struct txcom_softc*));
123 1.3.2.2 wrstuden
124 1.3.2.2 wrstuden int
125 1.3.2.2 wrstuden txcom_match(parent, cf, aux)
126 1.3.2.2 wrstuden struct device *parent;
127 1.3.2.2 wrstuden struct cfdata *cf;
128 1.3.2.2 wrstuden void *aux;
129 1.3.2.2 wrstuden {
130 1.3.2.2 wrstuden /* if the autoconfiguration got this far, there's a slot here */
131 1.3.2.2 wrstuden return 1;
132 1.3.2.2 wrstuden }
133 1.3.2.2 wrstuden
134 1.3.2.2 wrstuden void
135 1.3.2.2 wrstuden txcom_attach(parent, self, aux)
136 1.3.2.2 wrstuden struct device *parent;
137 1.3.2.2 wrstuden struct device *self;
138 1.3.2.2 wrstuden void *aux;
139 1.3.2.2 wrstuden {
140 1.3.2.2 wrstuden struct tx39uart_attach_args *ua = aux;
141 1.3.2.2 wrstuden struct txcom_softc *sc = (void*)self;
142 1.3.2.2 wrstuden tx_chipset_tag_t tc;
143 1.3.2.2 wrstuden struct tty *tp;
144 1.3.2.2 wrstuden
145 1.3.2.2 wrstuden printf("\n");
146 1.3.2.2 wrstuden
147 1.3.2.2 wrstuden /* Check this slot used as serial console */
148 1.3.2.2 wrstuden if (ua->ua_slot == cn_sc.sc_slot &&
149 1.3.2.2 wrstuden (cn_sc.sc_hwflags & TXCOM_HW_CONSOLE)) {
150 1.3.2.2 wrstuden memcpy(&cn_sc, self, sizeof(struct device));
151 1.3.2.2 wrstuden memcpy(self, &cn_sc, sizeof(struct txcom_softc));
152 1.3.2.2 wrstuden }
153 1.3.2.2 wrstuden
154 1.3.2.2 wrstuden tc = sc->sc_tc = ua->ua_tc;
155 1.3.2.2 wrstuden sc->sc_slot = ua->ua_slot;
156 1.3.2.2 wrstuden
157 1.3.2.2 wrstuden tp = ttymalloc();
158 1.3.2.2 wrstuden tp->t_oproc = txcomstart;
159 1.3.2.2 wrstuden tp->t_param = txcomparam;
160 1.3.2.2 wrstuden tp->t_hwiflow = NULL;
161 1.3.2.2 wrstuden sc->sc_tty = tp;
162 1.3.2.2 wrstuden cn_sc.sc_tty = tp;
163 1.3.2.2 wrstuden tty_attach(tp);
164 1.3.2.2 wrstuden
165 1.3.2.2 wrstuden if (ISSET(sc->sc_hwflags, TXCOM_HW_CONSOLE)) {
166 1.3.2.2 wrstuden int maj;
167 1.3.2.2 wrstuden /* locate the major number */
168 1.3.2.2 wrstuden for (maj = 0; maj < nchrdev; maj++)
169 1.3.2.2 wrstuden if (cdevsw[maj].d_open == txcomopen)
170 1.3.2.2 wrstuden break;
171 1.3.2.2 wrstuden
172 1.3.2.2 wrstuden cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
173 1.3.2.2 wrstuden
174 1.3.2.2 wrstuden printf("%s: console\n", sc->sc_dev.dv_xname);
175 1.3.2.2 wrstuden }
176 1.3.2.2 wrstuden
177 1.3.2.2 wrstuden
178 1.3.2.2 wrstuden /*
179 1.3.2.2 wrstuden * Enable interrupt
180 1.3.2.2 wrstuden */
181 1.3.2.2 wrstuden switch (sc->sc_slot) {
182 1.3.2.2 wrstuden case TX39_UARTA:
183 1.3.2.2 wrstuden tx_intr_establish(tc, MAKEINTR(2, TX39_INTRSTATUS2_UARTARXINT),
184 1.3.2.2 wrstuden IST_EDGE, IPL_TTY,
185 1.3.2.2 wrstuden txcom_a_rxintr, sc);
186 1.3.2.2 wrstuden break;
187 1.3.2.2 wrstuden case TX39_UARTB:
188 1.3.2.2 wrstuden tx_intr_establish(tc, MAKEINTR(2, TX39_INTRSTATUS2_UARTBRXINT),
189 1.3.2.2 wrstuden IST_EDGE, IPL_TTY,
190 1.3.2.2 wrstuden txcom_b_rxintr, sc);
191 1.3.2.2 wrstuden break;
192 1.3.2.2 wrstuden }
193 1.3.2.2 wrstuden }
194 1.3.2.2 wrstuden
195 1.3.2.2 wrstuden int
196 1.3.2.2 wrstuden txcom_enable(sc)
197 1.3.2.2 wrstuden struct txcom_softc *sc;
198 1.3.2.2 wrstuden {
199 1.3.2.2 wrstuden tx_chipset_tag_t tc;
200 1.3.2.2 wrstuden txreg_t reg;
201 1.3.2.2 wrstuden int slot;
202 1.3.2.2 wrstuden
203 1.3.2.2 wrstuden tc = sc->sc_tc;
204 1.3.2.2 wrstuden slot = sc->sc_slot;
205 1.3.2.2 wrstuden
206 1.3.2.2 wrstuden reg = tx_conf_read(tc, TX39_UARTCTRL1_REG(slot));
207 1.3.2.2 wrstuden /* Power */
208 1.3.2.2 wrstuden reg |= TX39_UARTCTRL1_ENUART;
209 1.3.2.2 wrstuden reg &= ~TX39_UARTCTRL1_ENBREAHALT;
210 1.3.2.2 wrstuden tx_conf_write(tc, TX39_UARTCTRL1_REG(slot), reg);
211 1.3.2.2 wrstuden /*
212 1.3.2.2 wrstuden * XXX Disable DMA (DMA not coded yet)
213 1.3.2.2 wrstuden */
214 1.3.2.2 wrstuden reg &= ~(TX39_UARTCTRL1_ENDMARX | TX39_UARTCTRL1_ENDMATX);
215 1.3.2.2 wrstuden tx_conf_write(tc, TX39_UARTCTRL1_REG(slot), reg);
216 1.3.2.2 wrstuden
217 1.3.2.2 wrstuden /* XXX Clock */
218 1.3.2.2 wrstuden reg = tx_conf_read(tc, TX39_CLOCKCTRL_REG);
219 1.3.2.2 wrstuden reg |= (slot ? TX39_CLOCK_ENUARTBCLK : TX39_CLOCK_ENUARTACLK);
220 1.3.2.2 wrstuden tx_conf_write(tc, TX39_CLOCKCTRL_REG, reg);
221 1.3.2.2 wrstuden
222 1.3.2.2 wrstuden
223 1.3.2.2 wrstuden return 0;
224 1.3.2.2 wrstuden }
225 1.3.2.2 wrstuden
226 1.3.2.2 wrstuden void
227 1.3.2.2 wrstuden txcom_disable(sc)
228 1.3.2.2 wrstuden struct txcom_softc *sc;
229 1.3.2.2 wrstuden {
230 1.3.2.2 wrstuden tx_chipset_tag_t tc;
231 1.3.2.2 wrstuden txreg_t reg;
232 1.3.2.2 wrstuden int slot;
233 1.3.2.2 wrstuden
234 1.3.2.2 wrstuden tc = sc->sc_tc;
235 1.3.2.2 wrstuden slot = sc->sc_slot;
236 1.3.2.2 wrstuden
237 1.3.2.2 wrstuden reg = tx_conf_read(tc, TX39_UARTCTRL1_REG(slot));
238 1.3.2.2 wrstuden /* DMA */
239 1.3.2.2 wrstuden reg &= ~(TX39_UARTCTRL1_ENDMARX | TX39_UARTCTRL1_ENDMATX);
240 1.3.2.2 wrstuden /* Power */
241 1.3.2.2 wrstuden reg &= ~TX39_UARTCTRL1_ENUART;
242 1.3.2.2 wrstuden tx_conf_write(tc, TX39_UARTCTRL1_REG(slot), reg);
243 1.3.2.2 wrstuden /* Clock */
244 1.3.2.2 wrstuden reg = tx_conf_read(tc, TX39_CLOCKCTRL_REG);
245 1.3.2.2 wrstuden reg &= ~(slot ? TX39_CLOCK_ENUARTBCLK : TX39_CLOCK_ENUARTACLK);
246 1.3.2.2 wrstuden tx_conf_write(tc, TX39_CLOCKCTRL_REG, reg);
247 1.3.2.2 wrstuden
248 1.3.2.2 wrstuden }
249 1.3.2.2 wrstuden
250 1.3.2.2 wrstuden int
251 1.3.2.2 wrstuden txcom_cnattach(slot, speed, cflag)
252 1.3.2.2 wrstuden int slot, speed, cflag;
253 1.3.2.2 wrstuden {
254 1.3.2.2 wrstuden cn_tab = &txcomcons;
255 1.3.2.2 wrstuden
256 1.3.2.2 wrstuden cn_sc.sc_tc = tx_conf_get_tag();
257 1.3.2.2 wrstuden cn_sc.sc_slot = slot;
258 1.3.2.2 wrstuden cn_sc.sc_cflag = cflag;
259 1.3.2.2 wrstuden cn_sc.sc_speed = speed;
260 1.3.2.2 wrstuden cn_sc.sc_hwflags |= TXCOM_HW_CONSOLE;
261 1.3.2.2 wrstuden #ifdef WINCE_DEFAULT_SETTING
262 1.3.2.2 wrstuden #warning WINCE_DEFAULT_SETTING
263 1.3.2.2 wrstuden #else
264 1.3.2.2 wrstuden txcom_enable(&cn_sc);
265 1.3.2.2 wrstuden txcom_setmode(&cn_sc);
266 1.3.2.2 wrstuden txcom_setbaudrate(&cn_sc);
267 1.3.2.2 wrstuden #endif
268 1.3.2.2 wrstuden return 0;
269 1.3.2.2 wrstuden }
270 1.3.2.2 wrstuden
271 1.3.2.2 wrstuden int
272 1.3.2.2 wrstuden txcom_cngetc(dev)
273 1.3.2.2 wrstuden dev_t dev;
274 1.3.2.2 wrstuden {
275 1.3.2.2 wrstuden tx_chipset_tag_t tc;
276 1.3.2.2 wrstuden int ofs, c;
277 1.3.2.2 wrstuden tc = cn_sc.sc_tc;
278 1.3.2.2 wrstuden
279 1.3.2.2 wrstuden ofs = TX39_UARTCTRL1_REG(cn_sc.sc_slot);
280 1.3.2.2 wrstuden
281 1.3.2.2 wrstuden while(!(TX39_UARTCTRL1_RXHOLDFULL & tx_conf_read(tc, ofs)))
282 1.3.2.2 wrstuden ;
283 1.3.2.2 wrstuden ofs = TX39_UARTRXHOLD_REG(cn_sc.sc_slot);
284 1.3.2.2 wrstuden c = TX39_UARTRXHOLD_RXDATA(tx_conf_read(tc, ofs));
285 1.3.2.2 wrstuden if (c == '\r') {
286 1.3.2.2 wrstuden c = '\n';
287 1.3.2.2 wrstuden }
288 1.3.2.2 wrstuden
289 1.3.2.2 wrstuden return c;
290 1.3.2.2 wrstuden }
291 1.3.2.2 wrstuden
292 1.3.2.2 wrstuden void
293 1.3.2.2 wrstuden txcom_cnputc(dev, c)
294 1.3.2.2 wrstuden dev_t dev;
295 1.3.2.2 wrstuden int c;
296 1.3.2.2 wrstuden {
297 1.3.2.2 wrstuden tx_chipset_tag_t tc;
298 1.3.2.2 wrstuden int ofs;
299 1.3.2.2 wrstuden
300 1.3.2.2 wrstuden tc = cn_sc.sc_tc;
301 1.3.2.2 wrstuden ofs = TX39_UARTCTRL1_REG(cn_sc.sc_slot);
302 1.3.2.2 wrstuden
303 1.3.2.2 wrstuden while (!(tx_conf_read(tc, ofs) & TX39_UARTCTRL1_EMPTY))
304 1.3.2.2 wrstuden delay(20);
305 1.3.2.2 wrstuden
306 1.3.2.2 wrstuden tx_conf_write(tc, TX39_UARTTXHOLD_REG(cn_sc.sc_slot),
307 1.3.2.2 wrstuden (c & TX39_UARTTXHOLD_TXDATA_MASK));
308 1.3.2.2 wrstuden
309 1.3.2.2 wrstuden while (!(tx_conf_read(tc, ofs) & TX39_UARTCTRL1_EMPTY))
310 1.3.2.2 wrstuden delay(20);
311 1.3.2.2 wrstuden
312 1.3.2.2 wrstuden }
313 1.3.2.2 wrstuden
314 1.3.2.2 wrstuden void
315 1.3.2.2 wrstuden txcom_cnpollc(dev, on)
316 1.3.2.2 wrstuden dev_t dev;
317 1.3.2.2 wrstuden int on;
318 1.3.2.2 wrstuden {
319 1.3.2.2 wrstuden }
320 1.3.2.2 wrstuden
321 1.3.2.2 wrstuden void
322 1.3.2.2 wrstuden txcom_setmode(sc)
323 1.3.2.2 wrstuden struct txcom_softc *sc;
324 1.3.2.2 wrstuden {
325 1.3.2.2 wrstuden tcflag_t cflag;
326 1.3.2.2 wrstuden txreg_t reg;
327 1.3.2.2 wrstuden
328 1.3.2.2 wrstuden cflag = sc->sc_cflag;
329 1.3.2.2 wrstuden reg = tx_conf_read(sc->sc_tc, TX39_UARTCTRL1_REG(sc->sc_slot));
330 1.3.2.2 wrstuden
331 1.3.2.2 wrstuden switch (ISSET(cflag, CSIZE)) {
332 1.3.2.2 wrstuden default:
333 1.3.2.2 wrstuden printf("txcom_setmode: CS7, CS8 only. use CS7");
334 1.3.2.2 wrstuden /* FALL THROUGH */
335 1.3.2.2 wrstuden case CS7:
336 1.3.2.2 wrstuden reg |= TX39_UARTCTRL1_BIT7;
337 1.3.2.2 wrstuden break;
338 1.3.2.2 wrstuden case CS8:
339 1.3.2.2 wrstuden reg &= ~TX39_UARTCTRL1_BIT7;
340 1.3.2.2 wrstuden break;
341 1.3.2.2 wrstuden }
342 1.3.2.2 wrstuden if (ISSET(cflag, PARENB)) {
343 1.3.2.2 wrstuden reg |= TX39_UARTCTRL1_ENPARITY;
344 1.3.2.2 wrstuden if (ISSET(cflag, PARODD)) {
345 1.3.2.2 wrstuden reg &= ~TX39_UARTCTRL1_EVENPARITY;
346 1.3.2.2 wrstuden } else {
347 1.3.2.2 wrstuden reg |= TX39_UARTCTRL1_EVENPARITY;
348 1.3.2.2 wrstuden }
349 1.3.2.2 wrstuden } else {
350 1.3.2.2 wrstuden reg &= ~TX39_UARTCTRL1_ENPARITY;
351 1.3.2.2 wrstuden }
352 1.3.2.2 wrstuden if (ISSET(cflag, CSTOPB)) {
353 1.3.2.2 wrstuden reg |= TX39_UARTCTRL1_TWOSTOP;
354 1.3.2.2 wrstuden }
355 1.3.2.2 wrstuden tx_conf_write(sc->sc_tc, TX39_UARTCTRL1_REG(sc->sc_slot), reg);
356 1.3.2.2 wrstuden
357 1.3.2.2 wrstuden }
358 1.3.2.2 wrstuden
359 1.3.2.2 wrstuden void
360 1.3.2.2 wrstuden txcom_setbaudrate(sc)
361 1.3.2.2 wrstuden struct txcom_softc *sc;
362 1.3.2.2 wrstuden {
363 1.3.2.2 wrstuden int baudrate;
364 1.3.2.2 wrstuden txreg_t reg;
365 1.3.2.2 wrstuden
366 1.3.2.2 wrstuden baudrate = TX39_UARTCLOCKHZ / (sc->sc_speed * 16) - 1;
367 1.3.2.2 wrstuden reg = TX39_UARTCTRL2_BAUDRATE_SET(0, baudrate);
368 1.3.2.2 wrstuden
369 1.3.2.2 wrstuden tx_conf_write(sc->sc_tc, TX39_UARTCTRL2_REG(sc->sc_slot), reg);
370 1.3.2.2 wrstuden }
371 1.3.2.2 wrstuden
372 1.3.2.2 wrstuden void
373 1.3.2.2 wrstuden txcom_rxsoft(arg)
374 1.3.2.2 wrstuden void *arg;
375 1.3.2.2 wrstuden {
376 1.3.2.2 wrstuden struct txcom_softc *sc = arg;
377 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
378 1.3.2.2 wrstuden int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint;
379 1.3.2.2 wrstuden int code = sc->sc_rbuf;
380 1.3.2.2 wrstuden
381 1.3.2.2 wrstuden DPRINTF(("txcom_rxsoft %c %08x\n", code, code));
382 1.3.2.2 wrstuden com_softrxintr_scheduled = 0;
383 1.3.2.2 wrstuden
384 1.3.2.2 wrstuden if ((*rint)(code, tp) == -1) {
385 1.3.2.2 wrstuden
386 1.3.2.2 wrstuden }
387 1.3.2.2 wrstuden }
388 1.3.2.2 wrstuden
389 1.3.2.2 wrstuden int
390 1.3.2.2 wrstuden txcom_a_rxintr(arg)
391 1.3.2.2 wrstuden void *arg;
392 1.3.2.2 wrstuden {
393 1.3.2.2 wrstuden struct txcom_softc *sc = arg;
394 1.3.2.2 wrstuden u_int8_t c;
395 1.3.2.2 wrstuden
396 1.3.2.2 wrstuden if (!com_softrxintr_scheduled) {
397 1.3.2.2 wrstuden com_softrxintr_scheduled = 1;
398 1.3.2.2 wrstuden timeout(txcom_rxsoft, arg, 1);
399 1.3.2.2 wrstuden }
400 1.3.2.2 wrstuden DPRINTF(("txcom_rxintr\n"));
401 1.3.2.2 wrstuden c = 0xff & tx_conf_read(sc->sc_tc, TX39_UARTRXHOLD_REG(sc->sc_slot));
402 1.3.2.2 wrstuden sc->sc_rbuf = c;
403 1.3.2.2 wrstuden
404 1.3.2.2 wrstuden return 0;
405 1.3.2.2 wrstuden }
406 1.3.2.2 wrstuden
407 1.3.2.2 wrstuden int
408 1.3.2.2 wrstuden txcom_b_rxintr(arg)
409 1.3.2.2 wrstuden void *arg;
410 1.3.2.2 wrstuden {
411 1.3.2.2 wrstuden struct txcom_softc *sc = arg;
412 1.3.2.2 wrstuden u_int8_t c;
413 1.3.2.2 wrstuden
414 1.3.2.2 wrstuden if (!com_softrxintr_scheduled) {
415 1.3.2.2 wrstuden com_softrxintr_scheduled = 1;
416 1.3.2.2 wrstuden timeout(txcom_rxsoft, arg, 1);
417 1.3.2.2 wrstuden }
418 1.3.2.2 wrstuden DPRINTF(("txcom_rxintr\n"));
419 1.3.2.2 wrstuden c = 0xff & tx_conf_read(sc->sc_tc, TX39_UARTRXHOLD_REG(sc->sc_slot));
420 1.3.2.2 wrstuden sc->sc_rbuf = c;
421 1.3.2.2 wrstuden
422 1.3.2.2 wrstuden return 0;
423 1.3.2.2 wrstuden }
424 1.3.2.2 wrstuden
425 1.3.2.2 wrstuden
426 1.3.2.2 wrstuden int
427 1.3.2.2 wrstuden txcomopen(dev, flag, mode, p)
428 1.3.2.2 wrstuden dev_t dev;
429 1.3.2.2 wrstuden int flag, mode;
430 1.3.2.2 wrstuden struct proc *p;
431 1.3.2.2 wrstuden {
432 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
433 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
434 1.3.2.2 wrstuden int err;
435 1.3.2.2 wrstuden struct termios t;
436 1.3.2.2 wrstuden
437 1.3.2.2 wrstuden tp->t_dev = dev;
438 1.3.2.2 wrstuden
439 1.3.2.2 wrstuden /* XXX XXX XXX */
440 1.3.2.2 wrstuden tp->t_ispeed = 0;
441 1.3.2.2 wrstuden tp->t_ospeed = 9600;
442 1.3.2.2 wrstuden tp->t_cflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8 | CLOCAL | HUPCL;
443 1.3.2.2 wrstuden txcomparam(tp, &t); /* not yet */
444 1.3.2.2 wrstuden /* XXX XXX XXX */
445 1.3.2.2 wrstuden
446 1.3.2.2 wrstuden tp->t_iflag = TTYDEF_IFLAG;
447 1.3.2.2 wrstuden tp->t_oflag = TTYDEF_OFLAG;
448 1.3.2.2 wrstuden tp->t_lflag = TTYDEF_LFLAG;
449 1.3.2.2 wrstuden ttychars(tp);
450 1.3.2.2 wrstuden ttsetwater(tp);
451 1.3.2.2 wrstuden
452 1.3.2.2 wrstuden if ((err = ttyopen(tp, minor(dev), ISSET(flag, O_NONBLOCK)))) {
453 1.3.2.2 wrstuden DPRINTF(("txcomopen: ttyopen failed\n"));
454 1.3.2.2 wrstuden return err;
455 1.3.2.2 wrstuden }
456 1.3.2.2 wrstuden if ((err = (*linesw[tp->t_line].l_open)(dev, tp))) {
457 1.3.2.2 wrstuden DPRINTF(("txcomopen: line dicipline open failed\n"));
458 1.3.2.2 wrstuden return err;
459 1.3.2.2 wrstuden }
460 1.3.2.2 wrstuden
461 1.3.2.2 wrstuden return err;
462 1.3.2.2 wrstuden }
463 1.3.2.2 wrstuden
464 1.3.2.2 wrstuden int
465 1.3.2.2 wrstuden txcomclose(dev, flag, mode, p)
466 1.3.2.2 wrstuden dev_t dev;
467 1.3.2.2 wrstuden int flag, mode;
468 1.3.2.2 wrstuden struct proc *p;
469 1.3.2.2 wrstuden {
470 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
471 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
472 1.3.2.2 wrstuden
473 1.3.2.2 wrstuden DPRINTF(("txcomclose\n"));
474 1.3.2.2 wrstuden (*linesw[tp->t_line].l_close)(tp, flag);
475 1.3.2.2 wrstuden ttyclose(tp);
476 1.3.2.2 wrstuden
477 1.3.2.2 wrstuden return 0;
478 1.3.2.2 wrstuden }
479 1.3.2.2 wrstuden
480 1.3.2.2 wrstuden int
481 1.3.2.2 wrstuden txcomread(dev, uio, flag)
482 1.3.2.2 wrstuden dev_t dev;
483 1.3.2.2 wrstuden struct uio *uio;
484 1.3.2.2 wrstuden int flag;
485 1.3.2.2 wrstuden {
486 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
487 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
488 1.3.2.2 wrstuden DPRINTF(("txcomread\n"));
489 1.3.2.2 wrstuden return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
490 1.3.2.2 wrstuden }
491 1.3.2.2 wrstuden
492 1.3.2.2 wrstuden int
493 1.3.2.2 wrstuden txcomwrite(dev, uio, flag)
494 1.3.2.2 wrstuden dev_t dev;
495 1.3.2.2 wrstuden struct uio *uio;
496 1.3.2.2 wrstuden int flag;
497 1.3.2.2 wrstuden {
498 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
499 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
500 1.3.2.2 wrstuden
501 1.3.2.2 wrstuden DPRINTF(("txcomwrite\n"));
502 1.3.2.2 wrstuden return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
503 1.3.2.2 wrstuden }
504 1.3.2.2 wrstuden
505 1.3.2.2 wrstuden struct tty *
506 1.3.2.2 wrstuden txcomtty(dev)
507 1.3.2.2 wrstuden dev_t dev;
508 1.3.2.2 wrstuden {
509 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
510 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
511 1.3.2.2 wrstuden DPRINTF(("txcomtty\n"));
512 1.3.2.2 wrstuden return tp;
513 1.3.2.2 wrstuden }
514 1.3.2.2 wrstuden
515 1.3.2.2 wrstuden int
516 1.3.2.2 wrstuden txcomioctl(dev, cmd, data, flag, p)
517 1.3.2.2 wrstuden dev_t dev;
518 1.3.2.2 wrstuden u_long cmd;
519 1.3.2.2 wrstuden caddr_t data;
520 1.3.2.2 wrstuden int flag;
521 1.3.2.2 wrstuden struct proc *p;
522 1.3.2.2 wrstuden {
523 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(dev)];
524 1.3.2.2 wrstuden struct tty *tp = sc->sc_tty;
525 1.3.2.2 wrstuden int error;
526 1.3.2.2 wrstuden
527 1.3.2.2 wrstuden DPRINTF(("txcomioctl\n"));
528 1.3.2.2 wrstuden error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
529 1.3.2.2 wrstuden if (error >= 0)
530 1.3.2.2 wrstuden return (error);
531 1.3.2.2 wrstuden
532 1.3.2.2 wrstuden error = ttioctl(tp, cmd, data, flag, p);
533 1.3.2.2 wrstuden if (error >= 0)
534 1.3.2.2 wrstuden return (error);
535 1.3.2.2 wrstuden
536 1.3.2.2 wrstuden return 0;
537 1.3.2.2 wrstuden }
538 1.3.2.2 wrstuden
539 1.3.2.2 wrstuden void
540 1.3.2.2 wrstuden txcomstop(tp, flag)
541 1.3.2.2 wrstuden struct tty *tp;
542 1.3.2.2 wrstuden int flag;
543 1.3.2.2 wrstuden {
544 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(tp->t_dev)];
545 1.3.2.2 wrstuden int s;
546 1.3.2.2 wrstuden
547 1.3.2.2 wrstuden DPRINTF(("txcomstop\n"));
548 1.3.2.2 wrstuden s = spltty();
549 1.3.2.2 wrstuden
550 1.3.2.2 wrstuden if (ISSET(tp->t_state, TS_BUSY)) {
551 1.3.2.2 wrstuden /* Stop transmitting at the next chunk. */
552 1.3.2.2 wrstuden sc->sc_tbc = 0;
553 1.3.2.2 wrstuden sc->sc_heldtbc = 0;
554 1.3.2.2 wrstuden if (!ISSET(tp->t_state, TS_TTSTOP))
555 1.3.2.2 wrstuden SET(tp->t_state, TS_FLUSH);
556 1.3.2.2 wrstuden }
557 1.3.2.2 wrstuden splx(s);
558 1.3.2.2 wrstuden }
559 1.3.2.2 wrstuden
560 1.3.2.2 wrstuden void
561 1.3.2.2 wrstuden txcomstart(tp)
562 1.3.2.2 wrstuden struct tty *tp;
563 1.3.2.2 wrstuden {
564 1.3.2.2 wrstuden struct txcom_softc *sc = txcom_cd.cd_devs[minor(tp->t_dev)];
565 1.3.2.2 wrstuden int s;
566 1.3.2.2 wrstuden
567 1.3.2.2 wrstuden DPRINTF(("txcomstart\n"));
568 1.3.2.2 wrstuden s = spltty();
569 1.3.2.2 wrstuden if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
570 1.3.2.2 wrstuden return;
571 1.3.2.2 wrstuden
572 1.3.2.2 wrstuden if (tp->t_outq.c_cc <= tp->t_lowat) {
573 1.3.2.2 wrstuden if (ISSET(tp->t_state, TS_ASLEEP)) {
574 1.3.2.2 wrstuden CLR(tp->t_state, TS_ASLEEP);
575 1.3.2.2 wrstuden wakeup(&tp->t_outq);
576 1.3.2.2 wrstuden }
577 1.3.2.2 wrstuden selwakeup(&tp->t_wsel);
578 1.3.2.2 wrstuden if (tp->t_outq.c_cc == 0)
579 1.3.2.2 wrstuden return;
580 1.3.2.2 wrstuden }
581 1.3.2.2 wrstuden sc->sc_tba = tp->t_outq.c_cf;
582 1.3.2.2 wrstuden sc->sc_tbc = ndqb(&tp->t_outq, 0);
583 1.3.2.2 wrstuden while (sc->sc_tbc-- > 0) {
584 1.3.2.2 wrstuden txcom_cnputc(tp->t_dev, *sc->sc_tba++);
585 1.3.2.2 wrstuden }
586 1.3.2.2 wrstuden sc->sc_tbc = 0;
587 1.3.2.2 wrstuden
588 1.3.2.2 wrstuden CLR(tp->t_state, TS_BUSY);
589 1.3.2.2 wrstuden if (ISSET(tp->t_state, TS_FLUSH)) {
590 1.3.2.2 wrstuden CLR(tp->t_state, TS_FLUSH);
591 1.3.2.2 wrstuden } else {
592 1.3.2.2 wrstuden ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
593 1.3.2.2 wrstuden }
594 1.3.2.2 wrstuden splx(s);
595 1.3.2.2 wrstuden }
596 1.3.2.2 wrstuden
597 1.3.2.2 wrstuden int
598 1.3.2.2 wrstuden txcomparam(tp, t)
599 1.3.2.2 wrstuden struct tty *tp;
600 1.3.2.2 wrstuden struct termios *t;
601 1.3.2.2 wrstuden {
602 1.3.2.2 wrstuden DPRINTF(("txcomparam\n"));
603 1.3.2.2 wrstuden return 0;
604 1.3.2.2 wrstuden }
605