it's my first question here :)
I'm currently writing a generic kext which provides a character device and targets OSX 10.7+. It's pure C, with zero IOKit/C++. (In case this matters, I'm testing the driver on 10.11.)
I want the driver to be unloaded once all file descriptors that refer to the character device are closed, but this doesn't seem to work.
According to Apple's documentation for OSKextRetainKextWithLoadTag
:
When autounload is enabled, then shortly after the kext's last reference is dropped, it will be unloaded if there are no outstanding references to it and there are no instances of its Libkern C++ subclasses (if any).
...
Kexts that define subclasses of IOService have autounload enabled automatically. Other kexts can use the reference count to manage automatic unload without having to define and create Libkern C++ objects.
As mentioned above, my kext doesn't have any IOService
subclasses (or any classes, for that matter), so I should be able to use OSKextRetainKextWithLoadTag
.
However, the kext remains loaded forever, after all file descriptors are closed:
static int cdev_open(dev_t dev, int flags, int devtype, struct proc *p)
{
/* ... */
return OSKextRetainKextWithLoadTag(OSKextGetCurrentLoadTag()) == kOSReturnSuccess) ? 0 : kOSReturnError
}
static int cdev_close(dev_t dev, int flags, int devtype, struct proc *p)
{
/* ... */
OSKextReleaseKextWithLoadTag(OSKextGetCurrentLoadTag());
return 0;
}
In addition, I wrote "hybrid" version of my kext, where I wrapped the start and stop routines with a thin C++ wrapper that provides a IOService
subclass (with IOResources
as the provider), in case unloading is no longer supported with generic kexts. Same result.
(I've found several examples of generic kexts that use OSKextRetainKextWithLoadTag
and OSKextReleaseKextWithLoadTag
, but they're extremely old and don't know if they work against recent versions of OS X.)
Any idea what I'm doing wrong?
Thank you.