在Mac OS X上手动重置USB设备后,Kext驱动程序没有响应

时间:2015-10-16 13:13:57

标签: macos usb driver iokit kernel-extension

我正在使用通过USB连接到Mac OS X操作系统的计算机的蓝牙耳机。

我在应用程序中运行应用程序以及通过发送设备请求和读/写管道来使用耳机的kext驱动程序。

要更改耳机设置,请拨打IOUSBDevice :: DeviceRequest(...),但要应用这些设置,我需要重新启动耳机芯片。

问题是在从kext驱动程序发送特殊设备请求后重新启动芯片时,不会调用函数stop(IOService * provider)和free(void)。因此设备会在系统中消失一秒钟,但驱动程序仍处于工作状态:我无法卸载此驱动程序:

bash-3.2# kextunload -b VXiCorp.USBDriver
(kernel) Can't unload kext VXiCorp.USBDriver; classes have instances:
(kernel)     Kext VXiCorp.USBDriver class VXiCorp_USBDriver has 1 instance.
Failed to unload VXiCorp.USBDriver - (libkern/kext) kext is in use or retained (cannot unload).

此外,当重新启动后出现耳机时(即使我连接其他USB耳机),也不会调用函数start()和probe()。因此,在重新启动操作系统之前,我无法使用耳机。

如何重新启动耳机并让kext驱动程序正常工作?

我尝试使用IOUSBDeviceInterface300 :: DeviceRequest从用户空间发送重启请求,但它没有帮助。也许我需要在重启耳机之前手动停止并释放驱动程序实例,但我不知道如何正确执行。

在不使用kext文件的情况下,我会更好地与用户空间的设备进行通信,但问题是我无法让IOUSBInterfaceInterface300具有读/写管道功能。我有IOUSBDeviceInterface300,当我试图调用IOCreatePlugInInterfaceForService时,我收到错误kIOReturnUnsupported - 0x2c7(不支持的函数)。

IOUSBFindInterfaceRequest request;

request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
request.bAlternateSetting = kIOUSBFindInterfaceDontCare;

if ((*device)->CreateInterfaceIterator(device, &request, &iterator) != kIOReturnSuccess)
{
    fprintf(stderr, "[!] Failed to create interface iterator\n");
    return NULL;
}

while ((service = IOIteratorNext(iterator)) != 0)
{
    if (IOCreatePlugInInterfaceForService(service, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score) == kIOReturnSuccess)
    {
         ...
    }
}

我已经检查了这个帖子http://lists.apple.com/archives/usb/2008/Mar/msg00001.html,但无代码kext对我没用。

此外我无法调用IOUSBDeviceInterface300 :: OpenDevice或IOUSBDeviceInterface300 :: SetConfiguration,它看起来像标准的osx驱动程序在连接后立即打开我的设备。

您是否可以建议避免设备重启问题的方法?

ioreg输出部分:

+-o Root  <class IORegistryEntry, id 0x100000100, retain 11>
  +-o VMware7,1  <class IOPlatformExpertDevice, id 0x10000010f, registered, mat$
    +-o AppleACPIPlatformExpert  <class AppleACPIPlatformExpert, id 0x100000110$
    | +-o PCI0@0  <class IOACPIPlatformDevice, id 0x10000012b, registered, matc$
    | | +-o AppleACPIPCI  <class AppleACPIPCI, id 0x100000195, registered, matc$
    | |   +-o PE50@16  <class IOPCIDevice, id 0x100000175, registered, matched,$
    | |   | +-o IOPP  <class IOPCI2PCIBridge, id 0x1000001e9, registered, match$
    | |   |   +-o S1F0@0  <class IOPCIDevice, id 0x100000176, registered, match$
    | |   |     +-o AppleUSBXHCI  <class AppleUSBXHCI, id 0x1000001fd, register$
    | |   |       +-o VXi B350-XT@16310000  <class IOUSBDevice, id 0x100000460,$
    | |   |       | +-o IOUSBInterface@2  <class IOUSBInterface, id 0x100000465$
    | |   |       +-o VXi B350-XT@16310000  <class IOUSBDevice, id 0x100000483,$
    | |   |         +-o IOUSBInterface@0  <class IOUSBInterface, id 0x100000486$
    | |   |         +-o IOUSBInterface@2  <class IOUSBInterface, id 0x100000488$
    | |   |         +-o VXiCorp_USBDriver  <class VXiCorp_USBDriver, id 0x10000$

1 个答案:

答案 0 :(得分:0)

这里有很多问题,但我会尝试回答一些问题:

  • 如果由于重置设备而导致IOUSBDevice对象被终止,并且您的驱动程序未被停止,则很可能以某种方式阻止终止。我建议覆盖terminate系列方法并为它们添加一些日志记录。如果删除kext失败,您可能会经常retain一个或多个对象。例如,不要永久保留您的提供者对象。如有疑问,请在重置之前和之后向我们展示ioreg状态。
  • 对于许多USB设备或接口,同时从多个客户端访问它们通常不是一个好主意。这适用于来自kext和用户空间的并发访问。尝试仅从用户空间或仅使用kext访问它。
  • 我不确定为什么IOCreatePlugInInterfaceForService在这种情况下会失败,但如果您有无代码kext,则可能与此无关。发布可能会有所帮助。