Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Feb 2018 13:50:24 +0100
From:      Hans Petter Selasky <hps@selasky.org>
To:        Jakob Alvermark <jakob@alvermark.net>, freebsd-current@freebsd.org
Subject:   Re: devd in r329188M don't start
Message-ID:  <c80494a1-38be-0d67-c3aa-25e989b45334@selasky.org>
In-Reply-To: <ab958658-771e-d68f-bd37-d1594cef958b@alvermark.net>
References:  <6dda893b-e1a1-6e13-98f8-3c73d29fe936@gmail.com> <d6191ffb-3f6f-40b5-f990-fec83118fa31@selasky.org> <66467b7f-299c-83c8-798e-562d7fa39b8e@gmail.com> <4913dc5a-e3a9-01da-8f23-6f62d03d2cc7@selasky.org> <5fa0ef16-7689-91a2-a43b-1dd319d8b745@gmail.com> <ab958658-771e-d68f-bd37-d1594cef958b@alvermark.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------75CE02947371056AAE27BFDE
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

On 02/13/18 10:47, Jakob Alvermark wrote:
> +1
> 
> My USB mouse was working fine before the switch to devmatch. Now I have 
> to 'kldload ums' manually.
> 
> Same for USB audio, snd_uaudio.ko was loaded by devd before.
> 

Hi,

This is a known issue.

Can you try the attached patch?

Rebuild devmatch(8) and reinstall /etc/devd/devmatch.conf and 
/etc/rc.d/devmatch only.

--HPS

--------------75CE02947371056AAE27BFDE
Content-Type: text/x-patch;
 name="devmatch.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="devmatch.diff"

Index: etc/defaults/rc.conf
===================================================================
--- etc/defaults/rc.conf	(revision 329193)
+++ etc/defaults/rc.conf	(working copy)
@@ -41,7 +41,8 @@
 ddb_config="/etc/ddb.conf"	# ddb(8) config file.
 devd_enable="YES" 	# Run devd, to trigger programs on device tree changes.
 devd_flags=""		# Additional flags for devd(8).
-devmatch_enable="YES"	# Demand load kernel modules based on device ids.
+devmatch_enable="YES"	# Demand load kernel modules based on device IDs.
+devmatch_flags=""	# Additional flags for devmatch(8).
 #kld_list="" 		# Kernel modules to load after local disks are mounted
 kldxref_enable="NO"	# Build linker.hints files with kldxref(8).
 kldxref_clobber="NO"	# Overwrite old linker.hints at boot.
Index: etc/devd/devmatch.conf
===================================================================
--- etc/devd/devmatch.conf	(revision 329194)
+++ etc/devd/devmatch.conf	(working copy)
@@ -7,14 +7,10 @@
 # loading what modules we can based on nomatch
 # events.
 #
-# Generic NOMATCH event
+
+# USB NOMATCH event
 nomatch 100 {
-	action "service devmatch start";
+	match "bus" "uhub[0-9]+";
+	action "/etc/rc.d/devmatch start 'bus=usb device=$ugen vendor=$vendor product=$product devclass=$devclass devsubclass=$devsubclass devprotocol=$devproto release=$release intclass=$intclass intsubclass=$intsubclass intprotocol=$intprotocol mode=$mode'";
 };
 
-# Add the following to devd.conf to prevent this from running:
-# 	nomatch 1000 {
-#		action "true";
-#	};
-# it replaces the generic event with one of higher priority that
-# does nothing. You can also set 'devmatch_enable=NO' in /etc/rc.conf
Index: etc/rc.d/devmatch
===================================================================
--- etc/rc.d/devmatch	(revision 329193)
+++ etc/rc.d/devmatch	(working copy)
@@ -38,17 +38,54 @@
 start_cmd="${name}_start"
 stop_cmd=':'
 
-devmatch_start()
+fixed_pnpinfo=${2}
+
+devmatch_start_default()
 {
 	local x
+	local m
 
-	x=$(devmatch | sort -u)
+	x=$(devmatch $devmatch_flags | sort -u)
 
-	[ -n "$x" ] || return
+	#
+	# Load modules one by one, because
+	# kldload will bail out on the first
+	# failure:
+	#
+	for m in ${x}
+	do
+		echo "Autoloading module: ${m}"
+		kldload -n ${m}
+	done
+}
 
-	echo "Autoloading modules: ${x}"
-	kldload ${x}
+devmatch_start_pnpinfo()
+{
+	local x
+	local m
+
+	x=$(devmatch -p "$fixed_pnpinfo" | sort -u)
+
+	#
+	# Load modules one by one, because
+	# kldload will bail out on the first
+	# failure:
+	#
+	for m in ${x}
+	do
+		echo "Autoloading module: ${m}"
+		kldload -n ${m}
+	done
 }
 
+devmatch_start()
+{
+	if [ "$fixed_pnpinfo" ]; then
+		devmatch_start_pnpinfo
+	else
+		devmatch_start_default
+	fi
+}
+
 load_rc_config $name
 run_rc_command "$1"
Index: sbin/devmatch/devmatch.8
===================================================================
--- sbin/devmatch/devmatch.8	(revision 329193)
+++ sbin/devmatch/devmatch.8	(working copy)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 12, 2018
+.Dd February 13, 2018
 .Dt DEVMATCH 8
 .Os
 .Sh NAME
@@ -33,9 +33,10 @@
 .Nd print information about unattached devices
 .Sh SYNOPSIS
 .Nm
-.Op Fl aduv
+.Op Fl adpuv
 .Op Fl -all
 .Op Fl -dump
+.Op Fl -pnpinfo
 .Op Fl -unbound
 .Op Fl -verbose
 .Sh DESCRIPTION
@@ -50,6 +51,8 @@
 Produce a human readable dump of the
 .Pa linker.hints
 file.
+.It Fl p Fl -pnpinfo
+Specify plug and play information to be used when matching a driver.
 .It Fl u Fl -unbound
 Attempt to produce a list of those drivers with PNP info whose driver
 tables with that PNP info can't be found.
Index: sbin/devmatch/devmatch.c
===================================================================
--- sbin/devmatch/devmatch.c	(revision 329193)
+++ sbin/devmatch/devmatch.c	(working copy)
@@ -47,6 +47,7 @@
 static struct option longopts[] = {
 	{ "all",		no_argument,		NULL,	'a' },
 	{ "dump",		no_argument,		NULL,	'd' },
+	{ "pnpinfo",		required_argument,	NULL,	'p' },
 	{ "unbound",		no_argument,		NULL,	'u' },
 	{ "verbose",		no_argument,		NULL,	'v' },
 	{ NULL,			0,			NULL,	0 }
@@ -59,6 +60,7 @@
 
 static void *hints;
 static void *hints_end;
+static const char *fixed_pnpinfo;
 
 static void
 read_linker_hints(void)
@@ -137,36 +139,83 @@
 }
 
 static int
