From 16e964702ab44e3c96fce7fcbd6c742410ab21c8 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Sun, 29 Dec 2019 00:33:14 +1300 Subject: [PATCH] Implemented Stop/Eject command passthrough Conflicts: Downstream/.cproject Downstream/Inc/downstream_interface_def.h Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c Downstream/Src/downstream_msc.c Upstream/Inc/upstream_interface_def.h Upstream/Inc/upstream_msc.h Upstream/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c Upstream/Src/upstream_msc.c --- Downstream/.settings/language.settings.xml | 4 +- Downstream/Inc/downstream_interface_def.h | 17 +- .../Class/MSC/Inc/usbh_msc.h | 23 ++- .../Class/MSC/Inc/usbh_msc_scsi.h | 9 +- .../Class/MSC/Src/usbh_msc.c | 160 ++++++++++++------ .../Class/MSC/Src/usbh_msc_scsi.c | 70 +++++--- Downstream/Src/downstream_msc.c | 128 ++++++++++---- Upstream/Inc/upstream_interface_def.h | 17 +- Upstream/Inc/upstream_msc.h | 3 +- Upstream/Inc/upstream_statemachine.h | 2 - .../Class/MSC/Src/usbd_msc_scsi.c | 85 ++++++---- .../Core/Inc/usbd_core.h | 1 - .../Core/Inc/usbd_def.h | 3 +- .../Core/Src/usbd_core.c | 18 -- Upstream/Src/upstream_msc.c | 98 ++++++----- Upstream/Src/upstream_statemachine.c | 15 +- Upstream/Upstream Debug.launch | 1 + 17 files changed, 395 insertions(+), 259 deletions(-) diff --git a/Downstream/.settings/language.settings.xml b/Downstream/.settings/language.settings.xml index d1a6e73..8385451 100644 --- a/Downstream/.settings/language.settings.xml +++ b/Downstream/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/Downstream/Inc/downstream_interface_def.h b/Downstream/Inc/downstream_interface_def.h index dd6b538..77dc16a 100644 --- a/Downstream/Inc/downstream_interface_def.h +++ b/Downstream/Inc/downstream_interface_def.h @@ -47,26 +47,27 @@ InterfaceCommandInterfaceTypeDef; typedef enum { - COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result - COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size - COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream - COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream + COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result + COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size + COMMAND_MSC_READ, //Returns data stream or error packet + COMMAND_MSC_WRITE, //Waits for data stream or returns error packet + COMMAND_MSC_DISCONNECT //Returns same packet after sending Stop command to device } InterfaceCommandMscTypeDef; typedef enum { - COMMAND_HID_GET_REPORT, //Returns HID report from device - COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data. + COMMAND_HID_GET_REPORT, //Returns HID report from device + COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data. } InterfaceCommandHidTypeDef; typedef enum { - COMMAND_ERROR_GENERIC, - COMMAND_ERROR_DEVICE_DISCONNECTED, + COMMAND_ERROR_GENERIC, //Something went wrong, time to FREAKOUT + COMMAND_ERROR_DEVICE_DISCONNECTED, //Device unexpectedly disconnected } InterfaceCommandErrorTypeDef; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h index 8580dea..c968685 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc.h @@ -56,7 +56,7 @@ typedef enum MSC_READ, MSC_WRITE, MSC_UNRECOVERED_ERROR, - MSC_PERIODIC_CHECK, + MSC_START_STOP, } MSC_StateTypeDef; @@ -99,7 +99,7 @@ typedef struct MSC_LUNTypeDef; -typedef void (*MSC_RdWrCompleteCallback)(USBH_StatusTypeDef result); +typedef void (*MSC_CmdCompleteCallback)(USBH_StatusTypeDef result); /* Structure for MSC process */ typedef struct _MSC_Process @@ -121,7 +121,7 @@ typedef struct _MSC_Process uint16_t rw_lun; uint32_t timeout; uint32_t retry_timeout; - MSC_RdWrCompleteCallback RdWrCompleteCallback; + MSC_CmdCompleteCallback CmdCompleteCallback; } MSC_HandleTypeDef; @@ -153,6 +153,9 @@ MSC_HandleTypeDef; #define MSC_STARTUP_TIMEOUT_MS 15000 #define MSC_STARTUP_RETRY_TIME_MS 100 +#define MSC_START_STOP_EJECT_FLAG 0 +#define MSC_START_STOP_LOAD_FLAG 1 + /** * @} */ @@ -184,7 +187,9 @@ uint8_t USBH_MSC_IsReady (USBH_HandleTypeDef *phost); /* APIs for LUN */ int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost); -uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, uint8_t lun); +uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, + uint8_t lun, + MSC_CmdCompleteCallback callback); USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info); @@ -192,13 +197,19 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, uint8_t lun, uint32_t address, uint32_t length, - MSC_RdWrCompleteCallback callback); + MSC_CmdCompleteCallback callback); USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, uint8_t lun, uint32_t address, uint32_t length, - MSC_RdWrCompleteCallback callback); + MSC_CmdCompleteCallback callback); + +USBH_StatusTypeDef USBH_MSC_StartStopUnit(USBH_HandleTypeDef *phost, + uint8_t lun, + uint8_t startStop, + MSC_CmdCompleteCallback callback); + /** * @} */ diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_scsi.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_scsi.h index 2882eaf..9b2cf76 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_scsi.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_scsi.h @@ -93,12 +93,14 @@ typedef struct #define OPCODE_READ10 0x28 #define OPCODE_WRITE10 0x2A #define OPCODE_REQUEST_SENSE 0x03 -#define OPCODE_INQUIRY 0x12 +#define OPCODE_INQUIRY 0x12 +#define OPCODE_START_STOP_UNIT 0x1B #define DATA_LEN_MODE_TEST_UNIT_READY 0 #define DATA_LEN_READ_CAPACITY10 8 #define DATA_LEN_INQUIRY 36 -#define DATA_LEN_REQUEST_SENSE 14 +#define DATA_LEN_REQUEST_SENSE 14 +#define DATA_LEN_START_STOP_UNIT 0 #define CBW_CB_LENGTH 16 #define CBW_LENGTH 10 @@ -195,6 +197,9 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, uint32_t address, uint32_t length); +USBH_StatusTypeDef USBH_MSC_SCSI_StartStopUnit (USBH_HandleTypeDef *phost, + uint8_t lun, + uint8_t startStop); /** * @} diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c index bcbadb3..dd7a0a4 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c @@ -201,7 +201,7 @@ static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost) MSC_Handle->req_state = MSC_REQ_IDLE; MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp); MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp); - MSC_Handle->RdWrCompleteCallback = NULL; + MSC_Handle->CmdCompleteCallback = NULL; USBH_MSC_BOT_Init(phost); @@ -346,6 +346,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost) USBH_StatusTypeDef scsi_status = USBH_BUSY ; USBH_StatusTypeDef ready_status = USBH_BUSY ; + switch (MSC_Handle->state) { case MSC_INIT: @@ -360,7 +361,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost) case MSC_INIT: USBH_UsrLog ("LUN #%d: ", MSC_Handle->current_lun); MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY; - MSC_Handle->timeout = phost->Timer; + MSC_Handle->timeout = HAL_GetTick(); //Fallthrough case MSC_READ_INQUIRY: @@ -519,7 +520,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost) #endif case MSC_READ: error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun); - if(((int32_t)(phost->Timer - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0)) + if(((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0)) { error = USBH_FAIL; } @@ -527,14 +528,57 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost) if (error != USBH_BUSY) { MSC_Handle->state = MSC_IDLE; - if (MSC_Handle->RdWrCompleteCallback != NULL) + if (MSC_Handle->CmdCompleteCallback != NULL) { - MSC_Handle->RdWrCompleteCallback(error); - MSC_Handle->RdWrCompleteCallback = NULL; + MSC_Handle->CmdCompleteCallback(error); + MSC_Handle->CmdCompleteCallback = NULL; } } break; + case MSC_TEST_UNIT_READY: + error = USBH_MSC_SCSI_TestUnitReady(phost, MSC_Handle->rw_lun); + + if (((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0)) + { + error = USBH_FAIL; + } + if (error != USBH_BUSY) + { + MSC_Handle->state = MSC_IDLE; + if (error == USBH_OK) + { + MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK; + } + else + { + MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY; + } + if (MSC_Handle->CmdCompleteCallback != NULL) + { + MSC_Handle->CmdCompleteCallback(error); + MSC_Handle->CmdCompleteCallback = NULL; + } + } + break; + + case MSC_START_STOP: + error = USBH_MSC_SCSI_StartStopUnit(phost, MSC_Handle->rw_lun, 0); + + if((error != USBH_BUSY) || + ((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0)) + { + MSC_Handle->state = MSC_IDLE; + error = USBH_OK; + + if (MSC_Handle->CmdCompleteCallback != NULL) + { + MSC_Handle->CmdCompleteCallback(USBH_OK); + MSC_Handle->CmdCompleteCallback = NULL; + } + } + break; + default: break; } @@ -650,26 +694,6 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_ } -/** - * @brief USBH_MSC_IsReady - * The function check if the MSC function is ready - * @param phost: Host handle - * @retval USBH Status - */ -uint8_t USBH_MSC_IsReady (USBH_HandleTypeDef *phost) -{ - MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; - - if(phost->gState == HOST_CLASS) - { - return (MSC_Handle->state == MSC_IDLE); - } - else - { - return 0; - } -} - /** * @brief USBH_MSC_GetMaxLUN * The function return the Max LUN supported @@ -694,18 +718,25 @@ int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost) * @param lun: logical Unit Number * @retval Lun status (0: not ready / 1: ready) */ -uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, uint8_t lun) +uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost, + uint8_t lun, + MSC_CmdCompleteCallback callback) { - MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; + MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; - if(phost->gState == HOST_CLASS) - { - return (MSC_Handle->unit[lun].error == MSC_OK); - } - else - { - return 0; - } + if ((phost->device.is_connected == 0) || + (phost->gState != HOST_CLASS) || + (MSC_Handle->state != MSC_IDLE)) + { + return USBH_FAIL; + } + + MSC_Handle->state = MSC_TEST_UNIT_READY; + MSC_Handle->rw_lun = lun; + MSC_Handle->CmdCompleteCallback = callback; + MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS; + + return USBH_MSC_SCSI_TestUnitReady(phost, lun); } /** @@ -743,7 +774,7 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, uint8_t lun, uint32_t address, uint32_t length, - MSC_RdWrCompleteCallback callback) + MSC_CmdCompleteCallback callback) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; @@ -757,15 +788,14 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, MSC_Handle->state = MSC_READ; MSC_Handle->unit[lun].state = MSC_READ; - MSC_Handle->rw_lun = lun; - MSC_Handle->RdWrCompleteCallback = callback; + MSC_Handle->rw_lun = lun; + MSC_Handle->CmdCompleteCallback = callback; MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS; - USBH_MSC_SCSI_Read(phost, - lun, - address, - length); - return USBH_OK; + return USBH_MSC_SCSI_Read(phost, + lun, + address, + length); } @@ -785,7 +815,7 @@ USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, uint8_t lun, uint32_t address, uint32_t length, - MSC_RdWrCompleteCallback callback) + MSC_CmdCompleteCallback callback) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; @@ -799,18 +829,44 @@ USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, MSC_Handle->state = MSC_WRITE; MSC_Handle->unit[lun].state = MSC_WRITE; - MSC_Handle->rw_lun = lun; - MSC_Handle->RdWrCompleteCallback = callback; + MSC_Handle->rw_lun = lun; + MSC_Handle->CmdCompleteCallback = callback; MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS; - USBH_MSC_SCSI_Write(phost, - lun, - address, - length); - return USBH_OK; + return USBH_MSC_SCSI_Write(phost, + lun, + address, + length); } #endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED + + +USBH_StatusTypeDef USBH_MSC_StartStopUnit(USBH_HandleTypeDef *phost, + uint8_t lun, + uint8_t startStop, + MSC_CmdCompleteCallback callback) +{ + MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; + + if ((phost->device.is_connected == 0) || + (phost->gState != HOST_CLASS) || + (MSC_Handle->state != MSC_IDLE)) + { + return USBH_FAIL; + } + + MSC_Handle->state = MSC_START_STOP; + MSC_Handle->rw_lun = lun; + MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS; + MSC_Handle->CmdCompleteCallback = callback; + + return USBH_MSC_SCSI_StartStopUnit(phost, + lun, + startStop); +} + + #endif //#ifdef CONFIG_MASS_STORAGE_ENABLED /** diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c index 03e3191..bbd24de 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c @@ -110,35 +110,23 @@ USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost, uint8_t lun) { - USBH_StatusTypeDef error = USBH_FAIL ; - MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; - - switch(MSC_Handle->hbot.cmd_state) - { - case BOT_CMD_SEND: - - /*Prepare the CBW and relevent field*/ - MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY; - MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; - MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; - - USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); - MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY; - - MSC_Handle->hbot.state = BOT_SEND_CBW; - MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; - error = USBH_BUSY; - break; - - case BOT_CMD_WAIT: - error = USBH_MSC_BOT_Process(phost, lun); - break; + MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; - default: - break; - } - - return error; + if (MSC_Handle->hbot.cmd_state == BOT_CMD_SEND) + { + /*Prepare the CBW and relevent field*/ + MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY; + MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; + MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; + + USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); + MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY; + + MSC_Handle->hbot.state = BOT_SEND_CBW; + MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; + } + + return USBH_MSC_BOT_Process(phost, lun); } /** @@ -431,6 +419,32 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, return error; } + +USBH_StatusTypeDef USBH_MSC_SCSI_StartStopUnit(USBH_HandleTypeDef *phost, + uint8_t lun, + uint8_t startStop) +{ + MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; + + if (MSC_Handle->hbot.cmd_state == BOT_CMD_SEND) + { + /*Prepare the CBW and relevent field*/ + MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_START_STOP_UNIT; + MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; + MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; + + USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH); + MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_START_STOP_UNIT; + MSC_Handle->hbot.cbw.field.CB[4] = 0x02 | (startStop & 0x01); //LOEJ = 1, START = 0 for eject, START = 1 for load + + MSC_Handle->hbot.state = BOT_SEND_CBW; + MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; + } + + return USBH_MSC_BOT_Process(phost, lun); +} + + #endif //#ifdef CONFIG_MASS_STORAGE_ENABLED /** diff --git a/Downstream/Src/downstream_msc.c b/Downstream/Src/downstream_msc.c index 3692811..496800d 100644 --- a/Downstream/Src/downstream_msc.c +++ b/Downstream/Src/downstream_msc.c @@ -30,12 +30,15 @@ DownstreamPacketTypeDef* ReadStreamPacket; uint8_t ReadStreamBusy; -void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket); -void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket); -void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket); -void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket); -void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result); -void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result); +static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result); +static void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result); //High-level checks on the connected device. We don't want some weirdly @@ -86,6 +89,10 @@ void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) break; #endif + case COMMAND_MSC_DISCONNECT: + Downstream_MSC_PacketProcessor_Disconnect(receivedPacket); + break; + default: Downstream_PacketProcessor_FreakOut(); } @@ -93,22 +100,42 @@ void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) } -void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket) +static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket) { - if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) + Downstream_ReleasePacket(receivedPacket); + + if (USBH_MSC_UnitIsReady(&hUsbHostFS, + MSC_FIXED_LUN, + Downstream_MSC_PacketProcessor_TestUnitReadyCallback) != USBH_BUSY) { - receivedPacket->Data[0] = HAL_OK; + Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_FAIL); + } +} + + +static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result) +{ + DownstreamPacketTypeDef* freePacket; + + freePacket = Downstream_GetFreePacketImmediately(); + freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; + freePacket->Command = COMMAND_MSC_TEST_UNIT_READY; + freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; + + if (result == USBH_OK) + { + freePacket->Data[0] = HAL_OK; } else { - receivedPacket->Data[0] = HAL_ERROR; + freePacket->Data[0] = HAL_ERROR; } - receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; - Downstream_PacketProcessor_ClassReply(receivedPacket); + Downstream_PacketProcessor_ClassReply(freePacket); } -void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket) + +static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket) { MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; @@ -120,7 +147,7 @@ void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receive -void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket) +static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket) { uint64_t readBlockAddress; uint32_t readBlockCount; @@ -146,22 +173,22 @@ void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedP receivedPacket->Data[0] = HAL_ERROR; receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; - if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) + if (USBH_MSC_Read(&hUsbHostFS, + MSC_FIXED_LUN, + (uint32_t)readBlockAddress, + readBlockCount, + Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY) { - if (USBH_MSC_Read(&hUsbHostFS, - MSC_FIXED_LUN, - (uint32_t)readBlockAddress, - readBlockCount, - Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK) - { - receivedPacket->Data[0] = HAL_OK; - } + Downstream_ReleasePacket(receivedPacket); + return; } - Downstream_TransmitPacket(receivedPacket); + + //Fail: + Downstream_PacketProcessor_ClassReply(receivedPacket); } -void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result) +static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result) { if (result != USBH_OK) { @@ -172,8 +199,9 @@ void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef resu } + #ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED -void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket) +static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket) { uint64_t writeBlockAddress; uint32_t writeBlockCount; @@ -206,18 +234,18 @@ void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* received //Our host stack has no way to detect if write-protection is enabled. //So currently we can't return HAL_BUSY to Upstream in this situation. - if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) + if (USBH_MSC_Write(&hUsbHostFS, + MSC_FIXED_LUN, + (uint32_t)writeBlockAddress, + writeBlockCount, + Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY) { - if (USBH_MSC_Write(&hUsbHostFS, - MSC_FIXED_LUN, - (uint32_t)writeBlockAddress, - writeBlockCount, - Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK) - { - receivedPacket->Data[0] = HAL_OK; - } + Downstream_ReleasePacket(receivedPacket); + return; } - Downstream_TransmitPacket(receivedPacket); + + //Fail: + Downstream_PacketProcessor_ClassReply(receivedPacket); } #endif @@ -292,5 +320,33 @@ void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receive } #endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED + + +static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket) +{ + Downstream_ReleasePacket(receivedPacket); + + USBH_MSC_StartStopUnit(&hUsbHostFS, + MSC_FIXED_LUN, + MSC_START_STOP_EJECT_FLAG, + Downstream_MSC_PacketProcessor_DisconnectCallback); +} + + + +static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result) +{ + DownstreamPacketTypeDef* freePacket; + + if (result == USBH_OK) + { + freePacket = Downstream_GetFreePacketImmediately(); + freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; + freePacket->Command = COMMAND_MSC_DISCONNECT; + freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16; + Downstream_PacketProcessor_ClassReply(freePacket); + } +} + #endif //#ifdef CONFIG_MASS_STORAGE_ENABLED diff --git a/Upstream/Inc/upstream_interface_def.h b/Upstream/Inc/upstream_interface_def.h index f4d0a23..7bc519a 100644 --- a/Upstream/Inc/upstream_interface_def.h +++ b/Upstream/Inc/upstream_interface_def.h @@ -49,26 +49,27 @@ InterfaceCommandInterfaceTypeDef; typedef enum { - COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result - COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size - COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream - COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream + COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result + COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size + COMMAND_MSC_READ, //Returns data stream or error packet + COMMAND_MSC_WRITE, //Waits for data stream or returns error packet + COMMAND_MSC_DISCONNECT //Returns same packet after sending Stop command to device } InterfaceCommandMscTypeDef; typedef enum { - COMMAND_HID_GET_REPORT, //Returns HID report from device - COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data. + COMMAND_HID_GET_REPORT, //Returns HID report from device + COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data. } InterfaceCommandHidTypeDef; typedef enum { - COMMAND_ERROR_GENERIC, - COMMAND_ERROR_DEVICE_DISCONNECTED, + COMMAND_ERROR_GENERIC, //Something went wrong, time to FREAKOUT + COMMAND_ERROR_DEVICE_DISCONNECTED, //Device unexpectedly disconnected } InterfaceCommandErrorTypeDef; diff --git a/Upstream/Inc/upstream_msc.h b/Upstream/Inc/upstream_msc.h index 89b4770..67a34ef 100644 --- a/Upstream/Inc/upstream_msc.h +++ b/Upstream/Inc/upstream_msc.h @@ -42,7 +42,8 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, uint32_t writeBlockCount); HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend, uint32_t dataLength8); -void Upstream_MSC_RegisterDisconnect(void); +HAL_StatusTypeDef Upstream_MSC_RequestDisconnect(UpstreamMSCCallbackTypeDef callback); + #endif /* INC_UPSTREAM_MSC_H_ */ diff --git a/Upstream/Inc/upstream_statemachine.h b/Upstream/Inc/upstream_statemachine.h index c021111..e6b982b 100644 --- a/Upstream/Inc/upstream_statemachine.h +++ b/Upstream/Inc/upstream_statemachine.h @@ -24,7 +24,6 @@ typedef enum STATE_WAIT_DEVICE, STATE_DEVICE_ACTIVE, STATE_SUSPENDED, - STATE_DISCONNECTING, STATE_ERROR } UpstreamStateTypeDef; @@ -47,7 +46,6 @@ void Upstream_StateMachine_DeviceDisconnected(void); void Upstream_StateMachine_Suspend(void); void Upstream_StateMachine_CheckResume(void); void Upstream_StateMachine_Wakeup(void); -void Upstream_StateMachine_RegisterDisconnect(void); 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 9c21762..57f2163 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 @@ -108,19 +108,21 @@ static void SCSI_Write10(void); static void SCSI_Read10(void); static void SCSI_Verify10(void); static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr); - -void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result); -void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, - uint32_t result_uint1, - uint32_t result_uint2); -void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, - uint32_t result_uint1, - uint32_t result_uint2); -void SCSI_Read10BeginCallback(HAL_StatusTypeDef result); -void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, - uint16_t dataLength); -void SCSI_Write10BeginCallback(HAL_StatusTypeDef result); -void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket); + +static void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result); +static void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2); +static void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2); +static void SCSI_Read10BeginCallback(HAL_StatusTypeDef result); +static void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, + uint16_t dataLength); +static void SCSI_Write10BeginCallback(HAL_StatusTypeDef result); +static void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket); +static void SCSI_StartStopUnitCallback(HAL_StatusTypeDef result); + /** @@ -228,7 +230,7 @@ void SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, * @param params: Command parameters * @retval status */ -void SCSI_TestUnitReady(void) +static void SCSI_TestUnitReady(void) { /* case 9 : Hi > D0 */ if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != 0) @@ -254,7 +256,7 @@ void SCSI_TestUnitReady(void) } -void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result) +static void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result) { if (result != HAL_OK) { @@ -334,10 +336,10 @@ static void SCSI_ReadCapacity10(void) } } - + void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, uint32_t result_uint1, - uint32_t result_uint2) + uint32_t result_uint2) { if (upstreamPacket == NULL) { @@ -369,6 +371,8 @@ void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket, SCSI_ProcessCmd_callback(0); } + + /** * @brief SCSI_ReadFormatCapacity * Process Read Format Capacity command @@ -384,10 +388,10 @@ static void SCSI_ReadFormatCapacity(void) } } - -void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, - uint32_t result_uint1, - uint32_t result_uint2) + +static void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket, + uint32_t result_uint1, + uint32_t result_uint2) { if (upstreamPacket == NULL) { @@ -549,15 +553,30 @@ 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 - Upstream_MSC_RegisterDisconnect(); + if (Upstream_MSC_RequestDisconnect(SCSI_StartStopUnitCallback) != HAL_OK) //Host is signalling us to disconnect + { + SCSI_StartStopUnitCallback(HAL_ERROR); + } + } + else + { + SCSI_StartStopUnitCallback(HAL_OK); } +} - SCSI_ProcessCmd_hmsc->bot_data_length = 0; - SCSI_ProcessCmd_callback(0); + + +static void SCSI_StartStopUnitCallback(HAL_StatusTypeDef result) +{ + if (result == HAL_OK) + { + SCSI_ProcessCmd_hmsc->bot_data_length = 0; + SCSI_ProcessCmd_callback(0); + } } + static void SCSI_AllowMediumRemoval(void) { SCSI_ProcessCmd_hmsc->bot_data_length = 0; @@ -627,15 +646,14 @@ static void SCSI_Read10(void) return; } - //hmsc->bot_state is already USBD_BOT_DATA_IN if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK) { SCSI_Read10ReplyCallback(NULL, 0); } } - -void SCSI_Read10BeginCallback(HAL_StatusTypeDef result) + +static void SCSI_Read10BeginCallback(HAL_StatusTypeDef result) { if (result != HAL_OK) { @@ -654,9 +672,9 @@ void SCSI_Read10BeginCallback(HAL_StatusTypeDef result) } } - -void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, - uint16_t dataLength) + +static void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket, + uint16_t dataLength) { if (upstreamPacket == NULL) { @@ -787,7 +805,7 @@ static void SCSI_Write10(void) void SCSI_Write10BeginCallback(HAL_StatusTypeDef result) -{ +{ if (result == HAL_BUSY) { SCSI_SenseCode(SCSI_ProcessCmd_pdev, @@ -820,7 +838,8 @@ void SCSI_Write10BeginCallback(HAL_StatusTypeDef result) } -void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket) + +static void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket) { SCSI_ProcessCmd_hmsc->bot_packet = freePacket; SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data; 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 40cd83d..7748824 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,7 +92,6 @@ 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 5a3330c..1062ec7 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 @@ -226,8 +226,7 @@ typedef struct typedef enum { USB_STATUS_STOP, - USB_STATUS_START, - USB_STATUS_REQUEST_EJECT + USB_STATUS_START } UsbCoreStatusTypeDef; 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 792b1f2..523a2ec 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 @@ -214,17 +214,6 @@ USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) } -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 @@ -520,13 +509,6 @@ USBD_StatusTypeDef USBD_SOF(USBD_HandleTypeDef *pdev) } } - if (pdev->usbCoreStatus == USB_STATUS_REQUEST_EJECT) - { - if ((int32_t)(HAL_GetTick() - pdev->usbRequestEjectTime) >= 0) - { - USBD_Stop(pdev); - } - } return USBD_OK; } diff --git a/Upstream/Src/upstream_msc.c b/Upstream/Src/upstream_msc.c index fc9252b..954f870 100644 --- a/Upstream/Src/upstream_msc.c +++ b/Upstream/Src/upstream_msc.c @@ -23,6 +23,9 @@ //Stuff we need to save for our callbacks to use: UpstreamMSCCallbackTypeDef TestReadyCallback; +UpstreamMSCCallbackTypeDef BeginReadCallback; +UpstreamMSCCallbackTypeDef BeginWriteCallback; +UpstreamMSCCallbackTypeDef DisconnectCallback; UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback; UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback; uint64_t BlockStart; @@ -39,7 +42,8 @@ static void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPa static void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket); static void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket); static void Upstream_MSC_BeginWriteFreePacketCallback(UpstreamPacketTypeDef* freePacket); -static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket); +static void Upstream_MSC_RequestDisconnectFreePacketCallback(UpstreamPacketTypeDef* freePacket); +static void Upstream_MSC_RequestDisconnectReplyCallback(UpstreamPacketTypeDef* replyPacket); @@ -190,13 +194,13 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamBusy = 0; - TestReadyCallback = callback; + BeginReadCallback = callback; return Upstream_GetFreePacket(Upstream_MSC_BeginReadFreePacketCallback); } -void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket) +static void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket) { freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2); freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; @@ -206,16 +210,13 @@ void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket) if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK) //Re-use TestReadyReplyCallback because it does exactly what we want! - { - TestReadyCallback(HAL_ERROR); - } + BeginReadCallback(HAL_OK); return; } //else: Upstream_ReleasePacket(freePacket); - TestReadyCallback(HAL_ERROR); + BeginReadCallback(HAL_ERROR); } @@ -299,7 +300,7 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, BlockStart = writeBlockStart; BlockCount = writeBlockCount; - TestReadyCallback = callback; + BeginWriteCallback = callback; return Upstream_GetFreePacket(Upstream_MSC_BeginWriteFreePacketCallback); } @@ -315,46 +316,13 @@ void Upstream_MSC_BeginWriteFreePacketCallback(UpstreamPacketTypeDef* freePacket if (Upstream_TransmitPacket(freePacket) == HAL_OK) { - if (Upstream_ReceivePacket(Upstream_MSC_BeginWriteReplyCallback) != HAL_OK) - { - TestReadyCallback(HAL_ERROR); - } + BeginWriteCallback(HAL_OK); return; } //else: Upstream_ReleasePacket(freePacket); - TestReadyCallback(HAL_ERROR); -} - - - -void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) -{ - uint8_t tempResult; - - if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) - { - return; - } - - if (replyPacket == NULL) - { - TestReadyCallback(HAL_ERROR); - return; - } - - if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) || - ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY))) - { - Upstream_ReleasePacket(replyPacket); - TestReadyCallback(HAL_ERROR); - return; - } - - tempResult = replyPacket->Data[0]; - Upstream_ReleasePacket(replyPacket); - TestReadyCallback(tempResult); + BeginWriteCallback(HAL_ERROR); } @@ -381,11 +349,49 @@ HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packet -void Upstream_MSC_RegisterDisconnect(void) +HAL_StatusTypeDef Upstream_MSC_RequestDisconnect(UpstreamMSCCallbackTypeDef callback) { - Upstream_StateMachine_RegisterDisconnect(); + if (Upstream_StateMachine_CheckActiveClass() != COMMAND_CLASS_MASS_STORAGE) return HAL_ERROR; + + DisconnectCallback = callback; + return Upstream_GetFreePacket(Upstream_MSC_RequestDisconnectFreePacketCallback); } + +static void Upstream_MSC_RequestDisconnectFreePacketCallback(UpstreamPacketTypeDef* freePacket) +{ + freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16; + freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; + freePacket->Command = COMMAND_MSC_DISCONNECT; + + if (Upstream_TransmitPacket(freePacket) == HAL_OK) + { + //Upstream_PacketManager will free the packet when the transfer is done + if (Upstream_ReceivePacket(Upstream_MSC_RequestDisconnectReplyCallback) != HAL_OK) + { + DisconnectCallback(HAL_ERROR); + } + return; + } + + //else: + Upstream_ReleasePacket(freePacket); + DisconnectCallback(HAL_ERROR); +} + + + +static void Upstream_MSC_RequestDisconnectReplyCallback(UpstreamPacketTypeDef* replyPacket) +{ + //Acknowledge the SCSI Stop command to host now. + //We will disconnect from host when Downstream replies with COMMAND_ERROR_DEVICE_DISCONNECTED. + + Upstream_ReleasePacket(replyPacket); + DisconnectCallback(HAL_OK); +} + + + #endif //#ifdef CONFIG_MASS_STORAGE_ENABLED diff --git a/Upstream/Src/upstream_statemachine.c b/Upstream/Src/upstream_statemachine.c index 39794e7..0bb3e16 100644 --- a/Upstream/Src/upstream_statemachine.c +++ b/Upstream/Src/upstream_statemachine.c @@ -79,8 +79,7 @@ void Upstream_StateMachine_SetErrorState(void) InterfaceCommandClassTypeDef Upstream_StateMachine_CheckActiveClass(void) { - if ((UpstreamState == STATE_ERROR) || - (UpstreamState == STATE_DISCONNECTING)) + if (UpstreamState == STATE_ERROR) { return COMMAND_CLASS_ERROR; } @@ -296,15 +295,3 @@ void Upstream_StateMachine_Wakeup(void) } -//Host sends a SCSI motor stop command, so we shouldn't process any more commands. -void Upstream_StateMachine_RegisterDisconnect(void) -{ - if ((UpstreamState != STATE_DEVICE_ACTIVE) && - (UpstreamState != STATE_SUSPENDED)) - { - UPSTREAM_STATEMACHINE_FREAKOUT; - return; - } - - UpstreamState = STATE_DISCONNECTING; -} diff --git a/Upstream/Upstream Debug.launch b/Upstream/Upstream Debug.launch index b7d7183..ad069b6 100644 --- a/Upstream/Upstream Debug.launch +++ b/Upstream/Upstream Debug.launch @@ -59,5 +59,6 @@ +