From owner-freebsd-current@freebsd.org Tue Feb 13 12:53:23 2018 Return-Path: Delivered-To: freebsd-current@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D3F0FF1FE2E for ; Tue, 13 Feb 2018 12:53:22 +0000 (UTC) (envelope-from hps@selasky.org) Received: from mail.turbocat.net (turbocat.net [88.99.82.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 68EF876D64 for ; Tue, 13 Feb 2018 12:53:22 +0000 (UTC) (envelope-from hps@selasky.org) Received: from hps2016.home.selasky.org (unknown [62.141.128.70]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.turbocat.net (Postfix) with ESMTPSA id BED99260329; Tue, 13 Feb 2018 13:53:19 +0100 (CET) Subject: Re: devd in r329188M don't start To: Jakob Alvermark , freebsd-current@freebsd.org References: <6dda893b-e1a1-6e13-98f8-3c73d29fe936@gmail.com> <66467b7f-299c-83c8-798e-562d7fa39b8e@gmail.com> <4913dc5a-e3a9-01da-8f23-6f62d03d2cc7@selasky.org> <5fa0ef16-7689-91a2-a43b-1dd319d8b745@gmail.com> From: Hans Petter Selasky Message-ID: Date: Tue, 13 Feb 2018 13:50:24 +0100 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------75CE02947371056AAE27BFDE" Content-Language: en-US X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Feb 2018 12:53:23 -0000 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 ]"); } 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--