diff --git a/Class/CCID/Inc/usbd_ccid.h b/Class/CCID/Inc/usbd_ccid.h index d3b96a5..e8d12be 100644 --- a/Class/CCID/Inc/usbd_ccid.h +++ b/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/Class/CCID/Src/usbd_ccid_cmd.c b/Class/CCID/Src/usbd_ccid_cmd.c index b91cb1f..c65ac5a 100644 --- a/Class/CCID/Src/usbd_ccid_cmd.c +++ b/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/Class/CDC/Inc/usbd_cdc.h b/Class/CDC/Inc/usbd_cdc.h index aeac6bf..42ff56c 100644 --- a/Class/CDC/Inc/usbd_cdc.h +++ b/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/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/Class/CDC_ECM/Inc/usbd_cdc_ecm.h index a69c4fd..1284d4d 100644 --- a/Class/CDC_ECM/Inc/usbd_cdc_ecm.h +++ b/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/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h index 50d18c4..3a262c3 100644 --- a/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h +++ b/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/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c index f04f2c2..21bb18e 100644 --- a/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c +++ b/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -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; diff --git a/Class/CompositeBuilder/Src/usbd_composite_builder.c b/Class/CompositeBuilder/Src/usbd_composite_builder.c index e14c5cd..dc4bae9 100644 --- a/Class/CompositeBuilder/Src/usbd_composite_builder.c +++ b/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/Class/CustomHID/Inc/usbd_customhid.h b/Class/CustomHID/Inc/usbd_customhid.h index 2f4c634..f81a708 100644 --- a/Class/CustomHID/Inc/usbd_customhid.h +++ b/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/Class/CustomHID/Src/usbd_customhid.c b/Class/CustomHID/Src/usbd_customhid.c index c64ba99..83de04d 100644 --- a/Class/CustomHID/Src/usbd_customhid.c +++ b/Class/CustomHID/Src/usbd_customhid.c @@ -284,6 +284,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 +402,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 @@ -701,8 +714,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 +773,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/Class/CustomHID/Src/usbd_customhid_if_template.c b/Class/CustomHID/Src/usbd_customhid_if_template.c index 85881bd..e5a7e73 100644 --- a/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/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/Class/MSC/Inc/usbd_msc.h b/Class/MSC/Inc/usbd_msc.h index e55fef4..c9c26cb 100644 --- a/Class/MSC/Inc/usbd_msc.h +++ b/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]; } USBD_MSC_BOT_HandleTypeDef; /* Structure for MSC process */ diff --git a/Class/MSC/Inc/usbd_msc_data.h b/Class/MSC/Inc/usbd_msc_data.h index c96d2b8..a321c91 100644 --- a/Class/MSC/Inc/usbd_msc_data.h +++ b/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/Class/MSC/Inc/usbd_msc_scsi.h b/Class/MSC/Inc/usbd_msc_scsi.h index 477affb..6000c2b 100644 --- a/Class/MSC/Inc/usbd_msc_scsi.h +++ b/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/Class/MSC/Src/usbd_msc.c b/Class/MSC/Src/usbd_msc.c index 7f2152f..d02af8b 100644 --- a/Class/MSC/Src/usbd_msc.c +++ b/Class/MSC/Src/usbd_msc.c @@ -309,6 +309,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 +333,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/Class/MSC/Src/usbd_msc_bot.c b/Class/MSC/Src/usbd_msc_bot.c index c51b013..e1cb63c 100644 --- a/Class/MSC/Src/usbd_msc_bot.c +++ b/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); diff --git a/Class/MSC/Src/usbd_msc_data.c b/Class/MSC/Src/usbd_msc_data.c index 1641c20..333a87a 100644 --- a/Class/MSC/Src/usbd_msc_data.c +++ b/Class/MSC/Src/usbd_msc_data.c @@ -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/Class/MSC/Src/usbd_msc_scsi.c b/Class/MSC/Src/usbd_msc_scsi.c index 3c0fe2f..25f9423 100644 --- a/Class/MSC/Src/usbd_msc_scsi.c +++ b/Class/MSC/Src/usbd_msc_scsi.c @@ -92,6 +92,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); @@ -190,9 +192,16 @@ 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; ret = -1; break; } @@ -283,7 +292,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 +328,15 @@ 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 = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, - &hmsc->scsi_blk_size); + 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 +344,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; - } @@ -364,14 +373,15 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t uint32_t idx; int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { return -1; } - ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &hmsc->scsi_blk_nbr, - &hmsc->scsi_blk_size); + 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)) { @@ -389,15 +399,15 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t 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)(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); + 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_length = ((uint32_t)params[10] << 24) | ((uint32_t)params[11] << 16) | @@ -480,7 +490,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_Sense10_data[2] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */ } if (params[4] <= len) @@ -515,7 +529,11 @@ 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) @@ -635,7 +653,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,6 +722,7 @@ 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 = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { @@ -732,21 +751,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,6 +788,7 @@ 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 = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { @@ -797,24 +816,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 +856,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 = &hmsc->scsi_blk[lun]; uint32_t len; if (hmsc == NULL) @@ -879,22 +898,21 @@ static int8_t SCSI_Write10(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[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,6 +946,7 @@ 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 = &hmsc->scsi_blk[lun]; uint32_t len; if (hmsc == NULL) @@ -970,24 +989,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,6 +1039,7 @@ 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]; + USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { @@ -1029,11 +1048,11 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para 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); return -1; /* Error, Verify Mode Not supported*/ } - 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 */ } @@ -1043,6 +1062,90 @@ 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 lun_list_length; + uint32_t total_length; + uint8_t lun_idx; + + UNUSED(lun); + UNUSED(params); + + /* Define the report LUNs buffer Each LUN entry is 8 bytes */ + static uint8_t lun_report[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 */ + (void)USBD_memset(lun_report, 0, sizeof(lun_report)); + + /* 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; + + /* 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; + + /* Extract the allocation length from the CDB */ + allocation_length = (((uint16_t)params[3] << 8) | (uint16_t)params[4]); + + if (allocation_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 +1158,14 @@ 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 = &hmsc->scsi_blk[lun]; if (hmsc == NULL) { return -1; } - if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) + if ((blk_offset + blk_nbr) > p_scsi_blk->nbr) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); return -1; @@ -1079,6 +1183,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 = &hmsc->scsi_blk[lun]; uint32_t len; if (hmsc == NULL) @@ -1086,7 +1191,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) return -1; } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + len = p_scsi_blk->len * p_scsi_blk->size; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ @@ -1096,8 +1201,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 +1210,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 +1233,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 = &hmsc->scsi_blk[lun]; uint32_t len; if (hmsc == NULL) @@ -1135,7 +1241,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) return -1; } - len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + len = p_scsi_blk->len * p_scsi_blk->size; #ifdef USE_USBD_COMPOSITE /* Get the Endpoints addresses allocated for this class instance */ @@ -1144,27 +1250,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/Class/MTP/Inc/usbd_mtp.h b/Class/MTP/Inc/usbd_mtp.h index df2644f..77807f3 100644 --- a/Class/MTP/Inc/usbd_mtp.h +++ b/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/Class/MTP/Src/usbd_mtp_storage.c b/Class/MTP/Src/usbd_mtp_storage.c index e09cd39..ca35354 100644 --- a/Class/MTP/Src/usbd_mtp_storage.c +++ b/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,18 +150,18 @@ 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; - /* Reset the stat machine */ + /* 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; @@ -176,7 +188,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 +198,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 +259,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 +424,21 @@ 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; + } + + for (Counter = 0U; Counter < len; Counter++) { *pdst = (hmtp->rx_buff[Counter]); pdst++; } + return (uint8_t)USBD_OK; } @@ -456,17 +476,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/Core/Inc/usbd_conf_template.h b/Core/Inc/usbd_conf_template.h index 8d61e7a..1ff66bc 100644 --- a/Core/Inc/usbd_conf_template.h +++ b/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 */ diff --git a/Core/Inc/usbd_def.h b/Core/Inc/usbd_def.h index 2a295d7..5b2394e 100644 --- a/Core/Inc/usbd_def.h +++ b/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 diff --git a/Core/Inc/usbd_desc_template.h b/Core/Inc/usbd_desc_template.h index e392305..7be13ce 100644 --- a/Core/Inc/usbd_desc_template.h +++ b/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/Core/Src/usbd_core.c b/Core/Src/usbd_core.c index 0576c87..bcf571e 100644 --- a/Core/Src/usbd_core.c +++ b/Core/Src/usbd_core.c @@ -296,7 +296,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 +590,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 +601,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 +688,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 +699,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/Core/Src/usbd_desc_template.c b/Core/Src/usbd_desc_template.c index a9f995f..503eb13 100644 --- a/Core/Src/usbd_desc_template.c +++ b/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/Core/Src/usbd_ioreq.c b/Core/Src/usbd_ioreq.c index 7c8004a..2171398 100644 --- a/Core/Src/usbd_ioreq.c +++ b/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/Release_Notes.html b/Release_Notes.html index 94390d0..b72dc7d 100644 --- a/Release_Notes.html +++ b/Release_Notes.html @@ -59,8 +59,55 @@ Page : STM32Cube USB Wiki Page

Update History

- -
+
+ +

Main Changes

diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index b784d15..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,31 +0,0 @@ -# Report potential product security vulnerabilities - -ST places a high priority on security, and our Product Security Incident -Response Team (PSIRT) is committed to rapidly addressing potential security -vulnerabilities affecting our products. PSIRT's long history and vast experience -in security allows ST to perform clear analyses and provide appropriate guidance -on mitigations and solutions when applicable. - -If you wish to report potential security vulnerabilities regarding our products, -**please do not report them through public GitHub issues.** Instead, we -encourage you to report them to our ST PSIRT following the process described at: -**https://www.st.com/content/st_com/en/security/report-vulnerabilities.html** - -### IMPORTANT - READ CAREFULLY: - -STMicroelectronics International N.V., on behalf of itself, its affiliates and -subsidiaries, (collectively “ST”) takes all potential security vulnerability -reports or other related communications (“Report(s)”) seriously. In order to -review Your Report (the terms “You” and “Yours” include your employer, and all -affiliates, subsidiaries and related persons or entities) and take actions as -deemed appropriate, ST requires that we have the rights and Your permission to -do so. - -As such, by submitting Your Report to ST, You agree that You have the right to -do so, and You grant to ST the rights to use the Report for purposes related to -security vulnerability analysis, testing, correction, patching, reporting and -any other related purpose or function. - -By submitting Your Report, You agree that ST’s -[Privacy Policy](https://www.st.com/content/st_com/en/common/privacy-portal.html) -applies to all related communications.