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