AnsweredAssumed Answered

STM32Cube USB Host Mass Storage Class problem: some USB flash drives are not recognized

Question asked by S.Dmitriy on Oct 6, 2014
Latest reply on Oct 10, 2014 by S.Dmitriy
I found a problem with the current version 1.3.0 of STM32CubeF4 library. As it turned out STM32Cube USB host middleware does not work correctly with some USB flash drives I have, particularly the old ones with a capacity of about 2 GB. They are not recognized after being plugged in. After a thorough debugging I found out that these USB flash drives return STALL packets for 'Get Max LUN' requests. This behavior is in fact fully compliant with USB standard:

http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
USB Mass Storage Class Bulk-Only Transport
Get Max LUN device request is used to determine the number of logical units
supported by the device.
Devices that do not support multiple LUNs may STALL this command.

But STM32Cube expects that the USB device will always return the maximum LUN supported for such requests.

To fix the bug I had to modify the USBH_MSC_ClassRequest() function in usbh_msc.c. The MSC_REQ_GET_MAX_LUN case statement now looks like this:

case MSC_REQ_GET_MAX_LUN:  
    /* Issue GetMaxLUN request */
     
    // Try to get max LUN value.
    // Devices that do not support multiple LUNs may STALL this command.
    status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, (uint8_t *)&MSC_Handle->max_lun);
    if(status == USBH_OK)
    {
      MSC_Handle->max_lun = (uint8_t)(MSC_Handle->max_lun) + 1;
      if(MSC_Handle->max_lun > MAX_SUPPORTED_LUN)
        MSC_Handle->max_lun = MAX_SUPPORTED_LUN;
    }
    else if(status == USBH_NOT_SUPPORTED)
    {
      MSC_Handle->max_lun = 1;
    }
    else
    {
      status = USBH_BUSY;
      break;
    }
 
    USBH_UsrLog ("Number of supported LUN: %lu", (int32_t)(MSC_Handle->max_lun));
     
    for(i = 0; i < MSC_Handle->max_lun; i++)
    {
      MSC_Handle->unit[i].prev_ready_state = USBH_FAIL;
      MSC_Handle->unit[i].state_changed = 0;
    }
    status = USBH_OK;
    break;

     
Another bug that is fixed by this modification is that STM32Cube does not check against the MAX_SUPPORTED_LUN constant the max LUN value returned by a USB flash drive. This could cause a buffer overflow when using multi-volume USB flash drives.

I hope this helps to improve the STM32Cube library.

Outcomes