Re: Proper termination of an IOKit driver
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 | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Dean Reece