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

# UserMapHBAData

Maps any host bus adapter (HBA)-specific task data in response to a call from the framework.

```
virtual kern_return_t UserMapHBAData(uint32_t *uniqueTaskID);
```

## Parameters

`uniqueTaskID`

The unique ID for this task.

## Return Value

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

## Discussion

The driver extension class should override this function and memory-map and prepare any host bus adapter (HBA)-specific task data for direct memory access (DMA). The framework calls this method for every `SCSIParallelTask` immediately after creating the task in the kernel. The driver extension class should also set a unique task ID. The framework uses this ID to uniquely identify the corresponding `SCSIParallelTask` in the kernel.

The following listing shows an example of implementing [`UserMapHBAData`](/documentation/SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController/UserMapHBAData). It starts by creating an <doc://com.apple.documentation/documentation/DriverKit/IOBufferMemoryDescriptor> for the controller’s specific data structure. It also maps memory to the dext’s memory space. Then the example adds the task to its own task data list, and sets the `uniqueTaskID` in-out variable to a newly-incremented unique ID. This allows the kernel to associate this task with its corresponding <doc://com.apple.documentation/documentation/kernel/scsiparalleltaskidentifier>.

```objc
kern_return_t
IMPL ( ExampleSCSIDext, UserMapHBAData )
{
    …
    ret = IOBufferMemoryDescriptor::Create ( kIOMemoryDirectionOutIn, ivars->fTaskDataSize,        
                                             vm_page_size, &buffer );
    __Require ( ( kIOReturnSuccess == ret ), Exit );
    
    ret = buffer->CreateMapping ( 0, 0, 0, 0, 0, &memMap );
    __Require ( ( kIOReturnSuccess == ret ), Exit );
    taskData  =  ( typeof ( taskData ) ) memMap->GetAddress ( );

    ivars->fTaskID++;
    ivars->fTaskArray[ivars->fTaskID] = taskData;

    *uniqueTaskID = ivars->fTaskID;
   …
}
```

It’s important to perform preprocessing like memory mapping early — before serving I/O — because doing so on the I/O path can affect performance. For example, calling an API like <doc://com.apple.documentation/documentation/DriverKit/IOMemoryDescriptor/CreateMapping> in the I/O path can cause additional RPC overhead.

---

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)