This posting is older than 6 months and can contain outdated information.
I've been looking into the whole "keyboard and trackpad not available
after waking from sleep" issue, digging deeply into the kernel
sources, and here's what I've discovered:
1) after a (deep) sleep, the USB devices all have to be reenumerated,
which means that IOKit will look for available drivers and user space
apps that have registered for notifications (including Remote Buddy)
will try to connect to the device through the respective
IOUSB*UserClient.
2) Apple's HID drivers (IOUSBHIDDriver and subclasses) schedule an
async read on all HID devices (including the IR Receiver, which, too,
is just a HID device)
3) Right after, Remote Buddy receives notice from IOKit in userspace
that a matching device (here: the built-in IR receiver) is available
4) To start from a clean basis, Remote Buddy's current release will
make a ResetDevice() call via the user client for the respective
IOUSBDevice.
5) In Kernel space, Apple's HID drivers still have their async reads
scheduled. As the device is reset, they receive an error (errorcode
kIOReturnUnderrun). Their standard reaction is to make a synchronous
call to reset the interrupt pipe they are listening on.
6) The IOUSBController instance responsible for the device deadlocks.
Remote Buddy stack dump:
[..]
19 __ZN16IOUSBDeviceClass11ResetDeviceEv + 86 (in IOUSBLib)
[0x1484d326]
19 _IOConnectCallScalarMethod + 84 (in IOKit) [0x95e1b6a8]
19 _IOConnectCallMethod + 300 (in IOKit) [0x95e1b3f6]
19 _mach_msg_trap + 10 (in libSystem.B.dylib) [0x942fb8e6]
Remote Buddy - Kernel stack dump:
19 _dtrace_get_cpu_int_stack_top + 543 [0x196afc]
19 _mach_msg_overwrite_trap + 752 [0x126247]
19 _ipc_kobject_server + 247 [0x12d165]
19 _iokit_server_routine + 20111 [0x18d037]
19 _is_io_connect_method + 468 [0x4379b0]
19
__ZN12IOUserClient14externalMethodEjP25IOExternalMethodArgumentsP24IOExternalMethodDispatchP8OSObjectPv
+ 175 [0x439b71]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 117745 [0x698bf1]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 119708 [0x69939c]
19
__ZN13IOCommandGate9runActionEPFiP8OSObjectPvS2_S2_S2_ES2_S2_S2_S2_ +
96 [0x41d9ce]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 70185 [0x68d229]
19 _IORecursiveLockLock + 42 [0x401694]
19 _lck_mtx_lock + 289 [0x19a781]
19 _lck_mtx_lock_wait + 382 [0x13157e]
19 _thread_block + 33 [0x1368fe]
19 _thread_continue + 1181 [0x136691]
IOKit - Kernel thread 1 stack dump:
19 __ZN10IOWorkLoop10threadMainEv + 24 [0x41bf88]
19 __ZN10IOWorkLoop15runEventSourcesEv + 90 [0x41c2a6]
19 __ZN22IOInterruptEventSource12checkForWorkEv + 183 [0x41d149]
19 com.apple.driver.AppleUSBEHCI (3.0.3) + 14710 [0x88c976]
[..]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 42613 [0x686675]
19 __ZN9IOService14messageClientsEmPvj + 72 [0x409d40]
19 __ZN9IOService17applyToInterestedEPK8OSSymbolPFvP8OSObjectPvES5_
+ 60 [0x409c9e]
19 __ZN9IOService14applyToClientsEPFvPS_PvES1_ + 43 [0x409a21]
19
__ZNK15IORegistryEntry15applyToChildrenEPFvPS_PvES1_PK15IORegistryPlane
+ 104 [0x406324]
19 __ZN9IOService17applyToInterestedEPK8OSSymbolPFvP8OSObjectPvES5_
+ 137 [0x409ceb]
19 __ZN9IOService13messageClientEmP8OSObjectPvj + 73 [0x409a6d]
19 com.apple.driver.AppleUSBHub (3.0.3) + 19005 [0xbc4a3d]
19 com.apple.driver.AppleUSBHub (3.0.3) + 16639 [0xbc40ff]
19 _lck_mtx_lock + 289 [0x19a781]
19 _lck_mtx_lock_wait + 382 [0x13157e]
19 _thread_block + 33 [0x1368fe]
19 _thread_continue + 1181 [0x136691]
IOKit - Kernel thread 2 stack dump:
19 _thread_call_enter_delayed + 527 [0x13e987]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 66903 [0x68c557]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 66814 [0x68c4fe]
19 __ZN9IOService14messageClientsEmPvj + 72 [0x409d40]
19 __ZN9IOService17applyToInterestedEPK8OSSymbolPFvP8OSObjectPvES5_
+ 60 [0x409c9e]
19 __ZN9IOService14applyToClientsEPFvPS_PvES1_ + 43 [0x409a21]
19
__ZNK15IORegistryEntry15applyToChildrenEPFvPS_PvES1_PK15IORegistryPlane
+ 104 [0x406324]
19 __ZN9IOService17applyToInterestedEPK8OSSymbolPFvP8OSObjectPvES5_
+ 137 [0x409ceb]
19 __ZN9IOService13messageClientEmP8OSObjectPvj + 73 [0x409a6d]
19 com.apple.driver.AppleUSBHub (3.0.3) + 19005 [0xbc4a3d]
19 com.apple.driver.AppleUSBHub (3.0.3) + 17104 [0xbc42d0]
19 com.apple.driver.AppleUSBHub (3.0.3) + 31581 [0xbc7b5d]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 12080 [0x67ef30]
19
__ZN13IOCommandGate9runActionEPFiP8OSObjectPvS2_S2_S2_ES2_S2_S2_S2_ +
261 [0x41da73]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 11763 [0x67edf3]
19 _IORecursiveLockSleep + 67 [0x401783]
19 _lck_mtx_sleep + 87 [0x130a08]
19 _thread_block + 33 [0x1368fe]
19 _thread_continue + 1181 [0x136691]
IOKit - Other kernel thread stack dumps:
19 _thread_call_enter_delayed + 527 [0x13e987]
19 __ZN18IOTimerEventSource17timeoutAndReleaseEPvS0_ + 58 [0x41f8ac]
19 com.apple.iokit.IOUSBFamily (3.0.3) + 70185 [0x68d229]
19 _IORecursiveLockLock + 42 [0x401694]
19 _lck_mtx_lock + 289 [0x19a781]
19 _lck_mtx_lock_wait + 382 [0x13157e]
19 _thread_block + 33 [0x1368fe]
19 _thread_continue + 1181 [0x136691]
7) As the IOUSBController instance has deadlocked, but is responsible
for handling the communication for all other devices connected to the
same port, all other devices connected to the same port will no longer
appear to work, as data is neither handed to them nor polled from them.
8) As Santa Rosa MacBook Pros internally connect keyboard, trackpad
and built-in IR receiver to the same USB port, unfortunate timing can
lead to the ResetDevice() (in user space) and ClearStall() (on
IOUSBPipe, in kernel space) calls to deadlock the IOUSBController
instance handling all three devices. That's also, why all other USB
ports will continue to work.
Said simply, any application that uses the quite common and widely
used approach of accessing a USB device from user space and that makes
a call to ResetDevice() on the IOUSBDevice can potentially deadlock
the IOUSBController handling the port of the USB device - consequently
disabling all I/O handling for all other devices connected to the same
USB port.
So, if you are using Remote Buddy on a Santa Rosa MacBook Pro under
Leopard, your keyboard and trackpad may loose connection after a
(deep) sleep. I would like to underline, though, that the bug leading
to this actually sits in Apple's IOUSBFamily.kext and not Remote Buddy
or its kernel extension. That you see that problem only after
installing Remote Buddy's kernel extension is explained easily:
without it installed, Remote Buddy's own IR Receiver USB driver -
which currently resides entirely in userspace - is not registering for
notifications for the device and thus will also not try to initialize
it using ResetDevice().
That said, Apple has done a lot of (otherwise excellent) work on the
IOUSBFamily in Leopard, so it's not surprising that there are still
bugs left. I'm confident that Apple will fix it with one of the next
OS 10.5.x updates.
While the usage of any other apps that access USB devices from
userspace might still give you problems until Apple fixes the bug,
Remote Buddy's next version will feature a completely new set of
drivers that - among other things - also elegantly works around the bug.
As a temporary fix until the release of the next Remote Buddy update
(and updates to any other apps accessing USB HID devices), you may
want to disable safe sleep.
Best regards,
Felix