
#ifndef _RAID_LIB_H_
#define _RAID_LIB_H_

#if defined(__linux) || defined(__linux__) || defined(linux)
#	define VR_LINUX
#else
#	define VR_WIN32
#endif

#ifdef VR_LINUX
#define RAIDLIB_API
#else /* VR_WIN32 */
#define RAIDLIB_API __declspec(dllexport)
#endif


typedef int  VINT;
typedef int  VBOOL;
typedef char VCHAR;
typedef unsigned char VBYTE;
typedef unsigned short VWORD;
typedef unsigned long VDWORD;
#if defined(VR_LINUX)
#include <stdint.h>
#define VDWORD64 uint64_t 
#else /* VR_WIN32 */
typedef unsigned __int64 VDWORD64;
#endif


#define VR_MAX_DEVICES 128// max devices per computer
#define VR_MAX_CHANNELS 16// max channels per computer, 
#define VR_MAX_CONTROLLERS	(VR_MAX_DEVICES / 8)// max IDE controllers per computer,
#define VR_MAX_ARRAYSIZE	16// max devices per disk array,
#define VR_MAX_ARRAYS	VR_MAX_DEVICES// max disk arrays per computer,

//get stripe size (KB) from given index	
#define GET_STRIPE_SIZE(i) ((1 << (i)) * 4)// 4k, 8k, ...
#define VR_MAX_STRIPE_INDEX 4

//define the block size
#define VR_MAX_BLOCK_INDEX 15
#define GET_RAID5_BLOCKSIZE(i) ((i+1) << 8) //256k, 512k, .... 1536k

/* errer codes */
#if 0
#define VR_SUCCESS                        0

#define VR_ERR_INIT_FAILED                1
#define VR_ERR_INIT_AGAIN                 30
#define VR_ERR_INIT_DRV_ABSENT            31
#define VR_ERR_INIT_NO_DISK               32
#define VR_ERR_INIT_DRV_ERROR             33
            
#define VR_ERR_NOT_INITED                 2
#define VR_ERR_INVALID_INDEX              3
#define VR_ERR_INVALID_PARAM              4
#define VR_ERR_DISK_ABSENT                5
#define VR_ERR_DISK_ERROR                 6
#define VR_ERR_RAIDTYPE_UNSUPPORT         7
#define VR_ERR_DISK_NOT_ENOUGH            8
#define VR_ERR_CREATE_DISK_USED           9
#define VR_ERR_CREATE_DIFF_CTRLER         10
#define VR_ERR_CREATE_DISKSIZE_INVALID    11
#define VR_ERR_CREATE_STRIPESIZE_INVALID  12
#define VR_ERR_RAID_BROKEN                13
#define VR_ERR_SYNCVERIFY_FAILED          14
#define VR_ERR_SYNCVERIFY_DISK_INVALID    15
#define VR_ERR_SYNCVERIFY_ERROR_RAIDTYPE  16
#define VR_ERR_SYNCVERIFY_OFFSET_INVALID  17    
#define VR_ERR_SYNCVERIFY_NUM_INVALID     18
#define VR_VERIFY_MISMATCH                19
#define VR_ERR_REPAIR_CANNOT_REPAIR       20
#define VR_ERR_REPAIR_NONEED_REPAIR       21

#define VR_ERR_MIGRATION_NONEED           40
#define VR_ERR_MIGRATION_LOG_FAILED       41
#define VR_ERR_MIGRATION_FAILED           42

#define VR_ERR_RAID5INIT_NONEED           43
#define VR_ERR_RAID5INIT_LOG_FAILED       44
#define VR_ERR_RAID5INIT_FAILED           45
#define VR_RAID5INIT_FINISH               46

#define VR_ERR_RAID5SYNC_NONEED           47
#define VR_ERR_RAID5SYNC_LOG_FAILED       48
#define VR_ERR_RAID5SYNC_FAILED           49
#define VR_RAID5SYNC_FINISH               50

#define VR_ERR_SYSTEM_NEED_REBOOT         22
#define VR_ERR_UNEXPECTED_ERROR           23
#define VR_ERR_RAIDLIB_BUSY               24
#define VR_HARDWARE_INFO_CHANGED          25
#define VR_MIGRATION_FINISH               26
#define VR_SMART_DISK_DEGRADING           27
//for raid5 block size out of range
#define VR_ERR_CREATE_BLOCKSIZE_INVALID   100

