I'm working on kext driver for my USB device on OS X. In this driver I have a pointer to object IOUSBDevice *device
(it can be received in start() and probe() functions) and I have a problem: it is possible to open device (device->open(this, kIOServiceSeize)
) in probe() function, but in other functions open()
return false, because it seems like classic driver take the control on device.
I found article User-Mode USB Device Arbitration and tried to create "skeleton" kext to set "ClassicMustNotSeize" property to true, but it seems like it is not working, I still can't open the device.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.sample.iokit.ClassicNotSeizeDriver</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>IOKitPersonalities</key>
<dict>
<key>MyUSBDevice</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleUSBMergeNub</string>
<key>IOClass</key>
<string>AppleUSBMergeNub</string>
<key>IOProviderClass</key>
<string>IOUSBDevice</string>
<key>IOProviderMergeProperties</key>
<dict>
<key>ClassicMustNotSeize</key>
<true/>
</dict>
<key>idProduct</key>
<integer>1</integer>
<key>idVendor</key>
<integer>10978</integer>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.driver.AppleUSBMergeNub</key>
<string>1.8.3b1</string>
<key>com.apple.iokit.IOUSBFamily</key>
<string>1.8</string>
</dict>
</dict>
</plist>
Is it possible to set "ClassicMustNotSeize" property programmatically, for example in probe() function of my driver?
I tried:
device->setProperty("ClassicMustNotSeize", true);
and it seems like it also doesn't work.
Other kexts will not claim a service if yours has successfully matched and probe()
d. If you don't successfully start()
, it might get matched by another kext later if something re-initiates matching. So something isn't right, and it's not possible to tell from your question alone what it is because you haven't provided the relevant code, info.plist and ioreg excerpt, let alone your code's debug output…
So I can only guess:
kIOServiceSeize
? If your kext matches the device, has the highest probe score and returns non-null from probe()
, no other driver will have grabbed the device (yet). If you want to ensure exclusive access to USB devices, use the kUSBOptionBitOpenExclusivelyMask
option to open()
.open()
during probe()
, make sure you close()
before returning, no matter what value you return. Re-open()
in start()
. (Overriding probe()
is usually not needed anyway, it will return this
by default.)ClassicMustNotSeize
does nothing.