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