From e890e9df7aad8252fd874b3c26277ff18456af3b Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Sat, 31 Mar 2018 17:03:59 +1300 Subject: [PATCH] Disconnect on SCSI eject command from host --- .../Class/MSC/Inc/usbd_msc_scsi.h | 4 +++ .../Class/MSC/Src/usbd_msc_scsi.c | 16 ++++++++- .../Core/Inc/usbd_core.h | 1 + .../Core/Inc/usbd_def.h | 17 +++++++-- .../Core/Src/usbd_core.c | 35 ++++++++++++++++++- Upstream/Src/usbd_config.c | 2 +- 6 files changed, 69 insertions(+), 6 deletions(-) diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h index 600b0b3..2f499ae 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h @@ -117,6 +117,10 @@ #define STANDARD_INQUIRY_DATA_LEN 0x24 #define BLKVFY 0x04 +#define START_STOP_DATA_MASK 0x03 +#define START_STOP_DATA_EJECT_STOP_MOTOR 0x02 + + extern uint8_t Page00_Inquiry_Data[]; extern uint8_t Standard_Inquiry_Data[]; extern uint8_t Standard_Inquiry_Data2[]; diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index 90fd411..e2d8013 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -101,6 +101,7 @@ static void SCSI_ReadFormatCapacity(void); static void SCSI_ReadCapacity10(void); static void SCSI_RequestSense (void); static void SCSI_StartStopUnit(void); +static void SCSI_AllowMediumRemoval(void); static void SCSI_ModeSense6 (void); static void SCSI_ModeSense10 (void); static void SCSI_Write10(void); @@ -171,7 +172,7 @@ void SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, return; case SCSI_ALLOW_MEDIUM_REMOVAL: - SCSI_StartStopUnit(); + SCSI_AllowMediumRemoval(); return; case SCSI_MODE_SENSE6: @@ -546,10 +547,23 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_ */ static void SCSI_StartStopUnit(void) { + if ((SCSI_ProcessCmd_params[4] & START_STOP_DATA_MASK) == START_STOP_DATA_EJECT_STOP_MOTOR) + { + USBD_RequestStop(SCSI_ProcessCmd_pdev); //Host is signalling us to disconnect + } + SCSI_ProcessCmd_hmsc->bot_data_length = 0; SCSI_ProcessCmd_callback(0); } + +static void SCSI_AllowMediumRemoval(void) +{ + SCSI_ProcessCmd_hmsc->bot_data_length = 0; + SCSI_ProcessCmd_callback(0); +} + + /** * @brief SCSI_Read10 * Process Read10 command diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h index 7748824..40cd83d 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -92,6 +92,7 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef * USBD_ClassTypeDef* USBD_DeInit(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RequestStop(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev); diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 24db6eb..5a3330c 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -222,18 +222,29 @@ typedef struct uint32_t maxpacket; } USBD_EndpointTypeDef; + +typedef enum +{ + USB_STATUS_STOP, + USB_STATUS_START, + USB_STATUS_REQUEST_EJECT +} UsbCoreStatusTypeDef; + + /* USB Device handle structure */ typedef struct _USBD_HandleTypeDef { - uint8_t id; uint32_t dev_config; uint32_t dev_default_config; - uint32_t dev_config_status; + uint32_t dev_config_status; USBD_SpeedTypeDef dev_speed; USBD_EndpointTypeDef ep_in[15]; USBD_EndpointTypeDef ep_out[15]; uint32_t ep0_state; - uint32_t ep0_data_len; + uint32_t ep0_data_len; + uint32_t usbRequestEjectTime; + uint8_t id; + uint8_t usbCoreStatus; uint8_t dev_state; uint8_t dev_old_state; uint8_t dev_address; diff --git a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index 3a6e677..a808da5 100755 --- a/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/Upstream/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -121,6 +121,8 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef * /* Initialize low level driver */ USBD_LL_Init(pdev); + pdev->usbCoreStatus = USB_STATUS_STOP; + return USBD_OK; } @@ -184,10 +186,11 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeD */ USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) { - /* Start the low level driver */ USBD_LL_Start(pdev); + pdev->usbCoreStatus = USB_STATUS_START; + return USBD_OK; } @@ -205,9 +208,23 @@ USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) /* Stop the low level driver */ USBD_LL_Stop(pdev); + pdev->usbCoreStatus = USB_STATUS_STOP; + return USBD_OK; } + +USBD_StatusTypeDef USBD_RequestStop(USBD_HandleTypeDef *pdev) +{ + if (pdev->usbCoreStatus == USB_STATUS_START) + { + pdev->usbCoreStatus = USB_STATUS_REQUEST_EJECT; + pdev->usbRequestEjectTime = HAL_GetTick() + 5; //Allow > 1ms to transmit the SCSI eject reply before disconnecting + } + return USBD_OK; +} + + /** * @brief USBD_RunTestMode * Launch test mode process @@ -216,6 +233,8 @@ USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } @@ -500,6 +519,14 @@ USBD_StatusTypeDef USBD_SOF(USBD_HandleTypeDef *pdev) pdev->pClass->SOF(pdev); } } + + if (pdev->usbCoreStatus == USB_STATUS_REQUEST_EJECT) + { + if ((int32_t)(HAL_GetTick() - pdev->usbRequestEjectTime) >= 0) + { + USBD_Stop(pdev); + } + } return USBD_OK; } @@ -511,6 +538,8 @@ USBD_StatusTypeDef USBD_SOF(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { + UNUSED(pdev); + return USBD_OK; } @@ -522,6 +551,8 @@ USBD_StatusTypeDef USBD_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum */ USBD_StatusTypeDef USBD_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { + UNUSED(pdev); + return USBD_OK; } @@ -533,6 +564,8 @@ USBD_StatusTypeDef USBD_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnu */ USBD_StatusTypeDef USBD_DevConnected(USBD_HandleTypeDef *pdev) { + UNUSED(pdev); + return USBD_OK; } diff --git a/Upstream/Src/usbd_config.c b/Upstream/Src/usbd_config.c index 0c14415..29f2892 100755 --- a/Upstream/Src/usbd_config.c +++ b/Upstream/Src/usbd_config.c @@ -292,7 +292,7 @@ USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev) hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64; hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED; - hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + hpcd_USB_OTG_FS.Init.Sof_enable = ENABLE; hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE; hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;