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