1/*
2 * Copyright (c) 1998-2008 Apple 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 * IOKernelDebugger.cpp
24 *
25 * HISTORY
26 */
27
28#include <IOKit/assert.h>
29#include <IOKit/IOLib.h>
30#include <IOKit/IOMessage.h>
31#include <IOKit/IOLocks.h>
32#include <IOKit/network/IONetworkController.h>
33#include <IOKit/network/IOKernelDebugger.h>
34#include <IOKit/IOBSD.h> //for kIOBSDNameKey
35#include <libkern/OSAtomic.h>
36#include "IONetworkControllerPrivate.h"
37
38#define kIOPrimaryDebugPortKey      "IOPrimaryDebugPort"
39
40#define kMatchNameArg				"kdp_match_name"
41#define kMatchMacArg				"kdp_match_mac"
42
43//---------------------------------------------------------------------------
44// IOKDP
45
46class IOKDP : public IOService
47{
48    OSDeclareDefaultStructors( IOKDP )
49
50public:
51	/*! @function probe
52	@abstract verify controller meets criteria for debugger
53	@discussion This checks that the controller that is attaching the debugger
54	meets the criteria set by the user on the kernel command line. Current boot-args
55	are kdp_match_mac=001122334455 to match against a specific MAC address and
56	kdp_match_name=bsdname to match against interfaces with the specified BSD interface
57	name (for example, en1)
58	*/
59
60	virtual IOService *probe(IOService *provider, SInt32 *score);
61
62    virtual bool start( IOService * provider );
63
64    virtual void stop( IOService * provider );
65
66    virtual IOReturn message( UInt32       type,
67                              IOService *  provider,
68                              void *       argument = 0 );
69};
70
71//---------------------------------------------------------------------------
72// IOKDP defined globals.
73
74static IOLock * gIOKDPLock    = 0;
75static IOKDP *  gIOKDP        = 0;
76static UInt32   gDebugBootArg = 0;
77
78class IOKDPGlobals
79{
80public:
81    IOKDPGlobals();
82    ~IOKDPGlobals();
83
84    inline bool isValid() const;
85};
86
87static IOKDPGlobals gIOKDPGlobals;
88
89IOKDPGlobals::IOKDPGlobals()
90{
91    gIOKDPLock = IOLockAlloc();
92
93    PE_parse_boot_argn( "debug", &gDebugBootArg, sizeof (gDebugBootArg) );
94}
95
96IOKDPGlobals::~IOKDPGlobals()
97{
98    if ( gIOKDPLock )
99    {
100        IOLockFree( gIOKDPLock );
101        gIOKDPLock = 0;
102    }
103}
104
105bool IOKDPGlobals::isValid() const
106{
107    return ( gIOKDPLock );
108}
109
110#define super IOService
111OSDefineMetaClassAndStructors( IOKDP, IOService )
112
113//---------------------------------------------------------------------------
114// start/stop/message.
115IOService *IOKDP::probe(IOService *provider, SInt32 *score)
116{
117	char textBuffer[32];
118
119	// we expect our provider is an IOKernelDebugger and that its provider is an IONetworkController.
120	// If the controller has an IONetworkInterface client (it should) we can use info in it to
121	// determine if this is the best match for a debugger.
122	IONetworkInterface *interface = 0;
123	OSObject *client;
124	IOService *controller = provider->getProvider();
125
126//	IOLog("_kdp_ probing...\n");
127	if (controller)
128	{
129		OSIterator *clients = controller->getClientIterator();
130		//try to find a network interface on the provider
131		while ((client = clients->getNextObject()))
132		{
133			if ((interface = OSDynamicCast(IONetworkInterface, client)))
134				break;
135		}
136		clients->release();
137
138	}
139
140	do
141	{
142		if(PE_parse_boot_argn( kMatchNameArg, textBuffer, sizeof(textBuffer)))
143		{
144			if(!interface) //user wants name match but we're not on a controller with an interface
145			{
146				//IOLog("_kdp_ no interface\n");
147				return 0;
148			}
149			OSString *bsdname = OSDynamicCast(OSString, interface->getProperty(kIOBSDNameKey));
150			if(!bsdname)
151			{
152				//IOLog("_kdp_ no bsd property\n");
153				return 0;
154			}
155			if(bsdname->isEqualTo(textBuffer) == false)
156			{
157				//IOLog("_kdp_ name doesn't match %s\n", textBuffer);
158				return 0;
159			}
160			break;
161		}
162
163		if(PE_parse_boot_argn( kMatchMacArg, textBuffer, sizeof(textBuffer)))
164		{
165			char ctrMac[13];
166			if(!controller) //looking for mac match, but the debugger isn't on a controller (!?)
167			{
168				//IOLog("_kdp_ no controller\n");
169				return 0;
170			}
171			OSData * macAddr = OSDynamicCast(OSData, controller->getProperty(kIOMACAddress));
172			if ( (macAddr == 0) || (macAddr->getLength() != 6) )
173			{
174				//IOLog("_kdp_ bad mac\n");
175				return 0;
176			}
177
178			//make sure command line mac is in upper case
179			for(int i=0; i<12; i++)
180				textBuffer[i] = textBuffer[i] >= 'a' && textBuffer[i] <= 'z' ? textBuffer[i] - 32 : textBuffer[i];
181
182			// now convert the controller mac property to a string
183			unsigned char *macData = (unsigned char *)macAddr->getBytesNoCopy();
184			snprintf(ctrMac, sizeof(ctrMac), "%02X%02X%02X%02X%02X%02X", macData[0], macData[1], macData[2], macData[3], macData[4], macData[5]);
185
186			//now see if they match...
187			if(strncmp(ctrMac, textBuffer, 12))
188			{
189				//IOLog("_kdp_ mac doesn't match %s\n", textBuffer);
190				return 0;
191			}
192			break;
193		}
194
195		//else default to old plist metric: the IOKernelDebugger has IOPrimaryDebugPort property
196		OSBoolean *pdp = OSDynamicCast(OSBoolean, provider->getProperty(kIOPrimaryDebugPortKey));
197		if(!pdp || pdp->isFalse())
198		{
199			//IOLog("_kdp_ not primary debug port\n");
200			return 0;
201		}
202		break;
203	}while(false);
204
205	//IOLog("_kdp_ MATCHED!\n");
206
207	//make sure the super is ok with this.
208	IOService *ret = super::probe(provider, score);
209	return ret;
210}
211
212bool IOKDP::start( IOService * provider )
213{
214    bool ret = false;
215
216    if ( super::start(provider) == false )
217        return false;
218
219    if ( gIOKDPGlobals.isValid() == false )
220        return false;
221
222    IOLockLock( gIOKDPLock );
223
224    do {
225        if ( gIOKDP )
226            break;
227
228        if ( provider->open(this) == false )
229            break;
230
231        gIOKDP = this;
232        ret    = true;
233    }
234    while ( false );
235
236    IOLockUnlock( gIOKDPLock );
237
238    if ( ret ) registerService();
239
240    return ret;
241}
242
243void IOKDP::stop( IOService * provider )
244{
245    provider->close(this);
246
247    IOLockLock( gIOKDPLock );
248
249    if ( gIOKDP == this ) gIOKDP = 0;
250
251    IOLockUnlock( gIOKDPLock );
252
253    super::stop(provider);
254}
255
256IOReturn IOKDP::message( UInt32       type,
257                         IOService *  provider,
258                         void *       argument )
259{
260    if ( type == kIOMessageServiceIsTerminated )
261    {
262        provider->close(this);
263    }
264    return kIOReturnSuccess;
265}
266
267
268//---------------------------------------------------------------------------
269// IOKernelDebugger
270
271extern "C" {
272//
273// Defined in osfmk/kdp/kdp_en_debugger.h, but the header file is not
274// exported, thus the definition is replicated here.
275//
276typedef void (*kdp_send_t)( void * pkt, UInt pkt_len );
277typedef void (*kdp_receive_t)( void * pkt, UInt * pkt_len, UInt timeout );
278typedef UInt32  (*kdp_link_t)(void);
279typedef boolean_t (*kdp_mode_t)(boolean_t active);
280void kdp_register_send_receive( kdp_send_t send, kdp_receive_t receive );
281void kdp_unregister_send_receive( kdp_send_t send, kdp_receive_t receive );
282void kdp_register_link( kdp_link_t link, kdp_mode_t mode );
283void kdp_unregister_link( kdp_link_t link, kdp_mode_t mode );
284void kdp_set_interface(void *, const void *);
285}
286
287#undef  super
288#define super IOService
289OSDefineMetaClassAndStructors( IOKernelDebugger, IOService )
290OSMetaClassDefineReservedUnused( IOKernelDebugger, 0 );
291OSMetaClassDefineReservedUnused( IOKernelDebugger, 1 );
292OSMetaClassDefineReservedUnused( IOKernelDebugger, 2 );
293OSMetaClassDefineReservedUnused( IOKernelDebugger, 3 );
294
295// IOKernelDebugger global variables.
296//
297IOService *             gIODebuggerDevice                = 0;
298IODebuggerTxHandler     gIODebuggerTxHandler             = 0;
299IODebuggerRxHandler     gIODebuggerRxHandler             = 0;
300IODebuggerLinkStatusHandler gIODebuggerLinkStatusHandler = 0;
301IODebuggerSetModeHandler gIODebuggerSetModeHandler       = 0;
302UInt32                  gIODebuggerTxBytes               = 0;
303UInt32                  gIODebuggerRxBytes               = 0;
304SInt32                  gIODebuggerSemaphore             = 0;
305UInt32                  gIODebuggerFlag                  = 0;
306UInt8                   gIODebuggerSignalled             = 0;
307
308// Global debugger flags.
309//
310enum {
311    kIODebuggerFlagRegistered       = 0x01,
312    kIODebuggerFlagWarnNullHandler  = 0x02
313};
314
315// Expansion variables.
316//
317#define _state                      _reserved->stateVars[0]
318#define _activationChangeThreadCall _reserved->activationChangeThreadCall
319#define _interfaceNotifier	    _reserved->interfaceNotifier
320#define _linkStatusHandler          _reserved->linkStatusHandler
321#define _setModeHandler             _reserved->setModeHandler
322#define EARLY_DEBUG_SUPPORT         (gDebugBootArg != 0)
323
324static void handleActivationChange( IOKernelDebugger * debugger,
325                                    void *             change );
326
327bool IOKernelDebugger::interfacePublished(
328    void * target, void *param, IOService * service, IONotifier * notifier )
329{
330	IOService *debugger = (IOService *)target;
331    IONetworkInterface *interface = OSDynamicCast(IONetworkInterface, service);
332
333	//IOLog("new (or changes on) interface detected\n");
334	//only reregister ourselves if the interface has the same controller (provider) as we do.
335	if(debugger && service && debugger->getProvider() == service->getProvider())
336	{
337		//IOLog("it's on our controller- reregister\n");
338		debugger->registerService();
339        if (interface)
340            interface->debuggerRegistered();
341	}
342	return true;
343}
344
345//---------------------------------------------------------------------------
346// The KDP receive dispatch function. Dispatches KDP receive requests to the
347// registered receive handler. This function is registered with KDP via
348// kdp_register_send_receive().
349
350void IOKernelDebugger::kdpReceiveDispatcher( void *   buffer,
351                                             UInt32 * length,
352                                             UInt32   timeout )
353{
354    *length = 0;    // return a zero length field by default.
355
356    if ( gIODebuggerSemaphore ) return;  // FIXME - Driver is busy!
357
358    (*gIODebuggerRxHandler)( gIODebuggerDevice, buffer, length, timeout );
359
360    gIODebuggerRxBytes += *length;
361}
362
363//---------------------------------------------------------------------------
364// The KDP transmit dispatch function. Dispatches KDP transmit requests to the
365// registered transmit handler. This function is registered with KDP via
366// kdp_register_send_receive().
367
368void IOKernelDebugger::kdpTransmitDispatcher( void * buffer, UInt32 length )
369{
370    if ( gIODebuggerSemaphore ) return;  // FIXME - Driver is busy!
371
372    (*gIODebuggerTxHandler)( gIODebuggerDevice, buffer, length );
373
374    gIODebuggerTxBytes += length;
375}
376
377//---------------------------------------------------------------------------
378// The KDP link up dispatch function. Dispatches KDP link up queries to the
379// registered link up handler. This function is registered with KDP via
380// kdp_register_link().
381
382UInt32 IOKernelDebugger::kdpLinkStatusDispatcher( void )
383{
384    if ( gIODebuggerSemaphore )
385        return 0;  // FIXME - Driver is busy!
386
387    return (*gIODebuggerLinkStatusHandler)( gIODebuggerDevice);
388}
389
390
391//---------------------------------------------------------------------------
392// The KDP set mode dispatch function. Dispatches KDP set mode commands to the
393// registered setMode handler. This function is registered with KDP via
394// kdp_register_link().
395
396boolean_t IOKernelDebugger::kdpSetModeDispatcher(boolean_t active)
397{
398   if ( gIODebuggerSemaphore )
399        return FALSE;  // FIXME - Driver is busy!
400
401   if ((*gIODebuggerSetModeHandler)( gIODebuggerDevice, active == TRUE ? true : false) == true)
402        return TRUE;
403
404   return FALSE;
405}
406
407
408//---------------------------------------------------------------------------
409// Null debugger handlers.
410
411void IOKernelDebugger::nullTxHandler( IOService * target,
412                                      void *      buffer,
413                                      UInt32      length )
414{
415}
416
417void IOKernelDebugger::nullRxHandler( IOService * target,
418                                      void *      buffer,
419                                      UInt32 *    length,
420                                      UInt32      timeout )
421{
422    if ( gIODebuggerFlag & kIODebuggerFlagWarnNullHandler )
423    {
424        IOLog("IOKernelDebugger::%s no debugger device\n", __FUNCTION__);
425        gIODebuggerFlag &= ~kIODebuggerFlagWarnNullHandler;
426    }
427}
428
429UInt32 IOKernelDebugger::nullLinkStatusHandler(__unused IOService * target)
430{
431    return kIONetworkLinkValid | kIONetworkLinkActive; /* default is link up. */
432}
433
434bool IOKernelDebugger::nullSetModeHandler(__unused IOService * target,
435                                          __unused bool active)
436{
437    return true;
438}
439
440
441
442//---------------------------------------------------------------------------
443// Take the debugger lock conditionally.
444
445IODebuggerLockState IOKernelDebugger::lock( IOService * object )
446{
447    if ( gIODebuggerDevice == object )
448    {
449        OSIncrementAtomic( &gIODebuggerSemaphore );
450        return kIODebuggerLockTaken;
451    }
452    return (IODebuggerLockState) 0;
453}
454
455inline static void invokeDebugger(void)
456{
457    if ( gIODebuggerSemaphore )
458            return;
459
460    if (OSTestAndClear(0, &gIODebuggerSignalled) == false) {
461        Debugger("remote NMI");
462    }
463}
464
465//---------------------------------------------------------------------------
466// Release the debugger lock if the kIODebuggerLockTaken flag is set.
467
468void IOKernelDebugger::unlock( IODebuggerLockState state )
469{
470    if ( state & kIODebuggerLockTaken ) {
471        OSDecrementAtomic( &gIODebuggerSemaphore );
472
473        invokeDebugger();
474    }
475}
476
477//---------------------------------------------------------------------------
478// drop into the Debugger when safe
479void IOKernelDebugger::signalDebugger(void)
480{
481    OSTestAndSet(0, &gIODebuggerSignalled);
482    invokeDebugger();
483}
484
485//---------------------------------------------------------------------------
486// Initialize an IOKernelDebugger instance.
487
488bool IOKernelDebugger::init( IOService *                 target,
489                             IODebuggerTxHandler         txHandler,
490                             IODebuggerRxHandler         rxHandler,
491                             IODebuggerLinkStatusHandler linkStatusHandler,
492                             IODebuggerSetModeHandler    setModeHandler)
493{
494    if ( ( super::init() == false )                ||
495         ( OSDynamicCast(IOService, target) == 0 ) ||
496         ( txHandler == 0 )                        ||
497         ( rxHandler == 0 ) )
498    {
499        return false;
500    }
501
502    // Allocate memory for the ExpansionData structure.
503
504    _reserved = IONew( ExpansionData, 1 );
505    if ( _reserved == 0 )
506    {
507        return false;
508    }
509
510    _activationChangeThreadCall = thread_call_allocate(
511                                (thread_call_func_t)  handleActivationChange,
512                                (thread_call_param_t) this );
513
514	// if user wants bsd name matching, odds are good that the interface won't
515	// have been named at the time IOKDP is matching on us...fortunately IONetworkStack
516	// reregisters the interface service when it gets named, so we can add a notifier
517	// and reregister ourselves at that time in order to try matching IOKDP again.
518	char textBuffer[64];
519	if (PE_parse_boot_argn( kMatchNameArg, textBuffer, sizeof(textBuffer)))
520	{
521        OSDictionary * matching = serviceMatching(kIONetworkInterfaceClass);
522        if (matching)
523        {
524            _interfaceNotifier = addMatchingNotification(
525									   /* type   */    gIOPublishNotification,
526									   /* match  */    matching,
527									   /* action */    interfacePublished,
528									   /* param  */    this );
529            matching->release();
530        }
531    }
532	else _interfaceNotifier = 0;
533
534    if ( !_activationChangeThreadCall )
535    {
536        return false;
537    }
538
539    // Cache the target and handlers provided.
540
541    _target            = target;
542    _txHandler         = txHandler;
543    _rxHandler         = rxHandler;
544    _linkStatusHandler = linkStatusHandler;
545    _setModeHandler    = setModeHandler;
546    _state      = 0;
547
548    return true;
549}
550
551//---------------------------------------------------------------------------
552// Factory method which performs allocation and initialization of an
553// IOKernelDebugger instance.
554
555IOKernelDebugger * IOKernelDebugger::debugger( IOService *                 target,
556                                               IODebuggerTxHandler         txHandler,
557                                               IODebuggerRxHandler         rxHandler,
558                                               IODebuggerLinkStatusHandler linkStatusHandler,
559                                               IODebuggerSetModeHandler    setModeHandler)
560{
561    IOKernelDebugger * debugger = new IOKernelDebugger;
562
563    if (debugger && (debugger->init( target, txHandler, rxHandler, linkStatusHandler, setModeHandler ) == false))
564    {
565        debugger->release();
566        return 0;
567    }
568
569	// determine if this debugger is the "primary" debugger- the one KDP will attach to unless told otherwise
570    IOService * device = target->getProvider(); //get info from our provider's provider
571    //the debugger is primary if...
572	if ( device && device->getProperty( "built-in" )) // ...it is a built in controller...
573	{
574		OSObject *locationProperty = device->copyProperty("location");
575		OSData *locationAsData = OSDynamicCast(OSData, locationProperty);
576		if(!locationAsData || // ...AND we don't know anything else about its location.....
577		   (strcmp( (char *)locationAsData->getBytesNoCopy(), "1")== 0) ) // ...OR we do know its location and it is 'slot' 1
578			debugger->setProperty( kIOPrimaryDebugPortKey, true );
579		else
580			debugger->setProperty( kIOPrimaryDebugPortKey, false );
581		if(locationProperty)
582			locationProperty->release();
583	}
584    return debugger;
585}
586
587//---------------------------------------------------------------------------
588// Register the debugger handlers.
589
590void IOKernelDebugger::registerHandler( IOService *                 target,
591                                        IODebuggerTxHandler         txHandler,
592                                        IODebuggerRxHandler         rxHandler,
593                                        IODebuggerLinkStatusHandler linkStatusHandler,
594                                        IODebuggerSetModeHandler    setModeHandler)
595{
596    bool doRegister;
597
598    assert( ( target == gIODebuggerDevice ) ||
599            ( target == 0 )                 ||
600            ( gIODebuggerDevice == 0 ) );
601
602    doRegister = ( target && ( txHandler != 0 ) && ( rxHandler != 0 ) );
603
604    if ( !doRegister && ( gIODebuggerFlag & kIODebuggerFlagRegistered ) )
605    {
606        // Unregister the polling functions from KDP.
607        kdp_unregister_send_receive( (kdp_send_t) kdpTransmitDispatcher,
608                                     (kdp_receive_t) kdpReceiveDispatcher);
609        kdp_unregister_link( (kdp_link_t) kdpLinkStatusDispatcher, (kdp_mode_t) kdpSetModeDispatcher);
610
611        gIODebuggerFlag &= ~kIODebuggerFlagRegistered;
612    }
613
614    if ( txHandler == 0 ) txHandler = &IOKernelDebugger::nullTxHandler;
615    if ( rxHandler == 0 ) rxHandler = &IOKernelDebugger::nullRxHandler;
616    if ( linkStatusHandler == 0 ) linkStatusHandler = &IOKernelDebugger::nullLinkStatusHandler;
617    if ( setModeHandler == 0 ) setModeHandler = &IOKernelDebugger::nullSetModeHandler;
618
619    OSIncrementAtomic( &gIODebuggerSemaphore );
620
621    gIODebuggerDevice            = target;
622    gIODebuggerTxHandler         = txHandler;
623    gIODebuggerRxHandler         = rxHandler;
624    gIODebuggerLinkStatusHandler = linkStatusHandler;
625    gIODebuggerSetModeHandler    = setModeHandler;
626    gIODebuggerFlag     |= kIODebuggerFlagWarnNullHandler;
627
628    OSDecrementAtomic( &gIODebuggerSemaphore );
629
630    if ( doRegister && (( gIODebuggerFlag & kIODebuggerFlagRegistered ) == 0) )
631    {
632        // if we're on a controller that has an interfacet(we should be), we can register
633		// the IONetworkInterface * as an identifier so that the bsd portion
634		// knows when to assign an ip to kdp
635		IONetworkInterface *interface = 0;
636		OSIterator *clients = target->getClientIterator();
637		//try to find a network interface on the target
638		while (OSObject *client = clients->getNextObject())
639		{
640			if ((interface = OSDynamicCast(IONetworkInterface, client)))
641				break;
642		}
643		clients->release();
644
645                if (interface) {
646                    OSData *mac = OSDynamicCast(OSData,
647                                                interface->getController()->getProperty(kIOMACAddress));
648
649                    kdp_set_interface(interface, mac ? mac->getBytesNoCopy() : NULL);
650                    interface->debuggerRegistered();
651                }
652
653        // Register dispatch function, these in turn will call the
654        // handlers when the debugger is active.
655        //
656        // Note: The following call may trigger an immediate break
657        //       to the debugger.
658        kdp_register_link((kdp_link_t) kdpLinkStatusDispatcher, (kdp_mode_t) kdpSetModeDispatcher);
659        kdp_register_send_receive( (kdp_send_t) kdpTransmitDispatcher,
660                                   (kdp_receive_t) kdpReceiveDispatcher);
661
662        // Limit ourself to a single real KDP registration.
663
664        gIODebuggerFlag |= kIODebuggerFlagRegistered;
665
666        publishResource("kdp");
667    }
668}
669
670//---------------------------------------------------------------------------
671// enableTarget / disableTarget
672
673enum {
674    kEventClientOpen     = 0x0001,
675    kEventTargetUsable   = 0x0002,
676    kEventDebuggerActive = 0x0004,
677    kTargetIsEnabled     = 0x0100,
678    kTargetWasEnabled    = 0x0200,
679};
680
681static void enableTarget( IOKernelDebugger * self,
682                          IOService *        target,
683                          UInt32 *           state,
684                          UInt32             event )
685{
686    IONetworkController * ctr = OSDynamicCast( IONetworkController, target );
687
688    #define kReadyMask ( kEventClientOpen     | \
689                         kEventTargetUsable   | \
690                         kEventDebuggerActive )
691
692    *state |= event;
693    *state &= ~kTargetWasEnabled;
694
695    if ( ( *state & kReadyMask ) == kReadyMask )
696    {
697        if ( !ctr || ( *state & kTargetIsEnabled ) ||
698             ctr->doEnable( self ) == kIOReturnSuccess )
699        {
700            if ( ( *state & kTargetIsEnabled ) == 0 )
701                *state |= kTargetWasEnabled;
702            *state |= kTargetIsEnabled;
703        }
704    }
705}
706
707static void disableTarget( IOKernelDebugger * self,
708                           IOService *        target,
709                           UInt32 *           state,
710                           UInt32             event )
711{
712    IONetworkController * ctr = OSDynamicCast( IONetworkController, target );
713    UInt32                on  = *state & kTargetIsEnabled;
714
715    *state &= ~( event | kTargetIsEnabled | kTargetWasEnabled );
716
717    if ( ctr && on ) ctr->doDisable( self );
718}
719
720//---------------------------------------------------------------------------
721// Called by open() with the arbitration lock held.
722
723bool IOKernelDebugger::handleOpen( IOService *    forClient,
724                                   IOOptionBits   options,
725                                   void *         arg )
726{
727    bool ret = false;
728
729    do {
730        // Only a single client at a time.
731
732        if ( _client || !_target ) break;
733
734        // Register the target to prime the lock()/unlock() functionality
735        // before opening the target.
736
737        registerHandler( _target );
738
739        // While the target is opened/enabled, it must block any thread
740        // which may acquire the debugger lock in its execution path.
741
742        if ( _target->open( this ) == false )
743            break;
744
745        // For early debugging, the debugger must become active and enable
746        // the controller as early as possible. Otherwise, the debugger is
747        // not activated until the controller is enabled by BSD.
748
749        if ( EARLY_DEBUG_SUPPORT )
750            _state |= kEventDebuggerActive;
751
752        // Register interest in receiving notifications about controller
753        // power state changes. The controller is usable if it is power
754        // managed, and is in an usable state, or if the controller is
755        // not power managed.
756
757        if ( _target->registerInterestedDriver(this) &
758             ( kIOPMDeviceUsable | kIOPMNotPowerManaged ) )
759            _state |= kEventTargetUsable;
760
761        // Enable the target if possible.
762
763        enableTarget( this, _target, &_state, kEventClientOpen );
764        if ( _state & kTargetWasEnabled )
765        {
766            // If the target was enabled, complete the registration.
767            IOLog("%s: registering debugger\n", getName());
768            registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler );
769        }
770
771        // Remember the client.
772
773        _client = forClient;
774
775        ret = true;
776    }
777    while (0);
778
779    if ( ret == false )
780    {
781        registerHandler( 0 );
782        _target->close( this );
783    }
784
785    return ret;
786}
787
788//---------------------------------------------------------------------------
789// Called by IOService::close() with the arbitration lock held.
790
791void IOKernelDebugger::handleClose( IOService *   forClient,
792                                    IOOptionBits  options )
793{
794    if ( _target && _client && ( _client == forClient ) )
795    {
796        // There is no KDP un-registration. The best we can do is to
797        // register dummy handlers.
798
799        registerHandler( 0 );
800
801        disableTarget( this, _target, &_state, kEventClientOpen );
802
803        // Before closing the controller, remove interest in receiving
804        // notifications about controller power state changes.
805
806        _target->deRegisterInterestedDriver( this );
807
808        _client = 0;
809
810        _target->close( this );
811    }
812}
813
814//---------------------------------------------------------------------------
815// Called by IOService::isOpen() with the arbitration lock held.
816
817bool IOKernelDebugger::handleIsOpen( const IOService * forClient ) const
818{
819    if ( forClient == 0 )
820        return ( forClient != _client );
821    else
822        return ( forClient == _client );
823}
824
825//---------------------------------------------------------------------------
826// Free the IOKernelDebugger object.
827
828void IOKernelDebugger::free()
829{
830    if ( _reserved )
831    {
832        if ( _activationChangeThreadCall )
833            thread_call_free( _activationChangeThreadCall );
834
835		if ( _interfaceNotifier )
836			_interfaceNotifier->remove();
837
838        IODelete( _reserved, ExpansionData, 1 );
839        _reserved = 0;
840    }
841
842    super::free();
843}
844
845//---------------------------------------------------------------------------
846// Handle controller's power state change notitifications.
847
848IOReturn
849IOKernelDebugger::powerStateWillChangeTo( IOPMPowerFlags  flags,
850                                          unsigned long   stateNumber,
851                                          IOService *     policyMaker )
852{
853    if ((flags & IOPMDeviceUsable) == 0)
854    {
855        // Controller is about to transition to an un-usable state.
856        // The debugger nub should be disabled.
857
858        lockForArbitration();
859
860        // Keep an open on the controller, but inhibit access to the
861        // controller's debugger handlers, and disable controller's
862        // hardware support for the debugger.
863
864        if ( _client ) registerHandler( 0 );
865        disableTarget( this, _target, &_state, kEventTargetUsable );
866
867        unlockForArbitration();
868    }
869
870    return IOPMAckImplied;
871}
872
873IOReturn
874IOKernelDebugger::powerStateDidChangeTo( IOPMPowerFlags  flags,
875                                         unsigned long   stateNumber,
876                                         IOService *     policyMaker )
877{
878    if ( flags & IOPMDeviceUsable )
879    {
880        // Controller has transitioned to an usable state.
881        // The debugger nub should be enabled if necessary.
882
883        lockForArbitration();
884
885        enableTarget( this, _target, &_state, kEventTargetUsable );
886        if ( _state & kTargetWasEnabled )
887            registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler );
888
889        unlockForArbitration();
890    }
891
892    return IOPMAckImplied;
893}
894
895//---------------------------------------------------------------------------
896// handleActivationChange
897
898static void
899handleActivationChange( IOKernelDebugger * debugger, void * change )
900{
901    debugger->message( kMessageDebuggerActivationChange, 0, change );
902    debugger->release();
903}
904
905//---------------------------------------------------------------------------
906// message()
907
908IOReturn IOKernelDebugger::message( UInt32 type, IOService * provider,
909                                    void * argument )
910{
911    IOReturn ret = kIOReturnSuccess;
912
913	switch ( type )
914    {
915        case kMessageControllerWasEnabledForBSD:
916        case kMessageControllerWasDisabledForBSD:
917            // For early debugging support, these messages are ignored.
918            // The debugger will enable the controller independently
919            // from BSD.
920
921            if ( EARLY_DEBUG_SUPPORT ) break;
922
923            // Process this change in another thread to avoid deadlocks
924            // between the controller's work loop, and our arbitration
925            // lock.
926
927            retain();
928            if ( thread_call_enter1( _activationChangeThreadCall,
929                                     (void *)(uintptr_t) type ) == TRUE )
930                release();
931
932            break;
933
934        case kMessageControllerWillShutdown:
935            // Disable controller before system shutdown and restart.
936            // Intentional fall-through to next case.
937
938        case kMessageDebuggerActivationChange:
939            lockForArbitration();
940
941            // If controller was enabled, activate the debugger.
942            // Otherwise make the debugger inactive.
943
944            if ( (void *) kMessageControllerWasEnabledForBSD == argument )
945            {
946                enableTarget( this, _target, &_state, kEventDebuggerActive );
947                if ( _state & kTargetWasEnabled )
948                    registerHandler( _target, _txHandler, _rxHandler, _linkStatusHandler, _setModeHandler );
949            }
950            else
951            {
952                if ( _client ) registerHandler( 0 );
953                disableTarget( this, _target, &_state, kEventDebuggerActive );
954            }
955
956            unlockForArbitration();
957            break;
958
959        default:
960            ret = super::message( type, provider, argument );
961    }
962
963    return ret;
964}
965