Implemented hotplug support conforming to the active multiplexing specification.
Works with my notebook, but kernel support for unpublishing devices is broken. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17123 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -242,6 +242,7 @@ ps2_interrupt(void* cookie)
|
||||
{
|
||||
uint8 ctrl;
|
||||
uint8 data;
|
||||
bool error;
|
||||
ps2_dev *dev;
|
||||
|
||||
ctrl = ps2_read_ctrl();
|
||||
@@ -259,18 +260,30 @@ ps2_interrupt(void* cookie)
|
||||
uint8 idx;
|
||||
if (gActiveMultiplexingEnabled) {
|
||||
idx = ctrl >> 6;
|
||||
error = (ctrl & 0x04) != 0;
|
||||
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (mouse %d)\n", ctrl, data, idx));
|
||||
} else {
|
||||
idx = 0;
|
||||
error = (ctrl & 0xC0) != 0;
|
||||
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (aux)\n", ctrl, data));
|
||||
}
|
||||
dev = &ps2_device[PS2_DEVICE_MOUSE + idx];
|
||||
} else {
|
||||
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl, data));
|
||||
dev = &ps2_device[PS2_DEVICE_KEYB];
|
||||
error = (ctrl & 0xC0) != 0;
|
||||
|
||||
// TODO: remove me again; let us drop into the kernel debugger with F12
|
||||
if (data == 88)
|
||||
panic("keyboard requested halt.\n");
|
||||
}
|
||||
|
||||
return ps2_dev_handle_int(dev, data);
|
||||
dev->history[1] = dev->history[0];
|
||||
dev->history[0].time = system_time();
|
||||
dev->history[0].data = data;
|
||||
dev->history[0].error = error;
|
||||
|
||||
return ps2_dev_handle_int(dev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,8 +90,9 @@ ps2_dev_unpublish(ps2_dev *dev)
|
||||
|
||||
|
||||
int32
|
||||
ps2_dev_handle_int(ps2_dev *dev, uint8 data)
|
||||
ps2_dev_handle_int(ps2_dev *dev)
|
||||
{
|
||||
const uint8 data = dev->history[0].data;
|
||||
uint32 flags;
|
||||
|
||||
flags = atomic_get(&dev->flags);
|
||||
@@ -142,27 +143,33 @@ ps2_dev_handle_int(ps2_dev *dev, uint8 data)
|
||||
|
||||
pass_to_handler:
|
||||
|
||||
if ((flags & PS2_FLAG_KEYB) == 0) {
|
||||
if (dev->history[0].error && data == 0xfd) {
|
||||
dprintf("ps2: hot removal of %s\n", dev->name);
|
||||
ps2_service_notify_device_removed(dev);
|
||||
return B_INVOKE_SCHEDULER;
|
||||
}
|
||||
if (data == 0x00 && dev->history[1].data == 0xaa && (dev->history[0].time - dev->history[1].time) < 50000) {
|
||||
dprintf("ps2: hot plugin of %s\n", dev->name);
|
||||
ps2_service_notify_device_added(dev);
|
||||
return B_INVOKE_SCHEDULER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev->active) {
|
||||
ps2_service_notify_device_added(dev);
|
||||
dprintf("ps2: %s not active, data 0x%02x dropped\n", dev->name, data);
|
||||
if (data != 0x00 && data != 0xaa) {
|
||||
dprintf("ps2: possibly a hot plugin of %s\n", dev->name);
|
||||
ps2_service_notify_device_added(dev);
|
||||
return B_INVOKE_SCHEDULER;
|
||||
}
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
if ((flags & PS2_FLAG_ENABLED) == 0) {
|
||||
dprintf("ps2: %s not enabled, data 0x%02x dropped\n", dev->name, data);
|
||||
// TODO: remove me again; let us drop into the kernel debugger with F12
|
||||
if ((flags & PS2_FLAG_KEYB) != 0 && data == 88)
|
||||
panic("keyboard requested halt.\n");
|
||||
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
dev->history[4] = dev->history[3];
|
||||
dev->history[3] = dev->history[2];
|
||||
dev->history[2] = dev->history[1];
|
||||
dev->history[1] = dev->history[0];
|
||||
dev->history[0].time = system_time();
|
||||
dev->history[0].data = data;
|
||||
|
||||
return dev->handle_int(dev);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ typedef struct
|
||||
{
|
||||
bigtime_t time;
|
||||
uint8 data;
|
||||
bool error;
|
||||
} data_history;
|
||||
|
||||
struct ps2_dev
|
||||
@@ -32,7 +33,7 @@ struct ps2_dev
|
||||
int result_buf_idx;
|
||||
int result_buf_cnt;
|
||||
void * cookie;
|
||||
data_history history[5];
|
||||
data_history history[2];
|
||||
|
||||
// functions
|
||||
void (*disconnect)(ps2_dev *);
|
||||
@@ -63,6 +64,6 @@ status_t ps2_dev_command(ps2_dev *dev, uint8 cmd, const uint8 *out, int out_coun
|
||||
void ps2_dev_publish(ps2_dev *dev);
|
||||
void ps2_dev_unpublish(ps2_dev *dev);
|
||||
|
||||
int32 ps2_dev_handle_int(ps2_dev *dev, uint8 data);
|
||||
int32 ps2_dev_handle_int(ps2_dev *dev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -108,14 +108,9 @@ keyboard_handle_int(ps2_dev *dev)
|
||||
|
||||
TRACE(("scancode: %x\n", scancode));
|
||||
|
||||
// For now, F12 enters the kernel debugger
|
||||
// ToDo: remove me later :-)
|
||||
if (scancode == 88)
|
||||
panic("keyboard requested halt.\n");
|
||||
|
||||
if (scancode & 0x80) {
|
||||
keyInfo.is_keydown = false;
|
||||
scancode -= 0x80;
|
||||
scancode &= 0x7f;
|
||||
} else
|
||||
keyInfo.is_keydown = true;
|
||||
|
||||
|
||||
@@ -222,8 +222,8 @@ static int32
|
||||
mouse_handle_int(ps2_dev *dev)
|
||||
{
|
||||
mouse_cookie *cookie = dev->cookie;
|
||||
uint8 data = dev->history[0].data;
|
||||
|
||||
const uint8 data = dev->history[0].data;
|
||||
|
||||
if (cookie->packet_index == 0 && !(data & 8)) {
|
||||
TRACE(("bad mouse data, trying resync\n"));
|
||||
return B_HANDLED_INTERRUPT;
|
||||
|
||||
Reference in New Issue
Block a user