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
8a2e73e1
Commit
8a2e73e1
authored
Dec 29, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/spare/repo/linux-2.5
into redhat.com:/spare/repo/net-drivers-2.5
parents
7e223b72
dbf8623b
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
1086 additions
and
725 deletions
+1086
-725
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+2
-1
Makefile
Makefile
+1
-1
arch/i386/kernel/irq.c
arch/i386/kernel/irq.c
+14
-0
arch/i386/lib/usercopy.c
arch/i386/lib/usercopy.c
+3
-1
arch/i386/pci/irq.c
arch/i386/pci/irq.c
+1
-9
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+1
-1
drivers/block/scsi_ioctl.c
drivers/block/scsi_ioctl.c
+15
-8
drivers/char/keyboard.c
drivers/char/keyboard.c
+21
-14
drivers/ide/ide-cd.c
drivers/ide/ide-cd.c
+4
-0
drivers/ide/ide-cd.h
drivers/ide/ide-cd.h
+2
-1
drivers/input/input.c
drivers/input/input.c
+8
-6
drivers/input/joydev.c
drivers/input/joydev.c
+10
-4
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/atkbd.c
+162
-88
drivers/input/mouse/Kconfig
drivers/input/mouse/Kconfig
+7
-16
drivers/input/mouse/logips2pp.c
drivers/input/mouse/logips2pp.c
+21
-1
drivers/input/mouse/logips2pp.h
drivers/input/mouse/logips2pp.h
+1
-1
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse-base.c
+180
-155
drivers/input/mouse/psmouse.h
drivers/input/mouse/psmouse.h
+13
-0
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.c
+121
-111
drivers/input/mouse/synaptics.h
drivers/input/mouse/synaptics.h
+1
-5
drivers/input/serio/i8042.c
drivers/input/serio/i8042.c
+331
-204
drivers/input/serio/serio.c
drivers/input/serio/serio.c
+83
-23
drivers/scsi/qla1280.c
drivers/scsi/qla1280.c
+13
-2
drivers/usb/core/devio.c
drivers/usb/core/devio.c
+1
-1
drivers/usb/core/hub.c
drivers/usb/core/hub.c
+7
-3
drivers/usb/core/usb.c
drivers/usb/core/usb.c
+1
-0
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.c
+3
-0
drivers/usb/image/Kconfig
drivers/usb/image/Kconfig
+3
-1
drivers/usb/misc/auerswald.c
drivers/usb/misc/auerswald.c
+2
-2
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-serial.c
+14
-36
drivers/usb/storage/datafab.c
drivers/usb/storage/datafab.c
+1
-1
drivers/usb/storage/jumpshot.c
drivers/usb/storage/jumpshot.c
+1
-1
include/asm-i386/irq.h
include/asm-i386/irq.h
+1
-0
include/linux/input.h
include/linux/input.h
+1
-0
include/linux/keyboard.h
include/linux/keyboard.h
+1
-2
include/linux/serio.h
include/linux/serio.h
+6
-2
kernel/sched.c
kernel/sched.c
+15
-20
lib/kobject.c
lib/kobject.c
+7
-4
scripts/file2alias.c
scripts/file2alias.c
+7
-0
No files found.
Documentation/kernel-parameters.txt
View file @
8a2e73e1
...
...
@@ -790,7 +790,8 @@ running once the system is up.
before loading.
See Documentation/ramdisk.txt.
psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
psmouse_proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
probe for (bare|imps|exps).
psmouse_resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many
...
...
Makefile
View file @
8a2e73e1
VERSION
=
2
PATCHLEVEL
=
6
SUBLEVEL
=
0
EXTRAVERSION
=
-test11
EXTRAVERSION
=
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
...
...
arch/i386/kernel/irq.c
View file @
8a2e73e1
...
...
@@ -505,6 +505,20 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
return
1
;
}
int
can_request_irq
(
unsigned
int
irq
,
unsigned
long
irqflags
)
{
struct
irqaction
*
action
;
if
(
irq
>=
NR_IRQS
)
return
0
;
action
=
irq_desc
[
irq
].
action
;
if
(
action
)
{
if
(
irqflags
&
action
->
flags
&
SA_SHIRQ
)
action
=
NULL
;
}
return
!
action
;
}
/**
* request_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
...
...
arch/i386/lib/usercopy.c
View file @
8a2e73e1
...
...
@@ -541,8 +541,10 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long
goto
survive
;
}
if
(
retval
!=
1
)
if
(
retval
!=
1
)
{
up_read
(
&
current
->
mm
->
mmap_sem
);
break
;
}
maddr
=
kmap_atomic
(
pg
,
KM_USER0
);
memcpy
(
maddr
+
offset
,
from
,
len
);
...
...
arch/i386/pci/irq.c
View file @
8a2e73e1
...
...
@@ -695,11 +695,6 @@ static struct irq_info *pirq_get_info(struct pci_dev *dev)
return
NULL
;
}
static
irqreturn_t
pcibios_test_irq_handler
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
return
IRQ_NONE
;
}
static
int
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
)
{
u8
pin
;
...
...
@@ -761,11 +756,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
!
(
mask
&
(
1
<<
i
)))
continue
;
if
(
pirq_penalty
[
i
]
<
pirq_penalty
[
newirq
]
&&
!
request_irq
(
i
,
pcibios_test_irq_handler
,
SA_SHIRQ
,
"pci-test"
,
dev
))
{
free_irq
(
i
,
dev
);
if
(
pirq_penalty
[
i
]
<
pirq_penalty
[
newirq
]
&&
can_request_irq
(
i
,
SA_SHIRQ
))
newirq
=
i
;
}
}
}
DBG
(
" -> newirq=%d"
,
newirq
);
...
...
drivers/block/ll_rw_blk.c
View file @
8a2e73e1
...
...
@@ -2460,7 +2460,7 @@ static int __end_that_request_first(struct request *req, int uptodate,
if
(
!
uptodate
)
{
error
=
-
EIO
;
if
(
!
(
req
->
flags
&
REQ_QUIET
))
if
(
blk_fs_request
(
req
)
&&
!
(
req
->
flags
&
REQ_QUIET
))
printk
(
"end_request: I/O error, dev %s, sector %llu
\n
"
,
req
->
rq_disk
?
req
->
rq_disk
->
disk_name
:
"?"
,
(
unsigned
long
long
)
req
->
sector
);
...
...
drivers/block/scsi_ioctl.c
View file @
8a2e73e1
...
...
@@ -150,7 +150,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
struct
request
*
rq
;
struct
bio
*
bio
;
char
sense
[
SCSI_SENSE_BUFFERSIZE
];
unsigned
char
cdb
[
BLK_MAX_CDB
];
void
*
buffer
;
if
(
hdr
->
interface_id
!=
'S'
)
...
...
@@ -167,9 +166,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
if
(
hdr
->
dxfer_len
>
(
q
->
max_sectors
<<
9
))
return
-
EIO
;
if
(
copy_from_user
(
cdb
,
hdr
->
cmdp
,
hdr
->
cmd_len
))
return
-
EFAULT
;
reading
=
writing
=
0
;
buffer
=
NULL
;
bio
=
NULL
;
...
...
@@ -220,7 +216,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
* fill in request structure
*/
rq
->
cmd_len
=
hdr
->
cmd_len
;
memcpy
(
rq
->
cmd
,
cdb
,
hdr
->
cmd_len
);
memcpy
(
rq
->
cmd
,
hdr
->
cmdp
,
hdr
->
cmd_len
);
if
(
sizeof
(
rq
->
cmd
)
!=
hdr
->
cmd_len
)
memset
(
rq
->
cmd
+
hdr
->
cmd_len
,
0
,
sizeof
(
rq
->
cmd
)
-
hdr
->
cmd_len
);
...
...
@@ -436,12 +432,23 @@ int scsi_cmd_ioctl(struct block_device *bdev, unsigned int cmd, unsigned long ar
break
;
case
SG_IO
:
{
struct
sg_io_hdr
hdr
;
unsigned
char
cdb
[
BLK_MAX_CDB
],
*
old_cdb
;
if
(
copy_from_user
(
&
hdr
,
(
struct
sg_io_hdr
*
)
arg
,
sizeof
(
hdr
)))
{
err
=
-
EFAULT
;
err
=
-
EFAULT
;
if
(
copy_from_user
(
&
hdr
,
(
struct
sg_io_hdr
*
)
arg
,
sizeof
(
hdr
)))
break
;
}
err
=
-
EINVAL
;
if
(
hdr
.
cmd_len
>
sizeof
(
rq
->
cmd
))
break
;
err
=
-
EFAULT
;
if
(
copy_from_user
(
cdb
,
hdr
.
cmdp
,
hdr
.
cmd_len
))
break
;
old_cdb
=
hdr
.
cmdp
;
hdr
.
cmdp
=
cdb
;
err
=
sg_io
(
q
,
bdev
,
&
hdr
);
hdr
.
cmdp
=
old_cdb
;
if
(
copy_to_user
((
struct
sg_io_hdr
*
)
arg
,
&
hdr
,
sizeof
(
hdr
)))
err
=
-
EFAULT
;
break
;
...
...
drivers/char/keyboard.c
View file @
8a2e73e1
...
...
@@ -941,16 +941,16 @@ static unsigned short x86_keycodes[256] =
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
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
,
43
,
85
,
86
,
87
,
88
,
115
,
119
,
120
,
121
,
375
,
123
,
90
,
284
,
285
,
309
,
298
,
312
,
91
,
327
,
328
,
329
,
331
,
333
,
335
,
336
,
337
,
338
,
339
,
367
,
288
,
302
,
304
,
350
,
92
,
334
,
512
,
116
,
377
,
109
,
111
,
373
,
347
,
348
,
349
,
360
,
93
,
94
,
95
,
98
,
376
,
100
,
101
,
321
,
316
,
354
,
286
,
289
,
102
,
351
,
355
,
80
,
81
,
82
,
83
,
84
,
93
,
86
,
87
,
88
,
94
,
95
,
85
,
259
,
375
,
260
,
90
,
284
,
285
,
309
,
311
,
312
,
91
,
327
,
328
,
329
,
331
,
333
,
335
,
336
,
337
,
338
,
339
,
367
,
288
,
302
,
304
,
350
,
89
,
334
,
326
,
116
,
377
,
109
,
111
,
126
,
347
,
348
,
349
,
360
,
261
,
262
,
263
,
298
,
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
,
291
,
108
,
381
,
281
,
290
,
272
,
292
,
305
,
280
,
99
,
112
,
257
,
258
,
359
,
270
,
114
,
118
,
117
,
125
,
374
,
379
,
115
,
112
,
125
,
121
,
123
,
264
,
265
,
266
,
267
,
268
,
269
,
271
,
273
,
276
,
277
,
278
,
282
,
283
,
295
,
296
,
297
,
299
,
300
,
301
,
293
,
303
,
307
,
308
,
310
,
313
,
314
,
315
,
317
,
318
,
319
,
320
,
357
,
322
,
323
,
324
,
325
,
32
6
,
330
,
332
,
340
,
365
,
342
,
343
,
344
,
345
,
346
,
356
,
113
,
341
,
368
,
369
,
370
,
371
,
372
};
291
,
108
,
381
,
281
,
290
,
272
,
292
,
305
,
280
,
99
,
112
,
257
,
258
,
359
,
113
,
114
,
264
,
117
,
271
,
374
,
379
,
115
,
125
,
273
,
121
,
123
,
92
,
265
,
266
,
267
,
268
,
269
,
120
,
119
,
118
,
277
,
278
,
282
,
283
,
295
,
296
,
297
,
299
,
300
,
301
,
293
,
303
,
307
,
308
,
310
,
313
,
314
,
315
,
317
,
318
,
319
,
320
,
357
,
322
,
323
,
324
,
325
,
27
6
,
330
,
332
,
340
,
365
,
342
,
343
,
344
,
345
,
346
,
356
,
270
,
341
,
368
,
369
,
370
,
371
,
372
};
#ifdef CONFIG_MAC_EMUMOUSEBTN
extern
int
mac_hid_mouse_emulate_buttons
(
int
,
int
,
int
);
...
...
@@ -972,11 +972,18 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
if
(
keycode
>
255
||
!
x86_keycodes
[
keycode
])
return
-
1
;
if
(
keycode
==
KEY_PAUSE
)
{
put_queue
(
vc
,
0xe1
);
put_queue
(
vc
,
0x1d
|
up_flag
);
put_queue
(
vc
,
0x45
|
up_flag
);
return
0
;
switch
(
keycode
)
{
case
KEY_PAUSE
:
put_queue
(
vc
,
0xe1
);
put_queue
(
vc
,
0x1d
|
up_flag
);
put_queue
(
vc
,
0x45
|
up_flag
);
return
0
;
case
KEY_LANG1
:
if
(
!
up_flag
)
put_queue
(
vc
,
0xf1
);
return
0
;
case
KEY_LANG2
:
if
(
!
up_flag
)
put_queue
(
vc
,
0xf2
);
return
0
;
}
if
(
keycode
==
KEY_SYSRQ
&&
sysrq_alt
)
{
...
...
drivers/ide/ide-cd.c
View file @
8a2e73e1
...
...
@@ -799,6 +799,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* sector... If we got here the error is not correctable */
ide_dump_status
(
drive
,
"media error (bad sector)"
,
stat
);
do_end_request
=
1
;
}
else
if
(
sense_key
==
BLANK_CHECK
)
{
/* Disk appears blank ?? */
ide_dump_status
(
drive
,
"media error (blank)"
,
stat
);
do_end_request
=
1
;
}
else
if
((
err
&
~
ABRT_ERR
)
!=
0
)
{
/* Go to the default handler
for other errors. */
...
...
drivers/ide/ide-cd.h
View file @
8a2e73e1
...
...
@@ -501,6 +501,7 @@ struct cdrom_info {
#define ILLEGAL_REQUEST 0x05
#define UNIT_ATTENTION 0x06
#define DATA_PROTECT 0x07
#define BLANK_CHECK 0x08
#define ABORTED_COMMAND 0x0b
#define MISCOMPARE 0x0e
...
...
@@ -578,7 +579,7 @@ const char * const sense_key_texts[16] = {
"Illegal request"
,
"Unit attention"
,
"Data protect"
,
"
(reserved)
"
,
"
Blank check
"
,
"(reserved)"
,
"(reserved)"
,
"Aborted command"
,
...
...
drivers/input/input.c
View file @
8a2e73e1
...
...
@@ -447,9 +447,10 @@ void input_register_device(struct input_dev *dev)
list_add_tail
(
&
dev
->
node
,
&
input_dev_list
);
list_for_each_entry
(
handler
,
&
input_handler_list
,
node
)
if
((
id
=
input_match_device
(
handler
->
id_table
,
dev
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
input_link_handle
(
handle
);
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
)))
input_link_handle
(
handle
);
#ifdef CONFIG_HOTPLUG
input_call_hotplug
(
"add"
,
dev
);
...
...
@@ -507,9 +508,10 @@ void input_register_handler(struct input_handler *handler)
list_add_tail
(
&
handler
->
node
,
&
input_handler_list
);
list_for_each_entry
(
dev
,
&
input_dev_list
,
node
)
if
((
id
=
input_match_device
(
handler
->
id_table
,
dev
)))
if
((
handle
=
handler
->
connect
(
handler
,
dev
,
id
)))
input_link_handle
(
handle
);
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
)))
input_link_handle
(
handle
);
#ifdef CONFIG_PROC_FS
input_devices_state
++
;
...
...
drivers/input/joydev.c
View file @
8a2e73e1
...
...
@@ -380,10 +380,6 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
struct
joydev
*
joydev
;
int
i
,
j
,
t
,
minor
;
/* Avoid tablets */
if
(
test_bit
(
EV_KEY
,
dev
->
evbit
)
&&
test_bit
(
BTN_TOUCH
,
dev
->
keybit
))
return
NULL
;
for
(
minor
=
0
;
minor
<
JOYDEV_MINORS
&&
joydev_table
[
minor
];
minor
++
);
if
(
minor
==
JOYDEV_MINORS
)
{
printk
(
KERN_ERR
"joydev: no more free joydev devices
\n
"
);
...
...
@@ -464,6 +460,15 @@ static void joydev_disconnect(struct input_handle *handle)
joydev_free
(
joydev
);
}
static
struct
input_device_id
joydev_blacklist
[]
=
{
{
.
flags
=
INPUT_DEVICE_ID_MATCH_EVBIT
|
INPUT_DEVICE_ID_MATCH_KEYBIT
,
.
evbit
=
{
BIT
(
EV_KEY
)
},
.
keybit
=
{
[
LONG
(
BTN_TOUCH
)]
=
BIT
(
BTN_TOUCH
)
},
},
/* Avoid itouchpads, touchscreens and tablets */
{
},
/* Terminating entry */
};
static
struct
input_device_id
joydev_ids
[]
=
{
{
.
flags
=
INPUT_DEVICE_ID_MATCH_EVBIT
|
INPUT_DEVICE_ID_MATCH_ABSBIT
,
...
...
@@ -493,6 +498,7 @@ static struct input_handler joydev_handler = {
.
minor
=
JOYDEV_MINOR_BASE
,
.
name
=
"joydev"
,
.
id_table
=
joydev_ids
,
.
blacklist
=
joydev_blacklist
,
};
static
int
__init
joydev_init
(
void
)
...
...
drivers/input/keyboard/atkbd.c
View file @
8a2e73e1
...
...
@@ -48,33 +48,30 @@ static int atkbd_softrepeat;
*/
static
unsigned
char
atkbd_set2_keycode
[
512
]
=
{
0
,
67
,
65
,
63
,
61
,
59
,
60
,
88
,
0
,
68
,
66
,
64
,
62
,
15
,
41
,
85
,
0
,
56
,
42
,
182
,
29
,
16
,
2
,
89
,
0
,
0
,
44
,
31
,
30
,
17
,
3
,
90
,
0
,
46
,
45
,
32
,
18
,
5
,
4
,
91
,
90
,
57
,
47
,
33
,
20
,
19
,
6
,
0
,
91
,
49
,
48
,
35
,
34
,
21
,
7
,
0
,
0
,
0
,
50
,
36
,
22
,
8
,
9
,
0
,
0
,
67
,
65
,
63
,
61
,
59
,
60
,
88
,
0
,
68
,
66
,
64
,
62
,
15
,
41
,
117
,
0
,
56
,
42
,
182
,
29
,
16
,
2
,
0
,
0
,
0
,
44
,
31
,
30
,
17
,
3
,
0
,
0
,
46
,
45
,
32
,
18
,
5
,
4
,
186
,
0
,
57
,
47
,
33
,
20
,
19
,
6
,
85
,
0
,
49
,
48
,
35
,
34
,
21
,
7
,
89
,
0
,
0
,
50
,
36
,
22
,
8
,
9
,
90
,
0
,
51
,
37
,
23
,
24
,
11
,
10
,
0
,
0
,
52
,
53
,
38
,
39
,
25
,
12
,
0
,
122
,
89
,
40
,
120
,
26
,
13
,
0
,
0
,
58
,
54
,
28
,
27
,
0
,
43
,
0
,
0
,
85
,
86
,
90
,
91
,
92
,
93
,
14
,
94
,
95
,
79
,
183
,
75
,
71
,
121
,
0
,
123
,
0
,
181
,
40
,
0
,
26
,
13
,
0
,
0
,
58
,
54
,
28
,
27
,
0
,
43
,
0
,
194
,
0
,
86
,
193
,
192
,
184
,
0
,
14
,
185
,
0
,
79
,
182
,
75
,
71
,
124
,
0
,
0
,
82
,
83
,
80
,
76
,
77
,
72
,
1
,
69
,
87
,
78
,
81
,
74
,
55
,
73
,
70
,
99
,
0
,
0
,
0
,
65
,
99
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
25
5
,
0
,
0
,
92
,
90
,
85
,
0
,
137
,
0
,
0
,
0
,
0
,
91
,
89
,
144
,
115
,
0
,
217
,
100
,
255
,
0
,
97
,
165
,
164
,
0
,
156
,
0
,
0
,
140
,
115
,
0
,
0
,
125
,
1
73
,
114
,
0
,
113
,
152
,
163
,
151
,
126
,
128
,
166
,
0
,
140
,
0
,
147
,
0
,
127
,
159
,
167
,
115
,
160
,
164
,
0
,
0
,
116
,
158
,
0
,
150
,
166
,
0
,
0
,
0
,
142
,
157
,
0
,
114
,
166
,
168
,
0
,
0
,
213
,
155
,
0
,
98
,
113
,
0
,
163
,
0
,
138
,
226
,
0
,
0
,
0
,
0
,
0
,
153
,
140
,
0
,
255
,
96
,
0
,
0
,
0
,
143
,
0
,
133
,
0
,
116
,
0
,
143
,
0
,
174
,
133
,
0
,
107
,
0
,
105
,
102
,
0
,
0
,
112
,
110
,
111
,
108
,
112
,
106
,
103
,
0
,
119
,
0
,
118
,
109
,
0
,
99
,
104
,
119
217
,
100
,
255
,
0
,
97
,
165
,
0
,
0
,
156
,
0
,
0
,
0
,
0
,
0
,
0
,
12
5
,
173
,
114
,
0
,
113
,
0
,
0
,
0
,
126
,
128
,
0
,
0
,
140
,
0
,
0
,
0
,
127
,
159
,
0
,
115
,
0
,
164
,
0
,
0
,
116
,
158
,
0
,
150
,
166
,
0
,
0
,
0
,
142
,
1
57
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
155
,
0
,
98
,
0
,
0
,
163
,
0
,
0
,
226
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
255
,
96
,
0
,
0
,
0
,
143
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
107
,
0
,
105
,
102
,
0
,
0
,
112
,
110
,
111
,
108
,
112
,
106
,
103
,
0
,
119
,
0
,
118
,
109
,
0
,
99
,
104
,
119
,
0
,
0
,
0
,
0
,
65
,
99
,
};
static
unsigned
char
atkbd_set3_keycode
[
512
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
59
,
1
,
138
,
128
,
129
,
130
,
15
,
41
,
60
,
131
,
29
,
42
,
86
,
58
,
16
,
2
,
61
,
133
,
56
,
44
,
31
,
30
,
17
,
3
,
62
,
134
,
46
,
45
,
32
,
18
,
5
,
4
,
63
,
135
,
57
,
47
,
33
,
20
,
19
,
6
,
64
,
...
...
@@ -83,25 +80,21 @@ static unsigned char atkbd_set3_keycode[512] = {
113
,
114
,
40
,
84
,
26
,
13
,
87
,
99
,
97
,
54
,
28
,
27
,
43
,
84
,
88
,
70
,
108
,
105
,
119
,
103
,
111
,
107
,
14
,
110
,
0
,
79
,
106
,
75
,
71
,
109
,
102
,
104
,
82
,
83
,
80
,
76
,
77
,
72
,
69
,
98
,
0
,
96
,
81
,
0
,
78
,
73
,
55
,
85
,
89
,
90
,
91
,
92
,
74
,
185
,
184
,
182
,
0
,
0
,
0
,
125
,
126
,
127
,
112
,
0
,
0
,
139
,
150
,
163
,
165
,
115
,
152
,
150
,
166
,
140
,
160
,
154
,
113
,
114
,
167
,
168
,
148
,
149
,
147
,
140
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
255
148
,
149
,
147
,
140
};
static
unsigned
char
atkbd_unxlate_table
[
128
]
=
{
0
,
118
,
22
,
30
,
38
,
37
,
46
,
54
,
61
,
62
,
70
,
69
,
78
,
85
,
102
,
13
,
21
,
29
,
36
,
45
,
44
,
53
,
60
,
67
,
68
,
77
,
84
,
91
,
90
,
20
,
28
,
27
,
35
,
43
,
52
,
51
,
59
,
66
,
75
,
76
,
82
,
14
,
18
,
93
,
26
,
34
,
33
,
42
,
50
,
49
,
58
,
65
,
73
,
74
,
89
,
124
,
17
,
41
,
88
,
5
,
6
,
4
,
12
,
3
,
11
,
2
,
10
,
1
,
9
,
119
,
126
,
108
,
117
,
125
,
123
,
107
,
115
,
116
,
121
,
105
,
114
,
122
,
112
,
113
,
127
,
96
,
97
,
120
,
7
,
15
,
23
,
31
,
39
,
47
,
55
,
63
,
71
,
79
,
86
,
94
,
8
,
16
,
24
,
32
,
40
,
48
,
56
,
64
,
72
,
80
,
87
,
111
,
19
,
25
,
57
,
81
,
83
,
92
,
95
,
98
,
99
,
100
,
101
,
103
,
104
,
106
,
109
,
110
0
,
118
,
22
,
30
,
38
,
37
,
46
,
54
,
61
,
62
,
70
,
69
,
78
,
85
,
102
,
13
,
21
,
29
,
36
,
45
,
44
,
53
,
60
,
67
,
68
,
77
,
84
,
91
,
90
,
20
,
28
,
27
,
35
,
43
,
52
,
51
,
59
,
66
,
75
,
76
,
82
,
14
,
18
,
93
,
26
,
34
,
33
,
42
,
50
,
49
,
58
,
65
,
73
,
74
,
89
,
124
,
17
,
41
,
88
,
5
,
6
,
4
,
12
,
3
,
11
,
2
,
10
,
1
,
9
,
119
,
126
,
108
,
117
,
125
,
123
,
107
,
115
,
116
,
121
,
105
,
114
,
122
,
112
,
113
,
127
,
96
,
97
,
120
,
7
,
15
,
23
,
31
,
39
,
47
,
55
,
63
,
71
,
79
,
86
,
94
,
8
,
16
,
24
,
32
,
40
,
48
,
56
,
64
,
72
,
80
,
87
,
111
,
19
,
25
,
57
,
81
,
83
,
92
,
95
,
98
,
99
,
100
,
101
,
103
,
104
,
106
,
109
,
110
};
#define ATKBD_CMD_SETLEDS 0x10ed
...
...
@@ -125,6 +118,9 @@ static unsigned char atkbd_unxlate_table[128] = {
#define ATKBD_RET_EMULX 0x80
#define ATKBD_RET_EMUL1 0xe1
#define ATKBD_RET_RELEASE 0xf0
#define ATKBD_RET_HANGUEL 0xf1
#define ATKBD_RET_HANJA 0xf2
#define ATKBD_RET_ERR 0xff
#define ATKBD_KEY_UNKNOWN 0
#define ATKBD_KEY_NULL 255
...
...
@@ -156,6 +152,17 @@ struct atkbd {
unsigned
long
time
;
};
static
void
atkbd_report_key
(
struct
input_dev
*
dev
,
struct
pt_regs
*
regs
,
int
code
,
int
value
)
{
input_regs
(
dev
,
regs
);
if
(
value
==
3
)
{
input_report_key
(
dev
,
code
,
1
);
input_report_key
(
dev
,
code
,
0
);
}
else
input_event
(
dev
,
EV_KEY
,
code
,
value
);
input_sync
(
dev
);
}
/*
* atkbd_interrupt(). Here takes place processing of data received from
* the keyboard into events.
...
...
@@ -184,47 +191,37 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd
->
resend
=
0
;
#endif
switch
(
code
)
{
case
ATKBD_RET_ACK
:
atkbd
->
ack
=
1
;
goto
out
;
case
ATKBD_RET_NAK
:
atkbd
->
ack
=
-
1
;
goto
out
;
}
if
(
atkbd
->
translated
)
do
{
if
(
atkbd
->
emul
!=
1
)
{
if
(
code
==
ATKBD_RET_EMUL0
||
code
==
ATKBD_RET_EMUL1
)
break
;
if
(
code
==
ATKBD_RET_BAT
)
{
if
(
!
atkbd
->
bat_xl
)
break
;
atkbd
->
bat_xl
=
0
;
}
if
(
code
==
(
ATKBD_RET_BAT
&
0x7f
))
atkbd
->
bat_xl
=
1
;
if
(
!
atkbd
->
ack
)
switch
(
code
)
{
case
ATKBD_RET_ACK
:
atkbd
->
ack
=
1
;
goto
out
;
case
ATKBD_RET_NAK
:
atkbd
->
ack
=
-
1
;
goto
out
;
}
if
(
code
<
0x80
)
{
code
=
atkbd_unxlate_table
[
code
];
break
;
}
if
(
atkbd
->
cmdcnt
)
break
;
code
=
atkbd_unxlate_table
[
code
&
0x7f
];
atkbd
->
release
=
1
;
}
while
(
0
);
if
(
atkbd
->
cmdcnt
)
{
atkbd
->
cmdbuf
[
--
atkbd
->
cmdcnt
]
=
code
;
goto
out
;
}
if
(
atkbd
->
translated
)
{
if
(
atkbd
->
emul
||
!
(
code
==
ATKBD_RET_EMUL0
||
code
==
ATKBD_RET_EMUL1
||
code
==
ATKBD_RET_HANGUEL
||
code
==
ATKBD_RET_HANJA
||
code
==
ATKBD_RET_ERR
||
(
code
==
ATKBD_RET_BAT
&&
!
atkbd
->
bat_xl
)))
{
atkbd
->
release
=
code
>>
7
;
code
&=
0x7f
;
}
if
(
!
atkbd
->
emul
&&
(
code
&
0x7f
)
==
(
ATKBD_RET_BAT
&
0x7f
))
atkbd
->
bat_xl
=
!
atkbd
->
release
;
}
switch
(
code
)
{
case
ATKBD_RET_BAT
:
serio_rescan
(
atkbd
->
serio
);
...
...
@@ -238,22 +235,33 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
case
ATKBD_RET_RELEASE
:
atkbd
->
release
=
1
;
goto
out
;
case
ATKBD_RET_HANGUEL
:
atkbd_report_key
(
&
atkbd
->
dev
,
regs
,
KEY_LANG1
,
3
);
goto
out
;
case
ATKBD_RET_HANJA
:
atkbd_report_key
(
&
atkbd
->
dev
,
regs
,
KEY_LANG2
,
3
);
goto
out
;
case
ATKBD_RET_ERR
:
printk
(
KERN_WARNING
"atkbd.c: Keyboard on %s reports too many keys pressed.
\n
"
,
serio
->
phys
);
goto
out
;
}
if
(
atkbd
->
set
!=
3
)
code
=
(
code
&
0x7f
)
|
((
code
&
0x80
)
<<
1
);
if
(
atkbd
->
emul
)
{
if
(
--
atkbd
->
emul
)
goto
out
;
code
|=
0x100
;
code
|=
(
atkbd
->
set
!=
3
)
?
0x80
:
0x100
;
}
switch
(
atkbd
->
keycode
[
code
])
{
case
ATKBD_KEY_NULL
:
break
;
case
ATKBD_KEY_UNKNOWN
:
printk
(
KERN_WARNING
"atkbd.c: Unknown key %s (%s set %d, code %#x
, data %#x,
on %s).
\n
"
,
printk
(
KERN_WARNING
"atkbd.c: Unknown key %s (%s set %d, code %#x on %s).
\n
"
,
atkbd
->
release
?
"released"
:
"pressed"
,
atkbd
->
translated
?
"translated"
:
"raw"
,
atkbd
->
set
,
code
,
data
,
serio
->
phys
);
atkbd
->
set
,
code
,
serio
->
phys
);
break
;
default:
value
=
atkbd
->
release
?
0
:
...
...
@@ -273,9 +281,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
break
;
}
input_regs
(
&
atkbd
->
dev
,
regs
);
input_event
(
&
atkbd
->
dev
,
EV_KEY
,
atkbd
->
keycode
[
code
],
value
);
input_sync
(
&
atkbd
->
dev
);
atkbd_report_key
(
&
atkbd
->
dev
,
regs
,
atkbd
->
keycode
[
code
],
value
);
}
atkbd
->
release
=
0
;
...
...
@@ -369,10 +375,11 @@ static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
static
int
atkbd_event
(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
)
{
struct
atkbd
*
atkbd
=
dev
->
private
;
struct
{
int
p
;
u8
v
;
}
period
[]
=
{
{
30
,
0x00
},
{
25
,
0x02
},
{
20
,
0x04
},
{
15
,
0x08
},
{
10
,
0x0c
},
{
7
,
0x10
},
{
5
,
0x14
},
{
0
,
0x14
}
};
struct
{
int
d
;
u8
v
;
}
delay
[]
=
{
{
1000
,
0x60
},
{
750
,
0x40
},
{
500
,
0x20
},
{
250
,
0x00
},
{
0
,
0x00
}
};
const
short
period
[
32
]
=
{
33
,
37
,
42
,
46
,
50
,
54
,
58
,
63
,
67
,
75
,
83
,
92
,
100
,
109
,
116
,
125
,
133
,
149
,
167
,
182
,
200
,
217
,
232
,
250
,
270
,
303
,
333
,
370
,
400
,
435
,
470
,
500
};
const
short
delay
[
4
]
=
{
250
,
500
,
750
,
1000
};
char
param
[
2
];
int
i
,
j
;
...
...
@@ -406,11 +413,11 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
if
(
atkbd_softrepeat
)
return
0
;
i
=
j
=
0
;
while
(
period
[
i
].
p
>
dev
->
rep
[
REP_PERIOD
])
i
++
;
while
(
delay
[
j
].
d
>
dev
->
rep
[
REP_DELAY
])
j
++
;
dev
->
rep
[
REP_PERIOD
]
=
period
[
i
]
.
p
;
dev
->
rep
[
REP_DELAY
]
=
delay
[
j
]
.
d
;
param
[
0
]
=
period
[
i
].
v
|
delay
[
j
].
v
;
while
(
i
<
32
&&
period
[
i
]
<
dev
->
rep
[
REP_PERIOD
])
i
++
;
while
(
j
<
4
&&
delay
[
j
]
<
dev
->
rep
[
REP_DELAY
])
j
++
;
dev
->
rep
[
REP_PERIOD
]
=
period
[
i
];
dev
->
rep
[
REP_DELAY
]
=
delay
[
j
];
param
[
0
]
=
i
|
(
j
<<
5
)
;
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETREP
);
return
0
;
...
...
@@ -623,6 +630,7 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd
->
dev
.
rep
[
REP_PERIOD
]
=
33
;
}
atkbd
->
ack
=
1
;
atkbd
->
serio
=
serio
;
init_input_dev
(
&
atkbd
->
dev
);
...
...
@@ -665,16 +673,22 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
sprintf
(
atkbd
->
phys
,
"%s/input0"
,
serio
->
phys
);
if
(
atkbd
->
set
==
3
)
memcpy
(
atkbd
->
keycode
,
atkbd_set3_keycode
,
sizeof
(
atkbd
->
keycode
));
else
if
(
atkbd
->
translated
)
{
for
(
i
=
0
;
i
<
128
;
i
++
)
{
atkbd
->
keycode
[
i
]
=
atkbd_set2_keycode
[
atkbd_unxlate_table
[
i
]];
atkbd
->
keycode
[
i
|
0x80
]
=
atkbd_set2_keycode
[
atkbd_unxlate_table
[
i
]
|
0x80
];
}
}
else
if
(
atkbd
->
set
==
2
)
{
memcpy
(
atkbd
->
keycode
,
atkbd_set2_keycode
,
sizeof
(
atkbd
->
keycode
));
}
else
{
memcpy
(
atkbd
->
keycode
,
atkbd_set3_keycode
,
sizeof
(
atkbd
->
keycode
));
}
atkbd
->
dev
.
name
=
atkbd
->
name
;
atkbd
->
dev
.
phys
=
atkbd
->
phys
;
atkbd
->
dev
.
id
.
bustype
=
BUS_I8042
;
atkbd
->
dev
.
id
.
vendor
=
0x0001
;
atkbd
->
dev
.
id
.
product
=
atkbd
->
set
;
atkbd
->
dev
.
id
.
product
=
atkbd
->
translated
?
1
:
atkbd
->
set
;
atkbd
->
dev
.
id
.
version
=
atkbd
->
id
;
for
(
i
=
0
;
i
<
512
;
i
++
)
...
...
@@ -686,10 +700,62 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
atkbd
->
name
,
serio
->
phys
);
}
/*
* atkbd_reconnect() tries to restore keyboard into a sane state and is
* most likely called on resume.
*/
static
int
atkbd_reconnect
(
struct
serio
*
serio
)
{
struct
atkbd
*
atkbd
=
serio
->
private
;
struct
serio_dev
*
dev
=
serio
->
dev
;
int
i
;
if
(
!
dev
)
{
printk
(
KERN_DEBUG
"atkbd: reconnect request, but serio is disconnected, ignoring...
\n
"
);
return
-
1
;
}
if
(
atkbd
->
write
)
{
if
(
atkbd_probe
(
atkbd
))
return
-
1
;
atkbd
->
set
=
atkbd_set_3
(
atkbd
);
atkbd_enable
(
atkbd
);
}
else
{
atkbd
->
set
=
2
;
atkbd
->
id
=
0xab00
;
}
/*
* Here we probably should check if the keyboard has the same set that
* it had before and bail out if it's different. But this will most likely
* cause new keyboard device be created... and for the user it will look
* like keyboard is lost
*/
if
(
atkbd
->
translated
)
{
for
(
i
=
0
;
i
<
128
;
i
++
)
{
atkbd
->
keycode
[
i
]
=
atkbd_set2_keycode
[
atkbd_unxlate_table
[
i
]];
atkbd
->
keycode
[
i
|
0x80
]
=
atkbd_set2_keycode
[
atkbd_unxlate_table
[
i
]
|
0x80
];
}
}
else
if
(
atkbd
->
set
==
2
)
{
memcpy
(
atkbd
->
keycode
,
atkbd_set2_keycode
,
sizeof
(
atkbd
->
keycode
));
}
else
{
memcpy
(
atkbd
->
keycode
,
atkbd_set3_keycode
,
sizeof
(
atkbd
->
keycode
));
}
for
(
i
=
0
;
i
<
512
;
i
++
)
if
(
atkbd
->
keycode
[
i
]
&&
atkbd
->
keycode
[
i
]
<
255
)
set_bit
(
atkbd
->
keycode
[
i
],
atkbd
->
dev
.
keybit
);
return
0
;
}
static
struct
serio_dev
atkbd_dev
=
{
.
interrupt
=
atkbd_interrupt
,
.
connect
=
atkbd_connect
,
.
reconnect
=
atkbd_reconnect
,
.
disconnect
=
atkbd_disconnect
,
.
cleanup
=
atkbd_cleanup
,
};
...
...
@@ -709,9 +775,17 @@ static int __init atkbd_setup_reset(char *str)
if
(
ints
[
0
]
>
0
)
atkbd_reset
=
ints
[
1
];
return
1
;
}
static
int
__init
atkbd_setup_softrepeat
(
char
*
str
)
{
int
ints
[
4
];
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
ints
[
0
]
>
0
)
atkbd_softrepeat
=
ints
[
1
];
return
1
;
}
__setup
(
"atkbd_set="
,
atkbd_setup_set
);
__setup
(
"atkbd_reset"
,
atkbd_setup_reset
);
__setup
(
"atkbd_softrepeat="
,
atkbd_setup_softrepeat
);
#endif
int
__init
atkbd_init
(
void
)
...
...
drivers/input/mouse/Kconfig
View file @
8a2e73e1
...
...
@@ -23,27 +23,18 @@ config MOUSE_PS2
mice with wheels and extra buttons, Microsoft, Logitech or Genius
compatible.
Synaptics TouchPad users might be interested in a specialized
XFree86 driver at:
http://w1.894.telia.com/~u89404340/touchpad/index.html
and a new verion of GPM at:
http://www.geocities.com/dt_or/gpm/gpm.html
to take advantage of the advanced features of the touchpad.
If unsure, say Y.
To compile this driver as a module, choose M here: the
module will be called psmouse.
config MOUSE_PS2_SYNAPTICS
bool "Synaptics TouchPad"
default n
depends on INPUT && INPUT_MOUSE && MOUSE_PS2
---help---
Say Y here if you have a Synaptics TouchPad connected to your system.
This touchpad is found on many modern laptop computers.
Note that you also need a user space driver to interpret the data
generated by the kernel. A compatible driver for XFree86 is available
from http://w1.894.telia.com/~u89404340/touchpad/index.html
The gpm program is not yet able to interpret the data from this
driver, so if you need to use the touchpad in the console, you have to
say N for now.
config MOUSE_SERIAL
tristate "Serial mouse"
depends on INPUT && INPUT_MOUSE
...
...
drivers/input/mouse/logips2pp.c
View file @
8a2e73e1
...
...
@@ -10,6 +10,7 @@
*/
#include <linux/input.h>
#include <linux/serio.h>
#include "psmouse.h"
#include "logips2pp.h"
...
...
@@ -142,7 +143,7 @@ void ps2pp_set_800dpi(struct psmouse *psmouse)
* touchpad.
*/
int
ps2pp_detect_model
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
)
static
int
ps2pp_detect_model
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
)
{
int
i
;
static
int
logitech_4btn
[]
=
{
12
,
40
,
41
,
42
,
43
,
52
,
73
,
80
,
-
1
};
...
...
@@ -226,3 +227,22 @@ int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
return
0
;
}
/*
* Logitech magic init.
*/
int
ps2pp_detect
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
4
];
param
[
0
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
param
[
1
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
return
param
[
1
]
!=
0
?
ps2pp_detect_model
(
psmouse
,
param
)
:
0
;
}
drivers/input/mouse/logips2pp.h
View file @
8a2e73e1
...
...
@@ -13,5 +13,5 @@
struct
psmouse
;
void
ps2pp_process_packet
(
struct
psmouse
*
psmouse
);
void
ps2pp_set_800dpi
(
struct
psmouse
*
psmouse
);
int
ps2pp_detect
_model
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
);
int
ps2pp_detect
(
struct
psmouse
*
psmouse
);
#endif
drivers/input/mouse/psmouse-base.c
View file @
8a2e73e1
...
...
@@ -12,35 +12,44 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/pm.h>
#include "psmouse.h"
#include "synaptics.h"
#include "logips2pp.h"
MODULE_AUTHOR
(
"Vojtech Pavlik <vojtech@suse.cz>"
);
MODULE_DESCRIPTION
(
"PS/2 mouse driver"
);
MODULE_PARM
(
psmouse_noext
,
"1i"
);
MODULE_PARM_DESC
(
psmouse_noext
,
"Disable any protocol extensions. Useful for KVM switches."
);
MODULE_PARM
(
psmouse_resolution
,
"i"
);
MODULE_PARM_DESC
(
psmouse_resolution
,
"Resolution, in dpi."
);
MODULE_PARM
(
psmouse_rate
,
"i"
);
MODULE_PARM_DESC
(
psmouse_rate
,
"Report rate, in reports per second."
);
MODULE_PARM
(
psmouse_smartscroll
,
"i"
);
MODULE_PARM_DESC
(
psmouse_smartscroll
,
"Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."
);
MODULE_PARM
(
psmouse_resetafter
,
"i"
);
MODULE_PARM_DESC
(
psmouse_resetafter
,
"Reset Synaptics Touchpad after so many bad packets (0 = never)."
);
MODULE_LICENSE
(
"GPL"
);
static
int
psmouse_noext
;
module_param
(
psmouse_noext
,
int
,
0
);
MODULE_PARM_DESC
(
psmouse_noext
,
"[DEPRECATED] Disable any protocol extensions. Useful for KVM switches."
);
static
char
*
psmouse_proto
;
static
unsigned
int
psmouse_max_proto
=
-
1UL
;
module_param
(
psmouse_proto
,
charp
,
0
);
MODULE_PARM_DESC
(
psmouse_proto
,
"Highest protocol extension to probe (bare, imps, exps). Useful for KVM switches."
);
int
psmouse_resolution
=
200
;
module_param
(
psmouse_resolution
,
uint
,
0
);
MODULE_PARM_DESC
(
psmouse_resolution
,
"Resolution, in dpi."
);
unsigned
int
psmouse_rate
=
100
;
module_param
(
psmouse_rate
,
uint
,
0
);
MODULE_PARM_DESC
(
psmouse_rate
,
"Report rate, in reports per second."
);
int
psmouse_smartscroll
=
1
;
module_param
(
psmouse_smartscroll
,
bool
,
0
);
MODULE_PARM_DESC
(
psmouse_smartscroll
,
"Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."
);
unsigned
int
psmouse_resetafter
;
module_param
(
psmouse_resetafter
,
uint
,
0
);
MODULE_PARM_DESC
(
psmouse_resetafter
,
"Reset Synaptics Touchpad after so many bad packets (0 = never)."
);
static
char
*
psmouse_protocols
[]
=
{
"None"
,
"PS/2"
,
"PS2++"
,
"PS2T++"
,
"GenPS/2"
,
"ImPS/2"
,
"ImExPS/2"
,
"SynPS/2"
};
...
...
@@ -139,7 +148,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto
out
;
}
if
(
psmouse
->
pktcnt
&&
time_after
(
jiffies
,
psmouse
->
last
+
HZ
/
2
))
{
if
(
psmouse
->
state
==
PSMOUSE_ACTIVATED
&&
psmouse
->
pktcnt
&&
time_after
(
jiffies
,
psmouse
->
last
+
HZ
/
2
))
{
printk
(
KERN_WARNING
"psmouse.c: %s at %s lost synchronization, throwing %d bytes away.
\n
"
,
psmouse
->
name
,
psmouse
->
phys
,
psmouse
->
pktcnt
);
psmouse
->
pktcnt
=
0
;
...
...
@@ -256,6 +266,59 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
return
0
;
}
/*
* Genius NetMouse magic init.
*/
static
int
genius_detect
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
4
];
param
[
0
]
=
3
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
return
param
[
0
]
==
0x00
&&
param
[
1
]
==
0x33
&&
param
[
2
]
==
0x55
;
}
/*
* IntelliMouse magic init.
*/
static
int
intellimouse_detect
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
2
];
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
100
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
80
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETID
);
return
param
[
0
]
==
3
;
}
/*
* Try IntelliMouse/Explorer magic init.
*/
static
int
im_explorer_detect
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
2
];
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
80
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETID
);
return
param
[
0
]
==
4
;
}
/*
* psmouse_extensions() probes for any extensions to the basic PS/2 protocol
* the mouse may have.
...
...
@@ -263,49 +326,33 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
static
int
psmouse_extensions
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
4
]
;
int
synaptics_hardware
=
0
;
param
[
0
]
=
0
;
psmouse
->
vendor
=
"Generic"
;
psmouse
->
name
=
"Mouse"
;
psmouse
->
model
=
0
;
if
(
psmouse_noext
)
return
PSMOUSE_PS2
;
/*
* Try Synaptics TouchPad
magic ID
* Try Synaptics TouchPad
*/
param
[
0
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
if
(
param
[
1
]
==
0x47
)
{
if
(
psmouse_max_proto
>
PSMOUSE_PS2
&&
synaptics_detect
(
psmouse
))
{
synaptics_hardware
=
1
;
psmouse
->
vendor
=
"Synaptics"
;
psmouse
->
name
=
"TouchPad"
;
if
(
!
synaptics_init
(
psmouse
))
return
PSMOUSE_SYNAPTICS
;
else
return
PSMOUSE_PS2
;
}
if
(
psmouse_max_proto
>
PSMOUSE_IMEX
)
{
if
(
synaptics_init
(
psmouse
)
==
0
)
return
PSMOUSE_SYNAPTICS
;
/*
* Try Genius NetMouse magic init.
* Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
* Unfortunately Logitech/Genius probes confuse some firmware versions so
* we'll have to skip them.
*/
psmouse_max_proto
=
PSMOUSE_IMEX
;
}
}
param
[
0
]
=
3
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
if
(
param
[
0
]
==
0x00
&&
param
[
1
]
==
0x33
&&
param
[
2
]
==
0x55
)
{
if
(
psmouse_max_proto
>
PSMOUSE_IMEX
&&
genius_detect
(
psmouse
))
{
set_bit
(
BTN_EXTRA
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_SIDE
,
psmouse
->
dev
.
keybit
);
set_bit
(
REL_WHEEL
,
psmouse
->
dev
.
relbit
);
...
...
@@ -315,54 +362,17 @@ static int psmouse_extensions(struct psmouse *psmouse)
return
PSMOUSE_GENPS
;
}
/*
* Try Logitech magic ID.
*/
param
[
0
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
param
[
1
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
if
(
param
[
1
])
{
int
type
=
ps2pp_detect_model
(
psmouse
,
param
);
if
(
psmouse_max_proto
>
PSMOUSE_IMEX
)
{
int
type
=
ps2pp_detect
(
psmouse
);
if
(
type
)
return
type
;
}
/*
* Try IntelliMouse magic init.
*/
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
100
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
80
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETID
);
if
(
param
[
0
]
==
3
)
{
if
(
psmouse_max_proto
>=
PSMOUSE_IMPS
&&
intellimouse_detect
(
psmouse
))
{
set_bit
(
REL_WHEEL
,
psmouse
->
dev
.
relbit
);
/*
* Try IntelliMouse/Explorer magic init.
*/
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
200
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
param
[
0
]
=
80
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETID
);
if
(
param
[
0
]
==
4
)
{
if
(
psmouse_max_proto
>=
PSMOUSE_IMEX
&&
im_explorer_detect
(
psmouse
))
{
set_bit
(
BTN_SIDE
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_EXTRA
,
psmouse
->
dev
.
keybit
);
...
...
@@ -378,6 +388,15 @@ static int psmouse_extensions(struct psmouse *psmouse)
* Okay, all failed, we have a standard mouse here. The number of the buttons
* is still a question, though. We assume 3.
*/
if
(
synaptics_hardware
)
{
/*
* We detected Synaptics hardware but it did not respond to IMPS/2 probes.
* We need to reset the touchpad because if there is a track point on the
* pass through port it could get disabled while probing for protocol
* extensions.
*/
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_RESET_DIS
);
}
return
PSMOUSE_PS2
;
}
...
...
@@ -468,7 +487,7 @@ static void psmouse_initialize(struct psmouse *psmouse)
* We set the mouse report rate, resolution and scaling.
*/
if
(
!
psmouse_noext
)
{
if
(
psmouse_max_proto
!=
PSMOUSE_PS2
)
{
psmouse_set_rate
(
psmouse
);
psmouse_set_resolution
(
psmouse
);
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
);
...
...
@@ -513,45 +532,30 @@ static void psmouse_disconnect(struct serio *serio)
struct
psmouse
*
psmouse
=
serio
->
private
;
psmouse
->
state
=
PSMOUSE_IGNORE
;
synaptics_disconnect
(
psmouse
);
input_unregister_device
(
&
psmouse
->
dev
);
serio_close
(
serio
);
kfree
(
psmouse
);
}
/*
* Reinitialize mouse hardware after software suspend.
*/
static
int
psmouse_pm_callback
(
struct
pm_dev
*
dev
,
pm_request_t
request
,
void
*
data
)
{
struct
psmouse
*
psmouse
=
dev
->
data
;
struct
serio_dev
*
ser_dev
=
psmouse
->
serio
->
dev
;
synaptics_disconnect
(
psmouse
);
/* We need to reopen the serio port to reinitialize the i8042 controller */
serio_close
(
psmouse
->
serio
);
serio_open
(
psmouse
->
serio
,
ser_dev
);
if
(
psmouse
->
ptport
)
{
if
(
psmouse
->
ptport
->
deactivate
)
psmouse
->
ptport
->
deactivate
(
psmouse
);
__serio_unregister_port
(
&
psmouse
->
ptport
->
serio
);
/* we have serio_sem */
kfree
(
psmouse
->
ptport
);
psmouse
->
ptport
=
NULL
;
}
/* Probe and re-initialize the mouse */
psmouse_probe
(
psmouse
);
psmouse_initialize
(
psmouse
);
synaptics_pt_init
(
psmouse
);
psmouse_activate
(
psmouse
);
if
(
psmouse
->
disconnect
)
psmouse
->
disconnect
(
psmouse
);
return
0
;
input_unregister_device
(
&
psmouse
->
dev
);
serio_close
(
serio
);
kfree
(
psmouse
);
}
/*
* psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found.
*/
static
void
psmouse_connect
(
struct
serio
*
serio
,
struct
serio_dev
*
dev
)
{
struct
psmouse
*
psmouse
;
struct
pm_dev
*
pmdev
;
if
((
serio
->
type
&
SERIO_TYPE
)
!=
SERIO_8042
&&
(
serio
->
type
&
SERIO_TYPE
)
!=
SERIO_PS_PSTHRU
)
...
...
@@ -572,7 +576,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse
->
dev
.
private
=
psmouse
;
serio
->
private
=
psmouse
;
if
(
serio_open
(
serio
,
dev
))
{
kfree
(
psmouse
);
return
;
...
...
@@ -584,12 +587,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
return
;
}
pmdev
=
pm_register
(
PM_SYS_DEV
,
PM_SYS_UNKNOWN
,
psmouse_pm_callback
);
if
(
pmdev
)
{
psmouse
->
dev
.
pm_dev
=
pmdev
;
pmdev
->
data
=
psmouse
;
}
sprintf
(
psmouse
->
devname
,
"%s %s %s"
,
psmouse_protocols
[
psmouse
->
type
],
psmouse
->
vendor
,
psmouse
->
name
);
sprintf
(
psmouse
->
phys
,
"%s/input0"
,
...
...
@@ -608,59 +605,87 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse_initialize
(
psmouse
);
synaptics_pt_init
(
psmouse
);
if
(
psmouse
->
ptport
)
{
printk
(
KERN_INFO
"serio: %s port at %s
\n
"
,
psmouse
->
ptport
->
serio
.
name
,
psmouse
->
phys
);
__serio_register_port
(
&
psmouse
->
ptport
->
serio
);
/* we have serio_sem */
if
(
psmouse
->
ptport
->
activate
)
psmouse
->
ptport
->
activate
(
psmouse
);
}
psmouse_activate
(
psmouse
);
}
static
int
psmouse_reconnect
(
struct
serio
*
serio
)
{
struct
psmouse
*
psmouse
=
serio
->
private
;
struct
serio_dev
*
dev
=
serio
->
dev
;
int
old_type
=
psmouse
->
type
;
if
(
!
dev
)
{
printk
(
KERN_DEBUG
"psmouse: reconnect request, but serio is disconnected, ignoring...
\n
"
);
return
-
1
;
}
psmouse
->
state
=
PSMOUSE_NEW_DEVICE
;
psmouse
->
type
=
psmouse
->
acking
=
psmouse
->
cmdcnt
=
psmouse
->
pktcnt
=
0
;
if
(
psmouse
->
reconnect
)
{
if
(
psmouse
->
reconnect
(
psmouse
))
return
-
1
;
}
else
if
(
psmouse_probe
(
psmouse
)
!=
old_type
)
return
-
1
;
/* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization
*/
psmouse
->
type
=
old_type
;
psmouse_initialize
(
psmouse
);
if
(
psmouse
->
ptport
)
{
if
(
psmouse_reconnect
(
&
psmouse
->
ptport
->
serio
))
{
__serio_unregister_port
(
&
psmouse
->
ptport
->
serio
);
__serio_register_port
(
&
psmouse
->
ptport
->
serio
);
if
(
psmouse
->
ptport
->
activate
)
psmouse
->
ptport
->
activate
(
psmouse
);
}
}
psmouse_activate
(
psmouse
);
return
0
;
}
static
struct
serio_dev
psmouse_dev
=
{
.
interrupt
=
psmouse_interrupt
,
.
connect
=
psmouse_connect
,
.
reconnect
=
psmouse_reconnect
,
.
disconnect
=
psmouse_disconnect
,
.
cleanup
=
psmouse_cleanup
,
};
#ifndef MODULE
static
int
__init
psmouse_noext_setup
(
char
*
str
)
{
psmouse_noext
=
1
;
return
1
;
}
static
int
__init
psmouse_resolution_setup
(
char
*
str
)
{
get_option
(
&
str
,
&
psmouse_resolution
);
return
1
;
}
static
int
__init
psmouse_smartscroll_setup
(
char
*
str
)
static
inline
void
psmouse_parse_proto
(
void
)
{
get_option
(
&
str
,
&
psmouse_smartscroll
);
return
1
;
}
static
int
__init
psmouse_resetafter_setup
(
char
*
str
)
{
get_option
(
&
str
,
&
psmouse_resetafter
);
return
1
;
}
if
(
psmouse_noext
)
{
printk
(
KERN_WARNING
"psmouse: 'psmouse_noext' option is deprecated, please use 'psmouse_proto'
\n
"
);
psmouse_max_proto
=
PSMOUSE_PS2
;
}
static
int
__init
psmouse_rate_setup
(
char
*
str
)
{
get_option
(
&
str
,
&
psmouse_rate
);
return
1
;
/* even is psmouse_noext is present psmouse_proto overrides it */
if
(
psmouse_proto
)
{
if
(
!
strcmp
(
psmouse_proto
,
"bare"
))
psmouse_max_proto
=
PSMOUSE_PS2
;
else
if
(
!
strcmp
(
psmouse_proto
,
"imps"
))
psmouse_max_proto
=
PSMOUSE_IMPS
;
else
if
(
!
strcmp
(
psmouse_proto
,
"exps"
))
psmouse_max_proto
=
PSMOUSE_IMEX
;
else
printk
(
KERN_ERR
"psmouse: unknown protocol type '%s'
\n
"
,
psmouse_proto
);
}
}
__setup
(
"psmouse_noext"
,
psmouse_noext_setup
);
__setup
(
"psmouse_resolution="
,
psmouse_resolution_setup
);
__setup
(
"psmouse_smartscroll="
,
psmouse_smartscroll_setup
);
__setup
(
"psmouse_resetafter="
,
psmouse_resetafter_setup
);
__setup
(
"psmouse_rate="
,
psmouse_rate_setup
);
#endif
int
__init
psmouse_init
(
void
)
{
psmouse_parse_proto
();
serio_register_device
(
&
psmouse_dev
);
return
0
;
}
...
...
drivers/input/mouse/psmouse.h
View file @
8a2e73e1
...
...
@@ -22,10 +22,20 @@
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
struct
psmouse
;
struct
psmouse_ptport
{
struct
serio
serio
;
void
(
*
activate
)(
struct
psmouse
*
parent
);
void
(
*
deactivate
)(
struct
psmouse
*
parent
);
};
struct
psmouse
{
void
*
private
;
struct
input_dev
dev
;
struct
serio
*
serio
;
struct
psmouse_ptport
*
ptport
;
char
*
vendor
;
char
*
name
;
unsigned
char
cmdbuf
[
8
];
...
...
@@ -41,6 +51,9 @@ struct psmouse {
char
error
;
char
devname
[
64
];
char
phys
[
32
];
int
(
*
reconnect
)(
struct
psmouse
*
psmouse
);
void
(
*
disconnect
)(
struct
psmouse
*
psmouse
);
};
#define PSMOUSE_PS2 1
...
...
drivers/input/mouse/synaptics.c
View file @
8a2e73e1
...
...
@@ -2,7 +2,8 @@
* Synaptics TouchPad PS/2 mouse driver
*
* 2003 Dmitry Torokhov <dtor@mail.ru>
* Added support for pass-through port
* Added support for pass-through port. Special thanks to Peter Berg Larsen
* for explaining various Synaptics quirks.
*
* 2003 Peter Osterlund <petero2@telia.com>
* Ported to 2.5 input device infrastructure.
...
...
@@ -194,9 +195,7 @@ static void print_ident(struct synaptics_data *priv)
static
int
synaptics_query_hardware
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
int
retries
=
0
;
int
mode
;
while
((
retries
++
<
3
)
&&
synaptics_reset
(
psmouse
))
printk
(
KERN_ERR
"synaptics reset failed
\n
"
);
...
...
@@ -208,7 +207,14 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
if
(
synaptics_capability
(
psmouse
))
return
-
1
;
mode
=
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
;
return
0
;
}
static
int
synaptics_set_mode
(
struct
psmouse
*
psmouse
,
int
mode
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
mode
|=
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
;
if
(
SYN_ID_MAJOR
(
priv
->
identity
)
>=
4
)
mode
|=
SYN_BIT_DISABLE_GESTURE
;
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
...
...
@@ -265,49 +271,38 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet
}
}
int
synaptics_pt_init
(
struct
psmouse
*
psmouse
)
static
void
synaptics_pt_activate
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
serio
*
port
;
struct
psmouse
*
child
;
struct
psmouse
*
child
=
psmouse
->
ptport
->
serio
.
private
;
if
(
psmouse
->
type
!=
PSMOUSE_SYNAPTICS
)
return
-
1
;
if
(
!
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
return
-
1
;
if
(
!
SYN_CAP_PASS_THROUGH
(
priv
->
capabilities
))
return
-
1
;
/* adjust the touchpad to child's choice of protocol */
if
(
child
&&
child
->
type
>=
PSMOUSE_GENPS
)
{
if
(
synaptics_set_mode
(
psmouse
,
SYN_BIT_FOUR_BYTE_CLIENT
))
printk
(
KERN_INFO
"synaptics: failed to enable 4-byte guest protocol
\n
"
);
}
}
static
void
synaptics_pt_create
(
struct
psmouse
*
psmouse
)
{
struct
psmouse_ptport
*
port
;
p
riv
->
ptport
=
port
=
kmalloc
(
sizeof
(
struct
serio
),
GFP_KERNEL
);
p
smouse
->
ptport
=
port
=
kmalloc
(
sizeof
(
struct
psmouse_ptport
),
GFP_KERNEL
);
if
(
!
port
)
{
printk
(
KERN_ERR
"synaptics: not enough memory to allocate
serio
port
\n
"
);
return
-
1
;
printk
(
KERN_ERR
"synaptics: not enough memory to allocate
pass-through
port
\n
"
);
return
;
}
memset
(
port
,
0
,
sizeof
(
struct
serio
));
port
->
type
=
SERIO_PS_PSTHRU
;
port
->
name
=
"Synaptics pass-through"
;
port
->
phys
=
"synaptics-pt/serio0"
;
port
->
write
=
synaptics_pt_write
;
port
->
open
=
synaptics_pt_open
;
port
->
close
=
synaptics_pt_close
;
port
->
driver
=
psmouse
;
memset
(
port
,
0
,
sizeof
(
struct
psmouse_ptport
));
printk
(
KERN_INFO
"serio: %s port at %s
\n
"
,
port
->
name
,
psmouse
->
phys
);
serio_register_slave_port
(
port
);
port
->
serio
.
type
=
SERIO_PS_PSTHRU
;
port
->
serio
.
name
=
"Synaptics pass-through"
;
port
->
serio
.
phys
=
"synaptics-pt/serio0"
;
port
->
serio
.
write
=
synaptics_pt_write
;
port
->
serio
.
open
=
synaptics_pt_open
;
port
->
serio
.
close
=
synaptics_pt_close
;
port
->
serio
.
driver
=
psmouse
;
/* adjust the touchpad to child's choice of protocol */
child
=
port
->
private
;
if
(
child
&&
child
->
type
>=
PSMOUSE_GENPS
)
{
if
(
synaptics_mode_cmd
(
psmouse
,
(
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
|
SYN_BIT_DISABLE_GESTURE
|
SYN_BIT_FOUR_BYTE_CLIENT
|
SYN_BIT_W_MODE
)))
printk
(
KERN_INFO
"synaptics: failed to enable 4-byte guest protocol
\n
"
);
}
return
0
;
port
->
activate
=
synaptics_pt_activate
;
}
/*****************************************************************************
...
...
@@ -371,27 +366,82 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
clear_bit
(
REL_Y
,
dev
->
relbit
);
}
static
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
)
{
synaptics_mode_cmd
(
psmouse
,
0
);
kfree
(
psmouse
->
private
);
}
static
int
synaptics_reconnect
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
synaptics_data
old_priv
=
*
priv
;
if
(
!
synaptics_detect
(
psmouse
))
return
-
1
;
if
(
synaptics_query_hardware
(
psmouse
))
{
printk
(
KERN_ERR
"Unable to query Synaptics hardware.
\n
"
);
return
-
1
;
}
if
(
old_priv
.
identity
!=
priv
->
identity
||
old_priv
.
model_id
!=
priv
->
model_id
||
old_priv
.
capabilities
!=
priv
->
capabilities
||
old_priv
.
ext_cap
!=
priv
->
ext_cap
)
return
-
1
;
if
(
synaptics_set_mode
(
psmouse
,
0
))
{
printk
(
KERN_ERR
"Unable to initialize Synaptics hardware.
\n
"
);
return
-
1
;
}
return
0
;
}
int
synaptics_detect
(
struct
psmouse
*
psmouse
)
{
unsigned
char
param
[
4
];
param
[
0
]
=
0
;
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRES
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
return
param
[
1
]
==
0x47
;
}
int
synaptics_init
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
;
#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
return
-
1
;
#endif
psmouse
->
private
=
priv
=
kmalloc
(
sizeof
(
struct
synaptics_data
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
1
;
memset
(
priv
,
0
,
sizeof
(
struct
synaptics_data
));
if
(
synaptics_query_hardware
(
psmouse
))
{
printk
(
KERN_ERR
"Unable to query/initialize Synaptics hardware.
\n
"
);
printk
(
KERN_ERR
"Unable to query Synaptics hardware.
\n
"
);
goto
init_fail
;
}
if
(
synaptics_set_mode
(
psmouse
,
0
))
{
printk
(
KERN_ERR
"Unable to initialize Synaptics hardware.
\n
"
);
goto
init_fail
;
}
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
)
&&
SYN_CAP_PASS_THROUGH
(
priv
->
capabilities
))
synaptics_pt_create
(
psmouse
);
print_ident
(
priv
);
set_input_params
(
&
psmouse
->
dev
,
priv
);
psmouse
->
disconnect
=
synaptics_disconnect
;
psmouse
->
reconnect
=
synaptics_reconnect
;
return
0
;
init_fail:
...
...
@@ -399,36 +449,13 @@ int synaptics_init(struct psmouse *psmouse)
return
-
1
;
}
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
if
(
psmouse
->
type
==
PSMOUSE_SYNAPTICS
&&
priv
)
{
synaptics_mode_cmd
(
psmouse
,
0
);
if
(
priv
->
ptport
)
{
serio_unregister_slave_port
(
priv
->
ptport
);
kfree
(
priv
->
ptport
);
}
kfree
(
priv
);
}
}
/*****************************************************************************
* Functions to interpret the absolute mode packets
****************************************************************************/
static
void
synaptics_parse_hw_state
(
unsigned
char
buf
[],
struct
synaptics_data
*
priv
,
struct
synaptics_hw_state
*
hw
)
{
hw
->
up
=
0
;
hw
->
down
=
0
;
hw
->
b0
=
0
;
hw
->
b1
=
0
;
hw
->
b2
=
0
;
hw
->
b3
=
0
;
hw
->
b4
=
0
;
hw
->
b5
=
0
;
hw
->
b6
=
0
;
hw
->
b7
=
0
;
memset
(
hw
,
0
,
sizeof
(
struct
synaptics_hw_state
));
if
(
SYN_MODEL_NEWABS
(
priv
->
model_id
))
{
hw
->
x
=
(((
buf
[
3
]
&
0x10
)
<<
8
)
|
...
...
@@ -570,64 +597,47 @@ static void synaptics_process_packet(struct psmouse *psmouse)
input_sync
(
dev
);
}
static
int
synaptics_validate_byte
(
struct
psmouse
*
psmouse
)
{
static
unsigned
char
newabs_mask
[]
=
{
0xC0
,
0x00
,
0x00
,
0xC0
,
0x00
};
static
unsigned
char
newabs_rslt
[]
=
{
0x80
,
0x00
,
0x00
,
0xC0
,
0x00
};
static
unsigned
char
oldabs_mask
[]
=
{
0xC0
,
0x60
,
0x00
,
0xC0
,
0x60
};
static
unsigned
char
oldabs_rslt
[]
=
{
0xC0
,
0x00
,
0x00
,
0x80
,
0x00
};
struct
synaptics_data
*
priv
=
psmouse
->
private
;
int
idx
=
psmouse
->
pktcnt
-
1
;
if
(
SYN_MODEL_NEWABS
(
priv
->
model_id
))
return
(
psmouse
->
packet
[
idx
]
&
newabs_mask
[
idx
])
==
newabs_rslt
[
idx
];
else
return
(
psmouse
->
packet
[
idx
]
&
oldabs_mask
[
idx
])
==
oldabs_rslt
[
idx
];
}
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
)
{
struct
input_dev
*
dev
=
&
psmouse
->
dev
;
struct
synaptics_data
*
priv
=
psmouse
->
private
;
unsigned
char
data
=
psmouse
->
packet
[
psmouse
->
pktcnt
-
1
];
int
newabs
=
SYN_MODEL_NEWABS
(
priv
->
model_id
);
input_regs
(
dev
,
regs
);
switch
(
psmouse
->
pktcnt
)
{
case
1
:
if
(
newabs
?
((
data
&
0xC8
)
!=
0x80
)
:
((
data
&
0xC0
)
!=
0xC0
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 1st byte
\n
"
);
goto
bad_sync
;
}
break
;
case
2
:
if
(
!
newabs
&&
((
data
&
0x60
)
!=
0x00
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 2nd byte
\n
"
);
goto
bad_sync
;
}
break
;
case
4
:
if
(
newabs
?
((
data
&
0xC8
)
!=
0xC0
)
:
((
data
&
0xC0
)
!=
0x80
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 4th byte
\n
"
);
goto
bad_sync
;
}
break
;
case
5
:
if
(
!
newabs
&&
((
data
&
0x60
)
!=
0x00
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 5th byte
\n
"
);
goto
bad_sync
;
}
break
;
default:
if
(
psmouse
->
pktcnt
<
6
)
break
;
/* Wait for full packet */
if
(
psmouse
->
pktcnt
>=
6
)
{
/* Full packet received */
if
(
priv
->
out_of_sync
)
{
priv
->
out_of_sync
=
0
;
printk
(
KERN_NOTICE
"Synaptics driver resynced.
\n
"
);
}
if
(
p
riv
->
ptport
&&
synaptics_is_pt_packet
(
psmouse
->
packet
))
synaptics_pass_pt_packet
(
priv
->
ptport
,
psmouse
->
packet
);
if
(
p
smouse
->
ptport
&&
psmouse
->
ptport
->
serio
.
dev
&&
synaptics_is_pt_packet
(
psmouse
->
packet
))
synaptics_pass_pt_packet
(
&
psmouse
->
ptport
->
serio
,
psmouse
->
packet
);
else
synaptics_process_packet
(
psmouse
);
psmouse
->
pktcnt
=
0
;
}
else
if
(
psmouse
->
pktcnt
&&
!
synaptics_validate_byte
(
psmouse
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at byte %d
\n
"
,
psmouse
->
pktcnt
);
psmouse
->
pktcnt
=
0
;
break
;
}
return
;
bad_sync:
priv
->
out_of_sync
++
;
psmouse
->
pktcnt
=
0
;
if
(
psmouse_resetafter
>
0
&&
priv
->
out_of_sync
==
psmouse_resetafter
)
{
psmouse
->
state
=
PSMOUSE_IGNORE
;
serio_rescan
(
psmouse
->
serio
);
if
(
++
priv
->
out_of_sync
==
psmouse_resetafter
)
{
psmouse
->
state
=
PSMOUSE_IGNORE
;
printk
(
KERN_NOTICE
"synaptics: issuing reconnect request
\n
"
);
serio_reconnect
(
psmouse
->
serio
);
}
}
}
drivers/input/mouse/synaptics.h
View file @
8a2e73e1
...
...
@@ -9,11 +9,9 @@
#ifndef _SYNAPTICS_H
#define _SYNAPTICS_H
extern
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
);
extern
int
synaptics_detect
(
struct
psmouse
*
psmouse
);
extern
int
synaptics_init
(
struct
psmouse
*
psmouse
);
extern
int
synaptics_pt_init
(
struct
psmouse
*
psmouse
);
extern
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
);
/* synaptics queries */
#define SYN_QUE_IDENTIFY 0x00
...
...
@@ -105,8 +103,6 @@ struct synaptics_data {
/* Data for normal processing */
unsigned
int
out_of_sync
;
/* # of packets out of sync */
int
old_w
;
/* Previous w value */
struct
serio
*
ptport
;
/* pass-through port */
};
#endif
/* _SYNAPTICS_H */
drivers/input/serio/i8042.c
View file @
8a2e73e1
...
...
@@ -12,11 +12,14 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/pm.h>
#include <linux/serio.h>
#include <asm/io.h>
...
...
@@ -25,19 +28,23 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION
(
"i8042 keyboard and mouse controller driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_PARM
(
i8042_noaux
,
"1i"
);
MODULE_PARM
(
i8042_nomux
,
"1i"
);
MODULE_PARM
(
i8042_unlock
,
"1i"
);
MODULE_PARM
(
i8042_reset
,
"1i"
);
MODULE_PARM
(
i8042_direct
,
"1i"
);
MODULE_PARM
(
i8042_dumbkbd
,
"1i"
);
static
unsigned
int
i8042_noaux
;
module_param
(
i8042_noaux
,
bool
,
0
);
static
int
i8042_reset
;
static
int
i8042_noaux
;
static
int
i8042_nomux
;
static
int
i8042_unlock
;
static
int
i8042_direct
;
static
int
i8042_dumbkbd
;
static
unsigned
int
i8042_nomux
;
module_param
(
i8042_nomux
,
bool
,
0
);
static
unsigned
int
i8042_unlock
;
module_param
(
i8042_unlock
,
bool
,
0
);
static
unsigned
int
i8042_reset
;
module_param
(
i8042_reset
,
bool
,
0
);
static
unsigned
int
i8042_direct
;
module_param
(
i8042_direct
,
bool
,
0
);
static
unsigned
int
i8042_dumbkbd
;
module_param
(
i8042_dumbkbd
,
bool
,
0
);
#undef DEBUG
#include "i8042.h"
...
...
@@ -59,6 +66,9 @@ static struct serio i8042_aux_port;
static
unsigned
char
i8042_initial_ctr
;
static
unsigned
char
i8042_ctr
;
static
unsigned
char
i8042_mux_open
;
static
unsigned
char
i8042_mux_present
;
static
unsigned
char
i8042_sysdev_initialized
;
static
struct
pm_dev
*
i8042_pm_dev
;
struct
timer_list
i8042_timer
;
/*
...
...
@@ -214,16 +224,41 @@ static int i8042_aux_write(struct serio *port, unsigned char c)
}
/*
* i8042_open() is called when a port is open by the higher layer.
* It allocates the interrupt and enables it in the chip.
* i8042_activate_port() enables port on a chip.
*/
static
int
i8042_
open
(
struct
serio
*
port
)
static
int
i8042_
activate_port
(
struct
serio
*
port
)
{
struct
i8042_values
*
values
=
port
->
driver
;
i8042_flush
();
/*
* Enable port again here because it is disabled if we are
* resuming (normally it is enabled already).
*/
i8042_ctr
&=
~
values
->
disable
;
i8042_ctr
|=
values
->
irqen
;
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
{
i8042_ctr
&=
~
values
->
irqen
;
return
-
1
;
}
return
0
;
}
/*
* i8042_open() is called when a port is open by the higher layer.
* It allocates the interrupt and calls i8042_enable_port.
*/
static
int
i8042_open
(
struct
serio
*
port
)
{
struct
i8042_values
*
values
=
port
->
driver
;
if
(
values
->
mux
!=
-
1
)
if
(
i8042_mux_open
++
)
return
0
;
...
...
@@ -231,21 +266,26 @@ static int i8042_open(struct serio *port)
if
(
request_irq
(
values
->
irq
,
i8042_interrupt
,
SA_SHIRQ
,
"i8042"
,
i8042_request_irq_cookie
))
{
printk
(
KERN_ERR
"i8042.c: Can't get irq %d for %s, unregistering the port.
\n
"
,
values
->
irq
,
values
->
name
);
values
->
exists
=
0
;
serio_unregister_port
(
port
);
return
-
1
;
goto
irq_fail
;
}
i8042_ctr
|=
values
->
irqen
;
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
{
printk
(
KERN_ERR
"i8042.c: Can't write CTR while opening %s.
\n
"
,
values
->
name
);
return
-
1
;
if
(
i8042_activate_port
(
port
))
{
printk
(
KERN_ERR
"i8042.c: Can't activate %s, unregistering the port
\n
"
,
values
->
name
);
goto
activate_fail
;
}
i8042_interrupt
(
0
,
NULL
,
NULL
);
return
0
;
activate_fail:
free_irq
(
values
->
irq
,
i8042_request_irq_cookie
);
irq_fail:
values
->
exists
=
0
;
serio_unregister_port_delayed
(
port
);
return
-
1
;
}
/*
...
...
@@ -393,145 +433,78 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
/*
* i8042_
controller init initializes the i8042 controller, and,
* m
ost importantly, sets it into non-xlated mode if that's
*
desired
.
* i8042_
enable_mux_mode checks whether the controller has an active
* m
ultiplexor and puts the chip into Multiplexed (as opposed to
*
Legacy) mode
.
*/
static
int
__init
i8042_controller_init
(
void
)
static
int
i8042_enable_mux_mode
(
struct
i8042_values
*
values
,
unsigned
char
*
mux_version
)
{
unsigned
char
param
;
/*
* Test the i8042. We need to know if it thinks it's working correctly
* before doing anything else.
* Get rid of bytes in the queue.
*/
i8042_flush
();
if
(
i8042_reset
)
{
unsigned
char
param
;
if
(
i8042_command
(
&
param
,
I8042_CMD_CTL_TEST
))
{
printk
(
KERN_ERR
"i8042.c: i8042 controller self test timeout.
\n
"
);
return
-
1
;
}
if
(
param
!=
I8042_RET_CTL_TEST
)
{
printk
(
KERN_ERR
"i8042.c: i8042 controller selftest failed. (%#x != %#x)
\n
"
,
param
,
I8042_RET_CTL_TEST
);
return
-
1
;
}
}
/*
* Save the CTR for restoral on unload / reboot.
* Internal loopback test - send three bytes, they should come back from the
* mouse interface, the last should be version. Note that we negate mouseport
* command responses for the i8042_check_aux() routine.
*/
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_RCTR
))
{
printk
(
KERN_ERR
"i8042.c: Can't read CTR while initializing i8042.
\n
"
);
param
=
0xf0
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
!=
0x0f
)
return
-
1
;
}
i8042_initial_ctr
=
i8042_ctr
;
/*
* Disable the keyboard interface and interrupt.
*/
i8042_ctr
|=
I8042_CTR_KBDDIS
;
i8042_ctr
&=
~
I8042_CTR_KBDINT
;
/*
* Handle keylock.
*/
if
(
~
i8042_read_status
()
&
I8042_STR_KEYLOCK
)
{
if
(
i8042_unlock
)
i8042_ctr
|=
I8042_CTR_IGNKEYLOCK
;
else
printk
(
KERN_WARNING
"i8042.c: Warning: Keylock active.
\n
"
);
}
/*
* If the chip is configured into nontranslated mode by the BIOS, don't
* bother enabling translating and be happy.
*/
if
(
~
i8042_ctr
&
I8042_CTR_XLATE
)
i8042_direct
=
1
;
/*
* Set nontranslated mode for the kbd interface if requested by an option.
* After this the kbd interface becomes a simple serial in/out, like the aux
* interface is. We don't do this by default, since it can confuse notebook
* BIOSes.
*/
if
(
i8042_direct
)
{
i8042_ctr
&=
~
I8042_CTR_XLATE
;
i8042_kbd_port
.
type
=
SERIO_8042
;
}
/*
* Write CTR back.
*/
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
{
printk
(
KERN_ERR
"i8042.c: Can't write CTR while initializing i8042.
\n
"
);
param
=
0x56
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
!=
0xa9
)
return
-
1
;
param
=
0xa4
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
==
0x5b
)
return
-
1
;
}
if
(
mux_version
)
*
mux_version
=
~
param
;
return
0
;
}
/*
*
Here we try to reset everything back to a state in which the BIOS will be
*
able to talk to the hardware when rebooting.
*
i8042_enable_mux_ports enables 4 individual AUX ports after
*
the controller has been switched into Multiplexed mode
*/
void
i8042_controller_cleanup
(
void
)
static
int
i8042_enable_mux_ports
(
struct
i8042_values
*
values
)
{
unsigned
char
param
;
int
i
;
i8042_flush
();
/*
* Reset anything that is connected to the ports.
*/
if
(
i8042_kbd_values
.
exists
)
serio_cleanup
(
&
i8042_kbd_port
);
if
(
i8042_aux_values
.
exists
)
serio_cleanup
(
&
i8042_aux_port
);
for
(
i
=
0
;
i
<
4
;
i
++
)
if
(
i8042_mux_values
[
i
].
exists
)
serio_cleanup
(
i8042_mux_port
+
i
);
/*
* Reset the controller.
* Disable all muxed ports by disabling AUX.
*/
i
f
(
i8042_reset
)
{
unsigned
char
param
;
i
8042_ctr
|=
I8042_CTR_AUXDIS
;
i8042_ctr
&=
~
I8042_CTR_AUXINT
;
if
(
i8042_command
(
&
param
,
I8042_CMD_CTL_TEST
))
printk
(
KERN_ERR
"i8042.c: i8042 controller reset timeout.
\n
"
);
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
{
printk
(
KERN_ERR
"i8042.c: Failed to disable AUX port, can't use MUX.
\n
"
);
return
-
1
;
}
/*
*
Restore the original control register setting
.
*
Enable all muxed ports
.
*/
i8042_ctr
=
i8042_initial_ctr
;
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
printk
(
KERN_WARNING
"i8042.c: Can't restore CTR.
\n
"
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
i8042_command
(
&
param
,
I8042_CMD_MUX_PFX
+
i
);
i8042_command
(
&
param
,
I8042_CMD_AUX_ENABLE
);
}
return
0
;
}
/*
* i8042_check_mux() checks whether the controller supports the PS/2 Active
* Multiplexing specification by Synaptics, Phoenix, Insyde and
...
...
@@ -540,66 +513,31 @@ void i8042_controller_cleanup(void)
static
int
__init
i8042_check_mux
(
struct
i8042_values
*
values
)
{
unsigned
char
param
;
static
int
i8042_check_mux_cookie
;
int
i
;
unsigned
char
mux_version
;
/*
* Check if AUX irq is available.
*/
if
(
request_irq
(
values
->
irq
,
i8042_interrupt
,
SA_SHIRQ
,
"i8042"
,
&
i8042_check_mux_cookie
))
return
-
1
;
free_irq
(
values
->
irq
,
&
i8042_check_mux_cookie
);
/*
* Get rid of bytes in the queue.
*/
i8042_flush
();
/*
* Internal loopback test - send three bytes, they should come back from the
* mouse interface, the last should be version. Note that we negate mouseport
* command responses for the i8042_check_aux() routine.
*/
param
=
0xf0
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
!=
0x0f
)
return
-
1
;
param
=
0x56
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
!=
0xa9
)
return
-
1
;
param
=
0xa4
;
if
(
i8042_command
(
&
param
,
I8042_CMD_AUX_LOOP
)
||
param
==
0x5b
)
if
(
i8042_enable_mux_mode
(
values
,
&
mux_version
))
return
-
1
;
printk
(
KERN_INFO
"i8042.c: Detected active multiplexing controller, rev %d.%d.
\n
"
,
(
~
param
>>
4
)
&
0xf
,
~
param
&
0xf
);
/*
* Disable all muxed ports by disabling AUX.
*/
i8042_ctr
|=
I8042_CTR_AUXDIS
;
i8042_ctr
&=
~
I8042_CTR_AUXINT
;
(
mux_version
>>
4
)
&
0xf
,
mux_version
&
0xf
);
if
(
i8042_
command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
if
(
i8042_
enable_mux_ports
(
values
))
return
-
1
;
/*
* Enable all muxed ports.
*/
for
(
i
=
0
;
i
<
4
;
i
++
)
{
i8042_command
(
&
param
,
I8042_CMD_MUX_PFX
+
i
);
i8042_command
(
&
param
,
I8042_CMD_AUX_ENABLE
);
}
i8042_mux_present
=
1
;
return
0
;
}
/*
* i8042_check_aux() applies as much paranoia as it can at detecting
* the presence of an AUX interface.
...
...
@@ -675,6 +613,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
return
0
;
}
/*
* i8042_port_register() marks the device as existing,
* registers it, and reports to the user.
...
...
@@ -691,63 +630,205 @@ static int __init i8042_port_register(struct i8042_values *values, struct serio
return
-
1
;
}
serio_register_port
(
port
);
printk
(
KERN_INFO
"serio: i8042 %s port at %#lx,%#lx irq %d
\n
"
,
values
->
name
,
(
unsigned
long
)
I8042_DATA_REG
,
(
unsigned
long
)
I8042_COMMAND_REG
,
values
->
irq
);
serio_register_port
(
port
);
return
0
;
}
static
void
i8042_timer_func
(
unsigned
long
data
)
{
i8042_interrupt
(
0
,
NULL
,
NULL
);
mod_timer
(
&
i8042_timer
,
jiffies
+
I8042_POLL_PERIOD
);
}
#ifndef MODULE
static
int
__init
i8042_setup_reset
(
char
*
str
)
{
i8042_reset
=
1
;
return
1
;
}
static
int
__init
i8042_setup_noaux
(
char
*
str
)
{
i8042_noaux
=
1
;
i8042_nomux
=
1
;
return
1
;
}
static
int
__init
i8042_setup_nomux
(
char
*
str
)
{
i8042_nomux
=
1
;
return
1
;
}
static
int
__init
i8042_setup_unlock
(
char
*
str
)
/*
* i8042_controller init initializes the i8042 controller, and,
* most importantly, sets it into non-xlated mode if that's
* desired.
*/
static
int
i8042_controller_init
(
void
)
{
i8042_unlock
=
1
;
return
1
;
if
(
i8042_noaux
)
i8042_nomux
=
1
;
/*
* Test the i8042. We need to know if it thinks it's working correctly
* before doing anything else.
*/
i8042_flush
();
if
(
i8042_reset
)
{
unsigned
char
param
;
if
(
i8042_command
(
&
param
,
I8042_CMD_CTL_TEST
))
{
printk
(
KERN_ERR
"i8042.c: i8042 controller self test timeout.
\n
"
);
return
-
1
;
}
if
(
param
!=
I8042_RET_CTL_TEST
)
{
printk
(
KERN_ERR
"i8042.c: i8042 controller selftest failed. (%#x != %#x)
\n
"
,
param
,
I8042_RET_CTL_TEST
);
return
-
1
;
}
}
/*
* Save the CTR for restoral on unload / reboot.
*/
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_RCTR
))
{
printk
(
KERN_ERR
"i8042.c: Can't read CTR while initializing i8042.
\n
"
);
return
-
1
;
}
i8042_initial_ctr
=
i8042_ctr
;
/*
* Disable the keyboard interface and interrupt.
*/
i8042_ctr
|=
I8042_CTR_KBDDIS
;
i8042_ctr
&=
~
I8042_CTR_KBDINT
;
/*
* Handle keylock.
*/
if
(
~
i8042_read_status
()
&
I8042_STR_KEYLOCK
)
{
if
(
i8042_unlock
)
i8042_ctr
|=
I8042_CTR_IGNKEYLOCK
;
else
printk
(
KERN_WARNING
"i8042.c: Warning: Keylock active.
\n
"
);
}
/*
* If the chip is configured into nontranslated mode by the BIOS, don't
* bother enabling translating and be happy.
*/
if
(
~
i8042_ctr
&
I8042_CTR_XLATE
)
i8042_direct
=
1
;
/*
* Set nontranslated mode for the kbd interface if requested by an option.
* After this the kbd interface becomes a simple serial in/out, like the aux
* interface is. We don't do this by default, since it can confuse notebook
* BIOSes.
*/
if
(
i8042_direct
)
{
i8042_ctr
&=
~
I8042_CTR_XLATE
;
i8042_kbd_port
.
type
=
SERIO_8042
;
}
/*
* Write CTR back.
*/
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
{
printk
(
KERN_ERR
"i8042.c: Can't write CTR while initializing i8042.
\n
"
);
return
-
1
;
}
return
0
;
}
static
int
__init
i8042_setup_direct
(
char
*
str
)
/*
* Here we try to reset everything back to a state in which the BIOS will be
* able to talk to the hardware when rebooting.
*/
void
i8042_controller_cleanup
(
void
)
{
i8042_direct
=
1
;
return
1
;
int
i
;
i8042_flush
();
/*
* Reset anything that is connected to the ports.
*/
if
(
i8042_kbd_values
.
exists
)
serio_cleanup
(
&
i8042_kbd_port
);
if
(
i8042_aux_values
.
exists
)
serio_cleanup
(
&
i8042_aux_port
);
for
(
i
=
0
;
i
<
4
;
i
++
)
if
(
i8042_mux_values
[
i
].
exists
)
serio_cleanup
(
i8042_mux_port
+
i
);
/*
* Reset the controller.
*/
if
(
i8042_reset
)
{
unsigned
char
param
;
if
(
i8042_command
(
&
param
,
I8042_CMD_CTL_TEST
))
printk
(
KERN_ERR
"i8042.c: i8042 controller reset timeout.
\n
"
);
}
/*
* Restore the original control register setting.
*/
i8042_ctr
=
i8042_initial_ctr
;
if
(
i8042_command
(
&
i8042_ctr
,
I8042_CMD_CTL_WCTR
))
printk
(
KERN_WARNING
"i8042.c: Can't restore CTR.
\n
"
);
}
static
int
__init
i8042_setup_dumbkbd
(
char
*
str
)
/*
* Here we try to reset everything back to a state in which suspended
*/
static
int
i8042_controller_resume
(
void
)
{
i8042_dumbkbd
=
1
;
return
1
;
int
i
;
if
(
i8042_controller_init
())
{
printk
(
KERN_ERR
"i8042: resume failed
\n
"
);
return
-
1
;
}
if
(
i8042_mux_present
)
if
(
i8042_enable_mux_mode
(
&
i8042_aux_values
,
NULL
)
||
i8042_enable_mux_ports
(
&
i8042_aux_values
))
{
printk
(
KERN_WARNING
"i8042: failed to resume active multiplexor, mouse won't wotk.
\n
"
);
}
/*
* Reconnect anything that was connected to the ports.
*/
if
(
i8042_kbd_values
.
exists
&&
i8042_activate_port
(
&
i8042_kbd_port
)
==
0
)
serio_reconnect
(
&
i8042_kbd_port
);
if
(
i8042_aux_values
.
exists
&&
i8042_activate_port
(
&
i8042_aux_port
)
==
0
)
serio_reconnect
(
&
i8042_aux_port
);
for
(
i
=
0
;
i
<
4
;
i
++
)
if
(
i8042_mux_values
[
i
].
exists
&&
i8042_activate_port
(
i8042_mux_port
+
i
)
==
0
)
serio_reconnect
(
i8042_mux_port
+
i
);
return
0
;
}
__setup
(
"i8042_reset"
,
i8042_setup_reset
);
__setup
(
"i8042_noaux"
,
i8042_setup_noaux
);
__setup
(
"i8042_nomux"
,
i8042_setup_nomux
);
__setup
(
"i8042_unlock"
,
i8042_setup_unlock
);
__setup
(
"i8042_direct"
,
i8042_setup_direct
);
__setup
(
"i8042_dumbkbd"
,
i8042_setup_dumbkbd
);
#endif
/*
* We need to reset the 8042 back to original mode on system shutdown,
...
...
@@ -769,6 +850,35 @@ static struct notifier_block i8042_notifier=
0
};
/*
* Resume handler for the new PM scheme (driver model)
*/
static
int
i8042_resume
(
struct
sys_device
*
dev
)
{
return
i8042_controller_resume
();
}
static
struct
sysdev_class
kbc_sysclass
=
{
set_kset_name
(
"i8042"
),
.
resume
=
i8042_resume
,
};
static
struct
sys_device
device_i8042
=
{
.
id
=
0
,
.
cls
=
&
kbc_sysclass
,
};
/*
* Resume handler for the old PM scheme (APM)
*/
static
int
i8042_pm_callback
(
struct
pm_dev
*
dev
,
pm_request_t
request
,
void
*
dummy
)
{
if
(
request
==
PM_RESUME
)
return
i8042_controller_resume
();
return
0
;
}
static
void
__init
i8042_init_mux_values
(
struct
i8042_values
*
values
,
struct
serio
*
port
,
int
index
)
{
memcpy
(
port
,
&
i8042_aux_port
,
sizeof
(
struct
serio
));
...
...
@@ -817,6 +927,15 @@ int __init i8042_init(void)
i8042_timer
.
function
=
i8042_timer_func
;
mod_timer
(
&
i8042_timer
,
jiffies
+
I8042_POLL_PERIOD
);
if
(
sysdev_class_register
(
&
kbc_sysclass
)
==
0
)
{
if
(
sys_device_register
(
&
device_i8042
)
==
0
)
i8042_sysdev_initialized
=
1
;
else
sysdev_class_unregister
(
&
kbc_sysclass
);
}
i8042_pm_dev
=
pm_register
(
PM_SYS_DEV
,
PM_SYS_UNKNOWN
,
i8042_pm_callback
);
register_reboot_notifier
(
&
i8042_notifier
);
return
0
;
...
...
@@ -828,6 +947,14 @@ void __exit i8042_exit(void)
unregister_reboot_notifier
(
&
i8042_notifier
);
if
(
i8042_pm_dev
)
pm_unregister
(
i8042_pm_dev
);
if
(
i8042_sysdev_initialized
)
{
sys_device_unregister
(
&
device_i8042
);
sysdev_class_unregister
(
&
kbc_sysclass
);
}
del_timer
(
&
i8042_timer
);
i8042_controller_cleanup
();
...
...
drivers/input/serio/serio.c
View file @
8a2e73e1
...
...
@@ -49,14 +49,17 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL
(
serio_interrupt
);
EXPORT_SYMBOL
(
serio_register_port
);
EXPORT_SYMBOL
(
serio_register_slave_port
);
EXPORT_SYMBOL
(
serio_register_port_delayed
);
EXPORT_SYMBOL
(
__serio_register_port
);
EXPORT_SYMBOL
(
serio_unregister_port
);
EXPORT_SYMBOL
(
serio_unregister_slave_port
);
EXPORT_SYMBOL
(
serio_unregister_port_delayed
);
EXPORT_SYMBOL
(
__serio_unregister_port
);
EXPORT_SYMBOL
(
serio_register_device
);
EXPORT_SYMBOL
(
serio_unregister_device
);
EXPORT_SYMBOL
(
serio_open
);
EXPORT_SYMBOL
(
serio_close
);
EXPORT_SYMBOL
(
serio_rescan
);
EXPORT_SYMBOL
(
serio_reconnect
);
struct
serio_event
{
int
type
;
...
...
@@ -82,11 +85,23 @@ static void serio_find_dev(struct serio *serio)
}
}
#define SERIO_RESCAN 1
#define SERIO_RESCAN 1
#define SERIO_RECONNECT 2
#define SERIO_REGISTER_PORT 3
#define SERIO_UNREGISTER_PORT 4
static
DECLARE_WAIT_QUEUE_HEAD
(
serio_wait
);
static
DECLARE_COMPLETION
(
serio_exited
);
static
void
serio_invalidate_pending_events
(
struct
serio
*
serio
)
{
struct
serio_event
*
event
;
list_for_each_entry
(
event
,
&
serio_event_list
,
node
)
if
(
event
->
serio
==
serio
)
event
->
serio
=
NULL
;
}
void
serio_handle_events
(
void
)
{
struct
list_head
*
node
,
*
next
;
...
...
@@ -95,17 +110,35 @@ void serio_handle_events(void)
list_for_each_safe
(
node
,
next
,
&
serio_event_list
)
{
event
=
container_of
(
node
,
struct
serio_event
,
node
);
down
(
&
serio_sem
);
if
(
event
->
serio
==
NULL
)
goto
event_done
;
switch
(
event
->
type
)
{
case
SERIO_REGISTER_PORT
:
__serio_register_port
(
event
->
serio
);
break
;
case
SERIO_UNREGISTER_PORT
:
__serio_unregister_port
(
event
->
serio
);
break
;
case
SERIO_RECONNECT
:
if
(
event
->
serio
->
dev
&&
event
->
serio
->
dev
->
reconnect
)
if
(
event
->
serio
->
dev
->
reconnect
(
event
->
serio
)
==
0
)
break
;
/* reconnect failed - fall through to rescan */
case
SERIO_RESCAN
:
down
(
&
serio_sem
);
if
(
event
->
serio
->
dev
&&
event
->
serio
->
dev
->
disconnect
)
event
->
serio
->
dev
->
disconnect
(
event
->
serio
);
serio_find_dev
(
event
->
serio
);
up
(
&
serio_sem
);
break
;
default:
break
;
}
event_done:
up
(
&
serio_sem
);
list_del_init
(
node
);
kfree
(
event
);
}
...
...
@@ -130,18 +163,27 @@ static int serio_thread(void *nothing)
complete_and_exit
(
&
serio_exited
,
0
);
}
void
serio_rescan
(
struct
serio
*
serio
)
static
void
serio_queue_event
(
struct
serio
*
serio
,
int
event_type
)
{
struct
serio_event
*
event
;
if
(
!
(
event
=
kmalloc
(
sizeof
(
struct
serio_event
),
GFP_ATOMIC
)))
return
;
if
((
event
=
kmalloc
(
sizeof
(
struct
serio_event
),
GFP_ATOMIC
)))
{
event
->
type
=
event_type
;
event
->
serio
=
serio
;
list_add_tail
(
&
event
->
node
,
&
serio_event_list
);
wake_up
(
&
serio_wait
);
}
}
event
->
type
=
SERIO_RESCAN
;
event
->
serio
=
serio
;
void
serio_rescan
(
struct
serio
*
serio
)
{
serio_queue_event
(
serio
,
SERIO_RESCAN
);
}
list_add_tail
(
&
event
->
node
,
&
serio_event_list
);
wake_up
(
&
serio_wait
);
void
serio_reconnect
(
struct
serio
*
serio
)
{
serio_queue_event
(
serio
,
SERIO_RECONNECT
);
}
irqreturn_t
serio_interrupt
(
struct
serio
*
serio
,
...
...
@@ -163,17 +205,26 @@ irqreturn_t serio_interrupt(struct serio *serio,
void
serio_register_port
(
struct
serio
*
serio
)
{
down
(
&
serio_sem
);
list_add_tail
(
&
serio
->
node
,
&
serio_list
);
serio_find_dev
(
serio
);
__serio_register_port
(
serio
);
up
(
&
serio_sem
);
}
/*
* Same as serio_register_port but does not try to acquire serio_sem.
* Should be used when registering a serio from other input device's
* Submits register request to kseriod for subsequent execution.
* Can be used when it is not obvious whether the serio_sem is
* taken or not and when delayed execution is feasible.
*/
void
serio_register_port_delayed
(
struct
serio
*
serio
)
{
serio_queue_event
(
serio
,
SERIO_REGISTER_PORT
);
}
/*
* Should only be called directly if serio_sem has already been taken,
* for example when unregistering a serio from other input device's
* connect() function.
*/
void
serio_register_slave
_port
(
struct
serio
*
serio
)
void
__serio_register
_port
(
struct
serio
*
serio
)
{
list_add_tail
(
&
serio
->
node
,
&
serio_list
);
serio_find_dev
(
serio
);
...
...
@@ -182,19 +233,28 @@ void serio_register_slave_port(struct serio *serio)
void
serio_unregister_port
(
struct
serio
*
serio
)
{
down
(
&
serio_sem
);
list_del_init
(
&
serio
->
node
);
if
(
serio
->
dev
&&
serio
->
dev
->
disconnect
)
serio
->
dev
->
disconnect
(
serio
);
__serio_unregister_port
(
serio
);
up
(
&
serio_sem
);
}
/*
* Same as serio_unregister_port but does not try to acquire serio_sem.
* Should be used when unregistering a serio from other input device's
* Submits unregister request to kseriod for subsequent execution.
* Can be used when it is not obvious whether the serio_sem is
* taken or not and when delayed execution is feasible.
*/
void
serio_unregister_port_delayed
(
struct
serio
*
serio
)
{
serio_queue_event
(
serio
,
SERIO_UNREGISTER_PORT
);
}
/*
* Should only be called directly if serio_sem has already been taken,
* for example when unregistering a serio from other input device's
* disconnect() function.
*/
void
serio_unregister_slave
_port
(
struct
serio
*
serio
)
void
__serio_unregister
_port
(
struct
serio
*
serio
)
{
serio_invalidate_pending_events
(
serio
);
list_del_init
(
&
serio
->
node
);
if
(
serio
->
dev
&&
serio
->
dev
->
disconnect
)
serio
->
dev
->
disconnect
(
serio
);
...
...
drivers/scsi/qla1280.c
View file @
8a2e73e1
...
...
@@ -16,9 +16,13 @@
* General Public License for more details.
*
******************************************************************************/
#define QLA1280_VERSION "3.23.37"
#define QLA1280_VERSION "3.23.37
.1
"
/*****************************************************************************
Revision History:
Rev 3.23.37.1 December 17, 2003, Jes Sorensen
- Delete completion queue from srb if mailbox command failed to
to avoid qla1280_done completeting qla1280_error_action's
obsolete context
Rev 3.23.37 October 1, 2003, Jes Sorensen
- Make MMIO depend on CONFIG_X86_VISWS instead of yet another
random CONFIG option
...
...
@@ -1464,8 +1468,15 @@ qla1280_error_action(Scsi_Cmnd * cmd, enum action action)
/* If we didn't manage to issue the action, or we have no
* command to wait for, exit here */
if
(
result
==
FAILED
||
handle
==
NULL
||
handle
==
(
unsigned
char
*
)
INVALID_HANDLE
)
handle
==
(
unsigned
char
*
)
INVALID_HANDLE
)
{
/*
* Clear completion queue to avoid qla1280_done() trying
* to complete the command at a later stage after we
* have exited the current context
*/
sp
->
wait
=
NULL
;
goto
leave
;
}
/* set up a timer just in case we're really jammed */
init_timer
(
&
timer
);
...
...
drivers/usb/core/devio.c
View file @
8a2e73e1
...
...
@@ -261,7 +261,6 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
spin_lock
(
&
ps
->
lock
);
list_move_tail
(
&
as
->
asynclist
,
&
ps
->
async_completed
);
spin_unlock
(
&
ps
->
lock
);
wake_up
(
&
ps
->
wait
);
if
(
as
->
signr
)
{
sinfo
.
si_signo
=
as
->
signr
;
sinfo
.
si_errno
=
as
->
urb
->
status
;
...
...
@@ -269,6 +268,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
sinfo
.
si_addr
=
(
void
*
)
as
->
userurb
;
send_sig_info
(
as
->
signr
,
&
sinfo
,
as
->
task
);
}
wake_up
(
&
ps
->
wait
);
}
static
void
destroy_async
(
struct
dev_state
*
ps
,
struct
list_head
*
list
)
...
...
drivers/usb/core/hub.c
View file @
8a2e73e1
...
...
@@ -692,6 +692,9 @@ static int hub_port_status(struct usb_device *dev, int port,
struct
usb_hub
*
hub
=
usb_get_intfdata
(
dev
->
actconfig
->
interface
[
0
]);
int
ret
;
if
(
!
hub
)
return
-
ENODEV
;
ret
=
get_port_status
(
dev
,
port
+
1
,
&
hub
->
status
->
port
);
if
(
ret
<
0
)
dev_err
(
hubdev
(
dev
),
...
...
@@ -926,7 +929,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
break
;
}
hub
->
children
[
port
]
=
dev
;
dev
->
state
=
USB_STATE_POWERED
;
/* Reset the device, and detect its speed */
...
...
@@ -979,8 +981,10 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
dev
->
dev
.
parent
=
dev
->
parent
->
dev
.
parent
->
parent
;
/* Run it through the hoops (find a driver, etc) */
if
(
!
usb_new_device
(
dev
,
&
hub
->
dev
))
if
(
!
usb_new_device
(
dev
,
&
hub
->
dev
))
{
hub
->
children
[
port
]
=
dev
;
goto
done
;
}
/* Free the configuration if there was an error */
usb_put_dev
(
dev
);
...
...
@@ -989,7 +993,6 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
delay
=
HUB_LONG_RESET_TIME
;
}
hub
->
children
[
port
]
=
NULL
;
hub_port_disable
(
hub
,
port
);
done:
up
(
&
usb_address0_sem
);
...
...
@@ -1342,6 +1345,7 @@ int usb_physical_reset_device(struct usb_device *dev)
dev
->
devpath
,
ret
);
return
ret
;
}
dev
->
state
=
USB_STATE_CONFIGURED
;
for
(
i
=
0
;
i
<
dev
->
actconfig
->
desc
.
bNumInterfaces
;
i
++
)
{
struct
usb_interface
*
intf
=
dev
->
actconfig
->
interface
[
i
];
...
...
drivers/usb/core/usb.c
View file @
8a2e73e1
...
...
@@ -1120,6 +1120,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
if
(
err
)
{
dev_err
(
&
dev
->
dev
,
"can't set config #%d, error %d
\n
"
,
dev
->
config
[
0
].
desc
.
bConfigurationValue
,
err
);
device_del
(
&
dev
->
dev
);
goto
fail
;
}
...
...
drivers/usb/host/uhci-hcd.c
View file @
8a2e73e1
...
...
@@ -2182,6 +2182,9 @@ static int uhci_reset(struct usb_hcd *hcd)
uhci
->
io_addr
=
(
unsigned
long
)
hcd
->
regs
;
/* Turn off all interrupts */
outw
(
0
,
uhci
->
io_addr
+
USBINTR
);
/* Maybe kick BIOS off this hardware. Then reset, so we won't get
* interrupts from any previous setup.
*/
...
...
drivers/usb/image/Kconfig
View file @
8a2e73e1
...
...
@@ -18,13 +18,15 @@ config USB_MDC800
module will be called mdc800.
config USB_SCANNER
tristate "USB Scanner support"
tristate "USB Scanner support
(OBSOLETE)
"
depends on USB
help
Say Y here if you want to connect a USB scanner to your computer's
USB port. Please read <file:Documentation/usb/scanner.txt> for more
information.
This driver has been obsoleted by support via libusb.
To compile this driver as a module, choose M here: the
module will be called scanner.
...
...
drivers/usb/misc/auerswald.c
View file @
8a2e73e1
...
...
@@ -324,7 +324,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
urb
=
acep
->
urbp
;
dbg
(
"auerchain_complete: submitting next urb from chain"
);
urb
->
status
=
0
;
/* needed! */
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
/* check for submit errors */
if
(
result
)
{
...
...
@@ -402,7 +402,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea
if
(
acep
)
{
dbg
(
"submitting urb immediate"
);
urb
->
status
=
0
;
/* needed! */
result
=
usb_submit_urb
(
urb
,
GFP_
KERNEL
);
result
=
usb_submit_urb
(
urb
,
GFP_
ATOMIC
);
/* check for submit errors */
if
(
result
)
{
urb
->
status
=
result
;
...
...
drivers/usb/serial/usb-serial.c
View file @
8a2e73e1
...
...
@@ -493,12 +493,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
return
retval
;
}
static
void
__serial_close
(
struct
usb_serial_port
*
port
,
struct
file
*
filp
)
static
void
serial_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
if
(
!
port
->
open_count
)
{
dbg
(
"%s - port not opened"
,
__FUNCTION__
);
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
tty
->
driver_data
;
struct
usb_serial
*
serial
=
get_usb_serial
(
port
,
__FUNCTION__
);
if
(
!
serial
)
return
;
}
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
--
port
->
open_count
;
if
(
port
->
open_count
<=
0
)
{
...
...
@@ -506,30 +509,18 @@ static void __serial_close(struct usb_serial_port *port, struct file *filp)
* port is being closed by the last owner */
port
->
serial
->
type
->
close
(
port
,
filp
);
port
->
open_count
=
0
;
if
(
port
->
tty
)
{
if
(
port
->
tty
->
driver_data
)
port
->
tty
->
driver_data
=
NULL
;
port
->
tty
=
NULL
;
}
}
module_put
(
port
->
serial
->
type
->
owner
);
kobject_put
(
&
port
->
serial
->
kobj
);
}
static
void
serial_close
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
tty
->
driver_data
;
struct
usb_serial
*
serial
=
get_usb_serial
(
port
,
__FUNCTION__
);
if
(
!
serial
)
return
;
dbg
(
"%s - port %d"
,
__FUNCTION__
,
port
->
number
);
/* if disconnect beat us to the punch here, there's nothing to do */
if
(
tty
&&
tty
->
driver_data
)
{
__serial_close
(
port
,
filp
);
tty
->
driver_data
=
NULL
;
}
port
->
tty
=
NULL
;
}
static
int
serial_write
(
struct
tty_struct
*
tty
,
int
from_user
,
const
unsigned
char
*
buf
,
int
count
)
{
struct
usb_serial_port
*
port
=
(
struct
usb_serial_port
*
)
tty
->
driver_data
;
...
...
@@ -848,19 +839,6 @@ static void destroy_serial (struct kobject *kobj)
dbg
(
"%s - %s"
,
__FUNCTION__
,
kobj
->
name
);
serial
=
to_usb_serial
(
kobj
);
/* fail all future close/read/write/ioctl/etc calls */
for
(
i
=
0
;
i
<
serial
->
num_ports
;
++
i
)
{
port
=
serial
->
port
[
i
];
if
(
port
->
tty
!=
NULL
)
{
port
->
tty
->
driver_data
=
NULL
;
while
(
port
->
open_count
>
0
)
{
__serial_close
(
port
,
NULL
);
}
port
->
tty
=
NULL
;
}
}
serial_shutdown
(
serial
);
/* return the minor range that this device had */
...
...
@@ -1242,7 +1220,7 @@ int usb_serial_probe(struct usb_interface *interface,
/* register all of the individual ports with the driver core */
for
(
i
=
0
;
i
<
num_ports
;
++
i
)
{
port
=
serial
->
port
[
i
];
port
->
dev
.
parent
=
&
serial
->
dev
->
dev
;
port
->
dev
.
parent
=
&
interface
->
dev
;
port
->
dev
.
driver
=
NULL
;
port
->
dev
.
bus
=
&
usb_serial_bus_type
;
port
->
dev
.
release
=
&
port_release
;
...
...
drivers/usb/storage/datafab.c
View file @
8a2e73e1
...
...
@@ -387,7 +387,7 @@ static int datafab_id_device(struct us_data *us,
// we'll go ahead and extract the media capacity while we're here...
//
rc
=
datafab_bulk_read
(
us
,
reply
,
sizeof
(
reply
)
);
rc
=
datafab_bulk_read
(
us
,
reply
,
512
);
if
(
rc
==
USB_STOR_XFER_GOOD
)
{
// capacity is at word offset 57-58
//
...
...
drivers/usb/storage/jumpshot.c
View file @
8a2e73e1
...
...
@@ -317,7 +317,7 @@ static int jumpshot_id_device(struct us_data *us,
}
// read the reply
rc
=
jumpshot_bulk_read
(
us
,
reply
,
sizeof
(
reply
)
);
rc
=
jumpshot_bulk_read
(
us
,
reply
,
512
);
if
(
rc
!=
USB_STOR_XFER_GOOD
)
{
rc
=
USB_STOR_TRANSPORT_ERROR
;
goto
leave
;
...
...
include/asm-i386/irq.h
View file @
8a2e73e1
...
...
@@ -24,6 +24,7 @@ extern void disable_irq(unsigned int);
extern
void
disable_irq_nosync
(
unsigned
int
);
extern
void
enable_irq
(
unsigned
int
);
extern
void
release_x86_irqs
(
struct
task_struct
*
);
extern
int
can_request_irq
(
unsigned
int
,
unsigned
long
flags
);
#ifdef CONFIG_X86_LOCAL_APIC
#define ARCH_HAS_NMI_WATCHDOG
/* See include/linux/nmi.h */
...
...
include/linux/input.h
View file @
8a2e73e1
...
...
@@ -870,6 +870,7 @@ struct input_handler {
char
*
name
;
struct
input_device_id
*
id_table
;
struct
input_device_id
*
blacklist
;
struct
list_head
h_list
;
struct
list_head
node
;
...
...
include/linux/keyboard.h
View file @
8a2e73e1
...
...
@@ -2,7 +2,6 @@
#define __LINUX_KEYBOARD_H
#include <linux/wait.h>
#include <linux/input.h>
#define KG_SHIFT 0
#define KG_CTRL 2
...
...
@@ -17,7 +16,7 @@
#define NR_SHIFT 9
#define NR_KEYS
(KEY_MAX+1)
#define NR_KEYS
255
#define MAX_NR_KEYMAPS 256
/* This means 128Kb if all keymaps are allocated. Only the superuser
may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
...
...
include/linux/serio.h
View file @
8a2e73e1
...
...
@@ -49,6 +49,7 @@ struct serio_dev {
irqreturn_t
(
*
interrupt
)(
struct
serio
*
,
unsigned
char
,
unsigned
int
,
struct
pt_regs
*
);
void
(
*
connect
)(
struct
serio
*
,
struct
serio_dev
*
dev
);
int
(
*
reconnect
)(
struct
serio
*
);
void
(
*
disconnect
)(
struct
serio
*
);
void
(
*
cleanup
)(
struct
serio
*
);
...
...
@@ -58,12 +59,15 @@ struct serio_dev {
int
serio_open
(
struct
serio
*
serio
,
struct
serio_dev
*
dev
);
void
serio_close
(
struct
serio
*
serio
);
void
serio_rescan
(
struct
serio
*
serio
);
void
serio_reconnect
(
struct
serio
*
serio
);
irqreturn_t
serio_interrupt
(
struct
serio
*
serio
,
unsigned
char
data
,
unsigned
int
flags
,
struct
pt_regs
*
regs
);
void
serio_register_port
(
struct
serio
*
serio
);
void
serio_register_slave_port
(
struct
serio
*
serio
);
void
serio_register_port_delayed
(
struct
serio
*
serio
);
void
__serio_register_port
(
struct
serio
*
serio
);
void
serio_unregister_port
(
struct
serio
*
serio
);
void
serio_unregister_slave_port
(
struct
serio
*
serio
);
void
serio_unregister_port_delayed
(
struct
serio
*
serio
);
void
__serio_unregister_port
(
struct
serio
*
serio
);
void
serio_register_device
(
struct
serio_dev
*
dev
);
void
serio_unregister_device
(
struct
serio_dev
*
dev
);
...
...
kernel/sched.c
View file @
8a2e73e1
...
...
@@ -1470,6 +1470,7 @@ void scheduling_functions_start_here(void) { }
*/
asmlinkage
void
schedule
(
void
)
{
long
*
switch_count
;
task_t
*
prev
,
*
next
;
runqueue_t
*
rq
;
prio_array_t
*
array
;
...
...
@@ -1516,32 +1517,25 @@ asmlinkage void schedule(void)
* if entering off of a kernel preemption go straight
* to picking the next task.
*/
if
(
unlikely
(
preempt_count
()
&
PREEMPT_ACTIVE
))
goto
pick_next_task
;
switch
(
prev
->
state
)
{
case
TASK_INTERRUPTIBLE
:
if
(
unlikely
(
signal_pending
(
prev
)))
{
switch_count
=
&
prev
->
nivcsw
;
if
(
prev
->
state
&&
!
(
preempt_count
()
&
PREEMPT_ACTIVE
))
{
switch_count
=
&
prev
->
nvcsw
;
if
(
unlikely
((
prev
->
state
&
TASK_INTERRUPTIBLE
)
&&
unlikely
(
signal_pending
(
prev
))))
prev
->
state
=
TASK_RUNNING
;
break
;
}
default:
deactivate_task
(
prev
,
rq
);
prev
->
nvcsw
++
;
break
;
case
TASK_RUNNING
:
prev
->
nivcsw
++
;
else
deactivate_task
(
prev
,
rq
);
}
pick_next_task:
if
(
unlikely
(
!
rq
->
nr_running
))
{
#ifdef CONFIG_SMP
load_balance
(
rq
,
1
,
cpu_to_node_mask
(
smp_processor_id
()));
if
(
rq
->
nr_running
)
goto
pick_next_task
;
#endif
next
=
rq
->
idle
;
rq
->
expired_timestamp
=
0
;
goto
switch_tasks
;
if
(
!
rq
->
nr_running
)
{
next
=
rq
->
idle
;
rq
->
expired_timestamp
=
0
;
goto
switch_tasks
;
}
}
array
=
rq
->
active
;
...
...
@@ -1588,6 +1582,7 @@ asmlinkage void schedule(void)
next
->
timestamp
=
now
;
rq
->
nr_switches
++
;
rq
->
curr
=
next
;
++*
switch_count
;
prepare_arch_switch
(
rq
,
next
);
prev
=
context_switch
(
rq
,
prev
,
next
);
...
...
lib/kobject.c
View file @
8a2e73e1
...
...
@@ -236,8 +236,6 @@ static void unlink(struct kobject * kobj)
list_del_init
(
&
kobj
->
entry
);
up_write
(
&
kobj
->
kset
->
subsys
->
rwsem
);
}
if
(
kobj
->
parent
)
kobject_put
(
kobj
->
parent
);
kobject_put
(
kobj
);
}
...
...
@@ -274,9 +272,11 @@ int kobject_add(struct kobject * kobj)
kobj
->
parent
=
parent
;
error
=
create_dir
(
kobj
);
if
(
error
)
if
(
error
)
{
unlink
(
kobj
);
else
{
if
(
parent
)
kobject_put
(
parent
);
}
else
{
/* If this kobj does not belong to a kset,
try to find a parent that does. */
top_kobj
=
kobj
;
...
...
@@ -452,6 +452,7 @@ void kobject_cleanup(struct kobject * kobj)
{
struct
kobj_type
*
t
=
get_ktype
(
kobj
);
struct
kset
*
s
=
kobj
->
kset
;
struct
kobject
*
parent
=
kobj
->
parent
;
pr_debug
(
"kobject %s: cleaning up
\n
"
,
kobject_name
(
kobj
));
if
(
kobj
->
k_name
!=
kobj
->
name
)
...
...
@@ -461,6 +462,8 @@ void kobject_cleanup(struct kobject * kobj)
t
->
release
(
kobj
);
if
(
s
)
kset_put
(
s
);
if
(
parent
)
kobject_put
(
parent
);
}
/**
...
...
scripts/file2alias.c
View file @
8a2e73e1
...
...
@@ -52,6 +52,13 @@ static int do_usb_entry(const char *filename,
id
->
bcdDevice_lo
=
TO_NATIVE
(
id
->
bcdDevice_lo
);
id
->
bcdDevice_hi
=
TO_NATIVE
(
id
->
bcdDevice_hi
);
/*
* Some modules (visor) have empty slots as placeholder for
* run-time specification that results in catch-all alias
*/
if
(
!
(
id
->
idVendor
|
id
->
bDeviceClass
|
id
->
bInterfaceClass
))
return
1
;
strcpy
(
alias
,
"usb:"
);
ADD
(
alias
,
"v"
,
id
->
match_flags
&
USB_DEVICE_ID_MATCH_VENDOR
,
id
->
idVendor
);
...
...
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