2012-10-08 19 views
9

Estoy trabajando en un instalador en OS X que instala un controlador IOKit para un dispositivo USB, y estoy intentando que no requiera un reinicio al final. El instalador instala el controlador correctamente y reconstruye el caché de kext, y después de que se ejecute, si desconecto y vuelvo a conectar el dispositivo USB, carga correctamente el nuevo controlador y todo funciona bien.¿Desconecta y vuelve a conectar mediante programación un dispositivo USB para cargar un nuevo controlador en OS X?

Sin embargo, no deseo que el usuario desconecte físicamente el dispositivo para que se cargue el nuevo controlador. Tiene que haber una manera de hacer que OS X cargue el nuevo controlador de forma programática; en efecto, simule que el dispositivo esté desenchufado y enchufado de nuevo, o algo similar. ¿Cómo voy a hacer esto? Hasta ahora, las horas de búsqueda en Google no arrojaron nada, por lo que cualquier ayuda será muy apreciada.

+0

que iba a tratar mirar el código que se ejecuta cuando se expulsa un dispositivo de almacenamiento masivo USB - no estoy seguro de si hay tráfico correspondiente USB o si simplemente le dice al subsistema USB que ignore el puerto hasta que se desenchufe físicamente. En el primer caso (un mensaje de "expulsión de USB"), puede que no haya una manera fácil de "anular la expulsión", aparte de un ciclo de encendido o un reinicio de USB, los cuales pueden ser problemáticos para otros dispositivos USB. Pero espero que sea un lugar para empezar a buscar. –

+0

Leí sobre algo llamado 'pmount' que puede desmontar más dispositivos USB arbitrarios, pero no sé si eso incluye su dispositivo. El único gran inconveniente es que no viene con OS X de forma predeterminada. – rien333

+0

Estoy bastante seguro de que no puedes hacer esto directamente desde el espacio del usuario. Sin embargo, en el kernel, puedes intentar llamar a terminate() en el cliente existente que está acaparando el dispositivo. – pmdj

Respuesta

2

IOUSBDeviceInterface187 :: USBDeviceReEnumerate() hará lo que quiera. El único inconveniente es encontrar todos los dispositivos de interés y llamarlos manualmente con IOServiceGetMatchingServices().

/*! 
@function USBDeviceReEnumerate 
@abstract Tells the IOUSBFamily to reenumerate the device. 
@discussion This function will send a terminate message to all clients of the IOUSBDevice (such as 
      IOUSBInterfaces and their drivers, as well as the current User Client), emulating an unplug 
      of the device. The IOUSBFamily will then enumerate the device as if it had just 
      been plugged in. This call should be used by clients wishing to take advantage 
      of the Device Firmware Update Class specification. The device must be open to use this function. 
@availability This function is only available with IOUSBDeviceInterface187 and above. 
@param  self Pointer to the IOUSBDeviceInterface. 
@param  options A UInt32 reserved for future use. Ignored in current implementation. Set to zero. 
@result  Returns kIOReturnSuccess if successful, kIOReturnNoDevice if there is no connection to an IOService, 
      or kIOReturnNotOpen if the device is not open for exclusive access. 
*/ 

IOReturn (*USBDeviceReEnumerate)(void *self, UInt32 options); 

Buscar en IOKit/USB/IOUSBLib.h

1

Eche un vistazo a diskutil, y especialmente a las opciones mount y unmount. Esos expulsarán y montarán dispositivos por medio de software. Puede usar diskutil list para obtener una lista de todos los dispositivos montados actualmente. Si necesita más información sobre diskutil, simplemente mire la página man.

+0

Lamentablemente, este dispositivo no es un disco, es un dispositivo de interfaz humana, por lo que sé que diskutil no ayudará. – GuyGizmo

+0

Ah, ya veo. Mi error. – rien333

Cuestiones relacionadas