Hi,
I have developed a KEXT for Mac OS X 10.3.9 ppc and 10.4.7 Intel/PPC for my USB bulk devices.Enountering a strange problem and wanted expert advice from your side:
My user application communicates very well with our USB bulk devices through the kext developed. If we unplug the device, the user application gets stopped , as designed !
Now I attach my two USB bulk devices to the root HUB.
a) I attach my 1st USB bulk device
b) Now I attach my 2nd USB bulk device and start communicating with this device through my user application.
Everything;s work fine till now!!!
Now if I un-plug the 1st USB bulk device, which has no connection with the communication of user application going with the 2nd USB bulk device, the communication gets closed itself ! Ideally, the second application should have run fine since I the second key is already attached. (Also there is no power drop sceenrio)
To reproduce, this scenerio, i attached 1st USB device communicating with application1 and next 5 applications communicating to 5 USB bulk devices seperately. Now if I detach the 1st USB device, the communication of other application also closes itself!!!! But this scenerio does not happen if i unplug my 2,3,4,5th device.
/*----Code snippet ---*/
class MyKEXT : public IOService {
..
};
IOReturn MyKEXT::message( UInt32 type, IOService * provider, void * argument )
bool MyKEXT::didTerminate( IOService * provider, IOOptionBits options, bool * defer )
bool MyKEXT::willTerminate( IOService * provider, IOOptionBits options )
/*---------*/
In didTerminate function, I am closing my provider and freeing the memory I allocated.
In willTerminate function, I am aborting the pipes. My USB bulk has a default pipe, IN and OUT pipe.
In message function, I am just calling the superclass to the handle the message first.
Basically my cleanup functionality is in didTerminate and willTerminate function and not in message function. So when we remove the device, the message function calls the message of IOUserClient. Below is the code snippet for IOUserClient part:
/*----Code snippet---*/
IOReturn MyDriverUserClient::message(UInt32 type, IOService * provider, void * argument)
{
IOReturn retVal = kIOReturnSuccess;
switch ( type )
{
case kIOMessageServiceIsTerminated :
case kIOMessageServiceIsRequestingClose :
retVal = terminate ();
break;
default:
break;
}
return retVal;
}
bool MyDriverUserClient::finalize(IOOptionBits options)
{
return super::finalize(options);
}
bool MyDriverUserClient::terminate(IOOptionBits options)
{
return super::terminate(options);
}
/*-----*/
Now when I unplug the first device, the call from IOService message goes for each IOUserclient message that calls the terminate function for each application communicating. Why so ?? Ideally the call should only go the first devices's UserClient.
It seems that the call is recusively going to each client that is communicating.Why is it happening ? It seems that internally, IOSservice* is recusively being called and terminate is being called for each user application.
What can be the possible issue ? Am i missing something / or doing something wrong ?
Or is there might be some issue with the IOKit iself?
Did anybody enountered the similar issue before ? Please send your useful suggestions, as to why it is happening and how to avoid this issue.
Please feel free to ask if my query is not clear!
Thanks and Regards,
Rohit Dhamija