AnsweredAssumed Answered

Possible bug in USB 5.0 stack, in usb_dev.c

Question asked by John Strohm on Nov 21, 2014
Latest reply on Nov 24, 2014 by Make Shi

In file usb_dev.c, routine usb_device_recv_data() contains the following:

 

    OS_Mutex_lock(usb_dev_ptr->mutex);

 

    /* Initialize the new transfer descriptor */

    xd_ptr->ep_num = ep_num;

    xd_ptr->bdirection = USB_RECV;

    xd_ptr->wtotallength = size;

    xd_ptr->wstartaddress = buff_ptr;

    xd_ptr->wsofar = 0;

    xd_ptr->bstatus = USB_STATUS_TRANSFER_ACCEPTED;

 

    if (((usb_dev_interface_functions_struct_t*)\

       usb_dev_ptr->usb_dev_interface)->dev_recv != NULL)

    {

        error = ((usb_dev_interface_functions_struct_t*)\

                 usb_dev_ptr->usb_dev_interface)->dev_recv(usb_dev_ptr->controller_handle, xd_ptr); 

    }

    else

    {

        #if _DEBUG

        printf("usb_device_recv_data: DEV_RECV is NULL\n");                     

        #endif   

        return USBERR_ERROR;

    }

 

    OS_Mutex_unlock(usb_dev_ptr->mutex);

 

Observe that the dev_recv() function pointer is NULL, the mutex will be left locked.  This will probably have bad consequences down the road.

 

Observing that there is no point in setting up the transfer descriptor and locking the mutex if the transfer routine is missing, may I suggest the following revision?

 

    if (((usb_dev_interface_functions_struct_t*)\

       usb_dev_ptr->usb_dev_interface)->dev_recv != NULL)

    {

        OS_Mutex_lock(usb_dev_ptr->mutex);

 

        /* Initialize the new transfer descriptor */

        xd_ptr->ep_num = ep_num;

        xd_ptr->bdirection = USB_RECV;

        xd_ptr->wtotallength = size;

        xd_ptr->wstartaddress = buff_ptr;

        xd_ptr->wsofar = 0;

        xd_ptr->bstatus = USB_STATUS_TRANSFER_ACCEPTED;

 

        error = ((usb_dev_interface_functions_struct_t*)\

                 usb_dev_ptr->usb_dev_interface)->dev_recv(usb_dev_ptr->controller_handle, xd_ptr); 

 

        OS_Mutex_unlock(usb_dev_ptr->mutex);

    }

    else

    {

        #if _DEBUG

        printf("usb_device_recv_data: DEV_RECV is NULL\n");                     

        #endif   

        return USBERR_ERROR;

    }

Outcomes