git: 9d28e15e7bbe - main - ng_ubt(4): Probe USB Bluetooth per USB interface and not per USB device.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Fri, 03 Jun 2022 10:10:01 UTC
The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=9d28e15e7bbee7a809eb4ccab558d114d4343312

commit 9d28e15e7bbee7a809eb4ccab558d114d4343312
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-06-03 08:22:54 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-06-03 08:49:17 +0000

    ng_ubt(4): Probe USB Bluetooth per USB interface and not per USB device.
    
    PR:             264416
    MFC after:      1 week
    Sponsored by:   NVIDIA Networking
---
 sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c | 67 +++++++++++++++++------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
index d1c2b3a83072..87cca84f7d7a 100644
--- a/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
+++ b/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c
@@ -607,22 +607,31 @@ static int
 ubt_probe(device_t dev)
 {
 	struct usb_attach_arg	*uaa = device_get_ivars(dev);
-	int error;
+	const struct usb_device_id *id;
 
 	if (uaa->usb_mode != USB_MODE_HOST)
 		return (ENXIO);
 
-	if (uaa->info.bIfaceIndex != 0)
-		return (ENXIO);
-
 	if (usbd_lookup_id_by_uaa(ubt_ignore_devs,
 			sizeof(ubt_ignore_devs), uaa) == 0)
 		return (ENXIO);
 
-	error = usbd_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa);
-	if (error == 0)
+	id = usbd_lookup_id_by_info(ubt_devs,
+	    sizeof(ubt_devs), &uaa->info);
+	if (id == NULL)
+		return (ENXIO);
+
+	if (uaa->info.bIfaceIndex != 0) {
+		/* make sure we are matching the interface */
+		if (id->match_flag_int_class &&
+		    id->match_flag_int_subclass &&
+		    id->match_flag_int_protocol)
+			return (BUS_PROBE_GENERIC);
+		else
+			return (ENXIO);
+	} else {
 		return (BUS_PROBE_GENERIC);
-	return (error);
+	}
 } /* ubt_probe */
 
 /*
@@ -637,16 +646,32 @@ ubt_attach(device_t dev)
 	struct ubt_softc		*sc = device_get_softc(dev);
 	struct usb_endpoint_descriptor	*ed;
 	struct usb_interface_descriptor *id;
-	struct usb_interface		*iface;
+	struct usb_interface		*iface[2];
 	uint32_t			wMaxPacketSize;
 	uint8_t				alt_index, i, j;
-	uint8_t				iface_index[2] = { 0, 1 };
+	uint8_t				iface_index[2];
 
 	device_set_usb_desc(dev);
 
+	iface_index[0] = uaa->info.bIfaceIndex;
+	iface_index[1] = uaa->info.bIfaceIndex + 1;
+
+	iface[0] = usbd_get_iface(uaa->device, iface_index[0]);
+	iface[1] = usbd_get_iface(uaa->device, iface_index[1]);
+
 	sc->sc_dev = dev;
 	sc->sc_debug = NG_UBT_WARN_LEVEL;
 
+	/*
+	 * Sanity checks.
+	 */
+
+	if (iface[0] == NULL || iface[1] == NULL ||
+	    iface[0]->idesc == NULL || iface[1]->idesc == NULL) {
+		UBT_ALERT(sc, "could not get two interfaces\n");
+		return (ENXIO);
+	}
+
 	/* 
 	 * Create Netgraph node
 	 */
@@ -720,13 +745,13 @@ ubt_attach(device_t dev)
 		if ((ed->bDescriptorType == UDESC_INTERFACE) &&
 		    (ed->bLength >= sizeof(*id))) {
 			id = (struct usb_interface_descriptor *)ed;
-			i = id->bInterfaceNumber;
+			i = (id->bInterfaceNumber == iface[1]->idesc->bInterfaceNumber);
 			j = id->bAlternateSetting;
 		}
 
 		if ((ed->bDescriptorType == UDESC_ENDPOINT) &&
 		    (ed->bLength >= sizeof(*ed)) &&
-		    (i == 1)) {
+		    (i != 0)) {
 			uint32_t temp;
 
 			temp = usbd_get_max_frame_length(
@@ -740,7 +765,7 @@ ubt_attach(device_t dev)
 
 	/* Set alt configuration on interface #1 only if we found it */
 	if (wMaxPacketSize > 0 &&
-	    usbd_set_alt_interface_index(uaa->device, 1, alt_index)) {
+	    usbd_set_alt_interface_index(uaa->device, iface_index[1], alt_index)) {
 		UBT_ALERT(sc, "could not set alternate setting %d " \
 			"for interface 1!\n", alt_index);
 		goto detach;
@@ -754,21 +779,9 @@ ubt_attach(device_t dev)
 		goto detach;
 	}
 
-	/* Claim all interfaces belonging to the Bluetooth part */
-	for (i = 1;; i++) {
-		iface = usbd_get_iface(uaa->device, i);
-		if (iface == NULL)
-			break;
-		id = usbd_get_interface_descriptor(iface);
-
-		if ((id != NULL) &&
-		    (id->bInterfaceClass == UICLASS_WIRELESS) &&
-		    (id->bInterfaceSubClass == UISUBCLASS_RF) &&
-		    (id->bInterfaceProtocol == UIPROTO_BLUETOOTH)) {
-			usbd_set_parent_iface(uaa->device, i,
-			    uaa->info.bIfaceIndex);
-		}
-	}
+	/* Claim second interface belonging to the Bluetooth part */
+	usbd_set_parent_iface(uaa->device, iface_index[1], uaa->info.bIfaceIndex);
+
 	return (0); /* success */
 
 detach: