The branch main has been updated by hselasky:

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

commit 9d28e15e7bbee7a809eb4ccab558d114d4343312
Author:     Hans Petter Selasky <hsela...@freebsd.org>
AuthorDate: 2022-06-03 08:22:54 +0000
Commit:     Hans Petter Selasky <hsela...@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:

Reply via email to