summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2018-04-25 15:28:46 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2018-04-25 15:28:46 +0000
commit7762e8a12e3fd264096bdebea0613235599910df (patch)
treea1abbe186a072e37d4a82ca9fbe3626de6d522d1
parent4a5b4207385cabd19d4123e949dcff01211d0c58 (diff)
Notes
-rw-r--r--share/man/man4/ucom.47
-rw-r--r--sys/dev/usb/serial/umodem.c2
-rw-r--r--sys/dev/usb/serial/usb_serial.c72
-rw-r--r--sys/dev/usb/serial/usb_serial.h3
4 files changed, 74 insertions, 10 deletions
diff --git a/share/man/man4/ucom.4 b/share/man/man4/ucom.4
index e7dc77fb6243..4eb2d12c217c 100644
--- a/share/man/man4/ucom.4
+++ b/share/man/man4/ucom.4
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 24, 2018
+.Dd April 25, 2018
.Dt UCOM 4
.Os
.Sh NAME
@@ -74,6 +74,11 @@ tunables:
Debug output level, where 0 is debugging disabled and larger values increase
debug message verbosity.
Default is 0.
+.It Va hw.usb.ucom.device_mode_console
+When set to 1, the
+.Nm
+driver will mark terminals as console devices when operating in device mode.
+Default is 1.
.It Va hw.usb.ucom.pps_mode
Enables and configure PPS capture mode as described below.
.Sh Pulse Per Second (PPS) Timing Interface
diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c
index 11bd375113fb..567fbe3fd417 100644
--- a/sys/dev/usb/serial/umodem.c
+++ b/sys/dev/usb/serial/umodem.c
@@ -457,6 +457,8 @@ umodem_attach(device_t dev)
mtx_unlock(&sc->sc_mtx);
}
+ ucom_set_usb_mode(&sc->sc_super_ucom, uaa->usb_mode);
+
error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
&umodem_callback, &sc->sc_mtx);
if (error) {
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index 96c2c45c5ee6..445c9f2127b8 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -105,6 +105,12 @@ SYSCTL_INT(_hw_usb_ucom, OID_AUTO, pps_mode, CTLFLAG_RWTUN,
&ucom_pps_mode, 0,
"pulse capture mode: 0/1/2=disabled/CTS/DCD; add 0x10 to invert");
+static int ucom_device_mode_console = 1;
+
+SYSCTL_INT(_hw_usb_ucom, OID_AUTO, device_mode_console, CTLFLAG_RW,
+ &ucom_device_mode_console, 0,
+ "set to 1 to mark terminals as consoles when in device mode");
+
#ifdef USB_DEBUG
static int ucom_debug = 0;
@@ -288,7 +294,7 @@ ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
}
ssc->sc_subunits = subunits;
ssc->sc_flag = UCOM_FLAG_ATTACHED |
- UCOM_FLAG_FREE_UNIT;
+ UCOM_FLAG_FREE_UNIT | (ssc->sc_flag & UCOM_FLAG_DEVICE_MODE);
if (callback->ucom_free == NULL)
ssc->sc_flag |= UCOM_FLAG_WAIT_REFS;
@@ -388,6 +394,24 @@ ucom_drain_all(void *arg)
mtx_unlock(&ucom_mtx);
}
+static cn_probe_t ucom_cnprobe;
+static cn_init_t ucom_cninit;
+static cn_term_t ucom_cnterm;
+static cn_getc_t ucom_cngetc;
+static cn_putc_t ucom_cnputc;
+static cn_grab_t ucom_cngrab;
+static cn_ungrab_t ucom_cnungrab;
+
+const struct consdev_ops ucom_cnops = {
+ .cn_probe = ucom_cnprobe,
+ .cn_init = ucom_cninit,
+ .cn_term = ucom_cnterm,
+ .cn_getc = ucom_cngetc,
+ .cn_putc = ucom_cnputc,
+ .cn_grab = ucom_cngrab,
+ .cn_ungrab = ucom_cnungrab,
+};
+
static int
ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
{
@@ -450,6 +474,24 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
UCOM_MTX_UNLOCK(ucom_cons_softc);
}
+ if ((ssc->sc_flag & UCOM_FLAG_DEVICE_MODE) != 0 &&
+ ucom_device_mode_console > 0 &&
+ ucom_cons_softc == NULL) {
+ struct consdev *cp;
+
+ cp = malloc(sizeof(struct consdev), M_USBDEV,
+ M_WAITOK|M_ZERO);
+ cp->cn_ops = &ucom_cnops;
+ cp->cn_arg = NULL;
+ cp->cn_pri = CN_NORMAL;
+ strlcpy(cp->cn_name, "tty", sizeof(cp->cn_name));
+ strlcat(cp->cn_name, buf, sizeof(cp->cn_name));
+
+ sc->sc_consdev = cp;
+
+ cnadd(cp);
+ }
+
return (0);
}
@@ -460,6 +502,12 @@ ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty);
+ if (sc->sc_consdev != NULL) {
+ cnremove(sc->sc_consdev);
+ free(sc->sc_consdev, M_USBDEV);
+ sc->sc_consdev = NULL;
+ }
+
if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
UCOM_MTX_LOCK(ucom_cons_softc);
ucom_close(ucom_cons_softc->sc_tty);
@@ -533,6 +581,20 @@ ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
}
}
+void
+ucom_set_usb_mode(struct ucom_super_softc *ssc, enum usb_hc_mode usb_mode)
+{
+
+ switch (usb_mode) {
+ case USB_MODE_DEVICE:
+ ssc->sc_flag |= UCOM_FLAG_DEVICE_MODE;
+ break;
+ default:
+ ssc->sc_flag &= ~UCOM_FLAG_DEVICE_MODE;
+ break;
+ }
+}
+
static void
ucom_queue_command(struct ucom_softc *sc,
usb_proc_callback_t *fn, struct termios *pt,
@@ -1533,14 +1595,6 @@ ucom_free(void *xsc)
mtx_unlock(&ucom_mtx);
}
-static cn_probe_t ucom_cnprobe;
-static cn_init_t ucom_cninit;
-static cn_term_t ucom_cnterm;
-static cn_getc_t ucom_cngetc;
-static cn_putc_t ucom_cnputc;
-static cn_grab_t ucom_cngrab;
-static cn_ungrab_t ucom_cnungrab;
-
CONSOLE_DRIVER(ucom);
static void
diff --git a/sys/dev/usb/serial/usb_serial.h b/sys/dev/usb/serial/usb_serial.h
index 9a5e043e2474..cd60bcfb97a2 100644
--- a/sys/dev/usb/serial/usb_serial.h
+++ b/sys/dev/usb/serial/usb_serial.h
@@ -165,6 +165,7 @@ struct ucom_softc {
const struct ucom_callback *sc_callback;
struct ucom_super_softc *sc_super;
struct tty *sc_tty;
+ struct consdev *sc_consdev;
struct mtx *sc_mtx;
void *sc_parent;
int sc_subunit;
@@ -183,6 +184,7 @@ struct ucom_softc {
#define UCOM_FLAG_FREE_UNIT 0x0200 /* set if we must free the unit */
#define UCOM_FLAG_INWAKEUP 0x0400 /* set if we are in the tsw_inwakeup callback */
#define UCOM_FLAG_LSRTXIDLE 0x0800 /* set if sc_lsr bits ULSR_TSRE+TXRDY work */
+#define UCOM_FLAG_DEVICE_MODE 0x1000 /* set if we're an USB device, not a host */
uint8_t sc_lsr;
uint8_t sc_msr;
uint8_t sc_mcr;
@@ -211,6 +213,7 @@ int ucom_attach(struct ucom_super_softc *,
const struct ucom_callback *callback, struct mtx *);
void ucom_detach(struct ucom_super_softc *, struct ucom_softc *);
void ucom_set_pnpinfo_usb(struct ucom_super_softc *, device_t);
+void ucom_set_usb_mode(struct ucom_super_softc *, enum usb_hc_mode);
void ucom_status_change(struct ucom_softc *);
uint8_t ucom_get_data(struct ucom_softc *, struct usb_page_cache *,
uint32_t, uint32_t, uint32_t *);