Is it possible you flipped the two logs you posted? The one you've labeled "18" shows DriverKit attempting to load your DEXT after it had been deleted, which seems incorrect.
No, I checked and the logs are named correctly. As you mentioned, in the iPadOS 18 log, the driver is re-loaded and goes through the Start phase again which is not the case if you look at the iPadOS 17 log. Also, I can see Stop getting called only in the 18 log maybe because of this reload.
One thing I'd look for here is the I/O registry state of your kernel driver after you uninstall the app and then hot plug the accessory without reinstalling your app.
Could you please guide me on what you mean by the kernel driver here? I have already checked the IORegistry to see whether any instances of my driver is still present after a hot plug and I can't seem to find any. Also, it doesn't help if I reinstall the app, enable the driver and hot plug the accessory (still non-functional).
Alternatively, what does your driver "do" to your hardware during teardown?
In my actual implementation, I stop ongoing transfers if any and close the queues which were created in my Start(). I also suspected whether I was doing something wrong in my Stop() implementation first. However, I later changed my Start and Stop to be minimal (just open the PCI device and enable/disable bus mastering) to verify this. I get the same kind of logs even with this.
What happens if you uninstall your app/DEXT while your hardware ISN'T attached?
Whenever my hardware gets detached, Stop() is successful without any crashes. Doing an uninstall in this case seems to be of no harm.
I went through the IOPCIDevice::ClientCrashed_Impl which is getting called in both the logs here. Below is the code excerpt from the link.
kern_return_t IOPCIDevice::ClientCrashed_Impl(IOService *client, uint64_t options)
{
DLOG(ALWAYS_ON, "IOPCIDevice::ClientCrashed_Impl() for client %s\n", (client) ? client->getName() : "unknown");
// only reset the device if the driver potentially changed the state of the device
if(isOpen(client) == true)
{
DLOG(ALWAYS_ON, "%s: PCIDriverKit client, %s, crashed for device %s[" BDF() "], attempting to recover\n",
__PRETTY_FUNCTION__,
(client != NULL) ? client->getName() : "unknown",
getName(),
PCI_ADDRESS_TUPLE(this));
IOReturn ret = parent->childClientCrashRecovery(this);
// rdar://122664049 (Remove terminate-on-crash option from PCIDriverKit crash recovery)
if (ret == kIOReturnSuccess && getProperty("terminate-on-crash"))
{
launchReprobeThread();
}
}
This exact log inside the if-block is getting printed in my case and I suspect whether the childClientCrashRecovery() and launchReprobeThread() functions are actually the ones triggering the reload in the case of 18.
I have not got a chance to investigate deeper into this. The only difference between the two logs is the recovery/reprobe mechanism which happens in 18 but fails to do so in 17. Can it be something where the recovery mechanism with launchReprobeThread() was added starting from iPadOS 18 (maybe Driverkit 24) and not present in iPadOS 17 altogether?
If this would help, I have another driver for matching some USB3 accessories (USBDriverKit) which seems to follow the same cycle of [Uninstall -> Recovery/Reprobe -> Driver Start/Init -> Driver Stop] but across all versions of iPadOS without any issues.
Topic:
App & System Services
SubTopic:
Drivers
Tags: