]> git.saurik.com Git - apple/xnu.git/blame - iokit/Families/IOStorage/IOPartitionScheme.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Families / IOStorage / IOPartitionScheme.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, 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#include <IOKit/storage/IOPartitionScheme.h>
24
25#define super IOStorage
26OSDefineMetaClassAndStructors(IOPartitionScheme, IOStorage)
27
28// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
29
30IOMedia * IOPartitionScheme::getProvider() const
31{
32 //
33 // Obtain this object's provider. We override the superclass's method
34 // to return a more specific subclass of OSObject -- an IOMedia. This
35 // method serves simply as a convenience to subclass developers.
36 //
37
38 return (IOMedia *) IOService::getProvider();
39}
40
41// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42
43bool IOPartitionScheme::init(OSDictionary * properties = 0)
44{
45 //
46 // Initialize this object's minimal state.
47 //
48
49 if (super::init(properties) == false) return false;
50
51 _openLevel = kIOStorageAccessNone;
52 _openReaders = OSSet::withCapacity(16);
53 _openReaderWriters = OSSet::withCapacity(16);
54
55 if (_openReaders == 0 || _openReaderWriters == 0) return false;
56
57 return true;
58}
59
60// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
61
62void IOPartitionScheme::free()
63{
64 //
65 // Free all of this object's outstanding resources.
66 //
67
68 if (_openReaders) _openReaders->release();
69 if (_openReaderWriters) _openReaderWriters->release();
70
71 super::free();
72}
73
74// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
75
76bool IOPartitionScheme::handleOpen(IOService * client,
77 IOOptionBits options,
78 void * argument)
79{
80 //
81 // The handleOpen method grants or denies permission to access this object
82 // to an interested client. The argument is an IOStorageAccess value that
83 // specifies the level of access desired -- reader or reader-writer.
84 //
85 // This method can be invoked to upgrade or downgrade the access level for
86 // an existing client as well. The previous access level will prevail for
87 // upgrades that fail, of course. A downgrade should never fail. If the
88 // new access level should be the same as the old for a given client, this
89 // method will do nothing and return success. In all cases, one, singular
90 // close-per-client is expected for all opens-per-client received.
91 //
92 // This implementation replaces the IOService definition of handleOpen().
93 //
94 // We are guaranteed that no other opens or closes will be processed until
95 // we make our decision, change our state, and return from this method.
96 //
97
98 IOStorageAccess access = (IOStorageAccess) argument;
99 IOStorageAccess level;
100
101 assert(client);
102 assert( access == kIOStorageAccessReader ||
103 access == kIOStorageAccessReaderWriter );
104
105 //
106 // A partition scheme multiplexes the opens it receives from several clients
107 // and sends one open to the level below that satisfies the highest level of
108 // access.
109 //
110
111 unsigned writers = _openReaderWriters->getCount();
112
113 if (_openReaderWriters->containsObject(client)) writers--;
114 if (access == kIOStorageAccessReaderWriter) writers++;
115
116 level = (writers) ? kIOStorageAccessReaderWriter : kIOStorageAccessReader;
117
118 //
119 // Determine whether the levels below us accept this open or not (we avoid
120 // the open if the required access is the access we already hold).
121 //
122
123 if (_openLevel != level) // (has open level changed?)
124 {
125 IOStorage * provider = OSDynamicCast(IOStorage, getProvider());
126
127 if (provider && provider->open(this, options, level) == false)
128 return false;
129 }
130
131 //
132 // Process the open.
133 //
134
135 if (access == kIOStorageAccessReader)
136 {
137 _openReaders->setObject(client);
138
139 _openReaderWriters->removeObject(client); // (for a downgrade)
140 }
141 else // (access == kIOStorageAccessReaderWriter)
142 {
143 _openReaderWriters->setObject(client);
144
145 _openReaders->removeObject(client); // (for an upgrade)
146 }
147
148 _openLevel = level;
149
150 return true;
151}
152
153// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
154
155bool IOPartitionScheme::handleIsOpen(const IOService * client) const
156{
157 //
158 // The handleIsOpen method determines whether the specified client, or any
159 // client if none is specificed, presently has an open on this object.
160 //
161 // This implementation replaces the IOService definition of handleIsOpen().
162 //
163 // We are guaranteed that no other opens or closes will be processed until
164 // we return from this method.
165 //
166
167 if (client == 0) return (_openLevel != kIOStorageAccessNone);
168
169 return ( _openReaderWriters->containsObject(client) ||
170 _openReaders->containsObject(client) );
171}
172
173// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
174
175void IOPartitionScheme::handleClose(IOService * client, IOOptionBits options)
176{
177 //
178 // The handleClose method closes the client's access to this object.
179 //
180 // This implementation replaces the IOService definition of handleClose().
181 //
182 // We are guaranteed that no other opens or closes will be processed until
183 // we change our state and return from this method.
184 //
185
186 assert(client);
187
188 //
189 // Process the close.
190 //
191
192 if (_openReaderWriters->containsObject(client)) // (is it a reader-writer?)
193 {
194 _openReaderWriters->removeObject(client);
195 }
196 else if (_openReaders->containsObject(client)) // (is the client a reader?)
197 {
198 _openReaders->removeObject(client);
199 }
200 else // (is the client is an imposter?)
201 {
202 assert(0);
203 return;
204 }
205
206 //
207 // Reevaluate the open we have on the level below us. If no opens remain,
208 // we close, or if no reader-writer remains, but readers do, we downgrade.
209 //
210
211 IOStorageAccess level;
212
213 if (_openReaderWriters->getCount()) level = kIOStorageAccessReaderWriter;
214 else if (_openReaders->getCount()) level = kIOStorageAccessReader;
215 else level = kIOStorageAccessNone;
216
217 if (_openLevel != level) // (has open level changed?)
218 {
219 IOStorage * provider = OSDynamicCast(IOStorage, getProvider());
220
221 assert(level != kIOStorageAccessReaderWriter);
222
223 if (provider)
224 {
225 if (level == kIOStorageAccessNone) // (is a close in order?)
226 {
227 provider->close(this, options);
228 }
229 else // (is a downgrade in order?)
230 {
231 bool success;
232 success = provider->open(this, 0, level);
233 assert(success); // (should never fail, unless avoided deadlock)
234 }
235 }
236
237 _openLevel = level; // (set new open level)
238 }
239}
240
241// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
242
243void IOPartitionScheme::read(IOService * /* client */,
244 UInt64 byteStart,
245 IOMemoryDescriptor * buffer,
246 IOStorageCompletion completion)
247{
248 //
249 // Read data from the storage object at the specified byte offset into the
250 // specified buffer, asynchronously. When the read completes, the caller
251 // will be notified via the specified completion action.
252 //
253 // The buffer will be retained for the duration of the read.
254 //
255 // For simple partition schemes, the default behavior is to simply pass the
256 // read through to the provider media. More complex partition schemes such
257 // as RAID will need to do extra processing here.
258 //
259
260 getProvider()->read(this, byteStart, buffer, completion);
261}
262
263// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
264
265void IOPartitionScheme::write(IOService * /* client */,
266 UInt64 byteStart,
267 IOMemoryDescriptor * buffer,
268 IOStorageCompletion completion)
269{
270 //
271 // Write data into the storage object at the specified byte offset from the
272 // specified buffer, asynchronously. When the write completes, the caller
273 // will be notified via the specified completion action.
274 //
275 // The buffer will be retained for the duration of the write.
276 //
277 // For simple partition schemes, the default behavior is to simply pass the
278 // write through to the provider media. More complex partition schemes such
279 // as RAID will need to do extra processing here.
280 //
281
282 getProvider()->write(this, byteStart, buffer, completion);
283}
284
285// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
286
287IOReturn IOPartitionScheme::synchronizeCache(IOService * client)
288{
289 return getProvider()->synchronizeCache(this);
290}
291
292// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
293
294OSMetaClassDefineReservedUnused(IOPartitionScheme, 0);
295
296// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
297
298OSMetaClassDefineReservedUnused(IOPartitionScheme, 1);
299
300// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
301
302OSMetaClassDefineReservedUnused(IOPartitionScheme, 2);
303
304// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
305
306OSMetaClassDefineReservedUnused(IOPartitionScheme, 3);
307
308// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
309
310OSMetaClassDefineReservedUnused(IOPartitionScheme, 4);
311
312// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
313
314OSMetaClassDefineReservedUnused(IOPartitionScheme, 5);
315
316// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
317
318OSMetaClassDefineReservedUnused(IOPartitionScheme, 6);
319
320// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
321
322OSMetaClassDefineReservedUnused(IOPartitionScheme, 7);
323
324// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
325
326OSMetaClassDefineReservedUnused(IOPartitionScheme, 8);
327
328// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
329
330OSMetaClassDefineReservedUnused(IOPartitionScheme, 9);
331
332// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
333
334OSMetaClassDefineReservedUnused(IOPartitionScheme, 10);
335
336// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
337
338OSMetaClassDefineReservedUnused(IOPartitionScheme, 11);
339
340// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
341
342OSMetaClassDefineReservedUnused(IOPartitionScheme, 12);
343
344// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
345
346OSMetaClassDefineReservedUnused(IOPartitionScheme, 13);
347
348// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
349
350OSMetaClassDefineReservedUnused(IOPartitionScheme, 14);
351
352// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
353
354OSMetaClassDefineReservedUnused(IOPartitionScheme, 15);
355
356// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
357
358OSMetaClassDefineReservedUnused(IOPartitionScheme, 16);
359
360// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
361
362OSMetaClassDefineReservedUnused(IOPartitionScheme, 17);
363
364// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
365
366OSMetaClassDefineReservedUnused(IOPartitionScheme, 18);
367
368// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
369
370OSMetaClassDefineReservedUnused(IOPartitionScheme, 19);
371
372// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
373
374OSMetaClassDefineReservedUnused(IOPartitionScheme, 20);
375
376// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
377
378OSMetaClassDefineReservedUnused(IOPartitionScheme, 21);
379
380// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
381
382OSMetaClassDefineReservedUnused(IOPartitionScheme, 22);
383
384// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
385
386OSMetaClassDefineReservedUnused(IOPartitionScheme, 23);
387
388// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
389
390OSMetaClassDefineReservedUnused(IOPartitionScheme, 24);
391
392// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
393
394OSMetaClassDefineReservedUnused(IOPartitionScheme, 25);
395
396// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
397
398OSMetaClassDefineReservedUnused(IOPartitionScheme, 26);
399
400// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
401
402OSMetaClassDefineReservedUnused(IOPartitionScheme, 27);
403
404// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
405
406OSMetaClassDefineReservedUnused(IOPartitionScheme, 28);
407
408// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
409
410OSMetaClassDefineReservedUnused(IOPartitionScheme, 29);
411
412// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
413
414OSMetaClassDefineReservedUnused(IOPartitionScheme, 30);
415
416// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
417
418OSMetaClassDefineReservedUnused(IOPartitionScheme, 31);