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