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