Re: Proper termination of an IOKit driver
Re: Proper termination of an IOKit driver
- Subject: Re: Proper termination of an IOKit driver
- From: Dean Reece <email@hidden>
- Date: Tue, 30 Mar 2004 11:46:08 -0800
Hi Brad,
On Mar 30, 2004, at 10:10 AM, Brad Post (MACBU) wrote:
I am having problems with the unloading of an IOKit Driver and I need
some guidance as to the correct method to solve it.
The driver is based off the same code, so we only have the standard
functions: init, free, probe, start & stop
The problem we're running into is that the user can call kextunload on
our IOKit, which calls the stop method. Our code recognizes that the
application is still using the driver and fails, and we never call the
super::stop method. Unfortunately the IOServices removes our driver
from the IORegistry, and when the user then tries to reload the driver
with kextload bad things go amuck....
The problem is that you are trying to prevent the termination of your
driver too late in the chain of events. By the time stop() has been
called, the system has decided your driver object is no longer needed.
Also, failing to call super::stop() introduces other problems, as you
discovered. I'm curious, did you see this done somewhere else or find
some documentation that indicated not calling super::stop() was
appropriate?
What you need to do is override terminate() and return false in cases
where you don't want the termination process to proceed.
From IOService.h, discussion of terminate():
Registering an IOService informs possible clients of its existance and
instantiates drivers that may be used with it; terminate involves the
opposite process of informing clients that an IOService is no longer
able to be used and will be destroyed. By default, if any client has
the service open, terminate fails. If the kIOServiceRequired flag is
passed however, terminate will be sucessful though further progress in
the destruction of the IOService will not proceed until the last
client has closed it. The service will be made inactive immediately
upon successful termination, and all its clients will be notified via
their message method with a message of type
kIOMessageServiceIsTerminated. Both these actions take place on the
callers thread. After the IOService is made inactive, further matching
or attach calls will fail on it. Each client has its stop method
called upon their close of an inactive IOService, or on its
termination if they do not have it open. After stop, detach is called
in each client. When all clients have been detached, the finalize
method is called in the inactive service. The terminate process is
inherently asynchronous since it will be deferred until all clients
have chosen to close.
Additionally, something should be calling open() on your driver while
your app is using it, and close() once it is done. Generally, this
would be done by your IOUserClient, but the driver could call
open()/close() on itself if it is serving as it's own conduit to
user-space.
Forget the fact that this is an edge-case senario, and I know the
minute the user starts using kextunload, we don't really have to play
nice, but I want to play nice. We don't unload, which I thought was
enough, but now I have to figure out how to stop IOServices from
removing us from the IORegistry.
It is reasonable to prevent unloading while it is in active use - that
is just good defensive programming. The problem you are having is that
failing to call super::stop() isn't the right approach (and in fact
causes other problems).
Is there a routine I need to be calling or some message I need to be
listening for?
terminate(), open(), and close() are where you should be looking.
Sample code?
I'm not aware of a particularly relevant example, but look around in
Darwin for drivers that implement terminate().
Cheers,
- Dean
Thanks.
Brad
=3D=3D=3D=3D< my code snippet >=3D=3D=3D=3D=3D
void mykextclass::stop(IOService *provider)
{
kern_return_t result =3D KERN_SUCCESS;
IOLog("Stopping\n");
result =3D mydriver(provider);
if (result =3D=3D KERN_SUCCESS)
super::stop(provider);
}
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.