ports.
Suggested by deraadt@, USB route idea from kettenis@. Feedback
from anton@, man page improvements from deraadt@, jmc@,
schwarze@.
ok deraadt@ kettenis@
-.\" $OpenBSD: sysctl.2,v 1.52 2023/05/16 21:13:19 jmc Exp $
+.\" $OpenBSD: sysctl.2,v 1.53 2023/10/01 15:58:11 krw Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: May 16 2023 $
+.Dd $Mdocdate: October 1 2023 $
.Dt SYSCTL 2
.Os
.Sh NAME
.It Dv HW_SENSORS Ta "node" Ta "not applicable"
.It Dv HW_SETPERF Ta "integer" Ta "yes"
.It Dv HW_SMT Ta "integer" Ta "yes"
+.It DV HW_UCOMNAMES Ta "string" Ta "no"
.It Dv HW_USERMEM Ta "integer" Ta "no"
.It Dv HW_USERMEM64 Ta "int64_t" Ta "no"
.It Dv HW_UUID Ta "string" Ta "no"
If set to 1, enable simultaneous multithreading (SMT) on CPUs that
support it.
Disabled by default.
+.It Dv HW_UCOMNAMES Pq Va hw.ucomnames
+A comma-separated list of currently attached
+.Xr ucom 4
+devices in the following format:
+.Pp
+.Sm off
+.D1 Sy ucom Ar N : Sy usb Ar bus.route.interface
+.Sm on
+.Pp
+The
+.Ar route
+consists of five hexadecimal digits and identifies the port
+containing the
+.Ar interface .
.It Dv HW_USERMEM
The amount of available non-kernel memory in bytes.
This variable is deprecated; use
-/* $OpenBSD: ucom.c,v 1.75 2023/09/21 00:05:36 krw Exp $ */
+/* $OpenBSD: ucom.c,v 1.76 2023/10/01 15:58:11 krw Exp $ */
/* $NetBSD: ucom.c,v 1.49 2003/01/01 00:10:25 thorpej Exp $ */
/*
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <dev/usb/usb.h>
ucom_detach,
};
+static int ucom_change;
+struct rwlock sysctl_ucomlock = RWLOCK_INITIALIZER("sysctlulk");
+
void
ucom_lock(struct ucom_softc *sc)
{
sc->sc_tty = tp;
sc->sc_cua = 0;
+ ucom_change = 1;
rw_init(&sc->sc_lock, "ucomlk");
}
sc->sc_tty = NULL;
}
+ ucom_change = 1;
return (0);
}
}
}
-#endif /* NUCOM > 0 */
+/*
+ * Update ucom names for export by sysctl.
+ */
+char *
+sysctl_ucominit(void)
+{
+ static char *ucoms = NULL;
+ static size_t ucomslen = 0;
+ char name[34]; /* sizeof(dv_xname) + strlen(":usb000.00000.000,") */
+ struct ucom_softc *sc;
+ int rslt;
+ unsigned int unit;
+ uint32_t route;
+ uint8_t bus, ifaceidx;
+
+ KERNEL_ASSERT_LOCKED();
+
+ if (rw_enter(&sysctl_ucomlock, RW_WRITE|RW_INTR) != 0)
+ return NULL;
+
+ if (ucoms == NULL || ucom_change) {
+ free(ucoms, M_SYSCTL, ucomslen);
+ ucomslen = ucom_cd.cd_ndevs * sizeof(name);
+ ucoms = malloc(ucomslen, M_SYSCTL, M_WAITOK | M_ZERO);
+ for (unit = 0; unit < ucom_cd.cd_ndevs; unit++) {
+ sc = ucom_cd.cd_devs[unit];
+ if (sc == NULL || sc->sc_iface == NULL)
+ continue;
+ if (usbd_get_location(sc->sc_uparent, sc->sc_iface,
+ &bus, &route, &ifaceidx) == -1)
+ continue;
+ rslt = snprintf(name, sizeof(name), "%s:usb%u.%05x.%u,",
+ sc->sc_dev.dv_xname, bus, route, ifaceidx);
+ if (rslt < sizeof(name) && (strlen(ucoms) + rslt) < ucomslen)
+ strlcat(ucoms, name, ucomslen);
+ }
+ }
+
+ /* Remove trailing ','. */
+ if (strlen(ucoms))
+ ucoms[strlen(ucoms) - 1] = '\0';
+
+ rw_exit_write(&sysctl_ucomlock);
+
+ return ucoms;
+}
+#endif /* NUCOM > 0 */
int
ucomprint(void *aux, const char *pnp)
-/* $OpenBSD: ucomvar.h,v 1.19 2022/04/09 20:07:44 naddy Exp $ */
+/* $OpenBSD: ucomvar.h,v 1.20 2023/10/01 15:58:11 krw Exp $ */
/* $NetBSD: ucomvar.h,v 1.10 2001/12/31 12:15:21 augustss Exp $ */
/*
int ucomsubmatch(struct device *, void *, void *);
+char *sysctl_ucominit(void);
+
int ucomprint(void *aux, const char *pnp);
void ucom_status_change(struct ucom_softc *);
-/* $OpenBSD: usb_subr.c,v 1.159 2023/09/11 08:41:27 mvs Exp $ */
+/* $OpenBSD: usb_subr.c,v 1.160 2023/10/01 15:58:11 krw Exp $ */
/* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
sizeof(di->udi_serial));
}
+int
+usbd_get_routestring(struct usbd_device *dev, uint32_t *route)
+{
+ struct usbd_device *hub;
+ uint32_t r;
+ uint8_t port;
+
+ /*
+ * Calculate the Route String. Assume that there is no hub with
+ * more than 15 ports and that they all have a depth < 6. See
+ * section 8.9 of USB 3.1 Specification for more details.
+ */
+ r = dev->powersrc ? dev->powersrc->portno : 0;
+ for (hub = dev->myhub; hub && hub->depth; hub = hub->myhub) {
+ port = hub->powersrc ? hub->powersrc->portno : 0;
+ if (port > 15)
+ return -1;
+ r <<= 4;
+ r |= port;
+ }
+
+ *route = r;
+ return 0;
+}
+
+int
+usbd_get_location(struct usbd_device *dev, struct usbd_interface *iface,
+ uint8_t *bus, uint32_t *route, uint8_t *ifaceidx)
+{
+ int i;
+ uint32_t r;
+
+ if (dev == NULL || usbd_is_dying(dev) ||
+ dev->cdesc == NULL ||
+ dev->cdesc->bNumInterfaces == 0 ||
+ dev->bus == NULL ||
+ dev->bus->usbctl == NULL ||
+ dev->myhub == NULL ||
+ dev->powersrc == NULL)
+ return -1;
+
+ for(i = 0; i < dev->cdesc->bNumInterfaces; i++) {
+ if (iface == &dev->ifaces[i]) {
+ *bus = dev->bus->usbctl->dv_unit;
+ *route = (usbd_get_routestring(dev, &r)) ? 0 : r;
+ *ifaceidx = i;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
/* Retrieve a complete descriptor for a certain device and index. */
usb_config_descriptor_t *
usbd_get_cdesc(struct usbd_device *dev, int index, u_int *lenp)
-/* $OpenBSD: usbdi.h,v 1.72 2022/02/16 06:23:42 anton Exp $ */
+/* $OpenBSD: usbdi.h,v 1.73 2023/10/01 15:58:12 krw Exp $ */
/* $NetBSD: usbdi.h,v 1.62 2002/07/11 21:14:35 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
usbd_status usbd_set_interface(struct usbd_interface *, int);
int usbd_get_no_alts(usb_config_descriptor_t *, int);
void usbd_fill_deviceinfo(struct usbd_device *, struct usb_device_info *);
+int usbd_get_routestring(struct usbd_device *, uint32_t *);
+int usbd_get_location(struct usbd_device *, struct usbd_interface *, uint8_t *,
+ uint32_t *, uint8_t *);
usb_config_descriptor_t *usbd_get_cdesc(struct usbd_device *, int, u_int *);
int usbd_get_interface_altindex(struct usbd_interface *iface);
-/* $OpenBSD: kern_sysctl.c,v 1.419 2023/09/16 09:33:27 mpi Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.420 2023/10/01 15:58:12 krw Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
#include <dev/cons.h>
+#include <dev/usb/ucomvar.h>
+
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include "audio.h"
#include "dt.h"
#include "pf.h"
+#include "ucom.h"
#include "video.h"
extern struct forkstat forkstat;
case HW_ALLOWPOWERDOWN:
return (sysctl_securelevel_int(oldp, oldlenp, newp, newlen,
&allowpowerdown));
+#if NUCOM > 0
+ case HW_UCOMNAMES: {
+ const char *str = sysctl_ucominit();
+ if (str == NULL)
+ return EINVAL;
+ return (sysctl_rdstring(oldp, oldlenp, newp, str));
+ }
+#endif /* NUCOM > 0 */
#ifdef __HAVE_CPU_TOPOLOGY
case HW_SMT:
return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
-/* $OpenBSD: sysctl.h,v 1.234 2023/07/04 11:14:00 jsg Exp $ */
+/* $OpenBSD: sysctl.h,v 1.235 2023/10/01 15:58:12 krw Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
#define HW_NCPUONLINE 25 /* int: number of cpus being used */
#define HW_POWER 26 /* int: machine has wall-power */
#define HW_BATTERY 27 /* node: battery */
+#define HW_UCOMNAMES 28 /* strings: ucom names */
#define HW_MAXID 30 /* number of valid hw ids */
#define CTL_HW_NAMES { \
{ "ncpuonline", CTLTYPE_INT }, \
{ "power", CTLTYPE_INT }, \
{ "battery", CTLTYPE_NODE }, \
+ { "ucomnames", CTLTYPE_STRING }, \
}
/*