From 52eacf16a24e4c335dae2c3aed2f427d61e49128 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Sat, 7 Apr 2018 01:55:53 +0200 Subject: [PATCH] driver: usb: add check for endpoint capabilities Add function to check capabilities of an endpoint. Only basic properties are checked, especially on STM32 capabilities of different USB controller configurations have to be considered in the future. Signed-off-by: Johann Fischer --- drivers/usb/device/usb_dc_dw.c | 32 +++++++++++++++++++++++++++++ drivers/usb/device/usb_dc_kinetis.c | 29 ++++++++++++++++++++++++++ drivers/usb/device/usb_dc_nrf5.c | 26 +++++++++++++++++++++++ drivers/usb/device/usb_dc_sam0.c | 17 +++++++++++++++ drivers/usb/device/usb_dc_stm32.c | 26 +++++++++++++++++++++++ 5 files changed, 130 insertions(+) diff --git a/drivers/usb/device/usb_dc_dw.c b/drivers/usb/device/usb_dc_dw.c index df5326b5fd1..db90507c30c 100644 --- a/drivers/usb/device/usb_dc_dw.c +++ b/drivers/usb/device/usb_dc_dw.c @@ -814,6 +814,38 @@ int usb_dc_set_address(const u8_t addr) return 0; } +int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg) +{ + u8_t ep_idx = USB_DW_EP_ADDR2IDX(cfg->ep_addr); + + SYS_LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps, + cfg->ep_type); + + if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { + SYS_LOG_ERR("invalid endpoint configuration"); + return -1; + } + + if (cfg->ep_mps > QM_USB_MAX_PACKET_SIZE) { + SYS_LOG_WRN("unsupported packet size"); + return -1; + } + + if ((USB_DW_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) && + (ep_idx >= QM_USB_OUT_EP_NUM)) { + SYS_LOG_WRN("OUT endpoint address out of range"); + return -1; + } + + if ((USB_DW_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_IN) && + (ep_idx >= QM_USB_IN_EP_NUM)) { + SYS_LOG_WRN("IN endpoint address out of range"); + return -1; + } + + return 0; +} + int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const ep_cfg) { if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep_cfg->ep_addr)) { diff --git a/drivers/usb/device/usb_dc_kinetis.c b/drivers/usb/device/usb_dc_kinetis.c index abc7ea86be7..9b157f6c045 100644 --- a/drivers/usb/device/usb_dc_kinetis.c +++ b/drivers/usb/device/usb_dc_kinetis.c @@ -268,6 +268,35 @@ int usb_dc_set_address(const u8_t addr) return 0; } +int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg) +{ + u8_t ep_idx = EP_ADDR2IDX(cfg->ep_addr); + + if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { + SYS_LOG_ERR("invalid endpoint configuration"); + return -1; + } + + if (ep_idx > NUM_OF_EP_MAX) { + SYS_LOG_ERR("endpoint index/address out of range"); + return -1; + } + + if (ep_idx & BIT(0)) { + if (EP_ADDR2DIR(cfg->ep_addr) != USB_EP_DIR_IN) { + SYS_LOG_INF("pre-selected as IN endpoint"); + return -1; + } + } else { + if (EP_ADDR2DIR(cfg->ep_addr) != USB_EP_DIR_OUT) { + SYS_LOG_INF("pre-selected as OUT endpoint"); + return -1; + } + } + + return 0; +} + int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg) { u8_t idx_even = get_bdt_idx(cfg->ep_addr, 0); diff --git a/drivers/usb/device/usb_dc_nrf5.c b/drivers/usb/device/usb_dc_nrf5.c index 9a0cc4acbff..34ece2921e2 100644 --- a/drivers/usb/device/usb_dc_nrf5.c +++ b/drivers/usb/device/usb_dc_nrf5.c @@ -1816,6 +1816,32 @@ int usb_dc_set_address(const u8_t addr) return 0; } +int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg) +{ + u8_t ep_idx = NRF_USBD_EP_NR_GET(cfg->ep_addr); + + SYS_LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps, + cfg->ep_type); + + if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { + SYS_LOG_ERR("invalid endpoint configuration"); + return -1; + } + + if (!NRF_USBD_EP_VALIDATE(cfg->ep_addr)) { + SYS_LOG_ERR("invalid endpoint index/address"); + return -1; + } + + if ((cfg->ep_type == USB_DC_EP_ISOCHRONOUS) && + (!NRF_USBD_EPISO_CHECK(cfg->ep_addr))) { + SYS_LOG_WRN("invalid endpoint type"); + return -1; + } + + return 0; +} + int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const ep_cfg) { struct nrf5_usbd_ep_ctx *ep_ctx; diff --git a/drivers/usb/device/usb_dc_sam0.c b/drivers/usb/device/usb_dc_sam0.c index 686e9fb5472..503847c8768 100644 --- a/drivers/usb/device/usb_dc_sam0.c +++ b/drivers/usb/device/usb_dc_sam0.c @@ -260,6 +260,23 @@ int usb_dc_set_status_callback(const usb_dc_status_callback cb) return 0; } +int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg) +{ + u8_t ep_idx = cfg->ep_addr & ~USB_EP_DIR_MASK; + + if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { + SYS_LOG_ERR("invalid endpoint configuration"); + return -1; + } + + if (ep_idx > CONFIG_USB_DC_SAM0_NUM_BIDIR_ENDPOINTS) { + SYS_LOG_ERR("endpoint index/address too high"); + return -1; + } + + return 0; +} + int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg) { struct usb_sam0_data *data = usb_sam0_get_data(); diff --git a/drivers/usb/device/usb_dc_stm32.c b/drivers/usb/device/usb_dc_stm32.c index 88dbccf6fb3..0f33ccd6adb 100644 --- a/drivers/usb/device/usb_dc_stm32.c +++ b/drivers/usb/device/usb_dc_stm32.c @@ -453,6 +453,32 @@ int usb_dc_ep_get_read_count(u8_t ep, u32_t *read_bytes) return 0; } +int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg) +{ + u8_t ep_idx = EP_IDX(cfg->ep_addr); + + SYS_LOG_ERR("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps, + cfg->ep_type); + + if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) { + SYS_LOG_ERR("invalid endpoint configuration"); + return -1; + } + + if (EP_IS_IN(cfg->ep_addr) && (ep_idx > CONFIG_USB_NUM_IN_ENDPOINTS)) { + SYS_LOG_ERR("IN endpoint index/address out of range"); + return -1; + } + + if (EP_IS_OUT(cfg->ep_addr) && + (ep_idx > CONFIG_USB_NUM_OUT_ENDPOINTS)) { + SYS_LOG_ERR("OUT endpoint index/address out of range"); + return -1; + } + + return 0; +} + int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const ep_cfg) { u8_t ep = ep_cfg->ep_addr;