]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IONetworking/IONetworkMedium.cpp
7a10de58b08c6cf93b7c348f2de4a81bec574990
[apple/xnu.git] / iokit / Families / IONetworking / IONetworkMedium.cpp
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 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * IONetworkMedium.cpp
26 *
27 * HISTORY
28 *
29 */
30
31 #include <IOKit/assert.h>
32 #include <IOKit/IOLib.h>
33 #include <libkern/c++/OSObject.h>
34 #include <libkern/c++/OSNumber.h>
35 #include <libkern/c++/OSCollectionIterator.h>
36 #include <libkern/c++/OSDictionary.h>
37 #include <libkern/c++/OSSerialize.h>
38 #include <IOKit/network/IONetworkMedium.h>
39
40 //---------------------------------------------------------------------------
41 // OSMetaClass macros.
42
43 #define super OSObject
44 OSDefineMetaClassAndStructors( IONetworkMedium, OSObject )
45 OSMetaClassDefineReservedUnused( IONetworkMedium, 0);
46 OSMetaClassDefineReservedUnused( IONetworkMedium, 1);
47 OSMetaClassDefineReservedUnused( IONetworkMedium, 2);
48 OSMetaClassDefineReservedUnused( IONetworkMedium, 3);
49
50 //---------------------------------------------------------------------------
51 // Initialize an IONetworkMedium instance.
52 //
53 // type: The medium type, the fields are encoded with bits defined in
54 // IONetworkMedium.h.
55 //
56 // speed: The maximum (or the only) link speed supported over this medium
57 // in units of bits per second.
58 //
59 // flags: An optional flag for the medium object.
60 // See IONetworkMedium.h for defined flags.
61 //
62 // index: An optional 32-bit index assigned by the caller. Drivers can use
63 // this to store an index or a pointer to a media table inside the
64 // driver, or it may map to a driver defined media type.
65 //
66 // name: An name to assign to this medium object. If 0, then a name
67 // will be created based on the medium type given using nameForType().
68 //
69 // Returns true on success, false otherwise.
70
71 bool IONetworkMedium::init(IOMediumType type,
72 UInt64 speed,
73 UInt32 flags = 0,
74 UInt32 index = 0,
75 const char * name = 0)
76 {
77 if ( super::init() == false )
78 return false;
79
80 _type = type;
81 _flags = flags;
82 _speed = speed;
83 _index = index;
84
85 if (name)
86 _name = OSSymbol::withCString(name);
87 else
88 _name = IONetworkMedium::nameForType(type);
89
90 if (!_name)
91 return false;
92
93 return true;
94 }
95
96 //---------------------------------------------------------------------------
97 // Factory method which performs allocation and initialization
98 // of an IONetworkMedium instance.
99 //
100 // Returns an IONetworkMedium instance on success, or 0 otherwise.
101
102 IONetworkMedium * IONetworkMedium::medium(IOMediumType type,
103 UInt64 speed,
104 UInt32 flags = 0,
105 UInt32 index = 0,
106 const char * name = 0)
107 {
108 IONetworkMedium * medium = new IONetworkMedium;
109
110 if (medium && !medium->init(type, speed, flags, index, name))
111 {
112 medium->release();
113 medium = 0;
114 }
115
116 return medium;
117 }
118
119 //---------------------------------------------------------------------------
120 // Free the IONetworkMedium instance.
121
122 void IONetworkMedium::free()
123 {
124 if (_name)
125 {
126 _name->release();
127 _name = 0;
128 }
129 super::free();
130 }
131
132 //---------------------------------------------------------------------------
133 // Return the assigned medium type.
134
135 IOMediumType IONetworkMedium::getType() const
136 {
137 return _type;
138 }
139
140 //---------------------------------------------------------------------------
141 // Return the medium flags.
142
143 UInt32 IONetworkMedium::getFlags() const
144 {
145 return _flags;
146 }
147
148 //---------------------------------------------------------------------------
149 // Return the maximum medium speed.
150
151 UInt64 IONetworkMedium::getSpeed() const
152 {
153 return _speed;
154 }
155
156 //---------------------------------------------------------------------------
157 // Return the assigned index.
158
159 UInt32 IONetworkMedium::getIndex() const
160 {
161 return _index;
162 }
163
164 //---------------------------------------------------------------------------
165 // Return the name for this instance.
166
167 const OSSymbol * IONetworkMedium::getName() const
168 {
169 return _name;
170 }
171
172 //---------------------------------------------------------------------------
173 // Given a medium type, create an unique OSymbol name for the medium.
174 // The caller is responsible for releasing the OSSymbol object returned.
175 //
176 // type: A medium type. See IONetworkMedium.h for type encoding.
177 //
178 // Returns an OSSymbol created based on the type provided.
179
180 const OSSymbol * IONetworkMedium::nameForType(IOMediumType type)
181 {
182 char buffer[10];
183
184 sprintf(buffer, "%08lx", type);
185
186 // Caller must remember to free the OSSymbol!
187 //
188 return OSSymbol::withCString(buffer);
189 }
190
191 //---------------------------------------------------------------------------
192 // Test for equality between two IONetworkMedium objects.
193 // Two IONetworkMedium objects are considered equal if
194 // they have similar properties assigned to them during initialization.
195 //
196 // medium: An IONetworkMedium to test against the IONetworkMedium
197 // object being called.
198 //
199 // Returns true if equal, false otherwise.
200
201 bool IONetworkMedium::isEqualTo(const IONetworkMedium * medium) const
202 {
203 return ( (medium->_name == _name) &&
204 (medium->_type == _type) &&
205 (medium->_flags == _flags) &&
206 (medium->_speed == _speed) &&
207 (medium->_index == _index) );
208 }
209
210 //---------------------------------------------------------------------------
211 // Test for equality between a IONetworkMedium object and an OSObject.
212 // The OSObject is considered equal to the IONetworkMedium object if the
213 // OSObject is an IONetworkMedium, and they have similar properties assigned
214 // to them during initialization.
215 //
216 // obj: An OSObject to test against the IONetworkMedium object being called.
217 //
218 // Returns true if equal, false otherwise.
219
220 bool IONetworkMedium::isEqualTo(const OSMetaClassBase * obj) const
221 {
222 IONetworkMedium * medium;
223 if ((medium = OSDynamicCast(IONetworkMedium, obj)))
224 return isEqualTo(medium);
225 else
226 return false;
227 }
228
229 //---------------------------------------------------------------------------
230 // Create an OSData containing an IOMediumDescriptor structure (not copied),
231 // and ask the OSData to serialize.
232 //
233 // s: An OSSerialize object to handle the serialization.
234 //
235 // Returns true on success, false otherwise.
236
237 static bool addNumberToDict(OSDictionary * dict,
238 const char * key,
239 UInt32 val,
240 UInt32 bits = 32)
241 {
242 OSNumber * num = OSNumber::withNumber(val, bits);
243 bool ret;
244
245 if ( num == 0 ) return false;
246 ret = dict->setObject( key, num );
247 num->release();
248 return ret;
249 }
250
251 bool IONetworkMedium::serialize(OSSerialize * s) const
252 {
253 bool ret;
254 OSDictionary * dict;
255
256 dict = OSDictionary::withCapacity(4);
257 if ( dict == 0 ) return false;
258
259 addNumberToDict(dict, kIOMediumType, getType());
260 addNumberToDict(dict, kIOMediumSpeed, getSpeed(), 64);
261 addNumberToDict(dict, kIOMediumIndex, getIndex());
262 addNumberToDict(dict, kIOMediumFlags, getFlags());
263
264 ret = dict->serialize(s);
265 dict->release();
266
267 return ret;
268 }
269
270 //---------------------------------------------------------------------------
271 // A helper function to add an IONetworkMedium object to a given dictionary.
272 // The name of the medium is used as the key for the new dictionary entry.
273 //
274 // dict: An OSDictionary object where the medium object should be added to.
275 // medium: The IONetworkMedium object to add to the dictionary.
276 //
277 // Returns true on success, false otherwise.
278
279 bool IONetworkMedium::addMedium(OSDictionary * dict,
280 const IONetworkMedium * medium)
281 {
282 // Arguments type checking.
283 //
284 if (!OSDynamicCast(OSDictionary, dict) ||
285 !OSDynamicCast(IONetworkMedium, medium))
286 return false;
287
288 return dict->setObject(medium->getName(), medium);
289 }
290
291 //---------------------------------------------------------------------------
292 // A helper function to remove an entry in a dictionary with a key that
293 // matches the name of the IONetworkMedium object provided.
294 //
295 // dict: An OSDictionary object where the medium object should be removed
296 // from.
297 // medium: The name of this medium object is used as the removal key.
298
299 void IONetworkMedium::removeMedium(OSDictionary * dict,
300 const IONetworkMedium * medium)
301 {
302 // Arguments type checking.
303 //
304 if (!OSDynamicCast(OSDictionary, dict) ||
305 !OSDynamicCast(IONetworkMedium, medium))
306 return;
307
308 dict->removeObject(medium->getName());
309 }
310
311 //---------------------------------------------------------------------------
312 // Iterate through a dictionary and return an IONetworkMedium entry that
313 // satisfies the matching criteria. Returns 0 if there is no match.
314
315 IONetworkMedium * IONetworkMedium::getMediumWithType(
316 const OSDictionary * dict,
317 IOMediumType type,
318 IOMediumType mask = 0)
319 {
320 OSCollectionIterator * iter;
321 OSSymbol * key;
322 IONetworkMedium * medium;
323 IONetworkMedium * match = 0;
324
325 if (!dict) return 0;
326
327 // Shouldn't withCollection take an (const OSDictionary *) argument?
328
329 iter = OSCollectionIterator::withCollection((OSDictionary *) dict);
330 if (!iter)
331 return 0;
332
333 while ( (key = (OSSymbol *) iter->getNextObject()) )
334 {
335 medium = OSDynamicCast(IONetworkMedium, dict->getObject(key));
336 if (medium == 0) continue;
337
338 if ( ( (medium->getType() ^ type) & ~mask) == 0 )
339 {
340 match = medium;
341 break;
342 }
343 }
344
345 iter->release();
346
347 return match;
348 }
349
350 IONetworkMedium * IONetworkMedium::getMediumWithIndex(
351 const OSDictionary * dict,
352 UInt32 index,
353 UInt32 mask = 0)
354 {
355 OSCollectionIterator * iter;
356 OSSymbol * key;
357 IONetworkMedium * medium;
358 IONetworkMedium * match = 0;
359
360 if (!dict) return 0;
361
362 // Shouldn't withCollection take an (const OSDictionary *) argument?
363
364 iter = OSCollectionIterator::withCollection((OSDictionary *) dict);
365 if (!iter)
366 return 0;
367
368 while ( (key = (OSSymbol *) iter->getNextObject()) )
369 {
370 medium = OSDynamicCast(IONetworkMedium, dict->getObject(key));
371 if (medium == 0) continue;
372
373 if ( ( (medium->getIndex() ^ index) & ~mask) == 0 )
374 {
375 match = medium;
376 break;
377 }
378 }
379
380 iter->release();
381
382 return match;
383 }