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

# UserProcessParallelTask

Processes a parallel task in response to a call from the framework.

```
virtual kern_return_t UserProcessParallelTask(SCSIUserParallelTask parallelRequest, uint32_t *response, OSAction *completion);
```

## Parameters

`parallelRequest`

A [`SCSIUserParallelTask`](/documentation/SCSIControllerDriverKit/SCSIUserParallelTask) object that contains all necessary request information.

`response`

A service response for the request.

`completion`

An <doc://com.apple.documentation/documentation/DriverKit/OSAction> object that the dext class uses to complete the request.

## Discussion

The system calls this method to put a command on the bus, sending all information necessary to process the request in the `parallelRequest` parameter. Your HBA-specific subclass must implement this method.

The following example shows a minimal implementation of [`UserProcessParallelTask`](/documentation/SCSIControllerDriverKit/IOUserSCSIParallelInterfaceController/UserProcessParallelTask):

1. The example starts by using the `parallelRequest` parameter’s [`fControllerTaskIdentifier`](/documentation/SCSIControllerDriverKit/SCSIUserParallelTask/fControllerTaskIdentifier) to look up task data, which it stores in a hypothetical convenience type called `TaskData`.
2. Next, it sets the metadata for this I/O operation. The kernel generates one long phsyical segment with [`fBufferIOVMAddr`](/documentation/SCSIControllerDriverKit/SCSIUserParallelTask/fBufferIOVMAddr) as its start address, as seen here in the call to a hypothetical `PrepareScatterGatherList()` function. You may need to prepare a custom scatter gather list if your hardware specification requires you to split this up into multiple segments.
3. After that, the example retains and stashes  the `completion` callback for later.
4. Finally, the code posts the request to the hardware by calling `PostSCSIRequest()`, another hypothetical convenience function. Assuming this call returns <doc://com.apple.documentation/documentation/DriverKit/kIOReturnSuccess>, the example sets the `response` in-out parameter to <doc://com.apple.documentation/documentation/DriverKit/SCSIServiceResponse/kSCSIServiceResponse_Request_In_Process>, to indicate to the kernel that the request is underway.

```objc
kern_return_t
IMPL ( ExampleSCSIDext, UserProcessParallelTask )
{
    kern_return_t     ret          = kIOReturnError;
    TaskData *        taskData     = NULL;

    taskData = ivars->fTaskArray[parallelRequest.fControllerTaskIdentifier];

    // Set all the metadata for this IO.
    taskData->fRequestedTransferCount = parallelRequest.fRequestedTransferCount;
    taskData->fTransferDirection = parallelRequest.fTransferDirection;
    PrepareScatterGatherList ( taskData, parallelRequest.fBufferIOVMAddr );
    …

    // Retain and stash the completion callback.
    completion->retain ( );
    taskData->fAction = completion;
    
    // Submit the request to the hardware.
    ret = PostSCSIRequest ( taskData );
    __Require ( ( kIOReturnSuccess == ret ), Exit );

    // Set the response and return.
    *response = kSCSIServiceResponse_Request_In_Process;

    return ret;
}
```

---

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)