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 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user