/******************************************************************************
*
*  System Name : ARM USB Mass Storage Library
*  File Name   : usb0_hmscd_api.c
*  Contents    : API functions for USB Mass Storage Class Driver
*  Version     : 0.00.01
*  Device      : ARM
*  Tool-Chain  :
*  OS          :
*
*  Note        :
*
*  Copyright (C) 2014 Renesas Electronics Corporation and
*  Renesas Solutions Corp. All rights reserved.
*
*  History     : Feb.12,2014 Ver.0.00.01
******************************************************************************/


/*******************************************************************************
Includes   <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb_hmscd_rza1.h"
#include "usb0_hmscd.h"


/*******************************************************************************
Typedef definitions
*******************************************************************************/


/*******************************************************************************
Macro definitions
*******************************************************************************/


/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/
extern int32_t     usb0_class_ClearStall( uint16_t device_address, uint16_t Pipe, uint32_t time_out );


/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/


/*******************************************************************************
Private global variables and functions
*******************************************************************************/
static void        usb0_hmscd_init( uint16_t device_address );
static int32_t     usb0_hmscd_check( uint16_t device_address, uint8_t *ConfigDesctable,
                                     uint16_t interface_index, uint16_t interface_alt,
                                     uint16_t set_interface_flag );
static int32_t     usb0_hmscd_read10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus );
static int32_t     usb0_hmscd_write10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus );
static int32_t     usb0_hmscd_get_max_lun( uint16_t device_address, uint16_t interface, uint8_t *max_lun );
static int32_t     usb0_hmscd_mass_storage_reset( uint16_t device_address, uint16_t interface );


/*******************************************************************************
* Function Name: usb0_api_hmscd_registration
* Description  : Registers the I/O buffer area specified by the argument regist.
* Arguments    : uint16_t device_address     : Device address
*              : USB_HMSCD_REGIST_t  *regist : I/O buffer area address for
*              :                             : host mass storage class driver
*              :                             : Message time-out time from HCD
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*******************************************************************************/
int32_t usb0_api_hmscd_registration( uint16_t device_address, USB_HMSCD_REGIST_t *regist )
{
    if(device_address == 0)
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    if(device_address < (USB_HMSCD_MAX_ADDRESS + 1))
    {
        g_usb0_hmscd_global[ device_address ].mscd_regist = regist;
        return USB_HMSCD_SUCCESS;
    }

    return USB_HMSCD_DEV_ADDR_ERR;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_open
* Description  : Checks the information of the connected device specified by the argument.
*              : If it is correct, changes the device status to attached device and
*              : returns USB_HMSCD_SUCCESS as return value. If there is an error,
*              : USB_HMSCD_ERROR is returned.
* Arguments    : uint16_t device_address     : Device address
*              : uint16_t *config            : ConfigurationDescriptor information table storage address
*              : uint16_t interface_index    : InterfaceDescriptor information table index
*              : uint16_t interface_alt      : Alternative setting value of interface number
*              : uint16_t set_interface_flag : Execution flag for SetInterface
*              :                             : USB_HMSCD_YES : Execute SetInterface
*              :                             : USB_HMSCD_NO  : Do not execute SetInterface
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_open( uint16_t device_address,
                             uint16_t *config,
                             uint16_t interface_index,
                             uint16_t interface_alt,
                             uint16_t set_interface_flag )
{
    int32_t    ret;

    if( usb0_hmscd_get_dev_sts(device_address) == USB_HMSCD_DEV_DET )
    {
        ret = usb0_userdef_os_create_sem( (uint32_t)(USB_HMSCD + device_address) );
        if( ret != USB_HMSCD_SUCCESS )
        {
            return USB_HMSCD_ERROR;
        }

        ret = usb0_userdef_os_create_mbx( (uint32_t)(USB_HMSCD + device_address) );
        if( ret != USB_HMSCD_SUCCESS )
        {
            return USB_HMSCD_ERROR;
        }

        ret = usb0_hmscd_check( device_address,
                                (uint8_t *)config,
                                interface_index,
                                interface_alt,
                                set_interface_flag );
        if( ret == USB_HMSCD_SUCCESS )
        {
            usb0_hmscd_init(device_address);
            usb0_hmscd_set_dev_sts( device_address, (uint16_t)USB_HMSCD_DEV_ATT );
        }
    }
    else
    {
        ret = USB_HMSCD_DEV_ADDR_ERR;
    }

    return ret;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_close
* Description  : Changes the device status to detached device and sets USB_HMSCD_SUCCESS
*              : for the return value.
* Arguments    : uint16_t device_address : Host USB device address
* Return Value : int32_t USB_HMSCD_SUCCESS      : Normal end
*              :         USB_HMSCD_ERROR        : Port error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*******************************************************************************/
int32_t usb0_api_hmscd_close( uint16_t device_address )
{
    int32_t    ret;

    if( usb0_hmscd_get_dev_sts(device_address) == USB_HMSCD_DEV_ATT )
    {
        ret = usb0_userdef_os_delete_mbx( (uint32_t)(USB_HMSCD + device_address) );
        if( ret != USB_HMSCD_SUCCESS )
        {
            return USB_HMSCD_ERROR;
        }

        usb0_hmscd_set_dev_sts( device_address, (uint16_t)USB_HMSCD_DEV_DET );
    }
    else
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    return USB_HMSCD_SUCCESS;
}

/******************************************************************************
* Function Name: usb0_api_hmscd_get_max_unit
* Description  : Obtains the maximum logical unit number of the device specified by
*              : the argument device_address and returns it to the argument maxunit.
*              : When this function is called in a state except that the device status
*              : is attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned.
* Arguments    : uint16_t device_address : Host USB device address
*              : uint8_t  *maxunit       : Max value of logical unit number
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*****************************************************************************/
int32_t usb0_api_hmscd_get_max_unit( uint16_t device_address, uint8_t *maxunit )
{
    int32_t    ret;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        *maxunit = 0;
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    ret = usb0_hmscd_get_max_lun( device_address,
                                  g_usb0_hmscd_global[ device_address ].interface_num,
                                  maxunit );
    if( ret != USB_HMSCD_SUCCESS )
    {
        *maxunit = 0;
    }

    return ret;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_mass_storage_reset
* Description  : Resets the mass storage of the device specified by the argument device_address.
*              : When this function is called in the state except that the device status is
*              : attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned.
* Arguments    : uint16_t device_address : Host USB device address
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_mass_storage_reset( uint16_t device_address )
{
    int32_t    ret;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    ret = usb0_hmscd_mass_storage_reset( device_address, g_usb0_hmscd_global[ device_address ].interface_num );

    return ret;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_stall_recovery
* Description  : Resets the mass storage of the device specified by the argument
*              : device_address and executes the I/O pipe CLEAR STALL processing.
*              : This function is called only when the return value of the
*              : HMSCD API function is STALL. The STALL state is cleared.
*              : When this function is called in a state except that the device status
*              : is attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned. In
*              : other cases, USB_HMSCD_SUCCESS is returned.
* Arguments    : uint16_t device_address : Host USB device address
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*******************************************************************************/
int32_t usb0_api_hmscd_stall_recovery( uint16_t device_address )
{
    uint32_t    time_out;
    int32_t     mscd_retval;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    usb0_hmscd_mass_storage_reset( device_address, g_usb0_hmscd_global[ device_address ].interface_num );

    mscd_retval = usb0_userdef_os_twai_sem( (uint32_t)(USB_HMSCD + device_address),
                                            (uint32_t)g_usb0_hmscd_global[ device_address ].mscd_regist->time_out );
    if(mscd_retval != USB_HMSCD_SUCCESS)
    {
        if(mscd_retval == USB_HMSCD_ERROR)
        {
            return USB_HMSCD_TIMEOUT;
        }
        else
        {
            return USB_HMSCD_ERROR;
        }
    }

    mscd_retval = usb0_api_hcd_change_endpoint( g_usb0_hmscd_global[ device_address ].mscd_regist->pipe_table,
                                                USB_PIPE_TBL_END );
    if( mscd_retval != USB_HMSCD_SUCCESS )
    {
        usb0_userdef_os_sig_sem( (uint32_t)(USB_HMSCD + device_address) );
        return    mscd_retval;
    }

    time_out = g_usb0_hmscd_global[ device_address ].mscd_regist->time_out;
    usb0_class_ClearStall( device_address, g_usb0_hmscd_global[ device_address ].mscd_out_pipe, time_out );
    usb0_class_ClearStall( device_address, g_usb0_hmscd_global[ device_address ].mscd_in_pipe,  time_out );

    usb0_userdef_os_sig_sem( (uint32_t)(USB_HMSCD + device_address) );

    return USB_HMSCD_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_read10
* Description  : Executes the READ10 command by using the parameter of the argument
*              : mscd_rw and reads the data of the specified sector.
*              : The read data is stored in the mscd_rw member buffer. The byte count
*              : of the read data and the received CSW status are stored in the arguments
*              : bytes and the csw_status respectively.
*              : When this function is called in a state except that the device status
*              : is attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned.
* Arguments    : USB_HMSCD_RW_t *mscd_rw : Read/Write parameter information
*              : uint32_t *bytes         : Byte count of the data actually read
*              : uint8_t *cswstatus      : CSW status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_read10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus )
{
    int32_t     ret;
    uint16_t    device_address;

    device_address = mscd_rw->device_address;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    ret = usb0_hmscd_read10( mscd_rw, bytes, cswstatus );

    return ret;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_write10
* Description  : Executes the WRITE10 command by using the parameter of the argument
*              : mscd_rw and writes the data in mscd_rw member buffer to the specified
*              : sector. The byte count of the written data and the received CSW status are
*              : stored in the arguments bytes and the csw_status respectively.
*              : When this function is called in a state except that the device status
*              : is attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned.
* Arguments    : USB_HMSCD_RW_t  *mscd_rw : Read/Write parameter information
*              : uint32_t *bytes          : Byte count of the data actually written
*              : uint8_t *cswstatus       : CSW status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_write10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus )
{
    int32_t     ret;
    uint16_t    device_address;

    device_address = mscd_rw->device_address;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    ret = usb0_hmscd_write10( mscd_rw, bytes, cswstatus );

    return ret;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_test_unit
* Description  : Issues the TEST UNIT READY command to the specified unit in the
*              : specified device.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t unit_number    : Unit number
*              : uint8_t *cswstatus      : CSW status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_test_unit( uint16_t device_address,
                                  uint16_t unit_number, uint8_t *cswstatus )
{
    int32_t                  mscd_retval;
    uint8_t                  data[16];
    uint32_t                 bytes;
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    /* data set */
    data[0] = USB_HMSCD_CMD_TEST_UNIT_READY;    /* command */
    data[1] = 0x00;                             /* set LUN */
    data[2] = 0x00;                             /* reserved */
    data[3] = 0x00;                             /* reserved */
    data[4] = 0x00;
    data[5] = 0x00;                             /* vender definition */
    data[6] = 0x00;                             /* vender definition */
    data[7] = 0x00;                             /* vender definition */
    data[8] = 0x00;                             /* vender definition */
    data[9] = 0x00;                             /* vender definition */
    data[10] = 0x00;                            /* vender definition */
    data[11] = 0x00;                            /* vender definition */

    mscd_user_ctrl.device_address = device_address;
    mscd_user_ctrl.unit_number    = unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 6;
    mscd_user_ctrl.dir            = 0;
    mscd_user_ctrl.buffer         = ( uint8_t* )NULL;
    mscd_user_ctrl.transfer_bytes = 0;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, &bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_request_sense
* Description  : Issues the REQUEST SENSE command to the specified unit in the
*              : specified device.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t unit_number    : Unit number
*              : uint32_t *bytes         : Byte count of the sense data actually obtained
*              : uint8_t *cswstatus      : CSW status
*              : uint8_t *buffer         : Address to store the read sense data
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_request_sense( uint16_t device_address, uint16_t unit_number,
                                      uint32_t *bytes, uint8_t *cswstatus, uint8_t *buffer )
{
    int32_t                  mscd_retval;
    uint8_t                  data[16];
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    /* data set */
    data[0] = USB_HMSCD_CMD_REQUEST_SENSE;    /* command */
    data[1] = 0x00;                           /* set LUN */
    data[2] = 0x00;                           /* reserved */
    data[3] = 0x00;                           /* reserved */
    data[4] = 18;                             /* Allocation length */
    data[5] = 0x00;                           /* vender definition */
    data[6] = 0x00;                           /* vender definition */
    data[7] = 0x00;                           /* vender definition */
    data[8] = 0x00;                           /* vender definition */
    data[9] = 0x00;                           /* vender definition */
    data[10] = 0x00;                          /* vender definition */
    data[11] = 0x00;                          /* vender definition */

    mscd_user_ctrl.device_address = device_address;
    mscd_user_ctrl.unit_number    = unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 6;
    mscd_user_ctrl.dir            = 0;
    mscd_user_ctrl.buffer         = buffer;
    mscd_user_ctrl.transfer_bytes = 18;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_inquiry
* Description  : Issues the INQUIRY command to the specified unit in the
*              : specified device.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t unit_number    : Unit number
*              : uint32_t *bytes         : Byte count of the INQUIRY data actually obtained
*              : uint8_t *cswstatus      : CSW status
*              : uint8_t *buffer         : Address to store the read INQUIRY data
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_inquiry( uint16_t device_address, uint16_t unit_number,
                                uint32_t *bytes, uint8_t *cswstatus, uint8_t *buffer )
{
    int32_t                  mscd_retval;
    uint8_t                  data[16];
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    /* data set */
    data[0] = USB_HMSCD_CMD_INQUIRY;    /* command */
    data[1] = 0x00;                     /* set LUN */
    data[2] = 0x00;                     /* reserved */
    data[3] = 0x00;                     /* reserved */
    data[4] = 36;                       /* Allocation length */
    data[5] = 0x00;                     /* vender definition */
    data[6] = 0x00;                     /* vender definition */
    data[7] = 0x00;                     /* vender definition */
    data[8] = 0x00;                     /* vender definition */
    data[9] = 0x00;                     /* vender definition */
    data[10] = 0x00;                    /* vender definition */
    data[11] = 0x00;                    /* vender definition */

    mscd_user_ctrl.device_address = device_address;
    mscd_user_ctrl.unit_number    = unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 6;
    mscd_user_ctrl.dir            = 0;
    mscd_user_ctrl.buffer         = buffer;
    mscd_user_ctrl.transfer_bytes = 36;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_read_capacity
* Description  : Issues the READ_CAPACITY command to the specified unit in the
*              : specified device.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t unit_number    : Unit number
*              : uint32_t *bytes         : Byte count of the READ_CAPACITY data actually obtained
*              : uint8_t *cswstatus      : CSW status
*              : uint8_t *buffer         : Address to store the read CAPACITY data
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_read_capacity( uint16_t device_address, uint16_t unit_number,
                                      uint32_t *bytes, uint8_t *cswstatus, uint8_t *buffer )
{
    int32_t                  mscd_retval;
    uint8_t                  data[16];
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    /* data set */
    data[0] = USB_HMSCD_CMD_READ_CAPACITY;    /* command */
    data[1] = 0x00;                           /* set LUN */
    data[2] = 0x00;                           /* reserved */
    data[3] = 0x00;                           /* reserved */
    data[4] = 0x00;
    data[5] = 0x00;                           /* vender definition */
    data[6] = 0x00;                           /* vender definition */
    data[7] = 0x00;                           /* vender definition */
    data[8] = 0x00;                           /* vender definition */
    data[9] = 0x00;                           /* vender definition */
    data[10] = 0x00;                          /* vender definition */
    data[11] = 0x00;                          /* vender definition */

    mscd_user_ctrl.device_address = device_address;
    mscd_user_ctrl.unit_number    = unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 10;    /* Command bytes*/
    mscd_user_ctrl.dir            = 0;
    mscd_user_ctrl.buffer         = buffer;
    mscd_user_ctrl.transfer_bytes = 8;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_unit_search
* Description  : Searches the status of the unit number of the device specified by
*              : the argument device_address.
*              : Checks the usable unit by issuing TEST UNIT READY command.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t unit_number    : unit number storage address
*              : uint16_t retry_count    : retry count
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*              :         USB_HMSCD_BUSY         : USB device busy
*******************************************************************************/
int32_t usb0_api_hmscd_unit_search( uint16_t device_address, uint16_t unit_number, uint16_t retry_count )
{
    uint16_t    retry;
    int32_t     ret;
    uint32_t    bytes;
    uint8_t     cswstatus;
    uint8_t     *ascq;

    for( retry = 0; retry < retry_count; retry++ )
    {
        ret = usb0_api_hmscd_test_unit( device_address, unit_number, &cswstatus );
        if( ret != USB_HMSCD_SUCCESS )
        {
            return ret;
        }

        if( cswstatus == USB_HMSCD_CSW_PASS )
        {
            return USB_HMSCD_SUCCESS ;
        }

        if( cswstatus == USB_HMSCD_CSW_FAIL )
        {
            usb0_userdef_os_dly_tsk( 100 );
            ret = usb0_api_hmscd_request_sense( device_address,
                                                unit_number,
                                                &bytes,
                                                &cswstatus,
                                                (uint8_t *)&g_usb0_hmscd_work[ device_address ] );
            if( ret != USB_HMSCD_SUCCESS )
            {
                return ret;
            }

            if( cswstatus == USB_HMSCD_CSW_PASS )
            {
                ascq = ( uint8_t* )&g_usb0_hmscd_work[ device_address ];
                if( (ascq[ 12 ] == 0x3A) && (ascq[ 13 ] == 0x00) )
                {
                    return USB_HMSCD_NO_MEDIA;
                }
            }
            else
            {
                /* Phase Error -> ret=USB_HMSCD_SUCCESS_CSW_PHASE_ERROR->USB_HMSCD_ERROR    */
            }
        }
        else
        {
            /* Phase Error -> ret=USB_HMSCD_SUCCESS_CSW_PHASE_ERROR->USB_HMSCD_ERROR        */
        }

        usb0_userdef_os_dly_tsk( 100 );
    }

    return USB_HMSCD_BUSY;
}

/*******************************************************************************
* Function Name: usb0_api_hmscd_user_ctrl
* Description  : Executes the CBW transmission, the data transmission/reception, and
*              : the CSW reception to the specified device by using the user command
*              : parameter specified by the argument mscd_user_ctrl.
*              : The device and the data transmission/reception are all specified by the
*              : user command parameter.
*              : When this function is called in a state except that the device status
*              : is attached (USB_HMSCD_DEV_ATT), USB_HMSCD_DEV_ADDR_ERR is returned.
* Arguments    : USB_HMSCD_USER_CTRL_t *mscd_user_ctrl : User command parameter
*              : uint32_t *bytes                       : Byte count of the data actually processed
*              : uint8_t  *cswstatus                   : CSW command status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
int32_t usb0_api_hmscd_user_ctrl( USB_HMSCD_USER_CTRL_t *mscd_user_ctrl,
                                  uint32_t *bytes, uint8_t *cswstatus )
{
    uint16_t    i;
    uint8_t     *ptr;
    int32_t     mscd_retval;
    uint16_t    device_address;

    device_address = mscd_user_ctrl->device_address;

    if( usb0_hmscd_get_dev_sts(device_address) != USB_HMSCD_DEV_ATT )
    {
        return USB_HMSCD_DEV_ADDR_ERR;
    }

    mscd_retval = usb0_userdef_os_twai_sem( (uint32_t)(USB_HMSCD + device_address),
                                            (uint32_t)g_usb0_hmscd_global[ device_address ].mscd_regist->time_out );
    if(mscd_retval != USB_HMSCD_SUCCESS)
    {
        if(mscd_retval == USB_HMSCD_ERROR)
        {
            return USB_HMSCD_TIMEOUT;
        }
        else
        {
            return USB_HMSCD_ERROR;
        }
    }

    mscd_retval = usb0_api_hcd_change_endpoint( g_usb0_hmscd_global[ device_address ].mscd_regist->pipe_table,
                                                USB_PIPE_TBL_END );
    if( mscd_retval != USB_HMSCD_SUCCESS )
    {
        usb0_userdef_os_sig_sem( (uint32_t)(USB_HMSCD + device_address) );
        return mscd_retval;
    }

    g_usb0_hmscd_cbw[device_address].cbw_tag       = (uint8_t)g_usb0_hmscd_global[device_address].cbw_tag;
    g_usb0_hmscd_cbw[device_address].cbw_length_lo = (uint8_t)(mscd_user_ctrl->transfer_bytes      );
    g_usb0_hmscd_cbw[device_address].cbw_length_ml = (uint8_t)(mscd_user_ctrl->transfer_bytes >> 8 );
    g_usb0_hmscd_cbw[device_address].cbw_length_mh = (uint8_t)(mscd_user_ctrl->transfer_bytes >> 16);
    g_usb0_hmscd_cbw[device_address].cbw_length_hi = (uint8_t)(mscd_user_ctrl->transfer_bytes >> 24);
    g_usb0_hmscd_cbw[device_address].cbw_lun       = (uint8_t)mscd_user_ctrl->unit_number;
    g_usb0_hmscd_cbw[device_address].cbw_cb_length = (uint8_t)mscd_user_ctrl->cmd_bytes;

    ptr = ( uint8_t* )mscd_user_ctrl->command;
    for( i = 0; i < mscd_user_ctrl->cmd_bytes; ++i )
    {
        g_usb0_hmscd_cbw[device_address].cbw_cb[i] = ptr[i];
    }
    for( ; i < 16; ++i )
    {
        g_usb0_hmscd_cbw[device_address].cbw_cb[i] = 0;
    }

    if( mscd_user_ctrl->transfer_bytes == 0 )
    {
        g_usb0_hmscd_cbw[device_address].b7CBWFlags = (uint8_t)(0 << 7);
        mscd_retval = usb0_hmscd_no_data( mscd_user_ctrl->device_address,bytes,cswstatus );
    }
    else
    {
        if( mscd_user_ctrl->dir == 0 )
        {
            g_usb0_hmscd_cbw[device_address].b7CBWFlags = (uint8_t)(1 << 7);
            mscd_retval = usb0_hmscd_data_in( mscd_user_ctrl->device_address,
                                              (uint8_t *)mscd_user_ctrl->buffer,
                                              mscd_user_ctrl->transfer_bytes,bytes,cswstatus );
        }
        else
        {
            g_usb0_hmscd_cbw[device_address].b7CBWFlags = (uint8_t)(0 << 7);
            mscd_retval = usb0_hmscd_data_out( mscd_user_ctrl->device_address,
                                               (uint8_t *)mscd_user_ctrl->buffer,
                                               mscd_user_ctrl->transfer_bytes,bytes,cswstatus );
        }
    }

    usb0_userdef_os_sig_sem( (uint32_t)(USB_HMSCD + device_address) );

    if( ( mscd_retval == USB_HMSCD_STALL                   ) ||
        ( mscd_retval == USB_HMSCD_SUCCESS_CSW_PHASE_ERROR ) ||
        ( mscd_retval == USB_HMSCD_TAGERR                  )    )
    {
        usb0_api_hmscd_stall_recovery( mscd_user_ctrl->device_address );
    }

    return mscd_retval;
}










/*==============================================================================*/
/*                                                                              */
/*                              User disabled functions                         */
/*                                                                              */
/*==============================================================================*/

/*******************************************************************************
* Function Name: usb0_hmscd_init
* Description  : Initializes the mass storage control driver management area.
* Arguments    : uint16_t device_address : Device address
* Return Value : none
*******************************************************************************/
static void usb0_hmscd_init( uint16_t device_address )
{
    usb0_hmscd_cbw_init( device_address );
}

/*******************************************************************************
* Function Name: usb0_hmscd_check
* Description  : Checks the device information stored in the area specified by the
*              : argument table, and returns the check result.
* Arguments    : uint16_t device_address     : Device address
*              : uint8_t  *ConfigDesctable   : ConfigurationDescriptor information table storage address
*              : uint16_t interface_index    : InterfaceDescriptor information table index
*              : uint16_t interface_alt      : Alternative setting value of interface number
*              : uint16_t set_interface_flag : Execution flag for SetInterface
*              :                             : USB_HMSCD_YES : Execute SetInterface
*              :                             : USB_HMSCD_NO  : Do not execute SetInterface
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
static int32_t usb0_hmscd_check( uint16_t device_address, uint8_t *ConfigDesctable,
                                 uint16_t interface_index, uint16_t interface_alt,
                                 uint16_t set_interface_flag )
{
    uint8_t     InterfaceNum;
    uint8_t     *InterfaceDescTable = (uint8_t *)0;
    uint16_t    offset;
    int32_t     ret;
    uint16_t    TotalLength;

    InterfaceNum = ConfigDesctable[ 4 ];

    offset      = 0;
    TotalLength = (uint16_t)(ConfigDesctable[ 2 ] + ((uint16_t)ConfigDesctable[3] << 8));

    while( offset < TotalLength )
    {

        if( ( ConfigDesctable[ offset + 1 ] == USB_DT_INTERFACE )
            && ( ConfigDesctable[ offset + 2 ] == interface_index )
            && ( ConfigDesctable[ offset + 3 ] == interface_alt )         )
        {
            /* Find Interface Descriptor */
            InterfaceDescTable = ( uint8_t* )&ConfigDesctable[ offset ];
            break;
        }
        if(ConfigDesctable[ offset ] == 0)
        {
            break;
        }

        offset +=  ConfigDesctable[ offset ];
    }

    /* Cannot find Interface Descriptor */
    if(InterfaceDescTable == (uint8_t *)0)
    {
        return USB_HMSCD_TYPE_ERROR;
    }

    ret = usb0_hmscd_check_bot_descriptor( device_address, InterfaceDescTable );
    if( ret != USB_HMSCD_SUCCESS )
    {
        return USB_HMSCD_TYPE_ERROR;
    }

    ret = usb0_api_class_SetConfiguration( device_address, ( uint8_t )ConfigDesctable[5] );
    if( ret != USB_HMSCD_SUCCESS )
    {
        return ret;
    }

    if( set_interface_flag == USB_HMSCD_YES )
    {
        ret = usb0_api_class_SetInterface( device_address, interface_alt, interface_index );
        if( ret != USB_HMSCD_SUCCESS )
        {
            if( ret != USB_HMSCD_STALL )
            {
                return ret;
            }

            if( InterfaceNum != 1 )
            {
                /* If Interface Number is 1, ignore SetInterface Error */
                return ret;
            }
        }
    }

    /* Pipe Information table set */
    ret = usb0_hmscd_pipe_info( device_address,
                                InterfaceDescTable,
                                (uint16_t)(TotalLength - offset) );
    if( ret != USB_HMSCD_SUCCESS )
    {
        return USB_HMSCD_TYPE_ERROR;
    }

    /* Keep Interface Number to issue Mass Storage Reset/Get Max LUN */
    g_usb0_hmscd_global[ device_address ].interface_num = interface_index;

    return USB_HMSCD_SUCCESS;
}

/*====================    Mass Storage Device Class command    ====================*/
/*******************************************************************************
* Function Name: usb0_hmscd_read10
* Description  : Creates and issues the READ10 command based on the argument mscd_rw.
*              : The byte count of the received data and the received CSW status are
*              : stored in the arguments bytes and the csw_status respectively.
* Arguments    : USB_HMSCD_RW_t  *mscd_rw : Read/write parameter information
*              : uint32_t *bytes          : Byte count of the data required to be read
*              : uint8_t *cswstatus       : CSW status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
static int32_t usb0_hmscd_read10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus )
{
    int32_t                  mscd_retval;
    uint8_t                  data[16];
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    data[0] = (uint8_t)USB_HMSCD_CMD_READ10;              /* ATAPI_COMMAND  */
    data[1] = 0;                                          /* Unit Number    */
    data[2] = (uint8_t)(mscd_rw->sector_number >> 24);    /* sector address */
    data[3] = (uint8_t)(mscd_rw->sector_number >> 16);
    data[4] = (uint8_t)(mscd_rw->sector_number >>  8);
    data[5] = (uint8_t)mscd_rw->sector_number;
    data[6] = 0x00;                                       /* reserved       */
    data[7] = (uint8_t)(mscd_rw->sector_count  >>  8);    /* sector length  */
    data[8] = (uint8_t)mscd_rw->sector_count;             /* block address  */
    data[9] = (uint8_t)0x00;                              /* control data   */

    mscd_user_ctrl.device_address = mscd_rw->device_address;
    mscd_user_ctrl.unit_number    = mscd_rw->unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 10;
    mscd_user_ctrl.dir            = 0;
    mscd_user_ctrl.buffer         = mscd_rw->buffer;
    mscd_user_ctrl.transfer_bytes = mscd_rw->transfer_bytes;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_hmscd_write10
* Description  : Creates and issues the WRITE10 command based on the argument mscd_rw.
*              : The byte count of the transmitted data and the received CSW status are
*              : stored in the arguments byte and csw_status respectively.
* Arguments    : USB_HMSCD_RW_t  *mscd_rw : Read/write parameter information
*              : uint32_t *bytes          : Byte count of the data required to be written
*              : uint8_t *cswstatus       : CSW status
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
static int32_t usb0_hmscd_write10( USB_HMSCD_RW_t *mscd_rw, uint32_t *bytes, uint8_t *cswstatus )
{
    int32_t                   mscd_retval;
    uint8_t                   data[16];
    USB_HMSCD_USER_CTRL_t    mscd_user_ctrl;

    data[0] = (uint8_t)USB_HMSCD_CMD_WRITE10;             /* ATAPI_COMMAND  */
    data[1] = 0;                                          /* Unit Number    */
    data[2] = (uint8_t)(mscd_rw->sector_number >> 24);    /* sector address */
    data[3] = (uint8_t)(mscd_rw->sector_number >> 16);
    data[4] = (uint8_t)(mscd_rw->sector_number >>  8);
    data[5] = (uint8_t)mscd_rw->sector_number;
    data[6] = 0x00;                                       /* reserved       */
    data[7] = (uint8_t)(mscd_rw->sector_count  >>  8);    /* sector length  */
    data[8] = (uint8_t)mscd_rw->sector_count;             /* block address  */
    data[9] = (uint8_t)0x00;                              /* control data   */

    mscd_user_ctrl.device_address = mscd_rw->device_address;
    mscd_user_ctrl.unit_number    = mscd_rw->unit_number;
    mscd_user_ctrl.command        = data;
    mscd_user_ctrl.cmd_bytes      = 10;
    mscd_user_ctrl.dir            = 1;
    mscd_user_ctrl.buffer         = mscd_rw->buffer;
    mscd_user_ctrl.transfer_bytes = mscd_rw->transfer_bytes;

    mscd_retval = usb0_api_hmscd_user_ctrl( &mscd_user_ctrl, bytes, cswstatus );

    return mscd_retval;
}

/*******************************************************************************
* Function Name: usb0_hmscd_get_max_lun
* Description  : Sends the class request GETMAXLUN to the device specified by the
*              : argument device_address, and returns the maximum unit number obtained
*              : from the device as return value.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t interface      : Interface number
*              : uint8_t  *max_lun       : Maximum number of units
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
static int32_t usb0_hmscd_get_max_lun( uint16_t device_address, uint16_t interface, uint8_t *max_lun )
{
    uint16_t    Req_Table[ 4 ];
    int32_t     ret;

    Req_Table[ 0 ] = USB_HMSCD_MASS_STORAGE_GET_MAX_LUN;
    Req_Table[ 1 ] = 0x0000;
    Req_Table[ 2 ] = interface;
    Req_Table[ 3 ] = 1;

    ret = usb0_api_class_request( device_address, &Req_Table[ 0 ], max_lun );
    if( ret != USB_HMSCD_SUCCESS )
    {
        return ret;
    }

    return USB_HMSCD_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_hmscd_mass_storage_reset
* Description  : Sends the class request MASS STORAGE RESET to the device specified
*              : by the argument device_address.
* Arguments    : uint16_t device_address : Device address
*              : uint16_t interface      : Interface number
* Return Value : int32_t USB_HMSCD_SUCCESS      : Success of standard request
*              :         USB_HMSCD_ERROR        : Error end
*              :         USB_HMSCD_TIMEOUT      : Time-out error
*              :         USB_HMSCD_STALL        : Stall error
*              :         USB_HMSCD_DETACH       : Detach error
*              :         USB_HMSCD_SETUP_ERR    : Setup stage error
*              :         USB_HMSCD_CTRL_COM_ERR : USB communication error
*              :         USB_HMSCD_TYPE_ERROR   : Device type error
*              :         USB_HMSCD_DEV_ADDR_ERR : Device address error
*              :         USB_HMSCD_NAK_TIMEOUT  : Time-out error (Device response)
*******************************************************************************/
static int32_t usb0_hmscd_mass_storage_reset( uint16_t device_address, uint16_t interface )
{
    uint16_t    Req_Table[ 4 ];
    int32_t     ret;
    uint8_t     dummy;

    Req_Table[ 0 ] = USB_HMSCD_MASS_STORAGE_RESET;
    Req_Table[ 1 ] = 0x0000;
    Req_Table[ 2 ] = interface;
    Req_Table[ 3 ] = 0;

    ret = usb0_api_class_request( device_address, &Req_Table[ 0 ], &dummy );
    if( ret != USB_HMSCD_SUCCESS )
    {
        return ret;
    }

    return USB_HMSCD_SUCCESS;
}

/* End of File */
