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