📄 sbcmethods.c
字号:
// Send the block to the host
#if !defined(AT91C_EBI_SDRAM) && !defined(BOARD_USB_UDPHS)
status = MSDD_Write((void*)lun->readWriteBuffer,
lun->blockSize,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
#else
status = MSDD_Write((void*)(lun->media->baseAddress
+ lun->baseAddress
+ DWORDB(command->pLogicalBlockAddress) * lun->blockSize),
commandState->length,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
#endif
// Check operation result code
if (status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"RBC_Read10: Failed to start to send data\n\r");
SBC_UpdateSenseData(&(lun->requestSenseData),
SBC_SENSE_KEY_HARDWARE_ERROR,
0,
0);
result = MSDD_STATUS_ERROR;
}
else {
TRACE_INFO_WP("Sending ");
// Move to next command state
commandState->state = SBC_STATE_WAIT_WRITE;
}
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check semaphore value
if (transfer->semaphore > 0) {
TRACE_INFO_WP("Sent ");
// Take semaphore and move to next state
transfer->semaphore--;
commandState->state = SBC_STATE_NEXT_BLOCK;
}
break;
//------------------------------
case SBC_STATE_NEXT_BLOCK:
//------------------------------
// Check operation result code
if (transfer->status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"RBC_Read10: Failed to send data\n\r");
SBC_UpdateSenseData(&(lun->requestSenseData),
SBC_SENSE_KEY_HARDWARE_ERROR,
0,
0);
result = MSDD_STATUS_ERROR;
}
else {
TRACE_INFO_WP("Next ");
// Update transfer length and block address
STORE_DWORDB(DWORDB(command->pLogicalBlockAddress) + 1,
command->pLogicalBlockAddress);
#if !defined(AT91C_EBI_SDRAM) && !defined(BOARD_USB_UDPHS)
commandState->length--;
#else
commandState->length = 0;
#endif
// Check if transfer is finished
if (commandState->length == 0) {
result = MSDD_STATUS_SUCCESS;
}
else {
commandState->state = SBC_STATE_READ;
}
}
break;
}
}
#if !defined(AT91C_EBI_SDRAM) && !defined(BOARD_USB_UDPHS)
// Convert length from blocks to bytes
commandState->length *= lun->blockSize;
#endif
return result;
}
//------------------------------------------------------------------------------
//! \brief Performs a READ CAPACITY (10) command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of MSDDriver_STATUS_INCOMPLETE
//! indicates that at least another call of the method is necessary.
//! \param lun Pointer to the LUN affected by the command
//! \param commandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see MSDLun
//! \see MSDCommandState
//------------------------------------------------------------------------------
static unsigned char SBC_ReadCapacity10(MSDLun *lun,
MSDCommandState *commandState)
{
unsigned char result = MSDD_STATUS_INCOMPLETE;
unsigned char status;
MSDTransfer *transfer = &(commandState->transfer);
// Initialize command state if needed
if (commandState->state == 0) {
commandState->state = SBC_STATE_WRITE;
}
// Identify current command state
switch (commandState->state) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start the write operation
status = MSDD_Write(&(lun->readCapacityData),
commandState->length,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
// Check operation result code
if (status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"RBC_ReadCapacity: Cannot start sending data\n\r");
result = MSDD_STATUS_ERROR;
}
else {
// Proceed to next command state
TRACE_INFO_WP("Sending ");
commandState->state = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check semaphore value
if (transfer->semaphore > 0) {
// Take semaphore and terminate command
transfer->semaphore--;
if (transfer->status != USBD_STATUS_SUCCESS) {
TRACE_WARNING("RBC_ReadCapacity: Cannot send data\n\r");
result = MSDD_STATUS_ERROR;
}
else {
TRACE_INFO_WP("Sent ");
result = MSDD_STATUS_SUCCESS;
}
commandState->length -= transfer->transferred;
}
break;
}
return result;
}
//------------------------------------------------------------------------------
//! \brief Handles an INQUIRY command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of MSDDriver_STATUS_INCOMPLETE
//! indicates that at least another call of the method is necessary.
//! \param lun Pointer to the LUN affected by the command
//! \param commandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see MSDLun
//! \see MSDCommandState
//------------------------------------------------------------------------------
static unsigned char SBC_Inquiry(MSDLun *lun,
MSDCommandState *commandState)
{
unsigned char result = MSDD_STATUS_INCOMPLETE;
unsigned char status;
MSDTransfer *transfer = &(commandState->transfer);
// Check if required length is 0
if (commandState->length == 0) {
// Nothing to do
result = MSDD_STATUS_SUCCESS;
}
// Initialize command state if needed
else if (commandState->state == 0) {
commandState->state = SBC_STATE_WRITE;
// Change additional length field of inquiry data
lun->inquiryData->bAdditionalLength
= (unsigned char) (commandState->length - 5);
}
// Identify current command state
switch (commandState->state) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start write operation
status = MSDD_Write((void *) lun->inquiryData,
commandState->length,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
// Check operation result code
if (status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"SPC_Inquiry: Cannot start sending data\n\r");
result = MSDD_STATUS_ERROR;
}
else {
// Proceed to next state
TRACE_INFO_WP("Sending ");
commandState->state = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check the semaphore value
if (transfer->semaphore > 0) {
// Take semaphore and terminate command
transfer->semaphore--;
if (transfer->status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"SPC_Inquiry: Data transfer failed\n\r");
result = MSDD_STATUS_ERROR;
}
else {
TRACE_INFO_WP("Sent ");
result = MSDD_STATUS_SUCCESS;
}
// Update length field
commandState->length -= transfer->transferred;
}
break;
}
return result;
}
//------------------------------------------------------------------------------
//! \brief Performs a REQUEST SENSE command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of MSDDriver_STATUS_INCOMPLETE
//! indicates that at least another call of the method is necessary.
//! \param lun Pointer to the LUN affected by the command
//! \param commandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see MSDLun
//! \see MSDCommandState
//------------------------------------------------------------------------------
static unsigned char SBC_RequestSense(MSDLun *lun,
MSDCommandState *commandState)
{
unsigned char result = MSDD_STATUS_INCOMPLETE;
unsigned char status;
MSDTransfer *transfer = &(commandState->transfer);
// Check if requested length is zero
if (commandState->length == 0) {
// Nothing to do
result = MSDD_STATUS_SUCCESS;
}
// Initialize command state if needed
else if (commandState->state == 0) {
commandState->state = SBC_STATE_WRITE;
}
// Identify current command state
switch (commandState->state) {
//-------------------
case SBC_STATE_WRITE:
//-------------------
// Start transfer
status = MSDD_Write(&(lun->requestSenseData),
commandState->length,
(TransferCallback) MSDDriver_Callback,
(void *) transfer);
// Check result code
if (status != USBD_STATUS_SUCCESS) {
TRACE_WARNING(
"RBC_RequestSense: Cannot start sending data\n\r");
result = MSDD_STATUS_ERROR;
}
else {
// Change state
commandState->state = SBC_STATE_WAIT_WRITE;
}
break;
//------------------------
case SBC_STATE_WAIT_WRITE:
//------------------------
// Check the transfer semaphore
if (transfer->semaphore > 0) {
// Take semaphore and finish command
transfer->semaphore--;
if (transfer->status != USBD_STATUS_SUCCESS) {
result = MSDD_STATUS_ERROR;
}
else {
result = MSDD_STATUS_SUCCESS;
}
// Update length
commandState->length -= transfer->transferred;
}
break;
}
return result;
}
//------------------------------------------------------------------------------
//! \brief Performs a MODE SENSE (6) command.
//!
//! This function operates asynchronously and must be called multiple
//! times to complete. A result code of MSDDriver_STATUS_INCOMPLETE
//! indicates that at least another call of the method is necessary.
//! \param lun Pointer to the LUN affected by the command
//! \param commandState Current state of the command
//! \return Operation result code (SUCCESS, ERROR, INCOMPLETE or PARAMETER)
//! \see MSDLun
//! \see MSDCommandState
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -