Annotation of XNU/iokit/Families/IONetworking/IONetworkController.cpp, revision 1.1.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:  * IONetworkController.cpp
                     26:  *
                     27:  * HISTORY
                     28:  * 9-Dec-1998       Joe Liu (jliu) created.
                     29:  *
                     30:  */
                     31: 
                     32: #include <IOKit/assert.h>
                     33: #include <IOKit/IOCommandGate.h>
                     34: #include <IOKit/network/IONetworkController.h>
                     35: #include <IOKit/network/IOOutputQueue.h>
                     36: #include <IOKit/network/IONetworkMedium.h>
                     37: 
                     38: // IONetworkController needs to know about mbufs, but it shall have no
                     39: // other dependencies on BSD networking.
                     40: //
                     41: extern "C" {
                     42: #include <sys/param.h>  // mbuf limits defined here.
                     43: #include <sys/mbuf.h>
                     44: //
                     45: // osfmk/kern/spl.h - Need splimp for mbuf macros.
                     46: //
                     47: typedef unsigned spl_t;
                     48: extern spl_t    (splimp)(void);
                     49: }
                     50: 
                     51: //-------------------------------------------------------------------------
                     52: // Macros.
                     53: 
                     54: #define super IOService
                     55: 
                     56: OSDefineMetaClass(         IONetworkController, IOService )
                     57: OSDefineAbstractStructors( IONetworkController, IOService )
                     58: 
                     59: // Define SYNC_REQ macro to simplify syncRequest() calls.
                     60: //
                     61: #define SYNC_REQ(sender, action, ret, args...)  \
                     62:         syncRequest(sender, this, (IONetworkAction) action, (UInt32 *) ret, \
                     63:                     ## args)
                     64: 
                     65: #define DO_SYNC_REQ(action, args...)                                 \
                     66: {                                                                    \
                     67:     IOReturn  ret = kIOReturnNotReady;                               \
                     68:     syncRequest(client, this,                                        \
                     69:                 (RequestAction) &IONetworkController:: ## action,    \
                     70:                 (UInt32 *) &ret, ## args);                           \
                     71:     return ret;                                                      \
                     72: } 
                     73: 
                     74: static bool isPowerOfTwo(UInt num)
                     75: {
                     76:     return (num == (num & ~(num - 1)));
                     77: }
                     78: 
                     79: #ifndef MAX
                     80: #define MAX(a, b)   (((a)>(b))?(a):(b))
                     81: #endif
                     82: 
                     83: #define MEDIUM_LOCK     IOTakeLock(_mediumLock);
                     84: #define MEDIUM_UNLOCK   IOUnlock(_mediumLock);
                     85: 
                     86: #ifdef  DEBUG
                     87: #define DLOG(fmt, args...)  IOLog(fmt, ## args)
                     88: #else
                     89: #define DLOG
                     90: #endif
                     91: 
                     92: // OSSymbols for frequently used keys.
                     93: //
                     94: static const OSSymbol * gIOActiveMediumKey;
                     95: static const OSSymbol * gIOCurrentMediumKey;
                     96: 
                     97: //---------------------------------------------------------------------------
                     98: // Class initializer for IONetworkController. Create OSSymbol objects
                     99: // ahead of time that are used as keys. This method is called explicitly
                    100: // by a line in IOStartIOKit.cpp and not by the OSDefineMetaClassAndInit()
                    101: // mechanism, since the OSSymbol class is not guaranteed to be initialized
                    102: // first, thus its OSSymbol pool may not be setup.
                    103: 
                    104: void IONetworkController::initialize()
                    105: {
                    106:     gIOActiveMediumKey  = OSSymbol::withCStringNoCopy(kIOActiveMedium); 
                    107:     gIOCurrentMediumKey = OSSymbol::withCStringNoCopy(kIOCurrentMedium);
                    108:     
                    109:     assert(gIOActiveMediumKey && gIOCurrentMediumKey);
                    110: 
                    111:     IONetworkData::initialize();
                    112: }
                    113: 
                    114: //---------------------------------------------------------------------------
                    115: // Initialize the IONetworkController instance. Instance variables are 
                    116: // initialized to their default values, and the init() method in superclass
                    117: // is called.
                    118: //
                    119: // properties: A property table.
                    120: //
                    121: // Returns true on success, false otherwise.
                    122: 
                    123: bool IONetworkController::init(OSDictionary * properties)
                    124: {
                    125:     // Initialize instance variables.
                    126:     //
                    127:     _workLoop           = 0;
                    128:     _cmdGate            = 0;
                    129:     _outputQueue        = 0;
                    130:     _clientSet          = 0;
                    131:     _reqClient          = 0;
                    132:     _requestEnabled     = true;
                    133:     _handleReady        = true;
                    134:     _mediumLock         = 0;
                    135:     _linkData           = 0;
                    136: 
                    137:     if (!super::init(properties))
                    138:     {
                    139:         DLOG("IONetworkController: super::init() failed\n");
                    140:         return false;
                    141:     }
                    142:     return true;
                    143: }
                    144: 
                    145: //-------------------------------------------------------------------------
                    146: // Called when the controller was matched to a provider and
                    147: // has been selected to start running. IONetworkController will allocate
                    148: // resources and gather the controller's properties. No I/O will be
                    149: // triggered until the subclass attaches a client object from its own
                    150: // start method. Subclasses must override this method and call
                    151: // super::start() at the beginning of its implementation. They should
                    152: // also check the return value to make sure their superclass was
                    153: // started successfully. The resources allocated
                    154: // by IONetworkController are:
                    155: //
                    156: // - An IOWorkLoop object.
                    157: // - An IOCommandGate object to handle synchronous requests.
                    158: // - An OSSet to track our clients.
                    159: // - An optional IOOutputQueue object for output queueing.
                    160: //
                    161: // Tasks that are usually performed by a typical network driver in start
                    162: // include:
                    163: //
                    164: // - Resource allocation
                    165: // - Hardware initialization
                    166: // - Allocation of IOEventSources and attaching them to an IOWorkLoop object.
                    167: // - Publishing a medium dictionary.
                    168: // - And finally, attaching an interface object when the driver is ready
                    169: //   to handle client requests.
                    170: //
                    171: // provider: The provider that the controller was matched
                    172: //           (and attached) to.
                    173: //
                    174: // Returns true on success, false otherwise.
                    175: 
                    176: bool IONetworkController::start(IOService * provider)
                    177: {
                    178:     // Most drivers will probably want to wait for BSD due to their
                    179:     // dependency on mbufs, which is not available until BSD is
                    180:     // initialized.
                    181:     //
                    182:     if ((getFeatureSet() & kIONetworkFeatureNoBSDWait) == 0)
                    183:         waitForService(resourceMatching( "IOBSD" ));
                    184: 
                    185:     // Start our superclass.
                    186:     //
                    187:     if (!super::start(provider))
                    188:         return false;
                    189: 
                    190:     // Create an OSSet to store our clients.
                    191:     //
                    192:     _clientSet = OSSet::withCapacity(2);
                    193:     if (!_clientSet)
                    194:         return false;
                    195: 
                    196:     // Initialize link status properties.
                    197:     //
                    198:     setMediumProperty(gIOActiveMediumKey,  0, &_activeMedium,  true);
                    199:     setMediumProperty(gIOCurrentMediumKey, 0, &_currentMedium, true);
                    200:     setLink32Property(kIOLinkStatus,       0, &_linkStatus,    true);
                    201:     setLink64Property(kIOLinkSpeed,        0, &_linkSpeed,     true);
                    202:             
                    203:     // Allocate a mutex lock to serialize access to the medium dictionary.
                    204:     //
                    205:     _mediumLock = IOLockAlloc();
                    206:     if (!_mediumLock)
                    207:         return false;
                    208:     IOLockInitWithState(_mediumLock, kIOLockStateUnlocked);
                    209: 
                    210:     // Allocate and initialize the default IOWorkLoop object.
                    211:     //
                    212:     _workLoop = IOWorkLoop::workLoop();
                    213:     if (!_workLoop)
                    214:     {
                    215:         DLOG("%s: IOWorkLoop allocation failed\n", getName());
                    216:         return false;
                    217:     }
                    218: 
                    219:     // Create a 'private' IOCommandGate object and attach it to
                    220:     // our workloop created above. This is used by the syncRequest()
                    221:     // function.
                    222:     //
                    223:     _cmdGate = IOCommandGate::commandGate(this);
                    224:     if (!_cmdGate ||
                    225:         (_workLoop->addEventSource(_cmdGate) != kIOReturnSuccess))
                    226:     {
                    227:         DLOG("%s: IOCommandGate initialization failed\n", getName());
                    228:         return false;
                    229:     }
                    230: 
                    231:     // Try to allocate an IOOutputQueue instance. This is optional and
                    232:     // _outputQueue may be 0.
                    233:     //
                    234:     _outputQueue = createOutputQueue();
                    235: 
                    236:     // Remove this when allocateOutputQueue is deleted.
                    237:     if (!_outputQueue) 
                    238:         _outputQueue = allocateOutputQueue();
                    239: 
                    240:     // Query the controller's mbuf buffer restrictions.
                    241:     //
                    242:     IOPacketBufferConstraints constraints;
                    243:     getPacketBufferConstraints(&constraints);
                    244:     if ((constraints.alignStart  > kIOPacketBufferAlign32) ||
                    245:         (constraints.alignLength > kIOPacketBufferAlign32) ||
                    246:         !isPowerOfTwo(constraints.alignStart) ||
                    247:         !isPowerOfTwo(constraints.alignLength))
                    248:     {
                    249:         IOLog("%s: Invalid alignment: start:%ld, length:%ld\n",
                    250:             getName(),
                    251:             constraints.alignStart,
                    252:             constraints.alignLength);
                    253:         return false;
                    254:     }
                    255: 
                    256:     // Make it easier to satisfy both constraints.
                    257:     //
                    258:     if (constraints.alignStart < constraints.alignLength)
                    259:         constraints.alignStart = constraints.alignLength;
                    260:     
                    261:     // Convert to alignment masks.
                    262:     //
                    263:     _alignStart  = (constraints.alignStart) ? constraints.alignStart - 1 : 0;
                    264:     _alignLength = (constraints.alignLength) ? constraints.alignLength - 1 : 0;
                    265:     _alignPadding = _alignStart + _alignLength;
                    266: 
                    267:     // Starts the power manager
                    268:     //
                    269:     PMinit();           // initialize superclass power management variables
                    270:     provider->joinPMtree(this); // attach into the power management hierarchy
                    271: 
                    272:     return true;
                    273: }
                    274: 
                    275: //---------------------------------------------------------------------------
                    276: // The opposite of start(). The controller has been instructed to stop running.
                    277: // This method should release resources and undo actions performed by start().
                    278: // Subclasses must override this method and call super::stop() at the end of 
                    279: // its implementation.
                    280: //
                    281: // provider: The provider that the controller was matched
                    282: //           (and attached) to.
                    283: 
                    284: void IONetworkController::stop(IOService * provider)
                    285: {
                    286:     // Free the memory allocated by PMInit:
                    287:     PMstop();
                    288: 
                    289:     super::stop(provider);
                    290: }   
                    291: 
                    292: //---------------------------------------------------------------------------
                    293: // Get the IOWorkLoop object created by IONetworkController.
                    294: // An IOWorkLoop object is created by the start() method. Drivers can call 
                    295: // getWorkLoop() to obtain a reference to the IOWorkLoop object, and attach
                    296: // their event sources, such as IOTimerEventSource or IOInterruptEventSource.
                    297: // See IOWorkLoop.
                    298: //
                    299: // Returns the IOWorkLoop object created by IONetworkController.
                    300: 
                    301: IOWorkLoop * IONetworkController::getWorkLoop() const
                    302: {
                    303:     return _workLoop;
                    304: }
                    305: 
                    306: //---------------------------------------------------------------------------
                    307: // Get the IOCommandGate object created by IONetworkController.
                    308: // An IOCommandGate is created and attached to an IOWorkLoop by the start().
                    309: // method This IOCommandGate object is used to handle client requests issued
                    310: // through the syncRequest() method. Subclasses that need an IOCommandGate 
                    311: // should try to use the object returned by this method, rather than creating
                    312: // a new instance.
                    313: // See IOCommandGate.
                    314: //
                    315: // Returns the IOCommandGate object created by IONetworkController.
                    316:     
                    317: IOCommandGate * IONetworkController::getCommandGate() const
                    318: {
                    319:     return _cmdGate;
                    320: }
                    321: 
                    322: //---------------------------------------------------------------------------
                    323: // Get the address of the method designated to handle output packets.
                    324: //
                    325: // Returns the address of the outputPacket() method.
                    326: 
                    327: IOOutputAction IONetworkController::getOutputHandler() const
                    328: {
                    329:     return (IOOutputAction) &IONetworkController::outputPacket;
                    330: }
                    331: 
                    332: //---------------------------------------------------------------------------
                    333: // Create a new interface client object and attach it
                    334: // to the controller. The createInterface() method is called to
                    335: // perform the allocation and initialization, followed by a call to 
                    336: // configureInterface() to configure the interface. Both of these
                    337: // methods can be overridden by subclasses to customize the
                    338: // interface client attached. Drivers must call attachInterface()
                    339: // from its start() method, after it is ready to service client requests.
                    340: //
                    341: // interfaceP: If successful (return value is true), then the interface
                    342: //             object will be written to the handle provided.
                    343: //
                    344: // doRegister: If true, then registerService() is called to register
                    345: //             the interface, which will trigger the matching process,
                    346: //             and cause the interface to become registered with the network
                    347: //             layer. For drivers that wish to delay the registration, and
                    348: //             hold off servicing requests and data packets from the network
                    349: //             layer, set doRegister to false and call registerService() on
                    350: //             the interface client when the controller becomes ready.
                    351: //
                    352: // Returns true on success, false otherwise.
                    353: 
                    354: bool
                    355: IONetworkController::attachInterface(IONetworkInterface ** interfaceP,
                    356:                                      bool  doRegister = true)
                    357: {
                    358:     IONetworkInterface * netif;
                    359:     bool                 initOk = false;
                    360: 
                    361:     *interfaceP = 0;
                    362: 
                    363:     // We delay some initialization until the first time that
                    364:     // attachInterface() is called by the subclass.
                    365:     //
                    366:     SYNC_REQ(this, &IONetworkController::_controllerIsReady, &initOk);
                    367:     if (!initOk)
                    368:         return false;
                    369: 
                    370:     do {
                    371:         // Allocate a concrete subclass of IONetworkInterface
                    372:         // by calling createInterface().
                    373:         //
                    374:         netif = createInterface();
                    375:         if (!netif)
                    376:             break;
                    377: 
                    378:         // Configure the interface instance by calling 
                    379:         // configureInterface(), then attach it as our client.
                    380:         //
                    381:         if (!configureInterface(netif) ||
                    382:             !configureNetworkInterface(netif) ||
                    383:             !netif->attach(this))
                    384:         {
                    385:             netif->release();
                    386:             break;
                    387:         }
                    388: 
                    389:         *interfaceP = netif;
                    390: 
                    391:         // Register the interface nub. Spawns a matching thread.
                    392:         //
                    393:         if (doRegister)
                    394:             netif->registerService();
                    395: 
                    396:         return true;
                    397:     }
                    398:     while (0);
                    399: 
                    400:     return false;   // failed
                    401: }
                    402: 
                    403: //---------------------------------------------------------------------------
                    404: // Detach the interface object. This method will check that
                    405: // the object provided is indeed an IONetworkInterface, and if so its 
                    406: // terminate() method is called. The interface object will close and detach 
                    407: // from its controller only after the network layer has removed all references
                    408: // to the data structures exposed by the interface.
                    409: //
                    410: // interface: An interface object to be detached.
                    411: // sync:      If true, the interface is terminated synchronously.
                    412: //            Note that this may cause detachInterface() to block
                    413: //            for an indefinite period of time.
                    414: 
                    415: void
                    416: IONetworkController::detachInterface(IONetworkInterface * interface,
                    417:                                      bool                 sync = false)
                    418: {
                    419:     IOOptionBits options = kIOServiceRequired;
                    420: 
                    421:     if (OSDynamicCast(IONetworkInterface, interface) == 0)
                    422:         return;
                    423: 
                    424:     if (sync)
                    425:         options |= kIOServiceSynchronous;
                    426: 
                    427:     interface->terminate(options);
                    428: }
                    429: 
                    430: //---------------------------------------------------------------------------
                    431: // This method is called the first time that a controller driver calls 
                    432: // attachInterface() or attachDebuggerClient(), which is an indication that
                    433: // the driver has been started and is ready to service client requests.
                    434: // IONetworkController  uses this method to complete its initialization
                    435: // before any client objects are attached.
                    436: //
                    437: // provider: The controller's provider.
                    438: //
                    439: // Returns true on success, false otherwise.
                    440: 
                    441: bool IONetworkController::ready(IOService * provider)
                    442: {
                    443:     return publishCapabilities();
                    444: }
                    445: 
                    446: //---------------------------------------------------------------------------
                    447: // Called when the controller is ready to handle client requests.
                    448: // Returns true to indicate success, false otherwise.
                    449: 
                    450: bool IONetworkController::_controllerIsReady()
                    451: {
                    452:     if (!_handleReady)
                    453:         return true;
                    454: 
                    455:     if (!ready(getProvider()))    // Call ready().
                    456:         return false;
                    457: 
                    458:     _handleReady = false;
                    459:     return true;
                    460: }
                    461: 
                    462: //---------------------------------------------------------------------------
                    463: // Handle a client open on the controller object. IOService calls this method 
                    464: // with the arbitration lock held. Subclasses are not expected to override
                    465: // this method.
                    466: //
                    467: //   client: The client that is trying to open the controller.
                    468: //  options: See IOService.
                    469: // argument: See IOService.
                    470: //
                    471: // Returns true to accept the client open, false to refuse the open.
                    472: 
                    473: bool IONetworkController::handleOpen(IOService *  client,
                    474:                                      IOOptionBits options,
                    475:                                      void *       argument)
                    476: {
                    477:     bool ok;
                    478: 
                    479:     assert(client);
                    480: 
                    481:     ok = _clientSet->setObject(client);
                    482:     if (ok && OSDynamicCast(IOKernelDebugger, client))
                    483:     {
                    484:         ok = (doEnable(client) == kIOReturnSuccess);
                    485:         if (!ok)
                    486:             _clientSet->removeObject(client);
                    487:     }
                    488:     return ok;
                    489: }
                    490: 
                    491: //---------------------------------------------------------------------------
                    492: // Handle a close from one of our client objects. IOService calls this method
                    493: // with the arbitration lock held. Subclasses are not expected to override this 
                    494: // method.
                    495: //
                    496: //  client: The client that has closed the controller.
                    497: // options: See IOService.
                    498: 
                    499: void IONetworkController::handleClose(IOService * client, IOOptionBits options)
                    500: {
                    501:     _clientSet->removeObject(client);
                    502: 
                    503:     if (OSDynamicCast(IOKernelDebugger, client))
                    504:         doDisable(client);
                    505: }
                    506: 
                    507: //---------------------------------------------------------------------------
                    508: // This method is always called by IOService with the arbitration lock held. 
                    509: // Subclasses should not override this method.
                    510: //
                    511: // Returns true if the specified client, or any client if none is
                    512: // specified, presently has an open on this object.
                    513: 
                    514: bool IONetworkController::handleIsOpen(const IOService * client) const
                    515: {
                    516:     if (client)
                    517:         return _clientSet->containsObject(client);
                    518:     else
                    519:         return (_clientSet->getCount() > 0);
                    520: }
                    521: 
                    522: //---------------------------------------------------------------------------
                    523: // Free the IONetworkController instance and all allocated resources,
                    524: // then call super::free().
                    525: 
                    526: void IONetworkController::free()
                    527: {
                    528:     if (_outputQueue)
                    529:         _outputQueue->release();
                    530: 
                    531:     if (_cmdGate)
                    532:         _cmdGate->release();
                    533: 
                    534:     if (_workLoop)
                    535:         _workLoop->release();
                    536: 
                    537:     if (_clientSet)
                    538:     {
                    539:         // We should have no clients at this point. If we do,
                    540:         // then something is very wrong! It means that a client
                    541:         // has an open on us, and yet we are going away.
                    542:         //
                    543:         assert(_clientSet->getCount() == 0);
                    544:         _clientSet->release();
                    545:     }
                    546: 
                    547:     if (_mediumLock)
                    548:         IOLockFree(_mediumLock);
                    549: 
                    550:     super::free();
                    551: }
                    552: 
                    553: //---------------------------------------------------------------------------
                    554: // Handle an enable request from a client. The client's class
                    555: // is typecasted using OSDynamicCast, and if the client is an
                    556: // IOKernelDebugger or an IONetworkInterface, an overloaded enable
                    557: // method that takes a more specific argument is called. If the client
                    558: // matches neither type, a kIOReturnBadArgument is returned.
                    559: // A driver has the option of override this generic enable method,
                    560: // or the derived version.
                    561: //
                    562: // client: The client object requesting the enable.
                    563: //
                    564: // The return value from the derived enable method, or
                    565: // kIOReturnBadArgument if the client's type is unknown.
                    566: 
                    567: IOReturn IONetworkController::enable(IOService * client)
                    568: {
                    569:     if (OSDynamicCast(IONetworkInterface, client))
                    570:         return enable((IONetworkInterface *) client);
                    571:     
                    572:     if (OSDynamicCast(IOKernelDebugger, client))
                    573:         return enable((IOKernelDebugger *) client);
                    574: 
                    575:     IOLog("%s::%s Unknown client type\n", getName(), __FUNCTION__);
                    576:     return kIOReturnBadArgument;
                    577: }
                    578: 
                    579: //---------------------------------------------------------------------------
                    580: // Handle an enable request from a client. The client
                    581: // object is typecasted using OSDynamicCast, and if the client is an
                    582: // IOKernelDebugger or an IONetworkInterface, then an overloaded disable
                    583: // method that takes a more specific argument is called. If the client
                    584: // matches neither type, a kIOReturnBadArgument is returned.
                    585: // A driver has the option of override this generic enable method,
                    586: // or the derived version.
                    587: //
                    588: // client: The client object requesting the disable.
                    589: //
                    590: // The return from the derived disable method, or
                    591: // kIOReturnBadArgument if the client's type is unknown
                    592: 
                    593: IOReturn IONetworkController::disable(IOService * client)
                    594: {
                    595:     if (OSDynamicCast(IONetworkInterface, client))
                    596:         return disable((IONetworkInterface *) client);
                    597:     
                    598:     if (OSDynamicCast(IOKernelDebugger, client))
                    599:         return disable((IOKernelDebugger *) client);
                    600: 
                    601:     IOLog("%s::%s Unknown client type\n", getName(), __FUNCTION__);
                    602:     return kIOReturnBadArgument;
                    603: }
                    604: 
                    605: //---------------------------------------------------------------------------
                    606: // Called by an interface client to enable the controller.
                    607: // This method must bring up the hardware and enable event sources
                    608: // to prepare for packet transmission and reception. A driver should
                    609: // delay the allocation of most runtime resources until this method is
                    610: // called to conserve shared system resources.
                    611: //
                    612: // interface: The interface object that requested the enable.
                    613: //
                    614: // Returns kIOReturnUnsupported. Driver may override this method and
                    615: // return kIOReturnSuccess on success, or an error code otherwise.
                    616: 
                    617: IOReturn IONetworkController::enable(IONetworkInterface * interface)
                    618: {
                    619:     IOLog("IONetworkController::%s called\n", __FUNCTION__);
                    620:     return kIOReturnUnsupported;
                    621: }
                    622: 
                    623: //---------------------------------------------------------------------------
                    624: // Called by an interface object to disable the controller.
                    625: // This method should quiesce the hardware and disable event sources.
                    626: // Any resources allocated in enable() should also be deallocated.
                    627: //
                    628: // interface: The interface object that requested the disable.
                    629: //
                    630: // Returns kIOReturnUnsupported. Driver may override this method and
                    631: // return kIOReturnSuccess on success, or an error code otherwise.
                    632: 
                    633: IOReturn IONetworkController::disable(IONetworkInterface * interface)
                    634: {
                    635:     IOLog("IONetworkController::%s called\n", __FUNCTION__);
                    636:     return kIOReturnUnsupported;
                    637: }
                    638: 
                    639: //---------------------------------------------------------------------------
                    640: // With the various overloaded forms of enable() and disable(), what does it
                    641: // mean when one does &IONetworkController::enable, to get the address of the 
                    642: // member function?
                    643: // Instead, these private functions are registered which then calls the
                    644: // correct functions.
                    645: 
                    646: IOReturn IONetworkController::_enable(IOService * client)
                    647: {
                    648:     return enable(client);
                    649: };
                    650: 
                    651: IOReturn IONetworkController::_disable(IOService * client)
                    652: {
                    653:     return disable(client);
                    654: };
                    655: 
                    656: //---------------------------------------------------------------------------
                    657: // Discover and publish controller capabilities to the property table.
                    658: // This method is called by ready().
                    659: //
                    660: // Returns true if all capabilities were discovered and published
                    661: // successfully, false otherwise. Returning false will prevent client
                    662: // objects from attaching to the controller since a property that
                    663: // a client depends on may be missing
                    664: 
                    665: bool IONetworkController::publishCapabilities()
                    666: {
                    667:     bool        ret = true;
                    668:     OSString *  string;
                    669:     UInt32      index;
                    670: 
                    671:     string = OSString::withCString(getVendorString());
                    672:     if (string) {
                    673:         ret = setProperty(kIOVendor, string) && ret;
                    674:         string->release();
                    675:     }
                    676: 
                    677:     string = OSString::withCString(getModelString());
                    678:     if (string) {
                    679:         ret = setProperty(kIOModel, string) && ret;
                    680:         string->release();
                    681:     }
                    682: 
                    683:     string = OSString::withCString(getRevisionString());
                    684:     if (string) {
                    685:         ret = setProperty(kIORevision, string) && ret;
                    686:         string->release();
                    687:     }
                    688: 
                    689:     string = OSString::withCString(getInfoString());
                    690:     if (string) {
                    691:         ret = setProperty(kIOInfo, string) && ret;
                    692:         string->release();
                    693:     }
                    694: 
                    695:     // Set OSNumber properties.
                    696:     //  
                    697:     ret = (getControllerIndex(&index) == kIOReturnSuccess) && ret;
                    698:     ret = setProperty(kIOControllerIndex,  index, 32) && ret;
                    699:     ret = setProperty(kIOFeatureSet,       getFeatureSet(), 32) && ret;
                    700:     ret = setProperty(kIOFamilyFeatureSet, getFamilyFeatureSet(), 32) && ret;
                    701: 
                    702:     if (getPacketFilters(&index) == kIOReturnSuccess) {
                    703:         ret = setProperty(kIOPacketFilters, index, 32) && ret; 
                    704:     }
                    705:     else {
                    706:         ret = false;
                    707:     }
                    708: 
                    709:     if (!ret)
                    710:         DLOG("IONetworkController::%s error\n", __FUNCTION__);
                    711: 
                    712:     return ret;
                    713: }
                    714: 
                    715: //---------------------------------------------------------------------------
                    716: // Broadcast a network event to all attached interface objects.
                    717: // This is equivalent to calling the IONetworkInterface::inputEvent()
                    718: // function for each interface client.
                    719: //
                    720: // IONetworkController uses this method to broadcast link and media
                    721: // events. Drivers will usually call the inputEvent() method directly
                    722: // since it is more efficient, and most drivers will only attach a
                    723: // single interface client.
                    724: //
                    725: // type: Event type.
                    726: //  arg: Event argument.
                    727: //
                    728: // Returns true if the event was delivered, false if an error occurred
                    729: // (unable to perform object allocation) and the event was not delivered
                    730: 
                    731: bool IONetworkController::broadcastEvent(UInt32 type, void * arg = 0)
                    732: {
                    733:     IONetworkInterface *   netif;
                    734:     OSCollectionIterator * iter = 0;
                    735:     OSSet *                clientSet;
                    736: 
                    737:     lockForArbitration();   // locks open/close/state changes.
                    738:     
                    739:     if (_clientSet->getCount()) {
                    740:         clientSet = OSSet::withSet(_clientSet, _clientSet->getCount());
                    741:         if (clientSet) {
                    742:             iter = OSCollectionIterator::withCollection(clientSet);
                    743:             clientSet->release();
                    744:         }
                    745:     }
                    746:     
                    747:     unlockForArbitration();
                    748: 
                    749:     if (!iter)
                    750:         return false;
                    751: 
                    752:     // Send the event to all attached interface objects.
                    753:     //
                    754:     while ((netif = (IONetworkInterface *) iter->getNextObject())) {
                    755:         if (OSDynamicCast(IONetworkInterface, netif) == 0)
                    756:             continue;   // only send events to IONetworkInterface subclasses.
                    757:         netif->inputEvent(type, arg);
                    758:     }
                    759: 
                    760:     iter->release();
                    761: 
                    762:     return true;
                    763: }
                    764: 
                    765: //---------------------------------------------------------------------------
                    766: // A client request for the controller to switch to a new MTU size.
                    767: //
                    768: // mtu: The new MTU size requested.
                    769: //
                    770: // Returns kIOReturnUnsupported. Drivers may override this method
                    771: // and return either kIOReturnSuccess to indicate that the new MTU size
                    772: // was accepted and is in effect, or an error to indicate failure.
                    773: 
                    774: IOReturn IONetworkController::setMaxTransferUnit(UInt32 mtu)
                    775: {
                    776:     return kIOReturnUnsupported;
                    777: }
                    778: 
                    779: //---------------------------------------------------------------------------
                    780: // A client request for the driver to perform hardware 
                    781: // diagnostics and return the test result after completion.
                    782: //
                    783: // resultCodeP: In addition to the return code, drivers may return
                    784: //               a hardware specific failure code.
                    785: //
                    786: // Return kIOReturnSuccess if the hardware passed all test, or an
                    787: // appropriate error code otherwise. The default return is always
                    788: // kIOReturnUnsupported.
                    789: 
                    790: IOReturn IONetworkController::performDiagnostics(UInt32 * resultCodeP)
                    791: {
                    792:     return kIOReturnUnsupported;
                    793: }
                    794: 
                    795: //---------------------------------------------------------------------------
                    796: // Transmit a packet mbuf. If an IOOutputQueue was allocated and returned by 
                    797: // createOutputQueue(), then this method will be called by the queue object.
                    798: // Otherwise, an interface object will call this method directly upon 
                    799: // receiving an output packet from the network layer. When a queue object
                    800: // is not present, this method must be safe from multiple client threads,
                    801: // each pushing a packet to be sent on the wire.
                    802: //
                    803: // There is no upper limit on the number of mbufs, hence the number of
                    804: // memory fragments, in the mbuf chain provided. Drivers must be able to
                    805: // handle cases when the chain might exceed the limit supported by their
                    806: // DMA engines, and perform coalescing to copy the various memory fragments
                    807: // into a lesser number of fragments. This complexity can be hidden from
                    808: // a driver when an IOMBufMemoryCursor is used, which is able to convert
                    809: // a mbuf chain into a physical address scatter-gather list that will not
                    810: // exceed a specified number of physically contiguous memory segments.
                    811: // See IOMBufMemoryCursor.
                    812: //
                    813: // Packets may also be chained to form a packet chain. Although the
                    814: // network layer, through the interface object, will currently only
                    815: // send a single mbuf packet to the controller for each outputPacket()
                    816: // call, it is possible for this to change. When a queue object is used,
                    817: // the queue will automatically accept a single packet or a packet chain,
                    818: // but it will call outputPacket() for each packet removed from the queue.
                    819: //
                    820: // The implementation in IONetworkController performs no useful action
                    821: // and will drop all packets. A driver must always override this method.
                    822: //
                    823: // m: The packet mbuf.
                    824: //
                    825: // Returns a return code defined by the caller.
                    826: 
                    827: UInt32 IONetworkController::outputPacket(struct mbuf * m)
                    828: {
                    829:     // The implementation here is simply a sink-hole, all packets are
                    830:     // dropped.
                    831:     //
                    832:     if (m) freePacket(m);
                    833:     return 0;
                    834: }
                    835: 
                    836: //---------------------------------------------------------------------------
                    837: // A client request to adjust the capacity of the driver's output queue
                    838: // (number of packets the queue can hold). If a driver does not override
                    839: // this method, then the default action is to forward the request to
                    840: // an IOOutputQueue object if it was created. Otherwise return
                    841: // kIOReturnUnsupported.
                    842: //
                    843: // capacity: The new capacity of the output queue.
                    844: //
                    845: // Returns kIOReturnSuccess on success, kIOReturnBadArgument if the
                    846: // specified capacity is invalid, or kIOReturnUnsupported if the
                    847: // function is not supported.
                    848: 
                    849: IOReturn IONetworkController::setOutputQueueCapacity(UInt32 capacity)
                    850: {
                    851:     if (_outputQueue)
                    852:         return _outputQueue->setCapacity(capacity) ?
                    853:                kIOReturnSuccess : kIOReturnBadArgument;
                    854:     else
                    855:         return kIOReturnUnsupported;
                    856: }
                    857: 
                    858: //---------------------------------------------------------------------------
                    859: // A client request to get the capacity of the output queue. If a driver
                    860: // does not override this method, then the default action is to forward the
                    861: // request to an IOOutputQueue object if it was created. Otherwise return
                    862: // kIOReturnUnsupported.
                    863: //
                    864: // capacityP: Address of an integer where the capacity
                    865: //            shall be written to.
                    866: //
                    867: // Returns kIOReturnSuccess on success, or kIOReturnUnsupported if an
                    868: // IOOutputQueue object was not created.
                    869: 
                    870: IOReturn IONetworkController::getOutputQueueCapacity(UInt32 * capacityP) const
                    871: {
                    872:     if (_outputQueue) {
                    873:         *capacityP = _outputQueue->getCapacity();
                    874:         return kIOReturnSuccess;
                    875:     }
                    876:     return kIOReturnUnsupported;
                    877: }
                    878: 
                    879: //---------------------------------------------------------------------------
                    880: // A client request to fetch the number of packets currently held by the
                    881: // queue. If a driver does not override this method, then the default action
                    882: // is to forward the request to an IOOutputQueue object if it was created. 
                    883: // Otherwise return kIOReturnUnsupported.
                    884: //
                    885: // sizeP: Address of an integer where the size shall be written to.
                    886: //
                    887: // Returns kIOReturnSuccess on success, or kIOReturnUnsupported if an
                    888: // IOOutputQueue object was not created.
                    889: 
                    890: IOReturn IONetworkController::getOutputQueueSize(UInt32 * sizeP) const
                    891: {
                    892:     if (_outputQueue) {
                    893:         *sizeP = _outputQueue->getSize();
                    894:         return kIOReturnSuccess;
                    895:     }
                    896:     return kIOReturnUnsupported;
                    897: }
                    898: 
                    899: //---------------------------------------------------------------------------
                    900: // A client request to flush all packets currently held by the queue,
                    901: // and return the number of packets discarded. If a driver does not
                    902: // override this method, then the default action is to forward the
                    903: // request to an IOOutputQueue object if it was created. 
                    904: // Otherwise return kIOReturnUnsupported.
                    905: //
                    906: // flushCountP: Address of an integer where the number of packets
                    907: //              discarded shall be written to.
                    908: //
                    909: // Returns kIOReturnSuccess on success, or kIOReturnUnsupported if an
                    910: // IOOutputQueue object was not created.
                    911: 
                    912: IOReturn IONetworkController::flushOutputQueue(UInt32 * flushCountP)
                    913: {
                    914:     if (_outputQueue) {
                    915:         *flushCountP = _outputQueue->flush();
                    916:         return kIOReturnSuccess;
                    917:     }
                    918:     return kIOReturnUnsupported;
                    919: }
                    920: 
                    921: //---------------------------------------------------------------------------
                    922: // Report features supported by the controller.
                    923: //
                    924: // Returns 0. Drivers may override this method and return a mask
                    925: // containing all supported feature bits.
                    926: 
                    927: UInt32 IONetworkController::getFeatureSet() const
                    928: {
                    929:     return 0;
                    930: }
                    931: 
                    932: //---------------------------------------------------------------------------
                    933: // Return a string describing the revision level of the controller.
                    934: 
                    935: const char * IONetworkController::getRevisionString() const
                    936: {
                    937:     return 0;
                    938: }
                    939: 
                    940: //---------------------------------------------------------------------------
                    941: // Return a string containing any additional information about the controller
                    942: // and/or driver.
                    943: 
                    944: const char * IONetworkController::getInfoString() const
                    945: {
                    946:     return 0;
                    947: }
                    948: 
                    949: //---------------------------------------------------------------------------
                    950: // Return an ordinal number for multiport network adapters.
                    951: // The implementation in IONetworkController will work for PCI controllers
                    952: // behind a PCI-PCI bridge. This method exists solely to support the
                    953: // current interface naming scheme, and is likely to
                    954: // undergo changes or may disappear in the future.
                    955: //
                    956: // indexP: The oridinal number should be written to the
                    957: //         integer at this address.
                    958: //
                    959: // Returns kIOReturnSuccess.
                    960: 
                    961: IOReturn IONetworkController::getControllerIndex(UInt32 * index) const
                    962: {
                    963:     IOService * provider = getProvider();
                    964: 
                    965:     *index = 0;
                    966: 
                    967:     if (provider) {
                    968:         OSNumber * offset = OSDynamicCast(OSNumber,
                    969:                             provider->getProperty("IOChildIndex"));
                    970:         if (offset)
                    971:             *index = offset->unsigned32BitValue();
                    972:     }
                    973:     return kIOReturnSuccess;
                    974: }
                    975: 
                    976: //---------------------------------------------------------------------------
                    977: // Encodes a request received by syncRequest. This command structure is then
                    978: // submitted to commandHandler() through the IOCommandGate::runAction().
                    979: 
                    980: struct cmdStruct {
                    981:     OSObject *                          client;
                    982:     OSObject *                          target;
                    983:     IONetworkController::RequestAction  action;
                    984:     void *                              arg0;
                    985:     void *                              arg1;
                    986:     void *                              arg2;
                    987:     void *                              arg3;
                    988: };
                    989: 
                    990: //---------------------------------------------------------------------------
                    991: // Execute the request received by syncRequest() and encoded onto
                    992: // a cmdStruct structure. This method is called by IOCommandGate's
                    993: // runAction() method.
                    994: 
                    995: void IONetworkController::commandHandler(void * arg0,
                    996:                                          void * arg1,
                    997:                                          void * arg2,
                    998:                                          void * /*arg3*/)
                    999: {
                   1000:     cmdStruct * cmd       = (cmdStruct *) arg0;  // cmdStruct
                   1001:     UInt32 *    actRetP   = (UInt32 *)    arg1;  // action return
                   1002:     IOReturn *  cmdRetP   = (IOReturn *)  arg2;  // commandHandler return
                   1003:     OSObject *  oldClient = _reqClient;
                   1004:     bool        accept    = true;
                   1005: 
                   1006:     assert(cmd && actRetP && cmdRetP);
                   1007: 
                   1008:     if (cmd->client != this)
                   1009:     {
                   1010:         // Filter the client request.
                   1011: 
                   1012:         accept = syncRequestFilter(cmd->client,
                   1013:                                    cmd->target,
                   1014:                                    cmd->action,
                   1015:                                    cmd->arg0,
                   1016:                                    cmd->arg1,
                   1017:                                    cmd->arg2,
                   1018:                                    cmd->arg3);
                   1019:     }
                   1020: 
                   1021:     if (accept) {
                   1022:         _reqClient = cmd->client;
                   1023: 
                   1024:         *actRetP = ((cmd->target)->*(cmd->action))(cmd->arg0,
                   1025:                                                    cmd->arg1,
                   1026:                                                    cmd->arg2,
                   1027:                                                    cmd->arg3);
                   1028: 
                   1029:         _reqClient = oldClient;
                   1030: 
                   1031:         *cmdRetP = kIOReturnSuccess;
                   1032:     }
                   1033:     else {
                   1034:         // actRetP is not set if the request was rejected by the filter.
                   1035:         *cmdRetP = kIOReturnNotReady;
                   1036:     }
                   1037: }
                   1038: 
                   1039: //---------------------------------------------------------------------------
                   1040: // Perform a request action synchronously. Used both internally and also by
                   1041: // clients to execute an arbitrary request action using the IOCommandGate's 
                   1042: // runAction() method. For client requests, where the client field is not
                   1043: // equal to 'this', the request is filtered by calling syncRequestFilter()
                   1044: // to qualify the client request. This filter function must return true
                   1045: // in order for the request to be accepted and the request action called.
                   1046: //
                   1047: // client: The client (caller) of the synchronous request.
                   1048: // target: The target object that implements the request action.
                   1049: // action: The action to perform.
                   1050: // ret:    The return value from the action is written to the
                   1051: //         integer with the provided address. The result is
                   1052: //         not written if the request was rejected by the request filter.
                   1053: // arg0:   Optional action argument.
                   1054: // arg1:   Optional action argument.
                   1055: // arg2:   Optional action argument.
                   1056: // arg3:   Optional action argument.
                   1057: //
                   1058: // kIOReturnNotReady if the client request was rejected by the filter.
                   1059: // Otherwise kIOReturnSuccess is returned.
                   1060: 
                   1061: IOReturn IONetworkController::syncRequest(OSObject *     sender,
                   1062:                                           OSObject *     target,
                   1063:                                           RequestAction  action,
                   1064:                                           UInt32 *       ret  = 0,
                   1065:                                           void *         arg0 = 0,
                   1066:                                           void *         arg1 = 0,
                   1067:                                           void *         arg2 = 0,
                   1068:                                           void *         arg3 = 0)
                   1069: {
                   1070:     cmdStruct cmd;
                   1071:     IOReturn  rc;
                   1072:     UInt32    ra;
                   1073: 
                   1074:     // bzero(&cmd, sizeof(cmd));
                   1075: 
                   1076:     cmd.client  = sender;   // request client.
                   1077:     cmd.target  = target;   // target object.
                   1078:     cmd.action  = action;   // target action.
                   1079:     cmd.arg0    = arg0;     // action arguments.
                   1080:     cmd.arg1    = arg1;
                   1081:     cmd.arg2    = arg2;
                   1082:     cmd.arg3    = arg3;
                   1083: 
                   1084:     _cmdGate->runAction( (IOCommandGate::Action)
                   1085:                          &IONetworkController::commandHandler,     /* Action */
                   1086:                          (void *) &cmd,                 /* arg0 -  cmdStruct */
                   1087:                          (void *) &ra,               /* arg1 - action return */
                   1088:                          (void *) &rc );    /* arg2 -  commandHandler return */
                   1089: 
                   1090:     if ((rc == kIOReturnSuccess) && ret)
                   1091:         *ret = ra;
                   1092: 
                   1093:     return rc;
                   1094: }
                   1095: 
                   1096: //---------------------------------------------------------------------------
                   1097: // This method is called to qualify all client requests
                   1098: // sent to syncRequest(). This implementation will either allow or
                   1099: // refuse all requests, and this behavior is set by calling the 
                   1100: // enableSyncRequest() or disableSyncRequest() methods. By default,
                   1101: // all requests are allowed.
                   1102: //
                   1103: //  client: The client of the synchronous request.
                   1104: //  target: The target object that implements the request action.
                   1105: //  action: The action to perform.
                   1106: //  arg0:   Action argument.
                   1107: //  arg1:   Action argument.
                   1108: //  arg2:   Action argument.
                   1109: //  arg3:   Action argument.
                   1110: //
                   1111: // Returns true to accept the request and allow the request action to be
                   1112: // called, or false to refuse it.
                   1113: 
                   1114: bool IONetworkController::syncRequestFilter(OSObject *     client,
                   1115:                                             OSObject *     target,
                   1116:                                             RequestAction  action,
                   1117:                                             void *         arg0,
                   1118:                                             void *         arg1,
                   1119:                                             void *         arg2,
                   1120:                                             void *         arg3)
                   1121: {
                   1122:     // If _requestEnabled ifs true, allow the request, otherwise refuse it.
                   1123: 
                   1124:     return _requestEnabled;
                   1125: }
                   1126: 
                   1127: //---------------------------------------------------------------------------
                   1128: // A static member function to control the default syncRequestFilter()
                   1129: // filter function.
                   1130: 
                   1131: void  IONetworkController::_enableSyncRequestFilter(IONetworkController * ctlr,
                   1132:                                                     bool enabled)
                   1133: {
                   1134:     ctlr->_requestEnabled = enabled;
                   1135: }
                   1136: 
                   1137: //---------------------------------------------------------------------------
                   1138: // Enable all client requests sent to the syncRequest() method.
                   1139: // Don't use this method if the driver overrides syncRequestFilter().
                   1140: 
                   1141: void IONetworkController::enableSyncRequest()
                   1142: {
                   1143:     _cmdGate->runAction( (IOCommandGate::Action)
                   1144:                          &IONetworkController::_enableSyncRequestFilter,
                   1145:                          (void *) true );
                   1146: }
                   1147: 
                   1148: //---------------------------------------------------------------------------
                   1149: // Disable all client requests sent to the syncRequest() method.
                   1150: // Don't use this method if the driver overrides syncRequestFilter().
                   1151: 
                   1152: void IONetworkController::disableSyncRequest()
                   1153: {
                   1154:     _cmdGate->runAction( (IOCommandGate::Action)
                   1155:                          &IONetworkController::_enableSyncRequestFilter,
                   1156:                          (void *) false );
                   1157: }
                   1158: 
                   1159: //---------------------------------------------------------------------------
                   1160: // Get request client. Methods that are called by syncRequest() can call this
                   1161: // to get the client object which initiated the request.
                   1162: //
                   1163: // Returns the request client. If the caller's context does not indicate
                   1164: // that it is running through syncRequest(), then 0 is returned.
                   1165: 
                   1166: OSObject * IONetworkController::getSyncRequestClient() const
                   1167: {
                   1168:     return ( _workLoop->inGate() ? _reqClient : 0 );
                   1169: }
                   1170: 
                   1171: //---------------------------------------------------------------------------
                   1172: // Configure an interface object created through
                   1173: // createInterface(). IONetworkController will register
                   1174: // its output handler with the interface object provided.
                   1175: // Subclasses may override this method to customize the interface object.
                   1176: // Once the interface is registered and opened by a client, it will
                   1177: // refuse changes to its properties. And since this method is called
                   1178: // before the interface has become registered, this is a final
                   1179: // opportunity for the controller to configure the interface.
                   1180: //
                   1181: // interface: The interface object to be configured.
                   1182: //
                   1183: // Returns true if configuration was successful, false otherwise (this
                   1184: // will cause attachInterface() to fail).
                   1185: 
                   1186: bool IONetworkController::configureInterface(IONetworkInterface * interface)
                   1187: {
                   1188:     IOOutputAction  handler;
                   1189:     OSObject *      target;
                   1190:     bool            ret;
                   1191:     IONetworkData * stats;
                   1192: 
                   1193:     if (!OSDynamicCast(IONetworkInterface, interface))
                   1194:         return false;
                   1195: 
                   1196:     IOOutputQueue * outQueue = getOutputQueue();
                   1197: 
                   1198:     // Must register an output handler with the interface object.
                   1199:     // The interface will send output packets, and requests (commands)
                   1200:     // to its registered output handler. If we allocated an output
                   1201:     // queue, then we register the queue as the output handler,
                   1202:     // otherwise, we become the output handler.
                   1203: 
                   1204:     if (outQueue)
                   1205:     {
                   1206:         target  = outQueue;
                   1207:         handler = outQueue->getOutputHandler();
                   1208:     
                   1209:         stats   = outQueue->getStatisticsData();
                   1210:         interface->addNetworkData(stats);
                   1211:     }
                   1212:     else
                   1213:     {
                   1214:         target  = this;
                   1215:         handler = getOutputHandler();
                   1216:     }
                   1217:     ret = interface->registerOutputHandler(target, handler);
                   1218: 
                   1219:     return ret;
                   1220: }
                   1221: 
                   1222: bool
                   1223: IONetworkController::configureNetworkInterface(IONetworkInterface * interface)
                   1224: {
                   1225:     return true;
                   1226: }
                   1227: 
                   1228: //---------------------------------------------------------------------------
                   1229: // Called by start() to create an optional IOOutputQueue instance to handle
                   1230: // output queueing. The default implementation will always return 0, hence
                   1231: // no output queue will be created. A driver may override this method and 
                   1232: // return a subclass of IOOutputQueue. IONetworkController will keep a 
                   1233: // reference to the queue created, and will release the object when 
                   1234: // IONetworkController is freed. Also see getOutputQueue().
                   1235: //
                   1236: // Returns a newly allocated and initialized IOOutputQueue instance.
                   1237: 
                   1238: IOOutputQueue * IONetworkController::createOutputQueue()
                   1239: {
                   1240:     return 0;
                   1241: }
                   1242: 
                   1243: IOOutputQueue * IONetworkController::allocateOutputQueue()
                   1244: {
                   1245:     return 0;
                   1246: }
                   1247: 
                   1248: //---------------------------------------------------------------------------
                   1249: // Return the output queue allocated though createOutputQueue().
                   1250: 
                   1251: IOOutputQueue * IONetworkController::getOutputQueue() const
                   1252: {
                   1253:     return _outputQueue;
                   1254: }
                   1255: 
                   1256: //---------------------------------------------------------------------------
                   1257: // Called by start() to obtain the constraints on the memory buffer
                   1258: // associated with each mbuf allocated through allocatePacket().
                   1259: // Drivers can override this method to specify their buffer constraints
                   1260: // imposed by their bus master hardware. Note that outbound packets,
                   1261: // those that originate from the network stack, are not subject
                   1262: // to the constraints reported here.
                   1263: //
                   1264: // constraintsP: A pointer to an IOPacketBufferConstraints structure
                   1265: //               that that this method is expected to initialize.
                   1266: //               See IOPacketBufferConstraints structure definition.
                   1267: 
                   1268: void IONetworkController::getPacketBufferConstraints(
                   1269:                           IOPacketBufferConstraints * constraintsP) const
                   1270: {
                   1271:     assert(constraintsP);
                   1272:     constraintsP->alignStart  = kIOPacketBufferAlign1;
                   1273:     constraintsP->alignLength = kIOPacketBufferAlign1;
                   1274: }
                   1275: 
                   1276: //---------------------------------------------------------------------------
                   1277: // Allocates a mbuf chain. Each mbuf in the chain is aligned according to
                   1278: // the constraints from IONetworkController::getPacketBufferConstraints().
                   1279: // The last mbuf in the chain will be guaranteed to be length aligned if 
                   1280: // the 'size' argument is a multiple of the length alignment.
                   1281: //
                   1282: // The m->m_len and m->pkthdr.len fields are updated by this function.
                   1283: // This allows the driver to pass the mbuf chain obtained through this
                   1284: // function to the IOMbufMemoryCursor object directly.
                   1285: //
                   1286: // If (size + alignments) is smaller than MCLBYTES, then this function
                   1287: // will always return a single mbuf header or cluster.
                   1288: //
                   1289: // The allocation is guaranteed not to block. If a packet cannot be
                   1290: // allocated, this function will return NULL.
                   1291: 
                   1292: static inline UInt IO_ALIGN_MBUF(
                   1293:     struct mbuf * m,
                   1294:     UInt          size,
                   1295:     UInt          alignStart,
                   1296:     UInt          alignLength)
                   1297: {
                   1298:     assert(m);
                   1299:     UInt not_aligned = mtod(m, UInt) & alignStart;
                   1300:     
                   1301:     // Align starting address.
                   1302:     //
                   1303:     if (not_aligned) {
                   1304:         not_aligned = alignStart - not_aligned + 1;
                   1305:         m->m_data += not_aligned;
                   1306:         size      -= not_aligned;
                   1307:     }
                   1308:     
                   1309:     // Align buffer length.
                   1310:     //
                   1311:     if ((not_aligned = size & alignLength))
                   1312:         size -= not_aligned;
                   1313: 
                   1314:     return size;
                   1315: }
                   1316: 
                   1317: #define IO_APPEND_MBUF(head, tail, m) {     \
                   1318:     if (tail) {                             \
                   1319:         (tail)->m_next = (m);               \
                   1320:         (tail) = (m);                       \
                   1321:     }                                       \
                   1322:     else {                                  \
                   1323:         (head) = (tail) = (m);              \
                   1324:         (head)->m_pkthdr.len = 0;           \
                   1325:     }                                       \
                   1326: }
                   1327: 
                   1328: struct mbuf * IONetworkController::allocatePacket(UInt size)
                   1329: {
                   1330:     struct mbuf * head = 0;
                   1331:     struct mbuf * tail = 0;
                   1332: 
                   1333:     while (size) {
                   1334:         UInt mbufSize;
                   1335:         struct mbuf * m;
                   1336:     
                   1337:         // Allocate a mbuf, for the initial mbuf segment, allocate a
                   1338:         // mbuf header, otherwise a 'normal' mbuf will do.
                   1339:         
                   1340:         if (head) {
                   1341:             MGET(m, M_DONTWAIT, MT_DATA);
                   1342:             mbufSize = MLEN;
                   1343:         }
                   1344:         else {
                   1345:             MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1346:             mbufSize = MHLEN;
                   1347:         }
                   1348: 
                   1349:         if (!m) goto error;
                   1350: 
                   1351:         // Append the new mbuf to our chain.
                   1352:         
                   1353:         IO_APPEND_MBUF(head, tail, m);
                   1354: 
                   1355:         // If the remaining size exceed the buffer size of a normal mbuf,
                   1356:         // then attach a cluster to our mbuf. Currently, the cluster size
                   1357:         // is fixed, and the allocated memory is always MCLBYTES in size.
                   1358: 
                   1359:         if ((size + _alignPadding) > mbufSize) {
                   1360:             MCLGET(m, M_DONTWAIT);
                   1361:             if ((m->m_flags & M_EXT) == 0) goto error;
                   1362:             mbufSize = MCLBYTES;
                   1363:         }
                   1364:         
                   1365:         // mbufSize shall contain the (reduced) capacity of the mbuf after 
                   1366:         // alignment.
                   1367:         //
                   1368:         mbufSize = IO_ALIGN_MBUF(m, mbufSize, _alignStart, _alignLength);
                   1369: 
                   1370:         if (mbufSize > size) {
                   1371:             // If we wanted to force all mbufs in the chain to be aligned,
                   1372:             // including the last one, then do the following.
                   1373:             //
                   1374:             // mbufSize -= (mbufSize - size) & ~_alignLength;
                   1375: 
                   1376:             mbufSize = size;
                   1377:             size = 0;
                   1378:         }
                   1379:         else
                   1380:             size -= mbufSize;           // decrement the remaining size         
                   1381: 
                   1382:         m->m_len = mbufSize;            // update the length for this mbuf
                   1383:         head->m_pkthdr.len += mbufSize; // increment the total length
                   1384:     }
                   1385: 
                   1386:     return head;
                   1387: 
                   1388: error:
                   1389:     if (head) m_freem(head);
                   1390:     return 0;
                   1391: }
                   1392: 
                   1393: //---------------------------------------------------------------------------
                   1394: // Release the mbuf back to the free pool.
                   1395: 
                   1396: void IONetworkController::freePacket(struct mbuf * m)
                   1397: {
                   1398:     assert(m);
                   1399:     while (m) m = m_free(m);
                   1400: }
                   1401: 
                   1402: static inline bool IO_COPY_MBUF(
                   1403:     const struct mbuf * src,
                   1404:     struct mbuf *       dst,
                   1405:     int                 length)
                   1406: {
                   1407:     caddr_t src_dat, dst_dat;
                   1408:     int dst_len, src_len;
                   1409: 
                   1410:     assert(src && dst);
                   1411: 
                   1412:     dst_len = dst->m_len;
                   1413:     dst_dat = dst->m_data;
                   1414: 
                   1415:     while (src) {
                   1416: 
                   1417:         src_len = src->m_len;
                   1418:         src_dat = src->m_data;
                   1419: 
                   1420:         if (src_len > length)
                   1421:             src_len = length;
                   1422: 
                   1423:         while (src_len) {
                   1424:         
                   1425:             if (dst_len >= src_len) {
                   1426:                 // copy entire src mbuf to dst mbuf.
                   1427: 
                   1428:                 bcopy(src_dat, dst_dat, src_len);               
                   1429:                 length -= src_len;
                   1430:                 dst_len -= src_len;
                   1431:                 dst_dat += src_len;
                   1432:                 src_len = 0;
                   1433:             }
                   1434:             else {
                   1435:                 // fill up dst mbuf with some portion of the data in
                   1436:                 // the src mbuf.
                   1437: 
                   1438:                 bcopy(src_dat, dst_dat, dst_len);       // dst_len = 0?             
                   1439:                 length -= dst_len;
                   1440:                 dst_len = 0;
                   1441:                 src_len -= dst_len;         
                   1442:             }
                   1443:             
                   1444:             // Go to the next destination mbuf segment.
                   1445:             
                   1446:             if (dst_len == 0) {
                   1447:                 if (!(dst = dst->m_next))
                   1448:                     return (length == 0);
                   1449:                 dst_len = dst->m_len;
                   1450:                 dst_dat = dst->m_data;
                   1451:             }
                   1452: 
                   1453:         } /* while (src_len) */
                   1454: 
                   1455:         src = src->m_next;
                   1456: 
                   1457:     } /* while (src) */
                   1458:     
                   1459:     return (length == 0);   // returns true on success.
                   1460: }
                   1461: 
                   1462: //---------------------------------------------------------------------------
                   1463: // Replace the mbuf pointed by the given pointer with another mbuf.
                   1464: // Drivers can call this method to replace a mbuf before passing the
                   1465: // original mbuf, which contains a received frame, to the network layer.
                   1466: //
                   1467: // mp:   A pointer to the original mbuf that shall be updated by this
                   1468: //       method to point to the new mbuf.
                   1469: // size: If size is 0, then the new mbuf shall have the same size
                   1470: //       as the original mbuf that is being replaced. Otherwise, the new
                   1471: //       mbuf shall have the size specified here.
                   1472: //
                   1473: // If mbuf allocation was successful, then the replacement will
                   1474: // take place and the original mbuf will be returned. Otherwise,
                   1475: // a NULL is returned.
                   1476: 
                   1477: struct mbuf * IONetworkController::replacePacket(struct mbuf ** mp,
                   1478:                                                  UInt size = 0)
                   1479: {   
                   1480:     assert((mp != NULL) && (*mp != NULL));
                   1481: 
                   1482:     struct mbuf * m = *mp;
                   1483: 
                   1484:     // If size is zero, then size is taken from the source mbuf.
                   1485:     //  
                   1486:     if (size == 0)
                   1487:         size = m->m_pkthdr.len;
                   1488:     
                   1489:     // Allocate a new packet to replace the current packet.
                   1490:     //
                   1491:     if (!(*mp = allocatePacket(size)))
                   1492:     {
                   1493:         *mp = m; m = 0;
                   1494:     }
                   1495: 
                   1496:     return m;
                   1497: }
                   1498: 
                   1499: //---------------------------------------------------------------------------
                   1500: // Make a copy of a mbuf, and return the copy. The source mbuf is not modified.
                   1501: //
                   1502: // m:    The source mbuf.
                   1503: // size: The number of bytes to copy. If set to 0, then the entire
                   1504: //       source mbuf is copied.
                   1505: //
                   1506: // Returns a new mbuf created from the source packet.
                   1507: 
                   1508: struct mbuf * IONetworkController::copyPacket(const struct mbuf * m,
                   1509:                                               UInt size = 0)
                   1510: {
                   1511:     struct mbuf * mn;
                   1512: 
                   1513:     assert(m != NULL);
                   1514: 
                   1515:     // If size is zero, then size is taken from the source mbuf.
                   1516:     //  
                   1517:     if (size == 0)
                   1518:         size = m->m_pkthdr.len;
                   1519: 
                   1520:     // Copy the current mbuf to the new mbuf, and return the new mbuf.
                   1521:     // The input mbuf is left intact.
                   1522:     //
                   1523:     if (!(mn = allocatePacket(size)))
                   1524:         return 0;
                   1525: 
                   1526:     if (!IO_COPY_MBUF(m, mn, size))
                   1527:     {
                   1528:         IOLog("IONetworkController: copyPacket failure\n");
                   1529:         freePacket(mn);
                   1530:         mn = 0;
                   1531:     }
                   1532: 
                   1533:     return mn;
                   1534: }
                   1535: 
                   1536: //---------------------------------------------------------------------------
                   1537: // Either replace or copy the source mbuf given depending on the amount of
                   1538: // data in the source mbuf. This method will either perform a copy or replace 
                   1539: // the source mbuf, whichever is more time efficient. If replaced, then the
                   1540: // original mbuf is returned, and a new mbuf is allocated to take its place.
                   1541: // If copied, the source mbuf is left intact, while a copy is returned that
                   1542: // is just big enough to hold all the data from the source mbuf.
                   1543: //
                   1544: // mp:        A pointer to the source mbuf that may be updated by this
                   1545: //            method to point to the new mbuf if replaced.
                   1546: // rcvlen:    The number of data bytes in the source mbuf.
                   1547: // replacedP: Pointer to a bool that is set to true if the
                   1548: //            source mbuf was replaced, or set to false if the
                   1549: //            source mbuf was copied.
                   1550: //
                   1551: // Returns a replacement or a copy of the source mbuf, 0 if mbuf
                   1552: // allocation failed.
                   1553: 
                   1554: struct mbuf * IONetworkController::replaceOrCopyPacket(struct mbuf ** mp,
                   1555:                                                        UInt   rcvlen,
                   1556:                                                        bool * replacedP)
                   1557: {
                   1558:     struct mbuf * m;
                   1559: 
                   1560:     if ((rcvlen + _alignPadding) > MHLEN)
                   1561:     {
                   1562:         // Large packet, it is more efficient to allocate a new mbuf
                   1563:         // to replace the original mbuf than to make a copy. The new
                   1564:         // packet shall have the same size as the original mbuf being
                   1565:         // replaced.
                   1566:         // 
                   1567:         m = replacePacket(mp);
                   1568:         *replacedP = true;
                   1569:     }
                   1570:     else {
                   1571:         // The copy will fit within a header mbuf. Fine, make a copy
                   1572:         // of the original mbuf instead of replacing it. We only copy
                   1573:         // the rcvlen bytes, not the entire source mbuf.
                   1574:         //
                   1575:         assert((mp != NULL) && (*mp != NULL));
                   1576:         m = copyPacket(*mp, rcvlen);        
                   1577:         *replacedP = false;
                   1578:     }
                   1579: 
                   1580:     return m;
                   1581: }
                   1582: 
                   1583: //---------------------------------------------------------------------------
                   1584: // Used for debugging only. Log the mbuf header.
                   1585: 
                   1586: void IONetworkController::_logMbuf(struct mbuf * m)
                   1587: {
                   1588:     if (!m) {
                   1589:         IOLog("logMbuf: NULL mbuf\n");
                   1590:         return;
                   1591:     }
                   1592:     
                   1593:     while (m) {
                   1594:         IOLog("m_next   : %08x\n", (UInt) m->m_next);
                   1595:         IOLog("m_nextpkt: %08x\n", (UInt) m->m_nextpkt);
                   1596:         IOLog("m_len    : %d\n",   (UInt) m->m_len);
                   1597:         IOLog("m_data   : %08x\n", (UInt) m->m_data);
                   1598:         IOLog("m_type   : %08x\n", (UInt) m->m_type);
                   1599:         IOLog("m_flags  : %08x\n", (UInt) m->m_flags);
                   1600:         
                   1601:         if (m->m_flags & M_PKTHDR)
                   1602:             IOLog("m_pkthdr.len  : %d\n", (UInt) m->m_pkthdr.len);
                   1603: 
                   1604:         if (m->m_flags & M_EXT) {
                   1605:             IOLog("m_ext.ext_buf : %08x\n", (UInt) m->m_ext.ext_buf);
                   1606:             IOLog("m_ext.ext_size: %d\n", (UInt) m->m_ext.ext_size);
                   1607:         }
                   1608:         
                   1609:         m = m->m_next;
                   1610:     }
                   1611:     IOLog("\n");
                   1612: }
                   1613: 
                   1614: //---------------------------------------------------------------------------
                   1615: // Allocate and attache a new IOKernelDebugger client object.
                   1616: //
                   1617: // debuggerP: An IOKernelDebugger handle that is updated by this method
                   1618: //            to contain the allocated IOKernelDebugger instance.
                   1619: //
                   1620: // Returns true on success, false otherwise.
                   1621: 
                   1622: bool IONetworkController::attachDebuggerClient(IOKernelDebugger ** debugger)
                   1623: {
                   1624:     IOKernelDebugger *  client;
                   1625:     OSString *          debuggerString;
                   1626:     bool                ret = false;
                   1627:     bool                initOk = false;
                   1628: 
                   1629:     // We delay some initialization until the first time that
                   1630:     // attachInterface() is called by the subclass.
                   1631:     //
                   1632:     SYNC_REQ(this, &IONetworkController::_controllerIsReady, &initOk);
                   1633:     if (!initOk)
                   1634:         return false;
                   1635: 
                   1636:     // Refuse to attach a debugger client if the controller's kIOEnableDebugger
                   1637:     // property set to No (first letter starts with 'n' or 'N').
                   1638: 
                   1639:     debuggerString = OSDynamicCast(OSString, getProperty(kIOEnableDebugger));
                   1640:     if (!debuggerString ||
                   1641:         (debuggerString->getChar(0) == 'N') ||
                   1642:         (debuggerString->getChar(0) == 'n'))
                   1643:         return false;
                   1644: 
                   1645:     // Create a debugger client nub and register the static
                   1646:     // member functions as the polled-mode handlers.
                   1647:     //
                   1648:     client = IOKernelDebugger::debugger(this,
                   1649:                                         &debugTxHandler,
                   1650:                                         &debugRxHandler);
                   1651: 
                   1652:     *debugger = client;
                   1653: 
                   1654:     if (client && !client->attach(this))
                   1655:     {
                   1656:         // Unable to attach the client object.
                   1657:         *debugger = 0;
                   1658:         client->detach(this);
                   1659:         client->release();
                   1660:     }
                   1661: 
                   1662:     if (*debugger)
                   1663:     {
                   1664:         IOLog("%s: Debugger client attached\n", getName());
                   1665:         publishResource("kdp");
                   1666:         ret = true;
                   1667:     }
                   1668: 
                   1669:     return ret;
                   1670: }
                   1671: 
                   1672: //---------------------------------------------------------------------------
                   1673: // Detach and terminate the IOKernelDebugger client object provided.
                   1674: // A synchronous termination is issued, and this method returns after
                   1675: // the client has been terminated.
                   1676: //
                   1677: // debugger: The IOKernelDebugger instance to be detached and terminated.
                   1678: //           If the argument provided is NULL or is not an IOKernelDebugger,
                   1679: //           this method will return immediately.
                   1680: 
                   1681: void IONetworkController::detachDebuggerClient(IOKernelDebugger * debugger)
                   1682: {
                   1683:     if (OSDynamicCast(IOKernelDebugger, debugger) == 0)
                   1684:         return;
                   1685: 
                   1686:     // Terminate the debugger client and return after the client has
                   1687:     // been terminated. Since the debugger has no IOKit clients of
                   1688:     // its own, this should be fast.
                   1689: 
                   1690:     debugger->terminate(kIOServiceRequired | kIOServiceSynchronous);
                   1691: }
                   1692: 
                   1693: //---------------------------------------------------------------------------
                   1694: // An enable request from an IOKernelDebugger client. This method is called 
                   1695: // when an open is received from an IOKernelDebugger client. Drivers that
                   1696: // wish to provide debugging services must override this method and setup
                   1697: // the hardware to support the polled-mode send and receive methods;
                   1698: // receivePacket() and sendPacket(). Debug capable drivers may also override
                   1699: // the more generic enable/disable calls that take an IOService argument.
                   1700: //
                   1701: // debugger: The IOKernelDebugger client that issued the open.
                   1702: //
                   1703: // Returns kIOReturnSuccess. The driver method must return kIOReturnSuccess
                   1704: // to allow the debugger open, anything else will cause the debugger open
                   1705: // to fail and the attachDebuggerClient() method will return false.
                   1706: 
                   1707: IOReturn IONetworkController::enable(IOKernelDebugger * debugger)
                   1708: {
                   1709:     return handleDebuggerOpen(debugger);
                   1710: }
                   1711: 
                   1712: IOReturn IONetworkController::handleDebuggerOpen(IOKernelDebugger * debugger)
                   1713: {
                   1714:     return kIOReturnSuccess;
                   1715: }
                   1716: 
                   1717: //---------------------------------------------------------------------------
                   1718: // A disable request from an IOKernelDebugger client. This method is called
                   1719: // when a close is received from an IOKernelDebugger client. A driver which
                   1720: // implements enable(IOKernelDebugger *) should also implement this method
                   1721: // to disable hardware support for the polled-mode send and receive methods.
                   1722: //
                   1723: // debugger: The IOKernelDebugger client that issued the close.
                   1724: //
                   1725: // Returns kIOReturnSuccess. The driver method should return a status
                   1726: // from the disable operation.
                   1727: 
                   1728: IOReturn IONetworkController::disable(IOKernelDebugger * debugger)
                   1729: {
                   1730:     return handleDebuggerClose(debugger);
                   1731: }
                   1732: 
                   1733: IOReturn IONetworkController::handleDebuggerClose(IOKernelDebugger * debugger)
                   1734: {
                   1735:     return kIOReturnSuccess;
                   1736: }
                   1737: 
                   1738: //---------------------------------------------------------------------------
                   1739: // Take and release the debugger lock.
                   1740: 
                   1741: void IONetworkController::reserveDebuggerLock()
                   1742: {
                   1743:     _debugLockState = IODebuggerLock(this);
                   1744: }
                   1745: 
                   1746: void IONetworkController::releaseDebuggerLock()
                   1747: {
                   1748:     IODebuggerUnlock(_debugLockState);
                   1749: }
                   1750: 
                   1751: //---------------------------------------------------------------------------
                   1752: // This static C++ member function is registered by attachDebuggerClient()
                   1753: // as the debugger receive handler. IOKernelDebugger will call this
                   1754: // function when KDP is polling for a received packet. This function will
                   1755: // in turn will call the receivePacket() member function implemented by
                   1756: // a driver with debugger support.
                   1757: 
                   1758: void IONetworkController::debugRxHandler(IOService * handler,
                   1759:                                          void *      buffer,
                   1760:                                          UInt *      length,
                   1761:                                          UInt        timeout)
                   1762: {
                   1763:     ((IONetworkController *) handler)->receivePacket(buffer,
                   1764:                                                      length,
                   1765:                                                      timeout);   
                   1766: }
                   1767: 
                   1768: //---------------------------------------------------------------------------
                   1769: // This static C++ member function is registered by attachDebuggerClient()
                   1770: // as the debugger transmit handler. IOKernelDebugger will call this
                   1771: // function when KDP sends an outgoing packet. This function will in turn
                   1772: // call the sendPacket() member function implemented by a driver with
                   1773: // debugger support.
                   1774: 
                   1775: void IONetworkController::debugTxHandler(IOService * handler,
                   1776:                                          void *      buffer,
                   1777:                                          UInt        length)
                   1778: {
                   1779:     ((IONetworkController *) handler)->sendPacket(buffer, length);
                   1780: }
                   1781: 
                   1782: //---------------------------------------------------------------------------
                   1783: // Debugger polled-mode receive handler. This method must be implemented
                   1784: // by a driver that supports kernel debugging. After a debugger client is 
                   1785: // attached through attachDebuggerClient(), this method will be called by
                   1786: // the debugger object to poll for a incoming packet when the debugger is
                   1787: // active. This method can be called from an interrupt context, and the
                   1788: // driver must never block or perform any memory allocation. The
                   1789: // receivePacket() method in IONetworkController is used as a placeholder
                   1790: // and should never be called. A driver that attaches a debugger client
                   1791: // must override this method.
                   1792: //
                   1793: // pkt:     Pointer to a receive buffer where the received packet should
                   1794: //          be stored to. The buffer has room for 1518 bytes.
                   1795: // pkt_len: The length of the received packet must be written to the
                   1796: //          integer pointed by pkt_len.
                   1797: // timeout: The maximum amount of time in milliseconds to poll for
                   1798: //          a packet to arrive before this method must return.
                   1799: 
                   1800: void IONetworkController::receivePacket(void * /*pkt*/,
                   1801:                                         UInt * /*pkt_len*/,
                   1802:                                         UInt /*timeout*/)
                   1803: {
                   1804:     IOLog("IONetworkController::%s()\n", __FUNCTION__);
                   1805: }
                   1806: 
                   1807: //---------------------------------------------------------------------------
                   1808: // Debugger polled-mode transmit handler. This method must be implemented
                   1809: // by a driver that supports kernel debugging. After a debugger client is 
                   1810: // attached through attachDebuggerClient(), this method will be called by
                   1811: // the debugger object to send an outbound packet generated by the debugger.
                   1812: // This method can be called from an interrupt context, and the
                   1813: // driver must never block or perform any memory allocation. The
                   1814: // sendPacket() method in IONetworkController is used as a placeholder
                   1815: // and should never be called. A driver that attaches a debugger client
                   1816: // must override this method.
                   1817: //
                   1818: // pkt:     Pointer to a transmit buffer containing the packet to be sent.
                   1819: // pkt_len: The amount of data in the transmit buffer.
                   1820: 
                   1821: void IONetworkController::sendPacket(void * /*pkt*/, UInt /*pkt_len*/)
                   1822: {
                   1823:     IOLog("IONetworkController::%s()\n", __FUNCTION__);
                   1824: }
                   1825: 
                   1826: //---------------------------------------------------------------------------
                   1827: // Report the link status and the active medium. Update the link status 
                   1828: // parameters published by the controller. Drivers should call this method 
                   1829: // whenever the link status changes. Never call this method from interrupt 
                   1830: // context since this method may block. An event will be sent to all attached
                   1831: // interface objects when a change is detected.
                   1832: //
                   1833: // status: Link status bits. See IONetworkMedium.h for defined link
                   1834: //         status bits.
                   1835: // speed:  Link speed in units of bits per second.
                   1836: // activeMedium: A medium entry in the published medium dictionary
                   1837: //               where the link was established. This may not be the
                   1838: //               same as the current medium.
                   1839: // data:   An OSData containing any additional link information.
                   1840: //
                   1841: // Returns true if all link properties were successfully updated,
                   1842: // false otherwise.
                   1843: 
                   1844: bool IONetworkController::setLinkStatus(UInt32                  status,
                   1845:                                         UInt64                  speed,
                   1846:                                         const IONetworkMedium * activeMedium,
                   1847:                                         OSData *                data = 0)
                   1848: {
                   1849:     bool   ret;
                   1850:     bool   changed = false;
                   1851: 
                   1852:     MEDIUM_LOCK;
                   1853: 
                   1854:     ret = setMediumProperty(gIOActiveMediumKey,
                   1855:                             activeMedium,
                   1856:                             &_activeMedium,
                   1857:                             false,
                   1858:                             &changed);
                   1859: 
                   1860:     ret = setLink32Property(kIOLinkStatus,
                   1861:                             status,
                   1862:                             &_linkStatus,
                   1863:                             false,
                   1864:                             &changed) && ret;
                   1865: 
                   1866:     ret = setLink64Property(kIOLinkSpeed,
                   1867:                             speed,
                   1868:                             &_linkSpeed,
                   1869:                             false,
                   1870:                             &changed) && ret;
                   1871: 
                   1872:     if (data) {
                   1873:         if (_linkData != data) {
                   1874:             ret = setProperty(kIOLinkData, data) && ret;
                   1875:             _linkData = data;
                   1876:             changed = true;
                   1877:         }
                   1878:     }
                   1879:     else if (_linkData) {
                   1880:         _linkData = 0;
                   1881:         removeProperty(kIOLinkData);
                   1882:         changed = true;
                   1883:     }
                   1884: 
                   1885:     MEDIUM_UNLOCK;
                   1886: 
                   1887:     if (changed)
                   1888:         broadcastEvent(kIONetworkEventLinkChange);
                   1889: 
                   1890:     return ret;
                   1891: }
                   1892: 
                   1893: //---------------------------------------------------------------------------
                   1894: // Returns the medium dictionary published by the driver through
                   1895: // publishMediumDictionary(). Use copyMediumDictionary() to get a copy
                   1896: // of the medium dictionary.
                   1897: //
                   1898: // Returns the published medium dictionary, or 0 if the driver has not
                   1899: // yet published a medium dictionary using publishMediumDictionary().
                   1900: 
                   1901: const OSDictionary * IONetworkController::getMediumDictionary() const
                   1902: {
                   1903:     return OSDynamicCast(OSDictionary, getProperty(kIOMediumDictionary));
                   1904: }
                   1905: 
                   1906: //---------------------------------------------------------------------------
                   1907: // Returns a.copy of the medium dictionary published by the driver.
                   1908: // The caller is responsible for releasing the dictionary object returned.
                   1909: // Use getMediumDictionary() to get a reference to the published medium
                   1910: // dictionary instead of creating a copy.
                   1911: //
                   1912: // Returns a copy of the medium dictionary, or 0 if the driver has not
                   1913: // published a medium dictionary using publishMediumDictionary().
                   1914: 
                   1915: OSDictionary * IONetworkController::copyMediumDictionary() const
                   1916: {
                   1917:     OSDictionary * newMediumDict = 0;
                   1918: 
                   1919:     MEDIUM_LOCK;
                   1920: 
                   1921:     if (getMediumDictionary()) {
                   1922:         newMediumDict = OSDictionary::withDictionary(getMediumDictionary(),
                   1923:                                       getMediumDictionary()->getCount());
                   1924:     }
                   1925: 
                   1926:     MEDIUM_UNLOCK;
                   1927: 
                   1928:     return newMediumDict;
                   1929: }
                   1930: 
                   1931: //---------------------------------------------------------------------------
                   1932: // A client request for the controller to change the selected medium.
                   1933: // Drivers may override this method and provide an implementation
                   1934: // appropriate for its hardware, then call setCurrentMedium() to update
                   1935: // the current medium property if a change occurred.
                   1936: //
                   1937: // medium: An entry in the published medium dictionary.
                   1938: //
                   1939: // Return kIOReturnUnsupported. Drivers may override this method and
                   1940: // return kIOReturnSuccess if the selected medium was activated,
                   1941: // or an error code otherwise.
                   1942: 
                   1943: IOReturn IONetworkController::selectMedium(const IONetworkMedium * medium)
                   1944: {
                   1945:     return kIOReturnUnsupported;
                   1946: }
                   1947: 
                   1948: //---------------------------------------------------------------------------
                   1949: // Private function to lookup a key in the medium dictionary and call 
                   1950: // setMedium() if a match is found. This function is called by our
                   1951: // clients to change the medium by passing a name for the desired medium.
                   1952: 
                   1953: IOReturn IONetworkController::selectMediumWithName(const OSSymbol * mediumName)
                   1954: {
                   1955:     OSSymbol *        currentMediumName;
                   1956:     IONetworkMedium * newMedium = 0;
                   1957:     bool              doChange  = true;
                   1958:     IOReturn          ret       = kIOReturnSuccess;
                   1959: 
                   1960:     if (OSDynamicCast(OSSymbol, mediumName) == 0)
                   1961:         return kIOReturnBadArgument;
                   1962: 
                   1963:     MEDIUM_LOCK;
                   1964: 
                   1965:     do {
                   1966:         const OSDictionary * mediumDict = getMediumDictionary();
                   1967:         if (!mediumDict) {  // no medium dictionary, bail out.
                   1968:             ret = kIOReturnUnsupported;
                   1969:             break;
                   1970:         }
                   1971: 
                   1972:         // Lookup the new medium in the dictionary.
                   1973:         //
                   1974:         newMedium = OSDynamicCast(IONetworkMedium, 
                   1975:                                   mediumDict->getObject(mediumName));
                   1976:         if (!newMedium) {
                   1977:             ret = kIOReturnBadArgument;
                   1978:             break;          // not found, invalid mediumName.
                   1979:         }
                   1980: 
                   1981:         newMedium->retain();
                   1982: 
                   1983:         // Lookup the current medium key to avoid unnecessary
                   1984:         // medium changes.
                   1985:         //
                   1986:         currentMediumName = (OSSymbol *) getProperty(gIOCurrentMediumKey);
                   1987: 
                   1988:         // Is change necessary?
                   1989:         //
                   1990:         if (currentMediumName && mediumName->isEqualTo(currentMediumName))
                   1991:             doChange = false;
                   1992:     }
                   1993:     while (0);
                   1994: 
                   1995:     MEDIUM_UNLOCK;
                   1996: 
                   1997:     if (newMedium)
                   1998:     {
                   1999:         // Call the driver's selectMedium() without holding the medium lock.
                   2000:     
                   2001:         if (doChange)
                   2002:             ret = selectMedium(newMedium);
                   2003: 
                   2004:         // offset the earlier retain count increment.
                   2005:         //
                   2006:         newMedium->release();
                   2007:     }
                   2008: 
                   2009:     return ret;
                   2010: }
                   2011: 
                   2012: //---------------------------------------------------------------------------
                   2013: // Private function to add/replace/remove a medium property in the 
                   2014: // property table. Returns true if the medium property was successfully
                   2015: // added to the property table. The medium lock should be held before
                   2016: // calling this function.
                   2017: 
                   2018: bool IONetworkController::setMediumProperty(const OSSymbol *         key,
                   2019:                                             const IONetworkMedium *  medium,
                   2020:                                             const IONetworkMedium ** cache,
                   2021:                                             bool                     force,
                   2022:                                             bool *                   changed)
                   2023: {
                   2024:     bool  ret = false;
                   2025: 
                   2026:     do {
                   2027:         if (!force && (*cache == medium))
                   2028:         {
                   2029:             ret = true;
                   2030:             break;
                   2031:         }
                   2032: 
                   2033:         if (medium == 0)
                   2034:         {
                   2035:             removeProperty(key);
                   2036:             if (changed) *changed = true;
                   2037:             *cache = 0;
                   2038:             ret = true;
                   2039:             break;
                   2040:         }
                   2041: 
                   2042:         const OSDictionary * mediumDict = getMediumDictionary();
                   2043:         if (!mediumDict)
                   2044:             break;    // no medium dictionary, bail out.
                   2045: 
                   2046:         if (OSDynamicCast(IONetworkMedium, medium) == 0)
                   2047:             break;    // not a valid IONetworkMedium.
                   2048: 
                   2049:         // Make sure the medium given is an entry in the medium dictionary.
                   2050:         //
                   2051:         if (mediumDict->getObject(medium->getName()) != (OSObject *) medium)
                   2052:             break;    // not a member of dictionary.
                   2053: 
                   2054:         // Update property table.
                   2055:         //
                   2056:         if ((ret = setProperty(key, (OSSymbol *) medium->getName())))
                   2057:         {
                   2058:             if (changed) *changed = true;
                   2059:             *cache = medium;
                   2060:         }
                   2061:     }
                   2062:     while (0);
                   2063: 
                   2064:     return ret;
                   2065: }
                   2066: 
                   2067: bool IONetworkController::setLink64Property(const char *   key,
                   2068:                                             UInt64         value,
                   2069:                                             UInt64 *       cache,
                   2070:                                             bool           force = false,
                   2071:                                             bool *         changed = 0)
                   2072: {
                   2073:     if (!force && (*cache == value))
                   2074:         return true;
                   2075: 
                   2076:     if (setProperty(key, value, 64))
                   2077:     {
                   2078:         if (changed) *changed = true;
                   2079:         *cache = value;
                   2080:         return true;
                   2081:     }
                   2082: 
                   2083:     return false;
                   2084: }
                   2085: 
                   2086: bool IONetworkController::setLink32Property(const char *   key,
                   2087:                                             UInt32         value,
                   2088:                                             UInt32 *       cache,
                   2089:                                             bool           force = false,
                   2090:                                             bool *         changed = 0)
                   2091: {
                   2092:     if (!force && (*cache == value))
                   2093:         return true;
                   2094: 
                   2095:     if (setProperty(key, value, 32))
                   2096:     {
                   2097:         if (changed) *changed = true;
                   2098:         *cache = value;
                   2099:         return true;
                   2100:     }
                   2101: 
                   2102:     return false;
                   2103: }
                   2104: 
                   2105: //---------------------------------------------------------------------------
                   2106: // From the set of medium objects in the medium dictionary published by the 
                   2107: // driver, one of them can be designated as the currently selected medium. 
                   2108: // Drivers should call this method whenever their media selection changes.
                   2109: // An entry in the driver's property table is updated to advertise the 
                   2110: // current medium.
                   2111: //
                   2112: // A media change event will be broadcasted to all attached interface
                   2113: // clients when the current medium property changes.
                   2114: //
                   2115: // medium: A medium object to promote as the current medium.
                   2116: //
                   2117: // Returns true if the medium dictionary exists, the medium object
                   2118: // provided matches an entry in this dictionary, and the property
                   2119: // table update was successful, false otherwise.
                   2120: 
                   2121: bool IONetworkController::setCurrentMedium(const IONetworkMedium * medium)
                   2122: {
                   2123:     bool ret, changed;
                   2124: 
                   2125:     MEDIUM_LOCK;
                   2126:     ret = setMediumProperty(gIOCurrentMediumKey,
                   2127:                             medium, 
                   2128:                             &_currentMedium,
                   2129:                             false,
                   2130:                             &changed);
                   2131:     MEDIUM_UNLOCK;
                   2132: 
                   2133:     if (changed)
                   2134:         broadcastEvent(kIONetworkEventMediumChange);
                   2135:     
                   2136:     return ret;
                   2137: }
                   2138: 
                   2139: //---------------------------------------------------------------------------
                   2140: // Returns the currently selected medium object. If the driver has yet to
                   2141: // assign an entry in its medium dictionary as the current medium using the
                   2142: // setCurrentMedium() method, then the driver's property table is consulted
                   2143: // and a default medium property (can be set by the user), is looked
                   2144: // up and the corresponding entry in the medium dictionary is returned.
                   2145: // Therefore, drivers can always call getCurrentMedium() to either get
                   2146: // the current medium selected by the driver, or the default
                   2147: // medium chosen by the user.
                   2148: //
                   2149: // Returns the current medium entry from the medium dictionary, or 0
                   2150: // if a matching entry was not found.
                   2151: 
                   2152: const IONetworkMedium * IONetworkController::getCurrentMedium() const
                   2153: {
                   2154:     IONetworkMedium * currentMedium     = 0;
                   2155:     OSString *        currentMediumName = 0;
                   2156: 
                   2157:     MEDIUM_LOCK;
                   2158: 
                   2159:     do {
                   2160:         const OSDictionary * mediumDict = getMediumDictionary();
                   2161:         if (!mediumDict)    // no medium dictionary, bail out.
                   2162:             break;
                   2163: 
                   2164:         // Fetch the current medium name from the property table.
                   2165:         //
                   2166:         currentMediumName = OSDynamicCast(OSString,
                   2167:                             getProperty(gIOCurrentMediumKey));
                   2168: 
                   2169:         // Make sure the current medium name points to an entry in
                   2170:         // the medium dictionary.
                   2171:         //
                   2172:         if (currentMediumName && !mediumDict->getObject(currentMediumName))
                   2173:             currentMediumName = 0;
                   2174: 
                   2175:         if (currentMediumName == 0) {
                   2176:             OSString * defaultMediumName;
                   2177: 
                   2178:             // No (valid) current medium name, try the default medium name.
                   2179:             //
                   2180:             defaultMediumName = OSDynamicCast(OSString, 
                   2181:                                 getProperty(kIODefaultMedium));
                   2182: 
                   2183:             // If there is a default medium name, and it points to a
                   2184:             // valid entry in the medium dictionary, then make it
                   2185:             // current.
                   2186:             //
                   2187:             if (defaultMediumName &&
                   2188:                 mediumDict->getObject(defaultMediumName))
                   2189:             {
                   2190:                 // setProperty(kIOCurrentMedium, defaultMediumKey);
                   2191:                 currentMediumName = defaultMediumName;
                   2192:             }
                   2193:         }
                   2194: 
                   2195:         if (currentMediumName)
                   2196:             currentMedium = OSDynamicCast(IONetworkMedium, 
                   2197:                             mediumDict->getObject(currentMediumName));
                   2198:     }
                   2199:     while (0);
                   2200: 
                   2201:     MEDIUM_UNLOCK;
                   2202: 
                   2203:     return currentMedium;
                   2204: }
                   2205: 
                   2206: //---------------------------------------------------------------------------
                   2207: // A private function to verify a medium dictionary. Returns true if the
                   2208: // dictionary is OK.
                   2209: 
                   2210: bool IONetworkController::verifyMediumDictionary(
                   2211:                                 const OSDictionary * mediumDict)
                   2212: {
                   2213:     OSCollectionIterator * iter;
                   2214:     bool                   verifyOk = true;
                   2215:     OSSymbol *             key;
                   2216: 
                   2217:     if (!OSDynamicCast(OSDictionary, mediumDict))
                   2218:         return false;   // invalid argument
                   2219: 
                   2220:     if (mediumDict->getCount() == 0)
                   2221:         return false;   // empty dictionary
                   2222: 
                   2223:     iter = OSCollectionIterator::withCollection((OSDictionary *) mediumDict);
                   2224:     if (!iter)
                   2225:         return false;   // cannot allocate iterator
                   2226: 
                   2227:     while ((key = (OSSymbol *) iter->getNextObject()))
                   2228:     {
                   2229:         if ( !OSDynamicCast(IONetworkMedium, mediumDict->getObject(key)) )
                   2230:         {
                   2231:             verifyOk = false;   // non-medium object in dictionary
                   2232:             break;
                   2233:         }
                   2234:     }
                   2235: 
                   2236:     iter->release();
                   2237:     
                   2238:     return verifyOk;
                   2239: }
                   2240: 
                   2241: //---------------------------------------------------------------------------
                   2242: // Called by drivers to publish their medium dictionary.
                   2243: // The dictionary consist of IONetworkMedium entries that represent
                   2244: // the entire media selection supported by the hardware. This method
                   2245: // will make a copy of the provided dictionary, then add the copy to
                   2246: // the driver's property table. The dictionary provided can be
                   2247: // released after this call returns. It is permissible to call
                   2248: // this method multiple times, which may be necessary if the hardware's
                   2249: // media capability changes dynamically. However, if this were not
                   2250: // so, then drivers will typically call this method from its start() 
                   2251: // implementation, after the hardware capability is discovered.
                   2252: //
                   2253: // Several methods depend on the presence of a medium dictionary.
                   2254: // They should be called after the dictionary has been published.
                   2255: // Those are:
                   2256: //   selectMedium()
                   2257: //   setCurrentMedium()
                   2258: //   getCurrentMedium()
                   2259: //   getMediumDictionary()
                   2260: //   copyMediumDictionary()
                   2261: //
                   2262: // Calling publishMediumDictionary() will cause a media change event
                   2263: // to be delivered to all attached interface clients.
                   2264: //
                   2265: // Returns true if the dictionary is valid, and was successfully
                   2266: // added to the property table, false otherwise.
                   2267: 
                   2268: bool
                   2269: IONetworkController::publishMediumDictionary(const OSDictionary * mediumDict)
                   2270: {
                   2271:     OSDictionary *   cloneDict;
                   2272:     bool             ret = false;
                   2273: 
                   2274:     if (!verifyMediumDictionary(mediumDict))
                   2275:         return false;   // invalid dictionary
                   2276: 
                   2277:     // Create a clone of the source dictionary. This prevents the driver
                   2278:     // from adding/removing entries after the medium dictionary is added
                   2279:     // to the property table.
                   2280:     //
                   2281:     cloneDict = OSDictionary::withDictionary(mediumDict,
                   2282:                                              mediumDict->getCount());
                   2283:     if (!cloneDict)
                   2284:         return false;  // unable to create a copy
                   2285: 
                   2286:     MEDIUM_LOCK;                              
                   2287: 
                   2288:     // Add the dictionary to the property table.
                   2289:     //
                   2290:     if (setProperty(kIOMediumDictionary, cloneDict))
                   2291:     {
                   2292:         const OSSymbol *   mediumName;
                   2293:         IONetworkMedium *  medium;
                   2294: 
                   2295:         mediumName = (OSSymbol *) getProperty(gIOCurrentMediumKey);
                   2296:         medium     = mediumName ?
                   2297:                      (IONetworkMedium *) cloneDict->getObject(mediumName) : 0;
                   2298:         setMediumProperty(gIOCurrentMediumKey, medium, &_currentMedium, true);
                   2299:         
                   2300:         mediumName = (OSSymbol *) getProperty(gIOActiveMediumKey);
                   2301:         medium     = mediumName ?
                   2302:                      (IONetworkMedium *) cloneDict->getObject(mediumName) : 0;
                   2303:         setMediumProperty(gIOActiveMediumKey, medium, &_activeMedium, true);
                   2304: 
                   2305:         ret = true;
                   2306:     }
                   2307: 
                   2308:     MEDIUM_UNLOCK;
                   2309: 
                   2310:     // Retained by the property table. drop our retain count.
                   2311:     //
                   2312:     cloneDict->release();
                   2313: 
                   2314:     // Broadcast a medium change event.
                   2315:     //
                   2316:     broadcastEvent(kIONetworkEventMediumChange);
                   2317: 
                   2318:     return ret;
                   2319: }
                   2320: 
                   2321: //---------------------------------------------------------------------------
                   2322: // Call enablePacketFilters() through syncRequest(). See enablePacketFilters().
                   2323: 
                   2324: IOReturn IONetworkController::doEnablePacketFilters(IOService * client,
                   2325:                                                     UInt32      newFilters,
                   2326:                                                     UInt32 *    activeFiltersP)
                   2327: {
                   2328:     IOReturn  ret = kIOReturnNotReady;
                   2329:     UInt32    dummy;
                   2330:     UInt32 *  activeP = activeFiltersP ? activeFiltersP : &dummy;
                   2331: 
                   2332:     *activeP = 0;
                   2333: 
                   2334:     if (SYNC_REQ(client, &IONetworkController::enablePacketFilters,
                   2335:                  &ret,
                   2336:                  (void *) newFilters, (void *) activeP) == kIOReturnSuccess)
                   2337:     {
                   2338:         // Update the registry.
                   2339:         //
                   2340:         setProperty(kIOActivePacketFilters, *activeP, 32);
                   2341:     }
                   2342: 
                   2343:     return ret;
                   2344: }
                   2345: 
                   2346: //---------------------------------------------------------------------------
                   2347: // Calls getPacketFilters() through syncRequest(). See getPacketFilters().
                   2348: 
                   2349: IOReturn IONetworkController::doGetPacketFilters(IOService * client,
                   2350:                                                  UInt32 *    filtersP)
                   2351: {
                   2352:     DO_SYNC_REQ(getPacketFilters, (void *) filtersP)
                   2353: }
                   2354: 
                   2355: //---------------------------------------------------------------------------
                   2356: // Call enable(IOService *) through syncRequest(). See enable().
                   2357: 
                   2358: IOReturn IONetworkController:: doEnable(IOService * client)
                   2359: {
                   2360:     DO_SYNC_REQ(_enable, (void *) client)
                   2361: }
                   2362: 
                   2363: //---------------------------------------------------------------------------
                   2364: // Call disable(IOService *) through syncRequest(). See disable().
                   2365: 
                   2366: IOReturn IONetworkController:: doDisable(IOService * client)
                   2367: {
                   2368:     DO_SYNC_REQ(_disable, (void *) client)
                   2369: }
                   2370: 
                   2371: //---------------------------------------------------------------------------
                   2372: // Call getControllerIndex() through syncRequest(). See getControllerIndex().
                   2373: 
                   2374: IOReturn IONetworkController::doGetControllerIndex(IOService * client,
                   2375:                                                    UInt32 *    index)
                   2376: {
                   2377:     DO_SYNC_REQ(getControllerIndex, (void *) index)
                   2378: }
                   2379: 
                   2380: //---------------------------------------------------------------------------
                   2381: // Call setMaxTransferUnit() through syncRequest(). See setMaxTransferUnit().
                   2382: 
                   2383: IOReturn IONetworkController::doSetMaxTransferUnit(IOService * client,
                   2384:                                                    UInt32      mtu)
                   2385: {
                   2386:     DO_SYNC_REQ(setMaxTransferUnit, (void *) mtu)
                   2387: }
                   2388: 
                   2389: //---------------------------------------------------------------------------
                   2390: // Call selectMedium() through syncRequest(). See selectMedium().
                   2391: 
                   2392: IOReturn IONetworkController::doSelectMedium(IOService *      client,
                   2393:                                              const OSSymbol * mediumName)
                   2394: {
                   2395:     DO_SYNC_REQ(selectMediumWithName, (void *) mediumName)
                   2396: }
                   2397: 
                   2398: //---------------------------------------------------------------------------
                   2399: // Call setOutputQueueCapacity() through syncRequest().
                   2400: // See setOutputQueueCapacity().
                   2401: 
                   2402: IOReturn IONetworkController::doSetOutputQueueCapacity(IOService * client,
                   2403:                                                        UInt32      capacity)
                   2404: {
                   2405:     DO_SYNC_REQ(setOutputQueueCapacity, (void *) capacity)
                   2406: }
                   2407: 
                   2408: //---------------------------------------------------------------------------
                   2409: // Call getOutputQueueCapacity() through syncRequest().
                   2410: // See getOutputQueueCapacity().
                   2411: 
                   2412: IOReturn
                   2413: IONetworkController::doGetOutputQueueCapacity(IOService * client,
                   2414:                                               UInt32 *    capacityP)
                   2415: {
                   2416:     DO_SYNC_REQ(getOutputQueueCapacity, (void *) capacityP)
                   2417: }
                   2418: 
                   2419: //---------------------------------------------------------------------------
                   2420: // Call getOutputQueueSize() through syncRequest().
                   2421: // See getOutputQueueSize().
                   2422: 
                   2423: IOReturn
                   2424: IONetworkController::doGetOutputQueueSize(IOService * client,
                   2425:                                           UInt32 *    sizeP)
                   2426: {
                   2427:     DO_SYNC_REQ(getOutputQueueSize, (void *) sizeP)
                   2428: }
                   2429: 
                   2430: //---------------------------------------------------------------------------
                   2431: // Call flushOutputQueue() through syncRequest(). See flushOutputQueue().
                   2432: 
                   2433: IOReturn
                   2434: IONetworkController::doFlushOutputQueue(IOService * client,
                   2435:                                         UInt32 *    flushCountP)
                   2436: {
                   2437:     DO_SYNC_REQ(flushOutputQueue, (void *) flushCountP)
                   2438: }
                   2439: 
                   2440: //---------------------------------------------------------------------------
                   2441: // Call performDiagnostics() through syncRequest().
                   2442: // See performDiagnostics().
                   2443: 
                   2444: IOReturn
                   2445: IONetworkController::doPerformDiagnostics(IOService * client,
                   2446:                                           UInt32 *    failureCode)
                   2447: {
                   2448:     DO_SYNC_REQ(performDiagnostics, (void *) failureCode)
                   2449: }

unix.superglobalmegacorp.com

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