⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbc_methods.c

📁 This software package contains the USB framework core developped by ATMEL, as well as a Mass stora
💻 C
📖 第 1 页 / 共 3 页
字号:
                                    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 + -