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