/** 
 * @brief           Mass Storage Devices Class Driver API Header
 * @author          AXELL CORPORATION
 * @description     Mass Storage Devices Class Driver提供ヘッダ
 * @note            none
 * @history         2017_02_22	初版
 * @history         2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */
#ifndef __USB_MSC_API_H__
#define __USB_MSC_API_H__
/* DOM-IGNORE-END */

#include "uhs_type.h"

/** エラーコードの基準値 */
#define USBSTOR_ERRCODE_BASE -0x0100

/* USB Storage Class Driver が返却するエラーコード(API戻り値) */
/** 正常終了 */
#define USBSTOR_SUCCESS 0
/** マウント済みのユニットが指定された */
#define USBSTOR_API_MOUNTED_UNIT              (USBSTOR_ERRCODE_BASE - 1)
/** パラメータ指定に誤りがあった */
#define USBSTOR_API_PARAM_ERROR               (USBSTOR_ERRCODE_BASE - 2)
/** 未マウントのドライブが指定された */
#define USBSTOR_API_UNMOUNT_DRIVE             (USBSTOR_ERRCODE_BASE - 3)
/** ユニットが存在しない */
#define USBSTOR_API_NOT_FOUND_UNIT            (USBSTOR_ERRCODE_BASE - 20)
/** ユニットの準備ができていない */
#define USBSTOR_API_UNIT_NOT_READY            (USBSTOR_ERRCODE_BASE - 21)
/** ユニットが使用できない */
#define USBSTOR_API_UNIT_NOT_USE              (USBSTOR_ERRCODE_BASE - 22)
/** ユニットエラー */
#define USBSTOR_API_ILLIGAL_UNIT              (USBSTOR_ERRCODE_BASE - 23)
/** ドライブエラー */
#define USBSTOR_API_ILLIGAL_DRIVE             (USBSTOR_ERRCODE_BASE - 24)
/** USBストレージデバイスに対するコマンド実行時にエラーが発生した */
#define USBSTOR_MEDIUM_COMMAND_ERROR          (USBSTOR_ERRCODE_BASE - 4)
/** 必要なコマンドをUSBストレージデバイスがサポートしないため処理を継続できない */
#define USBSTOR_MEDIUM_COMMAND_NOT_SUPPORT    (USBSTOR_ERRCODE_BASE - 5)
/** USBストレージデバイスからReadエラーが報告された */
#define USBSTOR_MEDIUM_FAILED_READ            (USBSTOR_ERRCODE_BASE - 6)
/** USBストレージデバイスからWriteエラーが報告された */
#define USBSTOR_MEDIUM_FAILED_WRITE           (USBSTOR_ERRCODE_BASE - 7)
/** USBストレージデバイスのメディアが交換された */
#define USBSTOR_MEDIUM_MAY_HAVE_CHANGED       (USBSTOR_ERRCODE_BASE - 8)
/** USBストレージデバイスにメディアが装着されていない */
#define USBSTOR_MEDIUM_NOT_PRESENT            (USBSTOR_ERRCODE_BASE - 9)
/** USBストレージデバイスからコマンドパラメータエラーが報告された */
#define USBSTOR_MEDIUM_PARAMETER_ERROR        (USBSTOR_ERRCODE_BASE - 10)
/** 必要なコマンドパラメータをUSBストレージデバイスがサポートしないため処理を継続できない */
#define USBSTOR_MEDIUM_PARAMETER_NOT_SUPPORT  (USBSTOR_ERRCODE_BASE - 11)
/** USBストレージデバイスとのUSB通信でエラーが発生した */
#define USBSTOR_MEDIUM_TRANSFER_ERROR         (USBSTOR_ERRCODE_BASE - 12)
/** USBストレージデバイスが未知のSenseデータを報告してきた */
#define USBSTOR_MEDIUM_UNKNOWN_SENSE_ERROR    (USBSTOR_ERRCODE_BASE - 13)
/** ライトプロテクトされている */
#define USBSTOR_MEDIUM_WRITE_PROTECT          (USBSTOR_ERRCODE_BASE - 14)
/** 内部エラーが発生した(USB Core) */
#define USBSTOR_INTERNAL_FAILED_CORE          (USBSTOR_ERRCODE_BASE - 15)
/** 内部エラーが発生した(MSC Driver) */
#define USBSTOR_INTERNAL_FAILED_MSC           (USBSTOR_ERRCODE_BASE - 16)
/** システムリソース(メモリ、OSオブジェクト)が確保できなかった */
#define USBSTOR_SYS_OUT_OF_RESOURCE           (USBSTOR_ERRCODE_BASE - 17)
/** システムエラーが発生した */
#define USBSTOR_SYS_SYSTEM_ERROR              (USBSTOR_ERRCODE_BASE - 18)


