<!--
{
  "availability" : [
    "DriverKit: -"
  ],
  "documentType" : "symbol",
  "framework" : "SCSIControllerDriverKit",
  "identifier" : "/documentation/SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController/UserInitializeController",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "SCSIControllerDriverKit"
    ],
    "preciseIdentifier" : "c:@S@IOUserSCSIParallelInterfaceController@F@UserInitializeController#"
  },
  "title" : "UserInitializeController"
}
-->

# UserInitializeController

Initializes the controller in response to a call from the framework.

```
virtual kern_return_t UserInitializeController();
```

## Return Value

A value that indicates the result of initialization. <doc://com.apple.documentation/documentation/DriverKit/kIOReturnSuccess> indicates success. For error definitions, see <doc://com.apple.documentation/documentation/iokit/iokit_constants>.

## Discussion

The first method in the dext that the framework calls is [`UserInitializeController`](/documentation/SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController/UserInitializeController), which it only calls once per instantiation. Use this method to perform all necessary initialization that the hardware requires before it can accept requests to execute. Make all necessary resource allocations during this method call.

### Queuing Considerations

For best results, use a model with three dispatch queues. DriverKit creates a default queue for you, and you’ll also need to create interrupt auxiliary queues. Because DriverKit dispatch queues are serial, this arrangement prevents calls from DriverKit, interrupts, and I/O work from competing with one another on the same thread.

The following example shows how to implement [`UserInitializeController`](/documentation/SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController/UserInitializeController) to set up the queues. After opening the PCI device session, it creates the auxiliary and interrupt queues, and then uses the interrupt queue to register for interrupts.

```objc
IMPL ( ExampleSCSIDext, UserInitializeController )
{
    kern_return_t    ret;
    
    // Perform any needed initialization here

    // Open a new PCI session.
    ret = ivars->fPCIDevice->Open ( this, 0 );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    // Create and set dispatch queues.
    ret = SetDispatchQueue ( "AuxiliaryQueue", ivars->fAuxQueue );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    ret = SetDispatchQueue ( "InterruptQueue", ivars->fIntQueue );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    // Register for interrupts.
    ret = IOInterruptDispatchSource::Create ( ivars->fPCIDevice,
                                             index,
                                             ivars->fIntQueue,
                                             &ivars->fIntSource );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    ret = CreateActionInterruptOccurred ( sizeof ( void  * ),
                                          &ivars->fInterruptCompletion );
    __Require ( ( kIOReturnSuccess == ret ), Exit );
    
    ret = ivars->fIntSource->SetHandler ( ivars->fInterruptCompletion );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    // Perform any further initialization here.

}
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)