diff --git a/drivers/usb/udc/Kconfig b/drivers/usb/udc/Kconfig index fd5e25cf11344..40a75ea68800f 100644 --- a/drivers/usb/udc/Kconfig +++ b/drivers/usb/udc/Kconfig @@ -11,6 +11,16 @@ menuconfig UDC_DRIVER if UDC_DRIVER +config UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT + bool + +config UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED + bool "Allow High-Speed chirp" + default y if UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT + help + Allow High-Speed capable device to operate at High-Speed. Disable this + option to force Full-Speed only operation. + config UDC_BUF_COUNT int "Number of buffers in the pool" range 16 256 diff --git a/drivers/usb/udc/Kconfig.dwc2 b/drivers/usb/udc/Kconfig.dwc2 index 2f40c8f71a283..9486f88c3ba5b 100644 --- a/drivers/usb/udc/Kconfig.dwc2 +++ b/drivers/usb/udc/Kconfig.dwc2 @@ -5,6 +5,7 @@ config UDC_DWC2 bool "DWC2 USB device controller driver" default y depends on DT_HAS_SNPS_DWC2_ENABLED + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT select NRFS if NRFS_HAS_VBUS_DETECTOR_SERVICE select NRFS_VBUS_DETECTOR_SERVICE_ENABLED if NRFS_HAS_VBUS_DETECTOR_SERVICE select EVENTS diff --git a/drivers/usb/udc/Kconfig.mcux b/drivers/usb/udc/Kconfig.mcux index d68b21d171039..7ebace0e7f7c4 100644 --- a/drivers/usb/udc/Kconfig.mcux +++ b/drivers/usb/udc/Kconfig.mcux @@ -5,6 +5,7 @@ config UDC_NXP_EHCI bool "NXP MCUX USB EHCI Device controller driver" default y depends on DT_HAS_NXP_EHCI_ENABLED + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT select PINCTRL select NOCACHE_MEMORY if CPU_HAS_DCACHE imply UDC_BUF_FORCE_NOCACHE @@ -16,6 +17,7 @@ config UDC_NXP_IP3511 bool "NXP MCUX USB IP3511 Device controller driver" default y depends on DT_HAS_NXP_LPCIP3511_ENABLED + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT select PINCTRL imply UDC_WORKQUEUE help diff --git a/drivers/usb/udc/Kconfig.skeleton b/drivers/usb/udc/Kconfig.skeleton index bf7eb01323bf1..b6d96e0b89585 100644 --- a/drivers/usb/udc/Kconfig.skeleton +++ b/drivers/usb/udc/Kconfig.skeleton @@ -5,6 +5,7 @@ config UDC_SKELETON bool "Skeleton for an USB device controller driver" default y depends on DT_HAS_ZEPHYR_UDC_SKELETON_ENABLED + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT help Skeleton for an USB device controller driver. diff --git a/drivers/usb/udc/Kconfig.virtual b/drivers/usb/udc/Kconfig.virtual index b84e14ba971e1..7aff8ca8e20d4 100644 --- a/drivers/usb/udc/Kconfig.virtual +++ b/drivers/usb/udc/Kconfig.virtual @@ -6,6 +6,7 @@ config UDC_VIRTUAL select UVB default y depends on DT_HAS_ZEPHYR_UDC_VIRTUAL_ENABLED + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT help Virtual USB device controller driver. diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 2339356d8823c..915a4647e2736 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -2040,15 +2040,21 @@ static int udc_dwc2_init_controller(const struct device *dev) case USB_DWC2_GHWCFG2_HSPHYTYPE_ULPI: gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB20 | USB_DWC2_GUSBCFG_ULPI_UTMI_SEL_ULPI; - dcfg |= USB_DWC2_DCFG_DEVSPD_USBHS20 - << USB_DWC2_DCFG_DEVSPD_POS; + if (IS_ENABLED(CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED)) { + dcfg |= usb_dwc2_set_dcfg_devspd(USB_DWC2_DCFG_DEVSPD_USBHS20); + } else { + dcfg |= usb_dwc2_set_dcfg_devspd(USB_DWC2_DCFG_DEVSPD_USBFS20); + } hs_phy = true; break; case USB_DWC2_GHWCFG2_HSPHYTYPE_UTMIPLUS: gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB20 | USB_DWC2_GUSBCFG_ULPI_UTMI_SEL_UTMI; - dcfg |= USB_DWC2_DCFG_DEVSPD_USBHS20 - << USB_DWC2_DCFG_DEVSPD_POS; + if (IS_ENABLED(CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED)) { + dcfg |= usb_dwc2_set_dcfg_devspd(USB_DWC2_DCFG_DEVSPD_USBHS20); + } else { + dcfg |= usb_dwc2_set_dcfg_devspd(USB_DWC2_DCFG_DEVSPD_USBFS20); + } hs_phy = true; break; case USB_DWC2_GHWCFG2_HSPHYTYPE_NO_HS: @@ -2059,8 +2065,7 @@ static int udc_dwc2_init_controller(const struct device *dev) gusbcfg |= USB_DWC2_GUSBCFG_PHYSEL_USB11; } - dcfg |= USB_DWC2_DCFG_DEVSPD_USBFS1148 - << USB_DWC2_DCFG_DEVSPD_POS; + dcfg |= usb_dwc2_set_dcfg_devspd(USB_DWC2_DCFG_DEVSPD_USBFS1148); hs_phy = false; } diff --git a/include/zephyr/usb/usbd.h b/include/zephyr/usb/usbd.h index b85f6e2507fd5..5850643b31f7b 100644 --- a/include/zephyr/usb/usbd.h +++ b/include/zephyr/usb/usbd.h @@ -37,6 +37,12 @@ extern "C" { * @{ */ +/* 1 if USB device stack is compiled with High-Speed support */ +#define USBD_SUPPORTS_HIGH_SPEED IS_EQ(CONFIG_USBD_MAX_SPEED, 1) + +/* Maximum bulk max packet size the stack supports */ +#define USBD_MAX_BULK_MPS COND_CODE_1(USBD_SUPPORTS_HIGH_SPEED, (512), (64)) + /* * The USB Unicode bString is encoded in UTF16LE, which means it takes up * twice the amount of bytes than the same string encoded in ASCII7. diff --git a/samples/subsys/usb/common/sample_usbd_init.c b/samples/subsys/usb/common/sample_usbd_init.c index 9a187bc5f8df8..69642372a585a 100644 --- a/samples/subsys/usb/common/sample_usbd_init.c +++ b/samples/subsys/usb/common/sample_usbd_init.c @@ -126,7 +126,8 @@ struct usbd_context *sample_usbd_setup_device(usbd_msg_cb_t msg_cb) } /* doc add string descriptor end */ - if (usbd_caps_speed(&sample_usbd) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_caps_speed(&sample_usbd) == USBD_SPEED_HS) { err = usbd_add_configuration(&sample_usbd, USBD_SPEED_HS, &sample_hs_config); if (err) { diff --git a/subsys/usb/device_next/Kconfig b/subsys/usb/device_next/Kconfig index 52ce9d990858e..68ae7559845c3 100644 --- a/subsys/usb/device_next/Kconfig +++ b/subsys/usb/device_next/Kconfig @@ -16,6 +16,26 @@ module = USBD module-str = usbd source "subsys/logging/Kconfig.template.log_config" +choice USBD_MAX_SPEED_CHOICE + prompt "Max supported connection speed" + default USBD_MAX_SPEED_HIGH if UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT + default USBD_MAX_SPEED_FULL + +config USBD_MAX_SPEED_HIGH + bool "High-Speed" + depends on UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT + +config USBD_MAX_SPEED_FULL + bool "Full-Speed" + depends on !UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED + +endchoice + +config USBD_MAX_SPEED + int + default 0 if USBD_MAX_SPEED_FULL + default 1 if USBD_MAX_SPEED_HIGH + config USBD_SHELL bool "USB device shell" depends on SHELL diff --git a/subsys/usb/device_next/class/bt_hci.c b/subsys/usb/device_next/class/bt_hci.c index a7aed6378c623..150ef9569c205 100644 --- a/subsys/usb/device_next/class/bt_hci.c +++ b/subsys/usb/device_next/class/bt_hci.c @@ -68,13 +68,13 @@ static K_FIFO_DEFINE(bt_hci_tx_queue); /* * Transfers through three endpoints proceed in a synchronous manner, - * with maximum packet size of high speed bulk endpoint. + * with maximum packet size of max supported speed bulk endpoint. * * REVISE: global (bulk, interrupt, iso) specific pools would be more * RAM usage efficient. */ UDC_BUF_POOL_DEFINE(bt_hci_ep_pool, - 3, 512, + 3, USBD_MAX_BULK_MPS, sizeof(struct udc_buf_info), NULL); /* HCI RX/TX threads */ static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); @@ -138,7 +138,8 @@ static uint8_t bt_hci_get_bulk_in(struct usbd_class_data *const c_data) struct bt_hci_data *data = usbd_class_get_private(c_data); struct usbd_bt_hci_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_in_ep.bEndpointAddress; } @@ -151,7 +152,8 @@ static uint8_t bt_hci_get_bulk_out(struct usbd_class_data *const c_data) struct bt_hci_data *data = usbd_class_get_private(c_data); struct usbd_bt_hci_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_out_ep.bEndpointAddress; } @@ -449,7 +451,7 @@ static void *bt_hci_get_desc(struct usbd_class_data *const c_data, { struct bt_hci_data *data = usbd_class_get_private(c_data); - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return data->hs_desc; } diff --git a/subsys/usb/device_next/class/loopback.c b/subsys/usb/device_next/class/loopback.c index 0e5ba96f45932..85896cd549e21 100644 --- a/subsys/usb/device_next/class/loopback.c +++ b/subsys/usb/device_next/class/loopback.c @@ -254,7 +254,7 @@ static void *lb_get_desc(struct usbd_class_data *const c_data, { struct lb_data *data = usbd_class_get_private(c_data); - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return data->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_cdc_acm.c b/subsys/usb/device_next/class/usbd_cdc_acm.c index 15e3cab90a0e4..d3fef3b83b0f3 100644 --- a/subsys/usb/device_next/class/usbd_cdc_acm.c +++ b/subsys/usb/device_next/class/usbd_cdc_acm.c @@ -36,7 +36,7 @@ LOG_MODULE_REGISTER(usbd_cdc_acm, CONFIG_USBD_CDC_ACM_LOG_LEVEL); UDC_BUF_POOL_DEFINE(cdc_acm_ep_pool, DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) * 2, - 512, sizeof(struct udc_buf_info), NULL); + USBD_MAX_BULK_MPS, sizeof(struct udc_buf_info), NULL); #define CDC_ACM_DEFAULT_LINECODING {sys_cpu_to_le32(115200), 0, 0, 8} #define CDC_ACM_DEFAULT_INT_EP_MPS 16 @@ -171,7 +171,8 @@ static uint8_t cdc_acm_get_int_in(struct usbd_class_data *const c_data) const struct cdc_acm_uart_config *cfg = dev->config; struct usbd_cdc_acm_desc *desc = cfg->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_int_ep.bEndpointAddress; } @@ -185,7 +186,8 @@ static uint8_t cdc_acm_get_bulk_in(struct usbd_class_data *const c_data) const struct cdc_acm_uart_config *cfg = dev->config; struct usbd_cdc_acm_desc *desc = cfg->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_hs_in_ep.bEndpointAddress; } @@ -199,7 +201,8 @@ static uint8_t cdc_acm_get_bulk_out(struct usbd_class_data *const c_data) const struct cdc_acm_uart_config *cfg = dev->config; struct usbd_cdc_acm_desc *desc = cfg->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_hs_out_ep.bEndpointAddress; } @@ -210,7 +213,8 @@ static size_t cdc_acm_get_bulk_mps(struct usbd_class_data *const c_data) { struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data); - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return 512U; } @@ -350,7 +354,7 @@ static void *usbd_cdc_acm_get_desc(struct usbd_class_data *const c_data, const struct device *dev = usbd_class_get_private(c_data); const struct cdc_acm_uart_config *cfg = dev->config; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return cfg->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_cdc_ecm.c b/subsys/usb/device_next/class/usbd_cdc_ecm.c index e43f38bed6425..55aa2798a6471 100644 --- a/subsys/usb/device_next/class/usbd_cdc_ecm.c +++ b/subsys/usb/device_next/class/usbd_cdc_ecm.c @@ -106,7 +106,8 @@ static uint8_t cdc_ecm_get_int_in(struct usbd_class_data *const c_data) struct cdc_ecm_eth_data *data = dev->data; struct usbd_cdc_ecm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_int_ep.bEndpointAddress; } @@ -120,7 +121,8 @@ static uint8_t cdc_ecm_get_bulk_in(struct usbd_class_data *const c_data) struct cdc_ecm_eth_data *data = dev->data; struct usbd_cdc_ecm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_1_hs_in_ep.bEndpointAddress; } @@ -131,7 +133,8 @@ static uint16_t cdc_ecm_get_bulk_in_mps(struct usbd_class_data *const c_data) { struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data); - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return 512U; } @@ -145,7 +148,8 @@ static uint8_t cdc_ecm_get_bulk_out(struct usbd_class_data *const c_data) struct cdc_ecm_eth_data *data = dev->data; struct usbd_cdc_ecm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_1_hs_out_ep.bEndpointAddress; } @@ -475,7 +479,7 @@ static void *usbd_cdc_ecm_get_desc(struct usbd_class_data *const c_data, const struct device *dev = usbd_class_get_private(c_data); struct cdc_ecm_eth_data *const data = dev->data; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return data->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_cdc_ncm.c b/subsys/usb/device_next/class/usbd_cdc_ncm.c index a7ffb5f23f74d..c92754f72f839 100644 --- a/subsys/usb/device_next/class/usbd_cdc_ncm.c +++ b/subsys/usb/device_next/class/usbd_cdc_ncm.c @@ -249,7 +249,8 @@ static uint8_t cdc_ncm_get_int_in(struct usbd_class_data *const c_data) struct cdc_ncm_eth_data *data = dev->data; struct usbd_cdc_ncm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_int_ep.bEndpointAddress; } @@ -263,7 +264,8 @@ static uint8_t cdc_ncm_get_bulk_in(struct usbd_class_data *const c_data) struct cdc_ncm_eth_data *data = dev->data; struct usbd_cdc_ncm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_1_hs_in_ep.bEndpointAddress; } @@ -274,7 +276,8 @@ static uint16_t cdc_ncm_get_bulk_in_mps(struct usbd_class_data *const c_data) { struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data); - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return 512U; } @@ -288,7 +291,8 @@ static uint8_t cdc_ncm_get_bulk_out(struct usbd_class_data *const c_data) struct cdc_ncm_eth_data *data = dev->data; struct usbd_cdc_ncm_desc *desc = data->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if1_1_hs_out_ep.bEndpointAddress; } @@ -1009,7 +1013,7 @@ static void *usbd_cdc_ncm_get_desc(struct usbd_class_data *const c_data, const struct device *dev = usbd_class_get_private(c_data); struct cdc_ncm_eth_data *const data = dev->data; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return data->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_hid.c b/subsys/usb/device_next/class/usbd_hid.c index a3672148fd3d5..fd10eba3c8506 100644 --- a/subsys/usb/device_next/class/usbd_hid.c +++ b/subsys/usb/device_next/class/usbd_hid.c @@ -479,7 +479,7 @@ static void *usbd_hid_get_desc(struct usbd_class_data *const c_data, const struct device *dev = usbd_class_get_private(c_data); const struct hid_device_config *dcfg = dev->config; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return dcfg->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_midi2.c b/subsys/usb/device_next/class/usbd_midi2.c index 20d66590b5fae..1afab63b4d92f 100644 --- a/subsys/usb/device_next/class/usbd_midi2.c +++ b/subsys/usb/device_next/class/usbd_midi2.c @@ -344,7 +344,11 @@ static void *usbd_midi_class_get_desc(struct usbd_class_data *const class_data, LOG_DBG("Get descriptors for %s", dev->name); - return (speed == USBD_SPEED_HS) ? config->hs_descs : config->fs_descs; + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { + return config->hs_descs; + } + + return config->fs_descs; } @@ -382,7 +386,8 @@ static uint8_t usbd_midi_get_bulk_in(struct usbd_class_data *const class_data) const struct device *dev = usbd_class_get_private(class_data); const struct usbd_midi_config *cfg = dev->config; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return cfg->desc->if1_1_in_ep_hs.bEndpointAddress; } @@ -395,7 +400,8 @@ static uint8_t usbd_midi_get_bulk_out(struct usbd_class_data *const class_data) const struct device *dev = usbd_class_get_private(class_data); const struct usbd_midi_config *cfg = dev->config; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return cfg->desc->if1_1_out_ep_hs.bEndpointAddress; } diff --git a/subsys/usb/device_next/class/usbd_msc.c b/subsys/usb/device_next/class/usbd_msc.c index 6f8b7c4622634..07d5d09347f6a 100644 --- a/subsys/usb/device_next/class/usbd_msc.c +++ b/subsys/usb/device_next/class/usbd_msc.c @@ -61,7 +61,7 @@ struct CSW { #define MSC_NUM_INSTANCES CONFIG_USBD_MSC_INSTANCES_COUNT /* Can be 64 if device is not High-Speed capable */ -#define MSC_BUF_SIZE 512 +#define MSC_BUF_SIZE USBD_MAX_BULK_MPS UDC_BUF_POOL_DEFINE(msc_ep_pool, MSC_NUM_INSTANCES * 2, MSC_BUF_SIZE, @@ -149,7 +149,8 @@ static uint8_t msc_get_bulk_in(struct usbd_class_data *const c_data) struct msc_bot_ctx *ctx = usbd_class_get_private(c_data); struct msc_bot_desc *desc = ctx->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_in_ep.bEndpointAddress; } @@ -162,7 +163,8 @@ static uint8_t msc_get_bulk_out(struct usbd_class_data *const c_data) struct msc_bot_ctx *ctx = usbd_class_get_private(c_data); struct msc_bot_desc *desc = ctx->desc; - if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { return desc->if0_hs_out_ep.bEndpointAddress; } @@ -755,7 +757,7 @@ static void *msc_bot_get_desc(struct usbd_class_data *const c_data, { struct msc_bot_ctx *ctx = usbd_class_get_private(c_data); - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return ctx->hs_desc; } diff --git a/subsys/usb/device_next/class/usbd_uac2.c b/subsys/usb/device_next/class/usbd_uac2.c index 77bfde9c47222..2e55a9a017afc 100644 --- a/subsys/usb/device_next/class/usbd_uac2.c +++ b/subsys/usb/device_next/class/usbd_uac2.c @@ -890,7 +890,7 @@ static void *uac2_get_desc(struct usbd_class_data *const c_data, struct device *dev = usbd_class_get_private(c_data); const struct uac2_cfg *cfg = dev->config; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { return cfg->hs_descriptors; } diff --git a/subsys/usb/device_next/usbd_ch9.c b/subsys/usb/device_next/usbd_ch9.c index b9bfd00b3ae55..827206af7c377 100644 --- a/subsys/usb/device_next/usbd_ch9.c +++ b/subsys/usb/device_next/usbd_ch9.c @@ -472,9 +472,11 @@ static int sreq_get_desc_cfg(struct usbd_context *const uds_ctx, /* * If the other-speed-configuration-descriptor is requested and the - * controller does not support high speed, respond with an error. + * controller (or stack) does not support high speed, respond with + * an error. */ - if (other_cfg && usbd_caps_speed(uds_ctx) != USBD_SPEED_HS) { + if (other_cfg && !(USBD_SUPPORTS_HIGH_SPEED && + (usbd_caps_speed(uds_ctx) == USBD_SPEED_HS))) { errno = -ENOTSUP; return 0; } @@ -691,7 +693,8 @@ static int sreq_get_dev_qualifier(struct usbd_context *const uds_ctx, * If the Device Qualifier descriptor is requested and the controller * does not support high speed, respond with an error. */ - if (usbd_caps_speed(uds_ctx) != USBD_SPEED_HS) { + if (!USBD_SUPPORTS_HIGH_SPEED || + usbd_caps_speed(uds_ctx) != USBD_SPEED_HS) { errno = -ENOTSUP; return 0; } diff --git a/subsys/usb/device_next/usbd_class.c b/subsys/usb/device_next/usbd_class.c index eeb2cfa5a20a3..48f3d6d72681c 100644 --- a/subsys/usb/device_next/usbd_class.c +++ b/subsys/usb/device_next/usbd_class.c @@ -215,7 +215,7 @@ usbd_class_node_get(const char *name, const enum usbd_speed speed) return c_nd; } } - } else if (speed == USBD_SPEED_HS) { + } else if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, usbd_class_node, c_nd) { if (strcmp(name, c_nd->c_data->name) == 0) { @@ -358,7 +358,7 @@ int usbd_register_all_classes(struct usbd_context *const uds_ctx, { int ret; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, usbd_class_node, c_nd) { if (blocklist != NULL && is_blocklisted(c_nd, blocklist)) { continue; @@ -430,8 +430,8 @@ int usbd_unregister_class(struct usbd_context *const uds_ctx, /* TODO: The use of atomic here does not make this code thread safe. * The atomic should be changed to something else. */ - if (speed == USBD_SPEED_HS) { - STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_fs, + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { + STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, usbd_class_node, i) { if ((i->c_data == c_nd->c_data) && atomic_test_bit(&i->state, USBD_CCTX_REGISTERED)) { @@ -440,7 +440,7 @@ int usbd_unregister_class(struct usbd_context *const uds_ctx, } } } else { - STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, + STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_fs, usbd_class_node, i) { if ((i->c_data == c_nd->c_data) && atomic_test_bit(&i->state, USBD_CCTX_REGISTERED)) { @@ -470,7 +470,7 @@ int usbd_unregister_all_classes(struct usbd_context *const uds_ctx, { int ret; - if (speed == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { STRUCT_SECTION_FOREACH_ALTERNATE(usbd_class_hs, usbd_class_node, c_nd) { ret = usbd_unregister_class(uds_ctx, c_nd->c_data->name, speed, cfg); diff --git a/subsys/usb/device_next/usbd_config.c b/subsys/usb/device_next/usbd_config.c index 9d8627028a99b..8a589722e25d7 100644 --- a/subsys/usb/device_next/usbd_config.c +++ b/subsys/usb/device_next/usbd_config.c @@ -266,6 +266,12 @@ int usbd_add_configuration(struct usbd_context *const uds_ctx, goto add_configuration_exit; } + if (speed == USBD_SPEED_HS && !USBD_SUPPORTS_HIGH_SPEED) { + LOG_ERR("Stack was compiled without High-Speed support"); + ret = -ENOTSUP; + goto add_configuration_exit; + } + if (speed == USBD_SPEED_HS && usbd_caps_speed(uds_ctx) == USBD_SPEED_FS) { LOG_ERR("Controller doesn't support HS"); diff --git a/subsys/usb/device_next/usbd_core.c b/subsys/usb/device_next/usbd_core.c index 64c0a0ab654cd..9f24530fc2c2c 100644 --- a/subsys/usb/device_next/usbd_core.c +++ b/subsys/usb/device_next/usbd_core.c @@ -228,12 +228,14 @@ int usbd_device_shutdown_core(struct usbd_context *const uds_ctx) struct usbd_config_node *cfg_nd; int ret; - SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->hs_configs, cfg_nd, node) { - uint8_t cfg_value = usbd_config_get_value(cfg_nd); - - ret = usbd_class_remove_all(uds_ctx, USBD_SPEED_HS, cfg_value); - if (ret) { - LOG_ERR("Failed to cleanup registered classes, %d", ret); + if (USBD_SUPPORTS_HIGH_SPEED) { + SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->hs_configs, cfg_nd, node) { + uint8_t cfg_value = usbd_config_get_value(cfg_nd); + + ret = usbd_class_remove_all(uds_ctx, USBD_SPEED_HS, cfg_value); + if (ret) { + LOG_ERR("Failed to cleanup registered classes, %d", ret); + } } } diff --git a/subsys/usb/device_next/usbd_device.h b/subsys/usb/device_next/usbd_device.h index e2f0d98ab8b4e..8d29a19e6a9d9 100644 --- a/subsys/usb/device_next/usbd_device.h +++ b/subsys/usb/device_next/usbd_device.h @@ -45,7 +45,7 @@ static inline uint8_t usbd_get_num_configs(const struct usbd_context *const uds_ if (speed == USBD_SPEED_FS) { desc = uds_ctx->fs_desc; - } else if (speed == USBD_SPEED_HS) { + } else if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { desc = uds_ctx->hs_desc; } else { return 0; @@ -70,7 +70,7 @@ static inline void usbd_set_num_configs(struct usbd_context *const uds_ctx, if (speed == USBD_SPEED_FS) { desc = uds_ctx->fs_desc; - } else if (speed == USBD_SPEED_HS) { + } else if (USBD_SUPPORTS_HIGH_SPEED && speed == USBD_SPEED_HS) { desc = uds_ctx->hs_desc; } else { return; diff --git a/subsys/usb/device_next/usbd_init.c b/subsys/usb/device_next/usbd_init.c index fc31c8a211a93..021fc8f2fca5a 100644 --- a/subsys/usb/device_next/usbd_init.c +++ b/subsys/usb/device_next/usbd_init.c @@ -281,18 +281,20 @@ int usbd_init_configurations(struct usbd_context *const uds_ctx) usbd_init_update_fs_mps0(uds_ctx); - SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->hs_configs, cfg_nd, node) { - int ret; + if (USBD_SUPPORTS_HIGH_SPEED) { + SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->hs_configs, cfg_nd, node) { + int ret; - ret = init_configuration(uds_ctx, USBD_SPEED_HS, cfg_nd); - if (ret) { - LOG_ERR("Failed to init HS configuration %u", - usbd_config_get_value(cfg_nd)); - return ret; - } + ret = init_configuration(uds_ctx, USBD_SPEED_HS, cfg_nd); + if (ret) { + LOG_ERR("Failed to init HS configuration %u", + usbd_config_get_value(cfg_nd)); + return ret; + } - LOG_INF("HS bNumConfigurations %u", - usbd_get_num_configs(uds_ctx, USBD_SPEED_HS)); + LOG_INF("HS bNumConfigurations %u", + usbd_get_num_configs(uds_ctx, USBD_SPEED_HS)); + } } SYS_SLIST_FOR_EACH_CONTAINER(&uds_ctx->fs_configs, cfg_nd, node) { diff --git a/subsys/usb/device_next/usbd_shell.c b/subsys/usb/device_next/usbd_shell.c index 6b321204a24a3..4597143e78b96 100644 --- a/subsys/usb/device_next/usbd_shell.c +++ b/subsys/usb/device_next/usbd_shell.c @@ -147,7 +147,8 @@ static int register_classes(const struct shell *sh) shell_print(sh, "dev: register FS %s", c_nd->c_data->name); } - if (usbd_caps_speed(my_uds_ctx) != USBD_SPEED_HS) { + if (!USBD_SUPPORTS_HIGH_SPEED || + usbd_caps_speed(my_uds_ctx) != USBD_SPEED_HS) { return 0; } diff --git a/tests/subsys/usb/device_next/src/main.c b/tests/subsys/usb/device_next/src/main.c index 68dce57dfda46..0534a56141fad 100644 --- a/tests/subsys/usb/device_next/src/main.c +++ b/tests/subsys/usb/device_next/src/main.c @@ -136,7 +136,8 @@ static void *usb_test_enable(void) err = usbd_add_descriptor(&test_usbd, &test_sn); zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err); - if (usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) { err = usbd_add_configuration(&test_usbd, USBD_SPEED_HS, &test_hs_config); zassert_equal(err, 0, "Failed to add configuration (%d)"); } @@ -144,7 +145,8 @@ static void *usb_test_enable(void) err = usbd_add_configuration(&test_usbd, USBD_SPEED_FS, &test_fs_config); zassert_equal(err, 0, "Failed to add configuration (%d)"); - if (usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) { + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) { err = usbd_register_all_classes(&test_usbd, USBD_SPEED_HS, 1, NULL); zassert_equal(err, 0, "Failed to unregister all instances(%d)");