/* エラーコードの基準値(ステータスモニタ) */
#define USBSTOR_LOG_ERRCODE_BASE 0x0100

/* エラーコード(ステータスモニタ) */
#define USBSTOR_LOG_API_MOUNTED_UNIT              (USBSTOR_LOG_ERRCODE_BASE + 1)
#define USBSTOR_LOG_API_PARAM_ERROR               (USBSTOR_LOG_ERRCODE_BASE + 2)
#define USBSTOR_LOG_API_UNMOUNT_DRIVE             (USBSTOR_LOG_ERRCODE_BASE + 3)

#define USBSTOR_LOG_API_NOT_FOUND_UNIT            (USBSTOR_LOG_ERRCODE_BASE + 20)
#define USBSTOR_LOG_API_UNIT_NOT_READY            (USBSTOR_LOG_ERRCODE_BASE + 21)
#define USBSTOR_LOG_API_UNIT_NOT_USE              (USBSTOR_LOG_ERRCODE_BASE + 22)
#define USBSTOR_LOG_API_ILLIGAL_UNIT              (USBSTOR_LOG_ERRCODE_BASE + 23)
#define USBSTOR_LOG_API_ILLIGAL_DRIVE             (USBSTOR_LOG_ERRCODE_BASE + 24)

#define USBSTOR_LOG_MEDIUM_COMMAND_ERROR          (USBSTOR_LOG_ERRCODE_BASE + 4)
#define USBSTOR_LOG_MEDIUM_COMMAND_NOT_SUPPORT    (USBSTOR_LOG_ERRCODE_BASE + 5)
#define USBSTOR_LOG_MEDIUM_FAILED_READ            (USBSTOR_LOG_ERRCODE_BASE + 6)
#define USBSTOR_LOG_MEDIUM_FAILED_WRITE           (USBSTOR_LOG_ERRCODE_BASE + 7)
#define USBSTOR_LOG_MEDIUM_MAY_HAVE_CHANGED       (USBSTOR_LOG_ERRCODE_BASE + 8)
#define USBSTOR_LOG_MEDIUM_NOT_PRESENT            (USBSTOR_LOG_ERRCODE_BASE + 9)
#define USBSTOR_LOG_MEDIUM_PARAMETER_ERROR        (USBSTOR_LOG_ERRCODE_BASE + 10)
#define USBSTOR_LOG_MEDIUM_PARAMETER_NOT_SUPPORT  (USBSTOR_LOG_ERRCODE_BASE + 11)
#define USBSTOR_LOG_MEDIUM_TRANSFER_ERROR         (USBSTOR_LOG_ERRCODE_BASE + 12)
#define USBSTOR_LOG_MEDIUM_UNKNOWN_SENSE_ERROR    (USBSTOR_LOG_ERRCODE_BASE + 13)
#define USBSTOR_LOG_MEDIUM_WRITE_PROTECT          (USBSTOR_LOG_ERRCODE_BASE + 14)
#define USBSTOR_LOG_INTERNAL_FAILED_CORE          (USBSTOR_LOG_ERRCODE_BASE + 15)
#define USBSTOR_LOG_INTERNAL_FAILED_MSC           (USBSTOR_LOG_ERRCODE_BASE + 16)
#define USBSTOR_LOG_SYS_OUT_OF_RESOURCE           (USBSTOR_LOG_ERRCODE_BASE + 17)
#define USBSTOR_LOG_SYS_SYSTEM_ERROR              (USBSTOR_LOG_ERRCODE_BASE + 18)


