AnsweredAssumed Answered

USB 5.0 Stack: Possible bug

Question asked by John Strohm on Jul 15, 2015
Latest reply on Jul 15, 2015 by Kan_Li

In file usb_dev.c, routine _usb_device_call_service_internal():

 

usb_status _usb_device_call_service_internal

   (

      /* [IN] pointer to usb device status structure  */

      usb_dev_state_struct_t*       usb_dev_ptr,

      /* [IN] pointer to event structure  */

      usb_event_struct_t*    event

   )

{

    service_struct_t*             service_ptr = NULL;

    uint32_t                      i;

 

 

    /* Needs mutual exclusion */

    OS_Mutex_lock(usb_dev_ptr->mutex);

 

 

    switch (event->type)

    {

        case USB_SERVICE_EP0:

            USB_Control_Service(&usb_dev_ptr->usb_framework, event, service_ptr->arg);

            break;    

        case USB_SERVICE_BUS_RESET:

            USB_Reset_Service(&usb_dev_ptr->usb_framework, event, service_ptr->arg);

            break;

#if USBCFG_DEV_ADVANCED_SUSPEND_RESUME

        case USB_SERVICE_SUSPEND:

            USB_Suspend_Service(&usb_dev_ptr->usb_framework, event, service_ptr->arg);

            break;

        case USB_SERVICE_RESUME:

            USB_Resume_Service(&usb_dev_ptr->usb_framework, event, service_ptr->arg);

            break;

#endif

#if USBCFG_DEV_KHCI_ADVANCED_ERROR_HANDLING

        case USB_SERVICE_ERROR:

            USB_Error_Service(&usb_dev_ptr->usb_framework, event, service_ptr->arg);

            break;

#endif

        default:

            break;

    } /* Endswitch */

 

 

    /* Search for an existing entry for type */

    for (i = 0; i < MAX_DEVICE_SERVICE_NUMBER; i++)

    {

        service_ptr = &usb_dev_ptr->services[i];

        if (service_ptr->type == event->type)

        {  

            if((event->direction == USB_RECV) && (event->buffer_ptr != NULL))

                OS_dcache_invalidate_mlines((void*)event->buffer_ptr,event->len);

            service_ptr->service(event,service_ptr->arg);

            OS_Mutex_unlock(usb_dev_ptr->mutex);

            return USB_OK;

        } 

    }

 

 

  OS_Mutex_unlock(usb_dev_ptr->mutex);

    return USBERR_CLOSED_SERVICE;

} /* EndBody */

 

Observe that events USB_SERVICE_EP0, USB_SERVICE_BUS_RESET, USB_SERVICE_SUSPEND, USB_SERVICE_RESUME, and USB_SERVICE_ERROR will all return USBERR_CLOSED_SERVICE.

 

This is probably not what should happen.  It seems to me that USBERR_CLOSED_SERVICE should only be returned if there was no handler found for the specified event, which is emphatically not the case for the hardwired events.

 

The fix would be to add "return USB_OK;" statements to each arm of the switch except for the default: arm.

Outcomes