I'm developing an iPadOS USB audio-MIDI driver for a hardware device. The audio side uses AudioDriverKit and USBDriverKit (DriverKit SDK 27.0, AudioDriverKit deployment target 21.0, iPadOS 18.0 minimum).
I need clarification about the ordering between IOUserAudioDriver::Stop, StopDevice/StopIO, and in-flight IOOperationHandler callbacks.
According to Apple's DriverKit documentation, IOService::Stop must quiesce outstanding operations before invoking its superclass implementation. AudioDriverKit documents host-controlled audio I/O and the StopDevice → device StopIO sequence.
However, I cannot find an explicit guarantee that the framework has stopped and drained all BeginRead/WriteEnd callbacks before invoking the driver's service Stop.
Relevant implementation (simplified):
// Audio driver service termination
kern_return_t result = StopUSBTransport();
if (result != kIOReturnSuccess) {
return result;
}
// Release resources and close provider interfaces.
return Stop(in_provider, SUPERDISPATCH);
The transport retirement path currently refuses to release resources while framework I/O is marked active:
if (__atomic_load_n(&ivars->m_adk_running,
__ATOMIC_ACQUIRE)) {
// Retain ownership; resources cannot be released safely.
return kIOReturnBusy;
}
The local running state is cleared following successful device superclass StopIO, but this does not independently establish that already-entered framework audio callbacks have returned.
The USB teardown separately prevents new submissions, aborts outstanding transfers, waits for cancellation acknowledgements and native callback completion, and retains resources if ownership cannot be proven safe.
An offline regression exercising service termination while framework I/O is marked active reproduces the Busy result. We have not established that AudioDriverKit delivers this ordering on physical hardware.
Questions:
-
Before invoking
IOUserAudioDriver::Stop, does AudioDriverKit guarantee thatStopDevice/StopIOhas completed and that all outstandingIOOperationHandlerinvocations have returned? -
If not, what supported mechanism can a driver invoke during service
Stopto prevent newBeginRead/WriteEndcallbacks and wait for already-entered callbacks to finish? -
Does calling superclass
IOUserAudioDriver::Stopestablish this callback-drain boundary? If so, how should hardware and USB resources be shut down when provider access is no longer permitted afterward? -
If termination cannot safely complete, is returning
kIOReturnBusya supported way to defer service termination? Is a subsequent retry guaranteed?
I'm looking for the documented lifecycle and synchronization contract, rather than a workaround based on assumed callback ordering.
Any clarification from Apple's DriverKit or Core Audio engineering team would be appreciated.