#define VR_ERR_CONFIG_UNKNOWN  101
#endif

enum {
		VR_SUCCESS                      =0,
		
		VR_ERR_NOT_INITED				=100,
		VR_ERR_INIT_FAILED,
		VR_ERR_INIT_AGAIN,
		VR_ERR_INIT_DRV_ABSENT,
		VR_ERR_INIT_NO_DISK,
		VR_ERR_INIT_DRV_ERROR,
		VR_ERR_RAIDLIB_BUSY,
        
		VR_ERR_INVALID_INDEX			=200,
		VR_ERR_INVALID_PARAM,
		VR_ERR_RAIDTYPE_UNSUPPORT,
		VR_ERR_RAID_BROKEN,
		VR_ERR_DISK_ABSENT,
		VR_ERR_DISK_ERROR,
		VR_ERR_DISK_NOT_ENOUGH,
		VR_ERR_CREATE_DISK_USED,
		VR_ERR_CREATE_DIFF_CTRLER,
		VR_ERR_CREATE_DISKSIZE_INVALID,
		VR_ERR_CREATE_STRIPESIZE_INVALID,
		VR_ERR_CREATE_BLOCKSIZE_INVALID,
		
		VR_ERR_SYNCVERIFY_FAILED		=300,
		VR_ERR_SYNCVERIFY_DISK_INVALID,
		VR_ERR_SYNCVERIFY_ERROR_RAIDTYPE,
		VR_ERR_SYNCVERIFY_OFFSET_INVALID,
		VR_ERR_SYNCVERIFY_NUM_INVALID,
		VR_VERIFY_MISMATCH,
		
		VR_ERR_REPAIR_CANNOT_REPAIR		=400,
		VR_ERR_REPAIR_NONEED_REPAIR,
		
		VR_ERR_MIGRATION_NONEED			=500,
		VR_ERR_MIGRATION_LOG_FAILED,
		VR_ERR_MIGRATION_FAILED,
		VR_MIGRATION_FINISH,
		
		VR_ERR_RAID5INIT_NONEED			=600,
		VR_ERR_RAID5INIT_LOG_FAILED,
		VR_ERR_RAID5INIT_FAILED,
		VR_RAID5INIT_FINISH,
		
		VR_ERR_RAID5SYNC_NONEED			=700,
		VR_ERR_RAID5SYNC_LOG_FAILED,
		VR_ERR_RAID5SYNC_FAILED,
		VR_RAID5SYNC_FINISH,
		
		VR_ERR_SYSTEM_NEED_REBOOT		=800,
		VR_ERR_UNEXPECTED_ERROR,
		VR_HARDWARE_INFO_CHANGED,
		VR_SMART_DISK_DEGRADING,
		VR_ERR_NOT_PERMITTED,
		
		VR_ERR_CONFIG_UNKNOWN			=900,
};


/* device type */
#define VR_ATA_DEVICE   0
#define VR_ATAPI_DEVICE 1
#define VR_SATA_DEVICE  2

/* array type */
#define VR_RAID0        0
#define VR_RAID1        1
#define VR_RAID2        2
#define VR_RAID3        3
#define VR_RAID4        4
#define VR_RAID5        5
#define VR_RAID6        6
#define VR_RAID7        7
#define VR_SPAN         8
#define VR_RAID01       9  /* raid 0+1 */
#define VR_MATRIXRAID   10 /* matrix raid */
#define VR_STANDALONE_DISK        0xff

/* array postion */
#define VR_STANDALONE_DISK0                0
#define VR_RAID0_STRIPE0                0 /* first stripe disk of raid0 */
#define VR_RAID1_SOURCE                 0 /* source disk of raid1 */
#define VR_RAID1_MIRROR                 1 /* mirror disk of raid1 */
#define VR_RAID1_SPARE                  2 /* spare disk of raid1 */
#define VR_SPAN_DISK0                   0 /* first disk of span raid */
#define VR_RAID01_SOURCE_STRIPE0        0 
                        /* first stripe disk of source sub-raid of raid0+1 */
#define VR_RAID01_MIRROR_STRIPE0        8
                        /* first stripe disk of mirror sub-raid of raid0+1 */
