2015-10-16 12 views
0

Я работаю с Bluetooth-гарнитурой, подключенной к компьютеру с операционной системой Mac OS X через USB.Kext драйвер не отвечает после ручного сброса 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 но Codeless 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 [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 не выполняется, вы, вероятно, retain слишком часто используете один или несколько объектов. Например, не сохраняйте объект поставщика. Если есть сомнения, покажите нам состояние ioreg до и после сброса.
  • Для многих устройств USB или интерфейсов, как правило, не рекомендуется обращаться к ним с нескольких клиентов одновременно. Это касается одновременного доступа как из kext, так и для пользовательского пространства. Попытайтесь получить к нему доступ либо из только пользовательского пространства, либо только из kext.
  • Я не уверен, почему IOCreatePlugInInterfaceForService терпит неудачу в этом случае, но это может быть связано с вашим без кодовым kext, если он у вас есть. Проводка, вероятно, поможет.