1/*
2 * Copyright (c) 2001-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#ifndef _APPLERAIDMEMBER_H
24#define _APPLERAIDMEMBER_H
25
26#define kAppleRAIDSignature "AppleRAIDHeader"
27
28enum {
29    kAppleRAIDHeaderSize	= 0x1000,
30    kAppleRAIDDefaultChunkSize	= 0x8000
31};
32
33#define ARHEADER_OFFSET(s)  ( (UInt64)(s) / kAppleRAIDHeaderSize * kAppleRAIDHeaderSize - kAppleRAIDHeaderSize )
34
35struct AppleRAIDHeaderV2 {
36    char	raidSignature[16];
37    char	raidUUID[64];
38    char	memberUUID[64];
39    UInt64	size;
40    char 	plist[];
41};
42typedef struct AppleRAIDHeaderV2 AppleRAIDHeaderV2;
43
44#define ByteSwapHeaderV2(header) \
45{ \
46	(header)->size		= OSSwapBigToHostInt64((header)->size); \
47}
48
49// structs for primary meta data
50
51#define kAppleRAIDPrimaryMagic	"AppleRAIDPrimary"
52
53#define kAppleRAIDPrimaryBitMap		1
54#define kAppleRAIDPrimaryExtents	2
55#define kAppleRAIDPrimaryLVG		3
56
57typedef struct AppleRAIDPrimaryOnDisk {
58    char			priMagic[32];		// "AppleRAIDPrimary"
59    UInt64			priSize;		// max size of bit map
60    UInt64			priUsed;		// current size of bit map
61    UInt32			priType;		// bitmap, extent, TOC
62    UInt32			priSequenceNumber;
63    union {
64	UInt64			bytesPerBit;
65	UInt64			extentCount;
66	UInt64			volumeCount;
67    } pri;
68    char			reserved[448];		// 32 + 3*8 + 2*4 = 64 + 448 = 512
69} AppleRAIDPrimaryOnDisk;
70
71#define ByteSwapPrimaryHeader(header) \
72{ \
73	(header)->priSize		= OSSwapBigToHostInt64((header)->priSize); \
74	(header)->priUsed		= OSSwapBigToHostInt64((header)->priUsed); \
75	(header)->priType		= OSSwapBigToHostInt32((header)->priType); \
76	(header)->priSequenceNumber	= OSSwapBigToHostInt32((header)->priSequenceNumber); \
77	(header)->pri.bytesPerBit	= OSSwapBigToHostInt64((header)->pri.bytesPerBit); \
78}
79
80// use special extents magic for pointers to next block
81
82typedef struct AppleRAIDExtentOnDisk
83{
84    UInt64				extentByteOffset;
85    UInt64				extentByteCount;
86} AppleRAIDExtentOnDisk;
87
88#define ByteSwapExtent(extent) \
89{ \
90	(extent)->extentByteOffset	= OSSwapBigToHostInt64((extent)->extentByteOffset); \
91	(extent)->extentByteCount	= OSSwapBigToHostInt64((extent)->extentByteCount); \
92}
93
94#ifdef KERNEL
95
96#include <uuid/uuid.h>
97
98#define kAppleRAIDBaseOffsetKey		"appleraid-BaseOffset"		// CFNumber 64bit
99#define kAppleRAIDNativeBlockSizeKey	"appleraid-NativeBlockSize"	// CFNumber 64bit
100#define kAppleRAIDMemberCountKey	"appleraid-MemberCount"		// CFNumber 32bit
101
102
103enum {
104    kAppleRAIDMemberStateBroken = 0,
105    kAppleRAIDMemberStateSpare,
106    kAppleRAIDMemberStateClosed,
107    kAppleRAIDMemberStateClosing,
108    kAppleRAIDMemberStateRebuilding,
109    kAppleRAIDMemberStateOpen
110};
111
112class AppleRAID;
113
114class AppleRAIDMember: public IOStorage {
115
116    OSDeclareDefaultStructors(AppleRAIDMember)
117
118private:
119    IOMedia *			arTarget;		// short cut to provider
120
121    UInt64			arHeaderOffset;
122    IOBufferMemoryDescriptor *	arHeaderBuffer;
123    thread_call_t		arSyncronizeCacheThreadCall;
124
125protected:
126
127    OSDictionary *		arHeader;
128
129    AppleRAID *			arController;
130
131    UInt32			arMemberState;
132    UInt32			arMemberIndex;
133
134    UInt64			arNativeBlockSize;
135    UInt64			arBaseOffset;
136
137    bool			arIsEjectable;
138    bool			arIsWritable;
139    bool			arIsRAIDMember;
140
141    virtual bool handleOpen(IOService * client, IOOptionBits options, void * access);
142    virtual bool handleIsOpen(const IOService* client) const;
143    virtual void handleClose(IOService*client, IOOptionBits options);
144
145public:
146
147    virtual bool init(OSDictionary * properties = 0);
148    virtual void free(void);
149
150    virtual bool start(IOService * provider);
151    virtual void stop(IOService * provider);
152    virtual bool requestTerminate(IOService *provider, IOOptionBits options);
153
154    virtual void read(IOService *         client,
155		      UInt64              byteStart,
156		      IOMemoryDescriptor* buffer,
157		      IOStorageAttributes * attributes,
158		      IOStorageCompletion* completion);
159    virtual void write(IOService *         client,
160                       UInt64              byteStart,
161                       IOMemoryDescriptor * buffer,
162		       IOStorageAttributes * attributes,
163		       IOStorageCompletion *  completion);
164    virtual IOReturn synchronizeCache(IOService * client);
165    virtual IOReturn synchronizeCacheCallout(AppleRAIDSet *masterSet);
166
167    virtual IOReturn readRAIDHeader(void);
168    virtual IOReturn writeRAIDHeader(void);
169    virtual IOReturn updateRAIDHeader(OSDictionary * props);
170    virtual IOReturn zeroRAIDHeader(void);
171
172    virtual IOReturn parseRAIDHeaderV1(void);
173    virtual IOReturn buildOnDiskHeaderV1(void);
174    virtual IOReturn parseRAIDHeaderV2(void);
175    virtual IOReturn buildOnDiskHeaderV2(void);
176
177    virtual IOBufferMemoryDescriptor * readPrimaryMetaData(void);
178    virtual IOReturn writePrimaryMetaData(IOBufferMemoryDescriptor * primaryBuffer);
179
180    virtual OSDictionary * getHeader(void);
181    virtual OSObject * getHeaderProperty( const OSString * aKey) const;
182    virtual OSObject * getHeaderProperty( const char * aKey) const;
183    virtual bool setHeaderProperty(const OSString * aKey, OSObject * anObject);
184    virtual bool setHeaderProperty(const char * aKey, OSObject * anObject);
185    virtual bool setHeaderProperty(const char * aKey, const char * cString);
186    virtual bool setHeaderProperty(const char * aKey, unsigned long long aValue, unsigned int aNumberOfBits);
187
188    virtual const OSString * getSetName(void);
189    virtual const char * getSetNameString(void);
190    virtual const OSString * getUUID(void);
191    virtual const char * getUUIDString(void);
192    virtual const OSString * getSetUUID(void);
193    virtual const char * getSetUUIDString(void);
194    virtual const OSString * getDiskName(void);
195
196    virtual IOStorage * getTarget(void) const;
197    virtual bool isRAIDSet(void);
198    virtual bool isRAIDMember(void);
199    virtual bool isSpare(void);
200    virtual bool isBroken(void);
201    virtual UInt64 getSize(void) const;
202    virtual UInt64 getUsableSize() const;
203    virtual UInt64 getPrimaryMaxSize(void) const;
204    virtual UInt64 getSecondarySize(void) const;
205    inline  UInt32 getMemberIndex(void) const	{ return arMemberIndex; };
206    virtual void setMemberIndex(UInt32 index);
207
208    virtual bool isEjectable(void) const;
209    virtual bool isWritable(void) const;
210    virtual UInt64 getBase(void) const;
211
212    virtual bool addBootDeviceInfo(OSArray * bootArray);
213    virtual OSDictionary * getMemberProperties(void);
214
215    virtual bool changeMemberState(UInt32 newState, bool force = 0);
216    inline  UInt32 getMemberState(void)		{ return arMemberState; };
217};
218
219#endif KERNEL
220
221#endif /* ! _APPLERAIDMEMBER_H */
222