uart_tty.c (9199c09a159c4e3e98c212d4eec1edc5252d9e33) uart_tty.c (27d5dc189c8e2eaf1cbe7e47078bf065854ba210)
1/*-
1/*
2 * Copyright (c) 2003 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright

--- 24 unchanged lines hidden (view full) ---

34#include <sys/cons.h>
35#include <sys/fcntl.h>
36#include <sys/interrupt.h>
37#include <sys/kernel.h>
38#include <sys/malloc.h>
39#include <sys/reboot.h>
40#include <machine/bus.h>
41#include <sys/rman.h>
2 * Copyright (c) 2003 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright

--- 24 unchanged lines hidden (view full) ---

34#include <sys/cons.h>
35#include <sys/fcntl.h>
36#include <sys/interrupt.h>
37#include <sys/kernel.h>
38#include <sys/malloc.h>
39#include <sys/reboot.h>
40#include <machine/bus.h>
41#include <sys/rman.h>
42#include <sys/termios.h>
42#include <sys/tty.h>
43#include <machine/resource.h>
44#include <machine/stdarg.h>
45
46#include <dev/uart/uart.h>
47#include <dev/uart/uart_bus.h>
48#include <dev/uart/uart_cpu.h>
49
50#include "uart_if.h"
51
43#include <sys/tty.h>
44#include <machine/resource.h>
45#include <machine/stdarg.h>
46
47#include <dev/uart/uart.h>
48#include <dev/uart/uart_bus.h>
49#include <dev/uart/uart_cpu.h>
50
51#include "uart_if.h"
52
53#define UART_MINOR_CALLOUT 0x10000
54
52static cn_probe_t uart_cnprobe;
53static cn_init_t uart_cninit;
54static cn_term_t uart_cnterm;
55static cn_getc_t uart_cngetc;
55static cn_probe_t uart_cnprobe;
56static cn_init_t uart_cninit;
57static cn_term_t uart_cnterm;
58static cn_getc_t uart_cngetc;
59static cn_checkc_t uart_cncheckc;
56static cn_putc_t uart_cnputc;
57
60static cn_putc_t uart_cnputc;
61
58CONSOLE_DRIVER(uart);
62CONS_DRIVER(uart, uart_cnprobe, uart_cninit, uart_cnterm, uart_cngetc,
63 uart_cncheckc, uart_cnputc, NULL);
59
64
65static d_open_t uart_tty_open;
66static d_close_t uart_tty_close;
67static d_ioctl_t uart_tty_ioctl;
68
69static struct cdevsw uart_cdevsw = {
70 .d_open = uart_tty_open,
71 .d_close = uart_tty_close,
72 .d_read = ttyread,
73 .d_write = ttywrite,
74 .d_ioctl = uart_tty_ioctl,
75 .d_poll = ttypoll,
76 .d_name = uart_driver_name,
77 .d_maj = MAJOR_AUTO,
78 .d_flags = D_TTY,
79 .d_kqfilter = ttykqfilter,
80};
81
60static struct uart_devinfo uart_console;
61
62static void
63uart_cnprobe(struct consdev *cp)
64{
65
82static struct uart_devinfo uart_console;
83
84static void
85uart_cnprobe(struct consdev *cp)
86{
87
88 cp->cn_dev = NULL;
66 cp->cn_pri = CN_DEAD;
67
68 KASSERT(uart_console.cookie == NULL, ("foo"));
69
70 if (uart_cpu_getdev(UART_DEV_CONSOLE, &uart_console))
71 return;
72
73 if (uart_probe(&uart_console))
74 return;
75
89 cp->cn_pri = CN_DEAD;
90
91 KASSERT(uart_console.cookie == NULL, ("foo"));
92
93 if (uart_cpu_getdev(UART_DEV_CONSOLE, &uart_console))
94 return;
95
96 if (uart_probe(&uart_console))
97 return;
98
76 strlcpy(cp->cn_name, uart_driver_name, sizeof(cp->cn_name));
77 cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
78 cp->cn_arg = &uart_console;
79}
80
81static void
82uart_cninit(struct consdev *cp)
83{
84 struct uart_devinfo *di;

--- 25 unchanged lines hidden (view full) ---

110static void
111uart_cnputc(struct consdev *cp, int c)
112{
113
114 uart_putc(cp->cn_arg, c);
115}
116
117static int
99 cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
100 cp->cn_arg = &uart_console;
101}
102
103static void
104uart_cninit(struct consdev *cp)
105{
106 struct uart_devinfo *di;

--- 25 unchanged lines hidden (view full) ---

132static void
133uart_cnputc(struct consdev *cp, int c)
134{
135
136 uart_putc(cp->cn_arg, c);
137}
138
139static int
118uart_cngetc(struct consdev *cp)
140uart_cncheckc(struct consdev *cp)
119{
120
121 return (uart_poll(cp->cn_arg));
122}
123
124static int
141{
142
143 return (uart_poll(cp->cn_arg));
144}
145
146static int
125uart_tty_open(struct tty *tp)
147uart_cngetc(struct consdev *cp)
126{
148{
127 struct uart_softc *sc;
128
149
129 sc = tty_softc(tp);
130
131 if (sc == NULL || sc->sc_leaving)
132 return (ENXIO);
133
134 sc->sc_opened = 1;
135 return (0);
150 return (uart_getc(cp->cn_arg));
136}
137
138static void
151}
152
153static void
139uart_tty_close(struct tty *tp)
154uart_tty_oproc(struct tty *tp)
140{
141 struct uart_softc *sc;
142
155{
156 struct uart_softc *sc;
157
143 sc = tty_softc(tp);
144 if (sc == NULL || sc->sc_leaving || !sc->sc_opened)
158 KASSERT(tp->t_dev != NULL, ("foo"));
159 sc = tp->t_dev->si_drv1;
160 if (sc == NULL || sc->sc_leaving)
145 return;
146
161 return;
162
147 if (sc->sc_hwiflow)
148 UART_IOCTL(sc, UART_IOCTL_IFLOW, 0);
149 if (sc->sc_hwoflow)
150 UART_IOCTL(sc, UART_IOCTL_OFLOW, 0);
151 if (sc->sc_sysdev == NULL)
152 UART_SETSIG(sc, SER_DDTR | SER_DRTS);
163 /*
164 * Handle input flow control. Note that if we have hardware support,
165 * we don't do anything here. We continue to receive until our buffer
166 * is full. At that time we cannot empty the UART itself and it will
167 * de-assert RTS for us. In that situation we're completely stuffed.
168 * Without hardware support, we need to toggle RTS ourselves.
169 */
170 if ((tp->t_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) {
171 if ((tp->t_state & TS_TBLOCK) &&
172 (sc->sc_hwsig & UART_SIG_RTS))
173 UART_SETSIG(sc, UART_SIG_DRTS);
174 else if (!(tp->t_state & TS_TBLOCK) &&
175 !(sc->sc_hwsig & UART_SIG_RTS))
176 UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS);
177 }
153
178
154 wakeup(sc);
155 sc->sc_opened = 0;
156 return;
157}
158
159static void
160uart_tty_outwakeup(struct tty *tp)
161{
162 struct uart_softc *sc;
163
164 sc = tty_softc(tp);
165 if (sc == NULL || sc->sc_leaving)
179 if (tp->t_state & TS_TTSTOP)
166 return;
167
180 return;
181
168 if (sc->sc_txbusy)
182 if ((tp->t_state & TS_BUSY) || sc->sc_txbusy)
169 return;
170
183 return;
184
171 sc->sc_txdatasz = ttydisc_getc(tp, sc->sc_txbuf, sc->sc_txfifosz);
172 if (sc->sc_txdatasz != 0)
173 UART_TRANSMIT(sc);
174}
175
176static void
177uart_tty_inwakeup(struct tty *tp)
178{
179 struct uart_softc *sc;
180
181 sc = tty_softc(tp);
182 if (sc == NULL || sc->sc_leaving)
185 if (tp->t_outq.c_cc == 0) {
186 ttwwakeup(tp);
183 return;
187 return;
184
185 if (sc->sc_isquelch) {
186 if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow)
187 UART_SETSIG(sc, SER_DRTS|SER_RTS);
188 sc->sc_isquelch = 0;
189 uart_sched_softih(sc, SER_INT_RXREADY);
190 }
188 }
191}
192
189
193static int
194uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
195{
196 struct uart_softc *sc;
197
198 sc = tty_softc(tp);
199
200 switch (cmd) {
201 case TIOCSBRK:
202 UART_IOCTL(sc, UART_IOCTL_BREAK, 1);
203 return (0);
204 case TIOCCBRK:
205 UART_IOCTL(sc, UART_IOCTL_BREAK, 0);
206 return (0);
207 default:
208 return pps_ioctl(cmd, data, &sc->sc_pps);
209 }
190 sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf, sc->sc_txfifosz);
191 tp->t_state |= TS_BUSY;
192 UART_TRANSMIT(sc);
193 ttwwakeup(tp);
210}
211
212static int
213uart_tty_param(struct tty *tp, struct termios *t)
214{
215 struct uart_softc *sc;
216 int databits, parity, stopbits;
217
194}
195
196static int
197uart_tty_param(struct tty *tp, struct termios *t)
198{
199 struct uart_softc *sc;
200 int databits, parity, stopbits;
201
218 sc = tty_softc(tp);
202 KASSERT(tp->t_dev != NULL, ("foo"));
203 sc = tp->t_dev->si_drv1;
219 if (sc == NULL || sc->sc_leaving)
220 return (ENODEV);
221 if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0)
222 return (EINVAL);
223 /* Fixate certain parameters for system devices. */
224 if (sc->sc_sysdev != NULL) {
225 t->c_ispeed = t->c_ospeed = sc->sc_sysdev->baudrate;
226 t->c_cflag |= CLOCAL;
227 t->c_cflag &= ~HUPCL;
228 }
229 if (t->c_ospeed == 0) {
204 if (sc == NULL || sc->sc_leaving)
205 return (ENODEV);
206 if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0)
207 return (EINVAL);
208 /* Fixate certain parameters for system devices. */
209 if (sc->sc_sysdev != NULL) {
210 t->c_ispeed = t->c_ospeed = sc->sc_sysdev->baudrate;
211 t->c_cflag |= CLOCAL;
212 t->c_cflag &= ~HUPCL;
213 }
214 if (t->c_ospeed == 0) {
230 UART_SETSIG(sc, SER_DDTR | SER_DRTS);
215 UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
231 return (0);
232 }
233 switch (t->c_cflag & CSIZE) {
234 case CS5: databits = 5; break;
235 case CS6: databits = 6; break;
236 case CS7: databits = 7; break;
237 default: databits = 8; break;
238 }
239 stopbits = (t->c_cflag & CSTOPB) ? 2 : 1;
240 if (t->c_cflag & PARENB)
241 parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD
242 : UART_PARITY_EVEN;
243 else
244 parity = UART_PARITY_NONE;
216 return (0);
217 }
218 switch (t->c_cflag & CSIZE) {
219 case CS5: databits = 5; break;
220 case CS6: databits = 6; break;
221 case CS7: databits = 7; break;
222 default: databits = 8; break;
223 }
224 stopbits = (t->c_cflag & CSTOPB) ? 2 : 1;
225 if (t->c_cflag & PARENB)
226 parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD
227 : UART_PARITY_EVEN;
228 else
229 parity = UART_PARITY_NONE;
245 if (UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity) != 0)
246 return (EINVAL);
247 UART_SETSIG(sc, SER_DDTR | SER_DTR);
230 UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity);
231 UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR);
248 /* Set input flow control state. */
249 if (!sc->sc_hwiflow) {
232 /* Set input flow control state. */
233 if (!sc->sc_hwiflow) {
250 if ((t->c_cflag & CRTS_IFLOW) && sc->sc_isquelch)
251 UART_SETSIG(sc, SER_DRTS);
234 if ((t->c_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK))
235 UART_SETSIG(sc, UART_SIG_DRTS);
252 else
236 else
253 UART_SETSIG(sc, SER_DRTS | SER_RTS);
237 UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS);
254 } else
255 UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW));
256 /* Set output flow control state. */
257 if (sc->sc_hwoflow)
258 UART_IOCTL(sc, UART_IOCTL_OFLOW, (t->c_cflag & CCTS_OFLOW));
238 } else
239 UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW));
240 /* Set output flow control state. */
241 if (sc->sc_hwoflow)
242 UART_IOCTL(sc, UART_IOCTL_OFLOW, (t->c_cflag & CCTS_OFLOW));
259
243 ttsetwater(tp);
260 return (0);
261}
262
244 return (0);
245}
246
263static int
264uart_tty_modem(struct tty *tp, int biton, int bitoff)
247static void
248uart_tty_stop(struct tty *tp, int rw)
265{
266 struct uart_softc *sc;
267
249{
250 struct uart_softc *sc;
251
268 sc = tty_softc(tp);
269 if (biton != 0 || bitoff != 0)
270 UART_SETSIG(sc, SER_DELTA(bitoff|biton) | biton);
271 return (sc->sc_hwsig);
252 KASSERT(tp->t_dev != NULL, ("foo"));
253 sc = tp->t_dev->si_drv1;
254 if (sc == NULL || sc->sc_leaving)
255 return;
256 if (rw & FWRITE) {
257 if (sc->sc_txbusy) {
258 sc->sc_txbusy = 0;
259 UART_FLUSH(sc, UART_FLUSH_TRANSMITTER);
260 }
261 tp->t_state &= ~TS_BUSY;
262 }
263 if (rw & FREAD) {
264 UART_FLUSH(sc, UART_FLUSH_RECEIVER);
265 sc->sc_rxget = sc->sc_rxput = 0;
266 }
272}
273
274void
275uart_tty_intr(void *arg)
276{
277 struct uart_softc *sc = arg;
278 struct tty *tp;
267}
268
269void
270uart_tty_intr(void *arg)
271{
272 struct uart_softc *sc = arg;
273 struct tty *tp;
279 int c, err = 0, pend, sig, xc;
274 int c, pend, sig, xc;
280
281 if (sc->sc_leaving)
282 return;
283
284 pend = atomic_readandclear_32(&sc->sc_ttypend);
275
276 if (sc->sc_leaving)
277 return;
278
279 pend = atomic_readandclear_32(&sc->sc_ttypend);
285 if (!(pend & SER_INT_MASK))
280 if (!(pend & UART_IPEND_MASK))
286 return;
287
288 tp = sc->sc_u.u_tty.tp;
281 return;
282
283 tp = sc->sc_u.u_tty.tp;
289 tty_lock(tp);
290
284
291 if (pend & SER_INT_RXREADY) {
292 while (!uart_rx_empty(sc) && !sc->sc_isquelch) {
293 xc = uart_rx_peek(sc);
285 if (pend & UART_IPEND_RXREADY) {
286 while (!uart_rx_empty(sc) && !(tp->t_state & TS_TBLOCK)) {
287 xc = uart_rx_get(sc);
294 c = xc & 0xff;
295 if (xc & UART_STAT_FRAMERR)
288 c = xc & 0xff;
289 if (xc & UART_STAT_FRAMERR)
296 err |= TRE_FRAMING;
297 if (xc & UART_STAT_OVERRUN)
298 err |= TRE_OVERRUN;
290 c |= TTY_FE;
299 if (xc & UART_STAT_PARERR)
291 if (xc & UART_STAT_PARERR)
300 err |= TRE_PARITY;
301 if (ttydisc_rint(tp, c, err) != 0) {
302 sc->sc_isquelch = 1;
303 if ((tp->t_termios.c_cflag & CRTS_IFLOW) &&
304 !sc->sc_hwiflow)
305 UART_SETSIG(sc, SER_DRTS);
306 } else
307 uart_rx_next(sc);
292 c |= TTY_PE;
293 (*linesw[tp->t_line].l_rint)(c, tp);
308 }
309 }
310
294 }
295 }
296
311 if (pend & SER_INT_BREAK)
312 ttydisc_rint(tp, 0, TRE_BREAK);
297 if (pend & UART_IPEND_BREAK) {
298 if (tp != NULL && !(tp->t_iflag & IGNBRK))
299 (*linesw[tp->t_line].l_rint)(0, tp);
300 }
313
301
314 if (pend & SER_INT_SIGCHG) {
315 sig = pend & SER_INT_SIGMASK;
316 if (sig & SER_DDCD)
317 ttydisc_modem(tp, sig & SER_DCD);
318 if ((sig & SER_DCTS) && (tp->t_termios.c_cflag & CCTS_OFLOW) &&
302 if (pend & UART_IPEND_SIGCHG) {
303 sig = pend & UART_IPEND_SIGMASK;
304 if (sig & UART_SIG_DDCD)
305 (*linesw[tp->t_line].l_modem)(tp, sig & UART_SIG_DCD);
306 if ((sig & UART_SIG_DCTS) && (tp->t_cflag & CCTS_OFLOW) &&
319 !sc->sc_hwoflow) {
307 !sc->sc_hwoflow) {
320 if (sig & SER_CTS)
321 uart_tty_outwakeup(tp);
308 if (sig & UART_SIG_CTS) {
309 tp->t_state &= ~TS_TTSTOP;
310 (*linesw[tp->t_line].l_start)(tp);
311 } else
312 tp->t_state |= TS_TTSTOP;
322 }
323 }
324
313 }
314 }
315
325 if (pend & SER_INT_TXIDLE)
326 uart_tty_outwakeup(tp);
327 ttydisc_rint_done(tp);
328 tty_unlock(tp);
316 if (pend & UART_IPEND_TXIDLE) {
317 tp->t_state &= ~TS_BUSY;
318 (*linesw[tp->t_line].l_start)(tp);
319 }
329}
330
320}
321
331static void
332uart_tty_free(void *arg)
322int
323uart_tty_attach(struct uart_softc *sc)
333{
324{
325 struct tty *tp;
334
326
335 /*
336 * XXX: uart(4) could reuse the device unit number before it is
337 * being freed by the TTY layer. We should use this hook to free
338 * the device unit number, but unfortunately newbus does not
339 * seem to support such a construct.
340 */
327 tp = ttymalloc(NULL);
328 sc->sc_u.u_tty.tp = tp;
329
330 sc->sc_u.u_tty.si[0] = make_dev(&uart_cdevsw,
331 device_get_unit(sc->sc_dev), UID_ROOT, GID_WHEEL, 0600, "ttyu%r",
332 device_get_unit(sc->sc_dev));
333 sc->sc_u.u_tty.si[0]->si_drv1 = sc;
334 sc->sc_u.u_tty.si[0]->si_tty = tp;
335 sc->sc_u.u_tty.si[1] = make_dev(&uart_cdevsw,
336 device_get_unit(sc->sc_dev) | UART_MINOR_CALLOUT, UID_UUCP,
337 GID_DIALER, 0660, "uart%r", device_get_unit(sc->sc_dev));
338 sc->sc_u.u_tty.si[1]->si_drv1 = sc;
339 sc->sc_u.u_tty.si[1]->si_tty = tp;
340
341 tp->t_oproc = uart_tty_oproc;
342 tp->t_param = uart_tty_param;
343 tp->t_stop = uart_tty_stop;
344
345 if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
346 ((struct consdev *)sc->sc_sysdev->cookie)->cn_dev =
347 makedev(uart_cdevsw.d_maj, device_get_unit(sc->sc_dev));
348 }
349
350 swi_add(&tty_ithd, uart_driver_name, uart_tty_intr, sc, SWI_TTY,
351 INTR_TYPE_TTY, &sc->sc_softih);
352
353 return (0);
341}
342
354}
355
343static struct ttydevsw uart_tty_class = {
344 .tsw_flags = TF_INITLOCK|TF_CALLOUT,
345 .tsw_open = uart_tty_open,
346 .tsw_close = uart_tty_close,
347 .tsw_outwakeup = uart_tty_outwakeup,
348 .tsw_inwakeup = uart_tty_inwakeup,
349 .tsw_ioctl = uart_tty_ioctl,
350 .tsw_param = uart_tty_param,
351 .tsw_modem = uart_tty_modem,
352 .tsw_free = uart_tty_free,
353};
356int uart_tty_detach(struct uart_softc *sc)
357{
354
358
355int
356uart_tty_attach(struct uart_softc *sc)
359 ithread_remove_handler(sc->sc_softih);
360 destroy_dev(sc->sc_u.u_tty.si[0]);
361 destroy_dev(sc->sc_u.u_tty.si[1]);
362 /* ttyfree(sc->sc_u.u_tty.tp); */
363
364 return (0);
365}
366
367static int
368uart_tty_open(dev_t dev, int flags, int mode, struct thread *td)
357{
369{
370 struct uart_softc *sc;
358 struct tty *tp;
371 struct tty *tp;
359 int unit;
372 int error;
360
373
361 sc->sc_u.u_tty.tp = tp = tty_alloc(&uart_tty_class, sc);
374 sc = dev->si_drv1;
375 if (sc == NULL || sc->sc_leaving)
376 return (ENODEV);
362
377
363 unit = device_get_unit(sc->sc_dev);
378 tp = dev->si_tty;
364
379
365 if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
366 sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name,
367 "ttyu%r", unit);
368 tty_init_console(tp, 0);
380 loop:
381 if (sc->sc_opened) {
382 KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
383 /*
384 * The device is open, so everything has been initialized.
385 * Handle conflicts.
386 */
387 if (minor(dev) & UART_MINOR_CALLOUT) {
388 if (!sc->sc_callout)
389 return (EBUSY);
390 } else {
391 if (sc->sc_callout) {
392 if (flags & O_NONBLOCK)
393 return (EBUSY);
394 error = tsleep(sc, TTIPRI|PCATCH, "uartbi", 0);
395 if (error)
396 return (error);
397 sc = dev->si_drv1;
398 if (sc == NULL || sc->sc_leaving)
399 return (ENODEV);
400 goto loop;
401 }
402 }
403 if (tp->t_state & TS_XCLUDE && suser(td) != 0)
404 return (EBUSY);
405 } else {
406 KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
407 /*
408 * The device isn't open, so there are no conflicts.
409 * Initialize it. Initialization is done twice in many
410 * cases: to preempt sleeping callin opens if we are
411 * callout, and to complete a callin open after DCD rises.
412 */
413 sc->sc_callout = (minor(dev) & UART_MINOR_CALLOUT) ? 1 : 0;
414 tp->t_dev = dev;
415
416 tp->t_cflag = TTYDEF_CFLAG;
417 tp->t_iflag = TTYDEF_IFLAG;
418 tp->t_lflag = TTYDEF_LFLAG;
419 tp->t_oflag = TTYDEF_OFLAG;
420 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
421 ttychars(tp);
422 error = uart_tty_param(tp, &tp->t_termios);
423 if (error)
424 return (error);
425 /*
426 * Handle initial DCD.
427 */
428 if ((sc->sc_hwsig & UART_SIG_DCD) || sc->sc_callout)
429 (*linesw[tp->t_line].l_modem)(tp, 1);
369 }
430 }
431 /*
432 * Wait for DCD if necessary.
433 */
434 if (!(tp->t_state & TS_CARR_ON) && !sc->sc_callout &&
435 !(tp->t_cflag & CLOCAL) && !(flags & O_NONBLOCK)) {
436 error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "uartdcd", 0);
437 if (error)
438 return (error);
439 sc = dev->si_drv1;
440 if (sc == NULL || sc->sc_leaving)
441 return (ENODEV);
442 goto loop;
443 }
444 error = ttyopen(dev, tp);
445 if (error)
446 return (error);
447 error = (*linesw[tp->t_line].l_open)(dev, tp);
448 if (error)
449 return (error);
370
450
371 swi_add(&tty_intr_event, uart_driver_name, uart_tty_intr, sc, SWI_TTY,
372 INTR_TYPE_TTY, &sc->sc_softih);
451 KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
452 sc->sc_opened = 1;
453 return (0);
454}
373
455
374 tty_makedev(tp, NULL, "u%r", unit);
456static int
457uart_tty_close(dev_t dev, int flags, int mode, struct thread *td)
458{
459 struct uart_softc *sc;
460 struct tty *tp;
375
461
462 sc = dev->si_drv1;
463 if (sc == NULL || sc->sc_leaving)
464 return (ENODEV);
465 tp = dev->si_tty;
466 if (!sc->sc_opened) {
467 KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
468 return (0);
469 }
470 KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
471
472 if (sc->sc_hwiflow)
473 UART_IOCTL(sc, UART_IOCTL_IFLOW, 0);
474 if (sc->sc_hwoflow)
475 UART_IOCTL(sc, UART_IOCTL_OFLOW, 0);
476 if (sc->sc_sysdev == NULL)
477 UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
478
479 (*linesw[tp->t_line].l_close)(tp, flags);
480 ttyclose(tp);
481 wakeup(sc);
482 wakeup(TSA_CARR_ON(tp));
483 KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
484 sc->sc_opened = 0;
376 return (0);
377}
378
485 return (0);
486}
487
379int
380uart_tty_detach(struct uart_softc *sc)
488static int
489uart_tty_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags,
490 struct thread *td)
381{
491{
492 struct uart_softc *sc;
382 struct tty *tp;
493 struct tty *tp;
494 int bits, error, sig;
383
495
384 tp = sc->sc_u.u_tty.tp;
496 sc = dev->si_drv1;
497 if (sc == NULL || sc->sc_leaving)
498 return (ENODEV);
385
499
386 tty_lock(tp);
387 swi_remove(sc->sc_softih);
388 tty_rel_gone(tp);
500 tp = dev->si_tty;
501 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, td);
502 if (error != ENOIOCTL)
503 return (error);
504 error = ttioctl(tp, cmd, data, flags);
505 if (error != ENOIOCTL)
506 return (error);
389
507
508 switch (cmd) {
509 case TIOCSBRK:
510 UART_IOCTL(sc, UART_IOCTL_BREAK, 1);
511 break;
512 case TIOCCBRK:
513 UART_IOCTL(sc, UART_IOCTL_BREAK, 0);
514 break;
515 case TIOCSDTR:
516 UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR);
517 break;
518 case TIOCCDTR:
519 UART_SETSIG(sc, UART_SIG_DDTR);
520 break;
521 case TIOCMSET:
522 bits = *(int*)data;
523 sig = UART_SIG_DDTR | UART_SIG_DRTS;
524 if (bits & TIOCM_DTR)
525 sig |= UART_SIG_DTR;
526 if (bits & TIOCM_RTS)
527 sig |= UART_SIG_RTS;
528 UART_SETSIG(sc, sig);
529 break;
530 case TIOCMBIS:
531 bits = *(int*)data;
532 sig = 0;
533 if (bits & TIOCM_DTR)
534 sig |= UART_SIG_DDTR | UART_SIG_DTR;
535 if (bits & TIOCM_RTS)
536 sig |= UART_SIG_DRTS | UART_SIG_RTS;
537 UART_SETSIG(sc, sig);
538 break;
539 case TIOCMBIC:
540 bits = *(int*)data;
541 sig = 0;
542 if (bits & TIOCM_DTR)
543 sig |= UART_SIG_DDTR;
544 if (bits & TIOCM_RTS)
545 sig |= UART_SIG_DRTS;
546 UART_SETSIG(sc, sig);
547 break;
548 case TIOCMGET:
549 sig = sc->sc_hwsig;
550 bits = TIOCM_LE;
551 if (sig & UART_SIG_DTR)
552 bits |= TIOCM_DTR;
553 if (sig & UART_SIG_RTS)
554 bits |= TIOCM_RTS;
555 if (sig & UART_SIG_DSR)
556 bits |= TIOCM_DSR;
557 if (sig & UART_SIG_CTS)
558 bits |= TIOCM_CTS;
559 if (sig & UART_SIG_DCD)
560 bits |= TIOCM_CD;
561 if (sig & (UART_SIG_DRI | UART_SIG_RI))
562 bits |= TIOCM_RI;
563 *(int*)data = bits;
564 break;
565 default:
566 return (ENOTTY);
567 }
390 return (0);
391}
568 return (0);
569}