1 /* $NetBSD: ucom.c,v 1.118 2016/12/14 15:11:29 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.118 2016/12/14 15:11:29 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=%d out=%d", sc->sc_bulkin_no, sc->sc_bulkout_no, 310 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 %d), err=%d", 321 sc->sc_bulkin_no, err, 0, 0); 322 error = EIO; 323 goto fail_0; 324 } 325 /* Allocate input buffers */ 326 for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; 327 ub++) { 328 error = usbd_create_xfer(sc->sc_bulkin_pipe, 329 sc->sc_ibufsizepad, USBD_SHORT_XFER_OK, 0, 330 &ub->ub_xfer); 331 if (error) 332 goto fail_1; 333 ub->ub_data = usbd_get_buffer(ub->ub_xfer); 334 } 335 336 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 %d), err=%d", 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 %p", 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=%p flags=%d tp=%p", sc, flags, tp, 0); 407 DPRINTF("... pipe=%d,%d", sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0); 408 409 mutex_enter(&sc->sc_lock); 410 sc->sc_dying = true; 411 mutex_exit(&sc->sc_lock); 412 413 pmf_device_deregister(self); 414 415 if (sc->sc_bulkin_pipe != NULL) 416 usbd_abort_pipe(sc->sc_bulkin_pipe); 417 if (sc->sc_bulkout_pipe != NULL) 418 usbd_abort_pipe(sc->sc_bulkout_pipe); 419 420 mutex_enter(&sc->sc_lock); 421 422 /* wait for open/close to finish */ 423 while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) { 424 int error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock); 425 426 if (error) { 427 mutex_exit(&sc->sc_lock); 428 return error; 429 } 430 } 431 432 sc->sc_refcnt--; 433 while (sc->sc_refcnt > 0) { 434 /* Wake up anyone waiting */ 435 if (tp != NULL) { 436 mutex_spin_enter(&tty_lock); 437 CLR(tp->t_state, TS_CARR_ON); 438 CLR(tp->t_cflag, CLOCAL | MDMBUF); 439 ttyflush(tp, FREAD|FWRITE); 440 mutex_spin_exit(&tty_lock); 441 } 442 /* Wait for processes to go away. */ 443 if (cv_timedwait(&sc->sc_detachcv, &sc->sc_lock, hz * 60)) { 444 printf("%s: %s didn't detach\n", __func__, 445 device_xname(sc->sc_dev)); 446 } 447 } 448 449 softint_disestablish(sc->sc_si); 450 mutex_exit(&sc->sc_lock); 451 452 /* locate the major number */ 453 maj = cdevsw_lookup_major(&ucom_cdevsw); 454 455 /* Nuke the vnodes for any open instances. */ 456 mn = device_unit(self); 457 DPRINTF("maj=%d mn=%d", maj, mn, 0, 0); 458 vdevgone(maj, mn, mn, VCHR); 459 vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR); 460 vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR); 461 462 /* Detach and free the tty. */ 463 if (tp != NULL) { 464 tty_detach(tp); 465 tty_free(tp); 466 sc->sc_tty = NULL; 467 } 468 469 for (i = 0; i < UCOM_IN_BUFFS; i++) { 470 if (sc->sc_ibuff[i].ub_xfer != NULL) 471 usbd_destroy_xfer(sc->sc_ibuff[i].ub_xfer); 472 } 473 474 for (i = 0; i < UCOM_OUT_BUFFS; i++) { 475 if (sc->sc_obuff[i].ub_xfer != NULL) 476 usbd_destroy_xfer(sc->sc_obuff[i].ub_xfer); 477 } 478 479 if (sc->sc_bulkin_pipe != NULL) { 480 usbd_close_pipe(sc->sc_bulkin_pipe); 481 sc->sc_bulkin_pipe = NULL; 482 } 483 484 if (sc->sc_bulkout_pipe != NULL) { 485 usbd_close_pipe(sc->sc_bulkout_pipe); 486 sc->sc_bulkout_pipe = NULL; 487 } 488 489 /* Detach the random source */ 490 rnd_detach_source(&sc->sc_rndsource); 491 492 mutex_destroy(&sc->sc_lock); 493 cv_destroy(&sc->sc_statecv); 494 cv_destroy(&sc->sc_detachcv); 495 496 return 0; 497 } 498 499 int 500 ucom_activate(device_t self, enum devact act) 501 { 502 struct ucom_softc *sc = device_private(self); 503 504 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 505 506 DPRINTFN(5, "%d", act, 0, 0, 0); 507 508 switch (act) { 509 case DVACT_DEACTIVATE: 510 mutex_enter(&sc->sc_lock); 511 sc->sc_dying = true; 512 mutex_exit(&sc->sc_lock); 513 return 0; 514 default: 515 return EOPNOTSUPP; 516 } 517 } 518 519 void 520 ucom_shutdown(struct ucom_softc *sc) 521 { 522 struct tty *tp = sc->sc_tty; 523 524 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 525 526 /* 527 * Hang up if necessary. Wait a bit, so the other side has time to 528 * notice even if we immediately open the port again. 529 */ 530 if (ISSET(tp->t_cflag, HUPCL)) { 531 ucom_dtr(sc, 0); 532 /* XXX will only timeout */ 533 (void) kpause(ttclos, false, hz, NULL); 534 } 535 } 536 537 int 538 ucomopen(dev_t dev, int flag, int mode, struct lwp *l) 539 { 540 const int unit = UCOMUNIT(dev); 541 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 542 int error = 0; 543 544 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 545 546 if (sc == NULL) 547 return ENXIO; 548 549 mutex_enter(&sc->sc_lock); 550 if (sc->sc_dying) { 551 DPRINTF("... dying", 0, 0, 0, 0); 552 mutex_exit(&sc->sc_lock); 553 return EIO; 554 } 555 556 if (!device_is_active(sc->sc_dev)) { 557 mutex_exit(&sc->sc_lock); 558 return ENXIO; 559 } 560 561 struct tty *tp = sc->sc_tty; 562 563 DPRINTF("unit=%d, tp=%p", unit, tp, 0, 0); 564 565 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) { 566 mutex_exit(&sc->sc_lock); 567 return EBUSY; 568 } 569 570 /* 571 * Wait while the device is initialized by the 572 * first opener or cleaned up by the last closer. 573 */ 574 while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) { 575 error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock); 576 577 if (sc->sc_dying) 578 error = EIO; 579 580 if (error) { 581 mutex_exit(&sc->sc_lock); 582 return error; 583 } 584 } 585 enum ucom_state state = sc->sc_state; 586 587 KASSERTMSG(state == UCOM_OPEN || state == UCOM_ATTACHED, 588 "state is %d", state); 589 590 bool cleanup = false; 591 /* If this is the first open then perform the initialisation */ 592 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 593 KASSERT(state == UCOM_ATTACHED); 594 tp->t_dev = dev; 595 cleanup = true; 596 sc->sc_state = UCOM_OPENING; 597 598 mutex_exit(&sc->sc_lock); 599 if (sc->sc_methods->ucom_open != NULL) { 600 error = sc->sc_methods->ucom_open(sc->sc_parent, 601 sc->sc_portno); 602 if (error) { 603 goto fail_2; 604 } 605 } 606 607 ucom_status_change(sc); 608 609 /* Clear PPS capture state on first open. */ 610 mutex_spin_enter(&timecounter_lock); 611 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); 612 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 613 pps_init(&sc->sc_pps_state); 614 mutex_spin_exit(&timecounter_lock); 615 616 /* 617 * Initialize the termios status to the defaults. Add in the 618 * sticky bits from TIOCSFLAGS. 619 */ 620 struct termios t; 621 622 t.c_ispeed = 0; 623 t.c_ospeed = TTYDEF_SPEED; 624 t.c_cflag = TTYDEF_CFLAG; 625 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) 626 SET(t.c_cflag, CLOCAL); 627 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) 628 SET(t.c_cflag, CRTSCTS); 629 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) 630 SET(t.c_cflag, MDMBUF); 631 /* Make sure ucomparam() will do something. */ 632 tp->t_ospeed = 0; 633 (void) ucomparam(tp, &t); 634 tp->t_iflag = TTYDEF_IFLAG; 635 tp->t_oflag = TTYDEF_OFLAG; 636 tp->t_lflag = TTYDEF_LFLAG; 637 ttychars(tp); 638 ttsetwater(tp); 639 640 /* 641 * Turn on DTR. We must always do this, even if carrier is not 642 * present, because otherwise we'd have to use TIOCSDTR 643 * immediately after setting CLOCAL, which applications do not 644 * expect. We always assert DTR while the device is open 645 * unless explicitly requested to deassert it. Ditto RTS. 646 */ 647 ucom_dtr(sc, 1); 648 ucom_rts(sc, 1); 649 650 mutex_enter(&sc->sc_lock); 651 if (sc->sc_dying) { 652 DPRINTF("... dying", 0, 0, 0, 0); 653 error = EIO; 654 goto fail_1; 655 } 656 657 sc->sc_rx_unblock = 0; 658 sc->sc_rx_stopped = 0; 659 sc->sc_tx_stopped = 0; 660 661 for (size_t i = 0; i < UCOM_IN_BUFFS; i++) { 662 struct ucom_buffer *ub = &sc->sc_ibuff[i]; 663 error = ucomsubmitread(sc, ub); 664 if (error) { 665 mutex_exit(&sc->sc_lock); 666 goto fail_2; 667 } 668 } 669 } 670 sc->sc_state = UCOM_OPEN; 671 cv_signal(&sc->sc_statecv); 672 mutex_exit(&sc->sc_lock); 673 674 DPRINTF("unit=%d, tp=%p dialout %d nonblock %d", unit, tp, 675 !!UCOMDIALOUT(dev), !!ISSET(flag, O_NONBLOCK)); 676 error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); 677 if (error) 678 goto bad; 679 680 error = (*tp->t_linesw->l_open)(dev, tp); 681 if (error) 682 goto bad; 683 684 return 0; 685 686 bad: 687 cleanup = !ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0; 688 689 fail_2: 690 if (cleanup) { 691 /* 692 * We failed to open the device, and nobody else had 693 * it opened. Clean up the state as appropriate. 694 */ 695 ucom_cleanup(sc); 696 } 697 698 mutex_enter(&sc->sc_lock); 699 700 fail_1: 701 sc->sc_state = state; 702 cv_signal(&sc->sc_statecv); 703 mutex_exit(&sc->sc_lock); 704 705 return error; 706 } 707 708 int 709 ucomclose(dev_t dev, int flag, int mode, struct lwp *l) 710 { 711 const int unit = UCOMUNIT(dev); 712 struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); 713 int error = 0; 714 715 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 716 717 DPRINTF("unit=%d", UCOMUNIT(dev), 0, 0, 0); 718 719 if (sc == NULL) 720 return 0; 721 722 mutex_enter(&sc->sc_lock); 723 if (sc->sc_dying) { 724 DPRINTF("... dying", 0, 0, 0, 0); 725 mutex_exit(&sc->sc_lock); 726 return ENXIO; 727 } 728 729 /* 730 * Wait until any opens/closes have finished 731 */ 732 while (sc->sc_state == UCOM_OPENING || sc->sc_state == UCOM_CLOSING) { 733 error = cv_wait_sig(&sc->sc_statecv, &sc->sc_lock); 734 735 if (sc->sc_dying) 736 error = EIO; 737 738 if (error) { 739 mutex_exit(&sc->sc_lock); 740 return error; 741 } 742 } 743 744 struct tty *tp = sc->sc_tty; 745 746 if (!ISSET(tp->t_state, TS_ISOPEN)) { 747 KASSERT(sc->sc_state == UCOM_ATTACHED); 748 mutex_exit(&sc->sc_lock); 749 return 0; 750 } 751 752 KASSERT(sc->sc_state == UCOM_OPEN); 753 sc->sc_state = UCOM_CLOSING; 754 mutex_exit(&sc->sc_lock); 755 756 (*tp->t_linesw->l_close)(tp, flag); 757 ttyclose(tp); 758 759 /* state when we're done - default to open */ 760 enum ucom_state state = UCOM_OPEN; 761 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 762 /* 763 * Although we got a last close, the device may still be in 764 * use; e.g. if this was the dialout node, and there are still 765 * processes waiting for carrier on the non-dialout node. 766 */ 767 ucom_cleanup(sc); 768 if (sc->sc_methods->ucom_close != NULL) 769 sc->sc_methods->ucom_close(sc->sc_parent, 770 sc->sc_portno); 771 state = UCOM_ATTACHED; 772 } 773 774 mutex_enter(&sc->sc_lock); 775 sc->sc_state = state; 776 cv_signal(&sc->sc_statecv); 777 mutex_exit(&sc->sc_lock); 778 779 return error; 780 } 781 782 int 783 ucomread(dev_t dev, struct uio *uio, int flag) 784 { 785 const int unit = UCOMUNIT(dev); 786 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 787 int error; 788 789 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 790 791 if (sc == NULL) 792 return EIO; 793 794 mutex_enter(&sc->sc_lock); 795 if (sc->sc_dying) { 796 DPRINTF("... dying", 0, 0, 0, 0); 797 mutex_exit(&sc->sc_lock); 798 return EIO; 799 } 800 801 struct tty *tp = sc->sc_tty; 802 803 sc->sc_refcnt++; 804 mutex_exit(&sc->sc_lock); 805 806 error = ((*tp->t_linesw->l_read)(tp, uio, flag)); 807 808 mutex_enter(&sc->sc_lock); 809 if (--sc->sc_refcnt < 0) 810 cv_broadcast(&sc->sc_detachcv); 811 DPRINTF("unit=%d refcnt %d", UCOMUNIT(dev), sc->sc_refcnt, 0, 0); 812 mutex_exit(&sc->sc_lock); 813 814 return error; 815 } 816 817 int 818 ucomwrite(dev_t dev, struct uio *uio, int flag) 819 { 820 const int unit = UCOMUNIT(dev); 821 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 822 int error; 823 824 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 825 826 if (sc == NULL) 827 return EIO; 828 829 mutex_enter(&sc->sc_lock); 830 if (sc->sc_dying) { 831 DPRINTF("... dying", 0, 0, 0, 0); 832 mutex_exit(&sc->sc_lock); 833 return EIO; 834 } 835 836 struct tty *tp = sc->sc_tty; 837 838 sc->sc_refcnt++; 839 mutex_exit(&sc->sc_lock); 840 841 error = ((*tp->t_linesw->l_write)(tp, uio, flag)); 842 843 mutex_enter(&sc->sc_lock); 844 if (--sc->sc_refcnt < 0) 845 cv_broadcast(&sc->sc_detachcv); 846 DPRINTF("unit=%d refcnt %d", UCOMUNIT(dev), sc->sc_refcnt, 0, 0); 847 mutex_exit(&sc->sc_lock); 848 849 return error; 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 858 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 859 860 if (sc == NULL) 861 return POLLHUP; 862 863 mutex_enter(&sc->sc_lock); 864 if (sc->sc_dying) { 865 DPRINTF("... dying", 0, 0, 0, 0); 866 mutex_exit(&sc->sc_lock); 867 return POLLHUP; 868 } 869 struct tty *tp = sc->sc_tty; 870 871 sc->sc_refcnt++; 872 mutex_exit(&sc->sc_lock); 873 874 int revents = ((*tp->t_linesw->l_poll)(tp, events, l)); 875 876 mutex_enter(&sc->sc_lock); 877 if (--sc->sc_refcnt < 0) 878 cv_broadcast(&sc->sc_detachcv); 879 DPRINTF("unit=%d refcnt %d", UCOMUNIT(dev), sc->sc_refcnt, 0, 0); 880 mutex_exit(&sc->sc_lock); 881 882 return revents; 883 } 884 885 struct tty * 886 ucomtty(dev_t dev) 887 { 888 const int unit = UCOMUNIT(dev); 889 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 890 891 return sc != NULL ? sc->sc_tty : NULL; 892 } 893 894 int 895 ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 896 { 897 const int unit = UCOMUNIT(dev); 898 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 899 int error; 900 901 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 902 903 if (sc == NULL) 904 return EIO; 905 906 mutex_enter(&sc->sc_lock); 907 if (sc->sc_dying) { 908 DPRINTF("... dying", 0, 0, 0, 0); 909 mutex_exit(&sc->sc_lock); 910 return EIO; 911 } 912 913 sc->sc_refcnt++; 914 mutex_exit(&sc->sc_lock); 915 916 error = ucom_do_ioctl(sc, cmd, data, flag, l); 917 918 mutex_enter(&sc->sc_lock); 919 if (--sc->sc_refcnt < 0) 920 cv_broadcast(&sc->sc_detachcv); 921 DPRINTF("unit=%d refcnt %d", UCOMUNIT(dev), sc->sc_refcnt, 0, 0); 922 mutex_exit(&sc->sc_lock); 923 924 return error; 925 } 926 927 static int 928 ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, int flag, 929 struct lwp *l) 930 { 931 struct tty *tp = sc->sc_tty; 932 int error; 933 934 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 935 936 DPRINTF("cmd=0x%08lx", cmd, 0, 0, 0); 937 938 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 939 if (error != EPASSTHROUGH) 940 return error; 941 942 error = ttioctl(tp, cmd, data, flag, l); 943 if (error != EPASSTHROUGH) 944 return error; 945 946 if (sc->sc_methods->ucom_ioctl != NULL) { 947 error = sc->sc_methods->ucom_ioctl(sc->sc_parent, 948 sc->sc_portno, cmd, data, flag, l->l_proc); 949 if (error != EPASSTHROUGH) 950 return error; 951 } 952 953 error = 0; 954 955 DPRINTF("our cmd=0x%08lx", cmd, 0, 0, 0); 956 957 switch (cmd) { 958 case TIOCSBRK: 959 ucom_break(sc, 1); 960 break; 961 962 case TIOCCBRK: 963 ucom_break(sc, 0); 964 break; 965 966 case TIOCSDTR: 967 ucom_dtr(sc, 1); 968 break; 969 970 case TIOCCDTR: 971 ucom_dtr(sc, 0); 972 break; 973 974 case TIOCGFLAGS: 975 mutex_enter(&sc->sc_lock); 976 *(int *)data = sc->sc_swflags; 977 mutex_exit(&sc->sc_lock); 978 break; 979 980 case TIOCSFLAGS: 981 error = kauth_authorize_device_tty(l->l_cred, 982 KAUTH_DEVICE_TTY_PRIVSET, tp); 983 if (error) 984 break; 985 mutex_enter(&sc->sc_lock); 986 sc->sc_swflags = *(int *)data; 987 mutex_exit(&sc->sc_lock); 988 break; 989 990 case TIOCMSET: 991 case TIOCMBIS: 992 case TIOCMBIC: 993 tiocm_to_ucom(sc, cmd, *(int *)data); 994 break; 995 996 case TIOCMGET: 997 *(int *)data = ucom_to_tiocm(sc); 998 break; 999 1000 case PPS_IOC_CREATE: 1001 case PPS_IOC_DESTROY: 1002 case PPS_IOC_GETPARAMS: 1003 case PPS_IOC_SETPARAMS: 1004 case PPS_IOC_GETCAP: 1005 case PPS_IOC_FETCH: 1006 #ifdef PPS_SYNC 1007 case PPS_IOC_KCBIND: 1008 #endif 1009 mutex_spin_enter(&timecounter_lock); 1010 error = pps_ioctl(cmd, data, &sc->sc_pps_state); 1011 mutex_spin_exit(&timecounter_lock); 1012 break; 1013 1014 default: 1015 error = EPASSTHROUGH; 1016 break; 1017 } 1018 1019 return error; 1020 } 1021 1022 static void 1023 tiocm_to_ucom(struct ucom_softc *sc, u_long how, int ttybits) 1024 { 1025 u_char combits; 1026 1027 combits = 0; 1028 if (ISSET(ttybits, TIOCM_DTR)) 1029 SET(combits, UMCR_DTR); 1030 if (ISSET(ttybits, TIOCM_RTS)) 1031 SET(combits, UMCR_RTS); 1032 1033 mutex_enter(&sc->sc_lock); 1034 switch (how) { 1035 case TIOCMBIC: 1036 CLR(sc->sc_mcr, combits); 1037 break; 1038 1039 case TIOCMBIS: 1040 SET(sc->sc_mcr, combits); 1041 break; 1042 1043 case TIOCMSET: 1044 CLR(sc->sc_mcr, UMCR_DTR | UMCR_RTS); 1045 SET(sc->sc_mcr, combits); 1046 break; 1047 } 1048 u_char mcr = sc->sc_mcr; 1049 mutex_exit(&sc->sc_lock); 1050 1051 if (how == TIOCMSET || ISSET(combits, UMCR_DTR)) 1052 ucom_dtr(sc, (mcr & UMCR_DTR) != 0); 1053 if (how == TIOCMSET || ISSET(combits, UMCR_RTS)) 1054 ucom_rts(sc, (mcr & UMCR_RTS) != 0); 1055 } 1056 1057 static int 1058 ucom_to_tiocm(struct ucom_softc *sc) 1059 { 1060 u_char combits; 1061 int ttybits = 0; 1062 1063 mutex_enter(&sc->sc_lock); 1064 combits = sc->sc_mcr; 1065 if (ISSET(combits, UMCR_DTR)) 1066 SET(ttybits, TIOCM_DTR); 1067 if (ISSET(combits, UMCR_RTS)) 1068 SET(ttybits, TIOCM_RTS); 1069 1070 combits = sc->sc_msr; 1071 if (ISSET(combits, UMSR_DCD)) 1072 SET(ttybits, TIOCM_CD); 1073 if (ISSET(combits, UMSR_CTS)) 1074 SET(ttybits, TIOCM_CTS); 1075 if (ISSET(combits, UMSR_DSR)) 1076 SET(ttybits, TIOCM_DSR); 1077 if (ISSET(combits, UMSR_RI | UMSR_TERI)) 1078 SET(ttybits, TIOCM_RI); 1079 1080 #if 0 1081 XXX; 1082 if (sc->sc_ier != 0) 1083 SET(ttybits, TIOCM_LE); 1084 #endif 1085 mutex_exit(&sc->sc_lock); 1086 1087 return ttybits; 1088 } 1089 1090 static void 1091 ucom_break(struct ucom_softc *sc, int onoff) 1092 { 1093 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1094 1095 DPRINTF("onoff=%d", onoff, 0, 0, 0); 1096 1097 if (sc->sc_methods->ucom_set != NULL) 1098 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1099 UCOM_SET_BREAK, onoff); 1100 } 1101 1102 static void 1103 ucom_dtr(struct ucom_softc *sc, int onoff) 1104 { 1105 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1106 1107 DPRINTF("onoff=%d", onoff, 0, 0, 0); 1108 1109 if (sc->sc_methods->ucom_set != NULL) 1110 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1111 UCOM_SET_DTR, onoff); 1112 } 1113 1114 static void 1115 ucom_rts(struct ucom_softc *sc, int onoff) 1116 { 1117 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1118 1119 DPRINTF("onoff=%d", onoff, 0, 0, 0); 1120 1121 if (sc->sc_methods->ucom_set != NULL) 1122 sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, 1123 UCOM_SET_RTS, onoff); 1124 } 1125 1126 void 1127 ucom_status_change(struct ucom_softc *sc) 1128 { 1129 struct tty *tp = sc->sc_tty; 1130 1131 if (sc->sc_methods->ucom_get_status != NULL) { 1132 u_char msr, lsr; 1133 1134 sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno, 1135 &lsr, &msr); 1136 mutex_enter(&sc->sc_lock); 1137 u_char old_msr = sc->sc_msr; 1138 1139 sc->sc_lsr = lsr; 1140 sc->sc_msr = msr; 1141 mutex_exit(&sc->sc_lock); 1142 1143 if (ISSET((msr ^ old_msr), UMSR_DCD)) { 1144 mutex_spin_enter(&timecounter_lock); 1145 pps_capture(&sc->sc_pps_state); 1146 pps_event(&sc->sc_pps_state, 1147 (sc->sc_msr & UMSR_DCD) ? 1148 PPS_CAPTUREASSERT : 1149 PPS_CAPTURECLEAR); 1150 mutex_spin_exit(&timecounter_lock); 1151 1152 (*tp->t_linesw->l_modem)(tp, ISSET(msr, UMSR_DCD)); 1153 } 1154 } else { 1155 mutex_enter(&sc->sc_lock); 1156 sc->sc_lsr = 0; 1157 /* Assume DCD is present, if we have no chance to check it. */ 1158 sc->sc_msr = UMSR_DCD; 1159 mutex_exit(&sc->sc_lock); 1160 } 1161 } 1162 1163 static int 1164 ucomparam(struct tty *tp, struct termios *t) 1165 { 1166 const int unit = UCOMUNIT(tp->t_dev); 1167 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1168 int error = 0; 1169 1170 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1171 1172 if (sc == NULL) 1173 return EIO; 1174 1175 mutex_enter(&sc->sc_lock); 1176 if (sc->sc_dying) { 1177 DPRINTF("... dying", 0, 0, 0, 0); 1178 mutex_exit(&sc->sc_lock); 1179 return EIO; 1180 } 1181 1182 sc->sc_refcnt++; 1183 mutex_exit(&sc->sc_lock); 1184 1185 /* Check requested parameters. */ 1186 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) { 1187 error = EINVAL; 1188 goto out; 1189 } 1190 1191 /* 1192 * For the console, always force CLOCAL and !HUPCL, so that the port 1193 * is always active. 1194 */ 1195 if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR)) { 1196 SET(t->c_cflag, CLOCAL); 1197 CLR(t->c_cflag, HUPCL); 1198 } 1199 1200 /* 1201 * If there were no changes, don't do anything. This avoids dropping 1202 * input and improves performance when all we did was frob things like 1203 * VMIN and VTIME. 1204 */ 1205 if (tp->t_ospeed == t->c_ospeed && 1206 tp->t_cflag == t->c_cflag) { 1207 goto out; 1208 } 1209 1210 /* XXX lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); */ 1211 1212 /* And copy to tty. */ 1213 tp->t_ispeed = 0; 1214 tp->t_ospeed = t->c_ospeed; 1215 tp->t_cflag = t->c_cflag; 1216 1217 if (sc->sc_methods->ucom_param != NULL) { 1218 error = sc->sc_methods->ucom_param(sc->sc_parent, sc->sc_portno, 1219 t); 1220 if (error) 1221 goto out; 1222 } 1223 1224 /* XXX worry about CHWFLOW */ 1225 1226 /* 1227 * Update the tty layer's idea of the carrier bit, in case we changed 1228 * CLOCAL or MDMBUF. We don't hang up here; we only do that by 1229 * explicit request. 1230 */ 1231 DPRINTF("l_modem", 0, 0, 0, 0); 1232 (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD)); 1233 1234 #if 0 1235 XXX what if the hardware is not open 1236 if (!ISSET(t->c_cflag, CHWFLOW)) { 1237 if (sc->sc_tx_stopped) { 1238 sc->sc_tx_stopped = 0; 1239 ucomstart(tp); 1240 } 1241 } 1242 #endif 1243 out: 1244 mutex_enter(&sc->sc_lock); 1245 if (--sc->sc_refcnt < 0) 1246 cv_broadcast(&sc->sc_detachcv); 1247 DPRINTF("unit=%d refcnt %d", UCOMUNIT(tp->t_dev), sc->sc_refcnt, 0, 0); 1248 1249 mutex_exit(&sc->sc_lock); 1250 1251 return 0; 1252 } 1253 1254 static int 1255 ucomhwiflow(struct tty *tp, int block) 1256 { 1257 const int unit = UCOMUNIT(tp->t_dev); 1258 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1259 int old; 1260 1261 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1262 1263 if (sc == NULL) 1264 return 0; 1265 1266 mutex_enter(&sc->sc_lock); 1267 old = sc->sc_rx_stopped; 1268 sc->sc_rx_stopped = (u_char)block; 1269 1270 if (old && !block) { 1271 sc->sc_rx_unblock = 1; 1272 softint_schedule(sc->sc_si); 1273 } 1274 mutex_exit(&sc->sc_lock); 1275 1276 return 1; 1277 } 1278 1279 static void 1280 ucomstart(struct tty *tp) 1281 { 1282 const int unit = UCOMUNIT(tp->t_dev); 1283 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1284 struct ucom_buffer *ub; 1285 u_char *data; 1286 int cnt; 1287 1288 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1289 1290 if (sc == NULL) 1291 return; 1292 1293 KASSERT(&sc->sc_lock); 1294 KASSERT(mutex_owned(&tty_lock)); 1295 if (sc->sc_dying) { 1296 DPRINTF("... dying", 0, 0, 0, 0); 1297 return; 1298 } 1299 1300 if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) 1301 goto out; 1302 if (sc->sc_tx_stopped) 1303 goto out; 1304 1305 if (!ttypull(tp)) 1306 goto out; 1307 1308 /* Grab the first contiguous region of buffer space. */ 1309 data = tp->t_outq.c_cf; 1310 cnt = ndqb(&tp->t_outq, 0); 1311 1312 if (cnt == 0) 1313 goto out; 1314 1315 ub = SIMPLEQ_FIRST(&sc->sc_obuff_free); 1316 if (ub == NULL) { 1317 SET(tp->t_state, TS_BUSY); 1318 goto out; 1319 } 1320 1321 SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link); 1322 1323 if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL) 1324 SET(tp->t_state, TS_BUSY); 1325 1326 if (cnt > sc->sc_obufsize) 1327 cnt = sc->sc_obufsize; 1328 1329 if (sc->sc_methods->ucom_write != NULL) 1330 sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno, 1331 ub->ub_data, data, &cnt); 1332 else 1333 memcpy(ub->ub_data, data, cnt); 1334 1335 ub->ub_len = cnt; 1336 ub->ub_index = 0; 1337 1338 SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_full, ub, ub_link); 1339 1340 softint_schedule(sc->sc_si); 1341 1342 out: 1343 DPRINTF("... done", 0, 0, 0, 0); 1344 return; 1345 } 1346 1347 void 1348 ucomstop(struct tty *tp, int flag) 1349 { 1350 #if 0 1351 const int unit = UCOMUNIT(tp->t_dev); 1352 struct ucom_softc * const sc = device_lookup_private(&ucom_cd, unit); 1353 1354 mutex_enter(&sc->sc_lock); 1355 mutex_spin_enter(&tty_lock); 1356 if (ISSET(tp->t_state, TS_BUSY)) { 1357 /* obuff_full -> obuff_free? */ 1358 /* sc->sc_tx_stopped = 1; */ 1359 if (!ISSET(tp->t_state, TS_TTSTOP)) 1360 SET(tp->t_state, TS_FLUSH); 1361 } 1362 mutex_spin_exit(&tty_lock); 1363 mutex_exit(&sc->sc_lock); 1364 #endif 1365 } 1366 1367 static void 1368 ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub, 1369 usbd_status err) 1370 { 1371 struct tty *tp = sc->sc_tty; 1372 uint32_t cc = ub->ub_len; 1373 1374 KASSERT(mutex_owned(&sc->sc_lock)); 1375 1376 switch (err) { 1377 case USBD_IN_PROGRESS: 1378 ub->ub_index = ub->ub_len; 1379 break; 1380 case USBD_STALLED: 1381 ub->ub_index = 0; 1382 softint_schedule(sc->sc_si); 1383 break; 1384 case USBD_NORMAL_COMPLETION: 1385 usbd_get_xfer_status(ub->ub_xfer, NULL, NULL, &cc, NULL); 1386 rnd_add_uint32(&sc->sc_rndsource, cc); 1387 /*FALLTHROUGH*/ 1388 default: 1389 SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_full, ub_link); 1390 SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); 1391 cc -= sc->sc_opkthdrlen; 1392 1393 mutex_spin_enter(&tty_lock); 1394 CLR(tp->t_state, TS_BUSY); 1395 if (ISSET(tp->t_state, TS_FLUSH)) 1396 CLR(tp->t_state, TS_FLUSH); 1397 else 1398 ndflush(&tp->t_outq, cc); 1399 mutex_spin_exit(&tty_lock); 1400 1401 if (err != USBD_CANCELLED && err != USBD_IOERROR && 1402 !sc->sc_dying) { 1403 if ((ub = SIMPLEQ_FIRST(&sc->sc_obuff_full)) != NULL) 1404 ucom_submit_write(sc, ub); 1405 1406 mutex_spin_enter(&tty_lock); 1407 (*tp->t_linesw->l_start)(tp); 1408 mutex_spin_exit(&tty_lock); 1409 } 1410 break; 1411 } 1412 } 1413 1414 static void 1415 ucom_submit_write(struct ucom_softc *sc, struct ucom_buffer *ub) 1416 { 1417 1418 KASSERT(mutex_owned(&sc->sc_lock)); 1419 1420 usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, ub->ub_len, 1421 0, USBD_NO_TIMEOUT, ucomwritecb); 1422 1423 ucom_write_status(sc, ub, usbd_transfer(ub->ub_xfer)); 1424 } 1425 1426 static void 1427 ucomwritecb(struct usbd_xfer *xfer, void *p, usbd_status status) 1428 { 1429 struct ucom_softc *sc = (struct ucom_softc *)p; 1430 1431 mutex_enter(&sc->sc_lock); 1432 ucom_write_status(sc, SIMPLEQ_FIRST(&sc->sc_obuff_full), status); 1433 mutex_exit(&sc->sc_lock); 1434 1435 } 1436 1437 static void 1438 ucom_softintr(void *arg) 1439 { 1440 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1441 1442 struct ucom_softc *sc = arg; 1443 1444 mutex_enter(&sc->sc_lock); 1445 if (sc->sc_dying) { 1446 DPRINTF("... dying", 0, 0, 0, 0); 1447 mutex_exit(&sc->sc_lock); 1448 return; 1449 } 1450 1451 struct tty *tp = sc->sc_tty; 1452 mutex_enter(&tty_lock); 1453 if (!ISSET(tp->t_state, TS_ISOPEN)) { 1454 mutex_exit(&tty_lock); 1455 mutex_exit(&sc->sc_lock); 1456 return; 1457 } 1458 mutex_exit(&tty_lock); 1459 1460 struct ucom_buffer *ub = SIMPLEQ_FIRST(&sc->sc_obuff_full); 1461 1462 if (ub != NULL && ub->ub_index == 0) 1463 ucom_submit_write(sc, ub); 1464 1465 if (sc->sc_rx_unblock) 1466 ucom_read_complete(sc); 1467 1468 mutex_exit(&sc->sc_lock); 1469 } 1470 1471 static void 1472 ucom_read_complete(struct ucom_softc *sc) 1473 { 1474 int (*rint)(int, struct tty *); 1475 struct ucom_buffer *ub; 1476 struct tty *tp; 1477 1478 KASSERT(mutex_owned(&sc->sc_lock)); 1479 1480 tp = sc->sc_tty; 1481 rint = tp->t_linesw->l_rint; 1482 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); 1483 1484 while (ub != NULL && !sc->sc_rx_stopped) { 1485 1486 /* XXX ttyinput takes tty_lock */ 1487 while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) { 1488 /* Give characters to tty layer. */ 1489 if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) { 1490 /* Overflow: drop remainder */ 1491 ub->ub_index = ub->ub_len; 1492 } else 1493 ub->ub_index++; 1494 } 1495 1496 if (ub->ub_index == ub->ub_len) { 1497 SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link); 1498 1499 sc->sc_refcnt--; 1500 /* increments sc_refcnt */ 1501 ucomsubmitread(sc, ub); 1502 1503 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_full); 1504 } 1505 } 1506 1507 sc->sc_rx_unblock = (ub != NULL); 1508 } 1509 1510 static int 1511 ucomsubmitread(struct ucom_softc *sc, struct ucom_buffer *ub) 1512 { 1513 usbd_status err; 1514 1515 KASSERT(mutex_owned(&sc->sc_lock)); 1516 1517 usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize, 1518 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb); 1519 1520 if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) { 1521 /* XXX: Recover from this, please! */ 1522 printf("%s: err=%s\n", __func__, usbd_errstr(err)); 1523 return EIO; 1524 } 1525 1526 sc->sc_refcnt++; 1527 1528 SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link); 1529 1530 return 0; 1531 } 1532 1533 static void 1534 ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status) 1535 { 1536 struct ucom_softc *sc = (struct ucom_softc *)p; 1537 struct ucom_buffer *ub; 1538 uint32_t cc; 1539 u_char *cp; 1540 1541 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1542 1543 mutex_enter(&sc->sc_lock); 1544 1545 struct tty *tp = sc->sc_tty; 1546 1547 if (status == USBD_CANCELLED || status == USBD_IOERROR || 1548 sc->sc_dying) { 1549 1550 DPRINTF("... done (status %d dying %d)", status, sc->sc_dying, 1551 0, 0); 1552 1553 if (status == USBD_IOERROR || sc->sc_dying) { 1554 /* Send something to wake upper layer */ 1555 (tp->t_linesw->l_rint)('\n', tp); 1556 mutex_spin_enter(&tty_lock); /* XXX */ 1557 ttwakeup(tp); 1558 mutex_spin_exit(&tty_lock); /* XXX */ 1559 } 1560 1561 if (--sc->sc_refcnt < 0) 1562 cv_broadcast(&sc->sc_detachcv); 1563 DPRINTF("unit=%d refcnt %d", UCOMUNIT(tp->t_dev), sc->sc_refcnt, 1564 0, 0); 1565 mutex_exit(&sc->sc_lock); 1566 1567 return; 1568 } 1569 1570 ub = SIMPLEQ_FIRST(&sc->sc_ibuff_empty); 1571 SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link); 1572 1573 if (status != USBD_NORMAL_COMPLETION) { 1574 if (status == USBD_STALLED) { 1575 usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); 1576 } else { 1577 printf("ucomreadcb: wonky status=%s\n", 1578 usbd_errstr(status)); 1579 } 1580 1581 DPRINTF("... done (status %d)", status, 0, 0, 0); 1582 sc->sc_refcnt--; 1583 /* re-adds ub to sc_ibuff_empty and increments sc_refcnt */ 1584 ucomsubmitread(sc, ub); 1585 mutex_exit(&sc->sc_lock); 1586 return; 1587 } 1588 1589 usbd_get_xfer_status(xfer, NULL, (void *)&cp, &cc, NULL); 1590 1591 #ifdef UCOM_DEBUG 1592 /* This is triggered by uslsa(4) occasionally. */ 1593 if ((ucomdebug > 0) && (cc == 0)) { 1594 device_printf(sc->sc_dev, "ucomreadcb: zero length xfer!\n"); 1595 } 1596 #endif 1597 KDASSERT(cp == ub->ub_data); 1598 1599 rnd_add_uint32(&sc->sc_rndsource, cc); 1600 1601 if (sc->sc_state != UCOM_OPEN) { 1602 /* Go around again - we're not quite ready */ 1603 sc->sc_refcnt--; 1604 /* re-adds ub to sc_ibuff_empty and increments sc_refcnt */ 1605 ucomsubmitread(sc, ub); 1606 mutex_exit(&sc->sc_lock); 1607 DPRINTF("... done (not open)", 0, 0, 0, 0); 1608 return; 1609 } 1610 1611 mutex_exit(&sc->sc_lock); 1612 if (sc->sc_methods->ucom_read != NULL) { 1613 sc->sc_methods->ucom_read(sc->sc_parent, sc->sc_portno, 1614 &cp, &cc); 1615 ub->ub_index = (u_int)(cp - ub->ub_data); 1616 } else 1617 ub->ub_index = 0; 1618 1619 ub->ub_len = cc; 1620 1621 mutex_enter(&sc->sc_lock); 1622 if (sc->sc_dying) { 1623 if (--sc->sc_refcnt < 0) 1624 cv_broadcast(&sc->sc_detachcv); 1625 mutex_exit(&sc->sc_lock); 1626 DPRINTF("... dying", 0, 0, 0, 0); 1627 return; 1628 } 1629 1630 SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_full, ub, ub_link); 1631 1632 ucom_read_complete(sc); 1633 mutex_exit(&sc->sc_lock); 1634 1635 DPRINTF("... done", 0, 0, 0, 0); 1636 } 1637 1638 static void 1639 ucom_cleanup(struct ucom_softc *sc) 1640 { 1641 1642 UCOMHIST_FUNC(); UCOMHIST_CALLED(); 1643 1644 DPRINTF("aborting pipes", 0, 0, 0, 0); 1645 1646 mutex_enter(&sc->sc_lock); 1647 1648 /* If we're dying then the detach routine will abort our pipes, etc */ 1649 if (sc->sc_dying) { 1650 DPRINTF("... dying", 0, 0, 0, 0); 1651 1652 mutex_exit(&sc->sc_lock); 1653 return; 1654 } 1655 1656 mutex_exit(&sc->sc_lock); 1657 1658 ucom_shutdown(sc); 1659 1660 if (sc->sc_bulkin_pipe != NULL) { 1661 usbd_abort_pipe(sc->sc_bulkin_pipe); 1662 } 1663 if (sc->sc_bulkout_pipe != NULL) { 1664 usbd_abort_pipe(sc->sc_bulkout_pipe); 1665 } 1666 } 1667 1668 #endif /* NUCOM > 0 */ 1669 1670 int 1671 ucomprint(void *aux, const char *pnp) 1672 { 1673 struct ucom_attach_args *ucaa = aux; 1674 1675 if (pnp) 1676 aprint_normal("ucom at %s", pnp); 1677 if (ucaa->ucaa_portno != UCOM_UNK_PORTNO) 1678 aprint_normal(" portno %d", ucaa->ucaa_portno); 1679 return UNCONF; 1680 } 1681 1682 int 1683 ucomsubmatch(device_t parent, cfdata_t cf, 1684 const int *ldesc, void *aux) 1685 { 1686 struct ucom_attach_args *ucaa = aux; 1687 1688 if (ucaa->ucaa_portno != UCOM_UNK_PORTNO && 1689 cf->cf_loc[UCOMBUSCF_PORTNO] != UCOMBUSCF_PORTNO_DEFAULT && 1690 cf->cf_loc[UCOMBUSCF_PORTNO] != ucaa->ucaa_portno) 1691 return 0; 1692 return config_match(parent, cf, aux); 1693 } 1694