Module Name: src Committed By: martin Date: Tue Apr 16 18:45:39 UTC 2024
Modified Files: src/share/man/man4 [netbsd-10]: ugen.4 src/sys/dev/usb [netbsd-10]: uftdi.c ugen.c usbdevices.config Log Message: Pull up following revision(s) (requested by thorpej in ticket #649): sys/dev/usb/uftdi.c: revision 1.77 share/man/man4/ugen.4: revision 1.39 sys/dev/usb/ugen.c: revision 1.176 sys/dev/usb/usbdevices.config: revision 1.43 Define a "flags 1" config directive for ugenif, which is similar to ugen's, but rather forces the ugenif to match at the *lowest* match priority rather than the highest. This allows ugenif to claim only otherwise unclaimed interfaces. Add a "match quirk" mechanism to the uftdi driver that allows it to selectively reject individual interfaces based on the combination of - Vendor ID - Product ID - Interface number - Vendor string - Product string This is necessary[*] to allow some devices that would otherwise match uftdi (and thus instantiate a ucom) to be matched by ugenif instead, which is required to make the device available to libusb1. [*] ...due to a deficiency in the USB stack that does not provide a mechanism for a user-space driver to claim a device from a kernel driver and then return it back at a later time. Use this new match quirk mechanism to reject "interface 1" of the FTDI 2232C-based Tigard debug board; On this board, "interface 0" is brought out to regular TTL-level UART pins, but "interface 1" is brought out to SWD and JTAG headers, and is really only useful when used with something like openocd. Because the FTDI 2232C on this board just uses the standard FTDI vendor and product IDs, it can only be distinguished by the strings, which cannot be specified usbdevices.config, thus necessitating the match quirk entry (that works in combination with the ugenif entry added in usbdevices.config). To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.38.6.1 src/share/man/man4/ugen.4 cvs rdiff -u -r1.76 -r1.76.6.1 src/sys/dev/usb/uftdi.c cvs rdiff -u -r1.171 -r1.171.2.1 src/sys/dev/usb/ugen.c cvs rdiff -u -r1.42 -r1.42.10.1 src/sys/dev/usb/usbdevices.config Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/ugen.4 diff -u src/share/man/man4/ugen.4:1.38 src/share/man/man4/ugen.4:1.38.6.1 --- src/share/man/man4/ugen.4:1.38 Fri Aug 28 16:07:49 2020 +++ src/share/man/man4/ugen.4 Tue Apr 16 18:45:39 2024 @@ -1,4 +1,4 @@ -.\" $NetBSD: ugen.4,v 1.38 2020/08/28 16:07:49 fcambus Exp $ +.\" $NetBSD: ugen.4,v 1.38.6.1 2024/04/16 18:45:39 martin Exp $ .\" .\" Copyright (c) 1999 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 14, 2019 +.Dd March 25, 2024 .Dt UGEN 4 .Os .Sh NAME @@ -37,6 +37,7 @@ .Cd "ugen* at uhub? flags N" .Cd "ugen* at uhub? vendor V product P flags 1" .Cd "ugenif* at uhub? vendor V product P configuration C interface I" +.Cd "ugenif* at uhub? vendor V product P configuration C interface I flags 1" .Sh DESCRIPTION The .Nm @@ -62,7 +63,9 @@ locators this can be used to force the driver to be used for a certain device. .Pp -The second form of attachment can be used to +The +.Sq ugenif +form of attachment can be used to .Dq steal only one interface from some device for use by the .Nm @@ -74,6 +77,12 @@ as otherwise the driver would capture all of your .Nm usb devices. +If +.Dq flags 1 +is specified, the +.Sq ugenif +form will match at the lowest priority, thus allowing it to match only +otherwise unclaimed interfaces. .Em NOTE : You have to be extremely careful, when using this form, Index: src/sys/dev/usb/uftdi.c diff -u src/sys/dev/usb/uftdi.c:1.76 src/sys/dev/usb/uftdi.c:1.76.6.1 --- src/sys/dev/usb/uftdi.c:1.76 Sat Aug 7 16:19:17 2021 +++ src/sys/dev/usb/uftdi.c Tue Apr 16 18:45:39 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: uftdi.c,v 1.76 2021/08/07 16:19:17 thorpej Exp $ */ +/* $NetBSD: uftdi.c,v 1.76.6.1 2024/04/16 18:45:39 martin Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.76 2021/08/07 16:19:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.76.6.1 2024/04/16 18:45:39 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1. #include <dev/usb/usbdi.h> #include <dev/usb/usbdi_util.h> +#include <dev/usb/usbdivar.h> #include <dev/usb/usbdevs.h> #include <dev/usb/ucomvar.h> @@ -184,10 +185,72 @@ static int uftdi_detach(device_t, int); CFATTACH_DECL2_NEW(uftdi, sizeof(struct uftdi_softc), uftdi_match, uftdi_attach, uftdi_detach, NULL, NULL, uftdi_childdet); +struct uftdi_match_quirk_entry { + uint16_t vendor_id; + uint16_t product_id; + int iface_no; + const char * vendor_str; + const char * product_str; + int match_ret; +}; + +static const struct uftdi_match_quirk_entry uftdi_match_quirks[] = { + /* + * The Tigard board (https://github.com/tigard-tools/tigard) + * has two interfaces, one of which is meant to act as a + * regular USB serial port (interface 0), the other of which + * is meant for other protocols (SWD, JTAG, etc.). We must + * reject interface 1 so that ugenif matches, thus allowing + * full user-space control of that port. + */ + { + .vendor_id = USB_VENDOR_FTDI, + .product_id = USB_PRODUCT_FTDI_SERIAL_2232C, + .iface_no = 1, + .vendor_str = "SecuringHardware.com", + .product_str = "Tigard V1.1", + .match_ret = UMATCH_NONE, + } +}; + +static int +uftdi_quirk_match(struct usbif_attach_arg *uiaa, int rv) +{ + struct usbd_device *dev = uiaa->uiaa_device; + const struct uftdi_match_quirk_entry *q; + int i; + + for (i = 0; i < __arraycount(uftdi_match_quirks); i++) { + q = &uftdi_match_quirks[i]; + if (uiaa->uiaa_vendor != q->vendor_id || + uiaa->uiaa_product != q->product_id || + uiaa->uiaa_ifaceno != q->iface_no) { + continue; + } + if (q->vendor_str != NULL && + (dev->ud_vendor == NULL || + strcmp(dev->ud_vendor, q->vendor_str) != 0)) { + continue; + } + if (q->product_str != NULL && + (dev->ud_product == NULL || + strcmp(dev->ud_product, q->product_str) != 0)) { + continue; + } + /* + * Got a match! + */ + rv = q->match_ret; + break; + } + return rv; +} + static int uftdi_match(device_t parent, cfdata_t match, void *aux) { struct usbif_attach_arg *uiaa = aux; + int rv; DPRINTFN(20,("uftdi: vendor=%#x, product=%#x\n", uiaa->uiaa_vendor, uiaa->uiaa_product)); @@ -195,8 +258,12 @@ uftdi_match(device_t parent, cfdata_t ma if (uiaa->uiaa_configno != UFTDI_CONFIG_NO) return UMATCH_NONE; - return uftdi_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ? + rv = uftdi_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ? UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE; + if (rv != UMATCH_NONE) { + rv = uftdi_quirk_match(uiaa, rv); + } + return rv; } static void Index: src/sys/dev/usb/ugen.c diff -u src/sys/dev/usb/ugen.c:1.171 src/sys/dev/usb/ugen.c:1.171.2.1 --- src/sys/dev/usb/ugen.c:1.171 Sun Oct 23 11:06:37 2022 +++ src/sys/dev/usb/ugen.c Tue Apr 16 18:45:39 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ugen.c,v 1.171 2022/10/23 11:06:37 riastradh Exp $ */ +/* $NetBSD: ugen.c,v 1.171.2.1 2024/04/16 18:45:39 martin Exp $ */ /* * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.171 2022/10/23 11:06:37 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.171.2.1 2024/04/16 18:45:39 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -358,8 +358,12 @@ ugen_match(device_t parent, cfdata_t mat static int ugenif_match(device_t parent, cfdata_t match, void *aux) { - /* Assume that they knew what they configured! (see ugenif(4)) */ - return UMATCH_HIGHEST; + /* + * Like ugen(4), ugenif(4) also has an override flag. It has the + * opposite effect, however, causing us to match with GENERIC + * priority rather than HIGHEST. + */ + return (match->cf_flags & 1) ? UMATCH_GENERIC : UMATCH_HIGHEST; } static void Index: src/sys/dev/usb/usbdevices.config diff -u src/sys/dev/usb/usbdevices.config:1.42 src/sys/dev/usb/usbdevices.config:1.42.10.1 --- src/sys/dev/usb/usbdevices.config:1.42 Tue Jun 29 10:22:37 2021 +++ src/sys/dev/usb/usbdevices.config Tue Apr 16 18:45:39 2024 @@ -1,4 +1,4 @@ -# $NetBSD: usbdevices.config,v 1.42 2021/06/29 10:22:37 nia Exp $ +# $NetBSD: usbdevices.config,v 1.42.10.1 2024/04/16 18:45:39 martin Exp $ # # This file contains all USB related configuration. # It is suitable for inclusion in a kernel config(5) file. @@ -259,3 +259,10 @@ ugenif* at uhub? vendor 0x1050 product 0 ugenif* at uhub? vendor 0x1050 product 0x0405 configuration 1 interface 1 ugenif* at uhub? vendor 0x1050 product 0x0406 configuration 1 interface 1 ugenif* at uhub? vendor 0x1050 product 0x0407 configuration 1 interface 2 + +# Tigard debug board (FT2232C-based). This line is used in conjunction +# with a match quirk in uftdi.c. The "flags 1" is important; normally +# ugenif matches with higest priority, but we don't want that for all +# FT2232C interfaces, only interfaces that go unclaimed by uftdi (which +# is what the match quirk ensures). +ugenif* at uhub? vendor 0x0403 product 0x6010 configuration 1 interface 1 flags 1