The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=37e3b664669288dc1775a6f8fb0d84b962fc9c5b

commit 37e3b664669288dc1775a6f8fb0d84b962fc9c5b
Author:     Vladimir Kondratyev <w...@freebsd.org>
AuthorDate: 2025-08-17 21:00:45 +0000
Commit:     Vladimir Kondratyev <w...@freebsd.org>
CommitDate: 2025-08-17 21:00:45 +0000

    usbhid(4): Implement USB_GET_DEVICEINFO ioctl
    
    With factoring out of supporting code from ugen(4) driver.
    The ioctl is used in FIDO/U2F security key drivers to get
    USB product and manufacturer strings.
    
    PR:             264843
    Reviewed by:    emaste
    Differential Revision:  https://reviews.freebsd.org/D51609
---
 sys/dev/usb/input/usbhid.c |  4 ++++
 sys/dev/usb/usb_device.c   | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/usb/usb_generic.c  | 37 +----------------------------------
 sys/dev/usb/usbdi.h        |  3 +++
 4 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/sys/dev/usb/input/usbhid.c b/sys/dev/usb/input/usbhid.c
index 255e639621fe..cba3f34053e5 100644
--- a/sys/dev/usb/input/usbhid.c
+++ b/sys/dev/usb/input/usbhid.c
@@ -707,6 +707,10 @@ usbhid_ioctl(device_t dev, device_t child __unused, 
unsigned long cmd,
                if (error == 0)
                        ucr->ucr_actlen = UGETW(req.ctrl.wLength);
                break;
+       case USB_GET_DEVICEINFO:
+               error = usbd_fill_deviceinfo(sc->sc_udev,
+                   (struct usb_device_info *)data);
+               break;
        default:
                error = EINVAL;
        }
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 60c2d6745b3f..f0989972f49f 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -3111,3 +3111,51 @@ usbd_get_endpoint_mode(struct usb_device *udev, struct 
usb_endpoint *ep)
 {
        return (ep->ep_mode);
 }
+
+/*------------------------------------------------------------------------*
+ *     usbd_fill_deviceinfo
+ *
+ * This function dumps information about an USB device to the
+ * structure pointed to by the "di" argument.
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+int
+usbd_fill_deviceinfo(struct usb_device *udev, struct usb_device_info *di)
+{
+       struct usb_device *hub;
+
+       bzero(di, sizeof(di[0]));
+
+       di->udi_bus = device_get_unit(udev->bus->bdev);
+       di->udi_addr = udev->address;
+       di->udi_index = udev->device_index;
+       strlcpy(di->udi_serial, usb_get_serial(udev), sizeof(di->udi_serial));
+       strlcpy(di->udi_vendor, usb_get_manufacturer(udev), 
sizeof(di->udi_vendor));
+       strlcpy(di->udi_product, usb_get_product(udev), 
sizeof(di->udi_product));
+       usb_printbcd(di->udi_release, sizeof(di->udi_release),
+           UGETW(udev->ddesc.bcdDevice));
+       di->udi_vendorNo = UGETW(udev->ddesc.idVendor);
+       di->udi_productNo = UGETW(udev->ddesc.idProduct);
+       di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice);
+       di->udi_class = udev->ddesc.bDeviceClass;
+       di->udi_subclass = udev->ddesc.bDeviceSubClass;
+       di->udi_protocol = udev->ddesc.bDeviceProtocol;
+       di->udi_config_no = udev->curr_config_no;
+       di->udi_config_index = udev->curr_config_index;
+       di->udi_power = udev->flags.self_powered ? 0 : udev->power;
+       di->udi_speed = udev->speed;
+       di->udi_mode = udev->flags.usb_mode;
+       di->udi_power_mode = udev->power_mode;
+       di->udi_suspended = udev->flags.peer_suspended;
+
+       hub = udev->parent_hub;
+       if (hub) {
+               di->udi_hubaddr = hub->address;
+               di->udi_hubindex = hub->device_index;
+               di->udi_hubport = udev->port_no;
+       }
+       return (0);
+}
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index c0af27d77e5d..ccb0b2184ec4 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -831,42 +831,7 @@ ugen_get_iface_driver(struct usb_fifo *f, struct 
usb_gen_descriptor *ugd)
 int
 ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di)
 {
-       struct usb_device *udev;
-       struct usb_device *hub;
-
-       udev = f->udev;
-
-       bzero(di, sizeof(di[0]));
-
-       di->udi_bus = device_get_unit(udev->bus->bdev);
-       di->udi_addr = udev->address;
-       di->udi_index = udev->device_index;
-       strlcpy(di->udi_serial, usb_get_serial(udev), sizeof(di->udi_serial));
-       strlcpy(di->udi_vendor, usb_get_manufacturer(udev), 
sizeof(di->udi_vendor));
-       strlcpy(di->udi_product, usb_get_product(udev), 
sizeof(di->udi_product));
-       usb_printbcd(di->udi_release, sizeof(di->udi_release),
-           UGETW(udev->ddesc.bcdDevice));
-       di->udi_vendorNo = UGETW(udev->ddesc.idVendor);
-       di->udi_productNo = UGETW(udev->ddesc.idProduct);
-       di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice);
-       di->udi_class = udev->ddesc.bDeviceClass;
-       di->udi_subclass = udev->ddesc.bDeviceSubClass;
-       di->udi_protocol = udev->ddesc.bDeviceProtocol;
-       di->udi_config_no = udev->curr_config_no;
-       di->udi_config_index = udev->curr_config_index;
-       di->udi_power = udev->flags.self_powered ? 0 : udev->power;
-       di->udi_speed = udev->speed;
-       di->udi_mode = udev->flags.usb_mode;
-       di->udi_power_mode = udev->power_mode;
-       di->udi_suspended = udev->flags.peer_suspended;
-
-       hub = udev->parent_hub;
-       if (hub) {
-               di->udi_hubaddr = hub->address;
-               di->udi_hubindex = hub->device_index;
-               di->udi_hubport = udev->port_no;
-       }
-       return (0);
+       return (usbd_fill_deviceinfo(f->udev, di));
 }
 
 int
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 08d130aa2868..0826d9f078c4 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -38,6 +38,7 @@ struct usb_process;
 struct usb_proc_msg;
 struct usb_mbuf;
 struct usb_fs_privdata;
+struct usb_device_info;
 struct mbuf;
 
 typedef enum { /* keep in sync with usb_errstr_table */
@@ -587,6 +588,8 @@ usb_error_t usbd_set_endpoint_mode(struct usb_device *udev,
                        struct usb_endpoint *ep, uint8_t ep_mode);
 uint8_t                usbd_get_endpoint_mode(struct usb_device *udev,
                        struct usb_endpoint *ep);
+int            usbd_fill_deviceinfo(struct usb_device *udev,
+                       struct usb_device_info *di);
 
 const struct usb_device_id *usbd_lookup_id_by_info(
            const struct usb_device_id *id, usb_size_t sizeof_id,

Reply via email to