📄 sbc_methods.c
字号:
BOT_EPT_BULK_IN,
pLun->pReadWriteBuffer,
pLun->dBlockSize,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check operation result code
if (bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: RBC_Read10: Failed to start to send data\n\r");
SBC_UpdateSenseData(&(pLun->sRequestSenseData),
SBC_SENSE_KEY_HARDWARE_ERROR,
0,
0);
bResult = BOT_STATUS_ERROR;
}
else {
TRACE_DEBUG_M("Sending ");
// Move to next command state
pCommandState->bState = SBC_STATE_WAIT_WRITE;
}
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check semaphore value
if (pTransfer->bSemaphore > 0) {
TRACE_DEBUG_M("Sent ");
// Take semaphore and move to next state
pTransfer->bSemaphore--;
pCommandState->bState = SBC_STATE_NEXT_BLOCK;
}
break;
//------------------------------
case SBC_STATE_NEXT_BLOCK:
//------------------------------
// Check operation result code
if (pTransfer->bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: RBC_Read10: Failed to send data\n\r");
SBC_UpdateSenseData(&(pLun->sRequestSenseData),
SBC_SENSE_KEY_HARDWARE_ERROR,
0,
0);
bResult = BOT_STATUS_ERROR;
}
else {
TRACE_DEBUG_M("Next ");
// Update transfer length and block address
STORE_DWORDB(DWORDB(pCommand->pLogicalBlockAddress) + 1,
pCommand->pLogicalBlockAddress);
pCommandState->dLength--;
// Check if transfer is finished
if (pCommandState->dLength == 0) {
bResult = BOT_STATUS_SUCCESS;
}
else {
pCommandState->bState = SBC_STATE_READ;
}
}
break;
}
}
// Convert dLength from blocks to bytes
pCommandState->dLength *= pLun->dBlockSize;
return bResult;
}
//------------------------------------------------------------------------------
//! \brief Performs a READ CAPACITY (10) command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of BOT_STATUS_INCOMPLETE indicates
//! that at least another call of the method is necessary.
//! \param pUsb Pointer to a S_usb instance
//! \param pLun Pointer to the LUN affected by the command
//! \param pCommandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see S_usb
//! \see S_lun
//! \see S_bot_command_state
//------------------------------------------------------------------------------
static unsigned char SBC_ReadCapacity10(const S_usb *pUsb,
S_lun *pLun,
S_bot_command_state *pCommandState)
{
unsigned char bResult = BOT_STATUS_INCOMPLETE;
unsigned char bStatus;
S_bot_transfer *pTransfer = &(pCommandState->sTransfer);
// Initialize command state if needed
if (pCommandState->bState == 0) {
pCommandState->bState = SBC_STATE_WRITE;
}
// Identify current command state
switch (pCommandState->bState) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start the write operation
bStatus = USB_Write(pUsb,
BOT_EPT_BULK_IN,
&(pLun->sReadCapacityData),
pCommandState->dLength,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check operation result code
if (bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: RBC_ReadCapacity: Cannot start sending data\n\r");
bResult = BOT_STATUS_ERROR;
}
else {
// Proceed to next command state
TRACE_DEBUG_M("Sending ");
pCommandState->bState = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check semaphore value
if (pTransfer->bSemaphore > 0) {
// Take semaphore and terminate command
pTransfer->bSemaphore--;
if (pTransfer->bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: RBC_ReadCapacity: Cannot send data\n\r");
bResult = BOT_STATUS_ERROR;
}
else {
TRACE_DEBUG_M("Sent ");
bResult = BOT_STATUS_SUCCESS;
}
pCommandState->dLength -= pTransfer->dBytesTransferred;
}
break;
}
return bResult;
}
//------------------------------------------------------------------------------
//! \brief Handles an INQUIRY command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of BOT_STATUS_INCOMPLETE indicates
//! that at least another call of the method is necessary.
//! \param pUsb Pointer to a S_usb instance
//! \param pLun Pointer to the LUN affected by the command
//! \param pCommandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see S_usb
//! \see S_lun
//! \see S_bot_command_state
//------------------------------------------------------------------------------
static unsigned char SBC_Inquiry(const S_usb *pUsb,
S_lun *pLun,
S_bot_command_state *pCommandState)
{
unsigned char bResult = BOT_STATUS_INCOMPLETE;
unsigned char bStatus;
S_bot_transfer *pTransfer = &(pCommandState->sTransfer);
// Check if required length is 0
if (pCommandState->dLength == 0) {
// Nothing to do
bResult = BOT_STATUS_SUCCESS;
}
// Initialize command state if needed
else if (pCommandState->bState == 0) {
pCommandState->bState = SBC_STATE_WRITE;
// Change additional length field of inquiry data
pLun->pInquiryData->bAdditionalLength
= (unsigned char) (pCommandState->dLength - 5);
}
// Identify current command state
switch (pCommandState->bState) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start write operation
bStatus = USB_Write(pUsb,
BOT_EPT_BULK_IN,
(void *) pLun->pInquiryData,
pCommandState->dLength,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check operation result code
if (bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: SPC_Inquiry: Cannot start sending data\n\r");
bResult = BOT_STATUS_ERROR;
}
else {
// Proceed to next state
TRACE_DEBUG_M("Sending ");
pCommandState->bState = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check the semaphore value
if (pTransfer->bSemaphore > 0) {
// Take semaphore and terminate command
pTransfer->bSemaphore--;
if (pTransfer->bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: SPC_Inquiry: Data transfer failed\n\r");
bResult = BOT_STATUS_ERROR;
}
else {
TRACE_DEBUG_M("Sent ");
bResult = BOT_STATUS_SUCCESS;
}
// Update dLength field
pCommandState->dLength -= pTransfer->dBytesTransferred;
}
break;
}
return bResult;
}
//------------------------------------------------------------------------------
//! \brief Performs a REQUEST SENSE command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of BOT_STATUS_INCOMPLETE indicates
//! that at least another call of the method is necessary.
//! \param pUsb Pointer to a S_usb instance
//! \param pLun Pointer to the LUN affected by the command
//! \param pCommandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see S_usb
//! \see S_lun
//! \see S_bot_command_state
//------------------------------------------------------------------------------
static unsigned char SBC_RequestSense(const S_usb *pUsb,
S_lun *pLun,
S_bot_command_state *pCommandState)
{
unsigned char bResult = BOT_STATUS_INCOMPLETE;
unsigned char bStatus;
S_bot_transfer *pTransfer = &(pCommandState->sTransfer);
// Check if requested length is zero
if (pCommandState->dLength == 0) {
// Nothing to do
bResult = BOT_STATUS_SUCCESS;
}
// Initialize command state if needed
else if (pCommandState->bState == 0) {
pCommandState->bState = SBC_STATE_WRITE;
}
// Identify current command state
switch (pCommandState->bState) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start transfer
bStatus = USB_Write(pUsb,
BOT_EPT_BULK_IN,
&(pLun->sRequestSenseData),
pCommandState->dLength,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check result code
if (bStatus != USB_STATUS_SUCCESS) {
TRACE_WARNING("W: RBC_RequestSense: Cannot start sending data\n\r");
bResult = BOT_STATUS_ERROR;
}
else {
// Change state
pCommandState->bState = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check the transfer semaphore
if (pTransfer->bSemaphore > 0) {
// Take semaphore and finish command
pTransfer->bSemaphore--;
if (pTransfer->bStatus != USB_STATUS_SUCCESS) {
bResult = BOT_STATUS_ERROR;
}
else {
bResult = BOT_STATUS_SUCCESS;
}
// Update pLength
pCommandState->dLength -= pTransfer->dBytesTransferred;
}
break;
}
return bResult;
}
//------------------------------------------------------------------------------
//! \brief Performs a MODE SENSE (6) command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of BOT_STATUS_INCOMPLETE indicates
//! that at least another call of the method is necessary.
//! \param pUsb Pointer to a S_usb instance
//! \param pLun Pointer to the LUN affected by the command
//! \param pCommandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see S_usb
//! \see S_lun
//! \see S_bot_command_state
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -