/**
 * @file hv_drv_UsbFatfsDiskIo.c
 * @brief Low level disk I/O module skeleton for FatFs
 * @details If a working storage control module is available, it should be
 *          attached to the FatFs via a glue function rather than modifying it.
 *          This is an example of glue functions to attach various exsisting
 *          storage control modules to the FatFs module with a defined API.
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20230417
 * @copyright Copyright(c),2022-9, Hiview Software. All rights reserved.
 * @par History:
 * <table>
 * <tr><th>Author                         <th>Date             <th>Details
 * <tr><td>HiView SoC Software Team   <td>20230417       <td>Create and first Version.
 * </table>
 **/

#include "hv_drv_UsbFatfs.h"            /* Obtains integer types */
#include "hv_drv_UsbFatfsDiskIo.h"      /* Declarations of disk functions */

#include "hv_drv_UsbCorePlatform.h"
#include "hv_drv_UsbPortingTypes.h"
#include "hv_drv_UsbCoreHub.h"
#include "hv_drv_UsbPortingOsDisk.h"


/* Definitions of physical drive number for each drive */
#define DEV_RAM        0    /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC        1    /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB        2    /* Example: Map USB MSD to physical drive 2 */



int USB_disk_write(const BYTE *buff, LBA_t  sector, UINT count)
{
    int RET = 0;
    return get_scsi_disk_channel()->funs->write(get_scsi_disk_channel(),buff,count,sector);
}

int USB_disk_read(BYTE *buff, LBA_t  sector, UINT count)
{
    int RET = 0;
    return get_scsi_disk_channel()->funs->read(get_scsi_disk_channel(),buff,count,sector);
}

int USB_disk_initialize(void)
{
    int RET = 0;

    //Hv_Vos_MSleep(3000);
    USB_LOGV("USB_disk_initialize->hub_port_check");
    hub_port_check(usb_get_hub());
    return RET;
}

int RAM_disk_write(const BYTE *buff, LBA_t  sector, UINT count)
{
    int RET = 0;

    return RET;
}

int RAM_disk_read(const BYTE *buff, LBA_t  sector, UINT count)
{
    int RET = 0;

    return RET;
}

DSTATUS USB_disk_status(void)
{
    DSTATUS RET = 0;

    return RET;
}

DSTATUS RAM_disk_status(void)
{
    return 0;
}

int RAM_disk_initialize(void)
{
    int RET = 0;

    return RET;
}

DSTATUS MMC_disk_status(void)
{
    return 0;
}

int MMC_disk_initialize(void)
{
    int RET = 0;

    return RET;
}


/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
    BYTE pdrv        /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat = STA_NOINIT;

    switch (pdrv) {
    case DEV_RAM :
        stat = RAM_disk_status();
        break;
    case DEV_MMC :
        stat = MMC_disk_status();
        break;
    case DEV_USB :
        stat = USB_disk_status();
    default:
        break;
    }

    return stat;
}

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
    BYTE pdrv                /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat;
    int result;

    switch (pdrv) {
    case DEV_RAM :

    case DEV_MMC :

    case DEV_USB :
        result = USB_disk_initialize();
        return RES_OK;
    }
    return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
    BYTE pdrv,        /* Physical drive nmuber to identify the drive */
    BYTE *buff,        /* Data buffer to store read data */
    LBA_t sector,    /* Start sector in LBA */
    UINT count        /* Number of sectors to read */
)
{
    DRESULT res;
    int result;

    switch (pdrv) {
    case DEV_RAM :
        // translate the arguments here

    case DEV_MMC :
        // translate the arguments here

    case DEV_USB :
        // translate the arguments here
        result = USB_disk_read(buff, sector, count);

        if(!result)
            res = RES_OK;
        else
            res = (DRESULT)result;
        return res;
    }

    return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
    BYTE pdrv,            /* Physical drive nmuber to identify the drive */
    const BYTE *buff,    /* Data to be written */
    LBA_t sector,        /* Start sector in LBA */
    UINT count            /* Number of sectors to write */
)
{
    DRESULT res;
    int result;

    switch (pdrv) {
    case DEV_RAM :
        // translate the arguments here

    case DEV_MMC :
        // translate the arguments here

    case DEV_USB :
        // translate the arguments here

        result = USB_disk_write(buff, sector, count);

        if(!result)
            res = RES_OK;
        else
            res = (DRESULT)result;
        return res;
    }

    return RES_PARERR;
}

#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
    BYTE pdrv,        /* Physical drive nmuber (0..) */
    BYTE cmd,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
)
{
    DRESULT res = RES_OK;
    //int result;

    switch (pdrv) {
    case DEV_RAM :
        // Process of the command for the RAM drive

        return res;

    case DEV_MMC :
        // Process of the command for the MMC/SD card

        return res;

    case DEV_USB :
        // Process of the command the USB drive

        return res;
    }

    return RES_PARERR;
}





