1 /* $NetBSD: ucom.c,v 1.146 2025/10/22 05:41:51 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.146 2025/10/22 05:41:51 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/proc.h> 53 #include <sys/poll.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 sc->sc_tty = tp; 365 366 DPRINTF("tty_attach %#jx", (uintptr_t)tp, 0, 0, 0); 367 tty_attach(tp); 368 369 if (!pmf_device_register(self, NULL, NULL)) 370 aprint_error_dev(self, "couldn't establish power handler\n"); 371 372 sc->sc_state = UCOM_ATTACHED; 373 return; 374 375 fail_2: 376 for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; 377 ub++) { 378 if (ub->ub_xfer) 379 usbd_destroy_xfer(ub->ub_xfer); 380 } 381 usbd_close_pipe(sc->sc_bulkout_pipe); 382 sc->sc_bulkout_pipe = NULL; 383 384 fail_1: 385 for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; 386 ub++) { 387 if (ub->ub_xfer) 388 usbd_destroy_xfer(ub->ub_xfer); 389 } 390 usbd_close_pipe(sc->sc_bulkin_pipe); 391 sc->sc_bulkin_pipe = NULL; 392 393 fail_0: 394 aprint_error_dev(self, "attach failed, error=%d\n", error); 395 } 396 397 int 398 ucom_detach(device_t self, int flags) 399 { 400 struct ucom_softc *sc = device_private(self); 401 struct tty *tp = sc->sc_tty; 402 int maj, mn; 403 int i; 404 405 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 406 407 DPRINTF("sc=%#jx flags=%jd tp=%#jx", (uintptr_t)sc, flags, 408 (uintptr_t)tp, 0); 409 DPRINTF("... pipe=%jd,%jd", sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0); 410 411 /* Prevent new opens from hanging. */ 412 mutex_enter(&sc->sc_lock); 413 sc->sc_dying = true; 414 mutex_exit(&sc->sc_lock); 415 416 pmf_device_deregister(self); 417 418 /* tty is now off. */ 419 if (tp != NULL) { 420 ttylock(tp); 421 CLR(tp->t_state, TS_CARR_ON); 422 CLR(tp->t_cflag, CLOCAL | MDMBUF); 423 ttyunlock(tp); 424 } 425 426 /* locate the major number */ 427 maj = cdevsw_lookup_major(&ucom_cdevsw); 428 429 /* Nuke the vnodes for any open instances. */ 430 mn = device_unit(self); 431 DPRINTF("maj=%jd mn=%jd", maj, mn, 0, 0); 432 vdevgone(maj, mn, mn, VCHR); 433 vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR); 434 vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR); 435 436 softint_disestablish(sc->sc_si); 437 438 /* Detach and free the tty. */ 439 if (tp != NULL) { 440 tty_detach(tp); 441 tty_free(tp); 442 sc->sc_tty = NULL; 443 } 444 445 for (i = 0; i < UCOM_IN_BUFFS; i++) { 446 if (sc->sc_ibuff[i].ub_xfer != NULL) 447 usbd_destroy_xfer(sc->sc_ibuff[i].ub_xfer); 448 } 449 450 for (i = 0; i < UCOM_OUT_BUFFS; i++) { 451 if (sc->sc_obuff[i].ub_xfer != NULL) 452 usbd_destroy_xfer(sc->sc_obuff[i].ub_xfer); 453 } 454 455 if (sc->sc_bulkin_pipe != NULL) { 456 usbd_close_pipe(sc->sc_bulkin_pipe); 457 sc->sc_bulkin_pipe = NULL; 458 } 459 460 if (sc->sc_bulkout_pipe != NULL) { 461 usbd_close_pipe(sc->sc_bulkout_pipe); 462 sc->sc_bulkout_pipe = NULL; 463 } 464 465 /* Detach the random source */ 466 rnd_detach_source(&sc->sc_rndsource); 467 468 mutex_destroy(&sc->sc_lock); 469 cv_destroy(&sc->sc_statecv); 470 471 return 0; 472 } 473 474 void 475 ucom_shutdown(struct ucom_softc *sc) 476 { 477 struct tty *tp = sc->sc_tty; 478 479 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 480 481 /* 482 * Hang up if necessary. Wait a bit, so the other side has time to 483 * notice even if we immediately open the port again. 484 */ 485 if (ISSET(tp->t_cflag, HUPCL)) { 486 ucom_dtr(sc, 0); 487 mutex_enter(&sc->sc_lock); 488 microuptime(&sc->sc_hup_time); 489 sc->sc_hup_time.tv_sec++; 490 mutex_exit(&sc->sc_lock); 491 } 492 } 493 494 /* 495 * ucomopen(dev, flag, mode, l) 496 * 497 * Called when anyone tries to open /dev/ttyU? for an existing 498 * ucom? instance that has completed attach. The attach may have 499 * failed, though, or there may be concurrent detach or close in 500 * progress, so fail if attach failed (no sc_tty) or detach has 501 * begun (sc_dying), or wait if there's a concurrent close in 502 * progress before reopening. 503 */ 504 int 505 ucomopen(dev_t dev, int flag, int mode, struct lwp *l) 506 { 507 const int unit = UCOMUNIT(dev); 508 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 509 int error = 0; 510 511 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 512 513 mutex_enter(&sc->sc_lock); 514 if (sc->sc_dying) { 515 DPRINTF("... dying", 0, 0, 0, 0); 516 mutex_exit(&sc->sc_lock); 517 return ENXIO; 518 } 519 520 if (!device_is_active(sc->sc_dev)) { 521 mutex_exit(&sc->sc_lock); 522 return ENXIO; 523 } 524 525 struct tty *tp = sc->sc_tty; 526 if (tp == NULL) { 527 DPRINTF("... not attached", 0, 0, 0, 0); 528 mutex_exit(&sc->sc_lock); 529 return ENXIO; 530 } 531 532 DPRINTF("unit=%jd, tp=%#jx", unit, (uintptr_t)tp, 0, 0); 533 534 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) { 535 mutex_exit(&sc->sc_lock); 536 return EBUSY; 537 } 538 539 /* 540 * If the previous use had set DTR on close, wait up to one 541 * second for the other side to notice we hung up. After 542 * sleeping, the tty may have been revoked, so restart the 543 * whole operation. 544 * 545 * XXX The wchan is not ttclose but maybe should be. 546 */ 547 if (timerisset(&sc->sc_hup_time)) { 548 struct timeval now, delta; 549 int ms, ticks; 550 551 microuptime(&now); 552 if (timercmp(&now, &sc->sc_hup_time, <)) { 553 timersub(&sc->sc_hup_time, &now, &delta); 554 ms = MIN(INT_MAX - 1000, delta.tv_sec*1000); 555 ms += howmany(delta.tv_usec, 1000); 556 ticks = MAX(1, MIN(INT_MAX, mstohz(ms))); 557 (void)cv_timedwait(&sc->sc_statecv, &sc->sc_lock, 558 ticks); 559 mutex_exit(&sc->sc_lock); 560 return ERESTART; 561 } 562 timerclear(&sc->sc_hup_time); 563 } 564 565 /* 566 * Wait while the device is initialized by the 567 * first opener or cleaned up by the last closer. 568 */ 569 enum ucom_state state = sc->sc_state; 570 if (state == UCOM_OPENING || sc->sc_closing) { 571 if (flag & FNONBLOCK) 572 error = EWOULDBLOCK; 573 else 574 error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock); 575 mutex_exit(&sc->sc_lock); 576 return error ? error : ERESTART; 577 } 578 KASSERTMSG(state == UCOM_OPEN || state == UCOM_ATTACHED, 579 "state is %d", state); 580 581 /* 582 * If this is the first open, then make sure the pipes are 583 * running and perform any initialization needed. 584 */ 585 bool firstopen = (state == UCOM_ATTACHED); 586 if (firstopen) { 587 KASSERT(!ISSET(tp->t_state, TS_ISOPEN)); 588 KASSERT(tp->t_wopen == 0); 589 590 tp->t_dev = dev; 591 sc->sc_state = UCOM_OPENING; 592 mutex_exit(&sc->sc_lock); 593 594 if (sc->sc_methods->ucom_open != NULL) { 595 error = sc->sc_methods->ucom_open(sc->sc_parent, 596 sc->sc_portno); 597 if (error) 598 goto bad; 599 } 600 601 ucom_status_change(sc); 602 603 /* Clear PPS capture state on first open. */ 604 mutex_spin_enter(&timecounter_lock); 605 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); 606 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 607 pps_init(&sc->sc_pps_state); 608 mutex_spin_exit(&timecounter_lock); 609 610 /* 611 * Initialize the termios status to the defaults. Add in the 612 * sticky bits from TIOCSFLAGS. 613 */ 614 struct termios t; 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 mutex_enter(&sc->sc_lock); 645 sc->sc_rx_unblock = 0; 646 sc->sc_rx_stopped = 0; 647 sc->sc_tx_stopped = 0; 648 649 /* 650 * Either after ucom was attached, or after ucomclose(), this 651 * list must be empty, otherwise ucomsubmitread() will corrupt 652 * it by queueing an ucom_buffer that is already queued. 653 */ 654 KASSERT(SIMPLEQ_EMPTY(&sc->sc_ibuff_empty)); 655 656 for (size_t i = 0; i < UCOM_IN_BUFFS; i++) { 657 struct ucom_buffer *ub = &sc->sc_ibuff[i]; 658 error = ucomsubmitread(sc, ub); 659 if (error) { 660 mutex_exit(&sc->sc_lock); 661 goto bad; 662 } 663 } 664 } 665 mutex_exit(&sc->sc_lock); 666 667 DPRINTF("unit=%jd, tp=%#jx dialout %jd nonblock %jd", unit, 668 (uintptr_t)tp, !!UCOMDIALOUT(dev), !!ISSET(flag, O_NONBLOCK)); 669 error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 670 if (error) 671 goto bad; 672 673 error = (*tp->t_linesw->l_open)(dev, tp); 674 if (error) 675 goto bad; 676 677 /* 678 * Success! If this was the first open, notify waiters that 679 * the tty is open for business. 680 */ 681 if (firstopen) { 682 mutex_enter(&sc->sc_lock); 683 KASSERT(sc->sc_state == UCOM_OPENING); 684 sc->sc_state = UCOM_OPEN; 685 cv_broadcast(&sc->sc_statecv); 686 mutex_exit(&sc->sc_lock); 687 } 688 return 0; 689 690 bad: 691 /* 692 * Failure! If this was the first open, hang up, abort pipes, 693 * and notify waiters that we're not opening after all. 694 */ 695 if (firstopen) { 696 ucom_cleanup(sc, flag); 697 698 mutex_enter(&sc->sc_lock); 699 KASSERT(sc->sc_state == UCOM_OPENING); 700 sc->sc_state = UCOM_ATTACHED; 701 cv_broadcast(&sc->sc_statecv); 702 mutex_exit(&sc->sc_lock); 703 } 704 return error; 705 } 706 707 /* 708 * ucomcancel(dev, flag, mode, l) 709 * 710 * Called on revoke or last close. Must interrupt any pending I/O 711 * operations and make them fail promptly; once they have all 712 * finished (except possibly new opens), ucomclose will be called. 713 * We set sc_closing to block new opens until ucomclose runs. 714 */ 715 int 716 ucomcancel(dev_t dev, int flag, int mode, struct lwp *l) 717 { 718 const int unit = UCOMUNIT(dev); 719 struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); 720 721 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 722 723 DPRINTF("unit=%jd", UCOMUNIT(dev), 0, 0, 0); 724 725 /* 726 * This can run at any time before ucomclose on any device 727 * node, even if never attached or if attach failed, so we may 728 * not have a softc or a tty. 729 */ 730 if (sc == NULL) 731 return 0; 732 struct tty *tp = sc->sc_tty; 733 if (tp == NULL) 734 return 0; 735 736 /* 737 * Mark the device closing so opens block until we're done 738 * closing. Wake them up so they start over at the top -- if 739 * we're closing because we're detaching, they need to wake up 740 * and notice it's time to fail. 741 */ 742 mutex_enter(&sc->sc_lock); 743 sc->sc_closing = true; 744 cv_broadcast(&sc->sc_statecv); 745 mutex_exit(&sc->sc_lock); 746 747 /* 748 * Cancel any pending tty I/O operations, causing them to wake 749 * up and fail promptly, and preventing any new ones from 750 * starting to wait until we have finished closing. 751 */ 752 ttycancel(tp); 753 754 return 0; 755 } 756 757 /* 758 * ucomclose(dev, flag, mode, l) 759 * 760 * Called after ucomcancel, when all prior operations on the /dev 761 * node have completed. Only new opens may be in progress at this 762 * point, but they will block until sc_closing is set to false. 763 */ 764 int 765 ucomclose(dev_t dev, int flag, int mode, struct lwp *l) 766 { 767 const int unit = UCOMUNIT(dev); 768 struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); 769 int error = 0; 770 771 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 772 773 DPRINTF("unit=%jd", UCOMUNIT(dev), 0, 0, 0); 774 775 /* 776 * This can run at any time after ucomcancel on any device 777 * node, even if never attached or if attach failed, so we may 778 * not have a softc or a tty. 779 */ 780 if (sc == NULL) 781 return 0; 782 struct tty *tp = sc->sc_tty; 783 if (tp == NULL) 784 return 0; 785 786 /* 787 * Close the tty, causing anyone waiting for it to wake, and 788 * hang up the phone. 789 */ 790 ucom_cleanup(sc, flag); 791 792 /* 793 * ttyclose should have cleared TS_ISOPEN and interrupted all 794 * pending opens, which should have completed by now. 795 */ 796 ttylock(tp); 797 KASSERT(!ISSET(tp->t_state, TS_ISOPEN)); 798 KASSERT(tp->t_wopen == 0); 799 ttyunlock(tp); 800 801 /* 802 * Close any device-specific state. 803 */ 804 if (sc->sc_methods->ucom_close != NULL) { 805 sc->sc_methods->ucom_close(sc->sc_parent, 806 sc->sc_portno); 807 } 808 809 /* 810 * We're now closed. Can reopen after this point, so resume 811 * transfers, mark us no longer closing, and notify anyone 812 * waiting in open. The state may be OPEN or ATTACHED at this 813 * point -- OPEN if the device was already open when we closed 814 * it, ATTACHED if we interrupted it in the process of opening. 815 */ 816 mutex_enter(&sc->sc_lock); 817 KASSERTMSG(sc->sc_state == UCOM_ATTACHED || sc->sc_state == UCOM_OPEN, 818 "%s sc=%p state=%d", device_xname(sc->sc_dev), sc, sc->sc_state); 819 KASSERT(sc->sc_closing); 820 sc->sc_state = UCOM_ATTACHED; 821 sc->sc_closing = false; 822 cv_broadcast(&sc->sc_statecv); 823 mutex_exit(&sc->sc_lock); 824 825 return error; 826 } 827 828 int 829 ucomread(dev_t dev, struct uio *uio, int flag) 830 { 831 const int unit = UCOMUNIT(dev); 832 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 833 struct tty *tp = sc->sc_tty; 834 835 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 836 837 return (*tp->t_linesw->l_read)(tp, uio, flag); 838 } 839 840 int 841 ucomwrite(dev_t dev, struct uio *uio, int flag) 842 { 843 const int unit = UCOMUNIT(dev); 844 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 845 struct tty *tp = sc->sc_tty; 846 847 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 848 849 return (*tp->t_linesw->l_write)(tp, uio, flag); 850 } 851 852 int 853 ucompoll(dev_t dev, int events, struct lwp *l) 854 { 855 const int unit = UCOMUNIT(dev); 856 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 857 struct tty *tp = sc->sc_tty; 858 859 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 860 861 return (*tp->t_linesw->l_poll)(tp, events, l); 862 } 863 864 struct tty * 865 ucomtty(dev_t dev) 866 { 867 const int unit = UCOMUNIT(dev); 868 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 869 870 return sc->sc_tty; 871 } 872 873 int 874 ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 875 { 876 const int unit = UCOMUNIT(dev); 877 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 878 struct tty *tp = sc->sc_tty; 879 int error; 880 881 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 882 883 DPRINTF("cmd=0x%08jx", cmd, 0, 0, 0); 884 885 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 886 if (error != EPASSTHROUGH) 887 return error; 888 889 error = ttioctl(tp, cmd, data, flag, l); 890 if (error != EPASSTHROUGH) 891 return error; 892 893 if (sc->sc_methods->ucom_ioctl != NULL) { 894 error = sc->sc_methods->ucom_ioctl(sc->sc_parent, 895 sc->sc_portno, cmd, data, flag, l->l_proc); 896 if (error != EPASSTHROUGH) 897 return error; 898 } 899 900 error = 0; 901 902 DPRINTF("our cmd=0x%08jx", cmd, 0, 0, 0); 903 904 switch (cmd) { 905 case TIOCSBRK: 906 ucom_break(sc, 1); 907 break; 908 909 case TIOCCBRK: 910 ucom_break(sc, 0); 911 break; 912 913 case TIOCSDTR: 914 ucom_dtr(sc, 1); 915 break; 916 917 case TIOCCDTR: 918 ucom_dtr(sc, 0); 919 break; 920 921 case TIOCGFLAGS: 922 mutex_enter(&sc->sc_lock); 923 *(int *)data = sc->sc_swflags; 924 mutex_exit(&sc->sc_lock); 925 break; 926 927 case TIOCSFLAGS: 928 error = kauth_authorize_device_tty(l->l_cred, 929 KAUTH_DEVICE_TTY_PRIVSET, tp); 930 if (error) 931 break; 932 mutex_enter(&sc->sc_lock); 933 sc->sc_swflags = *(int *)data; 934 mutex_exit(&sc->sc_lock); 935 break; 936 937 case TIOCMSET: 938 case TIOCMBIS: 939 case TIOCMBIC: 940 tiocm_to_ucom(sc, cmd, *(int *)data); 941 break; 942 943 case TIOCMGET: 944 *(int *)data = ucom_to_tiocm(sc); 945 break; 946 947 case PPS_IOC_CREATE: 948 case PPS_IOC_DESTROY: 949 case PPS_IOC_GETPARAMS: 950 case PPS_IOC_SETPARAMS: 951 case PPS_IOC_GETCAP: 952 case PPS_IOC_FETCH: 953 #ifdef PPS_SYNC 954 case PPS_IOC_KCBIND: 955 #endif 956 mutex_spin_enter(&timecounter_lock); 957 error = pps_ioctl(cmd, data, &sc->sc_pps_state); 958 mutex_spin_exit(&timecounter_lock); 959 break; 960 961 default: 962 error = EPASSTHROUGH; 963 break; 964 } 965 966 return error; 967 } 968 969 static void 970 tiocm_to_ucom(struct ucom_softc *sc, u_long how, int ttybits) 971 { 972 u_char combits; 973 974 combits = 0; 975 if (ISSET(ttybits, TIOCM_DTR)) 976 SET(combits, UMCR_DTR); 977 if (ISSET(ttybits, TIOCM_RTS)) 978 SET(combits, UMCR_RTS); 979 980 mutex_enter(&sc->sc_lock); 981 switch (how) { 982 case TIOCMBIC: 983 CLR(sc->sc_mcr, combits); 984 break; 985 986 case TIOCMBIS: 987 SET(sc->sc_mcr, combits); 988 break; 989 990 case TIOCMSET: 991 CLR(sc->sc_mcr, UMCR_DTR | UMCR_RTS); 992 SET(sc->sc_mcr, combits); 993 break; 994 } 995 u_char mcr = sc->sc_mcr; 996 mutex_exit(&sc->sc_lock); 997 998 if (how == TIOCMSET || ISSET(combits, UMCR_DTR)) 999 ucom_dtr(sc, (mcr & UMCR_DTR) != 0); 1000 if (how == TIOCMSET || ISSET(combits, UMCR_RTS)) 1001 ucom_rts(sc, (mcr & UMCR_RTS) != 0); 1002 } 1003 1004 static int 1005 ucom_to_tiocm(struct ucom_softc *sc) 1006 { 1007 u_char combits; 1008 int ttybits = 0; 1009 1010 mutex_enter(&sc->sc_lock); 1011 combits = sc->sc_mcr; 1012 if (ISSET(combits, UMCR_DTR)) 1013 SET(ttybits, TIOCM_DTR); 1014 if (ISSET(combits, UMCR_RTS)) 1015 SET(ttybits, TIOCM_RTS); 1016 1017 combits = sc->sc_msr; 1018 if (ISSET(combits, UMSR_DCD)) 1019 SET(ttybits, TIOCM_CD); 1020 if (ISSET(combits, UMSR_CTS)) 1021 SET(ttybits, TIOCM_CTS); 1022 if (ISSET(combits, UMSR_DSR)) 1023 SET(ttybits, TIOCM_DSR); 1024 if (ISSET(combits, UMSR_RI | UMSR_TERI)) 1025 SET(ttybits, TIOCM_RI); 1026 1027 #if 0 1028 XXX; 1029 if (sc->sc_ier != 0) 1030 SET(ttybits, TIOCM_LE); 1031 #endif 1032 mutex_exit(&sc->sc_lock); 1033 1034 return ttybits; 1035 } 1036 1037 static void 1038 ucom_break(struct ucom_softc *sc, int onoff) 1039 { 1040 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1041 1042 DPRINTF("onoff=%jd", onoff, 0, 0, 0); 1043 1044 if (sc->sc_methods->ucom_set != NULL) 1045 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1046 UCOM_SET_BREAK, onoff); 1047 } 1048 1049 static void 1050 ucom_dtr(struct ucom_softc *sc, int onoff) 1051 { 1052 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1053 1054 DPRINTF("onoff=%jd", onoff, 0, 0, 0); 1055 1056 if (sc->sc_methods->ucom_set != NULL) 1057 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1058 UCOM_SET_DTR, onoff); 1059 } 1060 1061 static void 1062 ucom_rts(struct ucom_softc *sc, int onoff) 1063 { 1064 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1065 1066 DPRINTF("onoff=%jd", onoff, 0, 0, 0); 1067 1068 if (sc->sc_methods->ucom_set != NULL) 1069 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1070 UCOM_SET_RTS, onoff); 1071 } 1072 1073 void 1074 ucom_status_change(struct ucom_softc *sc) 1075 { 1076 struct tty *tp = sc->sc_tty; 1077 1078 if (sc->sc_methods->ucom_get_status != NULL) { 1079 u_char msr, lsr; 1080 1081 sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno, 1082 &lsr, &msr); 1083 mutex_enter(&sc->sc_lock); 1084 u_char old_msr = sc->sc_msr; 1085 1086 sc->sc_lsr = lsr; 1087 sc->sc_msr = msr; 1088 mutex_exit(&sc->sc_lock); 1089 1090 if (ISSET((msr ^ old_msr), UMSR_DCD)) { 1091 mutex_spin_enter(&timecounter_lock); 1092 pps_capture(&sc->sc_pps_state); 1093 pps_event(&sc->sc_pps_state, 1094 (sc->sc_msr & UMSR_DCD) ? 1095 PPS_CAPTUREASSERT : 1096 PPS_CAPTURECLEAR); 1097 mutex_spin_exit(&timecounter_lock); 1098 1099 (*tp->t_linesw->l_modem)(tp, ISSET(msr, UMSR_DCD)); 1100 } 1101 } else { 1102 mutex_enter(&sc->sc_lock); 1103 sc->sc_lsr = 0; 1104 /* Assume DCD is present, if we have no chance to check it. */ 1105 sc->sc_msr = UMSR_DCD; 1106 mutex_exit(&sc->sc_lock); 1107 } 1108 } 1109 1110 static int 1111 ucomparam(struct tty *tp, struct termios *t) 1112 { 1113 const int unit = UCOMUNIT(tp->t_dev); 1114 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1115 int error = 0; 1116 1117 /* XXX should take tty lock around touching tp */ 1118 1119 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1120 1121 /* Check requested parameters. */ 1122 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) { 1123 error = EINVAL; 1124 goto out; 1125 } 1126 1127 /* 1128 * For the console, always force CLOCAL and !HUPCL, so that the port 1129 * is always active. 1130 */ 1131 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR)) { 1132 SET(t->c_cflag, CLOCAL); 1133 CLR(t->c_cflag, HUPCL); 1134 } 1135 1136 /* 1137 * If there were no changes, don't do anything. This avoids dropping 1138 * input and improves performance when all we did was frob things like 1139 * VMIN and VTIME. 1140 */ 1141 if (tp->t_ospeed == t->c_ospeed && 1142 tp->t_cflag == t->c_cflag) { 1143 goto out; 1144 } 1145 1146 /* XXX lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); */ 1147 1148 /* And copy to tty. */ 1149 tp->t_ispeed = 0; 1150 tp->t_ospeed = t->c_ospeed; 1151 tp->t_cflag = t->c_cflag; 1152 1153 if (sc->sc_methods->ucom_param != NULL) { 1154 error = sc->sc_methods->ucom_param(sc->sc_parent, sc->sc_portno, 1155 t); 1156 if (error) 1157 goto out; 1158 } 1159 1160 /* XXX worry about CHWFLOW */ 1161 1162 /* 1163 * Update the tty layer's idea of the carrier bit, in case we changed 1164 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 1165 * explicit request. 1166 */ 1167 DPRINTF("l_modem", 0, 0, 0, 0); 1168 (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD)); 1169 1170 #if 0 1171 XXX what if the hardware is not open 1172 if (!ISSET(t->c_cflag, CHWFLOW)) { 1173 if (sc->sc_tx_stopped) { 1174 sc->sc_tx_stopped = 0; 1175 ucomstart(tp); 1176 } 1177 } 1178 #endif 1179 out: 1180 return error; 1181 } 1182 1183 static int 1184 ucomhwiflow(struct tty *tp, int block) 1185 { 1186 const int unit = UCOMUNIT(tp->t_dev); 1187 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 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 const int unit = UCOMUNIT(tp->t_dev); 1212 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1213 struct ucom_buffer *ub; 1214 u_char *data; 1215 int cnt; 1216 1217 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1218 1219 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 1220 goto out; 1221 if (sc->sc_tx_stopped) 1222 goto out; 1223 1224 if (!ttypull(tp)) 1225 goto out; 1226 1227 /* Grab the first contiguous region of buffer space. */ 1228 data = tp->t_outq.c_cf; 1229 cnt = ndqb(&tp->t_outq, 0); 1230 1231 if (cnt == 0) 1232 goto out; 1233 1234 ub = SIMPLEQ_FIRST(&sc->sc_obuff_free); 1235 if (ub == NULL) { 1236 SET(tp->t_state, TS_BUSY); 1237 goto out; 1238 } 1239 1240 SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link); 1241 1242 if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL) 1243 SET(tp->t_state, TS_BUSY); 1244 1245 if (cnt > sc->sc_obufsize) 1246 cnt = sc->sc_obufsize; 1247 1248 if (sc->sc_methods->ucom_write != NULL) 1249 sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno, 1250 ub->ub_data, data, &cnt); 1251 else 1252 memcpy(ub->ub_data, data, cnt); 1253 1254 ub->ub_len = cnt; 1255 ub->ub_index = 0; 1256 1257 SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_full, ub, ub_link); 1258 1259 kpreempt_disable(); 1260 softint_schedule(sc->sc_si); 1261 kpreempt_enable(); 1262 1263 out: 1264 DPRINTF("... done", 0, 0, 0, 0); 1265 return; 1266 } 1267 1268 void 1269 ucomstop(struct tty *tp, int flag) 1270 { 1271 #if 0 1272 const int unit = UCOMUNIT(tp->t_dev); 1273 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1274 1275 mutex_enter(&sc->sc_lock); 1276 ttylock(tp); 1277 if (ISSET(tp->t_state, TS_BUSY)) { 1278 /* obuff_full -> obuff_free? */ 1279 /* sc->sc_tx_stopped = 1; */ 1280 if (!ISSET(tp->t_state, TS_TTSTOP)) 1281 SET(tp->t_state, TS_FLUSH); 1282 } 1283 ttyunlock(tp); 1284 mutex_exit(&sc->sc_lock); 1285 #endif 1286 } 1287 1288 static void 1289 ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub, 1290 usbd_status err) 1291 { 1292 struct tty *tp = sc->sc_tty; 1293 uint32_t cc = ub->ub_len; 1294 1295 KASSERT(mutex_owned(&sc->sc_lock)); 1296 1297 switch (err) { 1298 case USBD_IN_PROGRESS: 1299 ub->ub_index = ub->ub_len; 1300 break; 1301 case USBD_STALLED: 1302 ub->ub_index = 0; 1303 kpreempt_disable(); 1304 softint_schedule(sc->sc_si); 1305 kpreempt_enable(); 1306 break; 1307 case USBD_NORMAL_COMPLETION: 1308 usbd_get_xfer_status(ub->ub_xfer, NULL, NULL, &cc, NULL); 1309 rnd_add_uint32(&sc->sc_rndsource, cc); 1310 /*FALLTHROUGH*/ 1311 default: 1312 SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_full, ub_link); 1313 SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); 1314 cc -= sc->sc_opkthdrlen; 1315 1316 ttylock(tp); 1317 CLR(tp->t_state, TS_BUSY); 1318 if (ISSET(tp->t_state, TS_FLUSH)) 1319 CLR(tp->t_state, TS_FLUSH); 1320 else 1321 ndflush(&tp->t_outq, cc); 1322 ttyunlock(tp); 1323 1324 if (err != USBD_CANCELLED && err != USBD_IOERROR && 1325 !sc->sc_closing) { 1326 if ((ub = SIMPLEQ_FIRST(&sc->sc_obuff_full)) != NULL) 1327 ucom_submit_write(sc, ub); 1328 1329 ttylock(tp); 1330 (*tp->t_linesw->l_start)(tp); 1331 ttyunlock(tp); 1332 } 1333 break; 1334 } 1335 } 1336 1337 static void 1338 ucom_submit_write(struct ucom_softc *sc, struct ucom_buffer *ub) 1339 { 1340 1341 KASSERT(mutex_owned(&sc->sc_lock)); 1342 1343 usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, ub->ub_len, 1344 0, USBD_NO_TIMEOUT, ucomwritecb); 1345 1346 ucom_write_status(sc, ub, usbd_transfer(ub->ub_xfer)); 1347 } 1348 1349 static void 1350 ucomwritecb(struct usbd_xfer *xfer, void *p, usbd_status status) 1351 { 1352 struct ucom_softc *sc = (struct ucom_softc *)p; 1353 1354 mutex_enter(&sc->sc_lock); 1355 ucom_write_status(sc, SIMPLEQ_FIRST(&sc->sc_obuff_full), status); 1356 mutex_exit(&sc->sc_lock); 1357 1358 } 1359 1360 static void 1361 ucom_softintr(void *arg) 1362 { 1363 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1364 1365 struct ucom_softc *sc = arg; 1366 struct tty *tp = sc->sc_tty; 1367 1368 mutex_enter(&sc->sc_lock); 1369 ttylock(tp); 1370 if (!ISSET(tp->t_state, TS_ISOPEN)) { 1371 ttyunlock(tp); 1372 mutex_exit(&sc->sc_lock); 1373 return; 1374 } 1375 ttyunlock(tp); 1376 1377 struct ucom_buffer *ub = SIMPLEQ_FIRST(&sc->sc_obuff_full); 1378 1379 if (ub != NULL && ub->ub_index == 0) 1380 ucom_submit_write(sc, ub); 1381 1382 if (sc->sc_rx_unblock) 1383 ucom_read_complete(sc); 1384 1385 mutex_exit(&sc->sc_lock); 1386 } 1387 1388 static void 1389 ucom_read_complete(struct ucom_softc *sc) 1390 { 1391 int (*rint)(int, struct tty *); 1392 struct ucom_buffer *ub; 1393 struct tty *tp; 1394 1395 KASSERT(mutex_owned(&sc->sc_lock)); 1396 1397 tp = sc->sc_tty; 1398 rint = tp->t_linesw->l_rint; 1399 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); 1400 1401 while (ub != NULL && !sc->sc_rx_stopped) { 1402 1403 /* XXX ttyinput takes ttylock */ 1404 while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) { 1405 /* Give characters to tty layer. */ 1406 if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) { 1407 /* Overflow: drop remainder */ 1408 ub->ub_index = ub->ub_len; 1409 } else 1410 ub->ub_index++; 1411 } 1412 1413 if (ub->ub_index == ub->ub_len) { 1414 SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link); 1415 ucomsubmitread(sc, ub); 1416 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); 1417 } 1418 } 1419 1420 sc->sc_rx_unblock = (ub != NULL); 1421 } 1422 1423 static int 1424 ucomsubmitread(struct ucom_softc *sc, struct ucom_buffer *ub) 1425 { 1426 usbd_status err; 1427 1428 KASSERT(mutex_owned(&sc->sc_lock)); 1429 1430 usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize, 1431 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb); 1432 1433 if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) { 1434 /* XXX: Recover from this, please! */ 1435 device_printf(sc->sc_dev, "%s: err=%s\n", 1436 __func__, usbd_errstr(err)); 1437 return EIO; 1438 } 1439 1440 SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link); 1441 1442 return 0; 1443 } 1444 1445 static void 1446 ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status) 1447 { 1448 struct ucom_softc *sc = (struct ucom_softc *)p; 1449 struct ucom_buffer *ub; 1450 uint32_t cc; 1451 u_char *cp; 1452 1453 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1454 1455 mutex_enter(&sc->sc_lock); 1456 1457 /* 1458 * Always remove the ucom_buffer from the sc_ibuff_empty list 1459 * regardless of transfer status. Leaving it on the list on 1460 * USBD_CANCELLED or USBD_IOERROR would cause corruption 1461 * next time the device is opened. 1462 * 1463 * USBD_CANCELLED is a reported when the device is closed 1464 * via ucomclose() -> usbd_abort_pipe() -> /usbd_xfer_abort() 1465 */ 1466 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_empty); 1467 SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link); 1468 1469 if (status == USBD_CANCELLED || status == USBD_IOERROR || 1470 sc->sc_closing) { 1471 DPRINTF("... done (status %jd closing %jd)", 1472 status, sc->sc_closing, 0, 0); 1473 mutex_exit(&sc->sc_lock); 1474 return; 1475 } 1476 1477 if (status != USBD_NORMAL_COMPLETION) { 1478 if (status == USBD_STALLED) { 1479 usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); 1480 } else { 1481 device_printf(sc->sc_dev, 1482 "ucomreadcb: wonky status=%s\n", 1483 usbd_errstr(status)); 1484 } 1485 1486 DPRINTF("... done (status %jd)", status, 0, 0, 0); 1487 /* re-adds ub to sc_ibuff_empty */ 1488 ucomsubmitread(sc, ub); 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 KDASSERT(cp == ub->ub_data); 1502 1503 rnd_add_uint32(&sc->sc_rndsource, cc); 1504 1505 if (sc->sc_state != UCOM_OPEN) { 1506 /* Go around again - we're not quite ready */ 1507 /* re-adds ub to sc_ibuff_empty */ 1508 ucomsubmitread(sc, ub); 1509 mutex_exit(&sc->sc_lock); 1510 DPRINTF("... done (not open)", 0, 0, 0, 0); 1511 return; 1512 } 1513 1514 mutex_exit(&sc->sc_lock); 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 mutex_enter(&sc->sc_lock); 1525 SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_full, ub, ub_link); 1526 ucom_read_complete(sc); 1527 mutex_exit(&sc->sc_lock); 1528 1529 DPRINTF("... done", 0, 0, 0, 0); 1530 } 1531 1532 static void 1533 ucom_cleanup(struct ucom_softc *sc, int flag) 1534 { 1535 struct tty *tp = sc->sc_tty; 1536 1537 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1538 1539 DPRINTF("closing pipes", 0, 0, 0, 0); 1540 1541 /* 1542 * Close the tty and interrupt any pending opens waiting for 1543 * carrier so they restart or give up. This may flush data. 1544 */ 1545 (*tp->t_linesw->l_close)(tp, flag); 1546 ttyclose(tp); 1547 1548 /* 1549 * Interrupt any pending xfers and cause them to fail promptly. 1550 * New xfers will only be submitted under the lock after 1551 * sc_closing is cleared. 1552 */ 1553 usbd_abort_pipe(sc->sc_bulkin_pipe); 1554 usbd_abort_pipe(sc->sc_bulkout_pipe); 1555 1556 /* 1557 * Hang up the phone and start the timer before we can make a 1558 * call again, if necessary. 1559 */ 1560 ucom_shutdown(sc); 1561 } 1562 1563 #endif /* NUCOM > 0 */ 1564 1565 int 1566 ucomprint(void *aux, const char *pnp) 1567 { 1568 struct ucom_attach_args *ucaa = aux; 1569 1570 if (pnp) 1571 aprint_normal("ucom at %s", pnp); 1572 if (ucaa->ucaa_portno != UCOM_UNK_PORTNO) 1573 aprint_normal(" portno %d", ucaa->ucaa_portno); 1574 return UNCONF; 1575 } 1576 1577 int 1578 ucomsubmatch(device_t parent, cfdata_t cf, 1579 const int *ldesc, void *aux) 1580 { 1581 struct ucom_attach_args *ucaa = aux; 1582 1583 if (ucaa->ucaa_portno != UCOM_UNK_PORTNO && 1584 cf->cf_loc[UCOMBUSCF_PORTNO] != UCOMBUSCF_PORTNO_DEFAULT && 1585 cf->cf_loc[UCOMBUSCF_PORTNO] != ucaa->ucaa_portno) 1586 return 0; 1587 return config_match(parent, cf, aux); 1588 } 1589