OpenSolaris

Printable Version Enter a New Search
Bug ID 6526932
Synopsis shift key press is buffered by kernel driver and not sent to X immediately
State 10-Fix Delivered (Fix available in build)
Category:Subcategory driver:usb-keyboard
Keywords
Responsible Engineer Strony Zhang
Reported Against snv_58 , snv_59 , vermillion_61
Duplicate Of
Introduced In solaris_nevada
Commit to Fix snv_60
Fixed In snv_60
Release Fixed solaris_nevada(snv_60) , solaris_10u4(s10u4_07) (Bug ID:2148192)
Related Bugs 4369166 , 6427784 , 6534459 , 6536450
Submit Date 21-February-2007
Last Update Date 6-November-2008
Description
When you press the shift key on a USB keyboard on snv_58, X does not receive a keydown
VUID event from /dev/kbd until either another key is pressed or the shift key is released.

For instance, if you press shift, click the mouse and release shift, the sequence of
events X recieves is:
	mouse button down
	mouse button up
	shift key down
	shift key up

Based on the past experience with 4369166, I strongly suspect this was introduced into
Nevada by the putback in nv_58 of the Shift-Pause alternate keyboard break sequence in
CR 6427784.

You can verify this by watching the timestamps on the events in the following dtrace
script.   (To use, use "ps -ef | grep Xorg" to find the Xorg process, then pfiles on
that process id - one of the fd's listed will be conskbd, another consms - run this
script with the conskbd fd as the first argument, the consms as the second one.   
For instance, if 8 is conskbd & 9 is consms, run this script as "./input.d 8 9" .)

#!/usr/sbin/dtrace -Cs

#include <sys/vuid_event.h>
#pragma D option quiet

Firm_event *fe;

syscall::read:entry
/execname == "Xorg" && arg0 == $1/
{
	self->kbdread = arg1;
}

syscall::read:return
/self->kbdread != 0/
{
	printf("--- Read %d bytes from kbd\n", arg0);
}

#define PRINT_KBD_EVENT \
	fe = (Firm_event *) copyin(self->kbdread, sizeof(Firm_event *)); \
	printf("id=%6d value=%5d (%s) time=%12d.%u (timestamp=%u)\n", fe->id, fe->value, fe->value == VKEY_DOWN ? "down" : " up ", fe->time.tv_sec, fe->time.tv_usec, timestamp); \
	self->kbdread += sizeof(Firm_event)

syscall::read:return
/self->kbdread != 0 && arg0 >= (sizeof(Firm_event) * 4)/
{
	PRINT_KBD_EVENT;
}

syscall::read:return
/self->kbdread != 0 && arg0 >= (sizeof(Firm_event) * 3)/
{
	PRINT_KBD_EVENT;
}

syscall::read:return
/self->kbdread != 0 && arg0 >= (sizeof(Firm_event) * 2)/
{
	PRINT_KBD_EVENT;
}

syscall::read:return
/self->kbdread != 0 && arg0 >= sizeof(Firm_event)/
{
	PRINT_KBD_EVENT;
}

syscall::read:return
/self->kbdread != 0/
{
	self->kbdread = 0;
}

syscall::read:entry
/execname == "Xorg" && arg0 == $2/
{
	self->mouseread = arg1;
}

syscall::read:return
/self->mouseread != 0/
{
	printf("--- Read %d bytes from mouse\n", arg0);
}

#define PRINT_MOUSE_EVENT \
	fe = (Firm_event *) copyin(self->mouseread, sizeof(Firm_event *)); \
	printf("id=%6d value=%12d time=%12d.%u (timestamp=%u)\n", fe->id, fe->value, fe->time.tv_sec, fe->time.tv_usec, timestamp); \
	self->mouseread += sizeof(Firm_event)

syscall::read:return
/self->mouseread != 0 && arg0 >= (sizeof(Firm_event) * 4)/
{
	PRINT_MOUSE_EVENT;
}

syscall::read:return
/self->mouseread != 0 && arg0 >= (sizeof(Firm_event) * 3)/
{
	PRINT_MOUSE_EVENT;
}

syscall::read:return
/self->mouseread != 0 && arg0 >= (sizeof(Firm_event) * 2)/
{
	PRINT_MOUSE_EVENT;
}

syscall::read:return
/self->mouseread != 0 && arg0 >= sizeof(Firm_event)/
{
	PRINT_MOUSE_EVENT;
}

syscall::read:return
/self->mouseread != 0/
{
	self->mouseread = 0;
}
Work Around
N/A
Comments
N/A