This is an automated email from the ASF dual-hosted git repository. kasjer pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 0fd0ce44e3d6179be47adb6e9c732dcbec1f16ac Author: Jerzy Kasenberg <[email protected]> AuthorDate: Tue Oct 13 12:46:48 2026 +0200 tinyusb/std_descriptors: Add MS OS 2.0 descriptors for NCM Windows 10+ has an inbox CDC-NCM driver but loads it automatically only when the device reports WINNCM compatible ID. When USBD_NET is NCM add BOS descriptor with Microsoft OS 2.0 platform capability and serve descriptor set with WINNCM compatible ID for the NCM function. bcdUSB is 0x0201 in that case as required for BOS. Controlled by USBD_NET_MS_OS20 (default 1). It can not be combined with USBD_WINDOWS_COMP_ID because Windows ignores MS OS 1.0 descriptors once 2.0 are present. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jerzy Kasenberg <[email protected]> --- .../tinyusb/std_descriptors/src/std_descriptors.c | 75 ++++++++++++++++++++++ hw/usb/tinyusb/std_descriptors/syscfg.yml | 8 +++ 2 files changed, 83 insertions(+) diff --git a/hw/usb/tinyusb/std_descriptors/src/std_descriptors.c b/hw/usb/tinyusb/std_descriptors/src/std_descriptors.c index 793d57cef..67002940c 100755 --- a/hw/usb/tinyusb/std_descriptors/src/std_descriptors.c +++ b/hw/usb/tinyusb/std_descriptors/src/std_descriptors.c @@ -187,7 +187,14 @@ tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_t } #endif /* CFG_TUD_HID */ +/* Microsoft OS 2.0 descriptors for NCM, they need BOS (USB 2.01) */ +#define USBD_MS_OS20 (CFG_TUD_NCM && MYNEWT_VAL(USBD_NET_MS_OS20)) + +#if USBD_MS_OS20 +#define USB_BCD tu_htole16(0x201) +#else #define USB_BCD tu_htole16(0x200) +#endif const tusb_desc_device_t desc_device = { .bLength = sizeof(tusb_desc_device_t), @@ -484,6 +491,74 @@ const char *string_desc_arr[] = { static uint16_t desc_string[MYNEWT_VAL(USBD_STRING_DESCRIPTOR_MAX_LENGTH) + 1]; +#if USBD_MS_OS20 + +#if MYNEWT_VAL(USBD_WINDOWS_COMP_ID) +#error "USBD_NET_MS_OS20 can not be used with USBD_WINDOWS_COMP_ID" +#endif + +#define MS_OS_20_VENDOR_CODE 0x01 +/* wIndex of GET_MS_OS_20_DESCRIPTOR vendor request */ +#define MS_OS_20_DESCRIPTOR_INDEX 0x07 +#define MS_OS_20_DESC_LEN (0x0A + 0x08 + 0x08 + 0x14) +#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + \ + TUD_BOS_MICROSOFT_OS_DESC_LEN) + +static const uint8_t desc_bos[] = { + TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), + TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, MS_OS_20_VENDOR_CODE), +}; + +/* + * Microsoft OS 2.0 descriptor set: NCM function gets WINNCM compatible ID + * so Windows binds its inbox NCM driver (UsbNcm) automatically. + */ +static const uint8_t desc_ms_os_20[] = { + /* Set header: length, type, Windows version (8.1+), total length */ + U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), + U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN), + /* Configuration subset: length, type, config index, reserved, length */ + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), + 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A), + /* Function subset: length, type, first interface, reserved, length */ + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), + ITF_NUM_NET, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN - 0x0A - 0x08), + /* Compatible ID: length, type, compatible ID, sub-compatible ID */ + U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), + 'W', 'I', 'N', 'N', 'C', 'M', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, + "MS OS 2.0 descriptor length mismatch"); + +/* + * Invoked when received GET BOS DESCRIPTOR request + */ +const uint8_t * +tud_descriptor_bos_cb(void) +{ + return desc_bos; +} + +bool +tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, + const tusb_control_request_t *request) +{ + if (request->bmRequestType_bit.type != TUSB_REQ_TYPE_VENDOR || + request->bRequest != MS_OS_20_VENDOR_CODE || + request->wIndex != MS_OS_20_DESCRIPTOR_INDEX) { + return false; + } + if (stage != CONTROL_STAGE_SETUP) { + return true; + } + + return tud_control_xfer(rhport, request, (void *)(uintptr_t)desc_ms_os_20, + sizeof(desc_ms_os_20)); +} +#endif /* USBD_MS_OS20 */ + #if MYNEWT_VAL(USBD_WINDOWS_COMP_ID) #define MICROSOFT_OS_STRING_DESCRIPTOR 0xEE diff --git a/hw/usb/tinyusb/std_descriptors/syscfg.yml b/hw/usb/tinyusb/std_descriptors/syscfg.yml index 0ad95a3fa..78b6115c6 100644 --- a/hw/usb/tinyusb/std_descriptors/syscfg.yml +++ b/hw/usb/tinyusb/std_descriptors/syscfg.yml @@ -386,6 +386,13 @@ syscfg.defs: Number of NCM transfer block buffers in each direction. On full speed 2 can improve throughput at the cost of RAM. value: 1 + USBD_NET_MS_OS20: + description: > + Add BOS and Microsoft OS 2.0 descriptors with WINNCM compatible + ID for NCM function, so Windows loads its NCM driver without + manual installation. Can not be used with USBD_WINDOWS_COMP_ID + (Windows ignores MS OS 1.0 descriptors when 2.0 are present). + value: 1 USBD_WINDOWS_COMP_ID: description: > @@ -411,6 +418,7 @@ syscfg.restrictions: - '(CFG_TUSB_DEBUG == 0) || (USBD_STACK_SIZE >= 400)' - '((USBD_NET != "NCM") && (USBD_NET != "ECM") && (USBD_NET != "RNDIS")) || USBD_COMPOSITE_DEVICE' + - '(USBD_NET != "NCM") || !USBD_NET_MS_OS20 || !USBD_WINDOWS_COMP_ID' syscfg.vals.USBD_COMPOSITE_DEVICE: USBD_DEVICE_CLASS: TUSB_CLASS_MISC