+extract_key(char *key, const char *val, int size, char end)
+{
+	char *old = key;
+
+	/* prepend a space character */
+	*key++ = ' ';
+	size--;
+
+	/* extract key */
+	while (1) {
+		if (*val == '\0' || *val == ';')
+			break;
+		if (size < 3) {
+			warnx("Key is too long.");
+			return (-1);
+		}
+		*key++ = *val++;
+		size--;
+	}
+
+	/* append end character, if any */
+	if (end != '\0')
+		*key++ = end;
+
+	/* zero terminate */
+	*key = '\0';
+
+	/* return string length */
+	return (key - old);
+}
+
+static int
 pnpval_as_int(const char *val, const char *pnpinfo)
 {
+	char key[256];
+	int len;
 	int rv;
-	char key[256];
-	char *cp;
 
 	if (pnpinfo == NULL)
-		return -1;
+		return (-1);
 
-	cp = strchr(val, ';');
-	key[0] = ' ';
-	if (cp == NULL)
-		strlcpy(key + 1, val, sizeof(key) - 1);
-	else {
-		memcpy(key + 1, val, cp - val);
-		key[cp - val + 1] = '\0';
-	}
-	strlcat(key, "=", sizeof(key));
-	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
-		rv = strtol(pnpinfo + strlen(key + 1), NULL, 0);
-	else {
-		cp = strstr(pnpinfo, key);
+	len = extract_key(key, val, sizeof(key), '=');
+	if (len < 1)
+		return (-1);
+
+	/* check for match at beginning, skipping first space */
+	if (strncmp(key + 1, pnpinfo, len - 1) == 0) {
+		rv = strtol(pnpinfo + len - 1, NULL, 0);
+	} else {
+		/* check for match inside */
+		const char *cp = strstr(pnpinfo, key);
 		if (cp == NULL)
 			rv = -1;
 		else
-			rv = strtol(cp + strlen(key), NULL, 0);
+			rv = strtol(cp + len, NULL, 0);
 	}
-	return rv;
+	return (rv);
 }
 
+static int
+pnpval_as_type_match(const char *val, const char *pnpinfo)
+{
+	char key[256];
+	int len;
+
+	if (pnpinfo == NULL)
+		return (0);
+
+	len = extract_key(key, val, sizeof(key), '\0');
+	if (len < 1)
+		return (0);
+
+	/* check for match */
+	return (strncmp(key + 1, pnpinfo, len - 1) == 0 ||
+		strstr(pnpinfo, key) != NULL);
+}
+
 static void
 quoted_strcpy(char *dst, const char *src)
 {
@@ -180,37 +229,35 @@
 	// XXX overflow
 }
 
-static char *
+static const char *
 pnpval_as_str(const char *val, const char *pnpinfo)
 {
 	static char retval[256];
 	char key[256];
-	char *cp;
+	int len;
 
 	if (pnpinfo == NULL) {
-		*retval = '\0';
-		return retval;
+		retval[0] = '\0';
+		return (retval);
 	}
 
-	cp = strchr(val, ';');
-	key[0] = ' ';
-	if (cp == NULL)
-		strlcpy(key + 1, val, sizeof(key) - 1);
-	else {
-		memcpy(key + 1, val, cp - val);
-		key[cp - val + 1] = '\0';
+	len = extract_key(key, val, sizeof(key), '=');
+	if (len < 1) {
+		retval[0] = '\0';
+		return (retval);
 	}
-	strlcat(key, "=", sizeof(key));
-	if (strncmp(key + 1, pnpinfo, strlen(key + 1)) == 0)
-		quoted_strcpy(retval, pnpinfo + strlen(key + 1));
-	else {
-		cp = strstr(pnpinfo, key);
+
+	/* check for match at beginning, skipping first space */
+	if (strncmp(key + 1, pnpinfo, len - 1) == 0) {
+		quoted_strcpy(retval, pnpinfo + len - 1);
+	} else {
+		const char *cp = strstr(pnpinfo, key);
 		if (cp == NULL)
 			strcpy(retval, "MISSING");
 		else
-			quoted_strcpy(retval, cp + strlen(key));
+			quoted_strcpy(retval, cp + len);
 	}
-	return retval;
+	return (retval);
 }
 
 static void
@@ -219,7 +266,8 @@
 	char val1[256], val2[256];
 	int ival, len, ents, i, notme, mask, bit, v, found;
 	void *ptr, *walker;
-	char *lastmod = NULL, *cp, *s;
+	char *lastmod = NULL;
+	const char *cp, *s;
 
 	walker = hints;
 	getint(&walker);
@@ -284,7 +332,7 @@
 								break;
 							/*FALLTHROUGH*/
 						case 'I':
-							if (v != ival && ival != 0)
+							if (v != ival)
 								notme++;
 							break;
 						case 'G':
@@ -313,6 +361,16 @@
 						if (strcmp(s, val1) != 0)
 							notme++;
 						break;
+					case 'T':
+						if (dump_flag) {
+							int x;
+							for (x = 2; cp[x] != '\0' && cp[x] != ';'; x++)
+								putchar(cp[x]);
+							break;
+						}
+						if (!pnpval_as_type_match(cp + 2, pnpinfo))
+							notme++;
+						break;
 					default:
 						break;
 					}
@@ -382,7 +440,7 @@
 usage(void)
 {
 
-	errx(1, "devmatch [-adv]");
+	errx(1, "devmatch [-adv] [-p <pnpinfo>]");
 }
 
 int
@@ -391,7 +449,7 @@
 	struct devinfo_dev *root;
 	int ch;
 
-	while ((ch = getopt_long(argc, argv, "aduv",
+	while ((ch = getopt_long(argc, argv, "aduvp:",
 		    longopts, NULL)) != -1) {
 		switch (ch) {
 		case 'a':
@@ -403,6 +461,9 @@
 		case 'u':
 			unbound_flag++;
 			break;
+		case 'p':
+			fixed_pnpinfo = optarg;
+			break;
 		case 'v':
 			verbose_flag++;
 			break;
@@ -422,6 +483,13 @@
 		exit(0);
 	}
 
+	if (fixed_pnpinfo != NULL) {
+		const char *bus = strdup(pnpval_as_str("bus", fixed_pnpinfo));
+		const char *dev = strdup(pnpval_as_str("device", fixed_pnpinfo));
+		search_hints(bus, dev, fixed_pnpinfo);
+		exit(0);
+	}
+
 	if (devinfo_init())
 		err(1, "devinfo_init");
 	if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL)

--------------75CE02947371056AAE27BFDE--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?c80494a1-38be-0d67-c3aa-25e989b45334>