📄 msddstatemachine.c
字号:
TRACE_WARNING(
"MSDD_ProcessCommand: Requested LUN does not exist\n\r");
status = MSDD_STATUS_ERROR;
}
else {
// Process command
if (pMsdDriver->maxLun > 0) {
TRACE_INFO_WP("LUN%d ", cbw->bCBWLUN);
}
status = SBC_ProcessCommand(lun, commandState);
}
// Check command result code
if (status == MSDD_STATUS_PARAMETER) {
TRACE_WARNING(
"MSDD_ProcessCommand: Unknown command 0x%02X\n\r",
cbw->pCommand[0]);
// Update sense data
SBC_UpdateSenseData(&(lun->requestSenseData),
SBC_SENSE_KEY_ILLEGAL_REQUEST,
SBC_ASC_INVALID_FIELD_IN_CDB,
0);
// Result codes
csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
isCommandComplete = 1;
// stall the request, IN or OUT
if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0)
&& (cbw->dCBWDataTransferLength > 0)) {
// Stall the OUT endpoint : host to device
MSDD_Halt(MSDD_CASE_STALL_OUT);
TRACE_INFO_WP("StaOUT ");
}
else {
// Stall the IN endpoint : device to host
MSDD_Halt(MSDD_CASE_STALL_IN);
TRACE_INFO_WP("StaIN ");
}
}
else if (status == MSDD_STATUS_ERROR) {
TRACE_WARNING("MSD_ProcessCommand: Command failed\n\r");
// Update sense data
// TODO (jjoannic#1#): Change code
SBC_UpdateSenseData(&(lun->requestSenseData),
SBC_SENSE_KEY_MEDIUM_ERROR,
SBC_ASC_INVALID_FIELD_IN_CDB,
0);
// Result codes
csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
isCommandComplete = 1;
}
else {
// Update sense data
SBC_UpdateSenseData(&(lun->requestSenseData),
SBC_SENSE_KEY_NO_SENSE,
0,
0);
// Is command complete ?
if (status == MSDD_STATUS_SUCCESS) {
isCommandComplete = 1;
}
}
// Check if command has been completed
if (isCommandComplete) {
TRACE_INFO_WP("Cplt ");
// Adjust data residue
if (commandState->length != 0) {
csw->dCSWDataResidue += commandState->length;
// STALL the endpoint waiting for data
if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) {
// Stall the OUT endpoint : host to device
MSDD_Halt(MSDD_CASE_STALL_OUT);
TRACE_INFO_WP("StaOUT ");
}
else {
// Stall the IN endpoint : device to host
MSDD_Halt(MSDD_CASE_STALL_IN);
TRACE_INFO_WP("StaIN ");
}
}
// Reset command state
commandState->state = 0;
}
return isCommandComplete;
}
//-----------------------------------------------------------------------------
/// State machine for the MSD %device driver
/// \param pMsdDriver Pointer to a MSDDriver instance
//-----------------------------------------------------------------------------
void MSDD_StateMachine(MSDDriver * pMsdDriver)
{
MSDCommandState *commandState = &(pMsdDriver->commandState);
MSCbw *cbw = &(commandState->cbw);
MSCsw *csw = &(commandState->csw);
MSDTransfer *transfer = &(commandState->transfer);
unsigned char status;
// Identify current driver state
switch (pMsdDriver->state) {
//----------------------
case MSDD_STATE_READ_CBW:
//----------------------
// Start the CBW read operation
transfer->semaphore = 0;
status = MSDD_Read(cbw,
MSD_CBW_SIZE,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
// Check operation result code
if (status == USBD_STATUS_SUCCESS) {
// If the command was successful, wait for transfer
pMsdDriver->state = MSDD_STATE_WAIT_CBW;
}
break;
//----------------------
case MSDD_STATE_WAIT_CBW:
//----------------------
// Check transfer semaphore
if (transfer->semaphore > 0) {
// Take semaphore and terminate transfer
transfer->semaphore--;
// Check if transfer was successful
if (transfer->status == USBD_STATUS_SUCCESS) {
TRACE_INFO_WP("------------------------------\n\r");
// Process received command
pMsdDriver->state = MSDD_STATE_PROCESS_CBW;
}
else if (transfer->status == USBD_STATUS_RESET) {
TRACE_INFO("MSDD_StateMachine: Endpoint resetted\n\r");
pMsdDriver->state = MSDD_STATE_READ_CBW;
}
else {
TRACE_WARNING(
"MSDD_StateMachine: Failed to read CBW\n\r");
pMsdDriver->state = MSDD_STATE_READ_CBW;
}
}
break;
//-------------------------
case MSDD_STATE_PROCESS_CBW:
//-------------------------
// Check if this is a new command
if (commandState->state == 0) {
// Copy the CBW tag
csw->dCSWTag = cbw->dCBWTag;
// Check that the CBW is 31 bytes long
if ((transfer->transferred != MSD_CBW_SIZE) ||
(transfer->remaining != 0)) {
TRACE_WARNING(
"MSDD_StateMachine: Invalid CBW (Bad Length)\n\r");
// Wait for a reset recovery
pMsdDriver->waitResetRecovery = 1;
// Halt the Bulk-IN and Bulk-OUT pipes
MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);
csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
pMsdDriver->state = MSDD_STATE_READ_CBW;
}
// Check the CBW Signature
else if (cbw->dCBWSignature != MSD_CBW_SIGNATURE) {
TRACE_WARNING(
"MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r");
// Wait for a reset recovery
pMsdDriver->waitResetRecovery = 1;
// Halt the Bulk-IN and Bulk-OUT pipes
MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);
csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
pMsdDriver->state = MSDD_STATE_READ_CBW;
}
else {
// Pre-process command
MSDD_PreProcessCommand(pMsdDriver);
}
}
// Process command
if (csw->bCSWStatus == MSDD_STATUS_SUCCESS) {
if (MSDD_ProcessCommand(pMsdDriver)) {
// Post-process command if it is finished
MSDD_PostProcessCommand(pMsdDriver);
pMsdDriver->state = MSDD_STATE_SEND_CSW;
}
TRACE_INFO_WP("\n\r");
}
break;
//----------------------
case MSDD_STATE_SEND_CSW:
//----------------------
// Set signature
csw->dCSWSignature = MSD_CSW_SIGNATURE;
// Start the CSW write operation
status = MSDD_Write(csw,
MSD_CSW_SIZE,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
// Check operation result code
if (status == USBD_STATUS_SUCCESS) {
TRACE_INFO_WP("SendCSW ");
// Wait for end of transfer
pMsdDriver->state = MSDD_STATE_WAIT_CSW;
}
break;
//----------------------
case MSDD_STATE_WAIT_CSW:
//----------------------
// Check transfer semaphore
if (transfer->semaphore > 0) {
// Take semaphore and terminate transfer
transfer->semaphore--;
// Check if transfer was successful
if (transfer->status == USBD_STATUS_RESET) {
TRACE_INFO("MSDD_StateMachine: Endpoint resetted\n\r");
}
else if (transfer->status == USBD_STATUS_ABORTED) {
TRACE_WARNING(
"MSDD_StateMachine: Failed to send CSW\n\r");
}
else {
TRACE_INFO_WP("ok");
}
// Read new CBW
pMsdDriver->state = MSDD_STATE_READ_CBW;
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -