diff --git a/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.c b/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.c index 968658a56d..e860c6f9bb 100644 --- a/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.c +++ b/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.c @@ -20,8 +20,7 @@ * 3. Data (input/output), mapped to port 60h * Data: * ~~~~ - * Since a mouse is an input only device, data can only be read, and - * not written. A packet read from the mouse data port is composed of + * A packet read from the mouse data port is composed of * three bytes: * byte 0: status byte, where * - bit 0: Y overflow (1 = true) @@ -61,7 +60,7 @@ #define DEVICE_NAME "input/mouse/ps2/0" -#define TRACE_PS2MOUSE +//#define TRACE_PS2MOUSE #ifdef TRACE_PS2MOUSE #define TRACE(x) dprintf x #else @@ -81,12 +80,14 @@ static isa_module_info *sIsa = NULL; static sem_id sMouseSem; static int32 sSync; static cbuf *sMouseChain; +static int32 sOpenMask; static bigtime_t sLastClickTime; static bigtime_t sClickSpeed; static int32 sClickCount; static int sButtonsState; -static int32 sOpenMask; + +static uint32 sPacketSize; ///////////////////////////////////////////////////////////////////////// // ps2 protocol stuff @@ -207,21 +208,20 @@ read_data_byte() ///////////////////////////////////////////////////////////////////////// // mouse functions -/* + static status_t ps2_reset_mouse() { int8 read; TRACE(("ps2_reset_mouse()\n")); - read = read_data_byte(); write_aux_byte(PS2_CMD_RESET_MOUSE); read = read_data_byte(); return B_OK; } -*/ + /** Enables or disables mouse reporting for the ps2 port. @@ -251,7 +251,7 @@ ps2_enable_mouse(bool enable) /** Converts a packet received by the mouse to a "movement". */ static void -packet_to_movement(uint8 packet[], mouse_movement *pos) +standard_packet_to_movement(uint8 packet[], mouse_movement *pos) { int buttons = packet[0] & 7; int xDelta = ((packet[0] & 0x10) ? 0xFFFFFF00 : 0) | packet[1]; @@ -277,8 +277,8 @@ packet_to_movement(uint8 packet[], mouse_movement *pos) pos->clicks = sClickCount; pos->modifiers = 0; pos->timestamp = currentTime; - pos->wheel_ydelta = 0; pos->wheel_xdelta = 0; + pos->wheel_ydelta = 0; } } @@ -289,21 +289,25 @@ static status_t ps2_mouse_read(mouse_movement *pos) { status_t status; - uint8 packet[PS2_PACKET_SIZE]; + uint8 packet[PS2_MAX_PACKET_SIZE]; TRACE(("ps2_mouse_read()\n")); status = acquire_sem_etc(sMouseSem, 1, B_CAN_INTERRUPT, 0); if (status < B_OK) return status; - status = cbuf_memcpy_from_chain(packet, sMouseChain, 0, PS2_PACKET_SIZE); + status = cbuf_memcpy_from_chain(packet, sMouseChain, 0, sPacketSize); if (status < B_OK) { TRACE(("error copying buffer\n")); return status; } - packet_to_movement(packet, pos); - + switch (sPacketSize) { + case PS2_PACKET_STANDARD: + default: + standard_packet_to_movement(packet, pos); + } + return B_OK; } @@ -325,8 +329,6 @@ handle_mouse_interrupt(void* data) TRACE(("mouse interrupt occurred!!!\n")); read = sIsa->read_io_8(PS2_PORT_CTRL); - TRACE(("PS2_PORT_CTRL: %02x\n", read)); - if (read < 0) { TRACE(("Interrupt was not generated by the ps2 mouse\n")); return B_UNHANDLED_INTERRUPT; @@ -340,7 +342,7 @@ handle_mouse_interrupt(void* data) return B_HANDLED_INTERRUPT; } - if (sSync++ == 2) { + if (++sSync == sPacketSize) { TRACE(("mouse synched\n")); sSync = 0; release_sem_etc(sMouseSem, 1, B_DO_NOT_RESCHEDULE); @@ -375,10 +377,10 @@ mouse_open(const char *name, uint32 flags, void **cookie) } TRACE(("mouse_open(): mouse succesfully enabled\n")); - + // register interrupt handler status = install_io_interrupt_handler(INT_PS2_MOUSE, handle_mouse_interrupt, NULL, 0); - + return status; } @@ -428,14 +430,25 @@ mouse_ioctl(void *cookie, uint32 op, void *buf, size_t len) case MS_NUM_EVENTS: { int32 count; - TRACE(("PS2_GET_EVENT_COUNT\n")); + TRACE(("MS_NUM_EVENTS\n")); get_sem_count(sMouseSem, &count); return count; } case MS_READ: - TRACE(("PS2_GET_MOUSE_MOVEMENTS\n")); + TRACE(("MS_READ\n")); return ps2_mouse_read(pos); - + case MS_SETTYPE: + TRACE(("MS_SETTYPE not implemented\n")); + return EINVAL; + case MS_SETMAP: + TRACE(("MS_SETMAP (set mouse mapping) not implemented\n")); + return EINVAL; + case MS_GETA: + TRACE(("MS_GETA (get mouse acceleration) not implemented\n")); + return EINVAL; + case MS_SETA: + TRACE(("MS_SETA (set mouse acceleration) not implemented\n")); + return EINVAL; default: TRACE(("unknown opcode: %ld\n", op)); return EINVAL; @@ -514,6 +527,9 @@ init_driver() TRACE(("A PS/2 mouse has been successfully detected\n")); + // TODO: Check mouse type, and set the correct packet size + sPacketSize = PS2_PACKET_STANDARD; + sMouseChain = cbuf_get_chain(MOUSE_HISTORY_SIZE); if (sMouseChain == NULL) { TRACE(("can't allocate cbuf chain\n")); diff --git a/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.h b/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.h index 9aa7a7f1ac..014fa96d40 100644 --- a/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.h +++ b/src/add-ons/kernel/drivers/arch/x86/ps2mouse/ps2mouse.h @@ -83,8 +83,11 @@ #define INT_PS2_MOUSE 0x0C // other stuff -#define PS2_PACKET_SIZE 3 #define MOUSE_HISTORY_SIZE 256 +// packet sizes +#define PS2_PACKET_STANDARD 3 +#define PS2_PACKET_INTELLIMOUSE 4 +#define PS2_MAX_PACKET_SIZE 4 // Should be equal to the biggest packet size #endif /* _KERNEL_ARCH_x86_PS2MOUSE_H */