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