21#include "pedigree/kernel/machine/InputManager.h"
22#include "pedigree/kernel/process/Thread.h"
23#include "pedigree/kernel/processor/Processor.h"
24#include "pedigree/kernel/processor/ProcessorInformation.h"
25#include "pedigree/kernel/time/Time.h"
26#include "pedigree/kernel/utilities/new"
28#include "system/kernel/machine/mach_pc/Ps2Controller.h"
32Ps2Mouse::Ps2Mouse(
Device* pDev)
33 : m_pController(0), m_PacketDecoder(), m_IrqWait(0), m_ReaderThread(), m_Callbacks() {
34 setSpecificType(
String(
"ps2-mouse"));
37Ps2Mouse::~Ps2Mouse() {
38 m_ReaderThread.stop();
44 m_pController = pController;
51 const uint8_t commands[] = {SetDefaults, MouseStream};
52 for (uint8_t command : commands) {
53 bool acknowledged =
false;
54 for (
size_t retry = 0; retry < 3 && !acknowledged; ++retry) {
57 bool received =
false;
58 for (
size_t poll = 0; poll < 250 && !m_pController->
readsStopping(); ++poll) {
63 Time::delay(Time::Multiplier::Millisecond);
65 acknowledged = received && response == MouseAck;
66 if (!received || (response != MouseAck && response != 0xfe))
71 WARNING(
"PS/2 mouse did not acknowledge command " <<
Hex << command);
77 Thread* pThread =
new Thread(pProcess, readerThreadTrampoline,
this);
78 pThread->setName(
"PS/2 mouse reader");
79 m_ReaderThread.adopt(pThread);
84void Ps2Mouse::write(
const char* bytes,
size_t len) {
85 for (
size_t i = 0; i < len; ++i) {
90bool Ps2Mouse::subscribe(MouseHandlerFunction handler,
void* param, Registration& registration) {
91 return m_Callbacks.subscribe(handler, param, registration);
94void Ps2Mouse::updateSubscribers(
const void* buffer,
size_t len) {
95 m_Callbacks.dispatch(buffer, len);
98int Ps2Mouse::readerThreadTrampoline(
void* param) {
100 instance->readerThread();
104void Ps2Mouse::readerThread() {
116 updateSubscribers(&
byte, 1);
119 if (m_PacketDecoder.
feed(
byte, packet)) {
static ProcessorInformation & information()
EXPORTED_PUBLIC bool readsStopping() const
Reports that buffered readers must leave their long-lived loops.
EXPORTED_PUBLIC void writeSecondPort(uint8_t byte)
Send a byte to the second port, dropping it on timeout.
EXPORTED_PUBLIC bool hasSecondPort() const
Reports whether this PS/2 controller has two ports.
EXPORTED_PUBLIC void setIrqEnable(bool firstEnabled, bool secondEnabled)
Enables/disables IRQs for the first or second ports.
EXPORTED_PUBLIC bool readSecondPort(uint8_t &byte, bool block=true)
Reads a single byte from the second port.
bool feed(uint8_t byte, Ps2MousePacket &packet)
@ Continue
No unwind necessary, carry on as normal.
UnwindType getUnwindState()