/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author: dtvbm11 $
 * $Date: 2015/11/10 $
 * $RCSfile: storage_if.h,v $
 * $Revision: #1 $
 *
 *---------------------------------------------------------------------------*/

/** @file storage_if.h
 *  storage_if.h The Storage devices upper layer interface header file.
 */

#ifndef STORAGE_IF_H
#define STORAGE_IF_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#include "x_lint.h"

LINT_EXT_HEADER_BEGIN
#include "x_typedef.h"
#include "x_os.h"
#include "x_assert.h"
#include "x_printf.h"
#include "x_blk_dev.h"
LINT_EXT_HEADER_END

//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------

#define STORG_DEV_MODELNAME_LEN     60
#define STORG_FLAG_CF           ((UINT32) 1 << 0)
#define STORG_FLAG_HD           ((UINT32) 1 << 1)
// FCI.
#define STORG_FLAG_MS           ((UINT32) 1 << 2)
#define STORG_FLAG_SD           ((UINT32) 1 << 3)
#define STORG_FLAG_SMXD         ((UINT32) 1 << 4)

#define STORG_FLAG_FCI           (STORG_FLAG_SD | STORG_FLAG_MS)

#define STORG_FLAG_NAND         ((UINT32) 1 << 5)
#define STORG_FLAG_NOR          ((UINT32) 1 << 6)
#define STORG_FLAG_EEPROM       ((UINT32) 1 << 7)
#define STORG_FLAG_MSDC         ((UINT32) 1 << 8)

#define FCI_UNKNOWN_CARD        0
#define FCI_SD_CARD             1
#define FCI_MMC_CARD            2
#define FCI_MS_CARD             3
#define FCI_MSPRO_CARD          4
#define FCI_SM_CARD             5
#define FCI_XD_CARD             6
#define FCI_SDIO_CARD           7
#define FCI_SDIO_COMBO_CARD     8
#define FCI_SDHC_CARD           9

//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------

typedef enum
{
    STORG_DEV_ABSENT = 0,
    STORG_DEV_FAIL,
    STORG_DEV_READY,    
    STORG_DEV_INIT,
    STORG_DEV_LAST
}STORG_DEV_STATUS_T;

typedef enum
{
    STORG_TYPE_INVALID = 0,
    STORG_TYPE_BLK,
    STORG_TYPE_CHR,
    STORG_TYPE_LAST
}STORG_TYPE_T;

typedef enum
{
    STORG_OP_NONE = 0,
    STORG_OP_INIT,
    STORG_OP_UNINIT,
    STORG_OP_READ,
    STORG_OP_WRITE,
    STORG_OP_ERASE,
    STORG_OP_FLUSH,     /* HD only. */
    STORG_OP_STDBYTIME, /* HD only. */
    STORG_OP_INSERT,
    STORG_OP_REMOVE,
    STORG_OP_LAST,
    STORG_OP_IOCTL
}STORG_OP_T;

typedef enum
{
    COND_FAIL = -1,    /* BLKDEV_COND_FAIL */
    COND_INIT,         /* Request just initial. */
    COND_INIT_OK,      /* Initialize OK */
    COND_UNINIT_OK,    /* Un-Initialize OK */
    COND_READ_OK,      /* BLKDEV_COND_READ_OK */
    COND_WRITE_OK,     /* BLKDEV_COND_WRITE_OK */
    COND_ERASE_OK,     /* BLKDEV_COND_ERASE_OK */
    COND_FLUSH_OK,     /* BLKDEV_COND_FLUSH_OK */
    COND_STDBYTIME_OK, /* Not used in middleware. */
    COND_INSERT_OK,    /* BLKDEV_STATUS_READY */
    COND_REMOVE_OK,    /* BLKDEV_STATUS_ABSENT */
    COND_HOTSWAP_FAIL, /* BLKDEV_STATUS_FAIL */
    CNOD_LAST
}STORG_COND_T;

typedef struct __rStgSegInfo
{
    UINT32 u4SectNum;
    UINT32 u4SectSize;
} StgSEGINFO_T;
typedef struct __rStgSectTbl
{
    UINT32 u4SegNum;
    StgSEGINFO_T *prSegInfo;
} SECTTBL_T;
/* function pointer type */
typedef VOID (*STORG_NFY_FCT)(VOID *pvNfyTag, BLKDEV_COND_T eNfyCond, VOID *pvData);
typedef VOID (*STORG_HOTSWAP_NFY_FCT)(VOID *pvNfyTag, STORG_COND_T eNfyCond, VOID *pvData);

