2012-10-08 6 views
9

Ich arbeite an einem Installationsprogramm in OS X, das einen IOKit-Treiber für ein USB-Gerät installiert, und ich versuche, dafür zu sorgen, dass am Ende kein Neustart erforderlich ist. Das Installationsprogramm installiert den Treiber korrekt und baut den Kext-Cache neu auf. Wenn ich das USB-Gerät abziehe und wieder einstecke, lädt es den neuen Treiber korrekt und alles funktioniert einwandfrei.Programmatisch "ein USB-Gerät ausstecken und umstecken", um neue Treiber in OS X zu laden?

Ich möchte jedoch nicht, dass der Benutzer das Gerät physisch trennen muss, damit der neue Treiber geladen werden kann. Es muss eine Möglichkeit geben, OS X dazu zu bringen, den neuen Treiber programmatisch zu laden - im Prinzip simulieren Sie, dass das Gerät ausgesteckt und wieder angeschlossen wird, oder etwas Ähnliches. Wie würde ich das machen? Bisher haben Stunden des Googelns nichts gebracht, also wird jede Hilfe sehr geschätzt!

+0

Ich würde versuchen, Blick auf den Code, der ausgeführt wird, wenn Sie ein USB-Massenspeichergerät auswerfen - Ich bin nicht sicher, ob es entsprechende USB-Verkehr oder wenn es nur das USB-Subsystem anweist, den Port zu ignorieren, bis eine physische Trennung erfolgt. Im ersteren Fall (eine "USB-Auswurf" -Meldung) gibt es möglicherweise keine einfache Möglichkeit zum "Auswerfen", abgesehen von einem Stromausfall oder einem USB-Reset, die beide für andere USB-Geräte problematisch sein können. Aber das ist hoffentlich irgendwo, wo ich anfangen soll. –

+0

Ich habe etwas über 'pmount' gelesen, das willkürlichere USB-Geräte aushängen kann, aber ich weiß nicht, ob das Ihr Gerät enthält. Der einzige große Nachteil ist, dass es standardmäßig nicht mit OS X geliefert wird. – rien333

+0

Ich bin mir ziemlich sicher, dass Sie dies nicht direkt aus Benutzerraum tun können. Im Kernel könnten Sie jedoch versuchen, terminate() auf dem vorhandenen Client aufzurufen, der das Gerät blockiert. – pmdj

Antwort

2

IOUSBDeviceInterface187 :: USBDeviceReEnumerate() wird tun, was Sie wollen. Die einzige Schwierigkeit besteht darin, alle interessierenden Geräte zu finden und diese manuell mit IOServiceGetMatchingServices() anzurufen.

/*! 
@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); 

Blick in IOKit/usb/IOUSBLib.h

1

Werfen Sie einen Blick auf diskutil, und vor allem die mount und unmount Optionen. Diese werden Geräte softwaremäßig auswerfen und bereitstellen. Sie können diskutil list verwenden, um eine Liste aller derzeit installierten Geräte zu erhalten. Wenn Sie mehr Informationen über diskutil benötigen, schauen Sie sich einfach die man-Seite an.

+0

Leider ist dieses Gerät keine Festplatte, es ist eine Mensch-Maschine-Schnittstelle, so weit ich weiß, wird diskutil nicht helfen. – GuyGizmo

+0

Ah, ich verstehe. Mein Fehler. – rien333