#define VR_RAID5_DISK0                  0 /* first disk of raid5 */
#define VR_MATRIXRAID_DISK0             0 /* first disk of matrix raid */


/* device status, definations of vr_device_info_t::status */
#define VR_DEVICE_STATUS_NEED_REBOOT                 0x0001
                        // need system reboot to enable the disk
#define VR_DEVICE_STATUS_NEED_SYNC                   0x0002
                        // is a mirror disk, need sync
#define VR_DEVICE_STATUS_DEGRADING                   0x0004
                        // reliability degrading, risk of data loss
#define VR_DEVICE_STATUS_ERROR                       0x0008
                        // disk failed
#define VR_DEVICE_STATUS_NEED_CLEAR_PARTITIONS       0x0010
                        // need to clear partition info on this disk
#define VR_DEVICE_STATUS_UNPLUGGED                   0x0020
                        // device is currently Unplugged
#define VR_DEVICE_STATUS_NEW_PLUGIN                  0x0040
                        // device is newly plugged in

/* array status, definations of vr_array_info_t::status */
#define VR_ARRAY_STATUS_BROKEN      0x0001 // array is broken, function failed
#define VR_ARRAY_STATUS_NEED_REBOOT 0x0002 // need reboot to enable the array
#define VR_ARRAY_STATUS_NEED_SYNC   0x0004 // some mirror disks in the array
                                           // need sync
#define VR_ARRAY_STATUS_WARNING     0x0008 // general warning condition
#define VR_ARRAY_STATUS_NEED_INIT   0x0010 // only for RAID5, need init

/* does the physical device contain system files of current running OS 
   definitions of vr_device_info_t::systemDisk */
#define VR_DEVICE_NOT_SYS_DISK         0 /* has no system files */
#define VR_DEVICE_MAYBE_SYS_DISK       1 /* maybe has system files */
#define VR_DEVICE_SYS_DISK             2 /* has system files */

/* function definition for vr_config_param */
#define VR_CONFIG_GET_RAID5OPT 1
#define VR_CONFIG_SET_RAID5OPT 2
#define VR_CONFIG_GET_USERINFO 3

#pragma pack(1)

/* IDE controller info struct  */
typedef struct  _vr_controller_info {
        VCHAR chipName[32];
        VCHAR manufactory[32];
        VBYTE support_PIO;        // max PIO mode
        VBYTE support_MutiDMA;    // max Muti-word DMA mode
        VBYTE support_UltraDMA;   // max UltraDMA mode
        VBYTE channel_Num;        // how many channels
		
		VBOOL bSupportRaid0Migration; // whether this controller support migration
									  // process of RAID0
		VBOOL bSupportRAID5;	  // whether this controller support RAID5 functions
		VINT  index;			  // internal index
} vr_controller_info_t;

/* IDE channel info */
typedef struct _vr_channel_info {
		VINT   index;			   // internal index
		VINT   ctrlerIndex;		   // of which controller

        VDWORD io_Base;            // data/command base address
        VDWORD control_Base;       // control/status base address for this channel
        VDWORD BusMaster_Base;     // bus master control registers' base address
        VBYTE cableType;           // 0: 40 pin; 1: 80 pin; 2: SATA cable
        VBYTE bMaster_Exist;       // whether master drive exist on this channel
        VBYTE bSlave_Exist;        // whether slave drive exist on this channel

		VBOOL bSlaveValid;         // whether the slave device of this channel is valid
} vr_channel_info_t;

/* Device(disk) info struct */
typedef struct _vr_device_info {
        VCHAR serialNumber[32];
        VCHAR firmwareRevison[16];
        VCHAR modelName[64];
        VCHAR minorRevisonNumber[64];
		
		// CHS parameters
        VDWORD cylinderNumber;
        VDWORD headNumber;
        VDWORD sectorNumberPerTrack;

        // following 8 bytes define the capcity (in sector) of the disk
        VDWORD capacityLow;        // (Unit: sector)
        VDWORD capacityHigh;       // (Unit: sector)

        // if any following supportxxxMode member has a value 0xFF, it will
        // mean the mode is totally unsupported, a value other than 0xFF means
        // the max mode number.
        VBYTE supportPIOTransferMode;
        VBYTE supportMultiDMAMode;
        VBYTE supportUltraDMAMode;

        // current transfer mode
        // bit 5,6,7: 0,PIO; 1,Multi-DMA; 2,Ultra-DMA
        // bit 0-4: Mode number
        VBYTE currentTransferMode;

        VBYTE deviceType;  // the possible values are:
						   // VR_ATA_DEVICE, VR_ATAPI_DEVICE, VR_SATA_DEVICE
        
        // device status
        VWORD status; /* the invalid value are defined in this file, and all 
                        start with VR_DEVICE_STATUS */

        // physical position info
        VBYTE ctrler_index;       /* which controller */
        VBYTE chan_index;         /* which channel in the controller */
        VBOOL master;             /* master or slave */
        VINT  index;              /* index of all devices in system */
		
		VBYTE systemDisk;         /* does the physical device contain system 
		                             files of current running OS ? 
		                             the probably value are:
									     VR_DEVICE_NOT_SYS_DISK
										 VR_DEVICE_MAYBE_SYS_DISK
										 VR_DEVICE_SYS_DISK
		                             they are defined in this file */

        // device's disk-array-relevant info
        VBOOL  bDevInRaid;             // whether the device in a valid raid
        VWORD  array_position;         // positon within the raid
        VINT   array_index;            // index of the raid in which the device be
        VDWORD realCapacityLow;        // (Unit: sector)
        VDWORD realCapacityHigh;       // (Unit: sector)
} vr_device_info_t;

typedef struct _vr_array_info {
        VWORD status;  // current status of disk array
                        
        VBYTE raidType;// same as Disk_Array.raidType, but value 0xFF means
                        // a stand-alone disk. When it's a stand-alone disk,
                        // only arDevices[0] and diskNum has meaning, and diskNum should
                        // always be 1 .

        VBYTE diskNum;// count of valid arDevices[] members. 

        // Note: disk array maybe incomplete, i.e. , some disk in the array maybe missing, 
        //     corresponding device ptr arDevices[i]->pRealDevice should be NULL.
        
        VDWORD capacityLow;// (Unit: sector)
        VDWORD capacityHigh;// (Unit: sector)

		// following 8 bytes define the real-capcity (in sector) of every disk in array
        VDWORD realCapacityLow;        // (Unit: sector)
        VDWORD realCapacityHigh;       // (Unit: sector)


        VDWORD stripeSize; // valid when raid is raid0, raid5 or raid01, in Kbytes
		VDWORD blockSize; // valid when raid is RAID5, in Kbytes

		VBOOL  bNeedMigration; // the raid need migration
		                       // only valid when raid0/raid5/matrixRaid
		VBOOL  bNeedInit;      // the raid need initialization, only valid for RAID5
		VBOOL  bOptimized;     // only for RAID5, this RAID5 access was optimized

		 VBYTE systemDisk;	   /* does the devices within this disk array 
							      contain system files of current running OS ? 
								   the probably value are:
								   VR_DEVICE_NOT_SYS_DISK
								   VR_DEVICE_MAYBE_SYS_DISK
								   VR_DEVICE_SYS_DISK
		                         they are defined in this file */

        VWORD raid_index;// only raid index, no meaning with stand-alone disk
        VINT  index; // all device index, including all raid and stand-alone disk
} vr_array_info_t;

#pragma pack()

RAIDLIB_API VINT vr_init (void);
RAIDLIB_API void vr_exit (void);

RAIDLIB_API VINT vr_get_version (VINT *pmajor, VINT *pminor, VINT *pmicro);

RAIDLIB_API 
VINT vr_get_controller_num (VINT *pnumber);
RAIDLIB_API 
VINT vr_get_controller_info (VINT index, vr_controller_info_t* pinfo);

RAIDLIB_API 
VINT vr_get_channel_info(VINT ctrler_index, VINT chan_index, vr_channel_info_t* pinfo);

RAIDLIB_API 
VINT vr_get_device_num (VINT *pnumber);
RAIDLIB_API 
VINT vr_get_device_info (VINT index, vr_device_info_t* pinfo);
RAIDLIB_API
VINT vr_get_device_info_by_phy_address (VINT ctrler_index, 
                                        VINT chan_index, 
                                        VINT master, 
                                        vr_device_info_t* pinfo);
RAIDLIB_API
VINT vr_get_device_info_by_array_pos (VINT array_index, 
                                      VINT pos, 
                                      vr_device_info_t* pinfo);

RAIDLIB_API 
VINT vr_get_array_num (VINT only_raid, VINT *pnumber);
RAIDLIB_API 
VINT vr_get_array_info (VINT array_index, vr_array_info_t* pinfo);
RAIDLIB_API 
VINT vr_get_array_info_by_disk (VINT disk_index, vr_array_info_t* pinfo); /* TODO */

RAIDLIB_API 
//VINT vr_create_raid (VINT type, VINT disk_num, VINT disks[], VDWORD param);
VINT vr_create_raid (VINT type, VINT disk_num, VINT disks[], VDWORD param, VDWORD paramBlockSize);
RAIDLIB_API 
VINT vr_create_mirror (VINT source, VINT mirror, VINT spare, VBOOL keep_source);
RAIDLIB_API 
VINT vr_create_stripe (VINT disk_num, VINT disks[], VDWORD stripe_size, VBOOL need_migration);
RAIDLIB_API 
VINT vr_create_span   (VINT disk_num, VINT disks[], VBOOL keep_first);
RAIDLIB_API 
VINT vr_create_raid01 (VINT disk_num, VINT disks[], VDWORD stripe_size);
RAIDLIB_API
VINT vr_create_raid5(VINT disk_num, VINT disks[], VDWORD stripe_size, VDWORD block_size, VBOOL need_migration, VBOOL bopt);

RAIDLIB_API 
VINT vr_mirror_add_spare (VINT array_index, VINT disk_index);
RAIDLIB_API 
VINT vr_mirror_remove_spare (VINT array_index);
RAIDLIB_API 
VINT vr_remove_raid (VINT array_index);

RAIDLIB_API 
VINT vr_update_hardware_info (void);

RAIDLIB_API 
VINT vr_sync_disk_pair   (VINT source_disk, VINT mirror_disk, 
							 VDWORD64 start_sector,VWORD sector_num);
RAIDLIB_API 
VINT vr_verify_disk_pair (VINT source_disk, VINT mirror_disk, 
							 VDWORD64 start_sector,VWORD sector_num);
RAIDLIB_API 
VINT vr_mark_disk_pair_as_synced (VINT source_disk, VINT mirror_disk);
RAIDLIB_API 
VINT vr_mark_raid_syned (VINT array_index);

RAIDLIB_API 
VINT vr_sync_mirror (VINT array_index, VDWORD64 *pcur_position,  VWORD *ppercent); /* TODO */
RAIDLIB_API 
VINT vr_sync_raid01 (VINT array_index, VINT stripe_index, VDWORD64 *pcur_position,  VWORD *ppercent); /* TODO */

RAIDLIB_API 
VINT vr_repair_broken_raid (VINT array_index, VINT disk_num, VINT disks[]);
RAIDLIB_API 
VINT vr_repair_mirror_with_spare (VINT array_index);
RAIDLIB_API 
VINT vr_repair_mirror_with_new_disk (VINT array_index, VINT disk_index);
RAIDLIB_API 
VINT vr_repair_broken_raid01 (VINT array_index, VINT disk_num, VINT disks[]);
RAIDLIB_API 
VINT vr_repair_raid5_with_new_disk (VINT array_index, VINT disk_index);

RAIDLIB_API 
VINT vr_migration_raid (VINT array_index, VDWORD64 *pcur_position, VWORD *ppercent);

RAIDLIB_API 
VINT vr_init_raid5 (VINT array_index, VDWORD64 *pcur_position, VWORD *ppercent);
RAIDLIB_API 
VINT vr_sync_raid5 (VINT array_index, VDWORD64 *pcur_position, VWORD *ppercent);
RAIDLIB_API
VINT vr_verify_raid5 (VINT array_index, VDWORD64 *pcur_position, VWORD *ppercent);


RAIDLIB_API 
VINT vr_exec_SMART (void);
RAIDLIB_API
VBOOL vr_is_system_support_dynamic_raid (void);
RAIDLIB_API
VBOOL vr_is_system_need_reboot (void);

RAIDLIB_API
VINT  vr_config_param (VINT function, void *param);

#endif /* #ifndef _RAID_LIB_H_ */

