135878b55SSascha Wildner /* 235878b55SSascha Wildner * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 335878b55SSascha Wildner * All rights reserved. 435878b55SSascha Wildner * 535878b55SSascha Wildner * Redistribution and use in source and binary forms, with or without 635878b55SSascha Wildner * modification, are permitted provided that the following conditions 735878b55SSascha Wildner * are met: 835878b55SSascha Wildner * 1. Redistributions of source code must retain the above copyright 935878b55SSascha Wildner * notice, this list of conditions and the following disclaimer. 1035878b55SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright 1135878b55SSascha Wildner * notice, this list of conditions and the following disclaimer in the 1235878b55SSascha Wildner * documentation and/or other materials provided with the distribution. 1335878b55SSascha Wildner * 1435878b55SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1535878b55SSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1635878b55SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1735878b55SSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1835878b55SSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1935878b55SSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2035878b55SSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2135878b55SSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2235878b55SSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2335878b55SSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2435878b55SSascha Wildner * SUCH DAMAGE. 2535878b55SSascha Wildner * 2635878b55SSascha Wildner * $FreeBSD: src/sys/dev/hptmv/array.h,v 1.4 2009/04/07 16:38:25 delphij Exp $ 2735878b55SSascha Wildner */ 2835878b55SSascha Wildner 2935878b55SSascha Wildner #ifndef _ARRAY_H_ 3035878b55SSascha Wildner #define _ARRAY_H_ 3135878b55SSascha Wildner 3235878b55SSascha Wildner /* 3335878b55SSascha Wildner * time represented in DWORD format 3435878b55SSascha Wildner */ 3535878b55SSascha Wildner #pragma pack(1) 3635878b55SSascha Wildner #ifdef __BIG_ENDIAN_BITFIELD 3735878b55SSascha Wildner typedef DWORD TIME_RECORD; 3835878b55SSascha Wildner #else 3935878b55SSascha Wildner typedef struct _TIME_RECORD { 4035878b55SSascha Wildner UINT seconds:6; /* 0 - 59 */ 4135878b55SSascha Wildner UINT minutes:6; /* 0 - 59 */ 4235878b55SSascha Wildner UINT month:4; /* 1 - 12 */ 4335878b55SSascha Wildner UINT hours:6; /* 0 - 59 */ 4435878b55SSascha Wildner UINT day:5; /* 1 - 31 */ 4535878b55SSascha Wildner UINT year:5; /* 0=2000, 31=2031 */ 4635878b55SSascha Wildner } TIME_RECORD; 4735878b55SSascha Wildner #endif 4835878b55SSascha Wildner #pragma pack() 4935878b55SSascha Wildner 5035878b55SSascha Wildner /*************************************************************************** 5135878b55SSascha Wildner * Description: Virtual Device Table 5235878b55SSascha Wildner ***************************************************************************/ 5335878b55SSascha Wildner 5435878b55SSascha Wildner typedef struct _RaidArray 5535878b55SSascha Wildner { 5635878b55SSascha Wildner /* 5735878b55SSascha Wildner * basic information 5835878b55SSascha Wildner */ 5935878b55SSascha Wildner UCHAR bArnMember; /* the number of members in array */ 6035878b55SSascha Wildner UCHAR bArRealnMember; /* real member count */ 6135878b55SSascha Wildner UCHAR bArBlockSizeShift; /* the number of shift bit for a block */ 6235878b55SSascha Wildner UCHAR reserve1; 6335878b55SSascha Wildner 6435878b55SSascha Wildner ULONG dArStamp; /* array ID. all disks in a array has same ID */ 6535878b55SSascha Wildner ULONG failedStamps[4]; /* stamp for failed members */ 6635878b55SSascha Wildner USHORT bStripeWitch; /* = (1 << BlockSizeShift) */ 6735878b55SSascha Wildner 6835878b55SSascha Wildner USHORT rf_broken: 1; 6935878b55SSascha Wildner USHORT rf_need_rebuild: 1; /* one member's data are incorrect. 7035878b55SSascha Wildner for R5, if CriticalMembers==0, it means 7135878b55SSascha Wildner parity needs to be constructed */ 7235878b55SSascha Wildner USHORT rf_need_sync: 1; /* need write array info to disk */ 7335878b55SSascha Wildner /* ioctl flags */ 7435878b55SSascha Wildner USHORT rf_auto_rebuild: 1; 7535878b55SSascha Wildner USHORT rf_newly_created: 1; 7635878b55SSascha Wildner USHORT rf_rebuilding: 1; 7735878b55SSascha Wildner USHORT rf_verifying: 1; 7835878b55SSascha Wildner USHORT rf_initializing: 1; 7935878b55SSascha Wildner USHORT rf_abort_rebuild: 1; 8035878b55SSascha Wildner USHORT rf_duplicate_and_create: 1; 8135878b55SSascha Wildner USHORT rf_duplicate_and_created: 1; 8235878b55SSascha Wildner USHORT rf_duplicate_must_done: 1; 8335878b55SSascha Wildner USHORT rf_raid15: 1; 8435878b55SSascha Wildner 8535878b55SSascha Wildner USHORT CriticalMembers; /* tell which member is critial */ 8635878b55SSascha Wildner UCHAR last_read; /* for RAID 1 load banlancing */ 8735878b55SSascha Wildner UCHAR alreadyBroken; 8835878b55SSascha Wildner 8935878b55SSascha Wildner LBA_T RebuildSectors; /* how many sectors is OK (LBA on member disk) */ 9035878b55SSascha Wildner 9135878b55SSascha Wildner PVDevice pMember[MAX_MEMBERS]; 9235878b55SSascha Wildner /* 9335878b55SSascha Wildner * utility working data 9435878b55SSascha Wildner */ 9535878b55SSascha Wildner UCHAR ArrayName[MAX_ARRAY_NAME]; /* The Name of the array */ 9635878b55SSascha Wildner TIME_RECORD CreateTime; /* when created it */ 9735878b55SSascha Wildner UCHAR Description[64]; /* array description */ 9835878b55SSascha Wildner UCHAR CreateManager[16]; /* who created it */ 9935878b55SSascha Wildner } RaidArray; 10035878b55SSascha Wildner 10135878b55SSascha Wildner /*************************************************************************** 10235878b55SSascha Wildner * Array Descripton on disk 10335878b55SSascha Wildner ***************************************************************************/ 10435878b55SSascha Wildner #pragma pack(1) 10535878b55SSascha Wildner typedef struct _ArrayDescript 10635878b55SSascha Wildner { 10735878b55SSascha Wildner ULONG Signature; /* This block is vaild array info block */ 10835878b55SSascha Wildner ULONG dArStamp; /* array ID. all disks in a array has same ID */ 10935878b55SSascha Wildner 11035878b55SSascha Wildner UCHAR bCheckSum; /* check sum of ArrayDescript_3_0_size bytes */ 11135878b55SSascha Wildner 11235878b55SSascha Wildner #ifdef __BIG_ENDIAN_BITFIELD 11335878b55SSascha Wildner UCHAR df_reservedbits: 6; /* put more flags here */ 11435878b55SSascha Wildner UCHAR df_user_mode_set: 1;/* user select device mode */ 11535878b55SSascha Wildner UCHAR df_bootmark:1; /* user set boot mark on the disk */ 11635878b55SSascha Wildner #else 11735878b55SSascha Wildner UCHAR df_bootmark:1; /* user set boot mark on the disk */ 11835878b55SSascha Wildner UCHAR df_user_mode_set: 1;/* user select device mode */ 11935878b55SSascha Wildner UCHAR df_reservedbits: 6; /* put more flags here */ 12035878b55SSascha Wildner #endif 12135878b55SSascha Wildner 12235878b55SSascha Wildner UCHAR bUserDeviceMode; /* see device.h */ 12335878b55SSascha Wildner UCHAR ArrayLevel; /* how many level[] is valid */ 12435878b55SSascha Wildner 12535878b55SSascha Wildner struct { 12635878b55SSascha Wildner ULONG Capacity; /* capacity for the array */ 12735878b55SSascha Wildner 12835878b55SSascha Wildner UCHAR VDeviceType; /* see above & arrayType in array.h */ 12935878b55SSascha Wildner UCHAR bMemberCount; /* all disk in the array */ 13035878b55SSascha Wildner UCHAR bSerialNumber; /* Serial Number */ 13135878b55SSascha Wildner UCHAR bArBlockSizeShift; /* the number of shift bit for a block */ 13235878b55SSascha Wildner 13335878b55SSascha Wildner #ifdef __BIG_ENDIAN_BITFIELD 13435878b55SSascha Wildner USHORT rf_reserved: 14; 13535878b55SSascha Wildner USHORT rf_raid15: 1; /* don't remove even you don't use it */ 13635878b55SSascha Wildner USHORT rf_need_rebuild:1; /* array is critical */ 13735878b55SSascha Wildner #else 13835878b55SSascha Wildner USHORT rf_need_rebuild:1; /* array is critical */ 13935878b55SSascha Wildner USHORT rf_raid15: 1; /* don't remove even you don't use it */ 14035878b55SSascha Wildner USHORT rf_reserved: 14; 14135878b55SSascha Wildner #endif 14235878b55SSascha Wildner USHORT CriticalMembers; /* record critical members */ 14335878b55SSascha Wildner ULONG RebuildSectors; /* how many sectors is OK (LBA on member disk) */ 14435878b55SSascha Wildner } level[2]; 14535878b55SSascha Wildner 14635878b55SSascha Wildner UCHAR ArrayName[MAX_ARRAY_NAME]; /* The Name of the array */ 14735878b55SSascha Wildner TIME_RECORD CreateTime; /* when created it */ 14835878b55SSascha Wildner UCHAR Description[64]; /* array description */ 14935878b55SSascha Wildner UCHAR CreateManager[16]; /* who created it */ 15035878b55SSascha Wildner 151a643c667SSascha Wildner #define ArrayDescript_3_0_size __offsetof(struct _ArrayDescript, bCheckSum31) 15235878b55SSascha Wildner #define ArrayDescript_3_1_size 512 15335878b55SSascha Wildner 15435878b55SSascha Wildner UCHAR bCheckSum31; /* new check sum */ 15535878b55SSascha Wildner UCHAR PrivateFlag1; /* private */ 15635878b55SSascha Wildner UCHAR alreadyBroken; /* last stamp has been saved to failedStamps */ 15735878b55SSascha Wildner 15835878b55SSascha Wildner #ifdef __BIG_ENDIAN_BITFIELD 15935878b55SSascha Wildner UCHAR df_read_ahead: 1; /* enable read ahead */ 16035878b55SSascha Wildner UCHAR df_read_ahead_set: 1; 16135878b55SSascha Wildner UCHAR df_write_cache: 1; /* enable write cache */ 16235878b55SSascha Wildner UCHAR df_write_cache_set: 1; 16335878b55SSascha Wildner UCHAR df_ncq: 1; /* enable NCQ */ 16435878b55SSascha Wildner UCHAR df_ncq_set: 1; 16535878b55SSascha Wildner UCHAR df_tcq: 1; /* enable TCQ */ 16635878b55SSascha Wildner UCHAR df_tcq_set: 1; 16735878b55SSascha Wildner #else 16835878b55SSascha Wildner UCHAR df_tcq_set: 1; 16935878b55SSascha Wildner UCHAR df_tcq: 1; /* enable TCQ */ 17035878b55SSascha Wildner UCHAR df_ncq_set: 1; 17135878b55SSascha Wildner UCHAR df_ncq: 1; /* enable NCQ */ 17235878b55SSascha Wildner UCHAR df_write_cache_set: 1; 17335878b55SSascha Wildner UCHAR df_write_cache: 1; /* enable write cache */ 17435878b55SSascha Wildner UCHAR df_read_ahead_set: 1; 17535878b55SSascha Wildner UCHAR df_read_ahead: 1; /* enable read ahead */ 17635878b55SSascha Wildner #endif 17735878b55SSascha Wildner 17835878b55SSascha Wildner struct { 17935878b55SSascha Wildner ULONG CapacityHi32; 18035878b55SSascha Wildner ULONG RebuildSectorsHi32; 18135878b55SSascha Wildner } 18235878b55SSascha Wildner levelex[2]; 18335878b55SSascha Wildner 18435878b55SSascha Wildner ULONG failedStamps[4]; /* failed memebrs's stamps */ 18535878b55SSascha Wildner 18635878b55SSascha Wildner } ArrayDescript; 18735878b55SSascha Wildner 18835878b55SSascha Wildner /* report an error if ArrayDescript size exceed 512 */ 18935878b55SSascha Wildner typedef char ArrayDescript_size_should_not_exceed_512[512-sizeof(ArrayDescript)]; 19035878b55SSascha Wildner 19135878b55SSascha Wildner #pragma pack() 19235878b55SSascha Wildner 19335878b55SSascha Wildner /* Signature */ 19435878b55SSascha Wildner #define HPT_ARRAY_V3 0x5a7816f3 19535878b55SSascha Wildner #ifdef ARRAY_V2_ONLY 19635878b55SSascha Wildner #define SAVE_FOR_RAID_INFO 0 19735878b55SSascha Wildner #else 19835878b55SSascha Wildner #define SAVE_FOR_RAID_INFO 10 19935878b55SSascha Wildner #endif 20035878b55SSascha Wildner 20135878b55SSascha Wildner /*************************************************************************** 20235878b55SSascha Wildner * Function protocol for array layer 20335878b55SSascha Wildner ***************************************************************************/ 20435878b55SSascha Wildner 20535878b55SSascha Wildner /* 20635878b55SSascha Wildner * array.c 20735878b55SSascha Wildner */ 20835878b55SSascha Wildner ULONG FASTCALL GetStamp(void); 20935878b55SSascha Wildner void HPTLIBAPI SyncArrayInfo(PVDevice pVDev); 21035878b55SSascha Wildner void HPTLIBAPI fDeleteArray(_VBUS_ARG PVDevice pVArray, BOOLEAN del_block0); 21135878b55SSascha Wildner 21235878b55SSascha Wildner /* 21335878b55SSascha Wildner * iArray.c 21435878b55SSascha Wildner */ 21535878b55SSascha Wildner void HPTLIBAPI fCheckArray(PDevice pDevice); 21635878b55SSascha Wildner void HPTLIBAPI CheckArrayCritical(_VBUS_ARG0); 21735878b55SSascha Wildner PVDevice HPTLIBAPI GetSpareDisk(_VBUS_ARG PVDevice pArray); 21835878b55SSascha Wildner #ifdef SUPPORT_OLD_ARRAY 21935878b55SSascha Wildner void HPTLIBAPI fFixRAID01Stripe(_VBUS_ARG PVDevice pStripe); 22035878b55SSascha Wildner #endif 22135878b55SSascha Wildner 22235878b55SSascha Wildner /*************************************************************************** 22335878b55SSascha Wildner * Macro defination 22435878b55SSascha Wildner ***************************************************************************/ 22535878b55SSascha Wildner #ifndef MAX_ARRAY_PER_VBUS 22635878b55SSascha Wildner #define MAX_ARRAY_PER_VBUS (MAX_VDEVICE_PER_VBUS*2) /* worst case */ 22735878b55SSascha Wildner #endif 22835878b55SSascha Wildner 22935878b55SSascha Wildner 23035878b55SSascha Wildner #if defined(MAX_ARRAY_DEVICE) 23135878b55SSascha Wildner #if MAX_ARRAY_DEVICE!=MAX_ARRAY_PER_VBUS 23235878b55SSascha Wildner #error "remove MAX_ARRAY_DEVICE and use MAX_ARRAY_PER_VBUS instead" 23335878b55SSascha Wildner #endif 23435878b55SSascha Wildner #endif 23535878b55SSascha Wildner 23635878b55SSascha Wildner #define _SET_ARRAY_BUS_(pArray) pArray->pVBus = _vbus_p; 23735878b55SSascha Wildner 23835878b55SSascha Wildner #ifdef ARRAY_V2_ONLY 23935878b55SSascha Wildner #define _SET_ARRAY_VER_(pArray) pArray->vf_format_v2 = 1; 24035878b55SSascha Wildner #else 24135878b55SSascha Wildner #define _SET_ARRAY_VER_(pArray) 24235878b55SSascha Wildner #endif 24335878b55SSascha Wildner 24435878b55SSascha Wildner #define mArGetArrayTable(pVArray) \ 245d8061892SSascha Wildner if((pVArray = _vbus_(pFreeArrayLink)) != NULL) { \ 24635878b55SSascha Wildner _vbus_(pFreeArrayLink) = (PVDevice)_vbus_(pFreeArrayLink)->pVBus; \ 24735878b55SSascha Wildner ZeroMemory(pVArray, ARRAY_VDEV_SIZE); \ 24835878b55SSascha Wildner _SET_ARRAY_BUS_(pVArray) \ 24935878b55SSascha Wildner _SET_ARRAY_VER_(pVArray) \ 250*7323311aSzrj } else { \ 251*7323311aSzrj /* no-op */ \ 252*7323311aSzrj } 25335878b55SSascha Wildner 25435878b55SSascha Wildner #define mArFreeArrayTable(pVArray) \ 25535878b55SSascha Wildner do { \ 25635878b55SSascha Wildner pVArray->pVBus = (PVBus)_vbus_(pFreeArrayLink);\ 25735878b55SSascha Wildner _vbus_(pFreeArrayLink) = pVArray; \ 25835878b55SSascha Wildner pVArray->u.array.dArStamp = 0; \ 25935878b55SSascha Wildner } while(0) 26035878b55SSascha Wildner 26135878b55SSascha Wildner UCHAR CheckSum(UCHAR *p, int size); 26235878b55SSascha Wildner 26335878b55SSascha Wildner void HPTLIBAPI fRAID0SendCommand(_VBUS_ARG PCommand pCmd); 26435878b55SSascha Wildner void HPTLIBAPI fRAID1SendCommand(_VBUS_ARG PCommand pCmd); 26535878b55SSascha Wildner void HPTLIBAPI fJBODSendCommand(_VBUS_ARG PCommand pCmd); 26635878b55SSascha Wildner void HPTLIBAPI fRAID0MemberFailed(_VBUS_ARG PVDevice pVDev); 26735878b55SSascha Wildner void HPTLIBAPI fRAID1MemberFailed(_VBUS_ARG PVDevice pVDev); 26835878b55SSascha Wildner void HPTLIBAPI fJBODMemberFailed(_VBUS_ARG PVDevice pVDev); 26935878b55SSascha Wildner #if SUPPORT_RAID5 27035878b55SSascha Wildner void HPTLIBAPI fRAID5SendCommand(_VBUS_ARG PCommand pCmd); 27135878b55SSascha Wildner void HPTLIBAPI fRAID5MemberFailed(_VBUS_ARG PVDevice pVDev); 27235878b55SSascha Wildner #else 27335878b55SSascha Wildner #define fRAID5SendCommand 0 27435878b55SSascha Wildner #define fRAID5MemberFailed 0 27535878b55SSascha Wildner #endif 27635878b55SSascha Wildner 27735878b55SSascha Wildner #endif 278