From 9d28e15e7bbee7a809eb4ccab558d114d4343312 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 3 Jun 2022 10:22:54 +0200 Subject: [PATCH] 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 | 65 ++++++++++++--------- 1 file changed, 39 insertions(+), 26 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); + /* Claim second interface belonging to the Bluetooth part */ + usbd_set_parent_iface(uaa->device, iface_index[1], uaa->info.bIfaceIndex); - 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); - } - } return (0); /* success */ detach: