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
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)
_______________________________________________
freebsd-current@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"