10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51623Stw21770 * Common Development and Distribution License (the "License"). 61623Stw21770 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 226367Sjr26306 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_MD_RAID_H 270Sstevel@tonic-gate #define _SYS_MD_RAID_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/lvm/mdvar.h> 300Sstevel@tonic-gate #include <sys/lvm/md_rename.h> 310Sstevel@tonic-gate 320Sstevel@tonic-gate #ifdef __cplusplus 330Sstevel@tonic-gate extern "C" { 340Sstevel@tonic-gate #endif 350Sstevel@tonic-gate 360Sstevel@tonic-gate 370Sstevel@tonic-gate /* 380Sstevel@tonic-gate * following bits are used in status word in the common section 390Sstevel@tonic-gate * of unit structure: un_status 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate #define RAID_UNMAGIC 0xBADBABE0 420Sstevel@tonic-gate #define RAID_PSMAGIC 0xBADBABE1 430Sstevel@tonic-gate #define RAID_CSMAGIC 0xBADBABE2 440Sstevel@tonic-gate #define RAID_PWMAGIC 0xBADBABE3 450Sstevel@tonic-gate #define RAID_BUFMAGIC 0xBADBABE4 460Sstevel@tonic-gate /* 470Sstevel@tonic-gate * These are the major constants for the definition of a raid device 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate #define PWCNT_MIN 10 /* mininum # prewrites */ 500Sstevel@tonic-gate #define PWCNT_MAX 100 /* maximum # prewrites */ 510Sstevel@tonic-gate #define RAID_MIN_INTERLACE (DEV_BSIZE * 2) 520Sstevel@tonic-gate 530Sstevel@tonic-gate #define UNIT_STATE(un) ((un)->un_state) 540Sstevel@tonic-gate #define COLUMN_STATE(un, column) ((un)->un_column[(column)].un_devstate) 550Sstevel@tonic-gate 560Sstevel@tonic-gate #define COLUMN_STATE_ONLY(un, column) (\ 570Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_INIT) || \ 580Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY) || \ 590Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_ERRED) || \ 600Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \ 610Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED) || \ 62*7592SViswanathan.Kannappan@Sun.COM ((un)->un_column[(column)].un_devstate == RCS_REGEN)) 630Sstevel@tonic-gate 640Sstevel@tonic-gate #define COLUMN_ISUP(un, column) (\ 650Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY) || \ 660Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \ 670Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED)) 680Sstevel@tonic-gate 690Sstevel@tonic-gate #define COLUMN_ISOKAY(un, column) (\ 700Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY)) 710Sstevel@tonic-gate 720Sstevel@tonic-gate #define COLUMN_ISLASTERR(un, column) (\ 730Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED)) 740Sstevel@tonic-gate 750Sstevel@tonic-gate #define WRITE_ALT(un, column) ( \ 760Sstevel@tonic-gate ((un)->un_column[(column)].un_alt_dev != NODEV64) && \ 770Sstevel@tonic-gate (((un)->un_column[(column)].un_devflags & MD_RAID_WRITE_ALT))) 780Sstevel@tonic-gate 790Sstevel@tonic-gate #define HOTSPARED(un, column) ( \ 800Sstevel@tonic-gate ((un)->un_column[(column)].un_hs_id != 0)) 810Sstevel@tonic-gate 820Sstevel@tonic-gate #define OVERLAPED(blk1, lblk1, blk2, lblk2) ( \ 830Sstevel@tonic-gate (((blk1 > lblk2) ? 1 : 0) || \ 840Sstevel@tonic-gate ((lblk1 < blk2) ? 1 : 0))) 850Sstevel@tonic-gate 860Sstevel@tonic-gate 870Sstevel@tonic-gate /* 880Sstevel@tonic-gate * Note: magic is needed only to set rpw_magic, not rpw_magic_ext! 890Sstevel@tonic-gate */ 900Sstevel@tonic-gate #define RAID_FILLIN_RPW(buf, un, sum, colnum, \ 910Sstevel@tonic-gate blkno, blkcnt, id, \ 920Sstevel@tonic-gate colcount, col, magic) { \ 931623Stw21770 if ((un)->c.un_revision & MD_64BIT_META_DEV) { \ 940Sstevel@tonic-gate raid_pwhdr_t *rpw64 = (raid_pwhdr_t *)(void *)(buf);\ 950Sstevel@tonic-gate rpw64->rpw_magic = magic; \ 960Sstevel@tonic-gate rpw64->rpw_sum = sum; \ 970Sstevel@tonic-gate rpw64->rpw_columnnum = colnum; \ 980Sstevel@tonic-gate rpw64->rpw_blkno = (diskaddr_t)blkno; \ 990Sstevel@tonic-gate rpw64->rpw_blkcnt = blkcnt; \ 1000Sstevel@tonic-gate rpw64->rpw_id = id; \ 1010Sstevel@tonic-gate rpw64->rpw_colcount = colcount; \ 1020Sstevel@tonic-gate rpw64->rpw_column = col; \ 1030Sstevel@tonic-gate rpw64->rpw_unit = MD_SID(un); \ 1040Sstevel@tonic-gate rpw64->rpw_magic_ext = RAID_PWMAGIC; \ 1050Sstevel@tonic-gate rpw64->rpw_origcolumncnt = (un)->un_origcolumncnt; \ 1060Sstevel@tonic-gate rpw64->rpw_totalcolumncnt = (un)->un_totalcolumncnt; \ 1070Sstevel@tonic-gate rpw64->rpw_segsize = (un)->un_segsize; \ 1080Sstevel@tonic-gate rpw64->rpw_segsincolumn = (diskaddr_t)((un)->un_segsincolumn);\ 1090Sstevel@tonic-gate rpw64->rpw_pwcnt = (un)->un_pwcnt; \ 1100Sstevel@tonic-gate rpw64->rpw_pwsize = (un)->un_pwsize; \ 1110Sstevel@tonic-gate rpw64->rpw_devstart = \ 1120Sstevel@tonic-gate (diskaddr_t)((un)->un_column[col].un_orig_devstart);\ 1130Sstevel@tonic-gate rpw64->rpw_pwstart = \ 1140Sstevel@tonic-gate (diskaddr_t)((un)->un_column[col].un_orig_pwstart);\ 1150Sstevel@tonic-gate } else { \ 1160Sstevel@tonic-gate raid_pwhdr32_od_t *rpw32 = \ 1170Sstevel@tonic-gate (raid_pwhdr32_od_t *)(void *)(buf); \ 1180Sstevel@tonic-gate rpw32->rpw_magic = magic; \ 1190Sstevel@tonic-gate rpw32->rpw_sum = sum; \ 1200Sstevel@tonic-gate rpw32->rpw_columnnum = colnum; \ 1210Sstevel@tonic-gate rpw32->rpw_blkno = (daddr_t)blkno; \ 1220Sstevel@tonic-gate rpw32->rpw_blkcnt = blkcnt; \ 1230Sstevel@tonic-gate rpw32->rpw_id = id; \ 1240Sstevel@tonic-gate rpw32->rpw_colcount = colcount; \ 1250Sstevel@tonic-gate rpw32->rpw_column = col; \ 1260Sstevel@tonic-gate rpw32->rpw_unit = MD_SID(un); \ 1270Sstevel@tonic-gate rpw32->rpw_magic_ext = RAID_PWMAGIC; \ 1280Sstevel@tonic-gate rpw32->rpw_origcolumncnt = (un)->un_origcolumncnt; \ 1290Sstevel@tonic-gate rpw32->rpw_totalcolumncnt = (un)->un_totalcolumncnt; \ 1300Sstevel@tonic-gate rpw32->rpw_segsize = (daddr_t)((un)->un_segsize); \ 1310Sstevel@tonic-gate rpw32->rpw_segsincolumn = (daddr_t)((un)->un_segsincolumn);\ 1320Sstevel@tonic-gate rpw32->rpw_pwcnt = (un)->un_pwcnt; \ 1330Sstevel@tonic-gate rpw32->rpw_pwsize = (un)->un_pwsize; \ 1340Sstevel@tonic-gate rpw32->rpw_devstart = \ 1350Sstevel@tonic-gate (daddr_t)((un)->un_column[col].un_orig_devstart);\ 1360Sstevel@tonic-gate rpw32->rpw_pwstart = \ 1370Sstevel@tonic-gate (daddr_t)((un)->un_column[col].un_orig_pwstart);\ 1380Sstevel@tonic-gate } \ 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate #define RAID_CONVERT_RPW(rpw32, rpw64) { \ 1420Sstevel@tonic-gate (rpw64)->rpw_magic = (rpw32)->rpw_magic; \ 1430Sstevel@tonic-gate (rpw64)->rpw_sum = (rpw32)->rpw_sum; \ 1440Sstevel@tonic-gate (rpw64)->rpw_columnnum = (rpw32)->rpw_columnnum; \ 1450Sstevel@tonic-gate (rpw64)->rpw_blkno = (rpw32)->rpw_blkno; \ 1460Sstevel@tonic-gate (rpw64)->rpw_blkcnt = (rpw32)->rpw_blkcnt; \ 1470Sstevel@tonic-gate (rpw64)->rpw_id = (rpw32)->rpw_id; \ 1480Sstevel@tonic-gate (rpw64)->rpw_colcount = (rpw32)->rpw_colcount; \ 1490Sstevel@tonic-gate (rpw64)->rpw_column = (rpw32)->rpw_column; \ 1500Sstevel@tonic-gate (rpw64)->rpw_unit = (rpw32)->rpw_unit; \ 1510Sstevel@tonic-gate (rpw64)->rpw_magic_ext = (rpw32)->rpw_magic_ext; \ 1520Sstevel@tonic-gate (rpw64)->rpw_origcolumncnt = (rpw32)->rpw_origcolumncnt; \ 1530Sstevel@tonic-gate (rpw64)->rpw_totalcolumncnt = (rpw32)->rpw_totalcolumncnt; \ 1540Sstevel@tonic-gate (rpw64)->rpw_segsize = (rpw32)->rpw_segsize; \ 1550Sstevel@tonic-gate (rpw64)->rpw_segsincolumn = (rpw32)->rpw_segsincolumn; \ 1560Sstevel@tonic-gate (rpw64)->rpw_pwcnt = (rpw32)->rpw_pwcnt; \ 1570Sstevel@tonic-gate (rpw64)->rpw_pwsize = (rpw32)->rpw_pwsize; \ 1580Sstevel@tonic-gate (rpw64)->rpw_devstart = (rpw32)->rpw_devstart; \ 1590Sstevel@tonic-gate (rpw64)->rpw_pwstart = (rpw32)->rpw_pwstart; \ 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate typedef struct mr_scoreboard { 1630Sstevel@tonic-gate int sb_column; 1640Sstevel@tonic-gate int sb_flags; 1650Sstevel@tonic-gate diskaddr_t sb_start_blk; 1660Sstevel@tonic-gate diskaddr_t sb_last_blk; 1670Sstevel@tonic-gate void *sb_cs; 1680Sstevel@tonic-gate } mr_scoreboard_t; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate #define SB_AVAIL (0x00000001) /* useable and valid blocks */ 1710Sstevel@tonic-gate #define SB_INUSE (0x00000002) /* being used */ 1720Sstevel@tonic-gate #define SB_UNUSED (0x00000004) /* useable and no valid blocks */ 1730Sstevel@tonic-gate #define SB_INVAL_PEND (0x00000008) /* being invalidated */ 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate typedef struct mr_pw_reserve { 1760Sstevel@tonic-gate uint_t pw_magic; 1770Sstevel@tonic-gate int pw_column; 1780Sstevel@tonic-gate int pw_free; 1790Sstevel@tonic-gate mr_scoreboard_t pw_sb[1]; 1800Sstevel@tonic-gate } mr_pw_reserve_t; 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 1840Sstevel@tonic-gate #pragma pack(4) 1850Sstevel@tonic-gate #endif 1860Sstevel@tonic-gate typedef struct mr_column { 1870Sstevel@tonic-gate rcs_state_t un_devstate; 1880Sstevel@tonic-gate rcs_flags_t un_devflags; 1890Sstevel@tonic-gate md_timeval32_t un_devtimestamp; /* time of last state change, 32 bit */ 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate mddb_recid_t un_hs_id; 1920Sstevel@tonic-gate diskaddr_t un_hs_pwstart; 1930Sstevel@tonic-gate diskaddr_t un_hs_devstart; 1940Sstevel@tonic-gate mdkey_t un_hs_key; 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate md_dev64_t un_orig_dev; /* original device, 64 bit */ 1980Sstevel@tonic-gate mdkey_t un_orig_key; 1990Sstevel@tonic-gate diskaddr_t un_orig_pwstart; 2000Sstevel@tonic-gate diskaddr_t un_orig_devstart; 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate md_dev64_t un_dev; /* current read/write dev */ 2030Sstevel@tonic-gate diskaddr_t un_pwstart; 2040Sstevel@tonic-gate diskaddr_t un_devstart; 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate md_dev64_t un_alt_dev; /* write to if resync */ 2070Sstevel@tonic-gate diskaddr_t un_alt_pwstart; 2080Sstevel@tonic-gate diskaddr_t un_alt_devstart; 2090Sstevel@tonic-gate } mr_column_t; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate /* 2120Sstevel@tonic-gate * mr_column32_od is for old 32 bit format only 2130Sstevel@tonic-gate */ 2140Sstevel@tonic-gate typedef struct mr_column32_od { 2150Sstevel@tonic-gate rcs_state_t un_devstate; 2160Sstevel@tonic-gate rcs_flags_t un_devflags; 2170Sstevel@tonic-gate struct timeval32 un_devtimestamp; /* time of last state change */ 2180Sstevel@tonic-gate caddr32_t xx_un_pw_reserve; 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate mddb_recid_t un_hs_id; 2210Sstevel@tonic-gate daddr32_t un_hs_pwstart; 2220Sstevel@tonic-gate daddr32_t un_hs_devstart; 2230Sstevel@tonic-gate mdkey_t un_hs_key; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate dev32_t un_orig_dev; /* original device */ 2260Sstevel@tonic-gate mdkey_t un_orig_key; 2270Sstevel@tonic-gate daddr32_t un_orig_pwstart; 2280Sstevel@tonic-gate daddr32_t un_orig_devstart; 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate dev32_t un_dev; /* current read/write dev */ 2310Sstevel@tonic-gate daddr32_t un_pwstart; 2320Sstevel@tonic-gate daddr32_t un_devstart; 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate dev32_t un_alt_dev; /* write to if resync */ 2350Sstevel@tonic-gate daddr32_t un_alt_pwstart; 2360Sstevel@tonic-gate daddr32_t un_alt_devstart; 2370Sstevel@tonic-gate } mr_column32_od_t; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate /* 2410Sstevel@tonic-gate * Incore only elements structures 2420Sstevel@tonic-gate */ 2430Sstevel@tonic-gate typedef struct mr_column_ic { 2440Sstevel@tonic-gate mr_pw_reserve_t *un_pw_reserve; 2450Sstevel@tonic-gate } mr_column_ic_t; 2460Sstevel@tonic-gate 2476367Sjr26306 /* 2486367Sjr26306 * Do not rearrange elements as mutexes must be aligned on 2496367Sjr26306 * an 8 byte boundary. Element _t_un_linlck_mx corresponds to 2506367Sjr26306 * _t_un_linlck_cv and element _t_un_mx corresponds to _t_un_cv 2516367Sjr26306 */ 2520Sstevel@tonic-gate typedef struct mr_unit_ic { 2530Sstevel@tonic-gate caddr_t _t_un_pbuffer; 2540Sstevel@tonic-gate caddr_t _t_un_dbuffer; 2550Sstevel@tonic-gate struct md_raidcs *_t_un_linlck_chn; 2560Sstevel@tonic-gate kmutex_t _t_un_linlck_mx; 2576367Sjr26306 kmutex_t _t_un_mx; 2580Sstevel@tonic-gate kcondvar_t _t_un_linlck_cv; 2590Sstevel@tonic-gate kcondvar_t _t_un_cv; 2600Sstevel@tonic-gate mr_column_ic_t *_t_un_column_ic; 2610Sstevel@tonic-gate } mr_unit_ic_t; 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate typedef struct mr_unit { 2640Sstevel@tonic-gate mdc_unit_t c; 2650Sstevel@tonic-gate int un_raid_res; 2660Sstevel@tonic-gate uint_t un_magic; 2670Sstevel@tonic-gate rus_state_t un_state; 2680Sstevel@tonic-gate md_timeval32_t un_timestamp; /* 32 bit fixed size */ 2690Sstevel@tonic-gate uint_t un_origcolumncnt; 2700Sstevel@tonic-gate uint_t un_totalcolumncnt; 2710Sstevel@tonic-gate uint_t un_rflags; 2720Sstevel@tonic-gate uint_t un_segsize; 2730Sstevel@tonic-gate diskaddr_t un_segsincolumn; 2740Sstevel@tonic-gate uint_t un_maxio; /* in blks */ 2750Sstevel@tonic-gate uint_t un_iosize; /* in blks */ 2760Sstevel@tonic-gate uint_t un_linlck_flg; 2770Sstevel@tonic-gate uint_t un_pwcnt; 2780Sstevel@tonic-gate uint_t un_pwsize; 2790Sstevel@tonic-gate long long un_pwid; 2800Sstevel@tonic-gate uint_t un_percent_done; 2810Sstevel@tonic-gate uint_t un_resync_copysize; /* in blks */ 2820Sstevel@tonic-gate hsp_t un_hsp_id; 2830Sstevel@tonic-gate /* 2840Sstevel@tonic-gate * This union has to begin at an 8 byte aligned address. 2850Sstevel@tonic-gate * If not, this structure has different sizes in 32 / 64 bit 2860Sstevel@tonic-gate * environments, since in a 64 bit environment the compiler 2870Sstevel@tonic-gate * adds paddings before a long long, if it doesn't start at an 8byte 2880Sstevel@tonic-gate * aligned address. 2890Sstevel@tonic-gate * Be careful if you add or remove structure elements before it! 2900Sstevel@tonic-gate */ 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate union { 2930Sstevel@tonic-gate struct { 2940Sstevel@tonic-gate diskaddr_t _t_un_resync_line_index; 2950Sstevel@tonic-gate uint_t _t_un_resync_segment; 2960Sstevel@tonic-gate int _t_un_resync_index; 2970Sstevel@tonic-gate } _resync; 2980Sstevel@tonic-gate struct { 2990Sstevel@tonic-gate diskaddr_t _t_un_grow_tb; 3000Sstevel@tonic-gate uint_t _t_un_init_colcnt; 3010Sstevel@tonic-gate u_longlong_t _t_un_init_iocnt; 3020Sstevel@tonic-gate } _init; 3030Sstevel@tonic-gate } _t_un; 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate /* 3060Sstevel@tonic-gate * This union has to begin at an 8 byte aligned address. 3070Sstevel@tonic-gate * Be careful if you add or remove structure elements before it! 3080Sstevel@tonic-gate */ 3090Sstevel@tonic-gate union { 3100Sstevel@tonic-gate mr_unit_ic_t *_mr_ic; 3110Sstevel@tonic-gate uint_t _mr_ic_pad[2]; 3120Sstevel@tonic-gate } un_mr_ic; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate mr_column_t un_column[1]; 3150Sstevel@tonic-gate } mr_unit_t; 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate #define mr_ic un_mr_ic._mr_ic 3180Sstevel@tonic-gate #define un_pbuffer mr_ic->_t_un_pbuffer 3190Sstevel@tonic-gate #define un_dbuffer mr_ic->_t_un_dbuffer 3200Sstevel@tonic-gate #define un_linlck_chn mr_ic->_t_un_linlck_chn 3210Sstevel@tonic-gate #define un_linlck_mx mr_ic->_t_un_linlck_mx 3220Sstevel@tonic-gate #define un_linlck_cv mr_ic->_t_un_linlck_cv 3230Sstevel@tonic-gate #define un_mx mr_ic->_t_un_mx 3240Sstevel@tonic-gate #define un_cv mr_ic->_t_un_cv 3250Sstevel@tonic-gate #define un_column_ic mr_ic->_t_un_column_ic 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate /* 3280Sstevel@tonic-gate * For old 32 bit format use only 3290Sstevel@tonic-gate */ 3300Sstevel@tonic-gate typedef struct mr_unit32_od { 3310Sstevel@tonic-gate mdc_unit32_od_t c; 3320Sstevel@tonic-gate caddr32_t xx_un_raid_res; 3330Sstevel@tonic-gate uint_t un_magic; 3340Sstevel@tonic-gate rus_state_t un_state; 3350Sstevel@tonic-gate struct timeval32 un_timestamp; 3360Sstevel@tonic-gate uint_t un_origcolumncnt; 3370Sstevel@tonic-gate uint_t un_totalcolumncnt; 3380Sstevel@tonic-gate uint_t un_rflags; 3390Sstevel@tonic-gate uint_t un_segsize; 3400Sstevel@tonic-gate uint_t un_segsincolumn; 3410Sstevel@tonic-gate uint_t un_maxio; 3420Sstevel@tonic-gate uint_t un_iosize; 3430Sstevel@tonic-gate caddr32_t xx_un_pbuffer; 3440Sstevel@tonic-gate caddr32_t xx_un_dbuffer; 3450Sstevel@tonic-gate uint_t un_linlck_flg; 3460Sstevel@tonic-gate caddr32_t xx_un_linlck_chn; 3470Sstevel@tonic-gate uint_t un_pwcnt; 3480Sstevel@tonic-gate uint_t un_pwsize; 3490Sstevel@tonic-gate long long un_pwid; 3500Sstevel@tonic-gate uint_t un_rebuild_size; 3510Sstevel@tonic-gate uint_t un_percent_done; 3520Sstevel@tonic-gate union { 3530Sstevel@tonic-gate struct { 3540Sstevel@tonic-gate uint_t _t_un_resync_segment; 3550Sstevel@tonic-gate int _t_un_resync_index; 3560Sstevel@tonic-gate uint_t _t_un_resync_line_index; 3570Sstevel@tonic-gate } _resync; 3580Sstevel@tonic-gate struct { 3590Sstevel@tonic-gate daddr32_t _t_un_grow_tb; 3600Sstevel@tonic-gate uint_t _t_un_init_colcnt; 3610Sstevel@tonic-gate uint_t _t_un_init_iocnt; 3620Sstevel@tonic-gate } _init; 3630Sstevel@tonic-gate } _t_un; 3640Sstevel@tonic-gate uint_t un_resync_copysize; 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate /* 3670Sstevel@tonic-gate * This spot is 8 byte aligned!!! 3680Sstevel@tonic-gate * Don't change this arrangement. 3690Sstevel@tonic-gate */ 3700Sstevel@tonic-gate union { 3710Sstevel@tonic-gate struct { 3720Sstevel@tonic-gate mr_unit_ic_t *_t_mr_ic; 3730Sstevel@tonic-gate } _mric; 3740Sstevel@tonic-gate struct { 3750Sstevel@tonic-gate uint_t xx_un_linlck_mx[2]; 3760Sstevel@tonic-gate } _lckmx; 3770Sstevel@tonic-gate } _unic; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate short xx_un_linlck_cv; 3800Sstevel@tonic-gate int xx_un_mx[2]; 3810Sstevel@tonic-gate short xx_un_cv; 3820Sstevel@tonic-gate hsp_t un_hsp_id; 3830Sstevel@tonic-gate mr_column32_od_t un_column[1]; 3840Sstevel@tonic-gate } mr_unit32_od_t; 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate typedef struct raid_pwhdr { 3870Sstevel@tonic-gate uint_t rpw_magic; 3880Sstevel@tonic-gate uint_t rpw_sum; 3890Sstevel@tonic-gate int rpw_columnnum; 3900Sstevel@tonic-gate diskaddr_t rpw_blkno; 3910Sstevel@tonic-gate uint_t rpw_blkcnt; 3920Sstevel@tonic-gate long long rpw_id; 3930Sstevel@tonic-gate uint_t rpw_colcount; 3940Sstevel@tonic-gate uint_t rpw_column; 3950Sstevel@tonic-gate uint_t rpw_unit; 3960Sstevel@tonic-gate uint_t rpw_magic_ext; 3970Sstevel@tonic-gate uint_t rpw_origcolumncnt; 3980Sstevel@tonic-gate uint_t rpw_totalcolumncnt; 3990Sstevel@tonic-gate uint_t rpw_segsize; 4000Sstevel@tonic-gate diskaddr_t rpw_segsincolumn; 4010Sstevel@tonic-gate uint_t rpw_pwcnt; 4020Sstevel@tonic-gate uint_t rpw_pwsize; 4030Sstevel@tonic-gate diskaddr_t rpw_devstart; 4040Sstevel@tonic-gate diskaddr_t rpw_pwstart; 4050Sstevel@tonic-gate char rpw_filler[12]; 4060Sstevel@tonic-gate } raid_pwhdr_t; 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate /* 4090Sstevel@tonic-gate * For old 32 bit pre-write area 4100Sstevel@tonic-gate */ 4110Sstevel@tonic-gate typedef struct raid_pwhdr32_od { 4120Sstevel@tonic-gate uint_t rpw_magic; 4130Sstevel@tonic-gate uint_t rpw_sum; 4140Sstevel@tonic-gate int rpw_columnnum; 4150Sstevel@tonic-gate daddr32_t rpw_blkno; 4160Sstevel@tonic-gate daddr32_t rpw_blkcnt; 4170Sstevel@tonic-gate long long rpw_id; 4180Sstevel@tonic-gate uint_t rpw_colcount; 4190Sstevel@tonic-gate uint_t rpw_column; 4200Sstevel@tonic-gate uint_t rpw_unit; 4210Sstevel@tonic-gate uint_t rpw_magic_ext; 4220Sstevel@tonic-gate uint_t rpw_origcolumncnt; 4230Sstevel@tonic-gate uint_t rpw_totalcolumncnt; 4240Sstevel@tonic-gate uint_t rpw_segsize; 4250Sstevel@tonic-gate uint_t rpw_segsincolumn; 4260Sstevel@tonic-gate uint_t rpw_pwcnt; 4270Sstevel@tonic-gate uint_t rpw_pwsize; 4280Sstevel@tonic-gate uint_t rpw_devstart; 4290Sstevel@tonic-gate uint_t rpw_pwstart; 4300Sstevel@tonic-gate rus_state_t rpw_unit_state; 4310Sstevel@tonic-gate rcs_state_t rpw_next_column_state; 4320Sstevel@tonic-gate rcs_state_t rpw_prev_column_state; 4330Sstevel@tonic-gate } raid_pwhdr32_od_t; 4340Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 4350Sstevel@tonic-gate #pragma pack() 4360Sstevel@tonic-gate #endif 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate #ifdef _KERNEL 4390Sstevel@tonic-gate 4400Sstevel@tonic-gate /* 4410Sstevel@tonic-gate * the buffer header is only bp_mapin if it is needed. It is needed on 4420Sstevel@tonic-gate * all writes and on some reads. ps_mapin is non zero if the buffer is 4430Sstevel@tonic-gate * maped in. ps_mapin_mx protect ps_mapin. The protocol for usage is 4440Sstevel@tonic-gate * 4450Sstevel@tonic-gate * 1) check for non-zero and continue if non-zero 4460Sstevel@tonic-gate * 2) aquire the ps_mapin_mx 4470Sstevel@tonic-gate * 3) recheck for non-zero and continue if non-zero 4480Sstevel@tonic-gate * 4) bp_mapin 4490Sstevel@tonic-gate * 5) set ps_mapin to non-zero 4500Sstevel@tonic-gate * 6) drop ps_mapin_mx 4510Sstevel@tonic-gate * 4520Sstevel@tonic-gate * the reason for this is to avoid the mutex when possible. 4530Sstevel@tonic-gate */ 4540Sstevel@tonic-gate typedef struct md_raidps { /* raid parent save */ 4550Sstevel@tonic-gate DAEMON_QUEUE 4560Sstevel@tonic-gate uint_t ps_magic; 4570Sstevel@tonic-gate mr_unit_t *ps_un; 4580Sstevel@tonic-gate mdi_unit_t *ps_ui; 4590Sstevel@tonic-gate buf_t *ps_bp; 4600Sstevel@tonic-gate caddr_t ps_addr; 4610Sstevel@tonic-gate int ps_flags; 4620Sstevel@tonic-gate int ps_error; 4630Sstevel@tonic-gate int ps_frags; 4640Sstevel@tonic-gate int ps_pwfrags; 4650Sstevel@tonic-gate int ps_mapin; /* buffer maped in if non zero */ 4660Sstevel@tonic-gate kmutex_t ps_mx; 4670Sstevel@tonic-gate kmutex_t ps_mapin_mx; /* protects ps_mapin */ 4680Sstevel@tonic-gate } md_raidps_t; 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate /* flags for parent save area */ 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate #define MD_RPS_ERROR 0x0001 4730Sstevel@tonic-gate #define MD_RPS_READ 0x0020 4740Sstevel@tonic-gate #define MD_RPS_WRITE 0x0040 4750Sstevel@tonic-gate #define MD_RPS_DONE 0x0080 4760Sstevel@tonic-gate #define MD_RPS_INUSE 0x0100 4770Sstevel@tonic-gate #define MD_RPS_IODONE 0x0200 4780Sstevel@tonic-gate #define MD_RPS_HSREQ 0x0400 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate /* 4810Sstevel@tonic-gate * used in cs_state to describe the type of io operation in progress 4820Sstevel@tonic-gate */ 4830Sstevel@tonic-gate enum raid_io_stage { 4840Sstevel@tonic-gate RAID_NONE = 0x0, 4850Sstevel@tonic-gate RAID_READ_DONE = 0x1, 4860Sstevel@tonic-gate RAID_WRITE_DONE = 0x2, 4870Sstevel@tonic-gate RAID_PREWRITE_DONE = 0x4, 4880Sstevel@tonic-gate RAID_WRITE_PONLY_DONE = 0x8, 4890Sstevel@tonic-gate RAID_WRITE_DONLY_DONE = 0x10, 4900Sstevel@tonic-gate RAID_LINE_PWDONE = 0x20 4910Sstevel@tonic-gate }; 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate typedef struct md_raidcbuf { 4940Sstevel@tonic-gate DAEMON_QUEUE 4950Sstevel@tonic-gate uint_t cbuf_magic; 4960Sstevel@tonic-gate struct md_raidcbuf *cbuf_next; /* 0x10 */ 4970Sstevel@tonic-gate mr_unit_t *cbuf_un; 4980Sstevel@tonic-gate md_raidps_t *cbuf_ps; 4990Sstevel@tonic-gate int cbuf_column; 5000Sstevel@tonic-gate size_t cbuf_bcount; /* 0x20 */ 5010Sstevel@tonic-gate caddr_t cbuf_buffer; 5020Sstevel@tonic-gate int cbuf_sum; 5030Sstevel@tonic-gate int cbuf_pwslot; 5040Sstevel@tonic-gate int cbuf_pwcnt; /* 0x30 */ 5050Sstevel@tonic-gate int cbuf_flags; 5060Sstevel@tonic-gate buf_t cbuf_bp; 5070Sstevel@tonic-gate uint_t cbuf_pad[4]; 5080Sstevel@tonic-gate } md_raidcbuf_t; 5090Sstevel@tonic-gate #define CBUF_PW_INVALIDATE (0x00000001) 5100Sstevel@tonic-gate #define CBUF_WRITE (0x00000002) 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate typedef struct md_raidcs { 5130Sstevel@tonic-gate DAEMON_QUEUE 5140Sstevel@tonic-gate uint_t cs_magic; 5150Sstevel@tonic-gate minor_t cs_mdunit; 5160Sstevel@tonic-gate mr_unit_t *cs_un; 5170Sstevel@tonic-gate int cs_flags; 5180Sstevel@tonic-gate md_raidps_t *cs_ps; 5190Sstevel@tonic-gate diskaddr_t cs_line; 5200Sstevel@tonic-gate void (*cs_call)(); 5210Sstevel@tonic-gate void (*cs_error_call)(); 5220Sstevel@tonic-gate void (*cs_retry_call)(); 5230Sstevel@tonic-gate struct md_raidcs *cs_linlck_next; 5240Sstevel@tonic-gate struct md_raidcs *cs_linlck_prev; 5250Sstevel@tonic-gate long long cs_pwid; 5260Sstevel@tonic-gate int cs_dcolumn; 5270Sstevel@tonic-gate int cs_dpwslot; 5280Sstevel@tonic-gate uint_t cs_dflags; 5290Sstevel@tonic-gate int cs_pcolumn; 5300Sstevel@tonic-gate int cs_ppwslot; 5310Sstevel@tonic-gate uint_t cs_pflags; 5320Sstevel@tonic-gate size_t cs_bcount; 5330Sstevel@tonic-gate uint_t cs_blkcnt; 5340Sstevel@tonic-gate diskaddr_t cs_blkno; 5350Sstevel@tonic-gate diskaddr_t cs_lastblk; 5360Sstevel@tonic-gate int cs_loop; 5370Sstevel@tonic-gate caddr_t cs_addr; /* base address of io */ 5380Sstevel@tonic-gate off_t cs_offset; /* offset into the base */ 5390Sstevel@tonic-gate caddr_t cs_dbuffer; 5400Sstevel@tonic-gate caddr_t cs_pbuffer; 5410Sstevel@tonic-gate int cs_frags; 5420Sstevel@tonic-gate int cs_strategy_flag; 5430Sstevel@tonic-gate void *cs_strategy_private; 5440Sstevel@tonic-gate md_raidcbuf_t *cs_buflist; 5450Sstevel@tonic-gate int cs_error; 5460Sstevel@tonic-gate int cs_resync_check; 5470Sstevel@tonic-gate int cs_rstate; 5480Sstevel@tonic-gate enum raid_io_stage cs_stage; /* current io stage */ 5490Sstevel@tonic-gate md_raidcbuf_t *cs_pw_inval_list; 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate kmutex_t cs_mx; 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate buf_t cs_pbuf; 5540Sstevel@tonic-gate uint_t cs_pad1; 5550Sstevel@tonic-gate buf_t cs_hbuf; 5560Sstevel@tonic-gate uint_t cs_pad2; 5570Sstevel@tonic-gate /* Add new structure members HERE!! */ 5580Sstevel@tonic-gate buf_t cs_dbuf; 5590Sstevel@tonic-gate /* DO NOT add struture members here; cs_dbuf is dynamically sized */ 5600Sstevel@tonic-gate } md_raidcs_t; 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate /* value definitions for cs_resync_check */ 5630Sstevel@tonic-gate #define RCL_OKAY 0x01 /* write to both orig and alt */ 5640Sstevel@tonic-gate #define RCL_ERRED 0x08 /* treat column as rcs_ERRED */ 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate #define RCL_DATA_MASK 0x000000ff 5670Sstevel@tonic-gate #define RCL_PARITY_MASK 0x0000ff00 5680Sstevel@tonic-gate #define RCL_PARITY_OFFSET 8 /* insure masks match offset */ 5690Sstevel@tonic-gate 5700Sstevel@tonic-gate #define RCL_PARITY(value) (((value) & RCL_PARITY_MASK) >> \ 5710Sstevel@tonic-gate RCL_PARITY_OFFSET) 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate #define RCL_DATA(value) ((value) & RCL_DATA_MASK) 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate /* value definitions for cs_flags */ 5760Sstevel@tonic-gate #define MD_RCS_ISCALL 0x000001 /* call cs_call in interrupt */ 5770Sstevel@tonic-gate #define MD_RCS_UNDBUF 0x000002 /* holding unit data buffer */ 5780Sstevel@tonic-gate #define MD_RCS_UNPBUF 0x000004 /* holding unit parity buffer */ 5790Sstevel@tonic-gate #define MD_RCS_MPBUF 0x000008 5800Sstevel@tonic-gate #define MD_RCS_HAVE_PW_SLOTS 0x000010 /* pw slots gotten */ 5810Sstevel@tonic-gate #define MD_RCS_PWDONE 0x000040 /* pwfrags are decremented */ 5820Sstevel@tonic-gate #define MD_RCS_READER 0x000100 /* reader line lock needed */ 5830Sstevel@tonic-gate #define MD_RCS_WRITER 0x000200 /* writer line lock needed */ 5840Sstevel@tonic-gate #define MD_RCS_LLOCKD 0x000400 /* line lock held */ 5850Sstevel@tonic-gate #define MD_RCS_WAITING 0x000800 /* line lock waiting */ 5860Sstevel@tonic-gate #define MD_RCS_LINE 0x001000 /* full line write */ 5870Sstevel@tonic-gate #define MD_RCS_ERROR 0x010000 /* I/O error on this child */ 5880Sstevel@tonic-gate #define MD_RCS_RECOVERY 0x020000 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate /* value definitions for cs_pflags or cs_dflags */ 5910Sstevel@tonic-gate #define MD_RCS_ISUP 0x0002 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate /* value definitions for gcs_flags */ 5940Sstevel@tonic-gate #define MD_RGCS_ALLOCBUF 0x0001 5950Sstevel@tonic-gate /* returned value from raid_replay() */ 5960Sstevel@tonic-gate #define RAID_RPLY_SUCCESS 0x0000 5970Sstevel@tonic-gate #define RAID_RPLY_ALLOCFAIL 0x0001 5980Sstevel@tonic-gate #define RAID_RPLY_COMPREPLAY 0x0002 5990Sstevel@tonic-gate #define RAID_RPLY_READONLY 0x0004 6000Sstevel@tonic-gate #define RAID_RPLY_EIO 0x0008 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate typedef struct raid_rplybuf { 6030Sstevel@tonic-gate caddr_t rpl_data; 6040Sstevel@tonic-gate buf_t *rpl_buf; 6050Sstevel@tonic-gate } raid_rplybuf_t; 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate typedef struct raid_rplylst { 6080Sstevel@tonic-gate struct raid_rplylst *rpl_next; 6090Sstevel@tonic-gate uint_t rpl_colcnt; 6100Sstevel@tonic-gate long long rpl_id; 6110Sstevel@tonic-gate int rpl_column1; 6120Sstevel@tonic-gate uint_t rpl_slot1; 6130Sstevel@tonic-gate raid_pwhdr_t rpl_pwhdr1; 6140Sstevel@tonic-gate int rpl_column2; 6150Sstevel@tonic-gate uint_t rpl_slot2; 6160Sstevel@tonic-gate raid_pwhdr_t rpl_pwhdr2; 6170Sstevel@tonic-gate } raid_rplylst_t; 6180Sstevel@tonic-gate 6190Sstevel@tonic-gate /* Externals from raid.c */ 6200Sstevel@tonic-gate extern int raid_build_incore(void *, int); 6210Sstevel@tonic-gate extern void reset_raid(mr_unit_t *, minor_t, int); 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate /* Externals from raid_ioctl.c */ 6240Sstevel@tonic-gate extern int md_raid_ioctl(dev_t dev, int cmd, void *data, 6250Sstevel@tonic-gate int mode, IOLOCK *lockp); 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate /* rename named service functions */ 6280Sstevel@tonic-gate md_ren_svc_t raid_rename_check; 6290Sstevel@tonic-gate md_ren_svc_t raid_rename_lock; 6300Sstevel@tonic-gate md_ren_void_svc_t raid_rename_unlock; 6310Sstevel@tonic-gate 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate /* redefinitions of the union shared by resync and init */ 6340Sstevel@tonic-gate #define un_resync_segment _t_un._resync._t_un_resync_segment 6350Sstevel@tonic-gate #define un_resync_index _t_un._resync._t_un_resync_index 6360Sstevel@tonic-gate #define un_resync_line_index _t_un._resync._t_un_resync_line_index 6370Sstevel@tonic-gate 6380Sstevel@tonic-gate #define un_grow_tb _t_un._init._t_un_grow_tb 6390Sstevel@tonic-gate #define un_init_colcnt _t_un._init._t_un_init_colcnt 6400Sstevel@tonic-gate #define un_init_iocnt _t_un._init._t_un_init_iocnt 6410Sstevel@tonic-gate 6420Sstevel@tonic-gate #define MD_RFLAG_NEEDBUF (0x0001) 6430Sstevel@tonic-gate #define MD_RFLAG_CLEAR (0x0002) 6440Sstevel@tonic-gate #define MD_RFLAG_KEEP (0x0004) 6450Sstevel@tonic-gate #define MD_RFLAG_NEEDPW (0x0008) 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate extern void raid_set_state(mr_unit_t *un, int col, 6490Sstevel@tonic-gate rcs_state_t new_state, int force); 6500Sstevel@tonic-gate extern int raid_replay(mr_unit_t *un); 6510Sstevel@tonic-gate extern void raid_commit(mr_unit_t *un, mddb_recid_t *extras); 6520Sstevel@tonic-gate extern char *raid_unit_state(rus_state_t state); 6530Sstevel@tonic-gate extern intptr_t raid_hotspares(); 6540Sstevel@tonic-gate extern void raid_hs_release(hs_cmds_t cmd, mr_unit_t *un, 6550Sstevel@tonic-gate mddb_recid_t *recids, int hs_index); 6560Sstevel@tonic-gate extern int raid_internal_open(minor_t mnum, int flag, int otyp, 6570Sstevel@tonic-gate int oflags); 6580Sstevel@tonic-gate extern int raid_internal_close(minor_t mnum, int otyp, 6590Sstevel@tonic-gate int init_pw, int cflags); 6600Sstevel@tonic-gate extern int raid_build_pwslot(mr_unit_t *unit, int column_index); 6610Sstevel@tonic-gate extern void raid_free_pwslot(mr_unit_t *unit, int column_index); 6620Sstevel@tonic-gate extern void release_resync_request(minor_t mnum); 6630Sstevel@tonic-gate extern int resync_request(minor_t mnum, int column_index, 6640Sstevel@tonic-gate size_t copysize, md_error_t *ep); 6650Sstevel@tonic-gate extern int raid_resync_unit(minor_t mnum, md_error_t *ep); 6660Sstevel@tonic-gate extern void raid_line_reader_lock(md_raidcs_t *cs, 6670Sstevel@tonic-gate int resync_thread); 6680Sstevel@tonic-gate extern void raid_line_exit(md_raidcs_t *cs); 6690Sstevel@tonic-gate extern int raid_state_cnt(mr_unit_t *un, rcs_state_t state); 6700Sstevel@tonic-gate extern int raid_build_pw_reservation(mr_unit_t *un, 6710Sstevel@tonic-gate int colindex); 6720Sstevel@tonic-gate extern int init_pw_area(mr_unit_t *un, md_dev64_t dev_to_write, 6730Sstevel@tonic-gate diskaddr_t pwstart, uint_t col); 6740Sstevel@tonic-gate extern void init_buf(buf_t *bp, int flags, size_t size); 6750Sstevel@tonic-gate extern void destroy_buf(buf_t *bp); 6760Sstevel@tonic-gate extern void reset_buf(buf_t *bp, int flags, size_t size); 6770Sstevel@tonic-gate extern void md_raid_strategy(buf_t *pb, int flag, void *private); 6780Sstevel@tonic-gate extern void raid_free_pw_reservation(mr_unit_t *un, 6790Sstevel@tonic-gate int colindex); 6800Sstevel@tonic-gate extern void raid_fillin_rpw(mr_unit_t *un, 6810Sstevel@tonic-gate raid_pwhdr_t *pwhdrp, int col); 6820Sstevel@tonic-gate #endif /* _KERNEL */ 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate #ifdef __cplusplus 6850Sstevel@tonic-gate } 6860Sstevel@tonic-gate #endif 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate #endif /* _SYS_MD_RAID_H */ 689