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:
Marcus Overhagen
2006-04-13 14:57:16 +00:00
parent fb072d3724
commit 45d3c4ec14
5 changed files with 40 additions and 24 deletions
@@ -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);
}
+20 -13
View File
@@ -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;