+
+ // Allocate our ExpansionData if it hasn't been allocated already.
+ if ( !reserved )
+ {
+ reserved = IONew(ExpansionData,1);
+ if ( !reserved )
+ return false;
+
+ bzero(reserved,sizeof(ExpansionData));
+ }
+
+#if DEBUG
+ OSBacktrace ( reserved->allocationBacktrace, sizeof ( reserved->allocationBacktrace ) / sizeof ( reserved->allocationBacktrace[0] ) );
+#endif
+
+ if ( gateLock == NULL ) {
+ if ( !( gateLock = IORecursiveLockAlloc()) )
+ return false;
+ }
+
+ if ( workToDoLock == NULL ) {
+ if ( !(workToDoLock = IOSimpleLockAlloc()) )
+ return false;
+ IOSimpleLockInit(workToDoLock);
+ workToDo = false;
+ }
+
+ IOStatisticsRegisterCounter();
+
+ if ( controlG == NULL ) {
+ controlG = IOCommandGate::commandGate(
+ this,
+ OSMemberFunctionCast(
+ IOCommandGate::Action,
+ this,
+ &IOWorkLoop::_maintRequest));
+
+ if ( !controlG )
+ return false;
+ // Point the controlGate at the workLoop. Usually addEventSource
+ // does this automatically. The problem is in this case addEventSource
+ // uses the control gate and it has to be bootstrapped.
+ controlG->setWorkLoop(this);
+ if (addEventSource(controlG) != kIOReturnSuccess)
+ return false;
+ }
+
+ if ( workThread == NULL ) {
+ thread_continue_t cptr = OSMemberFunctionCast(
+ thread_continue_t,
+ this,
+ &IOWorkLoop::threadMain);
+ if (KERN_SUCCESS != kernel_thread_start(cptr, this, &workThread))
+ return false;
+ }