usb: Fix for set/reset endpoints

setting/resetting endpoints is required when switching to alternate
interfaces. This is a common operation for usb audio class.

When audio device is enumerated host invokes set_interface request
to alternate with 0 endpoints associated. That operation lead to
disable never enabled endpoints. With previous solution error message
will appear.

This commit limits error messages to be present only if endpoint
was configured/enabled before and there was a problem when trying
to configure/enable it for the first time.

* Kinetis driver was updated with return error value when ep was
already configured/enabled.

* nxp driver updated with return error value when ep was already
enabled

* sam0 driver updated with return codes instead of magic numbers.

This is fix patch to  #21741

Signed-off-by: Emil Obalski <emil.obalski@nordicsemi.no>
This commit is contained in:
Emil Obalski 2020-02-05 10:45:50 +01:00 committed by Johan Hedberg
commit 3ed9dc3a24
4 changed files with 23 additions and 10 deletions

View file

@ -341,7 +341,7 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled || if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
dev_data.ep_ctrl[ep_idx].status.out_enabled)) { dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
LOG_WRN("endpoint already configured"); LOG_WRN("endpoint already configured");
return -EBUSY; return -EALREADY;
} }
LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps, LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps,
@ -531,7 +531,7 @@ int usb_dc_ep_enable(const u8_t ep)
if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled || if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
dev_data.ep_ctrl[ep_idx].status.out_enabled)) { dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
LOG_WRN("endpoint 0x%x already enabled", ep); LOG_WRN("endpoint 0x%x already enabled", ep);
return -EBUSY; return -EALREADY;
} }
if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) { if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {

View file

@ -232,7 +232,7 @@ int usb_dc_ep_enable(const u8_t ep)
} }
if (s_Device.eps[ep_abs_idx].ep_occupied) { if (s_Device.eps[ep_abs_idx].ep_occupied) {
LOG_WRN("endpoint 0x%x already enabled", ep); LOG_WRN("endpoint 0x%x already enabled", ep);
return -EBUSY; return -EALREADY;
} }
if ((EP_ADDR2IDX(ep) != USB_CONTROL_ENDPOINT) && (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT)) { if ((EP_ADDR2IDX(ep) != USB_CONTROL_ENDPOINT) && (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT)) {

View file

@ -494,7 +494,7 @@ int usb_dc_ep_enable(const u8_t ep)
if (ep_num >= USB_NUM_ENDPOINTS) { if (ep_num >= USB_NUM_ENDPOINTS) {
LOG_ERR("endpoint index/address out of range"); LOG_ERR("endpoint index/address out of range");
return -1; return -EINVAL;
} }
if (for_in) { if (for_in) {
@ -519,7 +519,7 @@ int usb_dc_ep_disable(u8_t ep)
if (ep_num >= USB_NUM_ENDPOINTS) { if (ep_num >= USB_NUM_ENDPOINTS) {
LOG_ERR("endpoint index/address out of range"); LOG_ERR("endpoint index/address out of range");
return -1; return -EINVAL;
} }
endpoint->EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0 endpoint->EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0

View file

@ -467,6 +467,7 @@ static bool usb_get_descriptor(u16_t type_index, u16_t lang_id,
static bool set_endpoint(const struct usb_ep_descriptor *ep_desc) static bool set_endpoint(const struct usb_ep_descriptor *ep_desc)
{ {
struct usb_dc_ep_cfg_data ep_cfg; struct usb_dc_ep_cfg_data ep_cfg;
int ret;
ep_cfg.ep_addr = ep_desc->bEndpointAddress; ep_cfg.ep_addr = ep_desc->bEndpointAddress;
ep_cfg.ep_mps = sys_le16_to_cpu(ep_desc->wMaxPacketSize); ep_cfg.ep_mps = sys_le16_to_cpu(ep_desc->wMaxPacketSize);
@ -480,12 +481,20 @@ static bool set_endpoint(const struct usb_ep_descriptor *ep_desc)
LOG_DBG("Set endpoint 0x%x type %u MPS %u", LOG_DBG("Set endpoint 0x%x type %u MPS %u",
ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps); ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps);
if (usb_dc_ep_configure(&ep_cfg) < 0) { ret = usb_dc_ep_configure(&ep_cfg);
LOG_WRN("Failed to configure endpoint 0x%02x", ep_cfg.ep_addr); if (ret == -EALREADY) {
LOG_WRN("Endpoint 0x%02x already configured", ep_cfg.ep_addr);
} else if (ret) {
LOG_ERR("Failed to configure endpoint 0x%02x", ep_cfg.ep_addr);
return false;
} }
if (usb_dc_ep_enable(ep_cfg.ep_addr) < 0) { ret = usb_dc_ep_enable(ep_cfg.ep_addr);
LOG_WRN("Failed to enable endpoint 0x%02x", ep_cfg.ep_addr); if (ret == -EALREADY) {
LOG_WRN("Endpoint 0x%02x already enabled", ep_cfg.ep_addr);
} else if (ret) {
LOG_ERR("Failed to enable endpoint 0x%02x", ep_cfg.ep_addr);
return false;
} }
usb_dev.configured = true; usb_dev.configured = true;
@ -506,6 +515,7 @@ static bool set_endpoint(const struct usb_ep_descriptor *ep_desc)
static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc) static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc)
{ {
struct usb_dc_ep_cfg_data ep_cfg; struct usb_dc_ep_cfg_data ep_cfg;
int ret;
ep_cfg.ep_addr = ep_desc->bEndpointAddress; ep_cfg.ep_addr = ep_desc->bEndpointAddress;
ep_cfg.ep_type = ep_desc->bmAttributes; ep_cfg.ep_type = ep_desc->bmAttributes;
@ -519,7 +529,10 @@ static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc)
usb_cancel_transfer(ep_cfg.ep_addr); usb_cancel_transfer(ep_cfg.ep_addr);
if (usb_dc_ep_disable(ep_cfg.ep_addr) < 0) { ret = usb_dc_ep_disable(ep_cfg.ep_addr);
if (ret == -EALREADY) {
LOG_WRN("Endpoint 0x%02x already disabled", ep_cfg.ep_addr);
} else if (ret) {
LOG_ERR("Failed to disable endpoint 0x%02x", ep_cfg.ep_addr); LOG_ERR("Failed to disable endpoint 0x%02x", ep_cfg.ep_addr);
return false; return false;
} }