From ebe21e41481becd722a7ecc0f1739ee9c29241e6 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Wed, 26 Aug 2026 17:08:08 +0200 Subject: [PATCH] chore(usb): update to stm32-mw-usb_device v2.11.6 Signed-off-by: Frederic Pillon --- .../Class/AUDIO/Inc/usbd_audio.h | 1 + .../Class/AUDIO/Src/usbd_audio.c | 3 + .../Class/CCID/Inc/usbd_ccid.h | 4 +- .../Class/CCID/Src/usbd_ccid.c | 3 + .../Class/CCID/Src/usbd_ccid_cmd.c | 8 +- .../Class/CDC/Inc/usbd_cdc.h | 5 +- .../Class/CDC/Src/usbd_cdc.c | 3 + .../Class/CDC_ECM/Inc/usbd_cdc_ecm.h | 5 +- .../Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h | 4 +- .../Class/CDC_RNDIS/Src/usbd_cdc_rndis.c | 11 +- .../Src/usbd_composite_builder.c | 11 +- .../Class/CustomHID/Inc/usbd_customhid.h | 7 + .../Class/CustomHID/Src/usbd_customhid.c | 34 +- .../Src/usbd_customhid_if_template.c | 16 +- .../Class/DFU/Src/usbd_dfu.c | 6 + .../Class/HID/Src/usbd_hid.c | 8 + .../Class/MSC/Inc/usbd_msc.h | 17 +- .../Class/MSC/Inc/usbd_msc_data.h | 4 + .../Class/MSC/Inc/usbd_msc_scsi.h | 7 +- .../Class/MSC/Src/usbd_msc.c | 7 +- .../Class/MSC/Src/usbd_msc_bot.c | 4 +- .../Class/MSC/Src/usbd_msc_data.c | 15 +- .../Class/MSC/Src/usbd_msc_scsi.c | 523 +++++-- .../Class/MTP/Inc/usbd_mtp.h | 5 +- .../Class/MTP/Inc/usbd_mtp_opt.h | 4 +- .../Class/MTP/Inc/usbd_mtp_storage.h | 9 +- .../Class/MTP/Src/usbd_mtp.c | 5 +- .../Class/MTP/Src/usbd_mtp_opt.c | 227 +-- .../Class/MTP/Src/usbd_mtp_storage.c | 89 +- .../Class/Printer/Src/usbd_printer.c | 3 + .../Class/Template/Src/usbd_template.c | 3 - .../Class/VIDEO/Src/usbd_video.c | 14 +- .../Core/Inc/usbd_conf_template.h | 4 +- .../Core/Inc/usbd_core.h | 4 - .../Core/Inc/usbd_ctlreq.h | 3 - .../Core/Inc/usbd_def.h | 10 +- .../Core/Inc/usbd_desc_template.h | 4 + .../Core/Inc/usbd_ioreq.h | 4 +- .../Core/Src/usbd_core.c | 21 +- .../Core/Src/usbd_ctlreq.c | 12 +- .../Core/Src/usbd_desc_template.c | 2 +- .../Core/Src/usbd_ioreq.c | 2 + .../ST/STM32_USB_Device_Library/LICENSE.md | 154 +- .../Release_Notes.html | 1282 +++++++++-------- .../SW_Security_Level.html | 138 ++ .../SW_Security_Level.md | 47 + .../_htmresc/Add_button.svg | 2 + .../_htmresc/Update.svg | 2 + .../{mini-st.css => mini-st_2020.css} | 12 +- 49 files changed, 1814 insertions(+), 954 deletions(-) create mode 100644 system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.html create mode 100644 system/Middlewares/ST/STM32_USB_Device_Library/SW_Security_Level.md create mode 100644 system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Add_button.svg create mode 100644 system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/Update.svg rename system/Middlewares/ST/STM32_USB_Device_Library/_htmresc/{mini-st.css => mini-st_2020.css} (99%) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h index a082d19046..177c84a411 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Inc/usbd_audio.h @@ -71,6 +71,7 @@ extern "C" { #define USB_DEVICE_CLASS_AUDIO 0x01U #define AUDIO_SUBCLASS_AUDIOCONTROL 0x01U #define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02U +#define AUDIO_SUBCLASS_MIDISTREAMING 0x03U #define AUDIO_PROTOCOL_UNDEFINED 0x00U #define AUDIO_STREAMING_GENERAL 0x01U #define AUDIO_STREAMING_FORMAT_TYPE 0x02U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c index 05153b1647..fa4c826d15 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c @@ -162,6 +162,9 @@ USBD_ClassTypeDef USBD_AUDIO = USBD_AUDIO_GetCfgDesc, USBD_AUDIO_GetDeviceQualifierDesc, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h index d3b96a536a..e8d12beffc 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Inc/usbd_ccid.h @@ -60,10 +60,12 @@ extern "C" { #define CCID_CMD_FS_BINTERVAL 0x10U #endif /* CCID_CMD_FS_BINTERVAL */ +#ifndef CCID_CMD_PACKET_SIZE +#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ +#endif /* CCID_CMD_PACKET_SIZE */ #define CCID_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ #define CCID_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ #define USB_CCID_CONFIG_DESC_SIZ 93U #define CCID_DATA_HS_IN_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c index 4c77b135d7..c9285922f1 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid.c @@ -129,6 +129,9 @@ USBD_ClassTypeDef USBD_CCID = USBD_CCID_GetOtherSpeedCfgDesc, USBD_CCID_GetDeviceQualifierDescriptor, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c index b91cb1f157..c65ac5aa54 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CCID/Src/usbd_ccid_cmd.c @@ -42,10 +42,10 @@ static void CCID_UpdateCommandStatus(USBD_HandleTypeDef *pdev, uint8_t cmd_stat uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev) { /* Apply the ICC VCC - Fills the Response buffer with ICC ATR - This Command is returned with RDR_to_PC_DataBlock(); - */ - USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + * Fills the Response buffer with ICC ATR + * This Command is returned with RDR_to_PC_DataBlock(); + */ + USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint8_t voltage; uint8_t sc_voltage = 0U; uint8_t index; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index aeac6bf588..42ff56c6bc 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -58,10 +58,13 @@ extern "C" { #define CDC_FS_BINTERVAL 0x10U #endif /* CDC_FS_BINTERVAL */ +#ifndef CDC_CMD_PACKET_SIZE +#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ +#endif /* CDC_CMD_PACKET_SIZE */ + /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ #define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ #define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ #define USB_CDC_CONFIG_DESC_SIZ 67U #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index ad8da254e0..050d996674 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -161,6 +161,9 @@ USBD_ClassTypeDef USBD_CDC = USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h index a69c4fd2e6..1284d4d608 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h @@ -68,6 +68,10 @@ extern "C" { #define CDC_ECM_FS_BINTERVAL 0x10U #endif /* CDC_ECM_FS_BINTERVAL */ +#ifndef CDC_ECM_CMD_PACKET_SIZE +#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ +#endif /* CDC_ECM_CMD_PACKET_SIZE */ + #ifndef USBD_SUPPORT_USER_STRING_DESC #define USBD_SUPPORT_USER_STRING_DESC 1U #endif /* USBD_SUPPORT_USER_STRING_DESC */ @@ -75,7 +79,6 @@ extern "C" { /* CDC_ECM Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ #define CDC_ECM_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ #define CDC_ECM_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ #define CDC_ECM_CONFIG_DESC_SIZ 79U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h index 50d18c42dd..3a262c3b80 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h @@ -66,12 +66,14 @@ extern "C" { #define CDC_RNDIS_FS_BINTERVAL 0x10U #endif /* CDC_RNDIS_FS_BINTERVAL */ +#ifndef CDC_RNDIS_CMD_PACKET_SIZE +#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ +#endif /* CDC_RNDIS_CMD_PACKET_SIZE */ /* CDC_RNDIS Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ #define CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ #define CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */ #define CDC_RNDIS_CONFIG_DESC_SIZ 75U #define CDC_RNDIS_DATA_HS_IN_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c index f04f2c222e..af56ca5ae0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -1414,7 +1414,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, case OID_GEN_VENDOR_DESCRIPTION: QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U); (void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC, - strlen(USBD_CDC_RNDIS_VENDOR_DESC)); + strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U); QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; break; @@ -1452,7 +1452,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, case OID_GEN_CURRENT_PACKET_FILTER: QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */ + QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter */ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; break; @@ -1641,6 +1641,13 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, /* Use temporary storage variables to comply with MISRA-C 2012 rule of (+) operand allowed types */ tmp1 = (uint32_t)PacketMsg; tmp2 = (uint32_t)(PacketMsg->DataOffset); + + /* Validate DataOffset and DataLength against the received MsgLength */ + if ((tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET + PacketMsg->DataLength) > PacketMsg->MsgLength) + { + return (uint8_t)USBD_FAIL; + } + hcdc->RxBuffer = (uint8_t *)(tmp1 + tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET); hcdc->RxLength = PacketMsg->DataLength; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c index e14c5cd817..dc4bae9454 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CompositeBuilder/Src/usbd_composite_builder.c @@ -511,11 +511,11 @@ uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev) /* Set IN endpoint slot */ iEp = pdev->tclasslist[pdev->classId].EpAdd[0]; - USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze); + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR,CUSTOM_HID_EPIN_SIZE); /* Set OUT endpoint slot */ iEp = pdev->tclasslist[pdev->classId].EpAdd[1]; - USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze); + USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE); /* Configure and Append the Descriptor */ USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL); @@ -1393,7 +1393,12 @@ static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, pDesc->bCountryCode = 0x00U; pDesc->bNumDescriptors = 0x01U; pDesc->bDescriptorType = 0x22U; +#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED + pDesc->wItemLength = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->wReportDescLen; +#else pDesc->wItemLength = USBD_CUSTOM_HID_REPORT_DESC_SIZE; +#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */ + *Sze += (uint32_t)sizeof(USBD_DescTypeDef); /* Descriptor of Custom HID endpoints */ @@ -1403,7 +1408,7 @@ static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, /* Append Endpoint descriptor to Configuration descriptor */ __USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[1].add, \ - USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL); + USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL); /* Update Config Descriptor and IAD descriptor */ ((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h index 2f4c6344f3..f81a708a07 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h @@ -103,9 +103,16 @@ typedef enum typedef struct _USBD_CUSTOM_HID_Itf { uint8_t *pReport; +#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED + uint16_t wReportDescLen; +#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */ int8_t (* Init)(void); int8_t (* DeInit)(void); +#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED + int8_t (* OutEvent)(uint8_t *report_buffer); +#else int8_t (* OutEvent)(uint8_t event_idx, uint8_t state); +#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ #ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED int8_t (* CtrlReqComplete)(uint8_t request, uint16_t wLength); #endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c index c64ba9913b..7ca8464db3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c @@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_CUSTOM_HID = USBD_CUSTOM_HID_GetOtherSpeedCfgDesc, USBD_CUSTOM_HID_GetDeviceQualifierDesc, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE @@ -284,6 +287,11 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 1U; + if (USBD_CUSTOMHID_OUTREPORT_BUF_SIZE < CUSTOM_HID_EPOUT_SIZE) + { + return (uint8_t)USBD_FAIL; + } + /* Open EP OUT */ (void)USBD_LL_OpenEP(pdev, CUSTOMHIDOutEpAdd, USBD_EP_TYPE_INTR, CUSTOM_HID_EPOUT_SIZE); @@ -397,9 +405,17 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, } #endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ #ifndef USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED + + if (req->wLength > USBD_CUSTOMHID_OUTREPORT_BUF_SIZE) + { + /* Stall EP0 */ + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + hhid->IsReportAvailable = 1U; - (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, - MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE)); + + (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength); #endif /* USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */ break; #ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED @@ -675,6 +691,11 @@ static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = CUSTOM_HID_IDLE; return (uint8_t)USBD_OK; @@ -701,8 +722,13 @@ static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application processing */ + +#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf); +#else ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0], hhid->Report_buf[1]); +#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ return (uint8_t)USBD_OK; } @@ -755,8 +781,12 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) if (hhid->IsReportAvailable == 1U) { +#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf); +#else ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0], hhid->Report_buf[1]); +#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ hhid->IsReportAvailable = 0U; } diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c index 85881bdc5b..e5a7e73f11 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -32,7 +32,11 @@ EndBSPDependencies */ static int8_t TEMPLATE_CUSTOM_HID_Init(void); static int8_t TEMPLATE_CUSTOM_HID_DeInit(void); +#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED +static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t *report_buffer); +#else static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state); +#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ #ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength); @@ -49,6 +53,9 @@ __ALIGN_BEGIN static uint8_t TEMPLATE_CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPO USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops = { TEMPLATE_CUSTOM_HID_ReportDesc, +#ifdef USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED + USBD_CUSTOM_HID_REPORT_DESC_SIZE, +#endif /* USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */ TEMPLATE_CUSTOM_HID_Init, TEMPLATE_CUSTOM_HID_DeInit, TEMPLATE_CUSTOM_HID_OutEvent, @@ -95,10 +102,17 @@ static int8_t TEMPLATE_CUSTOM_HID_DeInit(void) * @param state: event state * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ + +#ifdef USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED +static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t *report_buffer) +{ + UNUSED(report_buffer); +#else static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state) { UNUSED(event_idx); UNUSED(state); +#endif /* USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ /* Start next USB packet transfer once data processing is completed */ if (USBD_CUSTOM_HID_ReceivePacket(&USBD_Device) != (uint8_t)USBD_OK) @@ -151,7 +165,7 @@ static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLen static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength) { UNUSED(ReportLength); - uint8_t *pbuff; + uint8_t *pbuff = NULL; return (pbuff); } diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c index 67ba12c48e..4f0bac1e52 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c @@ -940,6 +940,12 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) if ((hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || (hdfu->dev_state == DFU_STATE_IDLE)) { #if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U) + /* Fill the buffer to be checked with the address stored in data buffer */ + hdfu->buffer.d8[1] = (uint8_t)(hdfu->data_ptr & 0xFFU); + hdfu->buffer.d8[2] = (uint8_t)((hdfu->data_ptr & 0xFF00U) >> 8U); + hdfu->buffer.d8[3] = (uint8_t)((hdfu->data_ptr & 0xFF0000U) >> 16U); + hdfu->buffer.d8[4] = (uint8_t)((hdfu->data_ptr & 0xFF000000U) >> 24U); + if (DfuInterface->VendorCheck(hdfu->buffer.d8, IS_DFU_SETADDRESSPOINTER, &VendorStatus) != USBD_OK) { /* Update the state machine */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c index fdf757810a..f226b0bba7 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c @@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_HID = USBD_HID_GetOtherSpeedCfgDesc, USBD_HID_GetDeviceQualifierDesc, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE @@ -615,6 +618,11 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) UNUSED(epnum); /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + ((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = USBD_HID_IDLE; return (uint8_t)USBD_OK; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h index e55fef48d9..1f1ad10f48 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h @@ -62,6 +62,10 @@ extern "C" { #define MSC_EPOUT_ADDR 0x01U #endif /* MSC_EPOUT_ADDR */ +#ifndef MSC_BOT_MAX_LUN +#define MSC_BOT_MAX_LUN 0x2U +#endif /* MSC_BOT_MAX_LUN */ + /** * @} */ @@ -82,6 +86,13 @@ typedef struct _USBD_STORAGE } USBD_StorageTypeDef; +typedef struct +{ + uint16_t size; + uint32_t nbr; + uint32_t addr; + uint32_t len; +} USBD_MSC_BOT_LUN_TypeDef; typedef struct { @@ -99,11 +110,7 @@ typedef struct uint8_t scsi_sense_tail; uint8_t scsi_medium_state; - uint16_t scsi_blk_size; - uint32_t scsi_blk_nbr; - - uint32_t scsi_blk_addr; - uint32_t scsi_blk_len; + USBD_MSC_BOT_LUN_TypeDef scsi_blk[MSC_BOT_MAX_LUN + 1U]; } USBD_MSC_BOT_HandleTypeDef; /* Structure for MSC process */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h index c96d2b84ed..a321c91fb3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h @@ -44,6 +44,8 @@ extern "C" { #define LENGTH_INQUIRY_PAGE00 0x06U #define LENGTH_INQUIRY_PAGE80 0x08U #define LENGTH_FORMAT_CAPACITIES 0x14U +#define DIAGNOSTIC_DATA_LEN 0x08U +#define LOG_PAGE_DATA_LEN 0x10U /** * @} @@ -74,6 +76,8 @@ extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00]; extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80]; extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN]; extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN]; +extern uint8_t MSC_Diagnostic_Data[DIAGNOSTIC_DATA_LEN]; +extern uint8_t MSC_Log_Page_Data[LOG_PAGE_DATA_LEN]; /** * @} diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h index 477affbb48..6000c2b5bd 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h @@ -70,8 +70,10 @@ extern "C" { #define SCSI_VERIFY12 0xAFU #define SCSI_VERIFY16 0x8FU -#define SCSI_SEND_DIAGNOSTIC 0x1DU #define SCSI_READ_FORMAT_CAPACITIES 0x23U +#define SCSI_RECEIVE_DIAGNOSTIC_RESULTS 0x1CU +#define SCSI_SEND_DIAGNOSTIC 0x1DU +#define SCSI_REPORT_LUNS 0xA0U #define NO_SENSE 0U #define RECOVERED_ERROR 1U @@ -88,9 +90,8 @@ extern "C" { #define VOLUME_OVERFLOW 13U #define MISCOMPARE 14U - #define INVALID_CDB 0x20U -#define INVALID_FIELED_IN_COMMAND 0x24U +#define INVALID_FIELD_IN_COMMAND 0x24U #define PARAMETER_LIST_LENGTH_ERROR 0x1AU #define INVALID_FIELD_IN_PARAMETER_LIST 0x26U #define ADDRESS_OUT_OF_RANGE 0x21U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c index 7f2152f38b..eafb8bafa4 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c @@ -125,6 +125,9 @@ USBD_ClassTypeDef USBD_MSC = USBD_MSC_GetOtherSpeedCfgDesc, USBD_MSC_GetDeviceQualifierDescriptor, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; /* USB Mass storage device Configuration Descriptor */ @@ -309,6 +312,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_StatusTypeDef ret = USBD_OK; + uint32_t max_lun; uint16_t status_info = 0U; #ifdef USE_USBD_COMPOSITE @@ -332,7 +336,8 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) if ((req->wValue == 0U) && (req->wLength == 1U) && ((req->bmRequest & 0x80U) == 0x80U)) { - hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun(); + max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetMaxLun(); + hmsc->max_lun = (max_lun > MSC_BOT_MAX_LUN) ? MSC_BOT_MAX_LUN : max_lun; (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U); } else diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c index c51b01361f..4dab4c8edc 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c @@ -273,7 +273,7 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) || (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) || - (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) || + (hmsc->cbw.bLUN > hmsc->max_lun) || (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U)) { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); @@ -346,7 +346,7 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t length = MIN(hmsc->cbw.dDataLength, len); - hmsc->csw.dDataResidue -= len; + hmsc->csw.dDataResidue -= length; hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; hmsc->bot_state = USBD_BOT_SEND_DATA; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c index 1641c20fec..b7acde32b5 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c @@ -81,7 +81,7 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = 0x00, 0x80, 0x00, - LENGTH_INQUIRY_PAGE80, + (LENGTH_INQUIRY_PAGE80 - 4U), 0x20, /* Put Product Serial number */ 0x20, 0x20, @@ -118,6 +118,19 @@ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = 0x00, /* BLOCK DESCRIPTOR LENGTH MSB. */ 0x00 /* BLOCK DESCRIPTOR LENGTH LSB. */ }; + +uint8_t MSC_Diagnostic_Data[DIAGNOSTIC_DATA_LEN] = +{ + 0x00, /* Byte 0: ADDITIONAL LENGTH (MSB) */ + 0x00, /* Byte 1: ADDITIONAL LENGTH (LSB) */ + 0x00, /* Byte 2: FRU CODE (most probable) */ + 0x00, /* Byte 3: FRU CODE */ + 0x00, /* Byte 4: FRU CODE */ + 0x00, /* Byte 5: FRU CODE (least probable) */ + 0x00, /* Byte 6: ERROR CODE (MSB) */ + 0x00, /* Byte 7: ERROR CODE (LSB) */ +}; + /** * @} */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index 3c0fe2f487..3ca57a5bea 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -85,6 +85,10 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun, + uint32_t param_list_length); +static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); @@ -92,6 +96,8 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReceiveDiagnosticResults(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, uint32_t blk_offset, uint32_t blk_nbr); @@ -150,6 +156,14 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) ret = SCSI_AllowPreventRemovable(pdev, lun, cmd); break; + case SCSI_MODE_SELECT6: + ret = SCSI_ModeSelect6(pdev, lun, cmd); + break; + + case SCSI_MODE_SELECT10: + ret = SCSI_ModeSelect10(pdev, lun, cmd); + break; + case SCSI_MODE_SENSE6: ret = SCSI_ModeSense6(pdev, lun, cmd); break; @@ -190,9 +204,17 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) ret = SCSI_Verify10(pdev, lun, cmd); break; + case SCSI_REPORT_LUNS: + ret = SCSI_ReportLuns(pdev, lun, cmd); + break; + + case SCSI_RECEIVE_DIAGNOSTIC_RESULTS: + ret = SCSI_ReceiveDiagnosticResults(pdev, lun, cmd); + break; + default: SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); - hmsc->bot_status = USBD_BOT_STATUS_ERROR; + hmsc->bot_state = USBD_BOT_NO_DATA; ret = -1; break; } @@ -283,7 +305,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param else /* Request Not supported */ { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, - INVALID_FIELED_IN_COMMAND); + INVALID_FIELD_IN_COMMAND); return -1; } @@ -319,14 +341,17 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t UNUSED(params); int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, - &hmsc->scsi_blk_size); + p_scsi_blk = &hmsc->scsi_blk[lun]; + + ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr, + &p_scsi_blk->size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { @@ -334,20 +359,19 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return -1; } - hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); - hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); - hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); - hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); + hmsc->bot_data[0] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 24); + hmsc->bot_data[1] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 16); + hmsc->bot_data[2] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 8); + hmsc->bot_data[3] = (uint8_t)(p_scsi_blk->nbr - 1U); - hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24); - hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16); - hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8); - hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); + hmsc->bot_data[4] = (uint8_t)(p_scsi_blk->size >> 24); + hmsc->bot_data[5] = (uint8_t)(p_scsi_blk->size >> 16); + hmsc->bot_data[6] = (uint8_t)(p_scsi_blk->size >> 8); + hmsc->bot_data[7] = (uint8_t)(p_scsi_blk->size); hmsc->bot_data_length = 8U; return 0; - } @@ -360,18 +384,21 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t */ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - UNUSED(params); uint32_t idx; + uint32_t alloc_len; int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, - &hmsc->scsi_blk_size); + p_scsi_blk = &hmsc->scsi_blk[lun]; + + ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr, + &p_scsi_blk->size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) { @@ -379,30 +406,29 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return -1; } - hmsc->bot_data_length = ((uint32_t)params[10] << 24) | - ((uint32_t)params[11] << 16) | - ((uint32_t)params[12] << 8) | - (uint32_t)params[13]; - - for (idx = 0U; idx < hmsc->bot_data_length; idx++) + /* READ CAPACITY(16) response is 32 bytes per SBC-3 */ + for (idx = 0U; idx < 32U; idx++) { hmsc->bot_data[idx] = 0U; } - hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); - hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); - hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 8); - hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); + hmsc->bot_data[4] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 24); + hmsc->bot_data[5] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 16); + hmsc->bot_data[6] = (uint8_t)((p_scsi_blk->nbr - 1U) >> 8); + hmsc->bot_data[7] = (uint8_t)(p_scsi_blk->nbr - 1U); + + hmsc->bot_data[8] = (uint8_t)(p_scsi_blk->size >> 24); + hmsc->bot_data[9] = (uint8_t)(p_scsi_blk->size >> 16); + hmsc->bot_data[10] = (uint8_t)(p_scsi_blk->size >> 8); + hmsc->bot_data[11] = (uint8_t)(p_scsi_blk->size); - hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >> 24); - hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >> 16); - hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >> 8); - hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size); + /* Clamp transfer length to actual response size (32 bytes) */ + alloc_len = ((uint32_t)params[10] << 24) | + ((uint32_t)params[11] << 16) | + ((uint32_t)params[12] << 8) | + (uint32_t)params[13]; - hmsc->bot_data_length = ((uint32_t)params[10] << 24) | - ((uint32_t)params[11] << 16) | - ((uint32_t)params[12] << 8) | - (uint32_t)params[13]; + hmsc->bot_data_length = MIN(alloc_len, 32U); return 0; } @@ -417,8 +443,8 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t */ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - UNUSED(params); uint16_t blk_size; + uint16_t alloc_len; uint32_t blk_nbr; uint16_t i; int8_t ret; @@ -453,12 +479,116 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin hmsc->bot_data[10] = (uint8_t)(blk_size >> 8); hmsc->bot_data[11] = (uint8_t)(blk_size); - hmsc->bot_data_length = 12U; + alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8]; + hmsc->bot_data_length = MIN(alloc_len, READ_FORMAT_CAPACITY_DATA_LEN); + + return 0; +} + + +/** + * @brief SCSI_ProcessModeSelect + * Drain MODE SELECT parameter data without applying mode pages + * @param lun: Logical unit number + * @param param_list_length: Mode parameter list length from the CDB + * @retval status + */ +static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun, + uint32_t param_list_length) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; + uint32_t packet_length; + uint32_t rx_length; + + UNUSED(param_list_length); + + if (hmsc == NULL) + { + return -1; + } + + p_scsi_blk = &hmsc->scsi_blk[lun]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (hmsc->bot_state == USBD_BOT_IDLE) + { + if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) + { + hmsc->bot_state = USBD_BOT_NO_DATA; + hmsc->bot_data_length = 0U; + return 0; + } + + if (hmsc->cbw.dDataLength == 0U) + { + hmsc->bot_data_length = 0U; + return 0; + } + + p_scsi_blk->len = hmsc->cbw.dDataLength; + hmsc->bot_state = USBD_BOT_DATA_OUT; + + packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET); + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length); + + return 0; + } + + rx_length = USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd); + + if (rx_length >= p_scsi_blk->len) + { + hmsc->csw.dDataResidue -= p_scsi_blk->len; + p_scsi_blk->len = 0U; + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + } + else + { + p_scsi_blk->len -= rx_length; + hmsc->csw.dDataResidue -= rx_length; + packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET); + (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length); + } return 0; } +/** + * @brief SCSI_ModeSelect6 + * Process Mode Select6 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ +static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + return SCSI_ProcessModeSelect(pdev, lun, params[4]); +} + + +/** + * @brief SCSI_ModeSelect10 + * Process Mode Select10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ +static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint32_t param_list_length; + + param_list_length = ((uint32_t)params[7] << 8) | (uint32_t)params[8]; + + return SCSI_ProcessModeSelect(pdev, lun, param_list_length); +} + + /** * @brief SCSI_ModeSense6 * Process Mode Sense6 command @@ -468,7 +598,6 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin */ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len = MODE_SENSE6_LEN; @@ -480,7 +609,11 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa /* Check If media is write-protected */ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) { - MSC_Mode_Sense6_data[2] |= 0x80U; + MSC_Mode_Sense6_data[2] |= (0x1U << 7); /* Set the WP (write protection) bit */ + } + else + { + MSC_Mode_Sense6_data[2] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */ } if (params[4] <= len) @@ -503,9 +636,9 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa */ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { - UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint16_t len = MODE_SENSE10_LEN; + uint16_t alloc_len; if (hmsc == NULL) { @@ -515,12 +648,19 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p /* Check If media is write-protected */ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) { - MSC_Mode_Sense10_data[3] |= 0x80U; + MSC_Mode_Sense10_data[3] |= (0x1U << 7); /* Set the WP (write protection) bit */ + } + else + { + MSC_Mode_Sense10_data[3] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */ } - if (params[8] <= len) + /* Allocation length is a 16-bit field: CDB bytes 7-8 */ + alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8]; + + if (alloc_len < len) { - len = params[8]; + len = alloc_len; } (void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense10_data, len); @@ -613,6 +753,16 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t { hmsc->scsi_sense_tail = 0U; } + + if (hmsc->scsi_sense_tail == hmsc->scsi_sense_head) + { + hmsc->scsi_sense_head++; + + if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) + { + hmsc->scsi_sense_head = 0U; + } + } } @@ -635,7 +785,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U)) { - SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELD_IN_COMMAND); return -1; } @@ -704,12 +854,15 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; if (hmsc == NULL) { return -1; } + p_scsi_blk = &hmsc->scsi_blk[lun]; + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { /* case 10 : Ho <> Di */ @@ -732,21 +885,20 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; } - hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | - ((uint32_t)params[3] << 16) | - ((uint32_t)params[4] << 8) | - (uint32_t)params[5]; + p_scsi_blk->addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; - hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | (uint32_t)params[8]; + p_scsi_blk->len = ((uint32_t)params[7] << 8) | (uint32_t)params[8]; - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, - hmsc->scsi_blk_len) < 0) + if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0) { return -1; /* error */ } /* cases 4,5 : Hi <> Dn */ - if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) + if (hmsc->cbw.dDataLength != (p_scsi_blk->len * p_scsi_blk->size)) { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); return -1; @@ -770,12 +922,15 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; if (hmsc == NULL) { return -1; } + p_scsi_blk = &hmsc->scsi_blk[lun]; + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { /* case 10 : Ho <> Di */ @@ -797,24 +952,23 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params return -1; } - hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | - ((uint32_t)params[3] << 16) | - ((uint32_t)params[4] << 8) | - (uint32_t)params[5]; + p_scsi_blk->addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; - hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) | - ((uint32_t)params[7] << 16) | - ((uint32_t)params[8] << 8) | - (uint32_t)params[9]; + p_scsi_blk->len = ((uint32_t)params[6] << 24) | + ((uint32_t)params[7] << 16) | + ((uint32_t)params[8] << 8) | + (uint32_t)params[9]; - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, - hmsc->scsi_blk_len) < 0) + if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0) { return -1; /* error */ } /* cases 4,5 : Hi <> Dn */ - if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) + if (hmsc->cbw.dDataLength != (p_scsi_blk->len * p_scsi_blk->size)) { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); return -1; @@ -838,6 +992,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; uint32_t len; if (hmsc == NULL) @@ -845,6 +1000,8 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param return -1; } + p_scsi_blk = &hmsc->scsi_blk[lun]; + #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); @@ -865,10 +1022,18 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param return -1; } + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + /* Check whether Media is ready */ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; return -1; } @@ -876,25 +1041,25 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0) { SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED); + hmsc->bot_state = USBD_BOT_NO_DATA; return -1; } - hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | - ((uint32_t)params[3] << 16) | - ((uint32_t)params[4] << 8) | - (uint32_t)params[5]; + p_scsi_blk->addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; - hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) | - (uint32_t)params[8]; + p_scsi_blk->len = ((uint32_t)params[7] << 8) | + (uint32_t)params[8]; /* check if LBA address is in the right range */ - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, - hmsc->scsi_blk_len) < 0) + if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0) { return -1; /* error */ } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + len = p_scsi_blk->len * p_scsi_blk->size; /* cases 3,11,13 : Hn,Ho <> D0 */ if (hmsc->cbw.dDataLength != len) @@ -928,12 +1093,16 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; uint32_t len; if (hmsc == NULL) { return -1; } + + p_scsi_blk = &hmsc->scsi_blk[lun]; + #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); @@ -954,6 +1123,13 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param return -1; } + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + /* Check whether Media is ready */ if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) { @@ -970,24 +1146,23 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param return -1; } - hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) | - ((uint32_t)params[3] << 16) | - ((uint32_t)params[4] << 8) | - (uint32_t)params[5]; + p_scsi_blk->addr = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; - hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) | - ((uint32_t)params[7] << 16) | - ((uint32_t)params[8] << 8) | - (uint32_t)params[9]; + p_scsi_blk->len = ((uint32_t)params[6] << 24) | + ((uint32_t)params[7] << 16) | + ((uint32_t)params[8] << 8) | + (uint32_t)params[9]; /* check if LBA address is in the right range */ - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, - hmsc->scsi_blk_len) < 0) + if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0) { return -1; /* error */ } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + len = p_scsi_blk->len * p_scsi_blk->size; /* cases 3,11,13 : Hn,Ho <> D0 */ if (hmsc->cbw.dDataLength != len) @@ -1021,19 +1196,51 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint32_t blk_offset; + uint32_t blk_nbr; if (hmsc == NULL) { return -1; } + if (hmsc->cbw.dDataLength != 0U) + { + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + + if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0) + { + SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + if ((params[1] & 0x02U) == 0x02U) { - SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELD_IN_COMMAND); + hmsc->bot_state = USBD_BOT_NO_DATA; return -1; /* Error, Verify Mode Not supported*/ } - if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) + /* Decode LBA and verification length from current CDB */ + blk_offset = ((uint32_t)params[2] << 24) | + ((uint32_t)params[3] << 16) | + ((uint32_t)params[4] << 8) | + (uint32_t)params[5]; + + blk_nbr = ((uint32_t)params[7] << 8) | (uint32_t)params[8]; + + if (SCSI_CheckAddressRange(pdev, lun, blk_offset, blk_nbr) < 0) { return -1; /* error */ } @@ -1043,6 +1250,111 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para return 0; } +/** + * @brief SCSI_ReportLuns12 + * Process ReportLuns command + * @retval status + */ +static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc; + uint32_t report_idx; + uint32_t lun_list_length; + uint32_t total_length; + uint32_t alloc_len; + uint8_t lun_idx; + + UNUSED(lun); + + /* Define the report LUNs buffer: 8-byte header + 8 bytes per LUN entry */ + static uint8_t lun_report[8U + (8U * (MSC_BOT_MAX_LUN + 1U))]; + + hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hmsc == NULL) + { + return -1; + } + + /* Initialize the report LUNs buffer */ + for (report_idx = 0U; report_idx < sizeof(lun_report); report_idx++) + { + lun_report[report_idx] = 0U; + } + + /* Set the LUN list length in the first 4 bytes */ + lun_list_length = 8U * (hmsc->max_lun + 1U); + lun_report[0] = (uint8_t)(lun_list_length >> 24); + lun_report[1] = (uint8_t)(lun_list_length >> 16); + lun_report[2] = (uint8_t)(lun_list_length >> 8); + lun_report[3] = (uint8_t)(lun_list_length & 0xFFU); + + /* Update the LUN list */ + for (lun_idx = 0U; lun_idx <= hmsc->max_lun; lun_idx++) + { + /* LUN identifier is placed at the second byte of each 8-byte entry */ + lun_report[(8U * (lun_idx + 1U)) + 1U] = lun_idx; + } + + /* Calculate the total length of the report LUNs buffer */ + total_length = lun_list_length + 8U; + + /* Clamp to allocation length from CDB bytes 6-9 */ + alloc_len = ((uint32_t)params[6] << 24) | + ((uint32_t)params[7] << 16) | + ((uint32_t)params[8] << 8) | + (uint32_t)params[9]; + + if (alloc_len < total_length) + { + total_length = alloc_len; + } + + /* Update the BOT data with the report LUNs buffer */ + (void)SCSI_UpdateBotData(hmsc, lun_report, (uint16_t)total_length); + + return 0; +} + +/** + * @brief SCSI_ReceiveDiagnosticResults + * Process SCSI_Receive Diagnostic Results command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ +static int8_t SCSI_ReceiveDiagnosticResults(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + UNUSED(lun); + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint16_t allocation_length; + + if (hmsc == NULL) + { + return -1; + } + + /* Extract the allocation length from the CDB */ + allocation_length = (((uint16_t)params[3] << 8) | (uint16_t)params[4]); + + if (allocation_length == 0U) + { + hmsc->bot_data_length = 0U; + return 0; + } + + /* Ensure the allocation length does not exceed the diagnostic data length */ + if (allocation_length > DIAGNOSTIC_DATA_LEN) + { + allocation_length = DIAGNOSTIC_DATA_LEN; + } + + /* Send the diagnostic data to the host */ + (void)SCSI_UpdateBotData(hmsc, MSC_Diagnostic_Data, allocation_length); + + return 0; +} + /** * @brief SCSI_CheckAddressRange * Check address range @@ -1055,13 +1367,21 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, uint32_t blk_offset, uint32_t blk_nbr) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; if (hmsc == NULL) { return -1; } - if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) + p_scsi_blk = &hmsc->scsi_blk[lun]; + + /* Refresh cached capacity for this LUN so multi-LUN configs + with different sizes use the correct block count. */ + (void)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr, + &p_scsi_blk->size); + + if ((blk_nbr > p_scsi_blk->nbr) || (blk_offset > (p_scsi_blk->nbr - blk_nbr))) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); return -1; @@ -1079,6 +1399,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; uint32_t len; if (hmsc == NULL) @@ -1086,7 +1407,9 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) return -1; } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + p_scsi_blk = &hmsc->scsi_blk[lun]; + + len = p_scsi_blk->len * p_scsi_blk->size; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ @@ -1096,8 +1419,8 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) len = MIN(len, MSC_MEDIA_PACKET); if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Read(lun, hmsc->bot_data, - hmsc->scsi_blk_addr, - (len / hmsc->scsi_blk_size)) < 0) + p_scsi_blk->addr, + (len / p_scsi_blk->size)) < 0) { SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); return -1; @@ -1105,13 +1428,13 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) (void)USBD_LL_Transmit(pdev, MSCInEpAdd, hmsc->bot_data, len); - hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); - hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); + p_scsi_blk->addr += (len / p_scsi_blk->size); + p_scsi_blk->len -= (len / p_scsi_blk->size); /* case 6 : Hi = Di */ hmsc->csw.dDataResidue -= len; - if (hmsc->scsi_blk_len == 0U) + if (p_scsi_blk->len == 0U) { hmsc->bot_state = USBD_BOT_LAST_DATA_IN; } @@ -1128,6 +1451,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk; uint32_t len; if (hmsc == NULL) @@ -1135,7 +1459,9 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) return -1; } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + p_scsi_blk = &hmsc->scsi_blk[lun]; + + len = p_scsi_blk->len * p_scsi_blk->size; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ @@ -1144,27 +1470,26 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) len = MIN(len, MSC_MEDIA_PACKET); - if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data, - hmsc->scsi_blk_addr, - (len / hmsc->scsi_blk_size)) < 0) + if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Write(lun, hmsc->bot_data, p_scsi_blk->addr, + (len / p_scsi_blk->size)) < 0) { SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT); return -1; } - hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size); - hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size); + p_scsi_blk->addr += (len / p_scsi_blk->size); + p_scsi_blk->len -= (len / p_scsi_blk->size); /* case 12 : Ho = Do */ hmsc->csw.dDataResidue -= len; - if (hmsc->scsi_blk_len == 0U) + if (p_scsi_blk->len == 0U) { MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); } else { - len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET); + len = MIN((p_scsi_blk->len * p_scsi_blk->size), MSC_MEDIA_PACKET); /* Prepare EP to Receive next packet */ (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h index df2644fdd0..77807f3442 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp.h @@ -67,9 +67,12 @@ extern "C" { #define MTP_FS_BINTERVAL 0x10U #endif /* MTP_FS_BINTERVAL */ +#ifndef MTP_CMD_PACKET_SIZE +#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ +#endif /* MTP_CMD_PACKET_SIZE */ + #define MTP_DATA_MAX_HS_PACKET_SIZE 512U #define MTP_DATA_MAX_FS_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ -#define MTP_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ #define MTP_MEDIA_PACKET 512U #define MTP_CONT_HEADER_SIZE 12U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h index 4dee923d6b..55de393359 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_opt.h @@ -283,7 +283,7 @@ extern "C" { * Appendix C. Device Properties */ -/* MTP device properties code*/ +/* MTP device properties code */ #define MTP_DEV_PROP_UNDEFINED 0x5000U #define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U #define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U @@ -336,7 +336,7 @@ extern "C" { #define MTP_CONT_TYPE_EVENT 4U #ifndef MTP_STORAGE_ID -#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/ +#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted */ #endif /* MTP_STORAGE_ID */ #define MTP_NBR_STORAGE_ID 1U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h index ba01901e75..f77670c786 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Inc/usbd_mtp_storage.h @@ -53,15 +53,16 @@ extern "C" { typedef enum { - DATA_TYPE = 0x00, - REP_TYPE = 0x01, + DATA_TYPE = 0x00U, + REP_TYPE = 0x01U, } MTP_CONTAINER_TYPE; typedef enum { - READ_FIRST_DATA = 0x00, - READ_REST_OF_DATA = 0x01, + READ_FIRST_DATA = 0x00U, + READ_REST_OF_DATA = 0x01U, + READ_SEND_ZLP_DATA = 0x02U } MTP_READ_DATA_STATUS; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c index b0950e8eaa..adf8e0aeb0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp.c @@ -128,6 +128,9 @@ USBD_ClassTypeDef USBD_MTP = USBD_MTP_GetOtherSpeedCfgDesc, USBD_MTP_GetDeviceQualifierDescriptor, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE @@ -484,7 +487,7 @@ static uint8_t USBD_MTP_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /* prepare to receive next operation */ len = MIN(hmtp->MaxPcktLen, pdev->request.wLength); - (void)USBD_LL_PrepareReceive(pdev, MTPInEpAdd, (uint8_t *)&hmtp->rx_buff, len); + (void)USBD_LL_PrepareReceive(pdev, MTPOutEpAdd, (uint8_t *)&hmtp->rx_buff, len); break; case MTP_PHASE_IDLE : diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c index 9a49717bb7..df154aebec 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_opt.c @@ -23,7 +23,7 @@ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ -static uint8_t ObjInfo_buff[255]; +static uint8_t ObjInfo_buff[576]; static uint32_t objhandle; static uint16_t obj_format; static uint32_t storage_id; @@ -385,7 +385,6 @@ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; - static uint32_t tmp = 0U; switch (hmtp->RECEIVE_DATA_STATUS) { @@ -410,8 +409,7 @@ void USBD_MTP_OPT_SendObject(USBD_HandleTypeDef *pdev, uint8_t *buff, uint32_t { hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA; } - tmp = (uint32_t)buff; - hmtpif->WriteData(len, (uint8_t *)(tmp + 12U)); + hmtpif->WriteData(len, (buff + 12U)); break; case RECEIVE_REST_OF_DATA: @@ -474,21 +472,26 @@ void USBD_MTP_OPT_SendObjectInfo(USBD_HandleTypeDef *pdev, uint8_t *buff, uint3 tmp = buff; (void)USBD_memcpy(ObjInfo_buff, tmp + 12U, - (uint16_t)(hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE)); + (uint16_t)MIN(hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE, + sizeof(ObjInfo_buff))); hmtp->RECEIVE_DATA_STATUS = RECEIVE_REST_OF_DATA; break; case RECEIVE_REST_OF_DATA: - - (void)USBD_memcpy(ObjInfo_buff + len, buff, hmtp->MaxPcktLen); - + if (len < (uint32_t)sizeof(ObjInfo_buff)) + { + (void)USBD_memcpy(ObjInfo_buff + len, buff, + (uint16_t)MIN(hmtp->MaxPcktLen, + sizeof(ObjInfo_buff) - len)); + } break; case SEND_RESPONSE: (void)USBD_memcpy((uint8_t *)&ObjectInfo, ObjInfo_buff, dataLength); (void)USBD_memcpy((uint8_t *)&ObjectInfo.Filename, (ObjInfo_buff + dataLength), - ((uint32_t)(ObjectInfo.Filename_len) * 2U)); + MIN((uint32_t)(ObjectInfo.Filename_len) * 2U, + (uint32_t)(sizeof(ObjInfo_buff) - dataLength))); obj_format = ObjectInfo.ObjectFormat; @@ -537,50 +540,31 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; - uint8_t *buffer = hmtp->GenericContainer.data; - uint32_t i; + uint8_t *buffer; uint32_t n_idx; switch (hmtp->OperationsContainer.code) { case MTP_OP_GET_DEVICE_INFO: (void)MTP_Get_DeviceInfo(); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DeviceInfo, sizeof(MTP_DeviceInfo)); - - for (i = 0U; i < sizeof(MTP_StorageIDS); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_DeviceInfo, + MIN(sizeof(MTP_DeviceInfo), MTP_MEDIA_PACKET)); break; case MTP_OP_GET_STORAGE_IDS: (void)MTP_Get_StorageIDS(); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageIDS, sizeof(MTP_StorageIDS)); - - for (i = 0U; i < sizeof(MTP_StorageIDS); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_StorageIDS, sizeof(MTP_StorageIDS)); break; case MTP_OP_GET_STORAGE_INFO: (void)MTP_Get_StorageInfo(pdev); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_StorageInfo, sizeof(MTP_StorageInfo)); - - for (i = 0U; i < sizeof(MTP_StorageInfo); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_StorageInfo, sizeof(MTP_StorageInfo)); break; case MTP_OP_GET_OBJECT_HANDLES: (void)MTP_Get_ObjectHandle(pdev); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectHandle, hmtp->ResponseLength); - - for (i = 0U; i < hmtp->ResponseLength; i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_ObjectHandle, + MIN(hmtp->ResponseLength, MTP_MEDIA_PACKET)); break; case MTP_OP_GET_OBJECT_INFO: @@ -589,12 +573,7 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) case MTP_OP_GET_OBJECT_PROPS_SUPPORTED: (void)MTP_Get_ObjectPropSupp(); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_ObjectPropSupp, sizeof(MTP_ObjectPropSupp)); - - for (i = 0U; i < sizeof(MTP_ObjectPropSupp); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_ObjectPropSupp, sizeof(MTP_ObjectPropSupp)); break; case MTP_OP_GET_OBJECT_PROP_DESC: @@ -604,12 +583,7 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) case MTP_OP_GET_OBJECT_PROP_REFERENCES: MTP_Ref.ref_len = 0U; - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_Ref.ref_len, sizeof(MTP_Ref.ref_len)); - - for (i = 0U; i < sizeof(MTP_Ref.ref_len); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_Ref.ref_len, sizeof(MTP_Ref.ref_len)); break; case MTP_OP_GET_OBJECT_PROPLIST: @@ -618,20 +592,14 @@ static void MTP_Get_PayloadContent(USBD_HandleTypeDef *pdev) case MTP_OP_GET_OBJECT_PROP_VALUE: buffer = MTP_Get_ObjectPropValue(pdev); - for (i = 0U; i < hmtp->ResponseLength; i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } - + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)buffer, + MIN(hmtp->ResponseLength, MTP_MEDIA_PACKET)); break; case MTP_OP_GET_DEVICE_PROP_DESC: (void)MTP_Get_DevicePropDesc(); - (void)USBD_memcpy(buffer, (const uint8_t *)&MTP_DevicePropDesc, sizeof(MTP_DevicePropDesc)); - for (i = 0U; i < sizeof(MTP_DevicePropDesc); i++) - { - hmtp->GenericContainer.data[i] = buffer[i]; - } + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&MTP_DevicePropDesc, + MIN(sizeof(MTP_DevicePropDesc), MTP_MEDIA_PACKET)); break; case MTP_OP_SEND_OBJECT_INFO: @@ -837,7 +805,7 @@ static void MTP_Get_ObjectPropDesc(USBD_HandleTypeDef *pdev) case MTP_OB_PROP_PARENT_OBJECT : MTP_ObjectPropDesc.ObjectPropertyCode = (uint16_t)(hmtp->OperationsContainer.Param1); - MTP_ObjectPropDesc.DataType = MTP_DATATYPE_STR; + MTP_ObjectPropDesc.DataType = MTP_DATATYPE_UINT32; MTP_ObjectPropDesc.GetSet = MTP_PROP_GET; MTP_ObjectPropDesc.DefValue = 0U; MTP_ObjectPropDesc.GroupCode = 0U; @@ -919,9 +887,12 @@ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev) case MTP_OB_PROP_OBJ_FILE_NAME: MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, (uint16_t *)buf); - (void)USBD_memcpy(MTP_FileName.FileName, (uint16_t *)buf, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + (void)USBD_memcpy(MTP_FileName.FileName, (uint16_t *)buf, + MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U, + sizeof(MTP_FileName.FileName))); - hmtp->ResponseLength = ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U; + hmtp->ResponseLength = MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U, + sizeof(MTP_FileName.FileName)); break; case MTP_OB_PROP_PARENT_OBJECT : @@ -951,8 +922,8 @@ static uint8_t *MTP_Get_ObjectPropValue(USBD_HandleTypeDef *pdev) */ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_ItfTypeDef *hmtpif = (USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId]; uint16_t filename[255]; uint32_t storageid = MTP_STORAGE_ID; uint32_t default_val = 0U; @@ -960,6 +931,7 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) uint16_t format; uint64_t objsize; uint32_t parent_proval; + uint8_t mtp_pers_uniq_obj_id[16] = {0}; MTP_PropertiesList.MTP_Properties_len = SUPP_OBJ_PROP_LEN; hmtp->ResponseLength = 4U; /* size of MTP_PropertiesList.MTP_Properties_len */ @@ -991,7 +963,9 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) /* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */ MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename); - (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + (void)USBD_memcpy(MTP_FileName.FileName, filename, + MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U, + sizeof(MTP_FileName.FileName))); MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; break; @@ -1015,14 +989,20 @@ static void MTP_Get_ObjectPropList(USBD_HandleTypeDef *pdev) /* MTP_FileName.FileName_len value shall be set before USBD_MTP_FS_GetObjectName */ MTP_FileName.FileName_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_FileName.FileName_len, filename); - (void)USBD_memcpy(MTP_FileName.FileName, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + (void)USBD_memcpy(MTP_FileName.FileName, filename, + MIN(((uint32_t)MTP_FileName.FileName_len * 2U) + 1U, + sizeof(MTP_FileName.FileName))); MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&MTP_FileName; break; case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN : + /* Fill in the first 4 bytes with Param1 (Object ID) */ + (void)USBD_memcpy(mtp_pers_uniq_obj_id, &hmtp->OperationsContainer.Param1, + sizeof(hmtp->OperationsContainer.Param1)); + MTP_PropertiesList.MTP_Properties[i].PropertyCode = MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN; MTP_PropertiesList.MTP_Properties[i].Datatype = MTP_DATATYPE_UINT128; - MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)&hmtp->OperationsContainer.Param1; + MTP_PropertiesList.MTP_Properties[i].propval = (uint8_t *)mtp_pers_uniq_obj_id; break; case MTP_OB_PROP_PROTECTION_STATUS : @@ -1099,7 +1079,9 @@ static void MTP_Get_ObjectInfo(USBD_HandleTypeDef *pdev) /* we have to get this value before MTP_ObjectInfo.Filename */ MTP_ObjectInfo.Filename_len = hmtpif->GetObjectName_len(hmtp->OperationsContainer.Param1); hmtpif->GetObjectName(hmtp->OperationsContainer.Param1, MTP_ObjectInfo.Filename_len, filename); - (void)USBD_memcpy(MTP_ObjectInfo.Filename, filename, ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U); + (void)USBD_memcpy(MTP_ObjectInfo.Filename, filename, + MIN(((uint32_t)MTP_ObjectInfo.Filename_len * 2U) + 1U, + sizeof(MTP_ObjectInfo.Filename))); MTP_ObjectInfo.CaptureDate = 0U; MTP_ObjectInfo.ModificationDate = 0U; @@ -1128,42 +1110,55 @@ static void MTP_Get_StorageIDS(void) static uint32_t MTP_build_data_propdesc(USBD_HandleTypeDef *pdev, MTP_ObjectPropDescTypeDef def) { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - uint8_t DefValue_size = (MTP_FileName.FileName_len * 2U) + 1U; + uint32_t DefValue_size; uint32_t dataLength = offsetof(MTP_ObjectPropDescTypeDef, DefValue); + uint32_t totalLength; - (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&def, dataLength); - + /* Determine DefValue size based on data type */ switch (def.DataType) { case MTP_DATATYPE_UINT16: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint16_t)); - dataLength += sizeof(uint16_t); + DefValue_size = sizeof(uint16_t); break; case MTP_DATATYPE_UINT32: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint32_t)); - dataLength += sizeof(uint32_t); + DefValue_size = sizeof(uint32_t); break; case MTP_DATATYPE_UINT64: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, sizeof(uint64_t)); - dataLength += sizeof(uint64_t); + DefValue_size = sizeof(uint64_t); break; case MTP_DATATYPE_STR: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, DefValue_size); - dataLength += DefValue_size; + DefValue_size = ((uint32_t)MTP_FileName.FileName_len * 2U) + 1U; break; case MTP_DATATYPE_UINT128: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, (sizeof(uint64_t) * 2U)); - dataLength += (sizeof(uint64_t) * 2U); + DefValue_size = (sizeof(uint64_t) * 2U); break; default: + DefValue_size = 0U; break; } + /* Check if there is enough room in GenericContainer.data */ + totalLength = dataLength + DefValue_size + sizeof(MTP_ObjectPropDesc.GroupCode) + + sizeof(MTP_ObjectPropDesc.FormFlag); + + if (totalLength > MTP_MEDIA_PACKET) + { + return 0U; + } + + (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&def, dataLength); + + if ((DefValue_size > 0U) && (def.DefValue != NULL)) + { + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, def.DefValue, DefValue_size); + dataLength += DefValue_size; + } + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, (const uint8_t *)&MTP_ObjectPropDesc.GroupCode, sizeof(MTP_ObjectPropDesc.GroupCode)); @@ -1187,57 +1182,59 @@ static uint32_t MTP_build_data_proplist(USBD_HandleTypeDef *pdev, MTP_PropertiesListTypedef proplist, uint32_t idx) { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - uint8_t propval_size = (MTP_FileName.FileName_len * 2U) + 1U; + uint8_t *propval = proplist.MTP_Properties[idx].propval; uint32_t dataLength; + uint32_t payloadSize; dataLength = offsetof(MTP_PropertiesTypedef, propval); - (void)USBD_memcpy(hmtp->GenericContainer.data + hmtp->ResponseLength, - (const uint8_t *)&proplist.MTP_Properties[idx], dataLength); - - dataLength += hmtp->ResponseLength; - + /* Determine the payload size based on data type */ switch (proplist.MTP_Properties[idx].Datatype) { case MTP_DATATYPE_UINT16: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, - proplist.MTP_Properties[idx].propval, sizeof(uint16_t)); - - dataLength += sizeof(uint16_t); + payloadSize = sizeof(uint16_t); break; case MTP_DATATYPE_UINT32: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, - proplist.MTP_Properties[idx].propval, sizeof(uint32_t)); - - dataLength += sizeof(uint32_t); + payloadSize = sizeof(uint32_t); break; case MTP_DATATYPE_STR: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, - proplist.MTP_Properties[idx].propval, propval_size); - - dataLength += propval_size; + payloadSize = ((uint32_t)propval[0] * 2U) + 1U; break; case MTP_DATATYPE_UINT64: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, - proplist.MTP_Properties[idx].propval, sizeof(uint64_t)); - - dataLength += sizeof(uint64_t); + payloadSize = sizeof(uint64_t); break; case MTP_DATATYPE_UINT128: - (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, - proplist.MTP_Properties[idx].propval, (sizeof(uint64_t) * 2U)); - - dataLength += (sizeof(uint64_t) * 2U); + payloadSize = (sizeof(uint64_t) * 2U); break; default: + payloadSize = 0U; break; } + /* Check if there is enough room in GenericContainer.data for header + payload */ + if ((hmtp->ResponseLength + dataLength + payloadSize) > MTP_MEDIA_PACKET) + { + return hmtp->ResponseLength; + } + + (void)USBD_memcpy(hmtp->GenericContainer.data + hmtp->ResponseLength, + (const uint8_t *)&proplist.MTP_Properties[idx], dataLength); + + dataLength += hmtp->ResponseLength; + + if (payloadSize > 0U) + { + (void)USBD_memcpy(hmtp->GenericContainer.data + dataLength, + proplist.MTP_Properties[idx].propval, payloadSize); + + dataLength += payloadSize; + } + return dataLength; } @@ -1251,17 +1248,25 @@ static uint32_t MTP_build_data_ObjInfo(USBD_HandleTypeDef *pdev, MTP_ObjectInfoT { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t ObjInfo_len = offsetof(MTP_ObjectInfoTypeDef, Filename); + uint32_t fname_size; (void)USBD_memcpy(hmtp->GenericContainer.data, (const uint8_t *)&objinfo, ObjInfo_len); - (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, - (const uint8_t *)&objinfo.Filename, objinfo.Filename_len * sizeof(uint16_t)); - ObjInfo_len = ObjInfo_len + (objinfo.Filename_len * sizeof(uint16_t)); + fname_size = MIN((uint32_t)objinfo.Filename_len * sizeof(uint16_t), + (uint32_t)(MTP_MEDIA_PACKET - ObjInfo_len)); - (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, - (const uint8_t *)&objinfo.CaptureDate, sizeof(objinfo.CaptureDate)); + (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, + (const uint8_t *)&objinfo.Filename, fname_size); - ObjInfo_len = ObjInfo_len + sizeof(objinfo.CaptureDate); + ObjInfo_len = ObjInfo_len + fname_size; + + if ((ObjInfo_len + sizeof(objinfo.CaptureDate)) <= MTP_MEDIA_PACKET) + { + (void)USBD_memcpy(hmtp->GenericContainer.data + ObjInfo_len, + (const uint8_t *)&objinfo.CaptureDate, sizeof(objinfo.CaptureDate)); + + ObjInfo_len = ObjInfo_len + sizeof(objinfo.CaptureDate); + } return ObjInfo_len; } diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c index e09cd39226..b1f4bbf5e0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MTP/Src/usbd_mtp_storage.c @@ -95,26 +95,38 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) { USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t *data_buff; + uint32_t buffer_size; /* Get the data buffer pointer from the low layer interface */ data_buff = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuff; + /* Get Data Buffer Size */ + buffer_size = ((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ScratchBuffSze; + + if ((data_buff == NULL) || (buffer_size < MTP_CONT_HEADER_SIZE)) + { + return (uint8_t)USBD_FAIL; + } + switch (ReadDataStatus) { case READ_FIRST_DATA: /* Reset the data length */ MTP_DataLength.temp_length = 0U; - /* Perform the low layer read operation on the scratch buffer */ - (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1, - (uint8_t *)data_buff, &MTP_DataLength); - /* Add the container header to the data buffer */ (void)USBD_memcpy((uint8_t *)data_buff, (uint8_t *)&hmtp->GenericContainer, MTP_CONT_HEADER_SIZE); + /* Perform the low layer read operation on the scratch buffer + * first packet expected data length: MPS - MTP_CONT_HEADER_SIZE + */ + (void)((USBD_MTP_ItfTypeDef *)pdev->pUserData[pdev->classId])->ReadData(hmtp->OperationsContainer.Param1, + (uint8_t *)data_buff + + MTP_CONT_HEADER_SIZE, &MTP_DataLength); + /* Start USB data transmission to the host */ (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, - MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE); + MIN((MTP_DataLength.readbytes + MTP_CONT_HEADER_SIZE), buffer_size)); /* Check if this will be the last packet to send ? */ if (MTP_DataLength.readbytes < ((uint32_t)hmtp->MaxPcktLen - MTP_CONT_HEADER_SIZE)) @@ -138,24 +150,45 @@ uint8_t USBD_MTP_STORAGE_ReadData(USBD_HandleTypeDef *pdev) if (MTP_DataLength.temp_length == MTP_DataLength.totallen) { /* Start USB data transmission to the host */ - (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes); + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MIN(MTP_DataLength.readbytes, buffer_size)); - /* Move to response phase */ - hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + if (((MTP_DataLength.totallen + MTP_CONT_HEADER_SIZE) % hmtp->MaxPcktLen) == 0U) + { + /* Send ZLP Packet */ + ReadDataStatus = READ_SEND_ZLP_DATA; + } + else + { + /* Move to response phase */ + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; - /* Reset the stat machine */ - ReadDataStatus = READ_FIRST_DATA; + /* Reset the state machine */ + ReadDataStatus = READ_FIRST_DATA; + } } else { /* Start USB data transmission to the host */ - (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MTP_DataLength.readbytes); + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, MIN(MTP_DataLength.readbytes, buffer_size)); /* Keep the state machine into sending next packet of data */ ReadDataStatus = READ_REST_OF_DATA; } break; + case READ_SEND_ZLP_DATA: + + /* Send ZLP to the host */ + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)data_buff, 0U); + + /* Move to response phase */ + hmtp->MTP_ResponsePhase = MTP_RESPONSE_PHASE; + + /* Reset the state machine */ + ReadDataStatus = READ_FIRST_DATA; + + break; + default: break; } @@ -176,7 +209,8 @@ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_ { case DATA_TYPE: /* send header + data : hmtp->ResponseLength = header size + data size */ - (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength); + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, MIN(sizeof(MTP_GenericContainerTypeDef), + hmtp->ResponseLength)); break; case REP_TYPE: /* send header without data */ @@ -185,7 +219,8 @@ uint8_t USBD_MTP_STORAGE_SendContainer(USBD_HandleTypeDef *pdev, MTP_CONTAINER_ hmtp->GenericContainer.length = hmtp->ResponseLength; hmtp->GenericContainer.type = MTP_CONT_TYPE_RESPONSE; - (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, hmtp->ResponseLength); + (void)USBD_MTP_STORAGE_SendData(pdev, (uint8_t *)&hmtp->GenericContainer, MIN(sizeof(MTP_GenericContainerTypeDef), + hmtp->ResponseLength)); break; default: break; @@ -245,7 +280,7 @@ uint8_t USBD_MTP_STORAGE_ReceiveOpt(USBD_HandleTypeDef *pdev) */ uint8_t USBD_MTP_STORAGE_ReceiveData(USBD_HandleTypeDef *pdev) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; switch (hmtp->RECEIVE_DATA_STATUS) { case RECEIVE_COMMAND_DATA : @@ -410,15 +445,30 @@ static uint8_t USBD_MTP_STORAGE_DecodeOperations(USBD_HandleTypeDef *pdev) static uint8_t USBD_MTP_STORAGE_ReceiveContainer(USBD_HandleTypeDef *pdev, uint32_t *pDst, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; uint32_t Counter; uint32_t *pdst = pDst; - for (Counter = 0; Counter < len; Counter++) + if ((pDst == NULL) || (len > MTP_MEDIA_PACKET)) + { + return (uint8_t)USBD_FAIL; + } + + /* Convert byte count to uint32_t element count */ + len = len / sizeof(uint32_t); + + /* Clamp copy length to the size of OperationsContainer */ + if (len > (sizeof(MTP_OperationsTypeDef) / sizeof(uint32_t))) + { + len = (sizeof(MTP_OperationsTypeDef) / sizeof(uint32_t)); + } + + for (Counter = 0U; Counter < len; Counter++) { *pdst = (hmtp->rx_buff[Counter]); pdst++; } + return (uint8_t)USBD_OK; } @@ -456,17 +506,14 @@ void USBD_MTP_STORAGE_Cancel(USBD_HandleTypeDef *pdev, * @param len: Data Length * @retval status value */ -static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, - uint32_t len) +static uint8_t USBD_MTP_STORAGE_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len) { - USBD_MTP_HandleTypeDef *hmtp = (USBD_MTP_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; - uint32_t length = MIN(hmtp->GenericContainer.length, len); #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ MTPInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); #endif /* USE_USBD_COMPOSITE */ - (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, length); + (void)USBD_LL_Transmit(pdev, MTPInEpAdd, buf, len); return (uint8_t)USBD_OK; } diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c index 7c1a4ba830..a8f6d5f5aa 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c @@ -141,6 +141,9 @@ USBD_ClassTypeDef USBD_PRNT = USBD_PRNT_GetOtherSpeedCfgDesc, USBD_PRNT_GetDeviceQualifierDescriptor, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; #ifndef USE_USBD_COMPOSITE diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c index 947ae911e3..cd08a0ae2c 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c @@ -76,13 +76,10 @@ */ - - /** @defgroup USBD_TEMPLATE_Private_FunctionPrototypes * @{ */ - static uint8_t USBD_TEMPLATE_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_TEMPLATE_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c index 0e580ba59b..c4aef9ae29 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c @@ -140,6 +140,9 @@ USBD_ClassTypeDef USBD_VIDEO = USBD_VIDEO_GetOtherSpeedCfgDesc, USBD_VIDEO_GetDeviceQualifierDesc, #endif /* USE_USBD_COMPOSITE */ +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + NULL, +#endif /* USBD_SUPPORT_USER_STRING_DESC */ }; /* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */ @@ -315,7 +318,7 @@ __ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = UVC_IN_EP, /* bEndpointAddress */ 0x05, /* bmAttributes: ISO transfer */ LOBYTE(UVC_ISO_FS_MPS), /* wMaxPacketSize */ - LOBYTE(UVC_ISO_FS_MPS), + HIBYTE(UVC_ISO_FS_MPS), 0x01, /* bInterval: 1 frame interval */ }; @@ -688,8 +691,11 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) } else { - (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U), - Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U)); + if (RemainData > 2U) + { + (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U), + Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U)); + } RemainData = 0U; } @@ -723,7 +729,7 @@ static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev) { USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassDataCmsit[pdev->classId]; - uint8_t payload[2] = {0x02U, 0x00U}; + static uint8_t payload[2] = {0x02U, 0x00U}; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h index 8d61e7a0d6..73d4f3d7e5 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h @@ -79,10 +79,12 @@ extern "C" { #define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U #define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U +/* #define USBD_CUSTOMHID_REPORT_DESC_SIZE_ENABLED */ /* #define USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */ /* #define USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */ /* #define USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */ /* #define USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */ +/* #define USBD_CUSTOMHID_REPORT_BUFFER_EVENT_ENABLED */ /* VIDEO Class Config */ #define UVC_1_1 /* #define UVC_1_0 */ @@ -175,8 +177,6 @@ extern "C" { * @} */ - - /** * @} */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h index 4672921be1..8388e326a8 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -55,13 +55,11 @@ extern "C" { * @{ */ - /** * @} */ - /** @defgroup USBD_CORE_Exported_Macros * @{ */ @@ -171,5 +169,3 @@ USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); /** * @} */ - - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h index 6c45d6ce3d..efb78a728c 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h @@ -53,7 +53,6 @@ extern "C" { */ - /** @defgroup USBD_REQ_Exported_Macros * @{ */ @@ -97,5 +96,3 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); /** * @} */ - - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 2a295d78b4..7025f69367 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -305,12 +305,13 @@ typedef struct /* USB Device handle structure */ typedef struct { - uint32_t status; uint32_t total_length; uint32_t rem_length; - uint32_t maxpacket; - uint16_t is_used; - uint16_t bInterval; + uint32_t bInterval; + uint16_t maxpacket; + uint8_t status; + uint8_t is_used; + uint8_t *pbuffer; } USBD_EndpointTypeDef; #ifdef USE_USBD_COMPOSITE @@ -417,7 +418,6 @@ typedef enum */ - /** @defgroup USBD_DEF_Exported_Macros * @{ */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h index e3923055ad..7be13cebec 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_desc_template.h @@ -25,6 +25,10 @@ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ +/* + * User to provide a unique ID to define the USB device serial number + * The use of UID_BASE register can be considered as an example + */ #define DEVICE_ID1 (UID_BASE) #define DEVICE_ID2 (UID_BASE + 0x4U) #define DEVICE_ID3 (UID_BASE + 0x8U) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h index 15197b92ca..1a574b8e5d 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h @@ -40,6 +40,7 @@ extern "C" { /** @defgroup USBD_IOREQ_Exported_Defines * @{ */ + /** * @} */ @@ -49,13 +50,11 @@ extern "C" { * @{ */ - /** * @} */ - /** @defgroup USBD_IOREQ_Exported_Macros * @{ */ @@ -110,4 +109,3 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); /** * @} */ - diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index 0576c877cd..3b664a9b23 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -105,21 +105,22 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, #ifdef USE_USBD_COMPOSITE /* Parse the table of classes in use */ - for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) { /* Unlink previous class*/ pdev->pClass[i] = NULL; pdev->pUserData[i] = NULL; /* Set class as inactive */ - pdev->tclasslist[i].Active = 0; - pdev->NumClasses = 0; - pdev->classId = 0; + pdev->tclasslist[i].Active = 0U; + pdev->NumClasses = 0U; + pdev->classId = 0U; } #else /* Unlink previous class*/ pdev->pClass[0] = NULL; pdev->pUserData[0] = NULL; + pdev->NumClasses = 0U; #endif /* USE_USBD_COMPOSITE */ pdev->pConfDesc = NULL; @@ -296,7 +297,7 @@ USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_Cl */ USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev) { - USBD_StatusTypeDef ret = USBD_FAIL; + USBD_StatusTypeDef ret = USBD_OK; uint8_t idx1; uint8_t idx2; @@ -590,6 +591,8 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef ret = USBD_OK; uint8_t idx; + UNUSED(pdata); + if (epnum == 0U) { pep = &pdev->ep_out[0]; @@ -599,8 +602,9 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, if (pep->rem_length > pep->maxpacket) { pep->rem_length -= pep->maxpacket; + pep->pbuffer += pep->maxpacket; - (void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket)); + (void)USBD_CtlContinueRx(pdev, pep->pbuffer, MAX(pep->rem_length, pep->maxpacket)); } else { @@ -685,6 +689,8 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, USBD_StatusTypeDef ret; uint8_t idx; + UNUSED(pdata); + if (epnum == 0U) { pep = &pdev->ep_in[0]; @@ -694,8 +700,9 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, if (pep->rem_length > pep->maxpacket) { pep->rem_length -= pep->maxpacket; + pep->pbuffer += pep->maxpacket; - (void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length); + (void)USBD_CtlContinueSendData(pdev, pep->pbuffer, pep->rem_length); /* Prepare endpoint for premature end of transfer */ (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c index 814b810c5b..584a8cb9c2 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -361,6 +361,12 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef break; case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x7FU) > 0x0FU) + { + USBD_CtlError(pdev, req); + break; + } + if ((ep_addr & 0x80U) == 0x80U) { if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) @@ -378,8 +384,8 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef } } - pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ - &pdev->ep_out[ep_addr & 0x7FU]; + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0xFU] : \ + &pdev->ep_out[ep_addr & 0xFU]; if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) { @@ -1011,7 +1017,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) unicode[idx] = USB_DESC_TYPE_STRING; idx++; - while (*pdesc != (uint8_t)'\0') + while ((*pdesc != (uint8_t)'\0') && (idx < *len)) { unicode[idx] = *pdesc; pdesc++; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c index a9f995fa45..503eb13d7f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c @@ -65,7 +65,7 @@ USBD_DescriptorsTypeDef Class_Desc = USBD_Class_ConfigStrDescriptor, USBD_Class_InterfaceStrDescriptor, #if (USBD_CLASS_USER_STRING_DESC == 1) - USBD_CLASS_UserStrDescriptor, + USBD_Class_UserStrDescriptor, #endif /* USB_CLASS_USER_STRING_DESC */ #if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c index 7c8004ad80..2171398b19 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c @@ -89,6 +89,7 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_IN; pdev->ep_in[0].total_length = len; + pdev->ep_in[0].pbuffer = pbuf; #ifdef USBD_AVOID_PACKET_SPLIT_MPS pdev->ep_in[0].rem_length = 0U; @@ -133,6 +134,7 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_OUT; pdev->ep_out[0].total_length = len; + pdev->ep_out[0].pbuffer = pbuf; #ifdef USBD_AVOID_PACKET_SPLIT_MPS pdev->ep_out[0].rem_length = 0U; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md index 1af5233078..5f9caee9ff 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md +++ b/system/Middlewares/ST/STM32_USB_Device_Library/LICENSE.md @@ -1,80 +1,94 @@ -SLA0044 Rev5/February 2018 +This software component is provided to you as part of a software package and +applicable license terms are in the Package_license file. If you received this +software component outside of a package or without applicable license terms, +the terms of the SLA0044 license shall apply and are fully reproduced below: + +SLA0044 Rev6/October 2025 ## Software license agreement ### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__ -BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE -OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS -INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES -(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON -BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES -TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT. +BY CLICKING ON THE "I ACCEPT" BUTTON OR BY UNZIPPING, INSTALLING, COPYING, +DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE OR ANY PART THEREOF, +INCLUDING ANY RELATED DOCUMENTATION (collectively the “SOFTWARE”) +FROM STMICROELECTRONICS INTERNATIONAL N.V, SWISS BRANCH AND/OR +ITS AFFILIATED COMPANIES (collectively “STMICROELECTRONICS”), +YOU (hereinafter referred also to as “THE RECIPIENT”), ON BEHALF OF YOURSELF, +OR ON BEHALF OF ANY ENTITY BY WHICH YOU ARE EMPLOYED AND/OR ENGAGED, +AGREE TO BE BOUND BY THIS AGREEMENT. -Under STMicroelectronics’ intellectual property rights, the redistribution, -reproduction and use in source and binary forms of the software or any part +Under STMICROELECTRONICS’ intellectual property rights, the redistribution, +reproduction and use in source and binary forms of the SOFTWARE or any part thereof, with or without modification, are permitted provided that the following conditions are met: 1. Redistribution of source code (modified or not) must retain any copyright -notice, this list of conditions and the disclaimer set forth below as items 10 -and 11. - -2. Redistributions in binary form, except as embedded into microcontroller or -microprocessor device manufactured by or for STMicroelectronics or a software -update for such device, must reproduce any copyright notice provided with the -binary code, this list of conditions, and the disclaimer set forth below as -items 10 and 11, in documentation and/or other materials provided with the -distribution. - -3. Neither the name of STMicroelectronics nor the names of other contributors to -this software may be used to endorse or promote products derived from this -software or part thereof without specific written permission. - -4. This software or any part thereof, including modifications and/or derivative -works of this software, must be used and execute solely and exclusively on or in -combination with a microcontroller or microprocessor device manufactured by or -for STMicroelectronics. - -5. No use, reproduction or redistribution of this software partially or totally -may be done in any manner that would subject this software to any Open Source -Terms. “Open Source Terms” shall mean any open source license which requires as -part of distribution of software that the source code of such software is -distributed therewith or otherwise made available, or open source license that -substantially complies with the Open Source definition specified at -www.opensource.org and any other comparable open source license such as for -example GNU General Public License (GPL), Eclipse Public License (EPL), Apache -Software License, BSD license or MIT license. - -6. STMicroelectronics has no obligation to provide any maintenance, support or -updates for the software. - -7. The software is and will remain the exclusive property of STMicroelectronics -and its licensors. The recipient will not take any action that jeopardizes -STMicroelectronics and its licensors' proprietary rights or acquire any rights -in the software, except the limited rights specified hereunder. - -8. The recipient shall comply with all applicable laws and regulations affecting -the use of the software or any part thereof including any applicable export -control law or regulation. - -9. Redistribution and use of this software or any part thereof other than as -permitted under this license is void and will automatically terminate your -rights under this license. - -10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE -DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL -STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER -EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY -RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY. +notice accompanying the SOFTWARE, this list of conditions and the disclaimer below. + +2. Redistributions in binary form, except as embedded into a processing unit device +manufactured by or for STMicroelectronics or a software update for any such device, +must reproduce the accompanying copyright notice, this list of conditions, +and the below disclaimer in capital type, in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of STMicroelectronics nor the names of other contributors +to the SOFTWARE may be used to endorse or promote products derived +from the SOFTWARE or part thereof without specific written permission. + +4. The SOFTWARE or any part thereof, including modifications and/or +derivative works of the SOFTWARE, must be used and execute solely +and exclusively on or in combination with a processing unit device +manufactured by or for STMicroelectronics. + +5. No use, reproduction or redistribution of the SOFTWARE partially +or totally may be done in any manner that would subject the SOFTWARE +to any Open Source Terms. “Open Source Terms” shall mean +any open source license which requires as part of distribution +of software that the source code of such software is distributed +therewith or otherwise made available, or open source license +that substantially complies with the Open Source definition specified +at www.opensource.org and any other comparable open source license +such as for example GNU General Public License (GPL), +Eclipse Public License (EPL), Apache Software License, BSD license +or MIT license. + +6. STMicroelectronics has no obligation to provide any maintenance, +support or updates for the SOFTWARE. + +7. The SOFTWARE is and will remain the exclusive property of +STMicroelectronics and its licensors. The RECIPIENT will not take +any action that jeopardizes STMicroelectronics and its +licensors' proprietary rights or acquire any rights in the SOFTWARE, +except the limited rights specified hereunder. + +8. The RECIPIENT shall comply with all applicable laws and regulations +affecting the use of the SOFTWARE or any part thereof including +any applicable export control law or regulation. + +9. Redistribution and use of the SOFTWARE or any part thereof other +than as permitted under this AGREEMENT is void and will automatically +terminate RECIPIENT’s rights under this AGREEMENT. + +10. The RECIPIENT shall be solely liable to determine and verify that +the SOFTWARE is fit for the RECIPIENT intended use, environment or +application and comply with all regulatory, safety and security +related requirements concerning any use. + +DISCLAIMER: + +THE SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING,BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE +AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, ARE +DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. +IN NO EVENT SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, +WHETHER EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL +PROPERTY RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY. diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html index 94390d06ab..622f1ece3a 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html @@ -6,19 +6,23 @@ Release Notes for STM32Cube USB Device Library - - - +code{white-space: pre-wrap;} +span.smallcaps{font-variant: small-caps;} +div.columns{display: flex; gap: min(4vw, 1.5em);} +div.column{flex: auto; overflow-x: auto;} +div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} + +ul.task-list[class]{list-style: none;} +ul.task-list li input[type="checkbox"] { +font-size: inherit; +width: 0.8em; +margin: 0 0.8em 0.2em -1.6em; +vertical-align: middle; +} +.display.math{display: block; text-align: center; margin: 0.5rem auto;} + + +
@@ -28,12 +32,11 @@

Release Notes for STM32Cube USB Device Library

Copyright © 2015 STMicroelectronics

- +

Purpose

The USB device library comes on top of the STM32Cube™ USB device HAL -driver and offers all the APIs required to develop an USB device +driver and offers all the APIs required to develop a USB device application.

The main USB device library features are:

    @@ -49,8 +52,7 @@

    Purpose

Here is the list of references to user documents:

    -
  • UM1734 +
  • UM1734 : STM32Cube USB device library User Manual
  • Wiki Page : STM32Cube USB Wiki Page
  • @@ -59,29 +61,160 @@

    Purpose

    Update History

    - -
    +
    + + +
    +

    +Main Changes +

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Headline
    USB Core:
    SLA0044 Legal terms updated to latest revision (Rev 6 / October +2025)
    USB Classes:
    Add missing NULL pointer for user string descriptor
    USB MTP Class:
    Minor enhancement; remove useless data copy and add support of +ZLP
    +
    +
    +
    + + +
    +

    +Main Changes +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Headline
    USB Core:
    Fix return value of USBD_UnRegisterClassComposite function
    Increment EP0 data buffer inside HAL data callbacks
    USB MSC Class:
    Adding multi LUN support
    USB CustomHID Class:
    Adding support of different CustomHID report descriptor sizes
    Fix composite builder CustomHID EP size
    USB MTP Class:
    Minor enhancement; improve device data buffer management
    +
    +
    +
    + +
    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    USB Core:
    USB Core:
    Minor enhancement; add a check on device string descriptor length
    Minor enhancement; add a check on device string descriptor +length
    USB DFU Class:
    USB DFU Class:
    Improve DFU Vendor Commands support
    Improve DFU Vendor Commands support
    @@ -90,45 +223,47 @@

    Main Changes

    +27-September-2022
    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    USB Core:
    USB Core:
    Adding user callback to get device configuration state
    Adding user callback to get device configuration state
    USB DFU Class:
    USB DFU Class:
    Adding DFU Vendor Commands support
    Adding DFU Vendor Commands support
    USB MSC Class:
    USB MSC Class:
    fix data sense response to be aligned with SBC-3 specification
    Fix data sense response to be aligned with SBC-3 specification
    USB AUDIO Class:
    USB AUDIO Class:
    restart AUDIO ISO endpoint during ISO incomplete event
    Restart AUDIO ISO endpoint during ISO incomplete event
    USB VIDEO Class:
    USB VIDEO Class:
    restart VIDEO ISO endpoint during ISO incomplete event
    Restart VIDEO ISO endpoint during ISO incomplete event
    @@ -139,45 +274,45 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - - + + - - + +
    Headline
    Headline
    Improvement of the memory management -
    Improvement of the memory management
    USB Core:
    USB Core:
    Fix some compilation warnings related -to unused parameters
    Fix some compilation warnings related to unused parameters
    Improve some code parts style
    Improve some code parts style
    Add check on the USB Device status in -USBD_LL_Suspend before suspending it
    Add check on the USB Device status in USBD_LL_Suspend before +suspending it
    USB CDC-ACM Class:
    USB CDC-ACM Class:
    Remove redundant prototype declaration of +
    Remove redundant prototype declaration of USBD_CDC_GetOtherSpeedCfgDesc()
    USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS, -CustomHID, MSC & Video Classes:
    USB CompositeBuilder, CCID, CDC_ECM, CDC_RNDIS, CustomHID, +MSC & Video Classes:
    Improve some code parts style
    Improve some code parts style
    @@ -188,70 +323,69 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    USB VIDEO Class:
    USB VIDEO Class:
    Correction of the support of -VS_PROBE_CONTROL & VS_COMMIT_CONTROL requests
    Correction of the support of VS_PROBE_CONTROL & +VS_COMMIT_CONTROL requests
    USB AUDIO Class:
    USB AUDIO Class:
    Correction of the check on -AUDIO_TOTAL_BUF_SIZE to avoid vulnerabilities
    Correction of the check on AUDIO_TOTAL_BUF_SIZE to avoid +vulnerabilities
    USB HID Class:
    USB HID Class:
    Modification of some constants names to -avoid duplication versus USB host library
    Modification of some constants names to avoid duplication versus USB +host library
    USB CustomHID Class:
    USB CustomHID Class:
    Add support of Get Report control -request
    Add support of Get Report control request
    Allow disabling EP OUT prepare receive -using a dedicated macros that can be defined in usbd_conf.h application -file
    Allow disabling EP OUT prepare receive using a dedicated macro that +can be defined in usbd_conf.h application file
    Add support of Report Descriptor with -length greater than 255 bytes
    Add support of Report Descriptor with length greater than 255 +bytes
    USB CCID Class:
    USB CCID Class:
    Fix minor Code Spelling warning
    Fix minor Code Spelling warning
    USB All Classes:
    USB All Classes:
    Update all classes to support composite -multi-instance using the class id parameter
    Update all classes to support composite multi-instance using the +class id parameter
    Fix code spelling and improve code -style
    Fix code spelling and improve code style
    fix misraC 2012 rule 10.3
    Fix misraC 2012 rule 10.3
    @@ -262,37 +396,35 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Integration of new USB device -Class driver:
    Integration of new USB device Class driver:
    Adding support of Composite devices with -an auto generation of composite device configuration descriptors
    Adding support of Composite devices with an auto generation of +composite device configuration descriptors
    USB All Classes:
    USB All Classes:
    Fix Code Spelling and improve Code -Style
    Fix Code Spelling and improve Code Style
    Update device class drivers to support -Composite devices
    Update device class drivers to support Composite devices
    Improve declaration of USB configuration -descriptor table which is allocated if the composite builder is not -selected
    Improve declaration of USB configuration descriptor table which is +allocated if the composite builder is not selected
    @@ -303,44 +435,43 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Integration of new USB device -Class driver:
    Integration of new USB device Class driver:
    USB CCID Class driver based on Universal -Serial Bus Device Class Definition for Integrated Circuit(s) Cards -Interface Devices Revision 1.1
    USB CCID Class driver based on Universal Serial Bus Device Class +Definition for Integrated Circuit(s) Cards Interface Devices Revision +1.1
    USB MTP Class driver based on Universal -Serial Bus Device Class Media Transfer Protocol Revision 1.1
    USB MTP Class driver based on Universal Serial Bus Device Class +Media Transfer Protocol Revision 1.1
    USB All Classes:
    USB All Classes:
    Fix Code Spelling and improve Code -Style
    Fix Code Spelling and improve Code Style
    Update the way to declare licenses
    Update the way to declare Legal terms
    USB CDC/RNDIS/ECM -Classes:
    USB CDC/RNDIS/ECM Classes:
    Fix compilation warning with C++ due to -missing casting during class handler allocation
    Fix compilation warning with C++ due to missing casting during class +handler allocation
    @@ -349,50 +480,47 @@

    Main Changes

    +10-March-2021
    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Integration of new USB device -Class driver:
    Integration of new USB device Class driver:
    USB Printer Class driver based on -Universal Serial Bus Device Class Definition for Printing Devices -Version 1.1
    USB Printer Class driver based on Universal Serial Bus Device Class +Definition for Printing Devices Version 1.1
    USB All Classes:
    USB All Classes:
    Fix USB buffer overflow vulnerability for -CDC, CDC-ECM, CDC-RNDIS, DFU, AUDIO, CustomHID, and Video Classes
    Fix USB buffer overflow vulnerability for CDC, CDC-ECM, CDC-RNDIS, +DFU, AUDIO, CustomHID, and Video Classes
    Fix compilation warning with C++ due to -missing casting during class handler allocation
    Fix compilation warning with C++ due to missing casting during class +handler allocation
    Enhance comments of USB configuration -descriptors fields
    Enhance comments of USB configuration descriptors fields
    USB Video Class:
    USB Video Class:
    Fix missing closing bracket for extern “C” -in usbd_video.h
    Fix missing closing bracket for extern “C” in usbd_video.h
    Fix USBCV test with Uncompressed video -format support
    Fix USBCV test with Uncompressed video format support
    @@ -403,17 +531,18 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + +
    Headline
    Headline
    USB All Class: Add NULL pointer access -check to Class handler
    USB All Class: Add NULL pointer access check to Class handler
    @@ -424,83 +553,77 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Integration of new USB device -Class driver:
    Integration of new USB device Class driver:
    USB video Class driver based on USB-IF -video class definition version 1.1
    USB video Class driver based on USB-IF video class definition +version 1.1
    USB Core:
    USB Core:
    Enhance NULL pointer check in Core -APIs
    Enhance NULL pointer check in Core APIs
    Allow supporting both USER and USER Class -string desc
    Allow supporting both USER and USER Class string desc
    Add support of USB controller which -handles packet-size splitting by hardware
    Add support of USB controller which handles packet-size splitting by +hardware
    Avoid compilation warning due macro -redefinition
    Avoid compilation warning due to macro redefinition
    change added to USBD_HandleTypeDef -structure: dev_state, old_dev_state and ep0_state declaration become -volatile to disable compiler optimization
    Change added to USBD_HandleTypeDef structure: dev_state, +old_dev_state and ep0_state declaration become volatile to disable +compiler optimization
    Word spelling correction and file -indentation improved
    Word spelling correction and file indentation improved
    usbd_conf.h/c Template file updated to -suggest using by default a static memory allocation for Class -handler
    usbd_conf.h/c Template file updated to suggest using by default a +static memory allocation for Class handler
    USB All Classes:
    USB All Classes:
    Word spelling correction and file -indentation improved
    Word spelling correction and file indentation improved
    Allow updating device config descriptor -Max power from user code usbd_conf.h using USBD_MAX_POWER define
    Allow updating device config descriptor Max power from user code +usbd_conf.h using USBD_MAX_POWER define
    Fix device config descriptor bmAttributes -value which depends on user code define USBD_SELF_POWERED
    Fix device config descriptor bmAttributes value which depends on +user code define USBD_SELF_POWERED
    USB CDC Class:
    USB CDC Class:
    Class specific request, add protection to -limit the maximum data length to be sent by the CDC device
    Class specific request, add protection to limit the maximum data +length to be sent by the CDC device
    USB CustomHID Class:
    USB CustomHID Class:
    Allow changing CustomHID data EP size from -user code
    Allow changing CustomHID data EP size from user code
    @@ -511,38 +634,39 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Fix minor misra-c 2012 violations
    Fix minor misra-c 2012 violations
    USB Core:
    USB Core:
    minor rework on USBD_Init() -USBD_DeInit()
    Minor rework on USBD_Init() USBD_DeInit()
    Fix warning issue with Keil due to missing -return value of setup API
    Fix warning issue with Keil due to missing return value of setup +API
    USB CDC Class:
    USB CDC Class:
    Fix file indentation
    Fix file indentation
    Avoid accessing to NULL pointer in case -TransmitCplt() user fops is not defined to allow application -compatibility with device library version below v2.6.0
    Avoid accessing NULL pointer in case TransmitCplt() user fops is not +defined to allow application compatibility with device library version +below v2.6.0
    @@ -553,81 +677,78 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Integration of three new USB device Class -drivers:CDC ECM , CDC RNDIS Microsoft, USB Billboard
    Integration of three new USB device Class drivers: CDC ECM, CDC +RNDIS Microsoft, USB Billboard
    Fix mandatory misra-c 2012 violations
    Fix mandatory misra-c 2012 violations
    update user core and class template -files
    Update user core and class template files
    USB Core:
    USB Core:
    Fix unexpected EP0 stall during -enumeration phase
    Fix unexpected EP0 stall during enumeration phase
    Improve APIs error management and prevent -accessing NULL pointers
    Improve APIs error management and prevent accessing NULL +pointers
    USB MSC Class:
    USB MSC Class:
    Fix USBCV specific class tests
    Fix USBCV specific class tests
    Fix multiple error with SCSI commands -handling
    Fix multiple errors with SCSI commands handling
    Protect medium access when host ask for -medium ejection
    Protect medium access when host asks for medium ejection
    USB CDC Class:
    USB CDC Class:
    Add new function to inform user that -current IN transfer is completed
    Add new function to inform user that current IN transfer is +completed
    update transmit and receive APIs to -transfer up to 64KB
    Update transmit and receive APIs to transfer up to 64KB
    USB AUDIO Class:
    USB AUDIO Class:
    Fix audio sync start buffer size
    Fix audio sync start buffer size
    update user callback periodicTC args by -adding pointer to user buffer and size
    Update user callback periodicTC args by adding pointer to user +buffer and size
    USB CustomHID Class:
    USB CustomHID Class:
    Rework the OUT transfer complete and -prevent automatically re-enabling the OUT EP
    Rework the OUT transfer complete and prevent automatically +re-enabling the OUT EP
    Add new user API to restart the OUT -transfer: USBD_CUSTOM_HID_ReceivePacket()
    Add new user API to restart the OUT transfer: +USBD_CUSTOM_HID_ReceivePacket()
    @@ -638,37 +759,37 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Fix misra-c 2012 high severity -violations
    Fix misra-c 2012 high severity violations
    Core driver:
    Core driver:
    protect shared macros __ALIGN_BEGIN, -__ALIGN_END with C directive #ifndef
    Protect shared macros __ALIGN_BEGIN, __ALIGN_END with C directive +#ifndef
    update Core driver and DFU Class driver to -use USBD_SUPPORT_USER_STRING_DESC instead of -USBD_SUPPORT_USER_STRING
    Update Core driver and DFU Class driver to use +USBD_SUPPORT_USER_STRING_DESC instead of USBD_SUPPORT_USER_STRING
    prevent accessing to NULL pointer if the -get descriptor functions are not defined
    Prevent accessing NULL pointer if the get descriptor functions are +not defined
    Update on USBD_LL_Resume(), restore the -device state only if the current state is USBD_STATE_SUSPENDED
    Update on USBD_LL_Resume(), restore the device state only if the +current state is USBD_STATE_SUSPENDED
    @@ -677,20 +798,22 @@

    Main Changes

    +27-March-2019
    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + +
    Headline
    Headline
    DFU Class: fix compilation warning due to -unreachable instruction code introduced with CMSIS V5.4.0 -NVIC_SystemReset() prototype change
    DFU Class: fix compilation warning due to unreachable instruction +code introduced with CMSIS V5.4.0 NVIC_SystemReset() prototype +change
    @@ -701,33 +824,33 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Update license section by adding path to -get copy of ST Ultimate Liberty license
    Update Legal terms section by adding path to get copy of ST Ultimate +Liberty Legal terms
    Core: Fix unexpected stall during status -OUT phase
    Core: Fix unexpected stall during status OUT phase
    DFU Class: rework hdfu struct to prevent -unaligned addresses
    DFU Class: rework hdfu struct to prevent unaligned addresses
    MSC Class: fix lba address overflow during -large file transfers greater than 4Go
    MSC Class: fix lba address overflow during large file transfers +greater than 4 GB
    Template Class: add missing Switch case -Break on USBD_Template_Setup API
    Template Class: add missing Switch case Break on USBD_Template_Setup +API
    @@ -738,48 +861,44 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Update license section
    Update Legal terms section
    Update some functions to be MISRAC 2004 -compliant
    Update some functions to be MISRAC 2004 compliant
    Add HS and OtherSpeed configuration -descriptor for HID and CustomHID classes
    Add HS and OtherSpeed configuration descriptor for HID and CustomHID +classes
    Correct error handling in all class setup -function
    Correct error handling in all class setup function
    Add usbd_desc_template.c/ -usbd_desc_template.h templates files
    Add usbd_desc_template.c/ usbd_desc_template.h templates files
    Add support of class and vendor -request
    Add support of class and vendor request
    CDC Class: fix zero-length packet issue in -bulk IN transfer
    CDC Class: fix zero-length packet issue in bulk IN transfer
    Fix compilation warning with unused -arguments for some functions
    Fix compilation warning with unused arguments for some +functions
    Improve USB Core enumeration state -machine
    Improve USB Core enumeration state machine
    @@ -790,20 +909,22 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + +
    Headline
    Headline
    CDC Class
    CDC Class
    usbd_cdc.c: change #include “USBD_CDC.h” -by #include “usbd_cdc.h”
    usbd_cdc.c: change #include “USBD_CDC.h” by #include +“usbd_cdc.h”
    @@ -814,37 +935,37 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    CDC Class
    CDC Class
    usbd_cdc.c: comments update
    usbd_cdc.c: comments update
    MSC Class
    MSC Class
    usbd_msc_bot.h: update to be C++ -compliant
    usbd_msc_bot.h: update to be C++ compliant
    AUDIO Class
    AUDIO Class
    usbd_audio.c: fix issue when Host sends -GetInterface command it gets a wrong value
    usbd_audio.c: fix issue when Host sends GetInterface command it gets +a wrong value
    usbd_audio.c: remove useless management of -DMA half transfer
    usbd_audio.c: remove useless management of DMA half transfer
    @@ -855,56 +976,55 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Core Driver
    Core Driver
    Add support of Link Power Management -(LPM): add new API GetBOSDescriptor(), that is used only if -USBD_LPM_ENABLED switch is enabled in usbd_conf.h file
    Add support of Link Power Management (LPM): add new API +GetBOSDescriptor(), that is used only if USBD_LPM_ENABLED switch is +enabled in usbd_conf.h file
    usbd_core.c: Fix bug of unsupported -premature Host Out stage during data In stage (ie. when endpoint 0 -maximum data size is 8 and Host requests GetDeviceDescriptor for the -first time)
    usbd_core.c: Fix bug of unsupported premature Host Out stage during +data In stage (ie. when endpoint 0 maximum data size is 8 and Host +requests GetDeviceDescriptor for the first time)
    usbd_ctlreq.c: Fix bug of unsupported -Endpoint Class requests (ie. Audio SetCurrent request for endpoint -sampling rate setting)
    usbd_ctlreq.c: Fix bug of unsupported Endpoint Class requests (ie. +Audio SetCurrent request for endpoint sampling rate setting)
    HID Class
    HID Class
    Updating Polling time API -USBD_HID_GetPollingInterval() to query this period for HS and FS
    Updating Polling time API USBD_HID_GetPollingInterval() to query +this period for HS and FS
    usbd_hid.c: Fix USBD_LL_CloseEP() function -call in USBD_HID_DeInit() replacing endpoint size by endpoint -address.
    usbd_hid.c: Fix USBD_LL_CloseEP() function call in USBD_HID_DeInit() +replacing endpoint size by endpoint address.
    CDC Class
    CDC Class
    usbd_cdc.c: Add missing GetInterface -request management in USBD_CDC_Setup() function
    usbd_cdc.c: Add missing GetInterface request management in +USBD_CDC_Setup() function
    usbd_cdc.c: Update USBD_CDC_Setup() -function to allow correct user implementation of -CDC_SET_CONTROL_LINE_STATE and similar no-data setup requests.
    usbd_cdc.c: Update USBD_CDC_Setup() function to allow correct user +implementation of CDC_SET_CONTROL_LINE_STATE and similar no-data setup +requests.
    @@ -915,32 +1035,32 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Update all drivers to be C++ -compliant
    Update all drivers to be C++ compliant
    CDC Class
    CDC Class
    usbd_cdc.c: fix clear flag issue in -USBD_CDC_TransmitPacket() function
    usbd_cdc.c: fix clear flag issue in USBD_CDC_TransmitPacket() +function
    usbd_cdc_if_template.c: update -TEMPLATE_Receive() function header comment
    usbd_cdc_if_template.c: update TEMPLATE_Receive() function header +comment
    Miscellaneous source code comments -update
    Miscellaneous source code comments update
    @@ -951,52 +1071,50 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + @@ -1008,45 +1126,44 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    Headline
    Headline
    Source code comments review and -update
    Source code comments review and update
    HID class
    HID class
    Remove unused API -USBD_HID_DeviceQualifierDescriptor()
    Remove unused API USBD_HID_DeviceQualifierDescriptor()
    Add a new API in the HID class to query -the poll time USBD_HID_GetPollingInterval()
    Add a new API in the HID class to query the poll time +USBD_HID_GetPollingInterval()
    CDC class
    CDC class
    Bug fix: missing handling ZeroLength Setup -request
    Bug fix: missing handling ZeroLength Setup request
    All classes
    All classes
    Add alias for the class definition, it’s -defined as macro with capital letter
    Add alias for the class definition, it’s defined as macro with +capital letter
    ex. for the HID, the USBD_HID_CLASS macro -is defined this way #define USBD_HID_CLASS &USBD_HID
    ex. for the HID, the USBD_HID_CLASS macro is defined this way +#define USBD_HID_CLASS &USBD_HID
    and the application code can use the -previous definition: &USBD_HID ex. -USBD_RegisterClass(&USBD_Device, &USBD_HID) or the new -USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, +
    and the application code can use the previous definition: +&USBD_HID ex. USBD_RegisterClass(&USBD_Device, &USBD_HID) or +the new USBD_HID_CLASS ex. USBD_RegisterClass(&USBD_Device, USBD_HID_CLASS)
    - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + - - + +
    Headline
    Headline
    usbd_conf_template.c: update file with the -right content (it was using MSC memory management layer)
    usbd_conf_template.c: update file with the right content (it was +using MSC memory management layer)
    usbd_conf_template.h: change include of -stm32f4xx.h by stm32xxx.h and add comment to inform user to adapt it to -the device used
    usbd_conf_template.h: change include of stm32f4xx.h by stm32xxx.h +and add comment to inform user to adapt it to the device used
    Several enhancements in CustomHID -class
    Several enhancements in CustomHID class
    Update the Custom HID class driver to -simplify the link with user processes
    Update the Custom HID class driver to simplify the link with user +processes
    Optimize the Custom HID class driver and -reduce footprint
    Optimize the Custom HID class driver and reduce footprint
    Add USBD_CUSTOM_HID_RegisterInterface() -API to link user process to custom HID class
    Add USBD_CUSTOM_HID_RegisterInterface() API to link user process to +custom HID class
    Add Custom HID interface template file +
    Add Custom HID interface template file usbd_customhid_if_template.c/h
    Miscellaneous comments update
    Miscellaneous comments update
    @@ -1057,24 +1174,27 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    Major update based on STM32Cube specification.

    - - + + - - + +
    Headline
    Headline
    Library Core, Classes architecture and -APIs modified vs. V1.1.0, and thus the 2 versions are not -compatible.
    Library Core, Classes architecture and APIs modified vs. V1.1.0, and +thus the 2 versions are not compatible.
    -

    This version has to be used only with STM32Cube based -development

    +
      +
    • This version has to be used only with STM32Cube based +development
    • +
    @@ -1082,35 +1202,35 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    - - + + - - + + - - + + - - + + - - + + - - + + - - + +
    Headline
    Headline
    Official support of STM32F4xx devices
    Official support of STM32F4xx devices
    All source files: license disclaimer text -update and add link to the License file on ST Internet.
    All source files: Legal terms disclaimer text update and add link to +the Legal terms file on ST Internet.
    Handle test mode in the set feature -request
    Handle test mode in the set feature request
    Handle dynamically the USB SELF POWERED -feature
    Handle dynamically the USB SELF POWERED feature
    Handle correctly the USBD_CtlError process -to take into account error during Control OUT stage
    Handle correctly the USBD_CtlError process to take into account +error during Control OUT stage
    Miscellaneous bug fix
    Miscellaneous bug fix
    @@ -1121,11 +1241,13 @@

    Main Changes

    -

    Main Changes

    +

    +Main Changes +

    First official version for STM32F105/7xx and STM32F2xx devices

    -
+