Make it possible (controlled via sysctl, enabled by default) to mark

device-side (and only device-side) "virtual USB serial adapters" - the
ones you can get with an OTG-capable board - as consoles.  It boils down
to adding the device name to kern.console sysctl, although doing that
requires jumping through some hoops.  It doesn't change the actual
operation of those virtual devices.  The point is to make it possible
for init(8) to recognize them as console devices and to launch getty(8)
for them, when configured as "onifconsole" in ttys(5).  The point of
that, in turn, is to add such entries to the default ttys(5), so that
init(8) will launch gettys for device-side "virtual serial adapters",
but not for actual USB serial dongles.

Reviewed by:	hselasky@
No objections:	imp@
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Edward Tomasz Napierala 2018-04-25 15:28:46 +00:00
parent 4a5b420738
commit 7762e8a12e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332996
4 changed files with 74 additions and 10 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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 *);