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