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