// Only one writer at a time.
EnterCriticalSection(&m_csWrite);
// If we are already in, we're done.
if ( m_cEnterWrites++ )
{
goto leave_success;
}
ui8CmdByte = m_ui8CmdByte;
// Disable the interface first. Note that we are changing the local copy
// of the command byte, not the member variable.
ui8CmdByte |= cmdByteDisableKeybdInterface|cmdByteDisableAuxInterface;
// Wait for any data in the pipeline to finish.
// Most of the timings are on the order of 10's of
// microseconds, so 10 milliseconds should be enough.
Sleep(10);
// Read any junk data.
ui8OutputBufRead();
// Now disable the interrupts.
ui8CmdByte &= ~(cmdByteEnableAuxInterrupts|cmdByteEnableKeybdInterrupts);
// Write the command byte directly.
if ( !InputBufPollForEmpty() )
{
ASSERT(0);
goto leave_fail;
}
CommandWrite(cmd8042WriteModeByte);
InputBufPut(ui8CmdByte);
leave_success:
// Keep the critical section if we succeed.
return true;
leave_fail:
// Don't hold the critical section if we fail.
m_cEnterWrites--;
LeaveCriticalSection(&m_csWrite);
return false;
// Haven't really seen this but it's worth checking.
if ( m_cEnterWrites == 0 )
{
ERRORMSG(1,(TEXT("LeaveWrite: too many calls to LeaveWrite.\r\n")));
return bRet;
}
// Last one out turns everything back on.
if ( m_cEnterWrites != 1 )
{
bRet = true;
goto leave;
}
// Write command byte by sending command and writing.
if ( !InputBufPollForEmpty() )
{
ERRORMSG(1,(TEXT("LeaveWrite: too long waiting for input buffer to empty (2).\r\n")));
goto leave;
}
CommandWrite(cmd8042WriteModeByte);
InputBufPut(m_ui8CmdByte);