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 ctrl;
uint8 data; uint8 data;
bool error;
ps2_dev *dev; ps2_dev *dev;
ctrl = ps2_read_ctrl(); ctrl = ps2_read_ctrl();
@@ -259,18 +260,30 @@ ps2_interrupt(void* cookie)
uint8 idx; uint8 idx;
if (gActiveMultiplexingEnabled) { if (gActiveMultiplexingEnabled) {
idx = ctrl >> 6; idx = ctrl >> 6;
error = (ctrl & 0x04) != 0;
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (mouse %d)\n", ctrl, data, idx)); TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (mouse %d)\n", ctrl, data, idx));
} else { } else {
idx = 0; idx = 0;
error = (ctrl & 0xC0) != 0;
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (aux)\n", ctrl, data)); TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (aux)\n", ctrl, data));
} }
dev = &ps2_device[PS2_DEVICE_MOUSE + idx]; dev = &ps2_device[PS2_DEVICE_MOUSE + idx];
} else { } else {
TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl, data)); TRACE(("ps2_interrupt: ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl, data));
dev = &ps2_device[PS2_DEVICE_KEYB]; 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 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; uint32 flags;
flags = atomic_get(&dev->flags); flags = atomic_get(&dev->flags);
@@ -142,27 +143,33 @@ ps2_dev_handle_int(ps2_dev *dev, uint8 data)
pass_to_handler: 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) { if (!dev->active) {
ps2_service_notify_device_added(dev);
dprintf("ps2: %s not active, data 0x%02x dropped\n", dev->name, data); 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; return B_HANDLED_INTERRUPT;
} }
if ((flags & PS2_FLAG_ENABLED) == 0) { if ((flags & PS2_FLAG_ENABLED) == 0) {
dprintf("ps2: %s not enabled, data 0x%02x dropped\n", dev->name, data); 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; 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); return dev->handle_int(dev);
} }
@@ -19,6 +19,7 @@ typedef struct
{ {
bigtime_t time; bigtime_t time;
uint8 data; uint8 data;
bool error;
} data_history; } data_history;
struct ps2_dev struct ps2_dev
@@ -32,7 +33,7 @@ struct ps2_dev
int result_buf_idx; int result_buf_idx;
int result_buf_cnt; int result_buf_cnt;
void * cookie; void * cookie;
data_history history[5]; data_history history[2];
// functions // functions
void (*disconnect)(ps2_dev *); 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_publish(ps2_dev *dev);
void ps2_dev_unpublish(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 #endif
@@ -108,14 +108,9 @@ keyboard_handle_int(ps2_dev *dev)
TRACE(("scancode: %x\n", scancode)); 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) { if (scancode & 0x80) {
keyInfo.is_keydown = false; keyInfo.is_keydown = false;
scancode -= 0x80; scancode &= 0x7f;
} else } else
keyInfo.is_keydown = true; keyInfo.is_keydown = true;
@@ -222,8 +222,8 @@ static int32
mouse_handle_int(ps2_dev *dev) mouse_handle_int(ps2_dev *dev)
{ {
mouse_cookie *cookie = dev->cookie; 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)) { if (cookie->packet_index == 0 && !(data & 8)) {
TRACE(("bad mouse data, trying resync\n")); TRACE(("bad mouse data, trying resync\n"));
return B_HANDLED_INTERRUPT; return B_HANDLED_INTERRUPT;