stm32/usb: Verify number of used endpoints doesn't exceed maximum.
This commit is contained in:
parent
6705767da1
commit
bcaafa3823
|
@ -57,6 +57,19 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Maximum number of endpoints (excluding EP0)
|
||||
#if defined(STM32L0) || defined(STM32WB)
|
||||
#define MAX_ENDPOINT(dev_id) (7)
|
||||
#elif defined(STM32L4)
|
||||
#define MAX_ENDPOINT(dev_id) (5)
|
||||
#elif defined(STM32F4)
|
||||
#define MAX_ENDPOINT(dev_id) ((dev_id) == USB_PHY_FS_ID ? 3 : 5)
|
||||
#elif defined(STM32F7)
|
||||
#define MAX_ENDPOINT(dev_id) ((dev_id) == USB_PHY_FS_ID ? 5 : 8)
|
||||
#elif defined(STM32H7)
|
||||
#define MAX_ENDPOINT(dev_id) (8)
|
||||
#endif
|
||||
|
||||
STATIC void pyb_usb_vcp_init0(void);
|
||||
|
||||
// this will be persistent across a soft-reset
|
||||
|
@ -240,7 +253,7 @@ bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size
|
|||
// configure the VID, PID and the USBD mode (interfaces it will expose)
|
||||
int cdc_only = (mode & USBD_MODE_IFACE_MASK) == USBD_MODE_CDC;
|
||||
USBD_SetVIDPIDRelease(&usb_dev->usbd_cdc_msc_hid_state, vid, pid, 0x0200, cdc_only);
|
||||
if (USBD_SelectMode(&usb_dev->usbd_cdc_msc_hid_state, mode, hid_info) != 0) {
|
||||
if (USBD_SelectMode(&usb_dev->usbd_cdc_msc_hid_state, mode, hid_info, MAX_ENDPOINT(dev_id)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ static inline uint32_t usbd_cdc_max_packet(USBD_HandleTypeDef *pdev) {
|
|||
}
|
||||
|
||||
// returns 0 on success, -1 on failure
|
||||
int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info);
|
||||
int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info, uint8_t max_endpoint);
|
||||
// returns the current usb mode
|
||||
uint8_t USBD_GetMode(usbd_cdc_msc_hid_state_t *usbd);
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ uint8_t USBD_GetMode(usbd_cdc_msc_hid_state_t *usbd) {
|
|||
return usbd->usbd_mode;
|
||||
}
|
||||
|
||||
int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
|
||||
int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info, uint8_t max_endpoint) {
|
||||
// save mode
|
||||
usbd->usbd_mode = mode;
|
||||
|
||||
|
@ -656,6 +656,17 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode
|
|||
}
|
||||
}
|
||||
|
||||
// Verify that the endpoints that are used fit within the maximum number
|
||||
d = usbd->usbd_config_desc;
|
||||
const uint8_t *d_top = d + n;
|
||||
while (d < d_top) {
|
||||
if (d[0] == 7 && d[1] == USB_DESC_TYPE_ENDPOINT && (d[2] & 0x7f) > max_endpoint) {
|
||||
// Endpoint out of range of hardware
|
||||
return -1;
|
||||
}
|
||||
d += d[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue