]> git.saurik.com Git - apple/xnu.git/blame - iokit/Families/IONetworking/IONetworkMedium.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Families / IONetworking / IONetworkMedium.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 * 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
44OSDefineMetaClassAndStructors( IONetworkMedium, OSObject )
45OSMetaClassDefineReservedUnused( IONetworkMedium, 0);
46OSMetaClassDefineReservedUnused( IONetworkMedium, 1);
47OSMetaClassDefineReservedUnused( IONetworkMedium, 2);
48OSMetaClassDefineReservedUnused( 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
71bool 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
102IONetworkMedium * 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
122void 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
135IOMediumType IONetworkMedium::getType() const
136{
137 return _type;
138}
139
140//---------------------------------------------------------------------------
141// Return the medium flags.
142
143UInt32 IONetworkMedium::getFlags() const
144{
145 return _flags;
146}
147
148//---------------------------------------------------------------------------
149// Return the maximum medium speed.
150
151UInt64 IONetworkMedium::getSpeed() const
152{
153 return _speed;
154}
155
156//---------------------------------------------------------------------------
157// Return the assigned index.
158
159UInt32 IONetworkMedium::getIndex() const
160{
161 return _index;
162}
163
164//---------------------------------------------------------------------------
165// Return the name for this instance.
166
167const 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
180const 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
201bool 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
220bool 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
237static 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
251bool 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
279bool 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
299void 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
315IONetworkMedium * 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
350IONetworkMedium * 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}