git: 2f79adc28976 - main - usb: Implement usbd_req_get_bos_descriptor helper
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 02 Nov 2026 03:02:51 UTC
The branch main has been updated by aokblast:
URL: https://cgit.FreeBSD.org/src/commit/?id=2f79adc28976870f4f5ad3a2ce61f2f8da0eb131
commit 2f79adc28976870f4f5ad3a2ce61f2f8da0eb131
Author: ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-05-22 16:21:06 +0000
Commit: ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-11-02 03:02:11 +0000
usb: Implement usbd_req_get_bos_descriptor helper
Get the header or the complete BOS descriptor of SS+ devices.
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57202
---
sys/dev/usb/usb.h | 3 +++
sys/dev/usb/usb_request.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/usb/usb_request.h | 4 +++
3 files changed, 69 insertions(+)
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index 8eb36a24bbcd..90078df11361 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -309,6 +309,9 @@ struct usb_device_descriptor {
} __packed;
typedef struct usb_device_descriptor usb_device_descriptor_t;
+/* Maximum sane wTotalLength for a BOS descriptor */
+#define USB_BOS_DESC_MAX_LEN 4096
+
/* Binary Device Object Store (BOS) */
struct usb_bos_descriptor {
uByte bLength;
diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c
index df6dadae541b..2a57c75a85d2 100644
--- a/sys/dev/usb/usb_request.c
+++ b/sys/dev/usb/usb_request.c
@@ -1535,6 +1535,68 @@ usbd_req_get_ss_hub_descriptor(struct usb_device *udev, struct mtx *mtx,
return (usbd_do_request(udev, mtx, &req, hd));
}
+/*------------------------------------------------------------------------*
+ * usbd_req_get_bos_descriptor
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_get_bos_descriptor(struct usb_device *udev, struct mtx *mtx,
+ struct usb_bos_descriptor *bd)
+{
+ return (usbd_req_get_desc(udev, mtx, NULL, bd, sizeof(*bd),
+ sizeof(*bd), 0, UDESC_BOS, 0, 3));
+}
+
+/*------------------------------------------------------------------------*
+ * usbd_req_get_bos_descriptor_full
+ *
+ * Returns:
+ * 0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_get_bos_descriptor_full(struct usb_device *udev, struct mtx *mtx,
+ struct usb_bos_descriptor **bdp)
+{
+ struct usb_bos_descriptor bd;
+ struct usb_bos_descriptor *bdesc;
+ uint32_t len;
+ usb_error_t err;
+
+ *bdp = NULL;
+
+ err = usbd_req_get_bos_descriptor(udev, mtx, &bd);
+ if (err)
+ return (err);
+
+ len = UGETW(bd.wTotalLength);
+ if (len < sizeof(bd) || len > USB_BOS_DESC_MAX_LEN) {
+ DPRINTFN(0, "BOS descriptor wTotalLength %u is invalid\n",
+ len);
+ return (USB_ERR_INVAL);
+ }
+
+ bdesc = malloc(len, M_USBDEV, M_WAITOK | M_ZERO);
+ if (bdesc == NULL)
+ return (USB_ERR_NOMEM);
+ err = usbd_req_get_desc(udev, mtx, NULL, bdesc, len, len, 0,
+ UDESC_BOS, 0, 3);
+ if (err) {
+ free(bdesc, M_USBDEV);
+ return (err);
+ }
+ if (UGETW(bdesc->wTotalLength) != len) {
+ DPRINTFN(0, "BOS descriptor length changed\n");
+ free(bdesc, M_USBDEV);
+ return (USB_ERR_INVAL);
+ }
+ *bdp = bdesc;
+ return (0);
+}
+
/*------------------------------------------------------------------------*
* usbd_req_get_hub_status
*
diff --git a/sys/dev/usb/usb_request.h b/sys/dev/usb/usb_request.h
index f7ccd84eb69c..8e7d3632322e 100644
--- a/sys/dev/usb/usb_request.h
+++ b/sys/dev/usb/usb_request.h
@@ -60,6 +60,10 @@ usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev,
usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev,
struct mtx *mtx, struct usb_hub_ss_descriptor *hd,
uint8_t nports);
+usb_error_t usbd_req_get_bos_descriptor(struct usb_device *udev,
+ struct mtx *mtx, struct usb_bos_descriptor *desc);
+usb_error_t usbd_req_get_bos_descriptor_full(struct usb_device *udev,
+ struct mtx *mtx, struct usb_bos_descriptor **pdesc);
usb_error_t usbd_req_get_hub_status(struct usb_device *udev, struct mtx *mtx,
struct usb_hub_status *st);
usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx,