Merge branch 'tmaster' into future
[fw/stlink] / example / stm32f4 / STM32_USB_Device_Library / Class / msc / src / usbd_msc_core.c
diff --git a/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c b/example/stm32f4/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
new file mode 100644 (file)
index 0000000..cf03ef4
--- /dev/null
@@ -0,0 +1,490 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_core.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   This file provides all the MSC core functions.
+  *
+  * @verbatim
+  *      
+  *          ===================================================================      
+  *                                MSC Class  Description
+  *          =================================================================== 
+  *           This module manages the MSC class V1.0 following the "Universal 
+  *           Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+  *           Sep. 31, 1999".
+  *           This driver implements the following aspects of the specification:
+  *             - Bulk-Only Transport protocol
+  *             - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+  *      
+  *  @endverbatim
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_mem.h"
+#include "usbd_msc_core.h"
+#include "usbd_msc_bot.h"
+#include "usbd_req.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup MSC_CORE 
+  * @brief Mass storage core module
+  * @{
+  */ 
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup MSC_CORE_Private_Defines
+  * @{
+  */ 
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup MSC_CORE_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup MSC_CORE_Private_FunctionPrototypes
+  * @{
+  */ 
+uint8_t  USBD_MSC_Init (void  *pdev, 
+                            uint8_t cfgidx);
+
+uint8_t  USBD_MSC_DeInit (void  *pdev, 
+                              uint8_t cfgidx);
+
+uint8_t  USBD_MSC_Setup (void  *pdev, 
+                             USB_SETUP_REQ *req);
+
+uint8_t  USBD_MSC_DataIn (void  *pdev, 
+                              uint8_t epnum);
+
+
+uint8_t  USBD_MSC_DataOut (void  *pdev, 
+                               uint8_t epnum);
+
+uint8_t  *USBD_MSC_GetCfgDesc (uint8_t speed, 
+                                      uint16_t *length);
+
+#ifdef USB_OTG_HS_CORE  
+uint8_t  *USBD_MSC_GetOtherCfgDesc (uint8_t speed, 
+                                      uint16_t *length);
+#endif
+
+
+uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ];
+
+
+
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup MSC_CORE_Private_Variables
+  * @{
+  */ 
+
+
+USBD_Class_cb_TypeDef  USBD_MSC_cb = 
+{
+  USBD_MSC_Init,
+  USBD_MSC_DeInit,
+  USBD_MSC_Setup,
+  NULL, /*EP0_TxSent*/  
+  NULL, /*EP0_RxReady*/
+  USBD_MSC_DataIn,
+  USBD_MSC_DataOut,
+  NULL, /*SOF */ 
+  NULL,  
+  NULL,     
+  USBD_MSC_GetCfgDesc,
+#ifdef USB_OTG_HS_CORE  
+  USBD_MSC_GetOtherCfgDesc,
+#endif
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4   
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB Mass storage device Configuration Descriptor */
+/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+  
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
+  USB_MSC_CONFIG_DESC_SIZ,
+  
+  0x00,
+  0x01,   /* bNumInterfaces: 1 interface */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+  
+  /********************  Mass Storage interface ********************/
+  0x09,   /* bLength: Interface Descriptor size */
+  0x04,   /* bDescriptorType: */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints*/
+  0x08,   /* bInterfaceClass: MSC Class */
+  0x06,   /* bInterfaceSubClass : SCSI transparent*/
+  0x50,   /* nInterfaceProtocol */
+  0x05,          /* iInterface: */
+  /********************  Mass Storage Endpoints ********************/
+  0x07,   /*Endpoint descriptor length = 7*/
+  0x05,   /*Endpoint descriptor type */
+  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_PACKET),
+  HIBYTE(MSC_MAX_PACKET),
+  0x00,   /*Polling interval in milliseconds */
+  
+  0x07,   /*Endpoint descriptor length = 7 */
+  0x05,   /*Endpoint descriptor type */
+  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_PACKET),
+  HIBYTE(MSC_MAX_PACKET),
+  0x00     /*Polling interval in milliseconds*/
+};
+#ifdef USB_OTG_HS_CORE 
+ #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+     #pragma data_alignment=4   
+   #endif
+ #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USBD_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+  
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
+  USB_MSC_CONFIG_DESC_SIZ,
+  
+  0x00,
+  0x01,   /* bNumInterfaces: 1 interface */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+  
+  /********************  Mass Storage interface ********************/
+  0x09,   /* bLength: Interface Descriptor size */
+  0x04,   /* bDescriptorType: */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints*/
+  0x08,   /* bInterfaceClass: MSC Class */
+  0x06,   /* bInterfaceSubClass : SCSI transparent command set*/
+  0x50,   /* nInterfaceProtocol */
+  0x05,          /* iInterface: */
+  /********************  Mass Storage Endpoints ********************/
+  0x07,   /*Endpoint descriptor length = 7*/
+  0x05,   /*Endpoint descriptor type */
+  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
+  0x02,   /*Bulk endpoint type */
+  0x40,
+  0x00,
+  0x00,   /*Polling interval in milliseconds */
+  
+  0x07,   /*Endpoint descriptor length = 7 */
+  0x05,   /*Endpoint descriptor type */
+  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
+  0x02,   /*Bulk endpoint type */
+  0x40,
+  0x00,
+  0x00     /*Polling interval in milliseconds*/
+};
+#endif 
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4   
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN static uint8_t  USBD_MSC_MaxLun  __ALIGN_END = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4   
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN static uint8_t  USBD_MSC_AltSet  __ALIGN_END = 0;
+
+/**
+  * @}
+  */ 
+
+
+/** @defgroup MSC_CORE_Private_Functions
+  * @{
+  */ 
+
+/**
+* @brief  USBD_MSC_Init
+*         Initialize  the mass storage configuration
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status
+*/
+uint8_t  USBD_MSC_Init (void  *pdev, 
+                            uint8_t cfgidx)
+{
+  USBD_MSC_DeInit(pdev , cfgidx );
+  
+  /* Open EP IN */
+  DCD_EP_Open(pdev,
+              MSC_IN_EP,
+              MSC_EPIN_SIZE,
+              USB_OTG_EP_BULK);
+  
+  /* Open EP OUT */
+  DCD_EP_Open(pdev,
+              MSC_OUT_EP,
+              MSC_EPOUT_SIZE,
+              USB_OTG_EP_BULK);
+  /* Init the BOT  layer */
+  MSC_BOT_Init(pdev); 
+  
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_DeInit
+*         DeInitilaize  the mass storage configuration
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status
+*/
+uint8_t  USBD_MSC_DeInit (void  *pdev, 
+                              uint8_t cfgidx)
+{
+  /* Close MSC EPs */
+  DCD_EP_Close (pdev , MSC_IN_EP);
+  DCD_EP_Close (pdev , MSC_OUT_EP);
+  
+  /* Un Init the BOT layer */
+  MSC_BOT_DeInit(pdev);   
+  return USBD_OK;
+}
+/**
+* @brief  USBD_MSC_Setup
+*         Handle the MSC specific requests
+* @param  pdev: device instance
+* @param  req: USB request
+* @retval status
+*/
+uint8_t  USBD_MSC_Setup (void  *pdev, USB_SETUP_REQ *req)
+{
+  
+  switch (req->bmRequest & USB_REQ_TYPE_MASK)
+  {
+
+  /* Class request */
+  case USB_REQ_TYPE_CLASS :
+    switch (req->bRequest)
+    {
+    case BOT_GET_MAX_LUN :
+
+      if((req->wValue  == 0) && 
+         (req->wLength == 1) &&
+         ((req->bmRequest & 0x80) == 0x80))
+      {
+        USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
+        if(USBD_MSC_MaxLun > 0)
+        {
+           USBD_CtlSendData (pdev,
+                             &USBD_MSC_MaxLun,
+                              1);
+        }
+        else
+        {
+          USBD_CtlError(pdev , req);
+          return USBD_FAIL; 
+          
+        }
+      }
+      else
+      {
+         USBD_CtlError(pdev , req);
+         return USBD_FAIL; 
+      }
+      break;
+      
+    case BOT_RESET :
+      if((req->wValue  == 0) && 
+         (req->wLength == 0) &&
+        ((req->bmRequest & 0x80) != 0x80))
+      {      
+         MSC_BOT_Reset(pdev);
+      }
+      else
+      {
+         USBD_CtlError(pdev , req);
+         return USBD_FAIL; 
+      }
+      break;
+
+    default:
+       USBD_CtlError(pdev , req);
+       return USBD_FAIL; 
+    }
+    break;
+  /* Interface & Endpoint request */
+  case USB_REQ_TYPE_STANDARD:
+    switch (req->bRequest)
+    {
+    case USB_REQ_GET_INTERFACE :
+      USBD_CtlSendData (pdev,
+                        &USBD_MSC_AltSet,
+                        1);
+      break;
+      
+    case USB_REQ_SET_INTERFACE :
+      USBD_MSC_AltSet = (uint8_t)(req->wValue);
+      break;
+    
+    case USB_REQ_CLEAR_FEATURE:  
+      
+      /* Flush the FIFO and Clear the stall status */    
+      DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
+      
+      /* Re-activate the EP */      
+      DCD_EP_Close (pdev , (uint8_t)req->wIndex);
+      if((((uint8_t)req->wIndex) & 0x80) == 0x80)
+      {
+        DCD_EP_Open(pdev,
+                    ((uint8_t)req->wIndex),
+                    MSC_EPIN_SIZE,
+                    USB_OTG_EP_BULK);
+      }
+      else
+      {
+        DCD_EP_Open(pdev,
+                    ((uint8_t)req->wIndex),
+                    MSC_EPOUT_SIZE,
+                    USB_OTG_EP_BULK);
+      }
+      
+      /* Handle BOT error */
+      MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
+      break;
+      
+    }  
+    break;
+   
+  default:
+    break;
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_DataIn
+*         handle data IN Stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+uint8_t  USBD_MSC_DataIn (void  *pdev, 
+                              uint8_t epnum)
+{
+  MSC_BOT_DataIn(pdev , epnum);
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_DataOut
+*         handle data OUT Stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+uint8_t  USBD_MSC_DataOut (void  *pdev, 
+                               uint8_t epnum)
+{
+  MSC_BOT_DataOut(pdev , epnum);
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_GetCfgDesc 
+*         return configuration descriptor
+* @param  speed : current device speed
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t  *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+  *length = sizeof (USBD_MSC_CfgDesc);
+  return USBD_MSC_CfgDesc;
+}
+
+/**
+* @brief  USBD_MSC_GetOtherCfgDesc 
+*         return other speed configuration descriptor
+* @param  speed : current device speed
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+#ifdef USB_OTG_HS_CORE  
+uint8_t  *USBD_MSC_GetOtherCfgDesc (uint8_t speed, 
+                                      uint16_t *length)
+{
+  *length = sizeof (USBD_MSC_OtherCfgDesc);
+  return USBD_MSC_OtherCfgDesc;
+}
+#endif
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+
+/**
+  * @}
+  */ 
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/