Changed the way how the mouse interrupt handler works.

It will now first assemble a complete packet, and then write 
it into the ring buffer. This way, the last packet can easily
be dropped when the ring buffer is full, and we no longer 
need to flush an old packet from the queue (which could lead
to strange effects when handling the remaining packets in the
queue). Also fixed the bug that the semaphore was released 
despite nothing was written to the ring buffer when it was full.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14475 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2005-10-22 23:51:43 +00:00
parent aeb5fb20a0
commit a21a8b1324
3 changed files with 32 additions and 23 deletions

View File

@ -342,7 +342,7 @@ init_driver(void)
// Probing the mouse first and initializing the keyboard later appearantly
// clears the keyboard stall.
if (probe_mouse() == B_OK)
if (probe_mouse(NULL) == B_OK)
sMouseDetected = true;
else
dprintf("ps2_hid: no mouse detected!\n");

View File

@ -50,7 +50,7 @@ extern status_t ps2_common_initialize(void);
// prototypes from keyboard.c & mouse.c
extern status_t probe_keyboard(void);
extern status_t probe_mouse(void);
extern status_t probe_mouse(size_t *probed_packet_size);
extern status_t keyboard_open(const char *name, uint32 flags, void **cookie);
extern status_t keyboard_close(void *cookie);

View File

@ -70,7 +70,6 @@
// we record that many mouse packets before we start to drop them
static sem_id sMouseSem;
static int32 sSync;
static struct packet_buffer *sMouseBuffer;
static int32 sOpenMask;
@ -79,8 +78,10 @@ static bigtime_t sClickSpeed;
static int32 sClickCount;
static int sButtonsState;
static int32 sPacketSize;
static size_t sPacketSize;
static size_t sPacketIndex;
static uint8 sPacketBuffer[PS2_MAX_PACKET_SIZE];
/** Writes a byte to the mouse device. Uses the control port to indicate
* that the byte is sent to the auxiliary device (mouse), instead of the
@ -206,7 +207,7 @@ ps2_mouse_read(mouse_movement *userMovement)
if (status < B_OK)
return status;
if (packet_buffer_read(sMouseBuffer, packet, sPacketSize) != (ssize_t)sPacketSize) {
if (packet_buffer_read(sMouseBuffer, packet, sPacketSize) != sPacketSize) {
TRACE(("error copying buffer\n"));
return B_ERROR;
}
@ -258,27 +259,31 @@ handle_mouse_interrupt(void* cookie)
}
data = gIsa->read_io_8(PS2_PORT_DATA);
TRACE(("mouse interrupt : byte %x\n", data));
TRACE(("mouse interrupt: %d byte: 0x%02x\n", sPacketIndex, data));
if (sSync == 0 && !(data & 8)) {
TRACE(("mouse resynched, bad data\n"));
if (sPacketIndex == 0 && !(data & 8)) {
TRACE(("bad mouse data, trying resync\n"));
return B_HANDLED_INTERRUPT;
}
while (packet_buffer_write(sMouseBuffer, &data, sizeof(data)) == 0) {
// we start dropping packets when the buffer is full
packet_buffer_flush(sMouseBuffer, sPacketSize);
sPacketBuffer[sPacketIndex++] = data;
if (sPacketIndex != sPacketSize) {
// packet not yet complete
return B_HANDLED_INTERRUPT;
}
if (++sSync == sPacketSize) {
TRACE(("mouse synched\n"));
sSync = 0;
release_sem_etc(sMouseSem, 1, B_DO_NOT_RESCHEDULE);
return B_INVOKE_SCHEDULER;
// complete packet is assembled
sPacketIndex = 0;
if (packet_buffer_write(sMouseBuffer, sPacketBuffer, sPacketSize) != sPacketSize) {
// buffer is full, drop new data
return B_HANDLED_INTERRUPT;
}
return B_HANDLED_INTERRUPT;
release_sem_etc(sMouseSem, 1, B_DO_NOT_RESCHEDULE);
return B_INVOKE_SCHEDULER;
}
@ -286,7 +291,7 @@ handle_mouse_interrupt(void* cookie)
status_t
probe_mouse(void)
probe_mouse(size_t *probed_packet_size)
{
int8 deviceId = -1;
@ -313,11 +318,13 @@ probe_mouse(void)
}
if (deviceId == PS2_DEV_ID_STANDARD) {
sPacketSize = PS2_PACKET_STANDARD;
TRACE(("Standard PS/2 mouse found\n"));
if (probed_packet_size)
*probed_packet_size = PS2_PACKET_STANDARD;
} else if (deviceId == PS2_DEV_ID_INTELLIMOUSE) {
sPacketSize = PS2_PACKET_INTELLIMOUSE;
TRACE(("Extended PS/2 mouse found\n"));
if (probed_packet_size)
*probed_packet_size = PS2_PACKET_INTELLIMOUSE;
} else {
// Something's wrong. Better quit
return B_ERROR;
@ -344,9 +351,11 @@ mouse_open(const char *name, uint32 flags, void **_cookie)
acquire_sem(gDeviceOpenSemaphore);
status = probe_mouse();
status = probe_mouse(&sPacketSize);
if (status != B_OK)
goto err1;
sPacketIndex = 0;
status = ps2_common_initialize();
if (status != B_OK)