xref: /netbsd-src/sys/dev/usb/ucom.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: ucom.c,v 1.120 2018/01/21 13:57:12 skrll Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Lennart Augustsson (lennart@augustsson.net) at
9  * Carlstedt Research & Technology.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  * This code is very heavily based on the 16550 driver, com.c.
34  */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.120 2018/01/21 13:57:12 skrll Exp $");
38 
39 #ifdef _KERNEL_OPT
40 #include "opt_usb.h"
41 #endif
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/ioctl.h>
47 #include <sys/conf.h>
48 #include <sys/tty.h>
49 #include <sys/file.h>
50 #include <sys/select.h>
51 #include <sys/proc.h>
52 #include <sys/vnode.h>
53 #include <sys/device.h>
54 #include <sys/poll.h>
55 #include <sys/queue.h>
56 #include <sys/kauth.h>
57 #include <sys/sysctl.h>
58 #include <sys/timepps.h>
59 #include <sys/rndsource.h>
60 
61 #include <dev/usb/usb.h>
62 
63 #include <dev/usb/usbdi.h>
64 #include <dev/usb/usbdi_util.h>
65 #include <dev/usb/usbdevs.h>
66 #include <dev/usb/usb_quirks.h>
67 #include <dev/usb/usbhist.h>
68 
69 #include <dev/usb/ucomvar.h>
70 
71 #include "ucom.h"
72 
73 #include "locators.h"
74 
75 #if NUCOM > 0
76 
77 #ifdef USB_DEBUG
78 #ifndef UCOM_DEBUG
79 #define ucomdebug 0
80 #else
81 int ucomdebug = 0;
82 
83 SYSCTL_SETUP(sysctl_hw_ucom_setup, "sysctl hw.ucom setup")
84 {
85 	int err;
86 	const struct sysctlnode *rnode;
87 	const struct sysctlnode *cnode;
88 
89 	err = sysctl_createv(clog, 0, NULL, &rnode,
90 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "ucom",
91 	    SYSCTL_DESCR("ucom global controls"),
92 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
93 
94 	if (err)
95 		goto fail;
96 
97 	/* control debugging printfs */
98 	err = sysctl_createv(clog, 0, &rnode, &cnode,
99 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
100 	    "debug", SYSCTL_DESCR("Enable debugging output"),
101 	    NULL, 0, &ucomdebug, sizeof(ucomdebug), CTL_CREATE, CTL_EOL);
102 	if (err)
103 		goto fail;
104 
105 	return;
106 fail:
107 	aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
108 }
109 
110 #endif /* UCOM_DEBUG */
111 #endif /* USB_DEBUG */
112 
113 #define DPRINTF(FMT,A,B,C,D)    USBHIST_LOGN(ucomdebug,1,FMT,A,B,C,D)
114 #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(ucomdebug,N,FMT,A,B,C,D)
115 #define UCOMHIST_FUNC()         USBHIST_FUNC()
116 #define UCOMHIST_CALLED(name)   USBHIST_CALLED(ucomdebug)
117 
118 #define	UCOMCALLUNIT_MASK	TTCALLUNIT_MASK
119 #define	UCOMUNIT_MASK		TTUNIT_MASK
120 #define	UCOMDIALOUT_MASK	TTDIALOUT_MASK
121 
122 #define	UCOMCALLUNIT(x)		TTCALLUNIT(x)
123 #define	UCOMUNIT(x)		TTUNIT(x)
124 #define	UCOMDIALOUT(x)		TTDIALOUT(x)
125 
126 /*
127  * XXX: We can submit multiple input/output buffers to the usb stack
128  * to improve throughput, but the usb stack is too lame to deal with this
129  * in a number of places.
130  */
131 #define	UCOM_IN_BUFFS	1
132 #define	UCOM_OUT_BUFFS	1
133 
134 struct ucom_buffer {
135 	SIMPLEQ_ENTRY(ucom_buffer) ub_link;
136 	struct usbd_xfer *ub_xfer;
137 	u_char *ub_data;
138 	u_int ub_len;
139 	u_int ub_index;
140 };
141 
142 struct ucom_softc {
143 	device_t		sc_dev;		/* base device */
144 
145 	struct usbd_device *	sc_udev;	/* USB device */
146 	struct usbd_interface *	sc_iface;	/* data interface */
147 
148 	int			sc_bulkin_no;	/* bulk in endpoint address */
149 	struct usbd_pipe *	sc_bulkin_pipe;/* bulk in pipe */
150 	u_int			sc_ibufsize;	/* read buffer size */
151 	u_int			sc_ibufsizepad;	/* read buffer size padded */
152 	struct ucom_buffer	sc_ibuff[UCOM_IN_BUFFS];
153 	SIMPLEQ_HEAD(, ucom_buffer) sc_ibuff_empty;
154 	SIMPLEQ_HEAD(, ucom_buffer) sc_ibuff_full;
155 
156 	int			sc_bulkout_no;	/* bulk out endpoint address */
157 	struct usbd_pipe *	sc_bulkout_pipe;/* bulk out pipe */
158 	u_int			sc_obufsize;	/* write buffer size */
159 	u_int			sc_opkthdrlen;	/* header length of */
160 	struct ucom_buffer	sc_obuff[UCOM_OUT_BUFFS];
161 	SIMPLEQ_HEAD(, ucom_buffer) sc_obuff_free;
162 	SIMPLEQ_HEAD(, ucom_buffer) sc_obuff_full;
163 
164 	void			*sc_si;
165 
166 	const struct ucom_methods *sc_methods;
167 	void                    *sc_parent;
168 	int			sc_portno;
169 
170 	struct tty		*sc_tty;	/* our tty */
171 	u_char			sc_lsr;
172 	u_char			sc_msr;
173 	u_char			sc_mcr;
174 	volatile u_char		sc_rx_stopped;
175 	u_char			sc_rx_unblock;
176 	u_char			sc_tx_stopped;
177 	int			sc_swflags;
178 
179 	enum ucom_state {
180 	    UCOM_DEAD,
181 	    UCOM_ATTACHED,
182 	    UCOM_OPENING,
183 	    UCOM_CLOSING,
184 	    UCOM_OPEN
185 	}			sc_state;
186 	int			sc_refcnt;
187 	bool			sc_dying;	/* disconnecting */
188 
189 	struct pps_state	sc_pps_state;	/* pps state */
190 
191 	krndsource_t		sc_rndsource;	/* random source */
192 
193 	kmutex_t		sc_lock;
194 	kcondvar_t		sc_statecv;
195 	kcondvar_t		sc_detachcv;
196 };
197 
198 dev_type_open(ucomopen);
199 dev_type_close(ucomclose);
200 dev_type_read(ucomread);
201 dev_type_write(ucomwrite);
202 dev_type_ioctl(ucomioctl);
203 dev_type_stop(ucomstop);
204 dev_type_tty(ucomtty);
205 dev_type_poll(ucompoll);
206 
207 const struct cdevsw ucom_cdevsw = {
208 	.d_open = ucomopen,
209 	.d_close = ucomclose,
210 	.d_read = ucomread,
211 	.d_write = ucomwrite,
212 	.d_ioctl = ucomioctl,
213 	.d_stop = ucomstop,
214 	.d_tty = ucomtty,
215 	.d_poll = ucompoll,
216 	.d_mmap = nommap,
217 	.d_kqfilter = ttykqfilter,
218 	.d_discard = nodiscard,
219 	.d_flag = D_TTY | D_MPSAFE
220 };
221 
222 static void	ucom_cleanup(struct ucom_softc *);
223 static int	ucomparam(struct tty *, struct termios *);
224 static int	ucomhwiflow(struct tty *, int);
225 static void	ucomstart(struct tty *);
226 static void	ucom_shutdown(struct ucom_softc *);
227 static int	ucom_do_ioctl(struct ucom_softc *, u_long, void *,
228 			      int, struct lwp *);
229 static void	ucom_dtr(struct ucom_softc *, int);
230 static void	ucom_rts(struct ucom_softc *, int);
231 static void	ucom_break(struct ucom_softc *, int);
232 static void	tiocm_to_ucom(struct ucom_softc *, u_long, int);
233 static int	ucom_to_tiocm(struct ucom_softc *);
234 
235 static void	ucomreadcb(struct usbd_xfer *, void *, usbd_status);
236 static void	ucom_submit_write(struct ucom_softc *, struct ucom_buffer *);
237 static void	ucom_write_status(struct ucom_softc *, struct ucom_buffer *,
238 		    usbd_status);
239 
240 static void	ucomwritecb(struct usbd_xfer *, void *, usbd_status);
241 static void	ucom_read_complete(struct ucom_softc *);
242 static int	ucomsubmitread(struct ucom_softc *, struct ucom_buffer *);
243 static void	ucom_softintr(void *);
244 
245 int ucom_match(device_t, cfdata_t, void *);
246 void ucom_attach(device_t, device_t, void *);
247 int ucom_detach(device_t, int);
248 int ucom_activate(device_t, enum devact);
249 extern struct cfdriver ucom_cd;
250 CFATTACH_DECL_NEW(ucom, sizeof(struct ucom_softc), ucom_match, ucom_attach,
251     ucom_detach, ucom_activate);
252 
253 int
254 ucom_match(device_t parent, cfdata_t match, void *aux)
255 {
256 	return 1;
257 }
258 
259 void
260 ucom_attach(device_t parent, device_t self, void *aux)
261 {
262 	struct ucom_softc *sc = device_private(self);
263 	struct ucom_attach_args *ucaa = aux;
264 
265 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
266 
267 	if (ucaa->ucaa_info != NULL)
268 		aprint_normal(": %s", ucaa->ucaa_info);
269 	aprint_normal("\n");
270 
271 	prop_dictionary_set_int32(device_properties(self), "port",
272 	    ucaa->ucaa_portno);
273 
274 	sc->sc_dev = self;
275 	sc->sc_udev = ucaa->ucaa_device;
276 	sc->sc_iface = ucaa->ucaa_iface;
277 	sc->sc_bulkout_no = ucaa->ucaa_bulkout;
278 	sc->sc_bulkin_no = ucaa->ucaa_bulkin;
279 	sc->sc_ibufsize = ucaa->ucaa_ibufsize;
280 	sc->sc_ibufsizepad = ucaa->ucaa_ibufsizepad;
281 	sc->sc_obufsize = ucaa->ucaa_obufsize;
282 	sc->sc_opkthdrlen = ucaa->ucaa_opkthdrlen;
283 	sc->sc_methods = ucaa->ucaa_methods;
284 	sc->sc_parent = ucaa->ucaa_arg;
285 	sc->sc_portno = ucaa->ucaa_portno;
286 
287 	sc->sc_lsr = 0;
288 	sc->sc_msr = 0;
289 	sc->sc_mcr = 0;
290 	sc->sc_tx_stopped = 0;
291 	sc->sc_swflags = 0;
292 	sc->sc_refcnt = 0;
293 	sc->sc_dying = false;
294 	sc->sc_state = UCOM_DEAD;
295 
296 	sc->sc_si = softint_establish(SOFTINT_USB, ucom_softintr, sc);
297 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
298 	cv_init(&sc->sc_statecv, "ucomstate");
299 	cv_init(&sc->sc_detachcv, "ucomdtch");
300 
301 	SIMPLEQ_INIT(&sc->sc_ibuff_empty);
302 	SIMPLEQ_INIT(&sc->sc_ibuff_full);
303 	SIMPLEQ_INIT(&sc->sc_obuff_free);
304 	SIMPLEQ_INIT(&sc->sc_obuff_full);
305 
306 	memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff));
307 	memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff));
308 
309 	DPRINTF("open pipes in=%jd out=%jd",
310 	    sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0);
311 
312 	struct ucom_buffer *ub;
313 	usbd_status err;
314 	int error;
315 
316 	/* Open the bulk pipes */
317 	err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no,
318 	    USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
319 	if (err) {
320 		DPRINTF("open bulk in error (addr %jd), err=%jd",
321 		    sc->sc_bulkin_no, err, 0, 0);
322 		error = EIO;
323 		goto fail_0;
324 	}
325 	/* Allocate input buffers */
326 	for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
327 	    ub++) {
328 		error = usbd_create_xfer(sc->sc_bulkin_pipe,
329 		    sc->sc_ibufsizepad, 0, 0,
330 		    &ub->ub_xfer);
331 		if (error)
332 			goto fail_1;
333 		ub->ub_data = usbd_get_buffer(ub->ub_xfer);
334 	}
335 
336 	err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
337 	    USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
338 	if (err) {
339 		DPRINTF("open bulk out error (addr %jd), err=%jd",
340 		    sc->sc_bulkout_no, err, 0, 0);
341 		error = EIO;
342 		goto fail_1;
343 	}
344 	for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
345 	    ub++) {
346 		error = usbd_create_xfer(sc->sc_bulkout_pipe,
347 		    sc->sc_obufsize, 0, 0, &ub->ub_xfer);
348 		if (error)
349 			goto fail_2;
350 		ub->ub_data = usbd_get_buffer(ub->ub_xfer);
351 		SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link);
352 	}
353 
354 	struct tty *tp = tty_alloc();
355 	tp->t_oproc = ucomstart;
356 	tp->t_param = ucomparam;
357 	tp->t_hwiflow = ucomhwiflow;
358 	sc->sc_tty = tp;
359 
360 	DPRINTF("tty_attach %#jx", (uintptr_t)tp, 0, 0, 0);
361 	tty_attach(tp);
362 
363 	rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
364 			  RND_TYPE_TTY, RND_FLAG_DEFAULT);
365 
366 	if (!pmf_device_register(self, NULL, NULL))
367 		aprint_error_dev(self, "couldn't establish power handler\n");
368 
369 	sc->sc_state = UCOM_ATTACHED;
370 
371 	return;
372 
373 fail_2:
374 	for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS];
375 	    ub++) {
376 		if (ub->ub_xfer)
377 			usbd_destroy_xfer(ub->ub_xfer);
378 	}
379 
380 	usbd_close_pipe(sc->sc_bulkout_pipe);
381 
382 fail_1:
383 	for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS];
384 	    ub++) {
385 		if (ub->ub_xfer)
386 			usbd_destroy_xfer(ub->ub_xfer);
387 	}
388 	usbd_close_pipe(sc->sc_bulkin_pipe);
389 
390 fail_0:
391 	aprint_error_dev(self, "attach failed, error=%d\n", error);
392 
393 	return;
394 }
395 
396 int
397 ucom_detach(device_t self, int flags)
398 {
399 	struct ucom_softc *sc = device_private(self);
400 	struct tty *tp = sc->sc_tty;
401 	int maj, mn;
402 	int i;
403 
404 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
405 
406 	DPRINTF("sc=%#jx flags=%jd tp=%#jx", (uintptr_t)sc, flags,
407 	    (uintptr_t)tp, 0);
408 	DPRINTF("... pipe=%jd,%jd", sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0);
409 
410 	mutex_enter(&sc->sc_lock);
411 	sc->sc_dying = true;
412 	mutex_exit(&sc->sc_lock);
413 
414 	pmf_device_deregister(self);
415 
416 	if (sc->sc_bulkin_pipe != NULL)
417 		usbd_abort_pipe(sc->sc_bulkin_pipe);
418 	if (sc->sc_bulkout_pipe != NULL)
419 		usbd_abort_pipe(sc->sc_bulkout_pipe);
420 
421 	mutex_enter(&sc->sc_lock);
422 
423 	/* wait for open/close to finish */
424 	while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) {
425 		int error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock);
426 
427 		if (error) {
428 			mutex_exit(&sc->sc_lock);
429 			return error;
430 		}
431 	}
432 
433 	sc->sc_refcnt--;
434 	while (sc->sc_refcnt > 0) {
435 		/* Wake up anyone waiting */
436 		if (tp != NULL) {
437 			mutex_spin_enter(&tty_lock);
438 			CLR(tp->t_state, TS_CARR_ON);
439 			CLR(tp->t_cflag, CLOCAL | MDMBUF);
440 			ttyflush(tp, FREAD|FWRITE);
441 			mutex_spin_exit(&tty_lock);
442 		}
443 		/* Wait for processes to go away. */
444 		if (cv_timedwait(&sc->sc_detachcv, &sc->sc_lock, hz * 60)) {
445 			printf("%s: %s didn't detach\n", __func__,
446 			    device_xname(sc->sc_dev));
447 		}
448 	}
449 
450 	softint_disestablish(sc->sc_si);
451 	mutex_exit(&sc->sc_lock);
452 
453 	/* locate the major number */
454 	maj = cdevsw_lookup_major(&ucom_cdevsw);
455 
456 	/* Nuke the vnodes for any open instances. */
457 	mn = device_unit(self);
458 	DPRINTF("maj=%jd mn=%jd", maj, mn, 0, 0);
459 	vdevgone(maj, mn, mn, VCHR);
460 	vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR);
461 	vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR);
462 
463 	/* Detach and free the tty. */
464 	if (tp != NULL) {
465 		tty_detach(tp);
466 		tty_free(tp);
467 		sc->sc_tty = NULL;
468 	}
469 
470 	for (i = 0; i < UCOM_IN_BUFFS; i++) {
471 		if (sc->sc_ibuff[i].ub_xfer != NULL)
472 			usbd_destroy_xfer(sc->sc_ibuff[i].ub_xfer);
473 	}
474 
475 	for (i = 0; i < UCOM_OUT_BUFFS; i++) {
476 		if (sc->sc_obuff[i].ub_xfer != NULL)
477 			usbd_destroy_xfer(sc->sc_obuff[i].ub_xfer);
478 	}
479 
480 	if (sc->sc_bulkin_pipe != NULL) {
481 		usbd_close_pipe(sc->sc_bulkin_pipe);
482 		sc->sc_bulkin_pipe = NULL;
483 	}
484 
485 	if (sc->sc_bulkout_pipe != NULL) {
486 		usbd_close_pipe(sc->sc_bulkout_pipe);
487 		sc->sc_bulkout_pipe = NULL;
488 	}
489 
490 	/* Detach the random source */
491 	rnd_detach_source(&sc->sc_rndsource);
492 
493 	mutex_destroy(&sc->sc_lock);
494 	cv_destroy(&sc->sc_statecv);
495 	cv_destroy(&sc->sc_detachcv);
496 
497 	return 0;
498 }
499 
500 int
501 ucom_activate(device_t self, enum devact act)
502 {
503 	struct ucom_softc *sc = device_private(self);
504 
505 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
506 
507 	DPRINTFN(5, "%jd", act, 0, 0, 0);
508 
509 	switch (act) {
510 	case DVACT_DEACTIVATE:
511 		mutex_enter(&sc->sc_lock);
512 		sc->sc_dying = true;
513 		mutex_exit(&sc->sc_lock);
514 		return 0;
515 	default:
516 		return EOPNOTSUPP;
517 	}
518 }
519 
520 void
521 ucom_shutdown(struct ucom_softc *sc)
522 {
523 	struct tty *tp = sc->sc_tty;
524 
525 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
526 
527 	/*
528 	 * Hang up if necessary.  Wait a bit, so the other side has time to
529 	 * notice even if we immediately open the port again.
530 	 */
531 	if (ISSET(tp->t_cflag, HUPCL)) {
532 		ucom_dtr(sc, 0);
533 		/* XXX will only timeout */
534 		(void) kpause(ttclos, false, hz, NULL);
535 	}
536 }
537 
538 int
539 ucomopen(dev_t dev, int flag, int mode, struct lwp *l)
540 {
541 	const int unit = UCOMUNIT(dev);
542 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
543 	int error = 0;
544 
545 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
546 
547 	if (sc == NULL)
548 		return ENXIO;
549 
550 	mutex_enter(&sc->sc_lock);
551 	if (sc->sc_dying) {
552 		DPRINTF("... dying", 0, 0, 0, 0);
553 		mutex_exit(&sc->sc_lock);
554 		return EIO;
555 	}
556 
557 	if (!device_is_active(sc->sc_dev)) {
558 		mutex_exit(&sc->sc_lock);
559 		return ENXIO;
560 	}
561 
562 	struct tty *tp = sc->sc_tty;
563 
564 	DPRINTF("unit=%jd, tp=%#jx", unit, (uintptr_t)tp, 0, 0);
565 
566 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) {
567 		mutex_exit(&sc->sc_lock);
568 		return EBUSY;
569 	}
570 
571 	/*
572 	 * Wait while the device is initialized by the
573 	 * first opener or cleaned up by the last closer.
574 	 */
575 	while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) {
576 		error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock);
577 
578 		if (sc->sc_dying)
579 			error = EIO;
580 
581 		if (error) {
582 			mutex_exit(&sc->sc_lock);
583 			return error;
584 		}
585 	}
586 	enum ucom_state state = sc->sc_state;
587 
588 	KASSERTMSG(state == UCOM_OPEN || state == UCOM_ATTACHED,
589 	    "state is %d", state);
590 
591 	bool cleanup = false;
592 	/* If this is the first open then perform the initialisation */
593 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
594 		KASSERT(state == UCOM_ATTACHED);
595 		tp->t_dev = dev;
596 		cleanup = true;
597 		sc->sc_state = UCOM_OPENING;
598 
599 		mutex_exit(&sc->sc_lock);
600 		if (sc->sc_methods->ucom_open != NULL) {
601 			error = sc->sc_methods->ucom_open(sc->sc_parent,
602 			    sc->sc_portno);
603 			if (error) {
604 				goto fail_2;
605 			}
606 		}
607 
608 		ucom_status_change(sc);
609 
610 		/* Clear PPS capture state on first open. */
611 		mutex_spin_enter(&timecounter_lock);
612 		memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state));
613 		sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
614 		pps_init(&sc->sc_pps_state);
615 		mutex_spin_exit(&timecounter_lock);
616 
617 		/*
618 		 * Initialize the termios status to the defaults.  Add in the
619 		 * sticky bits from TIOCSFLAGS.
620 		 */
621 		struct termios t;
622 
623 		t.c_ispeed = 0;
624 		t.c_ospeed = TTYDEF_SPEED;
625 		t.c_cflag = TTYDEF_CFLAG;
626 		if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
627 			SET(t.c_cflag, CLOCAL);
628 		if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
629 			SET(t.c_cflag, CRTSCTS);
630 		if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
631 			SET(t.c_cflag, MDMBUF);
632 		/* Make sure ucomparam() will do something. */
633 		tp->t_ospeed = 0;
634 		(void) ucomparam(tp, &t);
635 		tp->t_iflag = TTYDEF_IFLAG;
636 		tp->t_oflag = TTYDEF_OFLAG;
637 		tp->t_lflag = TTYDEF_LFLAG;
638 		ttychars(tp);
639 		ttsetwater(tp);
640 
641 		/*
642 		 * Turn on DTR.  We must always do this, even if carrier is not
643 		 * present, because otherwise we'd have to use TIOCSDTR
644 		 * immediately after setting CLOCAL, which applications do not
645 		 * expect.  We always assert DTR while the device is open
646 		 * unless explicitly requested to deassert it.  Ditto RTS.
647 		 */
648 		ucom_dtr(sc, 1);
649 		ucom_rts(sc, 1);
650 
651 		mutex_enter(&sc->sc_lock);
652 		if (sc->sc_dying) {
653 			DPRINTF("... dying", 0, 0, 0, 0);
654 			error = EIO;
655 			goto fail_1;
656 		}
657 
658 		sc->sc_rx_unblock = 0;
659 		sc->sc_rx_stopped = 0;
660 		sc->sc_tx_stopped = 0;
661 
662 		for (size_t i = 0; i < UCOM_IN_BUFFS; i++) {
663 			struct ucom_buffer *ub = &sc->sc_ibuff[i];
664 			error = ucomsubmitread(sc, ub);
665 			if (error) {
666 		    		mutex_exit(&sc->sc_lock);
667 				goto fail_2;
668 			}
669 		}
670 	}
671 	sc->sc_state = UCOM_OPEN;
672 	cv_signal(&sc->sc_statecv);
673 	mutex_exit(&sc->sc_lock);
674 
675 	DPRINTF("unit=%jd, tp=%#jx dialout %jd nonblock %jd", unit,
676 	    (uintptr_t)tp, !!UCOMDIALOUT(dev), !!ISSET(flag, O_NONBLOCK));
677 	error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
678 	if (error)
679 		goto bad;
680 
681 	error = (*tp->t_linesw->l_open)(dev, tp);
682 	if (error)
683 		goto bad;
684 
685 	return 0;
686 
687 bad:
688 	cleanup = !ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0;
689 
690 fail_2:
691 	if (cleanup) {
692 		/*
693 		 * We failed to open the device, and nobody else had
694 		 * it opened.  Clean up the state as appropriate.
695 		 */
696 		ucom_cleanup(sc);
697 	}
698 
699 	mutex_enter(&sc->sc_lock);
700 
701 fail_1:
702 	sc->sc_state = state;
703 	cv_signal(&sc->sc_statecv);
704 	mutex_exit(&sc->sc_lock);
705 
706 	return error;
707 }
708 
709 int
710 ucomclose(dev_t dev, int flag, int mode, struct lwp *l)
711 {
712 	const int unit = UCOMUNIT(dev);
713 	struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit);
714 	int error = 0;
715 
716 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
717 
718 	DPRINTF("unit=%jd", UCOMUNIT(dev), 0, 0, 0);
719 
720 	if (sc == NULL)
721 		return 0;
722 
723 	mutex_enter(&sc->sc_lock);
724 	if (sc->sc_dying) {
725 		DPRINTF("... dying", 0, 0, 0, 0);
726 		mutex_exit(&sc->sc_lock);
727 		return ENXIO;
728 	}
729 
730 	/*
731 	 * Wait until any opens/closes have finished
732 	 */
733 	while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) {
734 		error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock);
735 
736 		if (sc->sc_dying)
737 			error = EIO;
738 
739 		if (error) {
740 			mutex_exit(&sc->sc_lock);
741 			return error;
742 		}
743 	}
744 
745 	struct tty *tp = sc->sc_tty;
746 
747 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
748 		KASSERT(sc->sc_state == UCOM_ATTACHED);
749 		mutex_exit(&sc->sc_lock);
750 		return 0;
751 	}
752 
753 	KASSERT(sc->sc_state == UCOM_OPEN);
754 	sc->sc_state = UCOM_CLOSING;
755 	mutex_exit(&sc->sc_lock);
756 
757 	(*tp->t_linesw->l_close)(tp, flag);
758 	ttyclose(tp);
759 
760 	/* state when we're done - default to open */
761 	enum ucom_state state = UCOM_OPEN;
762 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
763 		/*
764 		 * Although we got a last close, the device may still be in
765 		 * use; e.g. if this was the dialout node, and there are still
766 		 * processes waiting for carrier on the non-dialout node.
767 		 */
768 		ucom_cleanup(sc);
769 		if (sc->sc_methods->ucom_close != NULL)
770 			sc->sc_methods->ucom_close(sc->sc_parent,
771 			    sc->sc_portno);
772 		state = UCOM_ATTACHED;
773 	}
774 
775 	mutex_enter(&sc->sc_lock);
776 	sc->sc_state = state;
777 	cv_signal(&sc->sc_statecv);
778 	mutex_exit(&sc->sc_lock);
779 
780 	return error;
781 }
782 
783 int
784 ucomread(dev_t dev, struct uio *uio, int flag)
785 {
786 	const int unit = UCOMUNIT(dev);
787 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
788 	int error;
789 
790 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
791 
792 	if (sc == NULL)
793 		return EIO;
794 
795 	mutex_enter(&sc->sc_lock);
796 	if (sc->sc_dying) {
797 		DPRINTF("... dying", 0, 0, 0, 0);
798 		mutex_exit(&sc->sc_lock);
799 		return EIO;
800 	}
801 
802 	struct tty *tp = sc->sc_tty;
803 
804 	sc->sc_refcnt++;
805 	mutex_exit(&sc->sc_lock);
806 
807 	error = ((*tp->t_linesw->l_read)(tp, uio, flag));
808 
809 	mutex_enter(&sc->sc_lock);
810 	if (--sc->sc_refcnt < 0)
811 		cv_broadcast(&sc->sc_detachcv);
812 	DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(dev), sc->sc_refcnt, 0, 0);
813 	mutex_exit(&sc->sc_lock);
814 
815 	return error;
816 }
817 
818 int
819 ucomwrite(dev_t dev, struct uio *uio, int flag)
820 {
821 	const int unit = UCOMUNIT(dev);
822 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
823 	int error;
824 
825 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
826 
827 	if (sc == NULL)
828 		return EIO;
829 
830 	mutex_enter(&sc->sc_lock);
831 	if (sc->sc_dying) {
832 		DPRINTF("... dying", 0, 0, 0, 0);
833 		mutex_exit(&sc->sc_lock);
834 		return EIO;
835 	}
836 
837 	struct tty *tp = sc->sc_tty;
838 
839 	sc->sc_refcnt++;
840 	mutex_exit(&sc->sc_lock);
841 
842 	error = ((*tp->t_linesw->l_write)(tp, uio, flag));
843 
844 	mutex_enter(&sc->sc_lock);
845 	if (--sc->sc_refcnt < 0)
846 		cv_broadcast(&sc->sc_detachcv);
847 	DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(dev), sc->sc_refcnt, 0, 0);
848 	mutex_exit(&sc->sc_lock);
849 
850 	return error;
851 }
852 
853 int
854 ucompoll(dev_t dev, int events, struct lwp *l)
855 {
856 	const int unit = UCOMUNIT(dev);
857 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
858 
859 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
860 
861 	if (sc == NULL)
862 		return POLLHUP;
863 
864 	mutex_enter(&sc->sc_lock);
865 	if (sc->sc_dying) {
866 		DPRINTF("... dying", 0, 0, 0, 0);
867 		mutex_exit(&sc->sc_lock);
868 		return POLLHUP;
869 	}
870 	struct tty *tp = sc->sc_tty;
871 
872 	sc->sc_refcnt++;
873 	mutex_exit(&sc->sc_lock);
874 
875 	int revents = ((*tp->t_linesw->l_poll)(tp, events, l));
876 
877 	mutex_enter(&sc->sc_lock);
878 	if (--sc->sc_refcnt < 0)
879 		cv_broadcast(&sc->sc_detachcv);
880 	DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(dev), sc->sc_refcnt, 0, 0);
881 	mutex_exit(&sc->sc_lock);
882 
883 	return revents;
884 }
885 
886 struct tty *
887 ucomtty(dev_t dev)
888 {
889 	const int unit = UCOMUNIT(dev);
890 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
891 
892 	return sc != NULL ? sc->sc_tty : NULL;
893 }
894 
895 int
896 ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
897 {
898 	const int unit = UCOMUNIT(dev);
899 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
900 	int error;
901 
902 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
903 
904 	if (sc == NULL)
905 		return EIO;
906 
907 	mutex_enter(&sc->sc_lock);
908 	if (sc->sc_dying) {
909 		DPRINTF("... dying", 0, 0, 0, 0);
910 		mutex_exit(&sc->sc_lock);
911 		return EIO;
912 	}
913 
914 	sc->sc_refcnt++;
915 	mutex_exit(&sc->sc_lock);
916 
917 	error = ucom_do_ioctl(sc, cmd, data, flag, l);
918 
919 	mutex_enter(&sc->sc_lock);
920 	if (--sc->sc_refcnt < 0)
921 		cv_broadcast(&sc->sc_detachcv);
922 	DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(dev), sc->sc_refcnt, 0, 0);
923 	mutex_exit(&sc->sc_lock);
924 
925 	return error;
926 }
927 
928 static int
929 ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, int flag,
930     struct lwp *l)
931 {
932 	struct tty *tp = sc->sc_tty;
933 	int error;
934 
935 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
936 
937 	DPRINTF("cmd=0x%08jx", cmd, 0, 0, 0);
938 
939 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
940 	if (error != EPASSTHROUGH)
941 		return error;
942 
943 	error = ttioctl(tp, cmd, data, flag, l);
944 	if (error != EPASSTHROUGH)
945 		return error;
946 
947 	if (sc->sc_methods->ucom_ioctl != NULL) {
948 		error = sc->sc_methods->ucom_ioctl(sc->sc_parent,
949 		    sc->sc_portno, cmd, data, flag, l->l_proc);
950 		if (error != EPASSTHROUGH)
951 			return error;
952 	}
953 
954 	error = 0;
955 
956 	DPRINTF("our cmd=0x%08jx", cmd, 0, 0, 0);
957 
958 	switch (cmd) {
959 	case TIOCSBRK:
960 		ucom_break(sc, 1);
961 		break;
962 
963 	case TIOCCBRK:
964 		ucom_break(sc, 0);
965 		break;
966 
967 	case TIOCSDTR:
968 		ucom_dtr(sc, 1);
969 		break;
970 
971 	case TIOCCDTR:
972 		ucom_dtr(sc, 0);
973 		break;
974 
975 	case TIOCGFLAGS:
976 		mutex_enter(&sc->sc_lock);
977 		*(int *)data = sc->sc_swflags;
978 		mutex_exit(&sc->sc_lock);
979 		break;
980 
981 	case TIOCSFLAGS:
982 		error = kauth_authorize_device_tty(l->l_cred,
983 		    KAUTH_DEVICE_TTY_PRIVSET, tp);
984 		if (error)
985 			break;
986 		mutex_enter(&sc->sc_lock);
987 		sc->sc_swflags = *(int *)data;
988 		mutex_exit(&sc->sc_lock);
989 		break;
990 
991 	case TIOCMSET:
992 	case TIOCMBIS:
993 	case TIOCMBIC:
994 		tiocm_to_ucom(sc, cmd, *(int *)data);
995 		break;
996 
997 	case TIOCMGET:
998 		*(int *)data = ucom_to_tiocm(sc);
999 		break;
1000 
1001 	case PPS_IOC_CREATE:
1002 	case PPS_IOC_DESTROY:
1003 	case PPS_IOC_GETPARAMS:
1004 	case PPS_IOC_SETPARAMS:
1005 	case PPS_IOC_GETCAP:
1006 	case PPS_IOC_FETCH:
1007 #ifdef PPS_SYNC
1008 	case PPS_IOC_KCBIND:
1009 #endif
1010 		mutex_spin_enter(&timecounter_lock);
1011 		error = pps_ioctl(cmd, data, &sc->sc_pps_state);
1012 		mutex_spin_exit(&timecounter_lock);
1013 		break;
1014 
1015 	default:
1016 		error = EPASSTHROUGH;
1017 		break;
1018 	}
1019 
1020 	return error;
1021 }
1022 
1023 static void
1024 tiocm_to_ucom(struct ucom_softc *sc, u_long how, int ttybits)
1025 {
1026 	u_char combits;
1027 
1028 	combits = 0;
1029 	if (ISSET(ttybits, TIOCM_DTR))
1030 		SET(combits, UMCR_DTR);
1031 	if (ISSET(ttybits, TIOCM_RTS))
1032 		SET(combits, UMCR_RTS);
1033 
1034 	mutex_enter(&sc->sc_lock);
1035 	switch (how) {
1036 	case TIOCMBIC:
1037 		CLR(sc->sc_mcr, combits);
1038 		break;
1039 
1040 	case TIOCMBIS:
1041 		SET(sc->sc_mcr, combits);
1042 		break;
1043 
1044 	case TIOCMSET:
1045 		CLR(sc->sc_mcr, UMCR_DTR | UMCR_RTS);
1046 		SET(sc->sc_mcr, combits);
1047 		break;
1048 	}
1049 	u_char mcr = sc->sc_mcr;
1050 	mutex_exit(&sc->sc_lock);
1051 
1052 	if (how == TIOCMSET || ISSET(combits, UMCR_DTR))
1053 		ucom_dtr(sc, (mcr & UMCR_DTR) != 0);
1054 	if (how == TIOCMSET || ISSET(combits, UMCR_RTS))
1055 		ucom_rts(sc, (mcr & UMCR_RTS) != 0);
1056 }
1057 
1058 static int
1059 ucom_to_tiocm(struct ucom_softc *sc)
1060 {
1061 	u_char combits;
1062 	int ttybits = 0;
1063 
1064 	mutex_enter(&sc->sc_lock);
1065 	combits = sc->sc_mcr;
1066 	if (ISSET(combits, UMCR_DTR))
1067 		SET(ttybits, TIOCM_DTR);
1068 	if (ISSET(combits, UMCR_RTS))
1069 		SET(ttybits, TIOCM_RTS);
1070 
1071 	combits = sc->sc_msr;
1072 	if (ISSET(combits, UMSR_DCD))
1073 		SET(ttybits, TIOCM_CD);
1074 	if (ISSET(combits, UMSR_CTS))
1075 		SET(ttybits, TIOCM_CTS);
1076 	if (ISSET(combits, UMSR_DSR))
1077 		SET(ttybits, TIOCM_DSR);
1078 	if (ISSET(combits, UMSR_RI | UMSR_TERI))
1079 		SET(ttybits, TIOCM_RI);
1080 
1081 #if 0
1082 XXX;
1083 	if (sc->sc_ier != 0)
1084 		SET(ttybits, TIOCM_LE);
1085 #endif
1086 	mutex_exit(&sc->sc_lock);
1087 
1088 	return ttybits;
1089 }
1090 
1091 static void
1092 ucom_break(struct ucom_softc *sc, int onoff)
1093 {
1094 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1095 
1096 	DPRINTF("onoff=%jd", onoff, 0, 0, 0);
1097 
1098 	if (sc->sc_methods->ucom_set != NULL)
1099 		sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno,
1100 		    UCOM_SET_BREAK, onoff);
1101 }
1102 
1103 static void
1104 ucom_dtr(struct ucom_softc *sc, int onoff)
1105 {
1106 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1107 
1108 	DPRINTF("onoff=%jd", onoff, 0, 0, 0);
1109 
1110 	if (sc->sc_methods->ucom_set != NULL)
1111 		sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno,
1112 		    UCOM_SET_DTR, onoff);
1113 }
1114 
1115 static void
1116 ucom_rts(struct ucom_softc *sc, int onoff)
1117 {
1118 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1119 
1120 	DPRINTF("onoff=%jd", onoff, 0, 0, 0);
1121 
1122 	if (sc->sc_methods->ucom_set != NULL)
1123 		sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno,
1124 		    UCOM_SET_RTS, onoff);
1125 }
1126 
1127 void
1128 ucom_status_change(struct ucom_softc *sc)
1129 {
1130 	struct tty *tp = sc->sc_tty;
1131 
1132 	if (sc->sc_methods->ucom_get_status != NULL) {
1133 		u_char msr, lsr;
1134 
1135 		sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno,
1136 		    &lsr, &msr);
1137 		mutex_enter(&sc->sc_lock);
1138 		u_char old_msr = sc->sc_msr;
1139 
1140 		sc->sc_lsr = lsr;
1141 		sc->sc_msr = msr;
1142 		mutex_exit(&sc->sc_lock);
1143 
1144 		if (ISSET((msr ^ old_msr), UMSR_DCD)) {
1145 			mutex_spin_enter(&timecounter_lock);
1146 			pps_capture(&sc->sc_pps_state);
1147 			pps_event(&sc->sc_pps_state,
1148 			    (sc->sc_msr & UMSR_DCD) ?
1149 			    PPS_CAPTUREASSERT :
1150 			    PPS_CAPTURECLEAR);
1151 			mutex_spin_exit(&timecounter_lock);
1152 
1153 			(*tp->t_linesw->l_modem)(tp, ISSET(msr, UMSR_DCD));
1154 		}
1155 	} else {
1156 		mutex_enter(&sc->sc_lock);
1157 		sc->sc_lsr = 0;
1158 		/* Assume DCD is present, if we have no chance to check it. */
1159 		sc->sc_msr = UMSR_DCD;
1160 		mutex_exit(&sc->sc_lock);
1161 	}
1162 }
1163 
1164 static int
1165 ucomparam(struct tty *tp, struct termios *t)
1166 {
1167 	const int unit = UCOMUNIT(tp->t_dev);
1168 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
1169 	int error = 0;
1170 
1171 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1172 
1173 	if (sc == NULL)
1174 		return EIO;
1175 
1176 	mutex_enter(&sc->sc_lock);
1177 	if (sc->sc_dying) {
1178 		DPRINTF("... dying", 0, 0, 0, 0);
1179 		mutex_exit(&sc->sc_lock);
1180 		return EIO;
1181 	}
1182 
1183 	sc->sc_refcnt++;
1184 	mutex_exit(&sc->sc_lock);
1185 
1186 	/* Check requested parameters. */
1187 	if (t->c_ispeed && t->c_ispeed != t->c_ospeed) {
1188 		error = EINVAL;
1189 		goto out;
1190 	}
1191 
1192 	/*
1193 	 * For the console, always force CLOCAL and !HUPCL, so that the port
1194 	 * is always active.
1195 	 */
1196 	if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR)) {
1197 		SET(t->c_cflag, CLOCAL);
1198 		CLR(t->c_cflag, HUPCL);
1199 	}
1200 
1201 	/*
1202 	 * If there were no changes, don't do anything.  This avoids dropping
1203 	 * input and improves performance when all we did was frob things like
1204 	 * VMIN and VTIME.
1205 	 */
1206 	if (tp->t_ospeed == t->c_ospeed &&
1207 	    tp->t_cflag == t->c_cflag) {
1208 		goto out;
1209 	}
1210 
1211 	/* XXX lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); */
1212 
1213 	/* And copy to tty. */
1214 	tp->t_ispeed = 0;
1215 	tp->t_ospeed = t->c_ospeed;
1216 	tp->t_cflag = t->c_cflag;
1217 
1218 	if (sc->sc_methods->ucom_param != NULL) {
1219 		error = sc->sc_methods->ucom_param(sc->sc_parent, sc->sc_portno,
1220 		    t);
1221 		if (error)
1222 			goto out;
1223 	}
1224 
1225 	/* XXX worry about CHWFLOW */
1226 
1227 	/*
1228 	 * Update the tty layer's idea of the carrier bit, in case we changed
1229 	 * CLOCAL or MDMBUF.  We don't hang up here; we only do that by
1230 	 * explicit request.
1231 	 */
1232 	DPRINTF("l_modem", 0, 0, 0, 0);
1233 	(void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD));
1234 
1235 #if 0
1236 XXX what if the hardware is not open
1237 	if (!ISSET(t->c_cflag, CHWFLOW)) {
1238 		if (sc->sc_tx_stopped) {
1239 			sc->sc_tx_stopped = 0;
1240 			ucomstart(tp);
1241 		}
1242 	}
1243 #endif
1244 out:
1245 	mutex_enter(&sc->sc_lock);
1246 	if (--sc->sc_refcnt < 0)
1247 		cv_broadcast(&sc->sc_detachcv);
1248 	DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(tp->t_dev), sc->sc_refcnt,
1249 	    0, 0);
1250 
1251 	mutex_exit(&sc->sc_lock);
1252 
1253 	return 0;
1254 }
1255 
1256 static int
1257 ucomhwiflow(struct tty *tp, int block)
1258 {
1259 	const int unit = UCOMUNIT(tp->t_dev);
1260 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
1261 	int old;
1262 
1263 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1264 
1265 	if (sc == NULL)
1266 		return 0;
1267 
1268 	mutex_enter(&sc->sc_lock);
1269 	old = sc->sc_rx_stopped;
1270 	sc->sc_rx_stopped = (u_char)block;
1271 
1272 	if (old && !block) {
1273 		sc->sc_rx_unblock = 1;
1274 		softint_schedule(sc->sc_si);
1275 	}
1276 	mutex_exit(&sc->sc_lock);
1277 
1278 	return 1;
1279 }
1280 
1281 static void
1282 ucomstart(struct tty *tp)
1283 {
1284 	const int unit = UCOMUNIT(tp->t_dev);
1285 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
1286 	struct ucom_buffer *ub;
1287 	u_char *data;
1288 	int cnt;
1289 
1290 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1291 
1292 	if (sc == NULL)
1293 		return;
1294 
1295 	KASSERT(&sc->sc_lock);
1296 	KASSERT(mutex_owned(&tty_lock));
1297 	if (sc->sc_dying) {
1298 		DPRINTF("... dying", 0, 0, 0, 0);
1299 		return;
1300 	}
1301 
1302 	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
1303 		goto out;
1304 	if (sc->sc_tx_stopped)
1305 		goto out;
1306 
1307 	if (!ttypull(tp))
1308 		goto out;
1309 
1310 	/* Grab the first contiguous region of buffer space. */
1311 	data = tp->t_outq.c_cf;
1312 	cnt = ndqb(&tp->t_outq, 0);
1313 
1314 	if (cnt == 0)
1315 		goto out;
1316 
1317 	ub = SIMPLEQ_FIRST(&sc->sc_obuff_free);
1318 	if (ub == NULL) {
1319 		SET(tp->t_state, TS_BUSY);
1320 		goto out;
1321 	}
1322 
1323 	SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link);
1324 
1325 	if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL)
1326 		SET(tp->t_state, TS_BUSY);
1327 
1328 	if (cnt > sc->sc_obufsize)
1329 		cnt = sc->sc_obufsize;
1330 
1331 	if (sc->sc_methods->ucom_write != NULL)
1332 		sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno,
1333 		    ub->ub_data, data, &cnt);
1334 	else
1335 		memcpy(ub->ub_data, data, cnt);
1336 
1337 	ub->ub_len = cnt;
1338 	ub->ub_index = 0;
1339 
1340 	SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_full, ub, ub_link);
1341 
1342 	softint_schedule(sc->sc_si);
1343 
1344  out:
1345 	DPRINTF("... done", 0, 0, 0, 0);
1346 	return;
1347 }
1348 
1349 void
1350 ucomstop(struct tty *tp, int flag)
1351 {
1352 #if 0
1353 	const int unit = UCOMUNIT(tp->t_dev);
1354 	struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit);
1355 
1356 	mutex_enter(&sc->sc_lock);
1357 	mutex_spin_enter(&tty_lock);
1358 	if (ISSET(tp->t_state, TS_BUSY)) {
1359 		/* obuff_full -> obuff_free? */
1360 		/* sc->sc_tx_stopped = 1; */
1361 		if (!ISSET(tp->t_state, TS_TTSTOP))
1362 			SET(tp->t_state, TS_FLUSH);
1363 	}
1364 	mutex_spin_exit(&tty_lock);
1365 	mutex_exit(&sc->sc_lock);
1366 #endif
1367 }
1368 
1369 static void
1370 ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub,
1371     usbd_status err)
1372 {
1373 	struct tty *tp = sc->sc_tty;
1374 	uint32_t cc = ub->ub_len;
1375 
1376 	KASSERT(mutex_owned(&sc->sc_lock));
1377 
1378 	switch (err) {
1379 	case USBD_IN_PROGRESS:
1380 		ub->ub_index = ub->ub_len;
1381 		break;
1382 	case USBD_STALLED:
1383 		ub->ub_index = 0;
1384 		softint_schedule(sc->sc_si);
1385 		break;
1386 	case USBD_NORMAL_COMPLETION:
1387 		usbd_get_xfer_status(ub->ub_xfer, NULL, NULL, &cc, NULL);
1388 		rnd_add_uint32(&sc->sc_rndsource, cc);
1389 		/*FALLTHROUGH*/
1390 	default:
1391 		SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_full, ub_link);
1392 		SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link);
1393 		cc -= sc->sc_opkthdrlen;
1394 
1395 		mutex_spin_enter(&tty_lock);
1396 		CLR(tp->t_state, TS_BUSY);
1397 		if (ISSET(tp->t_state, TS_FLUSH))
1398 			CLR(tp->t_state, TS_FLUSH);
1399 		else
1400 			ndflush(&tp->t_outq, cc);
1401 		mutex_spin_exit(&tty_lock);
1402 
1403 		if (err != USBD_CANCELLED && err != USBD_IOERROR &&
1404 		    !sc->sc_dying) {
1405 			if ((ub = SIMPLEQ_FIRST(&sc->sc_obuff_full)) != NULL)
1406 				ucom_submit_write(sc, ub);
1407 
1408 			mutex_spin_enter(&tty_lock);
1409 			(*tp->t_linesw->l_start)(tp);
1410 			mutex_spin_exit(&tty_lock);
1411 		}
1412 		break;
1413 	}
1414 }
1415 
1416 static void
1417 ucom_submit_write(struct ucom_softc *sc, struct ucom_buffer *ub)
1418 {
1419 
1420 	KASSERT(mutex_owned(&sc->sc_lock));
1421 
1422 	usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, ub->ub_len,
1423 	    0, USBD_NO_TIMEOUT, ucomwritecb);
1424 
1425 	ucom_write_status(sc, ub, usbd_transfer(ub->ub_xfer));
1426 }
1427 
1428 static void
1429 ucomwritecb(struct usbd_xfer *xfer, void *p, usbd_status status)
1430 {
1431 	struct ucom_softc *sc = (struct ucom_softc *)p;
1432 
1433 	mutex_enter(&sc->sc_lock);
1434 	ucom_write_status(sc, SIMPLEQ_FIRST(&sc->sc_obuff_full), status);
1435 	mutex_exit(&sc->sc_lock);
1436 
1437 }
1438 
1439 static void
1440 ucom_softintr(void *arg)
1441 {
1442 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1443 
1444 	struct ucom_softc *sc = arg;
1445 
1446 	mutex_enter(&sc->sc_lock);
1447 	if (sc->sc_dying) {
1448 		DPRINTF("... dying", 0, 0, 0, 0);
1449 		mutex_exit(&sc->sc_lock);
1450 		return;
1451 	}
1452 
1453 	struct tty *tp = sc->sc_tty;
1454 	mutex_enter(&tty_lock);
1455 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
1456 		mutex_exit(&tty_lock);
1457 		mutex_exit(&sc->sc_lock);
1458 		return;
1459 	}
1460 	mutex_exit(&tty_lock);
1461 
1462 	struct ucom_buffer *ub = SIMPLEQ_FIRST(&sc->sc_obuff_full);
1463 
1464 	if (ub != NULL && ub->ub_index == 0)
1465 		ucom_submit_write(sc, ub);
1466 
1467 	if (sc->sc_rx_unblock)
1468 		ucom_read_complete(sc);
1469 
1470 	mutex_exit(&sc->sc_lock);
1471 }
1472 
1473 static void
1474 ucom_read_complete(struct ucom_softc *sc)
1475 {
1476 	int (*rint)(int, struct tty *);
1477 	struct ucom_buffer *ub;
1478 	struct tty *tp;
1479 
1480 	KASSERT(mutex_owned(&sc->sc_lock));
1481 
1482 	tp = sc->sc_tty;
1483 	rint = tp->t_linesw->l_rint;
1484 	ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full);
1485 
1486 	while (ub != NULL && !sc->sc_rx_stopped) {
1487 
1488 		/* XXX ttyinput takes tty_lock */
1489 		while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) {
1490 			/* Give characters to tty layer. */
1491 			if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) {
1492 				/* Overflow: drop remainder */
1493 				ub->ub_index = ub->ub_len;
1494 			} else
1495 				ub->ub_index++;
1496 		}
1497 
1498 		if (ub->ub_index == ub->ub_len) {
1499 			SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link);
1500 
1501 			sc->sc_refcnt--;
1502 			/* increments sc_refcnt */
1503 			ucomsubmitread(sc, ub);
1504 
1505 			ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full);
1506 		}
1507 	}
1508 
1509 	sc->sc_rx_unblock = (ub != NULL);
1510 }
1511 
1512 static int
1513 ucomsubmitread(struct ucom_softc *sc, struct ucom_buffer *ub)
1514 {
1515 	usbd_status err;
1516 
1517 	KASSERT(mutex_owned(&sc->sc_lock));
1518 
1519 	usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize,
1520 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb);
1521 
1522 	if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) {
1523 		/* XXX: Recover from this, please! */
1524 		printf("%s: err=%s\n", __func__, usbd_errstr(err));
1525 		return EIO;
1526 	}
1527 
1528 	sc->sc_refcnt++;
1529 
1530 	SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link);
1531 
1532 	return 0;
1533 }
1534 
1535 static void
1536 ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status)
1537 {
1538 	struct ucom_softc *sc = (struct ucom_softc *)p;
1539 	struct ucom_buffer *ub;
1540 	uint32_t cc;
1541 	u_char *cp;
1542 
1543 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1544 
1545 	mutex_enter(&sc->sc_lock);
1546 
1547 	struct tty *tp = sc->sc_tty;
1548 
1549 	if (status == USBD_CANCELLED || status == USBD_IOERROR ||
1550 	    sc->sc_dying) {
1551 
1552 		DPRINTF("... done (status %jd dying %jd)", status, sc->sc_dying,
1553 		    0, 0);
1554 
1555 		if (status == USBD_IOERROR || sc->sc_dying) {
1556 			/* Send something to wake upper layer */
1557 			(tp->t_linesw->l_rint)('\n', tp);
1558 			mutex_spin_enter(&tty_lock);	/* XXX */
1559 			ttwakeup(tp);
1560 			mutex_spin_exit(&tty_lock);	/* XXX */
1561 		}
1562 
1563 		if (--sc->sc_refcnt < 0)
1564 			cv_broadcast(&sc->sc_detachcv);
1565 		DPRINTF("unit=%jd refcnt %jd", UCOMUNIT(tp->t_dev),
1566 		    sc->sc_refcnt, 0, 0);
1567 		mutex_exit(&sc->sc_lock);
1568 
1569 		return;
1570 	}
1571 
1572 	ub = SIMPLEQ_FIRST(&sc->sc_ibuff_empty);
1573 	SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link);
1574 
1575 	if (status != USBD_NORMAL_COMPLETION) {
1576 		if (status == USBD_STALLED) {
1577 			usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
1578 		} else {
1579 			printf("ucomreadcb: wonky status=%s\n",
1580 			    usbd_errstr(status));
1581 		}
1582 
1583 		DPRINTF("... done (status %jd)", status, 0, 0, 0);
1584 		sc->sc_refcnt--;
1585 		/* re-adds ub to sc_ibuff_empty and increments sc_refcnt */
1586 		ucomsubmitread(sc, ub);
1587 		mutex_exit(&sc->sc_lock);
1588 		return;
1589 	}
1590 
1591 	usbd_get_xfer_status(xfer, NULL, (void *)&cp, &cc, NULL);
1592 
1593 #ifdef UCOM_DEBUG
1594 	/* This is triggered by uslsa(4) occasionally. */
1595 	if ((ucomdebug > 0) && (cc == 0)) {
1596 		device_printf(sc->sc_dev, "ucomreadcb: zero length xfer!\n");
1597 	}
1598 #endif
1599 	KDASSERT(cp == ub->ub_data);
1600 
1601 	rnd_add_uint32(&sc->sc_rndsource, cc);
1602 
1603 	if (sc->sc_state != UCOM_OPEN) {
1604 		/* Go around again - we're not quite ready */
1605 		sc->sc_refcnt--;
1606 		/* re-adds ub to sc_ibuff_empty and increments sc_refcnt */
1607 		ucomsubmitread(sc, ub);
1608 		mutex_exit(&sc->sc_lock);
1609 		DPRINTF("... done (not open)", 0, 0, 0, 0);
1610 		return;
1611 	}
1612 
1613 	mutex_exit(&sc->sc_lock);
1614 	if (sc->sc_methods->ucom_read != NULL) {
1615 		sc->sc_methods->ucom_read(sc->sc_parent, sc->sc_portno,
1616 		    &cp, &cc);
1617 		ub->ub_index = (u_int)(cp - ub->ub_data);
1618 	} else
1619 		ub->ub_index = 0;
1620 
1621 	ub->ub_len = cc;
1622 
1623 	mutex_enter(&sc->sc_lock);
1624 	if (sc->sc_dying) {
1625 		if (--sc->sc_refcnt < 0)
1626 			cv_broadcast(&sc->sc_detachcv);
1627 		mutex_exit(&sc->sc_lock);
1628 		DPRINTF("... dying", 0, 0, 0, 0);
1629 		return;
1630 	}
1631 
1632 	SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_full, ub, ub_link);
1633 
1634 	ucom_read_complete(sc);
1635 	mutex_exit(&sc->sc_lock);
1636 
1637 	DPRINTF("... done", 0, 0, 0, 0);
1638 }
1639 
1640 static void
1641 ucom_cleanup(struct ucom_softc *sc)
1642 {
1643 
1644 	UCOMHIST_FUNC(); UCOMHIST_CALLED();
1645 
1646 	DPRINTF("aborting pipes", 0, 0, 0, 0);
1647 
1648 	mutex_enter(&sc->sc_lock);
1649 
1650 	/* If we're dying then the detach routine will abort our pipes, etc */
1651 	if (sc->sc_dying) {
1652 		DPRINTF("... dying", 0, 0, 0, 0);
1653 
1654 		mutex_exit(&sc->sc_lock);
1655 		return;
1656 	}
1657 
1658 	mutex_exit(&sc->sc_lock);
1659 
1660 	ucom_shutdown(sc);
1661 
1662 	if (sc->sc_bulkin_pipe != NULL) {
1663 		usbd_abort_pipe(sc->sc_bulkin_pipe);
1664 	}
1665 	if (sc->sc_bulkout_pipe != NULL) {
1666 		usbd_abort_pipe(sc->sc_bulkout_pipe);
1667 	}
1668 }
1669 
1670 #endif /* NUCOM > 0 */
1671 
1672 int
1673 ucomprint(void *aux, const char *pnp)
1674 {
1675 	struct ucom_attach_args *ucaa = aux;
1676 
1677 	if (pnp)
1678 		aprint_normal("ucom at %s", pnp);
1679 	if (ucaa->ucaa_portno != UCOM_UNK_PORTNO)
1680 		aprint_normal(" portno %d", ucaa->ucaa_portno);
1681 	return UNCONF;
1682 }
1683 
1684 int
1685 ucomsubmatch(device_t parent, cfdata_t cf,
1686 	     const int *ldesc, void *aux)
1687 {
1688 	struct ucom_attach_args *ucaa = aux;
1689 
1690 	if (ucaa->ucaa_portno != UCOM_UNK_PORTNO &&
1691 	    cf->cf_loc[UCOMBUSCF_PORTNO] != UCOMBUSCF_PORTNO_DEFAULT &&
1692 	    cf->cf_loc[UCOMBUSCF_PORTNO] != ucaa->ucaa_portno)
1693 		return 0;
1694 	return config_match(parent, cf, aux);
1695 }
1696