Lines Matching +full:enable +full:- +full:ssc
3 /*-
4 * SPDX-License-Identifier: BSD-2-Clause
6 * Copyright (c) 2001-2003, 2005, 2008
33 /*-
131 static int ucom_cons_unit = -1;
200 ucom_unrhdr = new_unrhdr(0, UCOM_UNIT_MAX - 1, NULL);
203 SYSINIT(ucom_init, SI_SUB_KLD - 1, SI_ORDER_ANY, ucom_init, NULL);
219 SYSUNINIT(ucom_uninit, SI_SUB_KLD - 3, SI_ORDER_ANY, ucom_uninit, NULL);
235 return (-1);
262 * before calling into the ucom-layer!
265 ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
280 ssc->sc_unit = ucom_unit_alloc();
281 if (ssc->sc_unit == -1)
285 snprintf(ssc->sc_ttyname, sizeof(ssc->sc_ttyname),
286 UCOM_TTY_PREFIX "%d", ssc->sc_unit);
289 error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED);
291 ucom_unit_free(ssc->sc_unit);
294 ssc->sc_subunits = subunits;
295 ssc->sc_flag = UCOM_FLAG_ATTACHED |
296 UCOM_FLAG_FREE_UNIT | (ssc->sc_flag & UCOM_FLAG_DEVICE_MODE);
298 if (callback->ucom_free == NULL)
299 ssc->sc_flag |= UCOM_FLAG_WAIT_REFS;
302 ucom_ref(ssc);
304 for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
306 sc[subunit].sc_super = ssc;
311 error = ucom_attach_tty(ssc, &sc[subunit]);
313 ucom_detach(ssc, &sc[0]);
317 ucom_ref(ssc);
324 sc->sc_tty, ssc->sc_unit, ssc->sc_subunits);
331 * by "ssc" and "sc" is zero or has already been detached.
334 ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc)
338 if (!(ssc->sc_flag & UCOM_FLAG_ATTACHED))
341 if (ssc->sc_sysctl_ttyname != NULL) {
342 sysctl_remove_oid(ssc->sc_sysctl_ttyname, 1, 0);
343 ssc->sc_sysctl_ttyname = NULL;
346 if (ssc->sc_sysctl_ttyports != NULL) {
347 sysctl_remove_oid(ssc->sc_sysctl_ttyports, 1, 0);
348 ssc->sc_sysctl_ttyports = NULL;
351 usb_proc_drain(&ssc->sc_tq);
353 for (subunit = 0; subunit < ssc->sc_subunits; subunit++) {
355 ucom_detach_tty(ssc, &sc[subunit]);
361 usb_proc_free(&ssc->sc_tq);
363 ucom_unref(ssc);
365 if (ssc->sc_flag & UCOM_FLAG_WAIT_REFS)
366 ucom_drain(ssc);
369 ssc->sc_flag &= ~UCOM_FLAG_ATTACHED;
373 ucom_drain(struct ucom_super_softc *ssc)
376 while (ssc->sc_refs > 0) {
414 ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
419 tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx);
425 if (sc->sc_callback->ucom_tty_name) {
426 sc->sc_callback->ucom_tty_name(sc, buf,
427 sizeof(buf), ssc->sc_unit, sc->sc_subunit);
431 if (ssc->sc_subunits > 1) {
434 ssc->sc_unit, sc->sc_subunit);
438 ssc->sc_unit);
443 sc->sc_tty = tp;
445 sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
446 sc->sc_pps.driver_abi = PPS_ABI_VERSION;
447 sc->sc_pps.driver_mtx = sc->sc_mtx;
448 pps_init_abi(&sc->sc_pps);
454 (ssc->sc_unit == ucom_cons_unit) &&
455 (sc->sc_subunit == ucom_cons_subunit)) {
457 ssc->sc_unit, sc->sc_subunit);
468 sc->sc_flag |= UCOM_FLAG_CONSOLE;
469 ucom_open(ucom_cons_softc->sc_tty);
470 ucom_param(ucom_cons_softc->sc_tty, &tp->t_termios_init_in);
474 if ((ssc->sc_flag & UCOM_FLAG_DEVICE_MODE) != 0 &&
481 cp->cn_ops = &ucom_cnops;
482 cp->cn_arg = NULL;
483 cp->cn_pri = CN_NORMAL;
484 strlcpy(cp->cn_name, "tty", sizeof(cp->cn_name));
485 strlcat(cp->cn_name, buf, sizeof(cp->cn_name));
487 sc->sc_consdev = cp;
496 ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
498 struct tty *tp = sc->sc_tty;
500 DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty);
502 if (sc->sc_consdev != NULL) {
503 cnremove(sc->sc_consdev);
504 free(sc->sc_consdev, M_USBDEV);
505 sc->sc_consdev = NULL;
508 if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
510 ucom_close(ucom_cons_softc->sc_tty);
511 sc->sc_flag &= ~UCOM_FLAG_CONSOLE;
519 sc->sc_flag |= UCOM_FLAG_GONE;
520 sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY);
538 if (sc->sc_callback->ucom_stop_read)
539 (sc->sc_callback->ucom_stop_read) (sc);
540 if (sc->sc_callback->ucom_stop_write)
541 (sc->sc_callback->ucom_stop_write) (sc);
547 ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
554 "%d ttyports=%d", ssc->sc_unit, ssc->sc_subunits);
558 iface_index = uaa->info.bIfaceIndex;
560 if (usbd_set_pnpinfo(uaa->device, iface_index, buf) != 0)
564 * The following information is also replicated in the PNP-info
567 if (ssc->sc_sysctl_ttyname == NULL) {
568 ssc->sc_sysctl_ttyname = SYSCTL_ADD_STRING(NULL,
570 OID_AUTO, "ttyname", CTLFLAG_RD, ssc->sc_ttyname, 0,
573 if (ssc->sc_sysctl_ttyports == NULL) {
574 ssc->sc_sysctl_ttyports = SYSCTL_ADD_INT(NULL,
577 NULL, ssc->sc_subunits, "Number of ports");
582 ucom_set_usb_mode(struct ucom_super_softc *ssc, enum usb_hc_mode usb_mode)
587 ssc->sc_flag |= UCOM_FLAG_DEVICE_MODE;
590 ssc->sc_flag &= ~UCOM_FLAG_DEVICE_MODE;
609 struct ucom_super_softc *ssc = sc->sc_super;
616 if (usb_proc_is_gone(&ssc->sc_tq)) {
621 task = usb_proc_msignal(&ssc->sc_tq, &dummy, &dummy);
622 error = usb_proc_mwait_sig(&ssc->sc_tq, task, task);
623 if (error == 0 && sc->sc_tty != NULL && tty_gone(sc->sc_tty))
633 struct ucom_super_softc *ssc = sc->sc_super;
639 if (usb_proc_is_gone(&ssc->sc_tq)) {
649 usb_proc_msignal(&ssc->sc_tq, t0, t1);
652 task->hdr.pm_callback = fn;
653 task->sc = sc;
660 task->termios_copy = *pt;
666 error = usb_proc_mwait_sig(&ssc->sc_tq, t0, t1);
669 if (error == 0 && sc->sc_tty != NULL && tty_gone(sc->sc_tty))
680 sc->sc_last_start_xfer = &task->hdr;
688 struct tty *tp = sc->sc_tty;
697 if (tp->t_termios.c_cflag & HUPCL) {
710 struct ucom_super_softc *ssc = sc->sc_super;
712 return (usb_proc_is_gone(&ssc->sc_tq));
720 struct ucom_softc *sc = task->sc;
722 if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
725 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
730 if (_task == sc->sc_last_start_xfer)
731 sc->sc_flag |= UCOM_FLAG_GP_DATA;
733 if (sc->sc_callback->ucom_start_read) {
734 (sc->sc_callback->ucom_start_read) (sc);
736 if (sc->sc_callback->ucom_start_write) {
737 (sc->sc_callback->ucom_start_write) (sc);
744 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
751 if (sc->sc_callback->ucom_start_read) {
752 (sc->sc_callback->ucom_start_read) (sc);
754 if (sc->sc_callback->ucom_start_write) {
755 (sc->sc_callback->ucom_start_write) (sc);
764 struct ucom_softc *sc = task->sc;
768 if (sc->sc_flag & UCOM_FLAG_LL_READY) {
772 sc->sc_flag |= UCOM_FLAG_LL_READY;
774 if (sc->sc_callback->ucom_cfg_open) {
775 (sc->sc_callback->ucom_cfg_open) (sc);
778 usb_pause_mtx(sc->sc_mtx, hz / 10);
791 if (sc->sc_flag & UCOM_FLAG_GONE) {
794 if (sc->sc_flag & UCOM_FLAG_HL_READY) {
800 if (sc->sc_callback->ucom_pre_open) {
805 error = (sc->sc_callback->ucom_pre_open) (sc);
809 sc->sc_flag |= UCOM_FLAG_HL_READY;
812 sc->sc_flag &= ~UCOM_FLAG_GP_DATA;
814 sc->sc_lsr = 0;
815 sc->sc_msr = 0;
816 sc->sc_mcr = 0;
819 sc->sc_pls_curr = 0;
820 sc->sc_pls_set = 0;
821 sc->sc_pls_clr = 0;
824 sc->sc_jitterbuf_in = 0;
825 sc->sc_jitterbuf_out = 0;
828 &sc->sc_open_task[0].hdr,
829 &sc->sc_open_task[1].hdr, true);
834 * Queue transfer enable command last, we'll have a barrier later so we
838 &sc->sc_start_task[0].hdr,
839 &sc->sc_start_task[1].hdr, true);
843 if (sc->sc_tty == NULL || (sc->sc_tty->t_termios.c_cflag & CNO_RTSDTR) == 0)
862 struct ucom_softc *sc = task->sc;
866 if (sc->sc_flag & UCOM_FLAG_LL_READY) {
867 sc->sc_flag &= ~UCOM_FLAG_LL_READY;
868 if (sc->sc_callback->ucom_cfg_close)
869 (sc->sc_callback->ucom_cfg_close) (sc);
884 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
891 &sc->sc_close_task[0].hdr,
892 &sc->sc_close_task[1].hdr, true);
894 sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_RTS_IFLOW);
896 if (sc->sc_callback->ucom_stop_read) {
897 (sc->sc_callback->ucom_stop_read) (sc);
915 (sc->sc_flag & UCOM_FLAG_HL_READY) == 0 ||
916 (sc->sc_flag & UCOM_FLAG_INWAKEUP) != 0) {
921 sc->sc_flag |= UCOM_FLAG_INWAKEUP;
923 pos = sc->sc_jitterbuf_out;
925 while (sc->sc_jitterbuf_in != pos) {
928 c = (char)sc->sc_jitterbuf[pos];
930 if (ttydisc_rint(tp, c, 0) == -1)
934 pos -= UCOM_JITTERBUF_SIZE;
937 sc->sc_jitterbuf_out = pos;
940 if ((sc->sc_jitterbuf_in == pos) &&
941 (sc->sc_flag & UCOM_FLAG_RTS_IFLOW))
944 sc->sc_flag &= ~UCOM_FLAG_INWAKEUP;
955 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
984 if (sc->sc_callback->ucom_ioctl) {
985 error = (sc->sc_callback->ucom_ioctl)
991 error = pps_ioctl(cmd, data, &sc->sc_pps);
1005 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1009 if (sc->sc_mcr & SER_DTR) {
1012 if (sc->sc_mcr & SER_RTS) {
1015 if (sc->sc_msr & SER_CTS) {
1018 if (sc->sc_msr & SER_DCD) {
1021 if (sc->sc_msr & SER_DSR) {
1024 if (sc->sc_msr & SER_RI) {
1030 sc->sc_mcr |= SER_DTR;
1033 sc->sc_mcr &= ~SER_DTR;
1036 sc->sc_mcr |= SER_RTS;
1039 sc->sc_mcr &= ~SER_RTS;
1041 onoff = (sc->sc_mcr & SER_DTR) ? 1 : 0;
1044 onoff = (sc->sc_mcr & SER_RTS) ? 1 : 0;
1055 struct ucom_softc *sc = task->sc;
1062 if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
1068 if (sc->sc_callback->ucom_cfg_set_dtr)
1070 if (sc->sc_callback->ucom_cfg_set_rts)
1072 if (sc->sc_callback->ucom_cfg_set_break)
1074 if (sc->sc_callback->ucom_cfg_set_ring)
1078 notch_bits = (sc->sc_pls_set & sc->sc_pls_clr) & mask;
1079 any_bits = (sc->sc_pls_set | sc->sc_pls_clr) & mask;
1080 prev_value = sc->sc_pls_curr ^ notch_bits;
1081 last_value = sc->sc_pls_curr;
1084 sc->sc_pls_curr = 0;
1085 sc->sc_pls_set = 0;
1086 sc->sc_pls_clr = 0;
1090 sc->sc_callback->ucom_cfg_set_dtr(sc,
1093 sc->sc_callback->ucom_cfg_set_rts(sc,
1096 sc->sc_callback->ucom_cfg_set_break(sc,
1099 sc->sc_callback->ucom_cfg_set_ring(sc,
1104 sc->sc_callback->ucom_cfg_set_dtr(sc,
1107 sc->sc_callback->ucom_cfg_set_rts(sc,
1110 sc->sc_callback->ucom_cfg_set_break(sc,
1113 sc->sc_callback->ucom_cfg_set_ring(sc,
1123 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1130 sc->sc_pls_curr |= set_bits;
1131 sc->sc_pls_curr &= ~clear_bits;
1132 sc->sc_pls_set |= set_bits;
1133 sc->sc_pls_clr |= clear_bits;
1136 * defer driver programming - we don't propagate any error from
1140 &sc->sc_line_state_task[0].hdr,
1141 &sc->sc_line_state_task[1].hdr, false);
1193 struct ucom_softc *sc = task->sc;
1202 tp = sc->sc_tty;
1206 if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
1209 if (sc->sc_callback->ucom_cfg_get_status == NULL) {
1217 (sc->sc_callback->ucom_cfg_get_status) (sc, &new_lsr, &new_msr);
1219 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1223 msr_delta = (sc->sc_msr ^ new_msr);
1224 lsr_delta = (sc->sc_lsr ^ new_lsr);
1226 sc->sc_msr = new_msr;
1227 sc->sc_lsr = new_lsr;
1244 if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) &&
1246 pps_capture(&sc->sc_pps);
1247 onoff = (sc->sc_msr & pps_signal) ? 1 : 0;
1250 pps_event(&sc->sc_pps, onoff ? PPS_CAPTUREASSERT :
1255 onoff = (sc->sc_msr & SER_DCD) ? 1 : 0;
1262 if ((lsr_delta & ULSR_BI) && (sc->sc_lsr & ULSR_BI)) {
1269 if ((lsr_delta & ULSR_FE) && (sc->sc_lsr & ULSR_FE)) {
1276 if ((lsr_delta & ULSR_PE) && (sc->sc_lsr & ULSR_PE)) {
1289 if (sc->sc_flag & UCOM_FLAG_CONSOLE)
1292 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1298 &sc->sc_status_task[0].hdr,
1299 &sc->sc_status_task[1].hdr, true);
1307 struct ucom_softc *sc = task->sc;
1309 if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) {
1312 if (sc->sc_callback->ucom_cfg_param == NULL) {
1316 (sc->sc_callback->ucom_cfg_param) (sc, &task->termios_copy);
1319 usb_pause_mtx(sc->sc_mtx, hz / 10);
1334 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1350 if (t->c_ispeed && (t->c_ispeed != t->c_ospeed)) {
1356 t->c_ispeed = t->c_ospeed;
1358 if (sc->sc_callback->ucom_pre_param) {
1360 error = (sc->sc_callback->ucom_pre_param) (sc, t);
1368 sc->sc_flag &= ~UCOM_FLAG_GP_DATA;
1372 &sc->sc_param_task[0].hdr,
1373 &sc->sc_param_task[1].hdr, true);
1377 /* Queue transfer enable command last */
1379 &sc->sc_start_task[0].hdr,
1380 &sc->sc_start_task[1].hdr, true);
1384 if (t->c_cflag & CRTS_IFLOW) {
1385 sc->sc_flag |= UCOM_FLAG_RTS_IFLOW;
1386 } else if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW) {
1387 sc->sc_flag &= ~UCOM_FLAG_RTS_IFLOW;
1410 if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
1425 DPRINTFN(3, "sc = %p lsr 0x%02x\n", sc, sc->sc_lsr);
1432 if (sc->sc_flag & UCOM_FLAG_LSRTXIDLE)
1433 return ((sc->sc_lsr & txidle) != txidle);
1438 /*------------------------------------------------------------------------*
1444 *------------------------------------------------------------------------*/
1450 struct tty *tp = sc->sc_tty;
1456 if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
1461 temp = ucom_cons_tx_high - ucom_cons_tx_low;
1466 if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_tx_low))
1467 temp = (UCOM_CONS_BUFSIZE - ucom_cons_tx_low);
1489 !(sc->sc_flag & UCOM_FLAG_GP_DATA)) {
1505 len -= cnt;
1513 actlen[0] = offset - offset_orig;
1528 struct tty *tp = sc->sc_tty;
1534 if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
1539 temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_rx_high + ucom_cons_rx_low;
1544 if (temp > (UCOM_CONS_BUFSIZE - ucom_cons_rx_high))
1545 temp = (UCOM_CONS_BUFSIZE - ucom_cons_rx_high);
1576 len -= res.length;
1588 sc->sc_jitterbuf_in = 0;
1589 sc->sc_jitterbuf_out = 0;
1599 if (sc->sc_jitterbuf_in != sc->sc_jitterbuf_out ||
1600 ttydisc_rint(tp, buf[cnt], 0) == -1) {
1604 pos = sc->sc_jitterbuf_in;
1605 end = sc->sc_jitterbuf_out +
1606 UCOM_JITTERBUF_SIZE - 1;
1608 end -= UCOM_JITTERBUF_SIZE;
1613 sc->sc_jitterbuf[pos] = buf[cnt];
1616 pos -= UCOM_JITTERBUF_SIZE;
1619 sc->sc_jitterbuf_in = pos;
1622 if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW)
1626 "chars\n", tp, res.length - cnt);
1639 if (sc->sc_callback->ucom_free != NULL)
1640 sc->sc_callback->ucom_free(sc);
1642 ucom_unref(sc->sc_super);
1645 ucom_close_refs--;
1654 if (ucom_cons_unit != -1)
1655 cp->cn_pri = CN_NORMAL;
1657 cp->cn_pri = CN_DEAD;
1659 strlcpy(cp->cn_name, "ucom", sizeof(cp->cn_name));
1689 return (-1);
1698 c = -1;
1702 ucom_outwakeup(sc->sc_tty);
1707 if (USB_IN_POLLING_MODE_FUNC() && sc->sc_callback->ucom_poll)
1708 (sc->sc_callback->ucom_poll) (sc);
1728 temp = (UCOM_CONS_BUFSIZE - 1) - ucom_cons_tx_high + ucom_cons_tx_low;
1738 ucom_outwakeup(sc->sc_tty);
1743 if (USB_IN_POLLING_MODE_FUNC() && sc->sc_callback->ucom_poll) {
1744 (sc->sc_callback->ucom_poll) (sc);
1751 /*------------------------------------------------------------------------*
1755 *------------------------------------------------------------------------*/
1757 ucom_ref(struct ucom_super_softc *ssc)
1760 ssc->sc_refs++;
1764 /*------------------------------------------------------------------------*
1768 * number. This function can be called on a zero-initialized
1770 *------------------------------------------------------------------------*/
1772 ucom_free_unit(struct ucom_super_softc *ssc)
1774 if (!(ssc->sc_flag & UCOM_FLAG_FREE_UNIT))
1777 ucom_unit_free(ssc->sc_unit);
1779 ssc->sc_flag &= ~UCOM_FLAG_FREE_UNIT;
1782 /*------------------------------------------------------------------------*
1790 *------------------------------------------------------------------------*/
1792 ucom_unref(struct ucom_super_softc *ssc)
1797 retval = (ssc->sc_refs < 2);
1798 ssc->sc_refs--;
1802 ucom_free_unit(ssc);
1822 return ((ucom_cons_softc != NULL) ? 0 : -1);