Fix MSP output buffer overflow (#13879)
[betaflight.git] / lib / main / STM32G4 / Middlewares / ST / STM32_USB_Device_Library / Class / MSC / Src / usbd_msc.c
blobe26d84c6120788c8a2e5ffe0d807bcaa2c86e180
1 /**
2 ******************************************************************************
3 * @file usbd_msc.c
4 * @author MCD Application Team
5 * @brief This file provides all the MSC core functions.
7 * @verbatim
9 * ===================================================================
10 * MSC Class Description
11 * ===================================================================
12 * This module manages the MSC class V1.0 following the "Universal
13 * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
14 * Sep. 31, 1999".
15 * This driver implements the following aspects of the specification:
16 * - Bulk-Only Transport protocol
17 * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
19 * @endverbatim
21 ******************************************************************************
22 * @attention
24 * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
25 * All rights reserved.</center></h2>
27 * This software component is licensed by ST under Ultimate Liberty license
28 * SLA0044, the "License"; You may not use this file except in compliance with
29 * the License. You may obtain a copy of the License at:
30 * http://www.st.com/SLA0044
32 ******************************************************************************
35 /* BSPDependencies
36 - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
37 - "stm32xxxxx_{eval}{discovery}_io.c"
38 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
39 EndBSPDependencies */
41 /* Includes ------------------------------------------------------------------*/
42 #include "usbd_msc.h"
45 /** @addtogroup STM32_USB_DEVICE_LIBRARY
46 * @{
50 /** @defgroup MSC_CORE
51 * @brief Mass storage core module
52 * @{
55 /** @defgroup MSC_CORE_Private_TypesDefinitions
56 * @{
58 /**
59 * @}
63 /** @defgroup MSC_CORE_Private_Defines
64 * @{
67 /**
68 * @}
72 /** @defgroup MSC_CORE_Private_Macros
73 * @{
75 /**
76 * @}
80 /** @defgroup MSC_CORE_Private_FunctionPrototypes
81 * @{
83 uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev,
84 uint8_t cfgidx);
86 uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev,
87 uint8_t cfgidx);
89 uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev,
90 USBD_SetupReqTypedef *req);
92 uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev,
93 uint8_t epnum);
96 uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev,
97 uint8_t epnum);
99 uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length);
101 uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length);
103 uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length);
105 uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length);
109 * @}
113 /** @defgroup MSC_CORE_Private_Variables
114 * @{
118 USBD_ClassTypeDef USBD_MSC =
120 USBD_MSC_Init,
121 USBD_MSC_DeInit,
122 USBD_MSC_Setup,
123 NULL, /*EP0_TxSent*/
124 NULL, /*EP0_RxReady*/
125 USBD_MSC_DataIn,
126 USBD_MSC_DataOut,
127 NULL, /*SOF */
128 NULL,
129 NULL,
130 USBD_MSC_GetHSCfgDesc,
131 USBD_MSC_GetFSCfgDesc,
132 USBD_MSC_GetOtherSpeedCfgDesc,
133 USBD_MSC_GetDeviceQualifierDescriptor,
136 /* USB Mass storage device Configuration Descriptor */
137 /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
138 __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
141 0x09, /* bLength: Configuation Descriptor size */
142 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
143 USB_MSC_CONFIG_DESC_SIZ,
145 0x00,
146 0x01, /* bNumInterfaces: 1 interface */
147 0x01, /* bConfigurationValue: */
148 0x04, /* iConfiguration: */
149 0xC0, /* bmAttributes: */
150 0x32, /* MaxPower 100 mA */
152 /******************** Mass Storage interface ********************/
153 0x09, /* bLength: Interface Descriptor size */
154 0x04, /* bDescriptorType: */
155 0x00, /* bInterfaceNumber: Number of Interface */
156 0x00, /* bAlternateSetting: Alternate setting */
157 0x02, /* bNumEndpoints*/
158 0x08, /* bInterfaceClass: MSC Class */
159 0x06, /* bInterfaceSubClass : SCSI transparent*/
160 0x50, /* nInterfaceProtocol */
161 0x05, /* iInterface: */
162 /******************** Mass Storage Endpoints ********************/
163 0x07, /*Endpoint descriptor length = 7*/
164 0x05, /*Endpoint descriptor type */
165 MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
166 0x02, /*Bulk endpoint type */
167 LOBYTE(MSC_MAX_HS_PACKET),
168 HIBYTE(MSC_MAX_HS_PACKET),
169 0x00, /*Polling interval in milliseconds */
171 0x07, /*Endpoint descriptor length = 7 */
172 0x05, /*Endpoint descriptor type */
173 MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
174 0x02, /*Bulk endpoint type */
175 LOBYTE(MSC_MAX_HS_PACKET),
176 HIBYTE(MSC_MAX_HS_PACKET),
177 0x00 /*Polling interval in milliseconds*/
180 /* USB Mass storage device Configuration Descriptor */
181 /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
182 uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
185 0x09, /* bLength: Configuation Descriptor size */
186 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
187 USB_MSC_CONFIG_DESC_SIZ,
189 0x00,
190 0x01, /* bNumInterfaces: 1 interface */
191 0x01, /* bConfigurationValue: */
192 0x04, /* iConfiguration: */
193 0xC0, /* bmAttributes: */
194 0x32, /* MaxPower 100 mA */
196 /******************** Mass Storage interface ********************/
197 0x09, /* bLength: Interface Descriptor size */
198 0x04, /* bDescriptorType: */
199 0x00, /* bInterfaceNumber: Number of Interface */
200 0x00, /* bAlternateSetting: Alternate setting */
201 0x02, /* bNumEndpoints*/
202 0x08, /* bInterfaceClass: MSC Class */
203 0x06, /* bInterfaceSubClass : SCSI transparent*/
204 0x50, /* nInterfaceProtocol */
205 0x05, /* iInterface: */
206 /******************** Mass Storage Endpoints ********************/
207 0x07, /*Endpoint descriptor length = 7*/
208 0x05, /*Endpoint descriptor type */
209 MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
210 0x02, /*Bulk endpoint type */
211 LOBYTE(MSC_MAX_FS_PACKET),
212 HIBYTE(MSC_MAX_FS_PACKET),
213 0x00, /*Polling interval in milliseconds */
215 0x07, /*Endpoint descriptor length = 7 */
216 0x05, /*Endpoint descriptor type */
217 MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
218 0x02, /*Bulk endpoint type */
219 LOBYTE(MSC_MAX_FS_PACKET),
220 HIBYTE(MSC_MAX_FS_PACKET),
221 0x00 /*Polling interval in milliseconds*/
224 __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
227 0x09, /* bLength: Configuation Descriptor size */
228 USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
229 USB_MSC_CONFIG_DESC_SIZ,
231 0x00,
232 0x01, /* bNumInterfaces: 1 interface */
233 0x01, /* bConfigurationValue: */
234 0x04, /* iConfiguration: */
235 0xC0, /* bmAttributes: */
236 0x32, /* MaxPower 100 mA */
238 /******************** Mass Storage interface ********************/
239 0x09, /* bLength: Interface Descriptor size */
240 0x04, /* bDescriptorType: */
241 0x00, /* bInterfaceNumber: Number of Interface */
242 0x00, /* bAlternateSetting: Alternate setting */
243 0x02, /* bNumEndpoints*/
244 0x08, /* bInterfaceClass: MSC Class */
245 0x06, /* bInterfaceSubClass : SCSI transparent command set*/
246 0x50, /* nInterfaceProtocol */
247 0x05, /* iInterface: */
248 /******************** Mass Storage Endpoints ********************/
249 0x07, /*Endpoint descriptor length = 7*/
250 0x05, /*Endpoint descriptor type */
251 MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
252 0x02, /*Bulk endpoint type */
253 0x40,
254 0x00,
255 0x00, /*Polling interval in milliseconds */
257 0x07, /*Endpoint descriptor length = 7 */
258 0x05, /*Endpoint descriptor type */
259 MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
260 0x02, /*Bulk endpoint type */
261 0x40,
262 0x00,
263 0x00 /*Polling interval in milliseconds*/
266 /* USB Standard Device Descriptor */
267 __ALIGN_BEGIN uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
269 USB_LEN_DEV_QUALIFIER_DESC,
270 USB_DESC_TYPE_DEVICE_QUALIFIER,
271 0x00,
272 0x02,
273 0x00,
274 0x00,
275 0x00,
276 MSC_MAX_FS_PACKET,
277 0x01,
278 0x00,
281 * @}
284 static DMA_DATA_ZERO_INIT USBD_MSC_BOT_HandleTypeDef ClassData;
286 /** @defgroup MSC_CORE_Private_Functions
287 * @{
291 * @brief USBD_MSC_Init
292 * Initialize the mass storage configuration
293 * @param pdev: device instance
294 * @param cfgidx: configuration index
295 * @retval status
297 uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)
299 UNUSED(cfgidx);
301 pdev->pMSC_ClassData = (void *)&ClassData;
303 if(pdev->dev_speed == USBD_SPEED_HIGH)
305 /* Open EP OUT */
306 USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
307 pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
309 /* Open EP IN */
310 USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
311 pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
313 else
315 /* Open EP OUT */
316 USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
317 pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
319 /* Open EP IN */
320 USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
321 pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
324 /* Init the BOT layer */
325 MSC_BOT_Init(pdev);
327 return USBD_OK;
331 * @brief USBD_MSC_DeInit
332 * DeInitilaize the mass storage configuration
333 * @param pdev: device instance
334 * @param cfgidx: configuration index
335 * @retval status
337 uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev,
338 uint8_t cfgidx)
340 UNUSED(cfgidx);
342 /* Close MSC EPs */
343 USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
344 pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
346 /* Close EP IN */
347 USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
348 pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
350 /* De-Init the BOT layer */
351 MSC_BOT_DeInit(pdev);
353 /* Free MSC Class Resources */
354 if(pdev->pMSC_ClassData != NULL)
356 USBD_free(pdev->pMSC_ClassData);
357 pdev->pMSC_ClassData = NULL;
359 return USBD_OK;
362 * @brief USBD_MSC_Setup
363 * Handle the MSC specific requests
364 * @param pdev: device instance
365 * @param req: USB request
366 * @retval status
368 uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
370 USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pMSC_ClassData;
371 uint8_t ret = USBD_OK;
372 uint16_t status_info = 0U;
374 switch (req->bmRequest & USB_REQ_TYPE_MASK)
377 /* Class request */
378 case USB_REQ_TYPE_CLASS:
379 switch (req->bRequest)
381 case BOT_GET_MAX_LUN:
382 if((req->wValue == 0U) && (req->wLength == 1U) &&
383 ((req->bmRequest & 0x80U) == 0x80U))
385 hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pMSC_UserData)->GetMaxLun();
386 USBD_CtlSendData (pdev, (uint8_t *)(void *)&hmsc->max_lun, 1U);
388 else
390 USBD_CtlError(pdev, req);
391 ret = USBD_FAIL;
393 break;
395 case BOT_RESET :
396 if((req->wValue == 0U) && (req->wLength == 0U) &&
397 ((req->bmRequest & 0x80U) != 0x80U))
399 MSC_BOT_Reset(pdev);
401 else
403 USBD_CtlError(pdev , req);
404 ret = USBD_FAIL;
406 break;
408 default:
409 USBD_CtlError(pdev , req);
410 ret = USBD_FAIL;
411 break;
413 break;
414 /* Interface & Endpoint request */
415 case USB_REQ_TYPE_STANDARD:
416 switch (req->bRequest)
418 case USB_REQ_GET_STATUS:
419 if (pdev->dev_state == USBD_STATE_CONFIGURED)
421 USBD_CtlSendData (pdev, (uint8_t *)(void *)&status_info, 2U);
423 else
425 USBD_CtlError (pdev, req);
426 ret = USBD_FAIL;
428 break;
430 case USB_REQ_GET_INTERFACE:
431 if (pdev->dev_state == USBD_STATE_CONFIGURED)
433 USBD_CtlSendData (pdev, (uint8_t *)(void *)&hmsc->interface, 1U);
435 else
437 USBD_CtlError (pdev, req);
438 ret = USBD_FAIL;
440 break;
442 case USB_REQ_SET_INTERFACE:
443 if (pdev->dev_state == USBD_STATE_CONFIGURED)
445 hmsc->interface = (uint8_t)(req->wValue);
447 else
449 USBD_CtlError (pdev, req);
450 ret = USBD_FAIL;
452 break;
454 case USB_REQ_CLEAR_FEATURE:
456 /* Flush the FIFO and Clear the stall status */
457 USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
459 /* Reactivate the EP */
460 USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex);
461 if((((uint8_t)req->wIndex) & 0x80U) == 0x80U)
463 pdev->ep_in[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
464 if(pdev->dev_speed == USBD_SPEED_HIGH)
466 /* Open EP IN */
467 USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
468 MSC_MAX_HS_PACKET);
470 else
472 /* Open EP IN */
473 USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
474 MSC_MAX_FS_PACKET);
476 pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
478 else
480 pdev->ep_out[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
481 if(pdev->dev_speed == USBD_SPEED_HIGH)
483 /* Open EP OUT */
484 USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
485 MSC_MAX_HS_PACKET);
487 else
489 /* Open EP OUT */
490 USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
491 MSC_MAX_FS_PACKET);
493 pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
496 /* Handle BOT error */
497 MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
498 break;
500 default:
501 USBD_CtlError (pdev, req);
502 ret = USBD_FAIL;
503 break;
505 break;
507 default:
508 USBD_CtlError (pdev, req);
509 ret = USBD_FAIL;
510 break;
513 return ret;
517 * @brief USBD_MSC_DataIn
518 * handle data IN Stage
519 * @param pdev: device instance
520 * @param epnum: endpoint index
521 * @retval status
523 uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev,
524 uint8_t epnum)
526 MSC_BOT_DataIn(pdev , epnum);
527 return USBD_OK;
531 * @brief USBD_MSC_DataOut
532 * handle data OUT Stage
533 * @param pdev: device instance
534 * @param epnum: endpoint index
535 * @retval status
537 uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev,
538 uint8_t epnum)
540 MSC_BOT_DataOut(pdev , epnum);
541 return USBD_OK;
545 * @brief USBD_MSC_GetHSCfgDesc
546 * return configuration descriptor
547 * @param length : pointer data length
548 * @retval pointer to descriptor buffer
550 uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length)
552 *length = sizeof (USBD_MSC_CfgHSDesc);
553 return USBD_MSC_CfgHSDesc;
557 * @brief USBD_MSC_GetFSCfgDesc
558 * return configuration descriptor
559 * @param length : pointer data length
560 * @retval pointer to descriptor buffer
562 uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length)
564 *length = sizeof (USBD_MSC_CfgFSDesc);
565 return USBD_MSC_CfgFSDesc;
569 * @brief USBD_MSC_GetOtherSpeedCfgDesc
570 * return other speed configuration descriptor
571 * @param length : pointer data length
572 * @retval pointer to descriptor buffer
574 uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length)
576 *length = sizeof (USBD_MSC_OtherSpeedCfgDesc);
577 return USBD_MSC_OtherSpeedCfgDesc;
580 * @brief DeviceQualifierDescriptor
581 * return Device Qualifier descriptor
582 * @param length : pointer data length
583 * @retval pointer to descriptor buffer
585 uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length)
587 *length = sizeof (USBD_MSC_DeviceQualifierDesc);
588 return USBD_MSC_DeviceQualifierDesc;
592 * @brief USBD_MSC_RegisterStorage
593 * @param fops: storage callback
594 * @retval status
596 uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev,
597 USBD_StorageTypeDef *fops)
599 if(fops != NULL)
601 pdev->pMSC_UserData = fops;
603 return USBD_OK;
607 * @}
612 * @}
617 * @}
620 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/