/* 警告コード */
#define USBSTOR_WARNCODE_BASE 0x0400
#define USBSTOR_WARNING_OVERCONN              (USBSTOR_WARNCODE_BASE + 1)
#define USBSTOR_WARNING_NOT_SUPPORT_MULTI_LUN (USBSTOR_WARNCODE_BASE + 2)

/* ReadSector/WriteSector実行時のMilestone表示有無 */
/** TRUE=表示、FALSE=非表示 */
#define STOR_RW_MILESTONE_ERA FALSE

/* Milestone 値の定義 */
#define USBSTOR_CHECKPOINT_BASE 0x1000
#define USBSTOR_CHKPOINTS_API_INITIALIZE      (USBSTOR_CHECKPOINT_BASE + 1)
#define USBSTOR_CHKPOINTS_API_FINALIZE        (USBSTOR_CHECKPOINT_BASE + 2)
#define USBSTOR_CHKPOINTS_API_REREGISTCB      (USBSTOR_CHECKPOINT_BASE + 3)
#define USBSTOR_CHKPOINTS_API_MOUNT           (USBSTOR_CHECKPOINT_BASE + 4)
#define USBSTOR_CHKPOINTS_API_UNMOUNT         (USBSTOR_CHECKPOINT_BASE + 5)
#define USBSTOR_CHKPOINTS_API_GETUNMOUNTUNIT  (USBSTOR_CHECKPOINT_BASE + 6)
#define USBSTOR_CHKPOINTS_API_GETUNITINFO     (USBSTOR_CHECKPOINT_BASE + 7)
#define USBSTOR_CHKPOINTS_API_GETUNITSTATUS   (USBSTOR_CHECKPOINT_BASE + 8)
#define USBSTOR_CHKPOINTS_API_READSECTOR      (USBSTOR_CHECKPOINT_BASE + 9)
#define USBSTOR_CHKPOINTS_API_WRITESECTOR     (USBSTOR_CHECKPOINT_BASE + 10)
#define USBSTOR_CHKPOINTS_EVNT_ATTACH_DEVICE  (USBSTOR_CHECKPOINT_BASE + 11)
#define USBSTOR_CHKPOINTS_EVNT_DETACH_DEVICE  (USBSTOR_CHECKPOINT_BASE + 12)
#define USBSTOR_CHKPOINTS_API_STARTSTOP       (USBSTOR_CHECKPOINT_BASE + 13)

/** マスストレージクラスライバ：メジャーバージョン */
#define STOR_MAJOR_VERSION		(0x01)
/** マスストレージクラスドライバ：マイナーバージョン */
#define STOR_MINOR_VERSION		(0x00)

/** コールバックID */
typedef enum _STOR_CALLBACK_ID {
    CBID_STOR_DEVATTACH,                                /** デバイスが接続された(使用可能) */
    CBID_STOR_DEVATTACH_NOT_READY,                      /** デバイスが接続された(メディア無) */
    CBID_STOR_DEVATTACH_NOT_USE,                        /** デバイスが接続された(使用不可) */
    CBID_STOR_DEVDETACH                                 /** デバイスが切断された */
} STOR_CALLBACK_ID;

typedef enum _STOR_UNIT_STATUS {
    STOR_READY,
    STOR_NOT_READY,
    STOR_NOT_USE
} STOR_UNIT_STATUS;

typedef enum _STOR_IMMED_STATUS {
    STOR_IMMED_CLR,
    STOR_IMMED_SET
} STOR_IMMED_STATUS;

typedef enum _STOR_LOEJ_STATUS {
    STOR_LOEJ_CLR,
    STOR_LOEJ_SET
} STOR_LOEJ_STATUS;

typedef enum _STOR_START_STATUS {
    STOR_START_CLR,
    STOR_START_SET
} STOR_START_STATUS;


/** 本ドライバの内部データ管理単位であるストレージユニット構造体の参照用データ型<p>
    ストレージユニット構造体(struct StorUnit)はドライバの内部データであるため、本API群では保持のために参照用ポインタ型のみを公開します。 */
