Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Apr 2018 15:28:47 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r332996 - in head: share/man/man4 sys/dev/usb/serial
Message-ID:  <201804251528.w3PFSlqo097870@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Wed Apr 25 15:28:46 2018
New Revision: 332996
URL: https://svnweb.freebsd.org/changeset/base/332996

Log:
  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

Modified:
  head/share/man/man4/ucom.4
  head/sys/dev/usb/serial/umodem.c
  head/sys/dev/usb/serial/usb_serial.c
  head/sys/dev/usb/serial/usb_serial.h

Modified: head/share/man/man4/ucom.4
==============================================================================
--- head/share/man/man4/ucom.4	Wed Apr 25 14:40:15 2018	(r332995)
+++ head/share/man/man4/ucom.4	Wed Apr 25 15:28:46 2018	(r332996)
@@ -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

Modified: head/sys/dev/usb/serial/umodem.c
==============================================================================
--- head/sys/dev/usb/serial/umodem.c	Wed Apr 25 14:40:15 2018	(r332995)
+++ head/sys/dev/usb/serial/umodem.c	Wed Apr 25 15:28:46 2018	(r332996)
@@ -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) {

Modified: head/sys/dev/usb/serial/usb_serial.c
==============================================================================
--- head/sys/dev/usb/serial/usb_serial.c	Wed Apr 25 14:40:15 2018	(r332995)
+++ head/sys/dev/usb/serial/usb_serial.c	Wed Apr 25 15:28:46 2018	(r332996)
@@ -105,6 +105,12 @@ SYSCTL_INT(_hw_usb_ucom, OID_AUTO, pps_mode, CTLFLAG_R
     &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_
 	}
 	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 u
 		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 u
 
 	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, 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,
@@ -1532,14 +1594,6 @@ ucom_free(void *xsc)
 	ucom_close_refs--;
 	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);
 

Modified: head/sys/dev/usb/serial/usb_serial.h
==============================================================================
--- head/sys/dev/usb/serial/usb_serial.h	Wed Apr 25 14:40:15 2018	(r332995)
+++ head/sys/dev/usb/serial/usb_serial.h	Wed Apr 25 15:28:46 2018	(r332996)
@@ -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 *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804251528.w3PFSlqo097870>