]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Drivers/platform/drvApplePS2Controller/ApplePS2Controller.cpp
xnu-201.tar.gz
[apple/xnu.git] / iokit / Drivers / platform / drvApplePS2Controller / ApplePS2Controller.cpp
diff --git a/iokit/Drivers/platform/drvApplePS2Controller/ApplePS2Controller.cpp b/iokit/Drivers/platform/drvApplePS2Controller/ApplePS2Controller.cpp
deleted file mode 100644 (file)
index f73ced1..0000000
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <IOKit/assert.h>
-#include <IOKit/IOService.h>
-#include <IOKit/IOSyncer.h>
-#include <IOKit/IOCommandQueue.h>
-#include <IOKit/ps2/ApplePS2KeyboardDevice.h>
-#include <IOKit/ps2/ApplePS2MouseDevice.h>
-#include "ApplePS2Controller.h"
-
-extern "C"
-{
-    #include <architecture/i386/pio.h>
-    #include <machine/machine_routines.h>
-}
-
-static ApplePS2Controller * gApplePS2Controller = 0;  // global variable to self
-
-// =============================================================================
-// Interrupt-Time Support Functions
-//
-
-static void interruptHandlerMouse(OSObject *, void *, IOService *, int)
-{
-  //
-  // Wake our workloop to service the interrupt.    This is an edge-triggered
-  // interrupt, so returning from this routine without clearing the interrupt
-  // condition is perfectly normal.
-  //
-
-  gApplePS2Controller->_interruptSourceMouse->interruptOccurred(0, 0, 0);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-static void interruptHandlerKeyboard(OSObject *, void *, IOService *, int)
-{
-#if DEBUGGER_SUPPORT
-  //
-  // The keyboard interrupt handler reads in the pending scan code and stores
-  // it on our internal queue; should it completes a debugger escape sequence,
-  // we jump to the debugger function immediately.
-  //
-
-  UInt8 key;
-  UInt8 status;
-
-  // Lock out the keyboard interrupt handler [redundant here] and claim
-  // exclusive access to the internal keyboard queue.
-
-  gApplePS2Controller->lockController();
-
-  // Verify that data is available on the controller's input port.
-
-  if ( ((status = inb(kCommandPort)) & kOutputReady) )
-  {
-    // Verify that the data is keyboard data, otherwise call mouse handler.
-    // This case should never really happen, but if it does, we handle it.
-
-    if ( (status & kMouseData) )
-    {
-      interruptHandlerMouse(0, 0, 0, 0);
-    }
-    else
-    {
-      // Retrieve the keyboard data on the controller's input port.
-
-      key = inb(kDataPort);
-
-      // Call the debugger-key-sequence checking code (if a debugger sequence
-      // completes, the debugger function will be invoked immediately within
-      // doEscape).  The doEscape call may insist that we drop the scan code
-      // we just received in some cases (a true return) -- we don't question
-      // it's judgement and comply.
-
-      if (gApplePS2Controller->doEscape(key) == false)
-        gApplePS2Controller->enqueueKeyboardData(key);
-
-      // In all cases, we wake up our workloop to service the interrupt data.
-      gApplePS2Controller->_interruptSourceKeyboard->interruptOccurred(0, 0, 0);
-    }
-  }
-
-  // Remove the lockout on the keyboard interrupt handler [ineffective here]
-  // and release our exclusive access to the internal keyboard queue.
-
-  gApplePS2Controller->unlockController();
-#else
-  //
-  // Wake our workloop to service the interrupt.    This is an edge-triggered
-  // interrupt, so returning from this routine without clearing the interrupt
-  // condition is perfectly normal.
-  //
-
-    gApplePS2Controller->_interruptSourceKeyboard->interruptOccurred(0, 0, 0);
-
-#endif DEBUGGER_SUPPORT
-}
-
-// =============================================================================
-// ApplePS2Controller Class Implementation
-//
-
-#define super IOService
-OSDefineMetaClassAndStructors(ApplePS2Controller, IOService);
-
-bool ApplePS2Controller::init(OSDictionary * properties)
-{
-  if (!super::init(properties))  return false;
-
-  //
-  // Initialize minimal state.
-  //
-
-  _commandQueue            = 0;
-  _workLoop                = 0;
-
-  _interruptSourceKeyboard = 0;
-  _interruptSourceMouse    = 0;
-
-  _interruptTargetKeyboard = 0;
-  _interruptTargetMouse    = 0;
-
-  _interruptActionKeyboard = NULL;
-  _interruptActionMouse    = NULL;
-
-  _interruptInstalledKeyboard = false;
-  _interruptInstalledMouse    = false;
-
-  _mouseDevice    = 0;
-  _keyboardDevice = 0;
-
-#if DEBUGGER_SUPPORT
-  _extendedState = false;
-  _modifierState = 0x00;
-
-  _keyboardQueueAlloc = NULL;
-  queue_init(&_keyboardQueue);
-  queue_init(&_keyboardQueueUnused);
-
-  _controllerLockOldSpl = 0;
-  usimple_lock_init(&_controllerLock, ETAP_NO_TRACE);
-#endif DEBUGGER_SUPPORT
-
-  return true;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool ApplePS2Controller::start(IOService * provider)
-{
-  //
-  // The driver has been instructed to start.  Allocate all our resources.
-  //
-
-  if (!super::start(provider))  return false;
-
-#if DEBUGGER_SUPPORT
-  _keyboardQueueAlloc = (KeyboardQueueElement *)
-                      IOMalloc(kKeyboardQueueSize*sizeof(KeyboardQueueElement));
-  if (!_keyboardQueueAlloc)  return false;
-
-  // Add the allocated keyboard queue entries to "unused" queue.
-  for (int index = 0; index < kKeyboardQueueSize; index++)
-    queue_enter(&_keyboardQueueUnused, &_keyboardQueueAlloc[index],
-                KeyboardQueueElement *, chain);
-#endif DEBUGGER_SUPPORT
-
-  //
-  // Initialize the mouse and keyboard hardware to a known state --  the IRQs
-  // are disabled (don't want interrupts), the clock line is enabled (want to
-  // be able to send commands), and the device itself is disabled (don't want
-  // asynchronous data arrival for key/mouse events).  We call the read/write
-  // port routines directly, since no other thread will conflict with us.
-  //
-
-  UInt8 commandByte;
-  writeCommandPort(kCP_GetCommandByte);
-  commandByte  =  readDataPort(kDT_Keyboard);
-  commandByte &= ~(kCB_EnableMouseIRQ | kCB_DisableMouseClock);
-  writeCommandPort(kCP_SetCommandByte);
-  writeDataPort(commandByte);
-
-  writeDataPort(kDP_SetDefaultsAndDisable);
-  readDataPort(kDT_Keyboard);       // (discard acknowledge; success irrelevant)
-
-  writeCommandPort(kCP_TransmitToMouse);
-  writeDataPort(kDP_SetDefaultsAndDisable);
-  readDataPort(kDT_Mouse);          // (discard acknowledge; success irrelevant)
-
-  //
-  // Clear out garbage in the controller's input streams, before starting up
-  // the work loop.
-  //
-
-  while ( inb(kCommandPort) & kOutputReady )
-  {
-    inb(kDataPort);
-    IODelay(kDataDelay);
-  }
-
-  //
-  // Initialize our work loop, our command queue, and our interrupt event
-  // sources.  The work loop can accept requests after this step.
-  //
-
-  _workLoop                = IOWorkLoop::workLoop();
-  _commandQueue            = IOCommandQueue::commandQueue(
-        this, (IOCommandQueueAction) &ApplePS2Controller::processRequest);
-  _interruptSourceMouse    = IOInterruptEventSource::interruptEventSource(
-        this, (IOInterruptEventAction) &ApplePS2Controller::interruptOccurred);
-  _interruptSourceKeyboard = IOInterruptEventSource::interruptEventSource(
-        this, (IOInterruptEventAction) &ApplePS2Controller::interruptOccurred);
-
-  if ( !_workLoop                ||
-       !_commandQueue            ||
-       !_interruptSourceMouse    ||
-       !_interruptSourceKeyboard )  return false;
-
-  if ( _workLoop->addEventSource(_commandQueue) != kIOReturnSuccess )
-    return false;
-
-  //
-  // Create the keyboard nub and the mouse nub. The keyboard and mouse drivers
-  // will query these nubs to determine the existence of the keyboard or mouse,
-  // and should they exist, will attach themselves to the nub as clients.
-  //
-
-  _keyboardDevice = new ApplePS2KeyboardDevice;
-
-  if ( !_keyboardDevice               ||
-       !_keyboardDevice->init()       ||
-       !_keyboardDevice->attach(this) )  return false;
-
-  _mouseDevice = new ApplePS2MouseDevice;
-
-  if ( !_mouseDevice               ||
-       !_mouseDevice->init()       ||
-       !_mouseDevice->attach(this) )  return false;
-
-  gApplePS2Controller = this;
-
-  _keyboardDevice->registerService();
-  _mouseDevice->registerService();
-
-  return true; // success
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::stop(IOService * provider)
-{
-  //
-  // The driver has been instructed to stop.  Note that we must break all
-  // connections to other service objects now (ie. no registered actions,
-  // no pointers and retains to objects, etc), if any.
-  //
-
-  // Ensure that the interrupt handlers have been uninstalled (ie. no clients).
-  assert(_interruptInstalledKeyboard == false);
-  assert(_interruptInstalledMouse    == false);
-
-  // Free the nubs we created.
-  if (_keyboardDevice)  _keyboardDevice->release();
-  if (_mouseDevice)     _mouseDevice->release();
-
-  // Free the work loop.
-  if (_workLoop)  _workLoop->release();
-
-  // Free the interrupt source and command queue.
-  if (_commandQueue)             _commandQueue->release();
-  if (_interruptSourceKeyboard)  _interruptSourceKeyboard->release();
-  if (_interruptSourceMouse)     _interruptSourceMouse->release();
-
-#if DEBUGGER_SUPPORT
-  // Free the keyboard queue allocation space (after disabling interrupt).
-  if (_keyboardQueueAlloc)
-    IOFree(_keyboardQueueAlloc,kKeyboardQueueSize*sizeof(KeyboardQueueElement));
-#endif DEBUGGER_SUPPORT
-
-  gApplePS2Controller = 0;
-
-  super::stop(provider);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-IOWorkLoop * ApplePS2Controller::getWorkLoop() const
-{
-    return _workLoop;
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::installInterruptAction(PS2DeviceType      deviceType,
-                                                OSObject *         target, 
-                                                PS2InterruptAction action)
-{
-  //
-  // Install the keyboard or mouse interrupt handler.
-  //
-  // This method assumes only one possible mouse and only one possible
-  // keyboard client (ie. callers), and assumes two distinct interrupt
-  // handlers for each, hence needs no protection against races.
-  //
-
-  // Is it the keyboard or the mouse interrupt handler that was requested?
-  // We only install it if it is currently uninstalled.
-
-  if (deviceType == kDT_Keyboard && _interruptInstalledKeyboard == false)
-  {
-    target->retain();
-    _interruptTargetKeyboard = target;
-    _interruptActionKeyboard = action;
-    _workLoop->addEventSource(_interruptSourceKeyboard);
-    getProvider()->registerInterrupt(kIRQ_Keyboard,0, interruptHandlerKeyboard);
-    getProvider()->enableInterrupt(kIRQ_Keyboard);
-    _interruptInstalledKeyboard = true;
-  }
-
-  else if (deviceType == kDT_Mouse && _interruptInstalledMouse == false)
-  {
-    target->retain();
-    _interruptTargetMouse = target;
-    _interruptActionMouse = action;
-    _workLoop->addEventSource(_interruptSourceMouse);
-    getProvider()->registerInterrupt(kIRQ_Mouse, 0, interruptHandlerMouse);
-    getProvider()->enableInterrupt(kIRQ_Mouse);
-    _interruptInstalledMouse = true;
-  }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::uninstallInterruptAction(PS2DeviceType deviceType)
-{
-  //
-  // Uninstall the keyboard or mouse interrupt handler.
-  //
-  // This method assumes only one possible mouse and only one possible
-  // keyboard client (ie. callers), and assumes two distinct interrupt
-  // handlers for each, hence needs no protection against races.
-  //
-
-  // Is it the keyboard or the mouse interrupt handler that was requested?
-  // We only install it if it is currently uninstalled.
-
-  if (deviceType == kDT_Keyboard && _interruptInstalledKeyboard == true)
-  {
-    getProvider()->disableInterrupt(kIRQ_Keyboard);
-    getProvider()->unregisterInterrupt(kIRQ_Keyboard);
-    _workLoop->removeEventSource(_interruptSourceMouse);
-    _interruptInstalledKeyboard = false;
-    _interruptActionKeyboard = NULL;
-    _interruptTargetKeyboard->release();
-    _interruptTargetKeyboard = 0;
-  }
-
-  else if (deviceType == kDT_Mouse && _interruptInstalledMouse == true)
-  {
-    getProvider()->disableInterrupt(kIRQ_Mouse);
-    getProvider()->unregisterInterrupt(kIRQ_Mouse);
-    _workLoop->removeEventSource(_interruptSourceMouse);
-    _interruptInstalledMouse = false;
-    _interruptActionMouse = NULL;
-    _interruptTargetMouse->release();
-    _interruptTargetMouse = 0;
-  }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-PS2Request * ApplePS2Controller::allocateRequest()
-{
-  //
-  // Allocate a request structure.  Blocks until successful.  Request structure
-  // is guaranteed to be zeroed.
-  //
-
-  PS2Request * request = (PS2Request *) IOMalloc(sizeof(PS2Request));
-  bzero(request, sizeof(PS2Request));
-  return request; 
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::freeRequest(PS2Request * request)
-{
-  //
-  // Deallocate a request structure.
-  //
-
-  IOFree(request, sizeof(PS2Request));
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-bool ApplePS2Controller::submitRequest(PS2Request * request)
-{
-  //
-  // Submit the request to the controller for processing, asynchronously.
-  //
-
-  return (_commandQueue->enqueueCommand(false, request) == KERN_SUCCESS);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::submitRequestAndBlock(PS2Request * request)
-{
-  //
-  // Submit the request to the controller for processing, synchronously.
-  //
-
-  IOSyncer * completionSyncer = IOSyncer::create();
-
-  assert(completionSyncer);
-  request->completionTarget = this;
-  request->completionAction = submitRequestAndBlockCompletion;
-  request->completionParam  = completionSyncer;
-
-  _commandQueue->enqueueCommand(true, request);
-
-  completionSyncer->wait();                               // wait 'till done
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::submitRequestAndBlockCompletion(void *, void * param)
-{                                                      // PS2CompletionAction
-  IOSyncer * completionSyncer = (IOSyncer *) param;
-  completionSyncer->signal();
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::interruptOccurred(IOInterruptEventSource *, int)
-{                                                      // IOInterruptEventAction
-  //
-  // Our work loop has informed us of an interrupt, that is, asynchronous
-  // data has arrived on our input stream.  Read the data and dispatch it
-  // to the appropriate driver.
-  //
-  // This method should only be called from our single-threaded work loop.
-  //
-
-  UInt8 status;
-
-#if DEBUGGER_SUPPORT
-  lockController();                  // (lock out interrupt + access to queue)
-  while (1)
-  {
-    // See if data is available on the keyboard input stream (off queue);
-    // we do not read keyboard data from the real data port if it should
-    // be available. 
-
-    if (dequeueKeyboardData(&status))
-    {
-      unlockController();
-      dispatchDriverInterrupt(kDT_Keyboard, status);
-      lockController();
-    }
-
-    // See if data is available on the mouse input stream (off real port).
-
-    else if ( (inb(kCommandPort) & (kOutputReady | kMouseData)) ==
-                                   (kOutputReady | kMouseData))
-    {
-      unlockController();
-      dispatchDriverInterrupt(kDT_Mouse, inb(kDataPort));
-      lockController();
-    }
-    else break; // out of loop
-  }
-  unlockController();         // (release interrupt lockout + access to queue)
-#else
-  // Loop only while there is data currently on the input stream.
-
-  while ( ((status = inb(kCommandPort)) & kOutputReady) )
-  {
-    // Read in and dispatch the data, but only if it isn't what is required
-    // by the active command.
-
-    dispatchDriverInterrupt((status&kMouseData)?kDT_Mouse:kDT_Keyboard,
-                            inb(kDataPort));
-  }
-#endif DEBUGGER_SUPPORT
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::dispatchDriverInterrupt(PS2DeviceType deviceType,
-                                                 UInt8         data)
-{
-  //
-  // The supplied data is passed onto the interrupt handler in the appropriate
-  // driver, if one is registered, otherwise the data byte is thrown away.
-  //
-  // This method should only be called from our single-threaded work loop.
-  //
-
-  if ( deviceType == kDT_Mouse )
-  {
-    // Dispatch the data to the mouse driver.
-    if (_interruptInstalledMouse)
-      (*_interruptActionMouse)(_interruptTargetMouse, data);
-  }
-  else if ( deviceType == kDT_Keyboard )
-  {
-    // Dispatch the data to the keyboard driver.
-    if (_interruptInstalledKeyboard)       
-      (*_interruptActionKeyboard)(_interruptTargetKeyboard, data);
-  }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::processRequest(PS2Request * request,
-                                        void *       /* field1 */,
-                                        void *       /* field2 */,
-                                        void *       /* field3 */)
-                                                         // IOCommandQueueAction
-{
-  //
-  // Our work loop has informed us of a request submission. Process
-  // the request.  Note that this code "figures out" when the mouse
-  // input stream should be read over the keyboard input stream.
-  //
-  // This method should only be called from our single-threaded work loop.
-  //
-
-  UInt8         byte;
-  PS2DeviceType deviceMode      = kDT_Keyboard;
-  bool          failed          = false;
-  bool          transmitToMouse = false;
-  unsigned      index;
-
-  // Process each of the commands in the list.
-
-  for (index = 0; index < request->commandsCount; index++)
-  {
-    switch (request->commands[index].command)
-    {
-      case kPS2C_ReadDataPort:
-        request->commands[index].inOrOut = readDataPort(deviceMode);
-        break;
-
-      case kPS2C_ReadDataPortAndCompare:
-#if OUT_OF_ORDER_DATA_CORRECTION_FEATURE
-        byte = readDataPort(deviceMode, request->commands[index].inOrOut);
-#else 
-        byte = readDataPort(deviceMode);
-#endif
-        failed = (byte != request->commands[index].inOrOut);
-        break;
-
-      case kPS2C_WriteDataPort:
-        writeDataPort(request->commands[index].inOrOut);
-        if (transmitToMouse)     // next reads from mouse input stream
-        {
-          deviceMode      = kDT_Mouse;
-          transmitToMouse = false;
-        }
-        else
-        {
-           deviceMode   = kDT_Keyboard;
-        }
-        break;
-
-      case kPS2C_WriteCommandPort:
-        writeCommandPort(request->commands[index].inOrOut);
-        if (request->commands[index].inOrOut == kCP_TransmitToMouse)
-          transmitToMouse = true; // preparing to transmit data to mouse
-        break;
-    }
-
-    if (failed) break;
-  }
-
-  // If a command failed and stopped the request processing, store its
-  // index into the commandsCount field.
-
-  if (failed) request->commandsCount = index;
-
-  // Invoke the completion routine, if one was supplied.
-
-  if (request->completionTarget && request->completionAction)
-  {
-    (*request->completionAction)(request->completionTarget,
-                                 request->completionParam);
-  }
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-UInt8 ApplePS2Controller::readDataPort(PS2DeviceType deviceType)
-{
-  //
-  // Blocks until keyboard or mouse data is available from the controller
-  // and returns that data. Note, if mouse data is requested but keyboard
-  // data is what is available,  the data is delivered to the appropriate
-  // driver interrupt routine immediately (effectively, the request is
-  // "preempted" temporarily).
-  //
-  // There is a built-in timeout for this command of (timeoutCounter X
-  // kDataDelay) microseconds, approximately. 
-  //
-  // This method should only be called from our single-threaded work loop.
-  //
-
-  UInt8  readByte;
-  UInt8  status;
-  UInt32 timeoutCounter = 10000;    // (timeoutCounter * kDataDelay = 70 ms)
-
-  while (1)
-  {
-#if DEBUGGER_SUPPORT
-    lockController();              // (lock out interrupt + access to queue)
-    if (deviceType == kDT_Keyboard && dequeueKeyboardData(&readByte))
-    {
-      unlockController();
-      return readByte;
-    }
-#endif DEBUGGER_SUPPORT
-
-    //
-    // Wait for the controller's output buffer to become ready.
-    //
-
-    while (timeoutCounter && !((status = inb(kCommandPort)) & kOutputReady))
-    {
-      timeoutCounter--;
-      IODelay(kDataDelay);
-    }
-
-    //
-    // If we timed out, something went awfully wrong; return a fake value.
-    //
-
-    if (timeoutCounter == 0)
-    {
-#if DEBUGGER_SUPPORT
-      unlockController();    // (release interrupt lockout + access to queue)
-#endif DEBUGGER_SUPPORT
-
-      IOLog("%s: Timed out on %s input stream.\n", getName(),
-                          (deviceType == kDT_Keyboard) ? "keyboard" : "mouse");
-      return 0;
-    }
-
-    //
-    // Read in the data.  We return the data, however, only if it arrived on
-    // the requested input stream.
-    //
-
-    readByte = inb(kDataPort);
-
-#if DEBUGGER_SUPPORT
-    unlockController();      // (release interrupt lockout + access to queue)
-#endif DEBUGGER_SUPPORT
-
-    if ( (status & kMouseData) )
-    {
-      if (deviceType == kDT_Mouse)  return readByte;
-    }
-    else
-    {
-      if (deviceType == kDT_Keyboard)  return readByte;
-    }
-
-    //
-    // The data we just received is for the other input stream, not the one
-    // that was requested, so dispatch other device's interrupt handler.
-    //
-
-    dispatchDriverInterrupt((deviceType==kDT_Keyboard)?kDT_Mouse:kDT_Keyboard,
-                            readByte);
-  } // while (forever)
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-#if OUT_OF_ORDER_DATA_CORRECTION_FEATURE
-
-UInt8 ApplePS2Controller::readDataPort(PS2DeviceType deviceType,
-                                       UInt8         expectedByte)
-{
-  //
-  // Blocks until keyboard or mouse data is available from the controller
-  // and returns that data. Note, if mouse data is requested but keyboard
-  // data is what is available,  the data is delivered to the appropriate
-  // driver interrupt routine immediately (effectively, the request is
-  // "preempted" temporarily).
-  //
-  // There is a built-in timeout for this command of (timeoutCounter X
-  // kDataDelay) microseconds, approximately. 
-  //
-  // This method should only be called from our single-threaded work loop.
-  //
-  // This version of readDataPort does exactly the same as the original,
-  // except that if the value that should be read from the (appropriate)
-  // input stream is not what is expected, we make these assumptions:
-  //
-  // (a) the data byte we did get was  "asynchronous" data being sent by
-  //     the device, which has not figured out that it has to respond to
-  //     the command we just sent to it.
-  // (b) that the real  "expected" response will be the next byte in the
-  //     stream;   so what we do is put aside the first byte we read and
-  //     wait for the next byte; if it's the expected value, we dispatch
-  //     the first byte we read to the driver's interrupt handler,  then
-  //     return the expected byte. The caller will have never known that
-  //     asynchronous data arrived at a very bad time.
-  // (c) that the real "expected" response will arrive within (kDataDelay
-  //     X timeoutCounter) microseconds from the time the call is made.
-  //
-
-  UInt8  firstByte     = 0;
-  bool   firstByteHeld = false;
-  UInt8  readByte;
-  bool   requestedStream;
-  UInt8  status;
-  UInt32 timeoutCounter = 10000;    // (timeoutCounter * kDataDelay = 70 ms)
-
-  while (1)
-  {
-#if DEBUGGER_SUPPORT
-    lockController();              // (lock out interrupt + access to queue)
-    if (deviceType == kDT_Keyboard && dequeueKeyboardData(&readByte))
-    {
-      requestedStream = true;
-      goto skipForwardToY;
-    }
-#endif DEBUGGER_SUPPORT
-
-    //
-    // Wait for the controller's output buffer to become ready.
-    //
-
-    while (timeoutCounter && !((status = inb(kCommandPort)) & kOutputReady))
-    {
-      timeoutCounter--;
-      IODelay(kDataDelay);
-    }
-
-    //
-    // If we timed out, we return the first byte we read, unless THIS IS the
-    // first byte we are trying to read,  then something went awfully wrong
-    // and we return a fake value rather than lock up the controller longer.
-    //
-
-    if (timeoutCounter == 0)
-    {
-#if DEBUGGER_SUPPORT
-      unlockController();    // release interrupt lockout + access to queue
-#endif DEBUGGER_SUPPORT
-
-      if (firstByteHeld)  return firstByte;
-
-      IOLog("%s: Timed out on %s input stream.\n", getName(),
-                          (deviceType == kDT_Keyboard) ? "keyboard" : "mouse");
-      return 0;
-    }
-
-    //
-    // Read in the data.  We process the data, however, only if it arrived on
-    // the requested input stream.
-    //
-
-    readByte        = inb(kDataPort);
-    requestedStream = false;
-
-    if ( (status & kMouseData) )
-    {
-      if (deviceType == kDT_Mouse)  requestedStream = true;
-    }
-    else
-    {
-      if (deviceType == kDT_Keyboard)  requestedStream = true;
-    }
-
-#if DEBUGGER_SUPPORT
-skipForwardToY:
-    unlockController();      // (release interrupt lockout + access to queue)
-#endif DEBUGGER_SUPPORT
-
-    if (requestedStream)
-    {
-      if (readByte == expectedByte)
-      {
-        if (firstByteHeld == false)
-        {
-          //
-          // Normal case.  Return first byte received.
-          //
-
-          return readByte;
-        }
-        else
-        {
-          //
-          // Our assumption was correct.  The second byte matched.  Dispatch
-          // the first byte to the interrupt handler, and return the second.
-          //
-
-          dispatchDriverInterrupt(deviceType, firstByte);
-          return readByte;
-        }
-      }
-      else // (readByte does not match expectedByte)
-      {
-        if (firstByteHeld == false)
-        {
-          //
-          // The first byte was received, and does not match the byte we are
-          // expecting.  Put it aside for the moment.
-          //
-
-          firstByteHeld = true;
-          firstByte     = readByte;
-        }
-        else if (readByte != expectedByte)
-        {
-          //
-          // The second byte mismatched as well.  I have yet to see this case
-          // occur [Dan], however I do think it's plausible.  No error logged.
-          //
-
-          dispatchDriverInterrupt(deviceType, readByte);
-          return firstByte;
-        }
-      }
-    }
-    else
-    {
-      //
-      // The data we just received is for the other input stream, not ours,
-      // so dispatch appropriate interrupt handler.
-      //
-
-      dispatchDriverInterrupt((deviceType==kDT_Keyboard)?kDT_Mouse:kDT_Keyboard,
-                              readByte);
-    }
-  } // while (forever)
-}
-
-#endif
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::writeDataPort(UInt8 byte)
-{
-  //
-  // Block until room in the controller's input buffer is available, then
-  // write the given byte to the Data Port.
-  //
-  // This method should only be dispatched from our single-threaded work loop.
-  //
-
-  while (inb(kCommandPort) & kInputBusy)  IODelay(kDataDelay);
-  outb(kDataPort, byte);
-}
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-void ApplePS2Controller::writeCommandPort(UInt8 byte)
-{
-  //
-  // Block until room in the controller's input buffer is available, then
-  // write the given byte to the Command Port.
-  //
-  // This method should only be dispatched from our single-threaded work loop.
-  //
-
-  while (inb(kCommandPort) & kInputBusy)  IODelay(kDataDelay);
-  outb(kCommandPort, byte);
-}
-
-// =============================================================================
-// Escape-Key Processing Stuff Localized Here (eg. Mini-Monitor)
-//
-
-#if DEBUGGER_SUPPORT
-
-#define kModifierShiftLeft    0x01
-#define kModifierShiftRight   0x02
-#define kModifierCtrlLeft     0x04
-#define kModifierCtrlRight    0x08
-#define kModifierAltLeft      0x10
-#define kModifierAltRight     0x20
-#define kModifierWindowsLeft  0x40
-#define kModifierWindowsRight 0x80
-
-#define kModifierShiftMask    (kModifierShiftLeft   | kModifierShiftRight  )
-#define kModifierCtrlMask     (kModifierCtrlLeft    | kModifierCtrlRight   )
-#define kModifierAltMask      (kModifierAltLeft     | kModifierAltRight    )
-#define kModifierWindowsMask  (kModifierWindowsLeft | kModifierWindowsRight)
-
-bool ApplePS2Controller::doEscape(UInt8 scancode)
-{
-  static struct
-  {
-    UInt8  scancode;
-    UInt8  extended;
-    UInt16 modifier;
-  } modifierTable[] = { { kSC_Alt,          false, kModifierAltLeft      },
-                         { kSC_Alt,          true,  kModifierAltRight     },
-                         { kSC_Ctrl,         false, kModifierCtrlLeft     },
-                         { kSC_Ctrl,         true,  kModifierCtrlRight    },
-                         { kSC_ShiftLeft,    false, kModifierShiftLeft    },
-                         { kSC_ShiftRight,   false, kModifierShiftRight   },
-                         { kSC_WindowsLeft,  true,  kModifierWindowsLeft  },
-                         { kSC_WindowsRight, true,  kModifierWindowsRight },
-                         { 0,                0,   0                     } };
-
-  UInt32 index;
-  bool   releaseModifiers = false;
-  bool   upBit            = (scancode & kSC_UpBit) ? true : false;
-
-  //
-  // See if this is an extened scancode sequence.
-  //
-
-  if (scancode == kSC_Extend)
-  {
-    _extendedState = true;
-    return false;
-  }
-
-  //
-  // Update the modifier state, if applicable.
-  //
-
-  scancode &= ~kSC_UpBit;
-
-  for (index = 0; modifierTable[index].scancode; index++)
-  {
-    if ( modifierTable[index].scancode == scancode &&
-         modifierTable[index].extended == _extendedState )
-    {
-      if (upBit)  _modifierState &= ~modifierTable[index].modifier;
-      else        _modifierState |=  modifierTable[index].modifier;
-
-      _extendedState = false;
-      return false;
-    }
-  } 
-
-  //
-  // Call the debugger function, if applicable.
-  //
-
-  if (scancode == kSC_Delete)    // (both extended and non-extended scancodes)
-  {
-    if ( _modifierState == kModifierAltLeft ||
-         _modifierState == kModifierAltRight )
-    {
-      // Disable the mouse by forcing the clock line low.
-
-      while (inb(kCommandPort) & kInputBusy)  IODelay(kDataDelay);
-      outb(kCommandPort, kCP_DisableMouseClock);
-
-      // Call the debugger function.
-
-      Debugger("Programmer Key");
-
-      // Re-enable the mouse by making the clock line active.
-
-      while (inb(kCommandPort) & kInputBusy)  IODelay(kDataDelay);
-      outb(kCommandPort, kCP_EnableMouseClock);
-
-      releaseModifiers = true;
-    }
-  }
-
-  //
-  // Release all the modifier keys that were down before the debugger
-  // function was called  (assumption is that they are no longer held
-  // down after the debugger function returns).
-  //
-
-  if (releaseModifiers)
-  {
-    for (index = 0; modifierTable[index].scancode; index++)
-    {
-      if ( _modifierState & modifierTable[index].modifier )
-      {
-        if (modifierTable[index].extended)  enqueueKeyboardData(kSC_Extend);
-        enqueueKeyboardData(modifierTable[index].scancode | kSC_UpBit);
-      }
-    }
-    _modifierState = 0x00;
-  }
-
-  //
-  // Update all other state and return status.
-  //
-
-  _extendedState = false;
-  return (releaseModifiers);
-}
-
-void ApplePS2Controller::enqueueKeyboardData(UInt8 key)
-{
-  //
-  // Enqueue the supplied keyboard data onto our internal queues.  The
-  // controller must already be locked. 
-  //
-
-  KeyboardQueueElement * element;
-
-  // Obtain an unused keyboard data element. 
-  if (!queue_empty(&_keyboardQueueUnused))
-  {
-    queue_remove_first(&_keyboardQueueUnused,
-                       element, KeyboardQueueElement *, chain);
-
-    // Store the new keyboard data element on the queue. 
-    element->data = key; 
-    queue_enter(&_keyboardQueue, element, KeyboardQueueElement *, chain); 
-  }
-}
-
-bool ApplePS2Controller::dequeueKeyboardData(UInt8 * key)
-{
-  //
-  // Dequeue keyboard data from our internal queues, if the queue is not
-  // empty.  Should the queue be empty, false is returned.  The controller
-  // must already be locked. 
-  //
-
-  KeyboardQueueElement * element;
-
-  // Obtain an unused keyboard data element.
-  if (!queue_empty(&_keyboardQueue))
-  {
-    queue_remove_first(&_keyboardQueue, element, KeyboardQueueElement *, chain);
-    *key = element->data;
-
-    // Place the unused keyboard data element onto the unused queue.
-    queue_enter(&_keyboardQueueUnused, element, KeyboardQueueElement *, chain);
-
-    return true;
-  }
-  return false;
-}
-
-void ApplePS2Controller::unlockController(void)
-{
-  usimple_unlock(&_controllerLock); 
-  ml_set_interrupts_enabled(_controllerLockOldSpl);
-}
-
-void ApplePS2Controller::lockController(void)
-{
-  int oldSpl = ml_set_interrupts_enabled(FALSE);
-  usimple_lock(&_controllerLock); 
-  _controllerLockOldSpl = oldSpl;
-}
-
-#endif DEBUGGER_SUPPORT