/* successful operation will return 0, otherwise failed. */
typedef INT32 (*STORG_READ_FCT)(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
typedef INT32 (*STORG_WRITE_FCT)(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen);
typedef INT32 (*STORG_ERASE_FCT)(UINT64 u8Offset, UINT32 u4BlkNum);
typedef INT32 (*STORG_FLUSH_FCT)(VOID);
typedef INT32 (*STORG_STDBYTIME_FCT)(UINT32 u4Seconds); /* set standby timer, HDD only. */
typedef INT32 (*STORG_INSERT_FCT)(VOID);                /* media insert */
typedef INT32 (*STORG_REMOVE_FCT)(VOID);                /* media remove */
typedef INT32 (*STORG_IOCTL_FCT)(UINT32 u4oType, UINT64 u8IoData);                /* media remove */

typedef struct _STORG_FUNCTBL_T
{
    STORG_READ_FCT pfnRead;
    STORG_WRITE_FCT pfnWrite;
    STORG_ERASE_FCT pfnErase;
    STORG_FLUSH_FCT pfnFlush;
    STORG_STDBYTIME_FCT pfnStdbyTime;
    STORG_INSERT_FCT pfnInsert;
    STORG_REMOVE_FCT pfnRemove;
    STORG_IOCTL_FCT pfnIoCtl;
} STORG_FUNCTBL_T;

typedef struct
{
    UINT32 u4DevFlag;
    HANDLE_T hRequestMsg;
    HANDLE_T hThread;
    HANDLE_T hSemaExit;
    HANDLE_T hSemaLock;
    HANDLE_T hSemaDone;
} STORG_THRD_T;

typedef struct
{
    UINT32 u4DevFlag;   /* Input from outside. */
    INT32 fgInit;
    INT32 i4RefCnt;     /* Open Device reference. */
    VOID *pvHotswapTag; /* Set from middleware driver. */
    STORG_HOTSWAP_NFY_FCT pfnHotswapNfy;
    /* Below all are generated from u4DevFlag. */
    STORG_TYPE_T eDevType; /* blk dev must check io bytes, chr needn't. */
    STORG_THRD_T *prStorgThrd;
    STORG_FUNCTBL_T *prFuncTbl;
} STORG_DEV_T;

typedef struct
{
    STORG_DEV_T *prDev;
    STORG_OP_T eOp;
    VOID *pvData;
    VOID *pvTag;
    UINT64 u8Offset;      /* storage device byte offset. */
    UINT32 u4Count;       /* memory used byte, or storage used bytes */
    VOID *pvBuf;          /* read/write memory pointer. */
    STORG_NFY_FCT pfnNfy; /* NULL - sync, otherwise - async. */
    UINT32 *pu4XferCnt;
    STORG_COND_T eResult;    
    BOOL fgInvokedByDriver;
} STORG_REQ_T;
//---------------------------------------------------------------------------
// Constant definitions
//---------------------------------------------------------------------------
/// define partition number for middleware.
enum
{     
    // Use by Middleware.
    PART_MIDD_0 = 0, 
    PART_MIDD_1,           
    PART_MIDD_2,  /* channel list */         
    PART_MIDD_3,  /* configuration */         
    PART_MIDD_4,          
    PART_MIDD_5, 
    PART_MIDD_6, 
    PART_MIDD_7,
    PART_MIDD_8,
    PART_MIDD_9,
    PART_MIDD_10,
    PART_MIDD_11,           
    PART_MIDD_12,           
    PART_MIDD_13,         
    PART_MIDD_14,          
    PART_MIDD_15, 
    PART_MIDD_16, 
    PART_MIDD_17,
    PART_MIDD_18,
    PART_MIDD_19,
    PART_MIDD_20,
   	PART_MIDD_21, 
    PART_MIDD_END                                    /* Middleware last partition */
};
/// define partition number for driver.
enum
{
    // Use by Driver.
    PART_DRV_0 = PART_MIDD_END,      /* 1394 driver Nor7 */
    PART_DRV_END                                       /* Driver last partition */
};
/// define partition number for system.
enum
{
    // Use by System, not seen by user.
    PART_SYS_LOADER = PART_DRV_END,     /* Loader */
    PART_SYS_APPIMG,                                  /* Application image */
    PART_SYS_END                                         /* System last partition */
};

//-----------------------------------------------------------------------------
//  Public functions
//-----------------------------------------------------------------------------
EXTERN INT32 STORGInit(VOID);
EXTERN INT32 STORGStop(VOID);
EXTERN STORG_DEV_T *STORGOpenDev(UINT32 u4DevFlag);
EXTERN INT32 STORGCloseDev(STORG_DEV_T *prDrv);
EXTERN INT32 STORGSendReq(STORG_DEV_T *prDev, STORG_OP_T eOp, VOID *pvData, VOID *pvTag,
                          STORG_NFY_FCT pfnNfy, UINT64 u8Offset, UINT32 u4Count, VOID *pvBuf,
                          UINT32 *pu4XferCnt);
EXTERN UINT64 STORG_GetDevSize(UINT32 u4DevFlag, UINT16 ui2_id);
EXTERN STORG_DEV_STATUS_T STORG_GetDevStatus(UINT32 u4DevFlag);
EXTERN CHAR *STORG_GetDevModel(UINT32 u4DevFlag);
EXTERN INT32 STORG_GetDevCard(UINT32 u4DevFlag);
EXTERN INT32 STORG_GetDevStandbyTime(UINT32 u4DevFlag);

EXTERN INT32 STORG_NandAsyncReadBlock(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize, UINT32 *pu4XferCnt, STORG_NFY_FCT pfnNfy);
EXTERN INT32 STORG_NandAsyncWriteBlock(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize, UINT32 *pu4XferCnt, STORG_NFY_FCT pfnNfy);
EXTERN INT32 STORG_SyncNandReadBlock(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize);
EXTERN INT32 STORG_SyncNandWriteBlock(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize);
EXTERN UINT32 STORG_NandGetBlkSize(void);

EXTERN INT32 STORG_SyncNandRead(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize);
EXTERN INT32 STORG_SyncMsdcRead(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize);
EXTERN INT32 STORG_SyncRead(UINT32 u4PartId, UINT32 u4Offset, VOID* pvBuf, UINT32 u4BufSize);

#endif /* STORAGE_IF_H */
