2015-10-16 24 views
0

我正在通過USB將藍牙耳機連接到具有Mac OS X操作系統的計算機。在Mac OS X上手動重置USB設備後,Kext驅動程序無響應

我有用戶空間中運行的應用程序,也是通過發送設備請求和讀/寫管道與耳機一起工作的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我receice錯誤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,它看起來像standart 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 [email protected] <class IOACPIPlatformDevice, id 0x10000012b, registered, matc$ 
    | | +-o AppleACPIPCI <class AppleACPIPCI, id 0x100000195, registered, matc$ 
    | | +-o [email protected] <class IOPCIDevice, id 0x100000175, registered, matched,$ 
    | | | +-o IOPP <class IOPCI2PCIBridge, id 0x1000001e9, registered, match$ 
    | | | +-o [email protected] <class IOPCIDevice, id 0x100000176, registered, match$ 
    | | |  +-o AppleUSBXHCI <class AppleUSBXHCI, id 0x1000001fd, register$ 
    | | |  +-o VXi [email protected] <class IOUSBDevice, id 0x100000460,$ 
    | | |  | +-o [email protected] <class IOUSBInterface, id 0x100000465$ 
    | | |  +-o VXi [email protected] <class IOUSBDevice, id 0x100000483,$ 
    | | |   +-o [email protected] <class IOUSBInterface, id 0x100000486$ 
    | | |   +-o [email protected] <class IOUSBInterface, id 0x100000488$ 
    | | |   +-o VXiCorp_USBDriver <class VXiCorp_USBDriver, id 0x10000$ 
+0

我很難想象你的設備和驅動程序層次結構,因此有必要得到'ioreg'輸出的相關子樹 - 你可以把它添加到問題中嗎? – pmdj

+0

感謝您的理解,這對我來說是一個熱門話題。我添加了ioreg的子樹。請問我是否需要其他信息。 – Evgeniy

回答

0

這裏有很多的問題,但我會盡力回答幾個:

  • 如果IOUSBDevice對象被終止的重置設備的結果,並且您的驅動程序沒有被停止,那麼它很可能會以某種方式阻止終止。我建議覆蓋terminate方法家族並添加一些日誌記錄。如果刪除kext失敗,那麼您可能經常會碰到一個或多個對象。例如,不要永久保留您的提供者對象。如果有疑問,請在重置之前和之後向我們展示ioreg狀態。
  • 對於很多USB設備或接口,通常不是同時從多個客戶端訪問它們的好主意。這適用於來自kext和用戶空間的併發訪問。嘗試只從用戶空間或只有kext訪問它。
  • 我不確定爲什麼IOCreatePlugInInterfaceForService在這種情況下失敗,但它可能是如果你有一個你的無代碼kext。發佈這可能會有所幫助。
相關問題