我正在为MacOSX (Windows已经在运行)开发一个虚拟USB总线驱动程序,该驱动程序通过网络与linux机器相连。在10.6和10.7版本下,它在大容量存储设备和HID设备(如鼠标或键盘)上运行良好。
但是对于10.7(.5)以下的HID设备,移除设备(拔出)或更简单的卸载kext失败,因为有一个剩余的实例(分离后保留计数不会降到零)。我的10.6和10.7测试环境是完全相同的MacBooksPro 8.2 i7。
有时,在一段时间(5-50分钟)后,kext会变得空闲,而不需要我的操作。它似乎不依赖于不断变化的电源模式。
是的,我有USBFamily日志库和很多输出,但在工作(kextunload ok)和非工作运行之间,我发现日志没有区别,即使是在日志级别7。
由于大容量存储设备似乎工作得很好,我猜问题出在芯片HID驱动栈内部,尤其是在10.7下?
10.6和10.7之间是否存在删除USB HID设备驱动程序堆栈的已知差异?
My kext是一个(虚拟的) ControllerV3派生类,它为任何实际插入(在远程linux机器上)的USBDevice设备建立/创建一个USB。使用XCode 4.4.1。
提前感谢你的任何想法或提示,敬请马库斯
PS:在我看来,10.7下有这么多HID对象在驱动堆栈的顶部,这对我来说有点奇怪。在kextunload之后(失败为"..VirDevice has 1 instance"),它们看起来仍然活着。但这在100%相同的一个本地插拔罗技鼠标。
来自我的只是最低的两个对象MsVirBus (虚拟USB总线,派生自IOUSBControllerV3 )和鼠标@xaffe003f是IOUSBDevice派生的对象。

发布于 2012-12-06 20:21:01
我对HID堆栈没有深入的经验,但我可以给你一些关于如何追踪这类问题的根源的通用IOKit/kext建议。
kextunload对I/O注册表中的所有对象调用terminate()。这意味着有两种情况可能会导致您最终无法卸载kext:
terminate()无法或无法删除所有子对象中
使用ioreg命令检查是否有任何对象保留在I/O注册表中。还要检查他们有哪些客户端,因为这些客户端通常会阻止删除。
如果注册表中没有对象,那么很可能是保留/释放不匹配。我给出了一些关于追踪这些in this answer的建议,所以我不会在这里重复。这似乎也不太可能,因为你的kext最终会卸载并在10.6上工作。
如果您在I/O注册表中保留了对象,则需要跟踪这些对象仍然存在的原因。如果你还没有在你的类中重写terminate(),添加虚拟重写,它只是将调用转发到基类实现。但将该转发调用与日志记录输出一起包装,并输出调用是否成功。如果你已经覆盖了terminate,添加类似的日志记录。您可能还想为didTerminate()添加类似的日志记录,因为终止可以是异步的。
当terminate()设备被拔出时,您应该将USB沿着设备树向下传递给您的客户端。我会检查EHCI控制器代码的等效部分,看看是否需要任何特殊的参数等。
https://stackoverflow.com/questions/13706894
复制相似问题