Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
40a64fa8
Commit
40a64fa8
authored
Aug 05, 2006
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
parents
91a2eb28
2ffc1cca
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
509 additions
and
308 deletions
+509
-308
drivers/char/keyboard.c
drivers/char/keyboard.c
+78
-61
drivers/input/evdev.c
drivers/input/evdev.c
+3
-7
drivers/input/gameport/fm801-gp.c
drivers/input/gameport/fm801-gp.c
+2
-2
drivers/input/gameport/gameport.c
drivers/input/gameport/gameport.c
+49
-17
drivers/input/input.c
drivers/input/input.c
+44
-13
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-main.c
+10
-9
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceball.c
+1
-1
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/atkbd.c
+60
-43
drivers/input/misc/wistron_btns.c
drivers/input/misc/wistron_btns.c
+10
-10
drivers/input/mouse/logips2pp.c
drivers/input/mouse/logips2pp.c
+1
-2
drivers/input/mouse/trackpoint.c
drivers/input/mouse/trackpoint.c
+34
-18
drivers/input/serio/libps2.c
drivers/input/serio/libps2.c
+5
-0
drivers/input/serio/serio.c
drivers/input/serio/serio.c
+51
-14
drivers/usb/input/ati_remote.c
drivers/usb/input/ati_remote.c
+99
-74
drivers/usb/input/hid-input.c
drivers/usb/input/hid-input.c
+2
-1
drivers/usb/input/hiddev.c
drivers/usb/input/hiddev.c
+38
-34
include/linux/input.h
include/linux/input.h
+22
-2
No files found.
drivers/char/keyboard.c
View file @
40a64fa8
...
...
@@ -107,7 +107,6 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
struct
kbd_struct
kbd_table
[
MAX_NR_CONSOLES
];
static
struct
kbd_struct
*
kbd
=
kbd_table
;
static
struct
kbd_struct
kbd0
;
int
spawnpid
,
spawnsig
;
...
...
@@ -223,13 +222,13 @@ static void kd_nosound(unsigned long ignored)
{
struct
list_head
*
node
;
list_for_each
(
node
,
&
kbd_handler
.
h_list
)
{
list_for_each
(
node
,
&
kbd_handler
.
h_list
)
{
struct
input_handle
*
handle
=
to_handle_h
(
node
);
if
(
test_bit
(
EV_SND
,
handle
->
dev
->
evbit
))
{
if
(
test_bit
(
SND_TONE
,
handle
->
dev
->
sndbit
))
input_
event
(
handle
->
dev
,
EV_SND
,
SND_TONE
,
0
);
input_
inject_event
(
handle
,
EV_SND
,
SND_TONE
,
0
);
if
(
test_bit
(
SND_BELL
,
handle
->
dev
->
sndbit
))
input_
event
(
handle
->
dev
,
EV_SND
,
SND_BELL
,
0
);
input_
inject_event
(
handle
,
EV_SND
,
SND_BELL
,
0
);
}
}
}
...
...
@@ -247,11 +246,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
struct
input_handle
*
handle
=
to_handle_h
(
node
);
if
(
test_bit
(
EV_SND
,
handle
->
dev
->
evbit
))
{
if
(
test_bit
(
SND_TONE
,
handle
->
dev
->
sndbit
))
{
input_
event
(
handle
->
dev
,
EV_SND
,
SND_TONE
,
hz
);
input_
inject_event
(
handle
,
EV_SND
,
SND_TONE
,
hz
);
break
;
}
if
(
test_bit
(
SND_BELL
,
handle
->
dev
->
sndbit
))
{
input_
event
(
handle
->
dev
,
EV_SND
,
SND_BELL
,
1
);
input_
inject_event
(
handle
,
EV_SND
,
SND_BELL
,
1
);
break
;
}
}
...
...
@@ -272,15 +271,15 @@ int kbd_rate(struct kbd_repeat *rep)
unsigned
int
d
=
0
;
unsigned
int
p
=
0
;
list_for_each
(
node
,
&
kbd_handler
.
h_list
)
{
list_for_each
(
node
,
&
kbd_handler
.
h_list
)
{
struct
input_handle
*
handle
=
to_handle_h
(
node
);
struct
input_dev
*
dev
=
handle
->
dev
;
if
(
test_bit
(
EV_REP
,
dev
->
evbit
))
{
if
(
rep
->
delay
>
0
)
input_
event
(
dev
,
EV_REP
,
REP_DELAY
,
rep
->
delay
);
input_
inject_event
(
handle
,
EV_REP
,
REP_DELAY
,
rep
->
delay
);
if
(
rep
->
period
>
0
)
input_
event
(
dev
,
EV_REP
,
REP_PERIOD
,
rep
->
period
);
input_
inject_event
(
handle
,
EV_REP
,
REP_PERIOD
,
rep
->
period
);
d
=
dev
->
rep
[
REP_DELAY
];
p
=
dev
->
rep
[
REP_PERIOD
];
}
...
...
@@ -988,7 +987,7 @@ static inline unsigned char getleds(void)
* interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen.
* This allows for easy and efficient race-condition prevention
* for kbd_
refresh_leds => inpu
t_event(dev, EV_LED, ...) => ...
* for kbd_
start => input_injec
t_event(dev, EV_LED, ...) => ...
*/
static
void
kbd_bh
(
unsigned
long
dummy
)
...
...
@@ -998,11 +997,11 @@ static void kbd_bh(unsigned long dummy)
if
(
leds
!=
ledstate
)
{
list_for_each
(
node
,
&
kbd_handler
.
h_list
)
{
struct
input_handle
*
handle
=
to_handle_h
(
node
);
input_
event
(
handle
->
dev
,
EV_LED
,
LED_SCROLLL
,
!!
(
leds
&
0x01
));
input_
event
(
handle
->
dev
,
EV_LED
,
LED_NUML
,
!!
(
leds
&
0x02
));
input_
event
(
handle
->
dev
,
EV_LED
,
LED_CAPSL
,
!!
(
leds
&
0x04
));
input_
sync
(
handle
->
dev
);
struct
input_handle
*
handle
=
to_handle_h
(
node
);
input_
inject_event
(
handle
,
EV_LED
,
LED_SCROLLL
,
!!
(
leds
&
0x01
));
input_
inject_event
(
handle
,
EV_LED
,
LED_NUML
,
!!
(
leds
&
0x02
));
input_
inject_event
(
handle
,
EV_LED
,
LED_CAPSL
,
!!
(
leds
&
0x04
));
input_
inject_event
(
handle
,
EV_SYN
,
SYN_REPORT
,
0
);
}
}
...
...
@@ -1011,23 +1010,6 @@ static void kbd_bh(unsigned long dummy)
DECLARE_TASKLET_DISABLED
(
keyboard_tasklet
,
kbd_bh
,
0
);
/*
* This allows a newly plugged keyboard to pick the LED state.
*/
static
void
kbd_refresh_leds
(
struct
input_handle
*
handle
)
{
unsigned
char
leds
=
ledstate
;
tasklet_disable
(
&
keyboard_tasklet
);
if
(
leds
!=
0xff
)
{
input_event
(
handle
->
dev
,
EV_LED
,
LED_SCROLLL
,
!!
(
leds
&
0x01
));
input_event
(
handle
->
dev
,
EV_LED
,
LED_NUML
,
!!
(
leds
&
0x02
));
input_event
(
handle
->
dev
,
EV_LED
,
LED_CAPSL
,
!!
(
leds
&
0x04
));
input_sync
(
handle
->
dev
);
}
tasklet_enable
(
&
keyboard_tasklet
);
}
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
...
...
@@ -1043,7 +1025,7 @@ static const unsigned short x86_keycodes[256] =
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
,
75
,
76
,
77
,
78
,
79
,
80
,
81
,
82
,
83
,
84
,
118
,
86
,
87
,
88
,
115
,
120
,
119
,
121
,
112
,
123
,
92
,
284
,
285
,
309
,
298
,
312
,
91
,
327
,
328
,
329
,
331
,
333
,
335
,
336
,
337
,
338
,
339
,
284
,
285
,
309
,
0
,
312
,
91
,
327
,
328
,
329
,
331
,
333
,
335
,
336
,
337
,
338
,
339
,
367
,
288
,
302
,
304
,
350
,
89
,
334
,
326
,
267
,
126
,
268
,
269
,
125
,
347
,
348
,
349
,
360
,
261
,
262
,
263
,
268
,
376
,
100
,
101
,
321
,
316
,
373
,
286
,
289
,
102
,
351
,
355
,
103
,
104
,
105
,
275
,
287
,
279
,
306
,
106
,
274
,
107
,
294
,
364
,
358
,
363
,
362
,
361
,
...
...
@@ -1065,38 +1047,55 @@ extern void sun_do_break(void);
static
int
emulate_raw
(
struct
vc_data
*
vc
,
unsigned
int
keycode
,
unsigned
char
up_flag
)
{
if
(
keycode
>
255
||
!
x86_keycodes
[
keycode
])
return
-
1
;
int
code
;
switch
(
keycode
)
{
case
KEY_PAUSE
:
put_queue
(
vc
,
0xe1
);
put_queue
(
vc
,
0x1d
|
up_flag
);
put_queue
(
vc
,
0x45
|
up_flag
);
return
0
;
break
;
case
KEY_HANGEUL
:
if
(
!
up_flag
)
put_queue
(
vc
,
0xf2
);
return
0
;
break
;
case
KEY_HANJA
:
if
(
!
up_flag
)
put_queue
(
vc
,
0xf1
);
return
0
;
}
break
;
if
(
keycode
==
KEY_SYSRQ
&&
sysrq_alt
)
{
put_queue
(
vc
,
0x54
|
up_flag
);
return
0
;
}
case
KEY_SYSRQ
:
/*
* Real AT keyboards (that's what we're trying
* to emulate here emit 0xe0 0x2a 0xe0 0x37 when
* pressing PrtSc/SysRq alone, but simply 0x54
* when pressing Alt+PrtSc/SysRq.
*/
if
(
sysrq_alt
)
{
put_queue
(
vc
,
0x54
|
up_flag
);
}
else
{
put_queue
(
vc
,
0xe0
);
put_queue
(
vc
,
0x2a
|
up_flag
);
put_queue
(
vc
,
0xe0
);
put_queue
(
vc
,
0x37
|
up_flag
);
}
break
;
default:
if
(
keycode
>
255
)
return
-
1
;
if
(
x86_keycodes
[
keycode
]
&
0x100
)
put_queue
(
vc
,
0xe0
);
code
=
x86_keycodes
[
keycode
];
if
(
!
code
)
return
-
1
;
put_queue
(
vc
,
(
x86_keycodes
[
keycode
]
&
0x7f
)
|
up_flag
);
if
(
code
&
0x100
)
put_queue
(
vc
,
0xe0
);
put_queue
(
vc
,
(
code
&
0x7f
)
|
up_flag
);
if
(
keycode
==
KEY_SYSRQ
)
{
put_queue
(
vc
,
0xe0
);
put_queue
(
vc
,
0x37
|
up_flag
);
break
;
}
return
0
;
...
...
@@ -1298,16 +1297,15 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
if
(
i
==
BTN_MISC
&&
!
test_bit
(
EV_SND
,
dev
->
evbit
))
return
NULL
;
if
(
!
(
handle
=
kmalloc
(
sizeof
(
struct
input_handle
),
GFP_KERNEL
)))
handle
=
kzalloc
(
sizeof
(
struct
input_handle
),
GFP_KERNEL
);
if
(
!
handle
)
return
NULL
;
memset
(
handle
,
0
,
sizeof
(
struct
input_handle
));
handle
->
dev
=
dev
;
handle
->
handler
=
handler
;
handle
->
name
=
"kbd"
;
input_open_device
(
handle
);
kbd_refresh_leds
(
handle
);
return
handle
;
}
...
...
@@ -1318,6 +1316,24 @@ static void kbd_disconnect(struct input_handle *handle)
kfree
(
handle
);
}
/*
* Start keyboard handler on the new keyboard by refreshing LED state to
* match the rest of the system.
*/
static
void
kbd_start
(
struct
input_handle
*
handle
)
{
unsigned
char
leds
=
ledstate
;
tasklet_disable
(
&
keyboard_tasklet
);
if
(
leds
!=
0xff
)
{
input_inject_event
(
handle
,
EV_LED
,
LED_SCROLLL
,
!!
(
leds
&
0x01
));
input_inject_event
(
handle
,
EV_LED
,
LED_NUML
,
!!
(
leds
&
0x02
));
input_inject_event
(
handle
,
EV_LED
,
LED_CAPSL
,
!!
(
leds
&
0x04
));
input_inject_event
(
handle
,
EV_SYN
,
SYN_REPORT
,
0
);
}
tasklet_enable
(
&
keyboard_tasklet
);
}
static
struct
input_device_id
kbd_ids
[]
=
{
{
.
flags
=
INPUT_DEVICE_ID_MATCH_EVBIT
,
...
...
@@ -1338,6 +1354,7 @@ static struct input_handler kbd_handler = {
.
event
=
kbd_event
,
.
connect
=
kbd_connect
,
.
disconnect
=
kbd_disconnect
,
.
start
=
kbd_start
,
.
name
=
"kbd"
,
.
id_table
=
kbd_ids
,
};
...
...
@@ -1346,15 +1363,15 @@ int __init kbd_init(void)
{
int
i
;
kbd0
.
ledflagstate
=
kbd0
.
default_ledflagstate
=
KBD_DEFLEDS
;
kbd0
.
ledmode
=
LED_SHOW_FLAG
S
;
kbd0
.
lockstate
=
KBD_DEFLOCK
;
kbd0
.
slockstate
=
0
;
kbd0
.
modeflags
=
KBD_DEFMODE
;
kbd0
.
kbdmode
=
VC_XLATE
;
for
(
i
=
0
;
i
<
MAX_NR_CONSOLES
;
i
++
)
kbd_table
[
i
]
=
kbd0
;
for
(
i
=
0
;
i
<
MAX_NR_CONSOLES
;
i
++
)
{
kbd_table
[
i
].
ledflagstate
=
KBD_DEFLED
S
;
kbd_table
[
i
].
default_ledflagstate
=
KBD_DEFLEDS
;
kbd_table
[
i
].
ledmode
=
LED_SHOW_FLAGS
;
kbd_table
[
i
].
lockstate
=
KBD_DEFLOCK
;
kbd_table
[
i
].
slockstate
=
0
;
kbd_table
[
i
].
modeflags
=
KBD_DEFMODE
;
kbd_table
[
i
].
kbdmode
=
VC_XLATE
;
}
input_register_handler
(
&
kbd_handler
);
...
...
drivers/input/evdev.c
View file @
40a64fa8
...
...
@@ -127,14 +127,10 @@ static int evdev_open(struct inode * inode, struct file * file)
{
struct
evdev_list
*
list
;
int
i
=
iminor
(
inode
)
-
EVDEV_MINOR_BASE
;
int
accept_err
;
if
(
i
>=
EVDEV_MINORS
||
!
evdev_table
[
i
]
||
!
evdev_table
[
i
]
->
exist
)
return
-
ENODEV
;
if
((
accept_err
=
input_accept_process
(
&
(
evdev_table
[
i
]
->
handle
),
file
)))
return
accept_err
;
if
(
!
(
list
=
kzalloc
(
sizeof
(
struct
evdev_list
),
GFP_KERNEL
)))
return
-
ENOMEM
;
...
...
@@ -260,7 +256,7 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_
if
(
evdev_event_from_user
(
buffer
+
retval
,
&
event
))
return
-
EFAULT
;
input_
event
(
list
->
evdev
->
handle
.
dev
,
event
.
type
,
event
.
code
,
event
.
value
);
input_
inject_event
(
&
list
->
evdev
->
handle
,
event
.
type
,
event
.
code
,
event
.
value
);
retval
+=
evdev_event_size
();
}
...
...
@@ -428,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
if
(
get_user
(
v
,
ip
+
1
))
return
-
EFAULT
;
input_
event
(
dev
,
EV_REP
,
REP_DELAY
,
u
);
input_
event
(
dev
,
EV_REP
,
REP_PERIOD
,
v
);
input_
inject_event
(
&
evdev
->
handle
,
EV_REP
,
REP_DELAY
,
u
);
input_
inject_event
(
&
evdev
->
handle
,
EV_REP
,
REP_PERIOD
,
v
);
return
0
;
...
...
drivers/input/gameport/fm801-gp.c
View file @
40a64fa8
...
...
@@ -106,10 +106,10 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
gp
->
gameport
=
port
;
gp
->
res_port
=
request_region
(
port
->
io
,
0x10
,
"FM801 GP"
);
if
(
!
gp
->
res_port
)
{
kfree
(
gp
);
gameport_free_port
(
port
);
printk
(
KERN_DEBUG
"fm801-gp: unable to grab region 0x%x-0x%x
\n
"
,
port
->
io
,
port
->
io
+
0x0f
);
gameport_free_port
(
port
);
kfree
(
gp
);
return
-
EBUSY
;
}
...
...
drivers/input/gameport/gameport.c
View file @
40a64fa8
...
...
@@ -53,6 +53,7 @@ static LIST_HEAD(gameport_list);
static
struct
bus_type
gameport_bus
;
static
void
gameport_add_driver
(
struct
gameport_driver
*
drv
);
static
void
gameport_add_port
(
struct
gameport
*
gameport
);
static
void
gameport_destroy_port
(
struct
gameport
*
gameport
);
static
void
gameport_reconnect_port
(
struct
gameport
*
gameport
);
...
...
@@ -211,8 +212,14 @@ static void gameport_release_driver(struct gameport *gameport)
static
void
gameport_find_driver
(
struct
gameport
*
gameport
)
{
int
error
;
down_write
(
&
gameport_bus
.
subsys
.
rwsem
);
device_attach
(
&
gameport
->
dev
);
error
=
device_attach
(
&
gameport
->
dev
);
if
(
error
<
0
)
printk
(
KERN_WARNING
"gameport: device_attach() failed for %s (%s), error: %d
\n
"
,
gameport
->
phys
,
gameport
->
name
,
error
);
up_write
(
&
gameport_bus
.
subsys
.
rwsem
);
}
...
...
@@ -316,7 +323,6 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
spin_unlock_irqrestore
(
&
gameport_event_lock
,
flags
);
}
static
struct
gameport_event
*
gameport_get_event
(
void
)
{
struct
gameport_event
*
event
;
...
...
@@ -342,7 +348,6 @@ static struct gameport_event *gameport_get_event(void)
static
void
gameport_handle_event
(
void
)
{
struct
gameport_event
*
event
;
struct
gameport_driver
*
gameport_drv
;
mutex_lock
(
&
gameport_mutex
);
...
...
@@ -369,8 +374,7 @@ static void gameport_handle_event(void)
break
;
case
GAMEPORT_REGISTER_DRIVER
:
gameport_drv
=
event
->
object
;
driver_register
(
&
gameport_drv
->
driver
);
gameport_add_driver
(
event
->
object
);
break
;
default:
...
...
@@ -532,6 +536,7 @@ static void gameport_init_port(struct gameport *gameport)
if
(
gameport
->
parent
)
gameport
->
dev
.
parent
=
&
gameport
->
parent
->
dev
;
INIT_LIST_HEAD
(
&
gameport
->
node
);
spin_lock_init
(
&
gameport
->
timer_lock
);
init_timer
(
&
gameport
->
poll_timer
);
gameport
->
poll_timer
.
function
=
gameport_run_poll_handler
;
...
...
@@ -544,6 +549,8 @@ static void gameport_init_port(struct gameport *gameport)
*/
static
void
gameport_add_port
(
struct
gameport
*
gameport
)
{
int
error
;
if
(
gameport
->
parent
)
gameport
->
parent
->
child
=
gameport
;
...
...
@@ -558,8 +565,13 @@ static void gameport_add_port(struct gameport *gameport)
printk
(
KERN_INFO
"gameport: %s is %s, speed %dkHz
\n
"
,
gameport
->
name
,
gameport
->
phys
,
gameport
->
speed
);
device_add
(
&
gameport
->
dev
);
gameport
->
registered
=
1
;
error
=
device_add
(
&
gameport
->
dev
);
if
(
error
)
printk
(
KERN_ERR
"gameport: device_add() failed for %s (%s), error: %d
\n
"
,
gameport
->
phys
,
gameport
->
name
,
error
);
else
gameport
->
registered
=
1
;
}
/*
...
...
@@ -583,10 +595,11 @@ static void gameport_destroy_port(struct gameport *gameport)
if
(
gameport
->
registered
)
{
device_del
(
&
gameport
->
dev
);
list_del_init
(
&
gameport
->
node
);
gameport
->
registered
=
0
;
}
list_del_init
(
&
gameport
->
node
);
gameport_remove_pending_events
(
gameport
);
put_device
(
&
gameport
->
dev
);
}
...
...
@@ -704,11 +717,22 @@ static int gameport_driver_remove(struct device *dev)
}
static
struct
bus_type
gameport_bus
=
{
.
name
=
"gameport"
,
.
probe
=
gameport_driver_probe
,
.
remove
=
gameport_driver_remove
,
.
name
=
"gameport"
,
.
probe
=
gameport_driver_probe
,
.
remove
=
gameport_driver_remove
,
};
static
void
gameport_add_driver
(
struct
gameport_driver
*
drv
)
{
int
error
;
error
=
driver_register
(
&
drv
->
driver
);
if
(
error
)
printk
(
KERN_ERR
"gameport: driver_register() failed for %s, error: %d
\n
"
,
drv
->
driver
.
name
,
error
);
}
void
__gameport_register_driver
(
struct
gameport_driver
*
drv
,
struct
module
*
owner
)
{
drv
->
driver
.
bus
=
&
gameport_bus
;
...
...
@@ -778,16 +802,24 @@ void gameport_close(struct gameport *gameport)
static
int
__init
gameport_init
(
void
)
{
gameport_task
=
kthread_run
(
gameport_thread
,
NULL
,
"kgameportd"
);
if
(
IS_ERR
(
gameport_task
))
{
printk
(
KERN_ERR
"gameport: Failed to start kgameportd
\n
"
);
return
PTR_ERR
(
gameport_task
);
}
int
error
;
gameport_bus
.
dev_attrs
=
gameport_device_attrs
;
gameport_bus
.
drv_attrs
=
gameport_driver_attrs
;
gameport_bus
.
match
=
gameport_bus_match
;
bus_register
(
&
gameport_bus
);
error
=
bus_register
(
&
gameport_bus
);
if
(
error
)
{
printk
(
KERN_ERR
"gameport: failed to register gameport bus, error: %d
\n
"
,
error
);
return
error
;
}
gameport_task
=
kthread_run
(
gameport_thread
,
NULL
,
"kgameportd"
);
if
(
IS_ERR
(
gameport_task
))
{
bus_unregister
(
&
gameport_bus
);
error
=
PTR_ERR
(
gameport_task
);
printk
(
KERN_ERR
"gameport: Failed to start kgameportd, error: %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
...
...
drivers/input/input.c
View file @
40a64fa8
...
...
@@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list);
static
struct
input_handler
*
input_table
[
8
];
/**
* input_event() - report new input event
* @handle: device that generated the event
* @type: type of the event
* @code: event code
* @value: value of the event
*
* This function should be used by drivers implementing various input devices
* See also input_inject_event()
*/
void
input_event
(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
)
{
struct
input_handle
*
handle
;
...
...
@@ -183,6 +193,23 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
}
EXPORT_SYMBOL
(
input_event
);
/**
* input_inject_event() - send input event from input handler
* @handle: input handle to send event through
* @type: type of the event
* @code: event code
* @value: value of the event
*
* Similar to input_event() but will ignore event if device is "grabbed" and handle
* injecting event is not the one that owns the device.
*/
void
input_inject_event
(
struct
input_handle
*
handle
,
unsigned
int
type
,
unsigned
int
code
,
int
value
)
{
if
(
!
handle
->
dev
->
grab
||
handle
->
dev
->
grab
==
handle
)
input_event
(
handle
->
dev
,
type
,
code
,
value
);
}
EXPORT_SYMBOL
(
input_inject_event
);
static
void
input_repeat_key
(
unsigned
long
data
)
{
struct
input_dev
*
dev
=
(
void
*
)
data
;
...
...
@@ -197,15 +224,6 @@ static void input_repeat_key(unsigned long data)
mod_timer
(
&
dev
->
timer
,
jiffies
+
msecs_to_jiffies
(
dev
->
rep
[
REP_PERIOD
]));
}
int
input_accept_process
(
struct
input_handle
*
handle
,
struct
file
*
file
)
{
if
(
handle
->
dev
->
accept
)
return
handle
->
dev
->
accept
(
handle
->
dev
,
file
);
return
0
;
}
EXPORT_SYMBOL
(
input_accept_process
);
int
input_grab_device
(
struct
input_handle
*
handle
)
{
if
(
handle
->
dev
->
grab
)
...
...
@@ -218,8 +236,15 @@ EXPORT_SYMBOL(input_grab_device);
void
input_release_device
(
struct
input_handle
*
handle
)
{
if
(
handle
->
dev
->
grab
==
handle
)
handle
->
dev
->
grab
=
NULL
;
struct
input_dev
*
dev
=
handle
->
dev
;
if
(
dev
->
grab
==
handle
)
{
dev
->
grab
=
NULL
;
list_for_each_entry
(
handle
,
&
dev
->
h_list
,
d_node
)
if
(
handle
->
handler
->
start
)
handle
->
handler
->
start
(
handle
);
}
}
EXPORT_SYMBOL
(
input_release_device
);
...
...
@@ -963,8 +988,11 @@ int input_register_device(struct input_dev *dev)
list_for_each_entry
(
handler
,
&
input_handler_list
,
node
)
if
(
!
handler
->
blacklist
||
!
input_match_device
(
handler
->
blacklist
,
dev
))
if
((
id
=
input_match_device
(
handler
->
id_table
,
dev
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
{
input_link_handle
(
handle
);
if
(
handler
->
start
)
handler
->
start
(
handle
);
}
input_wakeup_procfs_readers
();
...
...
@@ -1028,8 +1056,11 @@ void input_register_handler(struct input_handler *handler)
list_for_each_entry
(
dev
,
&
input_dev_list
,
node
)
if
(
!
handler
->
blacklist
||
!
input_match_device
(
handler
->
blacklist
,
dev
))
if
((
id
=
input_match_device
(
handler
->
id_table
,
dev
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
{
input_link_handle
(
handle
);
if
(
handler
->
start
)
handler
->
start
(
handle
);
}
input_wakeup_procfs_readers
();
}
...
...
drivers/input/joystick/iforce/iforce-main.c
View file @
40a64fa8
...
...
@@ -79,6 +79,7 @@ static struct iforce_device iforce_device[] = {
{
0x06f8
,
0x0001
,
"Guillemot Race Leader Force Feedback"
,
btn_wheel
,
abs_wheel
,
ff_iforce
},
//?
{
0x06f8
,
0x0004
,
"Guillemot Force Feedback Racing Wheel"
,
btn_wheel
,
abs_wheel
,
ff_iforce
},
//?
{
0x06f8
,
0x0004
,
"Gullemot Jet Leader 3D"
,
btn_joystick
,
abs_joystick
,
ff_iforce
},
//?
{
0x06d6
,
0x29bc
,
"Trust Force Feedback Race Master"
,
btn_wheel
,
abs_wheel
,
ff_iforce
},
{
0x0000
,
0x0000
,
"Unknown I-Force Device [%04x:%04x]"
,
btn_joystick
,
abs_joystick
,
ff_iforce
}
};
...
...
@@ -222,22 +223,22 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id)
int
err
=
0
;
struct
iforce_core_effect
*
core_effect
;
/* Check who is trying to erase this effect */
if
(
iforce
->
core_effects
[
effect_id
].
owner
!=
current
->
pid
)
{
printk
(
KERN_WARNING
"iforce-main.c: %d tried to erase an effect belonging to %d
\n
"
,
current
->
pid
,
iforce
->
core_effects
[
effect_id
].
owner
);
return
-
EACCES
;
}
if
(
effect_id
<
0
||
effect_id
>=
FF_EFFECTS_MAX
)
return
-
EINVAL
;
core_effect
=
iforce
->
core_effects
+
effect_id
;
core_effect
=
&
iforce
->
core_effects
[
effect_id
];
/* Check who is trying to erase this effect */
if
(
core_effect
->
owner
!=
current
->
pid
)
{
printk
(
KERN_WARNING
"iforce-main.c: %d tried to erase an effect belonging to %d
\n
"
,
current
->
pid
,
core_effect
->
owner
);
return
-
EACCES
;
}
if
(
test_bit
(
FF_MOD1_IS_USED
,
core_effect
->
flags
))
err
=
release_resource
(
&
(
iforce
->
core_effects
[
effect_id
].
mod1_chunk
)
);
err
=
release_resource
(
&
core_effect
->
mod1_chunk
);
if
(
!
err
&&
test_bit
(
FF_MOD2_IS_USED
,
core_effect
->
flags
))
err
=
release_resource
(
&
(
iforce
->
core_effects
[
effect_id
].
mod2_chunk
)
);
err
=
release_resource
(
&
core_effect
->
mod2_chunk
);
/*TODO: remember to change that if more FF_MOD* bits are added */
core_effect
->
flags
[
0
]
=
0
;
...
...
drivers/input/joystick/spaceball.c
View file @
40a64fa8
...
...
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
*/
#define SPACEBALL_MAX_LENGTH 128
#define SPACEBALL_MAX_ID
8
#define SPACEBALL_MAX_ID
9
#define SPACEBALL_1003 1
#define SPACEBALL_2003B 3
...
...
drivers/input/keyboard/atkbd.c
View file @
40a64fa8
...
...
@@ -482,13 +482,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
return
IRQ_HANDLED
;
}
/*
* atkbd_event_work() is used to complete processing of events that
* can not be processed by input_event() which is often called from
* interrupt context.
*/
static
void
atkbd_event_work
(
void
*
data
)
static
int
atkbd_set_repeat_rate
(
struct
atkbd
*
atkbd
)
{
const
short
period
[
32
]
=
{
33
,
37
,
42
,
46
,
50
,
54
,
58
,
63
,
67
,
75
,
83
,
92
,
100
,
109
,
116
,
125
,
...
...
@@ -496,41 +490,64 @@ static void atkbd_event_work(void *data)
const
short
delay
[
4
]
=
{
250
,
500
,
750
,
1000
};
struct
atkbd
*
atkbd
=
data
;
struct
input_dev
*
dev
=
atkbd
->
dev
;
unsigned
char
param
;
int
i
=
0
,
j
=
0
;
while
(
i
<
ARRAY_SIZE
(
period
)
-
1
&&
period
[
i
]
<
dev
->
rep
[
REP_PERIOD
])
i
++
;
dev
->
rep
[
REP_PERIOD
]
=
period
[
i
];
while
(
j
<
ARRAY_SIZE
(
period
)
-
1
&&
delay
[
j
]
<
dev
->
rep
[
REP_DELAY
])
j
++
;
dev
->
rep
[
REP_DELAY
]
=
delay
[
j
];
param
=
i
|
(
j
<<
5
);
return
ps2_command
(
&
atkbd
->
ps2dev
,
&
param
,
ATKBD_CMD_SETREP
);
}
static
int
atkbd_set_leds
(
struct
atkbd
*
atkbd
)
{
struct
input_dev
*
dev
=
atkbd
->
dev
;
unsigned
char
param
[
2
];
int
i
,
j
;
mutex_lock
(
&
atkbd
->
event_mutex
);
param
[
0
]
=
(
test_bit
(
LED_SCROLLL
,
dev
->
led
)
?
1
:
0
)
|
(
test_bit
(
LED_NUML
,
dev
->
led
)
?
2
:
0
)
|
(
test_bit
(
LED_CAPSL
,
dev
->
led
)
?
4
:
0
);
if
(
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_SETLEDS
))
return
-
1
;
if
(
test_and_clear_bit
(
ATKBD_LED_EVENT_BIT
,
&
atkbd
->
event_mask
))
{
param
[
0
]
=
(
test_bit
(
LED_SCROLLL
,
dev
->
led
)
?
1
:
0
)
|
(
test_bit
(
LED_NUML
,
dev
->
led
)
?
2
:
0
)
|
(
test_bit
(
LED_CAPSL
,
dev
->
led
)
?
4
:
0
);
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_SETLEDS
);
if
(
atkbd
->
extra
)
{
param
[
0
]
=
0
;
param
[
1
]
=
(
test_bit
(
LED_COMPOSE
,
dev
->
led
)
?
0x01
:
0
)
|
(
test_bit
(
LED_SLEEP
,
dev
->
led
)
?
0x02
:
0
)
|
(
test_bit
(
LED_SUSPEND
,
dev
->
led
)
?
0x04
:
0
)
|
(
test_bit
(
LED_MISC
,
dev
->
led
)
?
0x10
:
0
)
|
(
test_bit
(
LED_MUTE
,
dev
->
led
)
?
0x20
:
0
);
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_EX_SETLEDS
);
}
if
(
atkbd
->
extra
)
{
param
[
0
]
=
0
;
param
[
1
]
=
(
test_bit
(
LED_COMPOSE
,
dev
->
led
)
?
0x01
:
0
)
|
(
test_bit
(
LED_SLEEP
,
dev
->
led
)
?
0x02
:
0
)
|
(
test_bit
(
LED_SUSPEND
,
dev
->
led
)
?
0x04
:
0
)
|
(
test_bit
(
LED_MISC
,
dev
->
led
)
?
0x10
:
0
)
|
(
test_bit
(
LED_MUTE
,
dev
->
led
)
?
0x20
:
0
);
if
(
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_EX_SETLEDS
))
return
-
1
;
}
if
(
test_and_clear_bit
(
ATKBD_REP_EVENT_BIT
,
&
atkbd
->
event_mask
))
{
i
=
j
=
0
;
while
(
i
<
31
&&
period
[
i
]
<
dev
->
rep
[
REP_PERIOD
])
i
++
;
while
(
j
<
3
&&
delay
[
j
]
<
dev
->
rep
[
REP_DELAY
])
j
++
;
dev
->
rep
[
REP_PERIOD
]
=
period
[
i
];
dev
->
rep
[
REP_DELAY
]
=
delay
[
j
];
param
[
0
]
=
i
|
(
j
<<
5
);
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_SETREP
);
}
return
0
;
}
/*
* atkbd_event_work() is used to complete processing of events that
* can not be processed by input_event() which is often called from
* interrupt context.
*/
static
void
atkbd_event_work
(
void
*
data
)
{
struct
atkbd
*
atkbd
=
data
;
mutex_lock
(
&
atkbd
->
event_mutex
);
if
(
test_and_clear_bit
(
ATKBD_LED_EVENT_BIT
,
&
atkbd
->
event_mask
))
atkbd_set_leds
(
atkbd
);
if
(
test_and_clear_bit
(
ATKBD_REP_EVENT_BIT
,
&
atkbd
->
event_mask
))
atkbd_set_repeat_rate
(
atkbd
);
mutex_unlock
(
&
atkbd
->
event_mutex
);
}
...
...
@@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio)
{
struct
atkbd
*
atkbd
=
serio_get_drvdata
(
serio
);
struct
serio_driver
*
drv
=
serio
->
drv
;
unsigned
char
param
[
1
];
if
(
!
atkbd
||
!
drv
)
{
printk
(
KERN_DEBUG
"atkbd: reconnect request, but serio is disconnected, ignoring...
\n
"
);
...
...
@@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_disable
(
atkbd
);
if
(
atkbd
->
write
)
{
param
[
0
]
=
(
test_bit
(
LED_SCROLLL
,
atkbd
->
dev
->
led
)
?
1
:
0
)
|
(
test_bit
(
LED_NUML
,
atkbd
->
dev
->
led
)
?
2
:
0
)
|
(
test_bit
(
LED_CAPSL
,
atkbd
->
dev
->
led
)
?
4
:
0
);
if
(
atkbd_probe
(
atkbd
))
return
-
1
;
if
(
atkbd
->
set
!=
atkbd_select_set
(
atkbd
,
atkbd
->
set
,
atkbd
->
extra
))
...
...
@@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_activate
(
atkbd
);
if
(
ps2_command
(
&
atkbd
->
ps2dev
,
param
,
ATKBD_CMD_SETLEDS
))
return
-
1
;
/*
* Restore repeat rate and LEDs (that were reset by atkbd_activate)
* to pre-resume state
*/
if
(
!
atkbd
->
softrepeat
)
atkbd_set_repeat_rate
(
atkbd
);
atkbd_set_leds
(
atkbd
);
}
atkbd_enable
(
atkbd
);
...
...
drivers/input/misc/wistron_btns.c
View file @
40a64fa8
...
...
@@ -94,7 +94,7 @@ static void call_bios(struct regs *regs)
static
ssize_t
__init
locate_wistron_bios
(
void
__iomem
*
base
)
{
static
const
unsigned
char
__initdata
signature
[]
=
static
unsigned
char
__initdata
signature
[]
=
{
0x42
,
0x21
,
0x55
,
0x30
};
ssize_t
offset
;
...
...
@@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
return
1
;
}
static
struct
key_entry
keymap_empty
[]
=
{
static
struct
key_entry
keymap_empty
[]
__initdata
=
{
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_fs_amilo_pro_v2000
[]
=
{
static
struct
key_entry
keymap_fs_amilo_pro_v2000
[]
__initdata
=
{
{
KE_KEY
,
0x01
,
KEY_HELP
},
{
KE_KEY
,
0x11
,
KEY_PROG1
},
{
KE_KEY
,
0x12
,
KEY_PROG2
},
...
...
@@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_fujitsu_n3510
[]
=
{
static
struct
key_entry
keymap_fujitsu_n3510
[]
__initdata
=
{
{
KE_KEY
,
0x11
,
KEY_PROG1
},
{
KE_KEY
,
0x12
,
KEY_PROG2
},
{
KE_KEY
,
0x36
,
KEY_WWW
},
...
...
@@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_wistron_ms2111
[]
=
{
static
struct
key_entry
keymap_wistron_ms2111
[]
__initdata
=
{
{
KE_KEY
,
0x11
,
KEY_PROG1
},
{
KE_KEY
,
0x12
,
KEY_PROG2
},
{
KE_KEY
,
0x13
,
KEY_PROG3
},
...
...
@@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_wistron_ms2141
[]
=
{
static
struct
key_entry
keymap_wistron_ms2141
[]
__initdata
=
{
{
KE_KEY
,
0x11
,
KEY_PROG1
},
{
KE_KEY
,
0x12
,
KEY_PROG2
},
{
KE_WIFI
,
0x30
,
0
},
...
...
@@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_acer_aspire_1500
[]
=
{
static
struct
key_entry
keymap_acer_aspire_1500
[]
__initdata
=
{
{
KE_KEY
,
0x11
,
KEY_PROG1
},
{
KE_KEY
,
0x12
,
KEY_PROG2
},
{
KE_WIFI
,
0x30
,
0
},
...
...
@@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_acer_travelmate_240
[]
=
{
static
struct
key_entry
keymap_acer_travelmate_240
[]
__initdata
=
{
{
KE_KEY
,
0x31
,
KEY_MAIL
},
{
KE_KEY
,
0x36
,
KEY_WWW
},
{
KE_KEY
,
0x11
,
KEY_PROG1
},
...
...
@@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] = {
{
KE_END
,
0
}
};
static
struct
key_entry
keymap_aopen_1559as
[]
=
{
static
struct
key_entry
keymap_aopen_1559as
[]
__initdata
=
{
{
KE_KEY
,
0x01
,
KEY_HELP
},
{
KE_KEY
,
0x06
,
KEY_PROG3
},
{
KE_KEY
,
0x11
,
KEY_PROG1
},
...
...
@@ -343,7 +343,7 @@ static struct key_entry keymap_aopen_1559as[] = {
* a list of buttons and their key codes (reported when loading this module
* with force=1) and the output of dmidecode to $MODULE_AUTHOR.
*/
static
struct
dmi_system_id
dmi_ids
[]
=
{
static
struct
dmi_system_id
dmi_ids
[]
__initdata
=
{
{
.
callback
=
dmi_matched
,
.
ident
=
"Fujitsu-Siemens Amilo Pro V2000"
,
...
...
drivers/input/mouse/logips2pp.c
View file @
40a64fa8
...
...
@@ -238,8 +238,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
{
100
,
PS2PP_KIND_MX
,
/* MX510 */
PS2PP_WHEEL
|
PS2PP_SIDE_BTN
|
PS2PP_TASK_BTN
|
PS2PP_EXTRA_BTN
|
PS2PP_NAV_BTN
},
{
111
,
PS2PP_KIND_MX
,
/* MX300 */
PS2PP_WHEEL
|
PS2PP_EXTRA_BTN
|
PS2PP_TASK_BTN
},
{
111
,
PS2PP_KIND_MX
,
PS2PP_WHEEL
|
PS2PP_SIDE_BTN
},
/* MX300 reports task button as side */
{
112
,
PS2PP_KIND_MX
,
/* MX500 */
PS2PP_WHEEL
|
PS2PP_SIDE_BTN
|
PS2PP_TASK_BTN
|
PS2PP_EXTRA_BTN
|
PS2PP_NAV_BTN
},
...
...
drivers/input/mouse/trackpoint.c
View file @
40a64fa8
...
...
@@ -183,21 +183,26 @@ static struct attribute_group trackpoint_attr_group = {
.
attrs
=
trackpoint_attrs
,
};
static
void
trackpoint_disconnect
(
struct
psmouse
*
psmouse
)
static
int
trackpoint_start_protocol
(
struct
psmouse
*
psmouse
,
unsigned
char
*
firmware_id
)
{
sysfs_remove_group
(
&
psmouse
->
ps2dev
.
serio
->
dev
.
kobj
,
&
trackpoint_attr_group
)
;
unsigned
char
param
[
2
]
=
{
0
}
;
kfree
(
psmouse
->
private
);
psmouse
->
private
=
NULL
;
if
(
ps2_command
(
&
psmouse
->
ps2dev
,
param
,
MAKE_PS2_CMD
(
0
,
2
,
TP_READ_ID
)))
return
-
1
;
if
(
param
[
0
]
!=
TP_MAGIC_IDENT
)
return
-
1
;
if
(
firmware_id
)
*
firmware_id
=
param
[
1
];
return
0
;
}
static
int
trackpoint_sync
(
struct
psmouse
*
psmouse
)
{
unsigned
char
toggle
;
struct
trackpoint_data
*
tp
=
psmouse
->
private
;
if
(
!
tp
)
return
-
1
;
unsigned
char
toggle
;
/* Disable features that may make device unusable with this driver */
trackpoint_read
(
&
psmouse
->
ps2dev
,
TP_TOGGLE_TWOHAND
,
&
toggle
);
...
...
@@ -263,27 +268,38 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
tp
->
ext_dev
=
TP_DEF_EXT_DEV
;
}
static
void
trackpoint_disconnect
(
struct
psmouse
*
psmouse
)
{
sysfs_remove_group
(
&
psmouse
->
ps2dev
.
serio
->
dev
.
kobj
,
&
trackpoint_attr_group
);
kfree
(
psmouse
->
private
);
psmouse
->
private
=
NULL
;
}
static
int
trackpoint_reconnect
(
struct
psmouse
*
psmouse
)
{
if
(
trackpoint_start_protocol
(
psmouse
,
NULL
))
return
-
1
;
if
(
trackpoint_sync
(
psmouse
))
return
-
1
;
return
0
;
}
int
trackpoint_detect
(
struct
psmouse
*
psmouse
,
int
set_properties
)
{
struct
trackpoint_data
*
priv
;
struct
ps2dev
*
ps2dev
=
&
psmouse
->
ps2dev
;
unsigned
char
firmware_id
;
unsigned
char
button_info
;
unsigned
char
param
[
2
];
param
[
0
]
=
param
[
1
]
=
0
;
if
(
ps2_command
(
ps2dev
,
param
,
MAKE_PS2_CMD
(
0
,
2
,
TP_READ_ID
)))
return
-
1
;
if
(
param
[
0
]
!=
TP_MAGIC_IDENT
)
if
(
trackpoint_start_protocol
(
psmouse
,
&
firmware_id
))
return
-
1
;
if
(
!
set_properties
)
return
0
;
firmware_id
=
param
[
1
];
if
(
trackpoint_read
(
&
psmouse
->
ps2dev
,
TP_EXT_BTN
,
&
button_info
))
{
printk
(
KERN_WARNING
"trackpoint.c: failed to get extended button data
\n
"
);
button_info
=
0
;
...
...
@@ -296,7 +312,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties)
psmouse
->
vendor
=
"IBM"
;
psmouse
->
name
=
"TrackPoint"
;
psmouse
->
reconnect
=
trackpoint_
sync
;
psmouse
->
reconnect
=
trackpoint_
reconnect
;
psmouse
->
disconnect
=
trackpoint_disconnect
;
trackpoint_defaults
(
priv
);
...
...
drivers/input/serio/libps2.c
View file @
40a64fa8
...
...
@@ -177,6 +177,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
return
-
1
;
}
if
(
send
&&
!
param
)
{
WARN_ON
(
1
);
return
-
1
;
}
mutex_lock_nested
(
&
ps2dev
->
cmd_mutex
,
SINGLE_DEPTH_NESTING
);
serio_pause_rx
(
ps2dev
->
serio
);
...
...
drivers/input/serio/serio.c
View file @
40a64fa8
...
...
@@ -62,6 +62,7 @@ static LIST_HEAD(serio_list);
static
struct
bus_type
serio_bus
;
static
void
serio_add_driver
(
struct
serio_driver
*
drv
);
static
void
serio_add_port
(
struct
serio
*
serio
);
static
void
serio_destroy_port
(
struct
serio
*
serio
);
static
void
serio_reconnect_port
(
struct
serio
*
serio
);
...
...
@@ -140,8 +141,14 @@ static void serio_release_driver(struct serio *serio)
static
void
serio_find_driver
(
struct
serio
*
serio
)
{
int
error
;
down_write
(
&
serio_bus
.
subsys
.
rwsem
);
device_attach
(
&
serio
->
dev
);
error
=
device_attach
(
&
serio
->
dev
);
if
(
error
<
0
)
printk
(
KERN_WARNING
"serio: device_attach() failed for %s (%s), error: %d
\n
"
,
serio
->
phys
,
serio
->
name
,
error
);
up_write
(
&
serio_bus
.
subsys
.
rwsem
);
}
...
...
@@ -272,7 +279,6 @@ static struct serio_event *serio_get_event(void)
static
void
serio_handle_event
(
void
)
{
struct
serio_event
*
event
;
struct
serio_driver
*
serio_drv
;
mutex_lock
(
&
serio_mutex
);
...
...
@@ -304,8 +310,7 @@ static void serio_handle_event(void)
break
;
case
SERIO_REGISTER_DRIVER
:
serio_drv
=
event
->
object
;
driver_register
(
&
serio_drv
->
driver
);
serio_add_driver
(
event
->
object
);
break
;
default:
...
...
@@ -525,6 +530,7 @@ static void serio_init_port(struct serio *serio)
__module_get
(
THIS_MODULE
);
INIT_LIST_HEAD
(
&
serio
->
node
);
spin_lock_init
(
&
serio
->
lock
);
mutex_init
(
&
serio
->
drv_mutex
);
device_initialize
(
&
serio
->
dev
);
...
...
@@ -542,6 +548,8 @@ static void serio_init_port(struct serio *serio)
*/
static
void
serio_add_port
(
struct
serio
*
serio
)
{
int
error
;
if
(
serio
->
parent
)
{
serio_pause_rx
(
serio
->
parent
);
serio
->
parent
->
child
=
serio
;
...
...
@@ -551,9 +559,19 @@ static void serio_add_port(struct serio *serio)
list_add_tail
(
&
serio
->
node
,
&
serio_list
);
if
(
serio
->
start
)
serio
->
start
(
serio
);
device_add
(
&
serio
->
dev
);
sysfs_create_group
(
&
serio
->
dev
.
kobj
,
&
serio_id_attr_group
);
serio
->
registered
=
1
;
error
=
device_add
(
&
serio
->
dev
);
if
(
error
)
printk
(
KERN_ERR
"serio: device_add() failed for %s (%s), error: %d
\n
"
,
serio
->
phys
,
serio
->
name
,
error
);
else
{
serio
->
registered
=
1
;
error
=
sysfs_create_group
(
&
serio
->
dev
.
kobj
,
&
serio_id_attr_group
);
if
(
error
)
printk
(
KERN_ERR
"serio: sysfs_create_group() failed for %s (%s), error: %d
\n
"
,
serio
->
phys
,
serio
->
name
,
error
);
}
}
/*
...
...
@@ -583,10 +601,10 @@ static void serio_destroy_port(struct serio *serio)
if
(
serio
->
registered
)
{
sysfs_remove_group
(
&
serio
->
dev
.
kobj
,
&
serio_id_attr_group
);
device_del
(
&
serio
->
dev
);
list_del_init
(
&
serio
->
node
);
serio
->
registered
=
0
;
}
list_del_init
(
&
serio
->
node
);
serio_remove_pending_events
(
serio
);
put_device
(
&
serio
->
dev
);
}
...
...
@@ -756,6 +774,17 @@ static struct bus_type serio_bus = {
.
remove
=
serio_driver_remove
,
};
static
void
serio_add_driver
(
struct
serio_driver
*
drv
)
{
int
error
;
error
=
driver_register
(
&
drv
->
driver
);
if
(
error
)
printk
(
KERN_ERR
"serio: driver_register() failed for %s, error: %d
\n
"
,
drv
->
driver
.
name
,
error
);
}
void
__serio_register_driver
(
struct
serio_driver
*
drv
,
struct
module
*
owner
)
{
drv
->
driver
.
bus
=
&
serio_bus
;
...
...
@@ -903,18 +932,26 @@ irqreturn_t serio_interrupt(struct serio *serio,
static
int
__init
serio_init
(
void
)
{
serio_task
=
kthread_run
(
serio_thread
,
NULL
,
"kseriod"
);
if
(
IS_ERR
(
serio_task
))
{
printk
(
KERN_ERR
"serio: Failed to start kseriod
\n
"
);
return
PTR_ERR
(
serio_task
);
}
int
error
;
serio_bus
.
dev_attrs
=
serio_device_attrs
;
serio_bus
.
drv_attrs
=
serio_driver_attrs
;
serio_bus
.
match
=
serio_bus_match
;
serio_bus
.
uevent
=
serio_uevent
;
serio_bus
.
resume
=
serio_resume
;
bus_register
(
&
serio_bus
);
error
=
bus_register
(
&
serio_bus
);
if
(
error
)
{
printk
(
KERN_ERR
"serio: failed to register serio bus, error: %d
\n
"
,
error
);
return
error
;
}
serio_task
=
kthread_run
(
serio_thread
,
NULL
,
"kseriod"
);
if
(
IS_ERR
(
serio_task
))
{
bus_unregister
(
&
serio_bus
);
error
=
PTR_ERR
(
serio_task
);
printk
(
KERN_ERR
"serio: Failed to start kseriod, error: %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
...
...
drivers/usb/input/ati_remote.c
View file @
40a64fa8
...
...
@@ -111,14 +111,28 @@
#define NAME_BUFSIZE 80
/* size of product name, path buffers */
#define DATA_BUFSIZE 63
/* size of URB data buffers */
/*
* Duplicate event filtering time.
* Sequential, identical KIND_FILTERED inputs with less than
* FILTER_TIME milliseconds between them are considered as repeat
* events. The hardware generates 5 events for the first keypress
* and we have to take this into account for an accurate repeat
* behaviour.
*/
#define FILTER_TIME 60
/* msec */
static
unsigned
long
channel_mask
;
module_param
(
channel_mask
,
ulong
,
0
4
44
);
module_param
(
channel_mask
,
ulong
,
0
6
44
);
MODULE_PARM_DESC
(
channel_mask
,
"Bitmask of remote control channels to ignore"
);
static
int
debug
;
module_param
(
debug
,
int
,
0
4
44
);
module_param
(
debug
,
int
,
0
6
44
);
MODULE_PARM_DESC
(
debug
,
"Enable extra debug messages and information"
);
static
int
repeat_filter
=
FILTER_TIME
;
module_param
(
repeat_filter
,
int
,
0644
);
MODULE_PARM_DESC
(
repeat_filter
,
"Repeat filter time, default = 60 msec"
);
#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
#undef err
#define err(format, arg...) printk(KERN_ERR format , ## arg)
...
...
@@ -143,18 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table);
static
char
init1
[]
=
{
0x01
,
0x00
,
0x20
,
0x14
};
static
char
init2
[]
=
{
0x01
,
0x00
,
0x20
,
0x14
,
0x20
,
0x20
,
0x20
};
/* Acceleration curve for directional control pad */
static
const
char
accel
[]
=
{
1
,
2
,
4
,
6
,
9
,
13
,
20
};
/* Duplicate event filtering time.
* Sequential, identical KIND_FILTERED inputs with less than
* FILTER_TIME jiffies between them are considered as repeat
* events. The hardware generates 5 events for the first keypress
* and we have to take this into account for an accurate repeat
* behaviour.
*/
#define FILTER_TIME 60
/* msec */
struct
ati_remote
{
struct
input_dev
*
idev
;
struct
usb_device
*
udev
;
...
...
@@ -411,6 +413,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
return
-
1
;
}
/*
* ati_remote_compute_accel
*
* Implements acceleration curve for directional control pad
* If elapsed time since last event is > 1/4 second, user "stopped",
* so reset acceleration. Otherwise, user is probably holding the control
* pad down, so we increase acceleration, ramping up over two seconds to
* a maximum speed.
*/
static
int
ati_remote_compute_accel
(
struct
ati_remote
*
ati_remote
)
{
static
const
char
accel
[]
=
{
1
,
2
,
4
,
6
,
9
,
13
,
20
};
unsigned
long
now
=
jiffies
;
int
acc
;
if
(
time_after
(
now
,
ati_remote
->
old_jiffies
+
msecs_to_jiffies
(
250
)))
{
acc
=
1
;
ati_remote
->
acc_jiffies
=
now
;
}
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
125
)))
acc
=
accel
[
0
];
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
250
)))
acc
=
accel
[
1
];
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
500
)))
acc
=
accel
[
2
];
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
1000
)))
acc
=
accel
[
3
];
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
1500
)))
acc
=
accel
[
4
];
else
if
(
time_before
(
now
,
ati_remote
->
acc_jiffies
+
msecs_to_jiffies
(
2000
)))
acc
=
accel
[
5
];
else
acc
=
accel
[
6
];
return
acc
;
}
/*
* ati_remote_report_input
*/
...
...
@@ -464,9 +503,9 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
if
(
ati_remote_tbl
[
index
].
kind
==
KIND_FILTERED
)
{
/* Filter duplicate events which happen "too close" together. */
if
(
(
ati_remote
->
old_data
[
0
]
==
data
[
1
])
&&
(
ati_remote
->
old_data
[
1
]
==
data
[
2
])
&&
time_before
(
jiffies
,
ati_remote
->
old_jiffies
+
msecs_to_jiffies
(
FILTER_TIME
)))
{
if
(
ati_remote
->
old_data
[
0
]
==
data
[
1
]
&&
ati_remote
->
old_data
[
1
]
==
data
[
2
]
&&
time_before
(
jiffies
,
ati_remote
->
old_jiffies
+
msecs_to_jiffies
(
repeat_filter
)))
{
ati_remote
->
repeat_count
++
;
}
else
{
ati_remote
->
repeat_count
=
0
;
...
...
@@ -476,75 +515,61 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
ati_remote
->
old_data
[
1
]
=
data
[
2
];
ati_remote
->
old_jiffies
=
jiffies
;
if
(
(
ati_remote
->
repeat_count
>
0
)
&&
(
ati_remote
->
repeat_count
<
5
)
)
if
(
ati_remote
->
repeat_count
>
0
&&
ati_remote
->
repeat_count
<
5
)
return
;
input_regs
(
dev
,
regs
);
input_event
(
dev
,
ati_remote_tbl
[
index
].
type
,
ati_remote_tbl
[
index
].
code
,
1
);
input_sync
(
dev
);
input_event
(
dev
,
ati_remote_tbl
[
index
].
type
,
ati_remote_tbl
[
index
].
code
,
0
);
input_sync
(
dev
);
return
;
}
}
else
{
/*
* Other event kinds are from the directional control pad, and have an
* acceleration factor applied to them. Without this acceleration, the
* control pad is mostly unusable.
*
* If elapsed time since last event is > 1/4 second, user "stopped",
* so reset acceleration. Otherwise, user is probably holding the control
* pad down, so we increase acceleration, ramping up over two seconds to
* a maximum speed. The acceleration curve is #defined above.
*/
if
(
time_after
(
jiffies
,
ati_remote
->
old_jiffies
+
(
HZ
>>
2
)))
{
acc
=
1
;
ati_remote
->
acc_jiffies
=
jiffies
;
}
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
(
HZ
>>
3
)))
acc
=
accel
[
0
];
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
(
HZ
>>
2
)))
acc
=
accel
[
1
];
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
(
HZ
>>
1
)))
acc
=
accel
[
2
];
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
HZ
))
acc
=
accel
[
3
];
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
HZ
+
(
HZ
>>
1
)))
acc
=
accel
[
4
];
else
if
(
time_before
(
jiffies
,
ati_remote
->
acc_jiffies
+
(
HZ
<<
1
)))
acc
=
accel
[
5
];
else
acc
=
accel
[
6
];
input_regs
(
dev
,
regs
);
switch
(
ati_remote_tbl
[
index
].
kind
)
{
case
KIND_ACCEL
:
input_event
(
dev
,
ati_remote_tbl
[
index
].
type
,
ati_remote_tbl
[
index
].
code
,
ati_remote_tbl
[
index
].
value
*
acc
);
break
;
case
KIND_LU
:
input_report_rel
(
dev
,
REL_X
,
-
acc
);
input_report_rel
(
dev
,
REL_Y
,
-
acc
);
break
;
case
KIND_RU
:
input_report_rel
(
dev
,
REL_X
,
acc
);
input_report_rel
(
dev
,
REL_Y
,
-
acc
);
break
;
case
KIND_LD
:
input_report_rel
(
dev
,
REL_X
,
-
acc
);
input_report_rel
(
dev
,
REL_Y
,
acc
);
break
;
case
KIND_RD
:
input_report_rel
(
dev
,
REL_X
,
acc
);
input_report_rel
(
dev
,
REL_Y
,
acc
);
break
;
default:
dev_dbg
(
&
ati_remote
->
interface
->
dev
,
"ati_remote kind=%d
\n
"
,
ati_remote_tbl
[
index
].
kind
);
}
input_sync
(
dev
);
/*
* Other event kinds are from the directional control pad, and have an
* acceleration factor applied to them. Without this acceleration, the
* control pad is mostly unusable.
*/
acc
=
ati_remote_compute_accel
(
ati_remote
);
input_regs
(
dev
,
regs
);
switch
(
ati_remote_tbl
[
index
].
kind
)
{
case
KIND_ACCEL
:
input_event
(
dev
,
ati_remote_tbl
[
index
].
type
,
ati_remote_tbl
[
index
].
code
,
ati_remote_tbl
[
index
].
value
*
acc
);
break
;
case
KIND_LU
:
input_report_rel
(
dev
,
REL_X
,
-
acc
);
input_report_rel
(
dev
,
REL_Y
,
-
acc
);
break
;
case
KIND_RU
:
input_report_rel
(
dev
,
REL_X
,
acc
);
input_report_rel
(
dev
,
REL_Y
,
-
acc
);
break
;
case
KIND_LD
:
input_report_rel
(
dev
,
REL_X
,
-
acc
);
input_report_rel
(
dev
,
REL_Y
,
acc
);
break
;
case
KIND_RD
:
input_report_rel
(
dev
,
REL_X
,
acc
);
input_report_rel
(
dev
,
REL_Y
,
acc
);
break
;
default:
dev_dbg
(
&
ati_remote
->
interface
->
dev
,
"ati_remote kind=%d
\n
"
,
ati_remote_tbl
[
index
].
kind
);
}
input_sync
(
dev
);
ati_remote
->
old_jiffies
=
jiffies
;
ati_remote
->
old_data
[
0
]
=
data
[
1
];
ati_remote
->
old_data
[
1
]
=
data
[
2
];
ati_remote
->
old_jiffies
=
jiffies
;
ati_remote
->
old_data
[
0
]
=
data
[
1
];
ati_remote
->
old_data
[
1
]
=
data
[
2
];
}
}
/*
...
...
drivers/usb/input/hid-input.c
View file @
40a64fa8
...
...
@@ -607,7 +607,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
}
if
(
usage
->
hat_min
<
usage
->
hat_max
||
usage
->
hat_dir
)
{
if
(
usage
->
type
==
EV_ABS
&&
(
usage
->
hat_min
<
usage
->
hat_max
||
usage
->
hat_dir
))
{
int
i
;
for
(
i
=
usage
->
code
;
i
<
usage
->
code
+
2
&&
i
<=
max
;
i
++
)
{
input_set_abs_params
(
input
,
i
,
-
1
,
1
,
0
,
0
);
...
...
drivers/usb/input/hiddev.c
View file @
40a64fa8
...
...
@@ -49,7 +49,7 @@ struct hiddev {
int
open
;
wait_queue_head_t
wait
;
struct
hid_device
*
hid
;
struct
hiddev_list
*
list
;
struct
list_head
list
;
};
struct
hiddev_list
{
...
...
@@ -59,7 +59,7 @@ struct hiddev_list {
unsigned
flags
;
struct
fasync_struct
*
fasync
;
struct
hiddev
*
hiddev
;
struct
hiddev_list
*
next
;
struct
list_head
node
;
};
static
struct
hiddev
*
hiddev_table
[
HIDDEV_MINORS
];
...
...
@@ -73,12 +73,15 @@ static struct hiddev *hiddev_table[HIDDEV_MINORS];
static
struct
hid_report
*
hiddev_lookup_report
(
struct
hid_device
*
hid
,
struct
hiddev_report_info
*
rinfo
)
{
unsigned
flags
=
rinfo
->
report_id
&
~
HID_REPORT_ID_MASK
;
unsigned
int
flags
=
rinfo
->
report_id
&
~
HID_REPORT_ID_MASK
;
unsigned
int
rid
=
rinfo
->
report_id
&
HID_REPORT_ID_MASK
;
struct
hid_report_enum
*
report_enum
;
struct
hid_report
*
report
;
struct
list_head
*
list
;
if
(
rinfo
->
report_type
<
HID_REPORT_TYPE_MIN
||
rinfo
->
report_type
>
HID_REPORT_TYPE_MAX
)
return
NULL
;
rinfo
->
report_type
>
HID_REPORT_TYPE_MAX
)
return
NULL
;
report_enum
=
hid
->
report_enum
+
(
rinfo
->
report_type
-
HID_REPORT_TYPE_MIN
);
...
...
@@ -88,21 +91,25 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
break
;
case
HID_REPORT_ID_FIRST
:
list
=
report_enum
->
report_list
.
next
;
if
(
list
==
&
report_enum
->
report_list
)
if
(
list_empty
(
&
report_enum
->
report_list
))
return
NULL
;
rinfo
->
report_id
=
((
struct
hid_report
*
)
list
)
->
id
;
list
=
report_enum
->
report_list
.
next
;
report
=
list_entry
(
list
,
struct
hid_report
,
list
);
rinfo
->
report_id
=
report
->
id
;
break
;
case
HID_REPORT_ID_NEXT
:
list
=
(
struct
list_head
*
)
report_enum
->
report_id_hash
[
rinfo
->
report_id
&
HID_REPORT_ID_MASK
];
if
(
list
==
NULL
)
report
=
report_enum
->
report_id_hash
[
rid
];
if
(
!
report
)
return
NULL
;
list
=
list
->
next
;
list
=
report
->
list
.
next
;
if
(
list
==
&
report_enum
->
report_list
)
return
NULL
;
rinfo
->
report_id
=
((
struct
hid_report
*
)
list
)
->
id
;
report
=
list_entry
(
list
,
struct
hid_report
,
list
);
rinfo
->
report_id
=
report
->
id
;
break
;
default:
...
...
@@ -125,12 +132,13 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
struct
hid_field
*
field
;
if
(
uref
->
report_type
<
HID_REPORT_TYPE_MIN
||
uref
->
report_type
>
HID_REPORT_TYPE_MAX
)
return
NULL
;
uref
->
report_type
>
HID_REPORT_TYPE_MAX
)
return
NULL
;
report_enum
=
hid
->
report_enum
+
(
uref
->
report_type
-
HID_REPORT_TYPE_MIN
);
list_for_each_entry
(
report
,
&
report_enum
->
report_list
,
list
)
list_for_each_entry
(
report
,
&
report_enum
->
report_list
,
list
)
{
for
(
i
=
0
;
i
<
report
->
maxfield
;
i
++
)
{
field
=
report
->
field
[
i
];
for
(
j
=
0
;
j
<
field
->
maxusage
;
j
++
)
{
...
...
@@ -142,6 +150,7 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
}
}
}
}
return
NULL
;
}
...
...
@@ -150,9 +159,9 @@ static void hiddev_send_event(struct hid_device *hid,
struct
hiddev_usage_ref
*
uref
)
{
struct
hiddev
*
hiddev
=
hid
->
hiddev
;
struct
hiddev_list
*
list
=
hiddev
->
list
;
struct
hiddev_list
*
list
;
while
(
list
)
{
list_for_each_entry
(
list
,
&
hiddev
->
list
,
node
)
{
if
(
uref
->
field_index
!=
HID_FIELD_INDEX_NONE
||
(
list
->
flags
&
HIDDEV_FLAG_REPORT
)
!=
0
)
{
list
->
buffer
[
list
->
head
]
=
*
uref
;
...
...
@@ -160,8 +169,6 @@ static void hiddev_send_event(struct hid_device *hid,
(
HIDDEV_BUFFER_SIZE
-
1
);
kill_fasync
(
&
list
->
fasync
,
SIGIO
,
POLL_IN
);
}
list
=
list
->
next
;
}
wake_up_interruptible
(
&
hiddev
->
wait
);
...
...
@@ -180,7 +187,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
uref
.
report_type
=
(
type
==
HID_INPUT_REPORT
)
?
HID_REPORT_TYPE_INPUT
:
((
type
==
HID_OUTPUT_REPORT
)
?
HID_REPORT_TYPE_OUTPUT
:
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
uref
.
report_id
=
field
->
report
->
id
;
uref
.
field_index
=
field
->
index
;
uref
.
usage_index
=
(
usage
-
field
->
usage
);
...
...
@@ -200,7 +207,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
uref
.
report_type
=
(
type
==
HID_INPUT_REPORT
)
?
HID_REPORT_TYPE_INPUT
:
((
type
==
HID_OUTPUT_REPORT
)
?
HID_REPORT_TYPE_OUTPUT
:
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
((
type
==
HID_FEATURE_REPORT
)
?
HID_REPORT_TYPE_FEATURE
:
0
));
uref
.
report_id
=
report
->
id
;
uref
.
field_index
=
HID_FIELD_INDEX_NONE
;
...
...
@@ -213,7 +220,9 @@ static int hiddev_fasync(int fd, struct file *file, int on)
{
int
retval
;
struct
hiddev_list
*
list
=
file
->
private_data
;
retval
=
fasync_helper
(
fd
,
file
,
on
,
&
list
->
fasync
);
return
retval
<
0
?
retval
:
0
;
}
...
...
@@ -224,14 +233,9 @@ static int hiddev_fasync(int fd, struct file *file, int on)
static
int
hiddev_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
hiddev_list
*
list
=
file
->
private_data
;
struct
hiddev_list
**
listptr
;
listptr
=
&
list
->
hiddev
->
list
;
hiddev_fasync
(
-
1
,
file
,
0
);
while
(
*
listptr
&&
(
*
listptr
!=
list
))
listptr
=
&
((
*
listptr
)
->
next
);
*
listptr
=
(
*
listptr
)
->
next
;
list_del
(
&
list
->
node
);
if
(
!--
list
->
hiddev
->
open
)
{
if
(
list
->
hiddev
->
exist
)
...
...
@@ -248,7 +252,8 @@ static int hiddev_release(struct inode * inode, struct file * file)
/*
* open file op
*/
static
int
hiddev_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
static
int
hiddev_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
hiddev_list
*
list
;
int
i
=
iminor
(
inode
)
-
HIDDEV_MINOR_BASE
;
...
...
@@ -260,9 +265,7 @@ static int hiddev_open(struct inode * inode, struct file * file) {
return
-
ENOMEM
;
list
->
hiddev
=
hiddev_table
[
i
];
list
->
next
=
hiddev_table
[
i
]
->
list
;
hiddev_table
[
i
]
->
list
=
list
;
list_add_tail
(
&
list
->
node
,
&
hiddev_table
[
i
]
->
list
);
file
->
private_data
=
list
;
if
(
!
list
->
hiddev
->
open
++
)
...
...
@@ -362,6 +365,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
static
unsigned
int
hiddev_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
struct
hiddev_list
*
list
=
file
->
private_data
;
poll_wait
(
file
,
&
list
->
hiddev
->
wait
,
wait
);
if
(
list
->
head
!=
list
->
tail
)
return
POLLIN
|
POLLRDNORM
;
...
...
@@ -382,7 +386,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct
hiddev_collection_info
cinfo
;
struct
hiddev_report_info
rinfo
;
struct
hiddev_field_info
finfo
;
struct
hiddev_usage_ref_multi
*
uref_multi
=
NULL
;
struct
hiddev_usage_ref_multi
*
uref_multi
=
NULL
;
struct
hiddev_usage_ref
*
uref
;
struct
hiddev_devinfo
dinfo
;
struct
hid_report
*
report
;
...
...
@@ -764,15 +768,15 @@ int hiddev_connect(struct hid_device *hid)
}
init_waitqueue_head
(
&
hiddev
->
wait
);
hiddev_table
[
hid
->
intf
->
minor
-
HIDDEV_MINOR_BASE
]
=
hiddev
;
INIT_LIST_HEAD
(
&
hiddev
->
list
);
hiddev
->
hid
=
hid
;
hiddev
->
exist
=
1
;
hid
->
minor
=
hid
->
intf
->
minor
;
hid
->
hiddev
=
hiddev
;
hiddev_table
[
hid
->
intf
->
minor
-
HIDDEV_MINOR_BASE
]
=
hiddev
;
return
0
;
}
...
...
include/linux/input.h
View file @
40a64fa8
...
...
@@ -893,7 +893,6 @@ struct input_dev {
int
(
*
open
)(
struct
input_dev
*
dev
);
void
(
*
close
)(
struct
input_dev
*
dev
);
int
(
*
accept
)(
struct
input_dev
*
dev
,
struct
file
*
file
);
int
(
*
flush
)(
struct
input_dev
*
dev
,
struct
file
*
file
);
int
(
*
event
)(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
);
int
(
*
upload_effect
)(
struct
input_dev
*
dev
,
struct
ff_effect
*
effect
);
...
...
@@ -961,6 +960,26 @@ struct input_dev {
struct
input_handle
;
/**
* struct input_handler - implements one of interfaces for input devices
* @private: driver-specific data
* @event: event handler
* @connect: called when attaching a handler to an input device
* @disconnect: disconnects a handler from input device
* @start: starts handler for given handle. This function is called by
* input core right after connect() method and also when a process
* that "grabbed" a device releases it
* @fops: file operations this driver implements
* @minor: beginning of range of 32 minors for devices this driver
* can provide
* @name: name of the handler, to be shown in /proc/bus/input/handlers
* @id_table: pointer to a table of input_device_ids this driver can
* handle
* @blacklist: prointer to a table of input_device_ids this driver should
* ignore even if they match @id_table
* @h_list: list of input handles associated with the handler
* @node: for placing the driver onto input_handler_list
*/
struct
input_handler
{
void
*
private
;
...
...
@@ -968,6 +987,7 @@ struct input_handler {
void
(
*
event
)(
struct
input_handle
*
handle
,
unsigned
int
type
,
unsigned
int
code
,
int
value
);
struct
input_handle
*
(
*
connect
)(
struct
input_handler
*
handler
,
struct
input_dev
*
dev
,
struct
input_device_id
*
id
);
void
(
*
disconnect
)(
struct
input_handle
*
handle
);
void
(
*
start
)(
struct
input_handle
*
handle
);
const
struct
file_operations
*
fops
;
int
minor
;
...
...
@@ -1030,10 +1050,10 @@ void input_release_device(struct input_handle *);
int
input_open_device
(
struct
input_handle
*
);
void
input_close_device
(
struct
input_handle
*
);
int
input_accept_process
(
struct
input_handle
*
handle
,
struct
file
*
file
);
int
input_flush_device
(
struct
input_handle
*
handle
,
struct
file
*
file
);
void
input_event
(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
);
void
input_inject_event
(
struct
input_handle
*
handle
,
unsigned
int
type
,
unsigned
int
code
,
int
value
);
static
inline
void
input_report_key
(
struct
input_dev
*
dev
,
unsigned
int
code
,
int
value
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment