Annotation of XNU/iokit/Families/IONetworking/IONetworkMedium.cpp, revision 1.1

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:       &ethernetDescriptions[0],
        !           275:       &ethernetOptionDescriptions[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()

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.