typedef struct StorUnit* PSTOR_UNIT;

/** 上位ユーザアプリケーションが定義するドライブ表現オブジェクトを受けるためのポインタ型<p>
    ストレージクラスドライバの各種APIに対するドライブ指定に使用します。<p>
    本ドライバは、ファイルシステム定義のドライブ表現によるドライブを受け取るためにPUSER_DRV型を使用しますが、
    ポインタが指すオブジェクト(アドレス)が一致するかどうかでドライブを判定しているためアドレスを変更してのドライブ指定は行わないで下さい。<p>
    書き換えた場合の動作保証はありません。 */
typedef void* PUSER_DRV;

/** ストレージユニットの情報を格納する構造体<p>
    本ドライバがストレージユニットの情報を報告するために使用します。<p>
    生成タイミング ： Usbh_Stor_GetUnitInfo APIの実行前に呼び出す側がメモリ領域を確保して下さい。<p>
    削除タイミング ： Usbh_Stor_GetUnitInfo APIの呼び出し側の任意のタイミング */
typedef struct StorUnitInfo {
    uhs_ubit16_t u16BlockSize;			/** セクタのブロックサイズ */
    uhs_ubit32_t u32LastBlockAddress;	/** 最終ブロックアドレス */
    uhs_boolean_t bRemovable;			/** デバイスが報告したリムーバブルフラグ */
    uhs_ubit8_t u8VendorName[8 + 1];	/** 製造社名(NUL文字終端) */
    uhs_ubit8_t u8ProductName[16 + 1];	/** 製品名(NUL文字終端) */
} STOR_UNIT_INFO, *PSTOR_UNIT_INFO;

/** スタートストップユニットコマンド型 */
typedef struct StorStartStopUnitInfo {
   STOR_IMMED_STATUS Immed;				/** Immedビット */
   STOR_LOEJ_STATUS  LoEj;				/** LoEjビット */
   STOR_START_STATUS Start;				/** Startビット */
} STOR_STARTSTOP_UNIT_INFO, *PSTOR_STARTSTOP_UNIT_INFO;


extern uhs_sbit32_t Usbh_Stor_Mount(PSTOR_UNIT pUnit, PUSER_DRV pDrv);
extern uhs_sbit32_t Usbh_Stor_Unmount(PUSER_DRV pDrv);
extern PSTOR_UNIT Usbh_Stor_GetUnmountUnit(void);
extern uhs_sbit32_t Usbh_Stor_GetUnitInfo(PSTOR_UNIT pUnit, STOR_UNIT_INFO *pInfo);
extern STOR_UNIT_STATUS Usbh_Stor_GetUnitStatus(PSTOR_UNIT pUnit);
extern uhs_sbit32_t Usbh_Stor_ReadSector(PUSER_DRV pDrv, uhs_ubit32_t u32LBA, uhs_ubit16_t u16BlockCount, uhs_ubit8_t *pDataBuffer);
extern uhs_sbit32_t Usbh_Stor_WriteSector(PUSER_DRV pDrv, uhs_ubit32_t u32LBA, uhs_ubit16_t u16BlockCount, uhs_ubit8_t *pDataBuffer);
extern uhs_sbit32_t Usbh_Stor_GetLastError(void *pObj);
extern uhs_status_t Usbh_Stor_GetVersion(uhs_ubit8_t* pu8MajorVersion, uhs_ubit8_t* pu8MinorVersion);
extern uhs_status_t Usbh_Stor_Api_StartStop(PSTOR_UNIT pUnit,PSTOR_STARTSTOP_UNIT_INFO pstData );
extern int Usbh_Stor_GetAttachDevNum(void);

/*****************************************************************************/
/*     extern variable                                                       */
/*****************************************************************************/

/*****************************************************************************/
/*     define macro                                                          */
/*****************************************************************************/
#define CONTEXT_BASE        0x70000000

/*****************************************************************************/
/*     const value                                                           */
/*****************************************************************************/

/*****************************************************************************/
/*     global variable                                                       */
/*****************************************************************************/


#endif /* __USB_MSC_API_H__ */
