|
|
1.1 ! root 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++/OSData.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: ! 46: //--------------------------------------------------------------------------- ! 47: // Initialize an IONetworkMedium instance. ! 48: // ! 49: // type: The medium type, the fields are encoded with bits defined in ! 50: // IONetworkMedium.h. ! 51: // ! 52: // speed: The maximum (or the only) link speed supported over this medium ! 53: // in units of bits per second. ! 54: // ! 55: // flags: An optional flag for the medium object. ! 56: // See IONetworkMedium.h for defined flags. ! 57: // ! 58: // index: An optional 32-bit index assigned by the caller. Drivers can use ! 59: // this to store an index or a pointer to a media table inside the ! 60: // driver, or it may map to a driver defined media type. ! 61: // ! 62: // name: An name to assign to this medium object. If 0, then a name ! 63: // will be created based on the medium type given using nameForType(). ! 64: // ! 65: // Returns true on success, false otherwise. ! 66: ! 67: bool IONetworkMedium::init(IOMediumType type, ! 68: UInt64 speed, ! 69: UInt32 flags = 0, ! 70: UInt32 index = 0, ! 71: const char * name = 0) ! 72: { ! 73: if (!super::init()) ! 74: return false; ! 75: ! 76: _desc = (IOMediumDescriptor *) IOMalloc(sizeof(*_desc)); ! 77: if (!_desc) ! 78: return false; ! 79: bzero(_desc, sizeof(*_desc)); ! 80: ! 81: _desc->type = type; ! 82: _desc->flags = flags; ! 83: _desc->speed = speed; ! 84: _desc->data = index; ! 85: ! 86: if (name) ! 87: _name = OSSymbol::withCString(name); ! 88: else ! 89: _name = IONetworkMedium::nameForType(type); ! 90: ! 91: if (!_name) ! 92: return false; ! 93: ! 94: return true; ! 95: } ! 96: ! 97: //--------------------------------------------------------------------------- ! 98: // Factory method which performs allocation and initialization ! 99: // of an IONetworkMedium instance. ! 100: // ! 101: // Returns an IONetworkMedium instance on success, or 0 otherwise. ! 102: ! 103: IONetworkMedium * IONetworkMedium::medium(IOMediumType type, ! 104: UInt64 speed, ! 105: UInt32 flags = 0, ! 106: UInt32 index = 0, ! 107: const char * name = 0) ! 108: { ! 109: IONetworkMedium * medium = new IONetworkMedium; ! 110: ! 111: if (medium && !medium->init(type, speed, flags, index, name)) ! 112: { ! 113: medium->release(); ! 114: medium = 0; ! 115: } ! 116: ! 117: return medium; ! 118: } ! 119: ! 120: //--------------------------------------------------------------------------- ! 121: // Free the IONetworkMedium instance. ! 122: ! 123: void IONetworkMedium::free() ! 124: { ! 125: if (_name) ! 126: _name->release(); ! 127: if (_desc) ! 128: IOFree(_desc, sizeof(*_desc)); ! 129: ! 130: super::free(); ! 131: } ! 132: ! 133: //--------------------------------------------------------------------------- ! 134: // Return the assigned medium type. ! 135: ! 136: IOMediumType IONetworkMedium::getType() const ! 137: { ! 138: return _desc->type; ! 139: } ! 140: ! 141: //--------------------------------------------------------------------------- ! 142: // Return the medium flags. ! 143: ! 144: UInt32 IONetworkMedium::getFlags() const ! 145: { ! 146: return _desc->flags; ! 147: } ! 148: ! 149: //--------------------------------------------------------------------------- ! 150: // Return the maximum medium speed. ! 151: ! 152: UInt64 IONetworkMedium::getSpeed() const ! 153: { ! 154: return _desc->speed; ! 155: } ! 156: ! 157: //--------------------------------------------------------------------------- ! 158: // Return the assigned index. ! 159: ! 160: UInt32 IONetworkMedium::getIndex() const ! 161: { ! 162: return _desc->data; ! 163: } ! 164: ! 165: //--------------------------------------------------------------------------- ! 166: // Return the name for this instance. ! 167: ! 168: const OSSymbol * IONetworkMedium::getName() const ! 169: { ! 170: return _name; ! 171: } ! 172: ! 173: //--------------------------------------------------------------------------- ! 174: // descP: The IOMediumDescriptor structure associated with the ! 175: // instance is copied to a structure provided by the caller. ! 176: ! 177: void IONetworkMedium::getDescriptor(IOMediumDescriptor * descP) const ! 178: { ! 179: assert(descP); ! 180: bcopy(_desc, descP, sizeof(*descP)); ! 181: } ! 182: ! 183: //=========================================================================== ! 184: // The definitions and the routines were adapted from FreeBSD ! 185: // (net/if_media.c). Should try to reuse the similar function in BSD. ! 186: //=========================================================================== ! 187: /* ! 188: * Copyright (c) 1997 ! 189: * Jonathan Stone and Jason R. Thorpe. All rights reserved. ! 190: * ! 191: * This software is derived from information provided by Matt Thomas. ! 192: * ! 193: * Redistribution and use in source and binary forms, with or without ! 194: * modification, are permitted provided that the following conditions ! 195: * are met: ! 196: * 1. Redistributions of source code must retain the above copyright ! 197: * notice, this list of conditions and the following disclaimer. ! 198: * 2. Redistributions in binary form must reproduce the above copyright ! 199: * notice, this list of conditions and the following disclaimer in the ! 200: * documentation and/or other materials provided with the distribution. ! 201: * 3. All advertising materials mentioning features or use of this software ! 202: * must display the following acknowledgement: ! 203: * This product includes software developed by Jonathan Stone ! 204: * and Jason R. Thorpe for the NetBSD Project. ! 205: * 4. The names of the authors may not be used to endorse or promote products ! 206: * derived from this software without specific prior written permission. ! 207: * ! 208: * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR ! 209: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ! 210: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ! 211: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ! 212: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ! 213: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ! 214: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED ! 215: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ! 216: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 217: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 218: * SUCH DAMAGE. ! 219: */ ! 220: ! 221: /* ! 222: * Append a C string to a buffer. A counter is updated with the remaining ! 223: * size of the buffer. ! 224: */ ! 225: static void append_string(char ** buf, ! 226: int * remain, ! 227: const char * str) ! 228: { ! 229: char * buffer = *buf; ! 230: int needed_length; ! 231: ! 232: if (!str) ! 233: return; ! 234: ! 235: // The remaining size must be big enough for 'str', ! 236: // and a terminating null character. ! 237: ! 238: needed_length = strlen(str) + 1; ! 239: ! 240: if (*remain >= needed_length) { // buffer is large enough ! 241: bcopy(str, buffer, strlen(str)); ! 242: buffer += strlen(str); ! 243: *buffer = '\0'; ! 244: ! 245: // decrement the remaining count, not counting the null char. ! 246: // ! 247: *remain -= (needed_length - 1); ! 248: *buf = buffer; ! 249: } ! 250: } ! 251: ! 252: struct IOMediumTypesAndOptions { ! 253: struct IOMediumDescription * types; ! 254: struct IOMediumDescription * options; ! 255: }; ! 256: ! 257: static struct IOMediumDescription familyDescriptions[] = ! 258: kIOMediumFamilyDescriptions; ! 259: ! 260: static struct IOMediumDescription ethernetDescriptions[] = ! 261: kIOMediumEthernetDescriptions; ! 262: ! 263: static struct IOMediumDescription ethernetOptionDescriptions[] = ! 264: kIOMediumEthernetOptionDescriptions; ! 265: ! 266: static struct IOMediumDescription commonDescriptions[] = ! 267: kIOMediumCommonDescriptions; ! 268: ! 269: static struct IOMediumDescription commonOptionDescriptions[] = ! 270: kIOMediumCommonOptionDescriptions; ! 271: ! 272: static struct IOMediumTypesAndOptions typesAndOptionsTable[] = { ! 273: { ! 274: ðernetDescriptions[0], ! 275: ðernetOptionDescriptions[0] ! 276: }, ! 277: }; ! 278: ! 279: #define IO_IFM_APPEND_OPTION(str) { \ ! 280: if (seen_option == 0) \ ! 281: append_string(&buf, &maxlen, " ("); \ ! 282: append_string(&buf, &maxlen, seen_option++ ? "," : ""); \ ! 283: append_string(&buf, &maxlen, str); \ ! 284: } ! 285: ! 286: /* ! 287: * print a media word. ! 288: */ ! 289: static int ! 290: ifmedia_printword(int ifmw, char * buf, int maxlen) ! 291: { ! 292: struct IOMediumDescription * desc; ! 293: struct IOMediumTypesAndOptions * ttos; ! 294: int seen_option = 0; ! 295: ! 296: /* Find the media family first */ ! 297: for (desc = familyDescriptions, ttos = typesAndOptionsTable; ! 298: desc->string != NULL; ! 299: desc++, ttos++) ! 300: if (IOMediumGetFamily(ifmw) == desc->word) ! 301: break; ! 302: ! 303: if (desc->string == NULL) ! 304: return 0; // unknown family type. ! 305: ! 306: #if 0 // disable family printing (e.g. Ethernet). ! 307: append_string(&buf, &maxlen, desc->string); ! 308: #endif ! 309: ! 310: /* ! 311: * Print the family specific type description. If the description ! 312: * is not found, then look at the common type descriptions. ! 313: */ ! 314: for (desc = ttos->types; desc->string != NULL; desc++) ! 315: if (IOMediumGetType(ifmw) == desc->word) ! 316: goto got_subtype; ! 317: ! 318: for (desc = commonDescriptions; desc->string != NULL; desc++) ! 319: if (IOMediumGetIndex(ifmw) == desc->word) ! 320: break; ! 321: ! 322: if (desc->string == NULL) ! 323: return 0; // unknown family specific type. ! 324: ! 325: got_subtype: ! 326: #if 0 // by disabling type printing, we don't need the space padding. ! 327: append_string(&buf, &maxlen, " "); ! 328: #endif ! 329: append_string(&buf, &maxlen, desc->string); ! 330: ! 331: /* ! 332: * Look for common options. ! 333: */ ! 334: for (desc = commonOptionDescriptions; desc->string != NULL; desc++) { ! 335: if (ifmw & desc->word) ! 336: IO_IFM_APPEND_OPTION(desc->string); ! 337: } ! 338: ! 339: /* ! 340: * Look for family specific options. ! 341: */ ! 342: for (desc = ttos->options; desc->string != NULL; desc++) { ! 343: if (ifmw & desc->word) ! 344: IO_IFM_APPEND_OPTION(desc->string); ! 345: } ! 346: ! 347: /* ! 348: * Print the instance number. ! 349: */ ! 350: if (IOMediumGetInstance(ifmw)) { ! 351: char instanceString[16]; ! 352: sprintf(instanceString, "%d", IOMediumGetInstance(ifmw)); ! 353: IO_IFM_APPEND_OPTION(instanceString); ! 354: } ! 355: ! 356: append_string(&buf, &maxlen, seen_option ? ")" : ""); ! 357: ! 358: return 1; ! 359: } ! 360: //=========================================================================== ! 361: // End of FreeBSD import. ! 362: //=========================================================================== ! 363: ! 364: //--------------------------------------------------------------------------- ! 365: // Given a 32-bit medium type, create an unique OSymbol name for the medium. ! 366: // The caller is responsible for releasing the OSSymbol object returned. ! 367: // ! 368: // type: A medium type. See IONetworkMedium.h for type encoding. ! 369: // ! 370: // Returns an OSSymbol created based on the type provided. ! 371: ! 372: const OSSymbol * IONetworkMedium::nameForType(IOMediumType type) ! 373: { ! 374: const UInt maxNameLen = 160; ! 375: char buffer[maxNameLen]; ! 376: ! 377: if (ifmedia_printword(type, buffer, maxNameLen) == 0) ! 378: return 0; // error, cannot create name. ! 379: ! 380: // Caller must remember to free the OSSymbol! ! 381: // ! 382: return OSSymbol::withCString(buffer); ! 383: } ! 384: ! 385: //--------------------------------------------------------------------------- ! 386: // Test for equality between two IONetworkMedium objects. ! 387: // Two IONetworkMedium objects are considered equal if ! 388: // they have similar properties assigned to them during initialization. ! 389: // ! 390: // medium: An IONetworkMedium to test against the IONetworkMedium ! 391: // object being called. ! 392: // ! 393: // Returns true if equal, false otherwise. ! 394: ! 395: bool IONetworkMedium::isEqualTo(const IONetworkMedium * medium) const ! 396: { ! 397: return ((bcmp(medium->_desc, _desc, sizeof(*_desc)) == 0) && ! 398: (medium->_name == _name)); ! 399: } ! 400: ! 401: //--------------------------------------------------------------------------- ! 402: // Test for equality between a IONetworkMedium object and an OSObject. ! 403: // The OSObject is considered equal to the IONetworkMedium object if the ! 404: // OSObject is an IONetworkMedium, and they have similar properties assigned ! 405: // to them during initialization. ! 406: // ! 407: // obj: An OSObject to test against the IONetworkMedium object being called. ! 408: // ! 409: // Returns true if equal, false otherwise. ! 410: ! 411: bool IONetworkMedium::isEqualTo(const OSObject * obj) const ! 412: { ! 413: IONetworkMedium * medium; ! 414: if ((medium = OSDynamicCast(IONetworkMedium, (OSObject *) obj))) ! 415: return isEqualTo(medium); ! 416: else ! 417: return false; ! 418: } ! 419: ! 420: //--------------------------------------------------------------------------- ! 421: // Create an OSData containing an IOMediumDescriptor structure (not copied), ! 422: // and ask the OSData to serialize. ! 423: // ! 424: // s: An OSSerialize object to handle the serialization. ! 425: // ! 426: // Returns true on success, false otherwise. ! 427: ! 428: bool IONetworkMedium::serialize(OSSerialize * s) const ! 429: { ! 430: bool ret = false; ! 431: OSData * descriptorData; ! 432: ! 433: // Create an OSData that encapsulates our IOMediumDescriptor structure. ! 434: // Then instruct the OSData to serialize itself. ! 435: // ! 436: descriptorData = OSData::withBytesNoCopy((void *) _desc, sizeof(*_desc)); ! 437: if (descriptorData) { ! 438: ret = descriptorData->serialize(s); ! 439: descriptorData->release(); ! 440: } ! 441: ! 442: return ret; ! 443: } ! 444: ! 445: //--------------------------------------------------------------------------- ! 446: // A helper function to add an IONetworkMedium object to a given dictionary. ! 447: // The name of the medium is used as the key for the new dictionary entry. ! 448: // ! 449: // dict: An OSDictionary object where the medium object should be added to. ! 450: // medium: The IONetworkMedium object to add to the dictionary. ! 451: // ! 452: // Returns true on success, false otherwise. ! 453: ! 454: bool IONetworkMedium::addMedium(OSDictionary * dict, ! 455: const IONetworkMedium * medium) ! 456: { ! 457: // Arguments type checking. ! 458: // ! 459: if (!OSDynamicCast(OSDictionary, dict) || ! 460: !OSDynamicCast(IONetworkMedium, medium)) ! 461: return false; ! 462: ! 463: return dict->setObject(medium->getName(), (OSObject *) medium); ! 464: } ! 465: ! 466: //--------------------------------------------------------------------------- ! 467: // A helper function to remove an entry in a dictionary with a key that ! 468: // matches the name of the IONetworkMedium object provided. ! 469: // ! 470: // dict: An OSDictionary object where the medium object should be removed ! 471: // from. ! 472: // medium: The name of this medium object is used as the removal key. ! 473: ! 474: void IONetworkMedium::removeMedium(OSDictionary * dict, ! 475: const IONetworkMedium * medium) ! 476: { ! 477: // Arguments type checking. ! 478: // ! 479: if (!OSDynamicCast(OSDictionary, dict) || ! 480: !OSDynamicCast(IONetworkMedium, medium)) ! 481: return; ! 482: ! 483: dict->removeObject(medium->getName()); ! 484: } ! 485: ! 486: //--------------------------------------------------------------------------- ! 487: // Iterate through a dictionary and return an IONetworkMedium entry that ! 488: // satisfies the matching criteria. Returns 0 if there is no match. ! 489: // Also see getMediumWithType() and getMediumWithIndex() that ! 490: // are specialized forms derived from this method. ! 491: // ! 492: // dict: The dictionary to look for a match. ! 493: // match: An IOMediumDescriptor structure containing the matching fields. ! 494: // mask: An IOMediumDescriptor structure containing the matching mask. ! 495: // Bits set are used for matching, while cleared bits are don't ! 496: // care bits. ! 497: // ! 498: // The first matching IONetworkMedium entry found, or 0 if no match was found. ! 499: ! 500: IONetworkMedium * IONetworkMedium::getMedium(const OSDictionary * dict, ! 501: IOMediumDescriptor * match, ! 502: IOMediumDescriptor * mask) ! 503: { ! 504: OSCollectionIterator * iter; ! 505: OSSymbol * keyObject; ! 506: IONetworkMedium * medium; ! 507: IONetworkMedium * retMedium = 0; ! 508: IOMediumDescriptor * desc; ! 509: UInt i; ! 510: ! 511: assert(match && mask); ! 512: ! 513: if (!dict) return 0; ! 514: ! 515: // Shouldn't withCollection take an (const OSDictionary *) argument? ! 516: ! 517: iter = OSCollectionIterator::withCollection((OSDictionary *) dict); ! 518: if (!iter) ! 519: return 0; ! 520: ! 521: while ( (keyObject = (OSSymbol *) iter->getNextObject()) ) ! 522: { ! 523: medium = OSDynamicCast(IONetworkMedium, dict->getObject(keyObject)); ! 524: if (!medium) ! 525: continue; ! 526: ! 527: desc = medium->_desc; ! 528: ! 529: // Perform bytewise matching. ! 530: // ! 531: for (i = 0; i < sizeof(IOMediumDescriptor); i++) { ! 532: if ( (((UInt8 *) desc)[i] ^ ((UInt8 *) match)[i]) & ! 533: ((UInt8 *) mask)[i] ) ! 534: break; ! 535: } ! 536: if (i == sizeof(IOMediumDescriptor)) { // match found. ! 537: retMedium = medium; ! 538: break; ! 539: } ! 540: } ! 541: ! 542: iter->release(); ! 543: ! 544: return retMedium; ! 545: } ! 546: ! 547: //--------------------------------------------------------------------------- ! 548: // getMedium___ macro. ! 549: // ! 550: // Returns a IONetworkMedium entry that has a IOMediumDescriptor ! 551: // with a 'field' which matches the given 'value'. ! 552: // ! 553: // name - function name. ! 554: // vartype - data type of the IOMediumDescriptor field. ! 555: // field - field in IOMediumDescriptor to perform search. ! 556: // mask - don't care bits. ! 557: ! 558: #define GET_MEDIUM_FUNC(name, vartype, field) \ ! 559: IONetworkMedium * \ ! 560: IONetworkMedium::getMediumWith ## name(const OSDictionary * dict, \ ! 561: vartype value, \ ! 562: vartype mask = 0) \ ! 563: { \ ! 564: IOMediumDescriptor match[2]; \ ! 565: \ ! 566: bzero(&match[0], sizeof(match)); \ ! 567: \ ! 568: match[0]. ## field = value; \ ! 569: match[1]. ## field = ~mask; \ ! 570: \ ! 571: return IONetworkMedium::getMedium(dict, &match[0], &match[1]); \ ! 572: } ! 573: ! 574: GET_MEDIUM_FUNC(Type, IOMediumType, type) // getMediumWithType() ! 575: GET_MEDIUM_FUNC(Index, UInt32, data) // getMediumWithIndex()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.