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
57d52f67
Commit
57d52f67
authored
Feb 11, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
0f739278
d96835d3
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
724 additions
and
405 deletions
+724
-405
drivers/usb/hid-core.c
drivers/usb/hid-core.c
+402
-229
drivers/usb/hid-debug.h
drivers/usb/hid-debug.h
+156
-7
drivers/usb/hid-input.c
drivers/usb/hid-input.c
+46
-11
drivers/usb/hid.h
drivers/usb/hid.h
+54
-101
drivers/usb/hiddev.c
drivers/usb/hiddev.c
+2
-2
drivers/usb/pegasus.h
drivers/usb/pegasus.h
+8
-0
drivers/usb/usbkbd.c
drivers/usb/usbkbd.c
+24
-26
drivers/usb/usbmouse.c
drivers/usb/usbmouse.c
+16
-17
drivers/usb/wacom.c
drivers/usb/wacom.c
+16
-12
No files found.
drivers/usb/hid-core.c
View file @
57d52f67
/*
* $Id: hid-core.c,v 1.
8 2001/05/23 12:02:18
vojtech Exp $
* $Id: hid-core.c,v 1.
42 2002/01/27 00:22:46
vojtech Exp $
*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* USB HID support for Linux
*
* Sponsored by SuSE
*/
/*
...
...
@@ -25,8 +23,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>
...
...
@@ -56,9 +54,10 @@
* Version Information
*/
#define DRIVER_VERSION "v1.8"
#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
#define DRIVER_DESC "USB HID support drivers"
#define DRIVER_VERSION "v1.31"
#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB HID core driver"
#define DRIVER_LICENSE "GPL"
static
char
*
hid_types
[]
=
{
"Device"
,
"Pointer"
,
"Mouse"
,
"Device"
,
"Joystick"
,
"Gamepad"
,
"Keyboard"
,
"Keypad"
,
"Multi-Axis Controller"
};
...
...
@@ -205,16 +204,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
return
-
1
;
}
if
(
HID_MAIN_ITEM_VARIABLE
&
~
flags
)
{
/* ARRAY */
if
(
parser
->
global
.
logical_maximum
<=
parser
->
global
.
logical_minimum
)
{
dbg
(
"logical range invalid %d %d"
,
parser
->
global
.
logical_minimum
,
parser
->
global
.
logical_maximum
);
return
-
1
;
}
usages
=
parser
->
local
.
usage_index
;
/* Hint: we can assume usages < MAX_USAGE here */
}
else
{
/* VARIABLE */
usages
=
parser
->
global
.
report_count
;
}
offset
=
report
->
size
;
report
->
size
+=
parser
->
global
.
report_size
*
parser
->
global
.
report_count
;
...
...
@@ -311,7 +305,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return
0
;
case
HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM
:
if
(
parser
->
global
.
logical_minimum
<
0
)
parser
->
global
.
logical_maximum
=
item_sdata
(
item
);
else
parser
->
global
.
logical_maximum
=
item_udata
(
item
);
return
0
;
case
HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM
:
...
...
@@ -319,11 +316,14 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
return
0
;
case
HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM
:
if
(
parser
->
global
.
physical_minimum
<
0
)
parser
->
global
.
physical_maximum
=
item_sdata
(
item
);
else
parser
->
global
.
physical_maximum
=
item_udata
(
item
);
return
0
;
case
HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT
:
parser
->
global
.
unit_exponent
=
item_
u
data
(
item
);
parser
->
global
.
unit_exponent
=
item_
s
data
(
item
);
return
0
;
case
HID_GLOBAL_ITEM_TAG_UNIT
:
...
...
@@ -508,8 +508,6 @@ static void hid_free_report(struct hid_report *report)
for
(
n
=
0
;
n
<
report
->
maxfield
;
n
++
)
kfree
(
report
->
field
[
n
]);
if
(
report
->
data
)
kfree
(
report
->
data
);
kfree
(
report
);
}
...
...
@@ -538,11 +536,15 @@ static void hid_free_device(struct hid_device *device)
* items, though they are not used yet.
*/
static
__
u8
*
fetch_item
(
__u8
*
start
,
__u8
*
end
,
struct
hid_item
*
item
)
static
u8
*
fetch_item
(
__u8
*
start
,
__u8
*
end
,
struct
hid_item
*
item
)
{
if
((
end
-
start
)
>
0
)
{
u8
b
;
if
((
end
-
start
)
<=
0
)
return
NULL
;
b
=
*
start
++
;
__u8
b
=
*
start
++
;
item
->
type
=
(
b
>>
2
)
&
3
;
item
->
tag
=
(
b
>>
4
)
&
15
;
...
...
@@ -550,48 +552,48 @@ static __u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
item
->
format
=
HID_ITEM_FORMAT_LONG
;
if
((
end
-
start
)
>=
2
)
{
if
((
end
-
start
)
<
2
)
return
NULL
;
item
->
size
=
*
start
++
;
item
->
tag
=
*
start
++
;
if
((
end
-
start
)
>=
item
->
size
)
{
if
((
end
-
start
)
<
item
->
size
)
return
NULL
;
item
->
data
.
longdata
=
start
;
start
+=
item
->
size
;
return
start
;
}
}
}
else
{
item
->
format
=
HID_ITEM_FORMAT_SHORT
;
item
->
size
=
b
&
3
;
switch
(
item
->
size
)
{
case
0
:
return
start
;
case
1
:
if
((
end
-
start
)
>=
1
)
{
if
((
end
-
start
)
<
1
)
return
NULL
;
item
->
data
.
u8
=
*
start
++
;
return
start
;
}
break
;
case
2
:
if
((
end
-
start
)
>=
2
)
{
item
->
data
.
u16
=
le16_to_cpu
(
get_unaligned
(((
__u16
*
)
start
)
++
));
if
((
end
-
start
)
<
2
)
return
NULL
;
item
->
data
.
u16
=
le16_to_cpu
(
get_unaligned
(((
__u16
*
)
start
)
++
));
return
start
;
}
case
3
:
item
->
size
++
;
if
((
end
-
start
)
>=
4
)
{
item
->
data
.
u32
=
le32_to_cpu
(
get_unaligned
(((
__u32
*
)
start
)
++
));
if
((
end
-
start
)
<
4
)
return
NULL
;
item
->
data
.
u32
=
le32_to_cpu
(
get_unaligned
(((
__u32
*
)
start
)
++
));
return
start
;
}
}
}
}
return
NULL
;
}
...
...
@@ -638,12 +640,14 @@ static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
end
=
start
+
size
;
while
((
start
=
fetch_item
(
start
,
end
,
&
item
))
!=
0
)
{
if
(
item
.
format
!=
HID_ITEM_FORMAT_SHORT
)
{
dbg
(
"unexpected long global item"
);
hid_free_device
(
device
);
kfree
(
parser
);
return
NULL
;
}
if
(
dispatch_type
[
item
.
type
](
parser
,
&
item
))
{
dbg
(
"item %u %u %u %u parsing failed
\n
"
,
item
.
format
,
(
unsigned
)
item
.
size
,
(
unsigned
)
item
.
type
,
(
unsigned
)
item
.
tag
);
...
...
@@ -742,7 +746,6 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
#endif
}
/*
* Analyse a received field, and fetch the data from it. The field
* content is stored for next report processing (we do differential
...
...
@@ -797,9 +800,12 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u
memcpy
(
field
->
value
,
value
,
count
*
sizeof
(
__s32
));
}
static
int
hid_input_report
(
int
type
,
u8
*
data
,
int
len
,
struct
hid_device
*
hid
)
static
int
hid_input_report
(
int
type
,
struct
urb
*
urb
)
{
struct
hid_device
*
hid
=
urb
->
context
;
struct
hid_report_enum
*
report_enum
=
hid
->
report_enum
+
type
;
u8
*
data
=
urb
->
transfer_buffer
;
int
len
=
urb
->
actual_length
;
struct
hid_report
*
report
;
int
n
,
size
;
...
...
@@ -818,92 +824,46 @@ static int hid_input_report(int type, u8 *data, int len, struct hid_device *hid)
len
--
;
}
if
(
!
(
report
=
report_enum
->
report_id_hash
[
n
]))
{
dbg
(
"undefined report_id %d received"
,
n
);
#ifdef DEBUG
printk
(
KERN_DEBUG
__FILE__
": report (size %u) = "
,
len
);
for
(
n
=
0
;
n
<
len
;
n
++
)
printk
(
" %02x"
,
data
[
n
]);
#ifdef DEBUG_DATA
{
int
i
;
printk
(
KERN_DEBUG
__FILE__
": report %d (size %u) = "
,
n
,
len
);
for
(
i
=
0
;
i
<
n
;
i
++
)
printk
(
" %02x"
,
data
[
i
]);
printk
(
"
\n
"
);
}
#endif
if
(
!
(
report
=
report_enum
->
report_id_hash
[
n
]))
{
dbg
(
"undefined report_id %d received"
,
n
);
return
-
1
;
}
size
=
((
report
->
size
-
1
)
>>
3
)
+
1
;
if
(
len
<
size
)
{
if
(
size
<=
8
)
{
dbg
(
"report %d is too short, (%d < %d)"
,
report
->
id
,
len
,
size
);
return
-
1
;
}
/*
* Some low-speed devices have large reports and maxpacketsize 8.
* We buffer the data in that case and parse it when we got it all.
* Works only for unnumbered reports. Doesn't make sense for numbered
* reports anyway - then they don't need to be large.
*/
if
(
!
report
->
data
)
if
(
!
(
report
->
data
=
kmalloc
(
size
,
GFP_ATOMIC
)))
{
dbg
(
"couldn't allocate report buffer"
);
return
-
1
;
}
if
(
report
->
idx
+
len
>
size
)
{
dbg
(
"report data buffer overflow"
);
report
->
idx
=
0
;
return
-
1
;
}
memcpy
(
report
->
data
+
report
->
idx
,
data
,
len
);
report
->
idx
+=
len
;
if
(
report
->
idx
<
size
)
return
0
;
data
=
report
->
data
;
}
for
(
n
=
0
;
n
<
report
->
maxfield
;
n
++
)
hid_input_field
(
hid
,
report
->
field
[
n
],
data
);
report
->
idx
=
0
;
return
0
;
}
/*
* In
terrupt input
handler.
* In
put interrupt completion
handler.
*/
static
void
hid_irq
(
struct
urb
*
urb
)
static
void
hid_irq
_in
(
struct
urb
*
urb
)
{
if
(
urb
->
status
)
{
dbg
(
"nonzero status in irq %d"
,
urb
->
status
);
dbg
(
"nonzero status in i
nput i
rq %d"
,
urb
->
status
);
return
;
}
hid_input_report
(
HID_INPUT_REPORT
,
urb
->
transfer_buffer
,
urb
->
actual_length
,
urb
->
context
);
}
/*
* hid_read_report() reads in report values without waiting for an irq urb.
*/
void
hid_read_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
{
int
len
=
((
report
->
size
-
1
)
>>
3
)
+
1
+
hid
->
report_enum
[
report
->
type
].
numbered
;
u8
data
[
len
];
int
read
;
if
((
read
=
hid_get_report
(
hid
->
dev
,
hid
->
ifnum
,
report
->
type
+
1
,
report
->
id
,
data
,
len
))
!=
len
)
{
dbg
(
"reading report type %d id %d failed len %d read %d"
,
report
->
type
+
1
,
report
->
id
,
len
,
read
);
return
;
}
hid_input_report
(
report
->
type
,
data
,
len
,
hid
);
hid_input_report
(
HID_INPUT_REPORT
,
urb
);
}
/*
...
...
@@ -949,7 +909,8 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
hid_dump_input
(
field
->
usage
+
offset
,
value
);
if
(
offset
>=
field
->
report_count
)
{
dbg
(
"offset exceeds report_count"
);
dbg
(
"offset (%d) exceeds report_count (%d)"
,
offset
,
field
->
report_count
);
hid_dump_field
(
field
,
8
);
return
-
1
;
}
if
(
field
->
logical_minimum
<
0
)
{
...
...
@@ -958,11 +919,6 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
return
-
1
;
}
}
if
(
(
value
>
field
->
logical_maximum
)
||
(
value
<
field
->
logical_minimum
))
{
dbg
(
"value %d is invalid"
,
value
);
return
-
1
;
}
field
->
value
[
offset
]
=
value
;
return
0
;
}
...
...
@@ -986,14 +942,56 @@ int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code,
return
-
1
;
}
/*
* Find a report with a specified HID usage.
*/
int
hid_find_report_by_usage
(
struct
hid_device
*
hid
,
__u32
wanted_usage
,
struct
hid_report
**
report
,
int
type
)
{
struct
hid_report_enum
*
report_enum
=
hid
->
report_enum
+
type
;
struct
list_head
*
list
=
report_enum
->
report_list
.
next
;
int
i
,
j
;
while
(
list
!=
&
report_enum
->
report_list
)
{
*
report
=
(
struct
hid_report
*
)
list
;
list
=
list
->
next
;
for
(
i
=
0
;
i
<
(
*
report
)
->
maxfield
;
i
++
)
{
struct
hid_field
*
field
=
(
*
report
)
->
field
[
i
];
for
(
j
=
0
;
j
<
field
->
maxusage
;
j
++
)
if
(
field
->
logical
==
wanted_usage
)
return
j
;
}
}
return
-
1
;
}
int
hid_find_field_in_report
(
struct
hid_report
*
report
,
__u32
wanted_usage
,
struct
hid_field
**
field
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
report
->
maxfield
;
i
++
)
{
*
field
=
report
->
field
[
i
];
for
(
j
=
0
;
j
<
(
*
field
)
->
maxusage
;
j
++
)
if
((
*
field
)
->
usage
[
j
].
hid
==
wanted_usage
)
return
j
;
}
return
-
1
;
}
static
int
hid_submit_out
(
struct
hid_device
*
hid
)
{
hid
->
urbout
.
transfer_buffer_length
=
le16_to_cpup
(
&
hid
->
out
[
hid
->
outtail
].
dr
.
wLength
);
hid
->
urbout
.
transfer_buffer
=
hid
->
out
[
hid
->
outtail
].
buffer
;
hid
->
urbout
.
setup_packet
=
(
void
*
)
&
(
hid
->
out
[
hid
->
outtail
].
dr
);
hid
->
urbout
.
dev
=
hid
->
dev
;
struct
hid_report
*
report
;
report
=
hid
->
out
[
hid
->
outtail
];
hid_output_report
(
report
,
hid
->
outbuf
);
hid
->
urbout
->
transfer_buffer_length
=
((
report
->
size
-
1
)
>>
3
)
+
1
;
hid
->
urbout
->
dev
=
hid
->
dev
;
if
(
usb_submit_urb
(
&
hid
->
urbout
,
GFP_KERNEL
))
{
dbg
(
"submitting out urb"
);
if
(
usb_submit_urb
(
hid
->
urbout
,
GFP_ATOMIC
))
{
err
(
"usb_submit_urb(out) failed"
);
return
-
1
;
}
...
...
@@ -1001,33 +999,168 @@ static int hid_submit_out(struct hid_device *hid)
return
0
;
}
static
int
hid_submit_ctrl
(
struct
hid_device
*
hid
)
{
struct
hid_report
*
report
;
unsigned
char
dir
;
report
=
hid
->
ctrl
[
hid
->
ctrltail
].
report
;
dir
=
hid
->
ctrl
[
hid
->
ctrltail
].
dir
;
if
(
dir
==
USB_DIR_OUT
)
hid_output_report
(
report
,
hid
->
ctrlbuf
);
hid
->
urbctrl
->
transfer_buffer_length
=
((
report
->
size
-
1
)
>>
3
)
+
1
+
((
report
->
id
>
0
)
&&
(
dir
!=
USB_DIR_OUT
));
hid
->
urbctrl
->
pipe
=
(
dir
==
USB_DIR_OUT
)
?
usb_sndctrlpipe
(
hid
->
dev
,
0
)
:
usb_rcvctrlpipe
(
hid
->
dev
,
0
);
hid
->
urbctrl
->
dev
=
hid
->
dev
;
hid
->
cr
.
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
|
dir
;
hid
->
cr
.
bRequest
=
(
dir
==
USB_DIR_OUT
)
?
HID_REQ_SET_REPORT
:
HID_REQ_GET_REPORT
;
hid
->
cr
.
wValue
=
((
report
->
type
+
1
)
<<
8
)
|
report
->
id
;
hid
->
cr
.
wIndex
=
cpu_to_le16
(
hid
->
ifnum
);
hid
->
cr
.
wLength
=
cpu_to_le16
(
hid
->
urbctrl
->
transfer_buffer_length
);
dbg
(
"submitting ctrl urb"
);
if
(
usb_submit_urb
(
hid
->
urbctrl
,
GFP_ATOMIC
))
{
err
(
"usb_submit_urb(ctrl) failed"
);
return
-
1
;
}
return
0
;
}
/*
* Output interrupt completion handler.
*/
static
void
hid_irq_out
(
struct
urb
*
urb
)
{
struct
hid_device
*
hid
=
urb
->
context
;
unsigned
long
flags
;
if
(
urb
->
status
)
warn
(
"output irq status %d received"
,
urb
->
status
);
spin_lock_irqsave
(
&
hid
->
outlock
,
flags
);
hid
->
outtail
=
(
hid
->
outtail
+
1
)
&
(
HID_OUTPUT_FIFO_SIZE
-
1
);
if
(
hid
->
outhead
!=
hid
->
outtail
)
{
hid_submit_out
(
hid
);
return
;
}
clear_bit
(
HID_OUT_RUNNING
,
&
hid
->
iofl
);
spin_unlock_irqrestore
(
&
hid
->
outlock
,
flags
);
wake_up
(
&
hid
->
wait
);
}
/*
* Control pipe completion handler.
*/
static
void
hid_ctrl
(
struct
urb
*
urb
)
{
struct
hid_device
*
hid
=
urb
->
context
;
unsigned
long
flags
;
if
(
urb
->
status
)
warn
(
"ctrl urb status %d received"
,
urb
->
status
);
hid
->
outtail
=
(
hid
->
outtail
+
1
)
&
(
HID_CONTROL_FIFO_SIZE
-
1
);
spin_lock_irqsave
(
&
hid
->
ctrllock
,
flags
);
if
(
hid
->
outhead
!=
hid
->
outtail
)
hid_submit_out
(
hid
);
if
(
hid
->
ctrl
[
hid
->
ctrltail
].
dir
==
USB_DIR_IN
)
hid_input_report
(
hid
->
ctrl
[
hid
->
ctrltail
].
report
->
type
,
urb
);
hid
->
ctrltail
=
(
hid
->
ctrltail
+
1
)
&
(
HID_CONTROL_FIFO_SIZE
-
1
);
if
(
hid
->
ctrlhead
!=
hid
->
ctrltail
)
{
hid_submit_ctrl
(
hid
);
return
;
}
clear_bit
(
HID_CTRL_RUNNING
,
&
hid
->
iofl
);
spin_unlock_irqrestore
(
&
hid
->
ctrllock
,
flags
);
wake_up
(
&
hid
->
wait
);
}
void
hid_
write_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
void
hid_
submit_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
,
unsigned
char
dir
)
{
hid_output_report
(
report
,
hid
->
out
[
hid
->
outhead
].
buffer
);
int
head
;
unsigned
long
flags
;
hid
->
out
[
hid
->
outhead
].
dr
.
wValue
=
cpu_to_le16
(
0x200
|
report
->
id
);
hid
->
out
[
hid
->
outhead
].
dr
.
wLength
=
cpu_to_le16
((
report
->
size
+
7
)
>>
3
);
if
(
hid
->
urbout
&&
dir
==
USB_DIR_OUT
&&
report
->
type
==
HID_OUTPUT_REPORT
)
{
hid
->
outhead
=
(
hid
->
outhead
+
1
)
&
(
HID_CONTROL_FIFO_SIZE
-
1
);
spin_lock_irqsave
(
&
hid
->
outlock
,
flags
);
if
(
hid
->
outhead
==
hid
->
outtail
)
hid
->
outtail
=
(
hid
->
outtail
+
1
)
&
(
HID_CONTROL_FIFO_SIZE
-
1
);
if
((
head
=
(
hid
->
outhead
+
1
)
&
(
HID_OUTPUT_FIFO_SIZE
-
1
))
==
hid
->
outtail
)
{
spin_unlock_irqrestore
(
&
hid
->
outlock
,
flags
);
warn
(
"output queue full"
);
return
;
}
hid
->
out
[
hid
->
outhead
]
=
report
;
hid
->
outhead
=
head
;
if
(
hid
->
urbout
.
status
!=
-
EINPROGRESS
)
if
(
!
test_and_set_bit
(
HID_OUT_RUNNING
,
&
hid
->
iofl
)
)
hid_submit_out
(
hid
);
spin_unlock_irqrestore
(
&
hid
->
outlock
,
flags
);
return
;
}
spin_lock_irqsave
(
&
hid
->
ctrllock
,
flags
);
if
((
head
=
(
hid
->
ctrlhead
+
1
)
&
(
HID_CONTROL_FIFO_SIZE
-
1
))
==
hid
->
ctrltail
)
{
spin_unlock_irqrestore
(
&
hid
->
ctrllock
,
flags
);
warn
(
"control queue full"
);
return
;
}
hid
->
ctrl
[
hid
->
ctrlhead
].
report
=
report
;
hid
->
ctrl
[
hid
->
ctrlhead
].
dir
=
dir
;
hid
->
ctrlhead
=
head
;
if
(
!
test_and_set_bit
(
HID_CTRL_RUNNING
,
&
hid
->
iofl
))
hid_submit_ctrl
(
hid
);
spin_unlock_irqrestore
(
&
hid
->
ctrllock
,
flags
);
}
int
hid_wait_io
(
struct
hid_device
*
hid
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
int
timeout
=
10
*
HZ
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
add_wait_queue
(
&
hid
->
wait
,
&
wait
);
while
(
timeout
&&
test_bit
(
HID_CTRL_RUNNING
,
&
hid
->
iofl
)
&&
test_bit
(
HID_OUT_RUNNING
,
&
hid
->
iofl
))
timeout
=
schedule_timeout
(
timeout
);
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
hid
->
wait
,
&
wait
);
if
(
!
timeout
)
{
dbg
(
"timeout waiting for ctrl or out queue to clear"
);
return
-
1
;
}
return
0
;
}
static
int
hid_get_class_descriptor
(
struct
usb_device
*
dev
,
int
ifnum
,
unsigned
char
type
,
void
*
buf
,
int
size
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
USB_REQ_GET_DESCRIPTOR
,
USB_RECIP_INTERFACE
|
USB_DIR_IN
,
(
type
<<
8
),
ifnum
,
buf
,
size
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
int
hid_open
(
struct
hid_device
*
hid
)
...
...
@@ -1035,9 +1168,9 @@ int hid_open(struct hid_device *hid)
if
(
hid
->
open
++
)
return
0
;
hid
->
urb
.
dev
=
hid
->
dev
;
hid
->
urb
in
->
dev
=
hid
->
dev
;
if
(
usb_submit_urb
(
&
hid
->
urb
,
GFP_KERNEL
))
if
(
usb_submit_urb
(
hid
->
urbin
,
GFP_KERNEL
))
return
-
EIO
;
return
0
;
...
...
@@ -1046,30 +1179,52 @@ int hid_open(struct hid_device *hid)
void
hid_close
(
struct
hid_device
*
hid
)
{
if
(
!--
hid
->
open
)
usb_unlink_urb
(
&
hid
->
urb
);
usb_unlink_urb
(
hid
->
urbin
);
}
/*
* Initialize all re
adable re
ports
* Initialize all reports
*/
void
hid_init_reports
(
struct
hid_device
*
hid
)
{
int
i
;
struct
hid_report
*
report
;
struct
hid_report_enum
*
report_enum
;
struct
hid_report
*
report
;
struct
list_head
*
list
;
int
len
;
for
(
i
=
0
;
i
<
HID_REPORT_TYPES
;
i
++
)
{
if
(
i
==
HID_FEATURE_REPORT
||
i
==
HID_INPUT_REPORT
)
{
report_enum
=
hid
->
report_enum
+
i
;
report_enum
=
hid
->
report_enum
+
HID_INPUT_REPORT
;
list
=
report_enum
->
report_list
.
next
;
while
(
list
!=
&
report_enum
->
report_list
)
{
report
=
(
struct
hid_report
*
)
list
;
hid_submit_report
(
hid
,
report
,
USB_DIR_IN
);
list
=
list
->
next
;
}
report_enum
=
hid
->
report_enum
+
HID_FEATURE_REPORT
;
list
=
report_enum
->
report_list
.
next
;
while
(
list
!=
&
report_enum
->
report_list
)
{
report
=
(
struct
hid_report
*
)
list
;
hid_set_idle
(
hid
->
dev
,
hid
->
ifnum
,
0
,
report
->
id
);
hid_read_report
(
hid
,
report
);
hid_submit_report
(
hid
,
report
,
USB_DIR_IN
);
list
=
list
->
next
;
}
if
(
hid_wait_io
(
hid
))
{
warn
(
"timeout initializing reports
\n
"
);
return
;
}
report_enum
=
hid
->
report_enum
+
HID_INPUT_REPORT
;
list
=
report_enum
->
report_list
.
next
;
while
(
list
!=
&
report_enum
->
report_list
)
{
report
=
(
struct
hid_report
*
)
list
;
len
=
((
report
->
size
-
1
)
>>
3
)
+
1
+
report_enum
->
numbered
;
if
(
len
>
hid
->
urbin
->
transfer_buffer_length
)
hid
->
urbin
->
transfer_buffer_length
=
len
<
HID_BUFFER_SIZE
?
len
:
HID_BUFFER_SIZE
;
usb_control_msg
(
hid
->
dev
,
usb_sndctrlpipe
(
hid
->
dev
,
0
),
0x0a
,
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
report
->
id
,
hid
->
ifnum
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
list
=
list
->
next
;
}
}
...
...
@@ -1077,6 +1232,10 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
#define USB_DEVICE_ID_WACOM_INTUOS 0x0020
#define USB_VENDOR_ID_GRIFFIN 0x077d
#define USB_DEVICE_ID_POWERMATE 0x0410
#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
struct
hid_blacklist
{
__u16
idVendor
;
__u16
idProduct
;
...
...
@@ -1087,19 +1246,11 @@ struct hid_blacklist {
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
2
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
3
},
{
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS
+
4
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_POWERMATE
},
{
USB_VENDOR_ID_GRIFFIN
,
USB_DEVICE_ID_SOUNDKNOB
},
{
0
,
0
}
};
static
int
get_class_descriptor
(
struct
usb_device
*
dev
,
int
ifnum
,
unsigned
char
type
,
void
*
buf
,
int
size
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
USB_REQ_GET_DESCRIPTOR
,
USB_RECIP_INTERFACE
|
USB_DIR_IN
,
(
type
<<
8
),
ifnum
,
buf
,
size
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
static
struct
hid_device
*
usb_hid_configure
(
struct
usb_device
*
dev
,
int
ifnum
)
{
struct
usb_interface_descriptor
*
interface
=
dev
->
actconfig
->
interface
[
ifnum
].
altsetting
+
0
;
...
...
@@ -1131,7 +1282,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
{
__u8
rdesc
[
rsize
];
if
((
n
=
get_class_descriptor
(
dev
,
interface
->
bInterfaceNumber
,
HID_DT_REPORT
,
rdesc
,
rsize
))
<
0
)
{
if
((
n
=
hid_
get_class_descriptor
(
dev
,
interface
->
bInterfaceNumber
,
HID_DT_REPORT
,
rdesc
,
rsize
))
<
0
)
{
dbg
(
"reading report descriptor failed"
);
return
NULL
;
}
...
...
@@ -1152,73 +1303,83 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
for
(
n
=
0
;
n
<
interface
->
bNumEndpoints
;
n
++
)
{
struct
usb_endpoint_descriptor
*
endpoint
=
&
interface
->
endpoint
[
n
];
int
pipe
,
maxp
;
int
pipe
;
if
((
endpoint
->
bmAttributes
&
3
)
!=
3
)
/* Not an interrupt endpoint */
continue
;
if
(
!
(
endpoint
->
bEndpointAddress
&
0x80
))
/* Not an input endpoint */
if
(
endpoint
->
bEndpointAddress
&
USB_DIR_IN
)
{
if
(
hid
->
urbin
)
continue
;
if
(
!
(
hid
->
urbin
=
usb_alloc_urb
(
0
)))
goto
fail
;
pipe
=
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
);
maxp
=
usb_maxpacket
(
dev
,
pipe
,
usb_pipeout
(
pipe
));
FILL_INT_URB
(
&
hid
->
urb
,
dev
,
pipe
,
hid
->
buffer
,
maxp
>
32
?
32
:
maxp
,
hid_irq
,
hid
,
endpoint
->
bInterval
);
break
;
FILL_INT_URB
(
hid
->
urbin
,
dev
,
pipe
,
hid
->
inbuf
,
0
,
hid_irq_in
,
hid
,
endpoint
->
bInterval
);
}
else
{
if
(
hid
->
urbout
)
continue
;
if
(
!
(
hid
->
urbout
=
usb_alloc_urb
(
0
)))
goto
fail
;
pipe
=
usb_sndbulkpipe
(
dev
,
endpoint
->
bEndpointAddress
);
FILL_BULK_URB
(
hid
->
urbout
,
dev
,
pipe
,
hid
->
outbuf
,
0
,
hid_irq_out
,
hid
);
}
}
if
(
n
==
interface
->
bNumEndpoints
)
{
dbg
(
"couldn't find an input interrupt endpoint"
);
hid_free_device
(
hid
);
return
NULL
;
if
(
!
hid
->
urbin
)
{
err
(
"couldn't find an input interrupt endpoint"
);
goto
fail
;
}
init_waitqueue_head
(
&
hid
->
wait
);
hid
->
outlock
=
SPIN_LOCK_UNLOCKED
;
hid
->
ctrllock
=
SPIN_LOCK_UNLOCKED
;
hid
->
version
=
hdesc
->
bcdHID
;
hid
->
country
=
hdesc
->
bCountryCode
;
hid
->
dev
=
dev
;
hid
->
ifnum
=
interface
->
bInterfaceNumber
;
for
(
n
=
0
;
n
<
HID_CONTROL_FIFO_SIZE
;
n
++
)
{
hid
->
out
[
n
].
dr
.
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
hid
->
out
[
n
].
dr
.
bRequest
=
HID_REQ_SET_REPORT
;
hid
->
out
[
n
].
dr
.
wIndex
=
cpu_to_le16
(
hid
->
ifnum
);
}
hid
->
name
[
0
]
=
0
;
if
(
!
(
buf
=
kmalloc
(
6
3
,
GFP_KERNEL
)))
return
NULL
;
if
(
!
(
buf
=
kmalloc
(
6
4
,
GFP_KERNEL
)))
goto
fail
;
if
(
usb_string
(
dev
,
dev
->
descriptor
.
iManufacturer
,
buf
,
6
3
)
>
0
)
{
if
(
usb_string
(
dev
,
dev
->
descriptor
.
iManufacturer
,
buf
,
6
4
)
>
0
)
{
strcat
(
hid
->
name
,
buf
);
if
(
usb_string
(
dev
,
dev
->
descriptor
.
iProduct
,
buf
,
6
3
)
>
0
)
if
(
usb_string
(
dev
,
dev
->
descriptor
.
iProduct
,
buf
,
6
4
)
>
0
)
sprintf
(
hid
->
name
,
"%s %s"
,
hid
->
name
,
buf
);
}
else
sprintf
(
hid
->
name
,
"%04x:%04x"
,
dev
->
descriptor
.
idVendor
,
dev
->
descriptor
.
idProduct
);
kfree
(
buf
);
usb_make_path
(
dev
,
buf
,
63
);
sprintf
(
hid
->
phys
,
"%s/input%d"
,
buf
,
ifnum
);
FILL_CONTROL_URB
(
&
hid
->
urbout
,
dev
,
usb_sndctrlpipe
(
dev
,
0
),
(
void
*
)
&
hid
->
out
[
0
].
dr
,
hid
->
out
[
0
].
buffer
,
1
,
hid_ctrl
,
hid
)
;
if
(
usb_string
(
dev
,
dev
->
descriptor
.
iSerialNumber
,
hid
->
uniq
,
64
)
<=
0
)
hid
->
uniq
[
0
]
=
0
;
/*
* Some devices don't like this and crash. I don't know of any devices
* needing this, so it is disabled for now.
*/
kfree
(
buf
);
#if 0
if (interface->bInterfaceSubClass == 1)
hid_set_protocol(dev, hid->ifnum, 1);
#endif
hid
->
urbctrl
=
usb_alloc_urb
(
0
);
FILL_CONTROL_URB
(
hid
->
urbctrl
,
dev
,
0
,
(
void
*
)
&
hid
->
cr
,
hid
->
ctrlbuf
,
1
,
hid_ctrl
,
hid
);
return
hid
;
fail:
hid_free_device
(
hid
);
if
(
hid
->
urbin
)
usb_free_urb
(
hid
->
urbin
);
if
(
hid
->
urbout
)
usb_free_urb
(
hid
->
urbout
);
if
(
hid
->
urbctrl
)
usb_free_urb
(
hid
->
urbctrl
);
return
NULL
;
}
static
void
*
hid_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
,
const
struct
usb_device_id
*
id
)
{
struct
hid_device
*
hid
;
char
path
[
64
];
int
i
;
char
*
c
;
...
...
@@ -1236,10 +1397,16 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
if
(
!
hiddev_connect
(
hid
))
hid
->
claimed
|=
HID_CLAIMED_HIDDEV
;
#endif
if
(
!
hid
->
claimed
)
{
hid_free_device
(
hid
);
return
NULL
;
}
printk
(
KERN_INFO
);
if
(
hid
->
claimed
&
HID_CLAIMED_INPUT
)
printk
(
"input
%d"
,
hid
->
input
.
number
);
printk
(
"input
"
);
if
(
hid
->
claimed
==
(
HID_CLAIMED_INPUT
|
HID_CLAIMED_HIDDEV
))
printk
(
","
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
...
...
@@ -1252,9 +1419,10 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum,
break
;
}
printk
(
": USB HID v%x.%02x %s [%s] on usb%d:%d.%d
\n
"
,
hid
->
version
>>
8
,
hid
->
version
&
0xff
,
c
,
hid
->
name
,
dev
->
bus
->
busnum
,
dev
->
devnum
,
ifnum
);
usb_make_path
(
dev
,
path
,
63
);
printk
(
": USB HID v%x.%02x %s [%s] on %s
\n
"
,
hid
->
version
>>
8
,
hid
->
version
&
0xff
,
c
,
hid
->
name
,
path
);
return
hid
;
}
...
...
@@ -1264,7 +1432,14 @@ static void hid_disconnect(struct usb_device *dev, void *ptr)
struct
hid_device
*
hid
=
ptr
;
dbg
(
"cleanup called"
);
usb_unlink_urb
(
&
hid
->
urb
);
usb_unlink_urb
(
hid
->
urbin
);
usb_unlink_urb
(
hid
->
urbout
);
usb_unlink_urb
(
hid
->
urbctrl
);
usb_free_urb
(
hid
->
urbin
);
usb_free_urb
(
hid
->
urbctrl
);
if
(
hid
->
urbout
)
usb_free_urb
(
hid
->
urbout
);
if
(
hid
->
claimed
&
HID_CLAIMED_INPUT
)
hidinput_disconnect
(
hid
);
...
...
@@ -1276,8 +1451,7 @@ static void hid_disconnect(struct usb_device *dev, void *ptr)
}
static
struct
usb_device_id
hid_usb_ids
[]
=
{
{
match_flags
:
USB_DEVICE_ID_MATCH_INT_CLASS
,
bInterfaceClass:
USB_INTERFACE_CLASS_HID
},
{
bInterfaceClass
:
USB_INTERFACE_CLASS_HID
},
{
}
/* Terminating entry */
};
...
...
@@ -1296,8 +1470,7 @@ static int __init hid_init(void)
hiddev_init
();
#endif
usb_register
(
&
hid_driver
);
info
(
DRIVER_VERSION
" "
DRIVER_AUTHOR
);
info
(
DRIVER_DESC
);
info
(
DRIVER_VERSION
":"
DRIVER_DESC
);
return
0
;
}
...
...
@@ -1313,6 +1486,6 @@ static void __exit hid_exit(void)
module_init
(
hid_init
);
module_exit
(
hid_exit
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
DRIVER_LICENSE
);
drivers/usb/hid-debug.h
View file @
57d52f67
/*
* $Id: hid-debug.h,v 1.
3 2001/05/10 15:56:0
7 vojtech Exp $
* $Id: hid-debug.h,v 1.
8 2001/09/25 09:37:5
7 vojtech Exp $
*
* (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
* (c) 2000-2001 Vojtech Pavlik <vojtech@
suse
.cz>
* (c) 2000-2001 Vojtech Pavlik <vojtech@
ucw
.cz>
*
* Some debug stuff for the HID parser.
*
* Sponsored by SuSE
*/
/*
...
...
@@ -25,8 +23,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
struct
hid_usage_entry
{
...
...
@@ -36,6 +34,7 @@ struct hid_usage_entry {
};
static
struct
hid_usage_entry
hid_usage_table
[]
=
{
{
0
,
0
,
"Undefined"
},
{
1
,
0
,
"GenericDesktop"
},
{
0
,
0x01
,
"Pointer"
},
{
0
,
0x02
,
"Mouse"
},
...
...
@@ -87,6 +86,7 @@ static struct hid_usage_entry hid_usage_table[] = {
{
7
,
0
,
"Keyboard"
},
{
8
,
0
,
"LED"
},
{
9
,
0
,
"Button"
},
{
10
,
0
,
"Ordinal"
},
{
12
,
0
,
"Hotkey"
},
{
13
,
0
,
"Digitizers"
},
{
0
,
0x01
,
"Digitizer"
},
...
...
@@ -112,6 +112,112 @@ static struct hid_usage_entry hid_usage_table[] = {
{
0
,
0x45
,
"Eraser"
},
{
0
,
0x46
,
"TabletPick"
},
{
15
,
0
,
"PhysicalInterfaceDevice"
},
{
0
,
0x00
,
"Undefined"
},
{
0
,
0x01
,
"Physical_Interface_Device"
},
{
0
,
0x20
,
"Normal"
},
{
0
,
0x21
,
"Set_Effect_Report"
},
{
0
,
0x22
,
"Effect_Block_Index"
},
{
0
,
0x23
,
"Parameter_Block_Offset"
},
{
0
,
0x24
,
"ROM_Flag"
},
{
0
,
0x25
,
"Effect_Type"
},
{
0
,
0x26
,
"ET_Constant_Force"
},
{
0
,
0x27
,
"ET_Ramp"
},
{
0
,
0x28
,
"ET_Custom_Force_Data"
},
{
0
,
0x30
,
"ET_Square"
},
{
0
,
0x31
,
"ET_Sine"
},
{
0
,
0x32
,
"ET_Triangle"
},
{
0
,
0x33
,
"ET_Sawtooth_Up"
},
{
0
,
0x34
,
"ET_Sawtooth_Down"
},
{
0
,
0x40
,
"ET_Spring"
},
{
0
,
0x41
,
"ET_Damper"
},
{
0
,
0x42
,
"ET_Inertia"
},
{
0
,
0x43
,
"ET_Friction"
},
{
0
,
0x50
,
"Duration"
},
{
0
,
0x51
,
"Sample_Period"
},
{
0
,
0x52
,
"Gain"
},
{
0
,
0x53
,
"Trigger_Button"
},
{
0
,
0x54
,
"Trigger_Repeat_Interval"
},
{
0
,
0x55
,
"Axes_Enable"
},
{
0
,
0x56
,
"Direction_Enable"
},
{
0
,
0x57
,
"Direction"
},
{
0
,
0x58
,
"Type_Specific_Block_Offset"
},
{
0
,
0x59
,
"Block_Type"
},
{
0
,
0x5A
,
"Set_Envelope_Report"
},
{
0
,
0x5B
,
"Attack_Level"
},
{
0
,
0x5C
,
"Attack_Time"
},
{
0
,
0x5D
,
"Fade_Level"
},
{
0
,
0x5E
,
"Fade_Time"
},
{
0
,
0x5F
,
"Set_Condition_Report"
},
{
0
,
0x60
,
"CP_Offset"
},
{
0
,
0x61
,
"Positive_Coefficient"
},
{
0
,
0x62
,
"Negative_Coefficient"
},
{
0
,
0x63
,
"Positive_Saturation"
},
{
0
,
0x64
,
"Negative_Saturation"
},
{
0
,
0x65
,
"Dead_Band"
},
{
0
,
0x66
,
"Download_Force_Sample"
},
{
0
,
0x67
,
"Isoch_Custom_Force_Enable"
},
{
0
,
0x68
,
"Custom_Force_Data_Report"
},
{
0
,
0x69
,
"Custom_Force_Data"
},
{
0
,
0x6A
,
"Custom_Force_Vendor_Defined_Data"
},
{
0
,
0x6B
,
"Set_Custom_Force_Report"
},
{
0
,
0x6C
,
"Custom_Force_Data_Offset"
},
{
0
,
0x6D
,
"Sample_Count"
},
{
0
,
0x6E
,
"Set_Periodic_Report"
},
{
0
,
0x6F
,
"Offset"
},
{
0
,
0x70
,
"Magnitude"
},
{
0
,
0x71
,
"Phase"
},
{
0
,
0x72
,
"Period"
},
{
0
,
0x73
,
"Set_Constant_Force_Report"
},
{
0
,
0x74
,
"Set_Ramp_Force_Report"
},
{
0
,
0x75
,
"Ramp_Start"
},
{
0
,
0x76
,
"Ramp_End"
},
{
0
,
0x77
,
"Effect_Operation_Report"
},
{
0
,
0x78
,
"Effect_Operation"
},
{
0
,
0x79
,
"Op_Effect_Start"
},
{
0
,
0x7A
,
"Op_Effect_Start_Solo"
},
{
0
,
0x7B
,
"Op_Effect_Stop"
},
{
0
,
0x7C
,
"Loop_Count"
},
{
0
,
0x7D
,
"Device_Gain_Report"
},
{
0
,
0x7E
,
"Device_Gain"
},
{
0
,
0x7F
,
"PID_Pool_Report"
},
{
0
,
0x80
,
"RAM_Pool_Size"
},
{
0
,
0x81
,
"ROM_Pool_Size"
},
{
0
,
0x82
,
"ROM_Effect_Block_Count"
},
{
0
,
0x83
,
"Simultaneous_Effects_Max"
},
{
0
,
0x84
,
"Pool_Alignment"
},
{
0
,
0x85
,
"PID_Pool_Move_Report"
},
{
0
,
0x86
,
"Move_Source"
},
{
0
,
0x87
,
"Move_Destination"
},
{
0
,
0x88
,
"Move_Length"
},
{
0
,
0x89
,
"PID_Block_Load_Report"
},
{
0
,
0x8B
,
"Block_Load_Status"
},
{
0
,
0x8C
,
"Block_Load_Success"
},
{
0
,
0x8D
,
"Block_Load_Full"
},
{
0
,
0x8E
,
"Block_Load_Error"
},
{
0
,
0x8F
,
"Block_Handle"
},
{
0
,
0x90
,
"PID_Block_Free_Report"
},
{
0
,
0x91
,
"Type_Specific_Block_Handle"
},
{
0
,
0x92
,
"PID_State_Report"
},
{
0
,
0x94
,
"Effect_Playing"
},
{
0
,
0x95
,
"PID_Device_Control_Report"
},
{
0
,
0x96
,
"PID_Device_Control"
},
{
0
,
0x97
,
"DC_Enable_Actuators"
},
{
0
,
0x98
,
"DC_Disable_Actuators"
},
{
0
,
0x99
,
"DC_Stop_All_Effects"
},
{
0
,
0x9A
,
"DC_Device_Reset"
},
{
0
,
0x9B
,
"DC_Device_Pause"
},
{
0
,
0x9C
,
"DC_Device_Continue"
},
{
0
,
0x9F
,
"Device_Paused"
},
{
0
,
0xA0
,
"Actuators_Enabled"
},
{
0
,
0xA4
,
"Safety_Switch"
},
{
0
,
0xA5
,
"Actuator_Override_Switch"
},
{
0
,
0xA6
,
"Actuator_Power"
},
{
0
,
0xA7
,
"Start_Delay"
},
{
0
,
0xA8
,
"Parameter_Block_Size"
},
{
0
,
0xA9
,
"Device_Managed_Pool"
},
{
0
,
0xAA
,
"Shared_Parameter_Blocks"
},
{
0
,
0xAB
,
"Create_New_Effect_Report"
},
{
0
,
0xAC
,
"RAM_Pool_Available"
},
{
0
,
0
,
NULL
}
};
...
...
@@ -176,7 +282,50 @@ static void hid_dump_field(struct hid_field *field, int n) {
tab
(
n
);
printk
(
"Unit Exponent(%d)
\n
"
,
field
->
unit_exponent
);
}
if
(
field
->
unit
)
{
tab
(
n
);
printk
(
"Unit(%u)
\n
"
,
field
->
unit
);
char
*
systems
[
5
]
=
{
"None"
,
"SI Linear"
,
"SI Rotation"
,
"English Linear"
,
"English Rotation"
};
char
*
units
[
5
][
8
]
=
{
{
"None"
,
"None"
,
"None"
,
"None"
,
"None"
,
"None"
,
"None"
,
"None"
},
{
"None"
,
"Centimeter"
,
"Gram"
,
"Seconds"
,
"Kelvin"
,
"Ampere"
,
"Candela"
,
"None"
},
{
"None"
,
"Radians"
,
"Gram"
,
"Seconds"
,
"Kelvin"
,
"Ampere"
,
"Candela"
,
"None"
},
{
"None"
,
"Inch"
,
"Slug"
,
"Seconds"
,
"Fahrenheit"
,
"Ampere"
,
"Candela"
,
"None"
},
{
"None"
,
"Degrees"
,
"Slug"
,
"Seconds"
,
"Fahrenheit"
,
"Ampere"
,
"Candela"
,
"None"
}
};
int
i
;
int
sys
;
__u32
data
=
field
->
unit
;
/* First nibble tells us which system we're in. */
sys
=
data
&
0xf
;
data
>>=
4
;
if
(
sys
>
4
)
{
tab
(
n
);
printk
(
"Unit(Invalid)
\n
"
);
}
else
{
int
earlier_unit
=
0
;
tab
(
n
);
printk
(
"Unit(%s : "
,
systems
[
sys
]);
for
(
i
=
1
;
i
<
sizeof
(
__u32
)
*
2
;
i
++
)
{
char
nibble
=
data
&
0xf
;
data
>>=
4
;
if
(
nibble
!=
0
)
{
if
(
earlier_unit
++
>
0
)
printk
(
"*"
);
printk
(
"%s"
,
units
[
sys
][
i
]);
if
(
nibble
!=
1
)
{
/* This is a _signed_ nibble(!) */
int
val
=
nibble
&
0x7
;
if
(
nibble
&
0x08
)
val
=
-
((
0x7
&
~
val
)
+
1
);
printk
(
"^%d"
,
val
);
}
}
}
printk
(
")
\n
"
);
}
}
tab
(
n
);
printk
(
"Report Size(%u)
\n
"
,
field
->
report_size
);
tab
(
n
);
printk
(
"Report Count(%u)
\n
"
,
field
->
report_count
);
...
...
drivers/usb/hid-input.c
View file @
57d52f67
/*
* $Id: hid-input.c,v 1.
5 2001/05/23 09:25:02
vojtech Exp $
* $Id: hid-input.c,v 1.
18 2001/11/07 09:01:18
vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* USB HID to Linux Input mapping module
*
* Sponsored by SuSE
* USB HID to Linux Input mapping
*/
/*
...
...
@@ -24,13 +22,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/usb.h>
...
...
@@ -61,12 +58,13 @@ static unsigned char hid_keyboard[256] = {
static
struct
{
__s32
x
;
__s32
y
;
}
hid_hat_to_axis
[]
=
{{
0
,
0
},
{
0
,
-
1
},
{
1
,
-
1
},
{
1
,
0
},
{
1
,
1
},
{
0
,
1
},
{
-
1
,
1
},
{
-
1
,
0
},
{
-
1
,
-
1
}};
}
hid_hat_to_axis
[]
=
{{
0
,
0
},
{
0
,
-
1
},
{
1
,
-
1
},
{
1
,
0
},
{
1
,
1
},
{
0
,
1
},
{
-
1
,
1
},
{
-
1
,
0
},
{
-
1
,
-
1
}};
static
void
hidinput_configure_usage
(
struct
hid_device
*
device
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
)
{
struct
input_dev
*
input
=
&
device
->
input
;
int
max
;
int
is_abs
=
0
;
unsigned
long
*
bit
;
switch
(
usage
->
hid
&
HID_USAGE_PAGE
)
{
...
...
@@ -198,6 +196,7 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case
HID_UP_CONSUMER
:
/* USB HUT v1.1, pages 56-62 */
set_bit
(
EV_REP
,
input
->
evbit
);
switch
(
usage
->
hid
&
HID_USAGE
)
{
case
0x000
:
usage
->
code
=
0
;
break
;
case
0x034
:
usage
->
code
=
KEY_SLEEP
;
break
;
...
...
@@ -205,14 +204,21 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case
0x08a
:
usage
->
code
=
KEY_WWW
;
break
;
case
0x095
:
usage
->
code
=
KEY_HELP
;
break
;
case
0x0b0
:
usage
->
code
=
KEY_PLAY
;
break
;
case
0x0b1
:
usage
->
code
=
KEY_PAUSE
;
break
;
case
0x0b2
:
usage
->
code
=
KEY_RECORD
;
break
;
case
0x0b3
:
usage
->
code
=
KEY_FASTFORWARD
;
break
;
case
0x0b4
:
usage
->
code
=
KEY_REWIND
;
break
;
case
0x0b5
:
usage
->
code
=
KEY_NEXTSONG
;
break
;
case
0x0b6
:
usage
->
code
=
KEY_PREVIOUSSONG
;
break
;
case
0x0b7
:
usage
->
code
=
KEY_STOPCD
;
break
;
case
0x0b8
:
usage
->
code
=
KEY_EJECTCD
;
break
;
case
0x0cd
:
usage
->
code
=
KEY_PLAYPAUSE
;
break
;
case
0x0e0
:
is_abs
=
1
;
usage
->
code
=
ABS_VOLUME
;
break
;
case
0x0e2
:
usage
->
code
=
KEY_MUTE
;
break
;
case
0x0e5
:
usage
->
code
=
KEY_BASSBOOST
;
break
;
case
0x0e9
:
usage
->
code
=
KEY_VOLUMEUP
;
break
;
case
0x0ea
:
usage
->
code
=
KEY_VOLUMEDOWN
;
break
;
...
...
@@ -220,7 +226,6 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case
0x18a
:
usage
->
code
=
KEY_MAIL
;
break
;
case
0x192
:
usage
->
code
=
KEY_CALC
;
break
;
case
0x194
:
usage
->
code
=
KEY_FILE
;
break
;
case
0x21a
:
usage
->
code
=
KEY_UNDO
;
break
;
case
0x21b
:
usage
->
code
=
KEY_COPY
;
break
;
case
0x21c
:
usage
->
code
=
KEY_CUT
;
break
;
...
...
@@ -234,6 +239,34 @@ static void hidinput_configure_usage(struct hid_device *device, struct hid_field
case
0x227
:
usage
->
code
=
KEY_REFRESH
;
break
;
case
0x22a
:
usage
->
code
=
KEY_BOOKMARKS
;
break
;
default:
usage
->
code
=
KEY_UNKNOWN
;
break
;
}
if
(
is_abs
)
{
usage
->
type
=
EV_ABS
;
bit
=
input
->
absbit
;
max
=
ABS_MAX
;
}
else
{
usage
->
type
=
EV_KEY
;
bit
=
input
->
keybit
;
max
=
KEY_MAX
;
}
break
;
case
HID_UP_HPVENDOR
:
/* Reported on a Dutch layout HP5308 */
set_bit
(
EV_REP
,
input
->
evbit
);
switch
(
usage
->
hid
&
HID_USAGE
)
{
case
0x021
:
usage
->
code
=
KEY_PRINT
;
break
;
case
0x070
:
usage
->
code
=
KEY_HP
;
break
;
case
0x071
:
usage
->
code
=
KEY_CAMERA
;
break
;
case
0x072
:
usage
->
code
=
KEY_SOUND
;
break
;
case
0x073
:
usage
->
code
=
KEY_QUESTION
;
break
;
case
0x080
:
usage
->
code
=
KEY_EMAIL
;
break
;
case
0x081
:
usage
->
code
=
KEY_CHAT
;
break
;
case
0x082
:
usage
->
code
=
KEY_SEARCH
;
break
;
case
0x083
:
usage
->
code
=
KEY_CONNECT
;
break
;
case
0x084
:
usage
->
code
=
KEY_FINANCE
;
break
;
case
0x085
:
usage
->
code
=
KEY_SPORT
;
break
;
case
0x086
:
usage
->
code
=
KEY_SHOP
;
break
;
default:
usage
->
code
=
KEY_UNKNOWN
;
break
;
}
...
...
@@ -353,7 +386,7 @@ static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsign
}
hid_set_field
(
field
,
offset
,
value
);
hid_
write_report
(
hid
,
field
->
report
);
hid_
submit_report
(
hid
,
field
->
report
,
USB_DIR_OUT
);
return
0
;
}
...
...
@@ -397,6 +430,8 @@ int hidinput_connect(struct hid_device *hid)
hid
->
input
.
close
=
hidinput_close
;
hid
->
input
.
name
=
hid
->
name
;
hid
->
input
.
phys
=
hid
->
phys
;
hid
->
input
.
uniq
=
hid
->
uniq
;
hid
->
input
.
idbus
=
BUS_USB
;
hid
->
input
.
idvendor
=
dev
->
descriptor
.
idVendor
;
hid
->
input
.
idproduct
=
dev
->
descriptor
.
idProduct
;
...
...
drivers/usb/hid.h
View file @
57d52f67
...
...
@@ -2,12 +2,10 @@
#define __HID_H
/*
* $Id: hid.h,v 1.
10 2001/05/10 15:56:07
vojtech Exp $
* $Id: hid.h,v 1.
24 2001/12/27 10:37:41
vojtech Exp $
*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
...
...
@@ -26,13 +24,24 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
/*
* USB HID (Human Interface Device) interface class code
*/
#define USB_INTERFACE_CLASS_HID 3
/*
* HID class requests
*/
#define HID_REQ_GET_REPORT 0x01
#define HID_REQ_GET_IDLE 0x02
#define HID_REQ_GET_PROTOCOL 0x03
...
...
@@ -43,85 +52,11 @@
/*
* HID class descriptor types
*/
#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
/*
* Utilities for class control messaging
*/
static
inline
int
hid_set_idle
(
struct
usb_device
*
dev
,
int
ifnum
,
int
duration
,
int
report_id
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_IDLE
,
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
(
duration
<<
8
)
|
report_id
,
ifnum
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
}
static
inline
int
hid_get_protocol
(
struct
usb_device
*
dev
,
int
ifnum
)
{
unsigned
char
type
;
int
ret
;
if
((
ret
=
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
HID_REQ_GET_PROTOCOL
,
USB_DIR_IN
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
0
,
ifnum
,
&
type
,
1
,
HZ
*
USB_CTRL_GET_TIMEOUT
))
<
0
)
return
ret
;
return
type
;
}
static
inline
int
hid_set_protocol
(
struct
usb_device
*
dev
,
int
ifnum
,
int
protocol
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_PROTOCOL
,
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
protocol
,
ifnum
,
NULL
,
0
,
HZ
*
USB_CTRL_SET_TIMEOUT
);
}
static
inline
int
hid_get_report
(
struct
usb_device
*
dev
,
int
ifnum
,
unsigned
char
type
,
unsigned
char
id
,
void
*
buf
,
int
size
)
{
return
usb_control_msg
(
dev
,
usb_rcvctrlpipe
(
dev
,
0
),
HID_REQ_GET_REPORT
,
USB_DIR_IN
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
(
type
<<
8
)
+
id
,
ifnum
,
buf
,
size
,
HZ
*
USB_CTRL_GET_TIMEOUT
);
}
static
inline
int
hid_set_report
(
struct
usb_device
*
dev
,
int
ifnum
,
unsigned
char
type
,
unsigned
char
id
,
void
*
buf
,
int
size
)
{
return
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_REPORT
,
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
(
type
<<
8
)
+
id
,
ifnum
,
buf
,
size
,
HZ
);
// FIXME USB_CTRL_SET_TIMEOUT
}
/*
* "Boot Protocol" keyboard/mouse drivers use don't use all of HID;
* they're a lot smaller but can't support all the device features.
*/
#ifndef _HID_BOOT_PROTOCOL
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
/*
* USB HID (Human Interface Device) interface class code
*/
#define USB_INTERFACE_CLASS_HID 3
/*
* We parse each description item into this structure. Short items data
* values are expanded to 32-bit signed int, long items contain a pointer
...
...
@@ -240,9 +175,11 @@ struct hid_item {
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
#define HID_UP_ORDINAL 0x000a0000
#define HID_UP_CONSUMER 0x000c0000
#define HID_UP_DIGITIZER 0x000d0000
#define HID_UP_PID 0x000f0000
#define HID_UP_HPVENDOR 0xff7f0000
#define HID_USAGE 0x0000ffff
...
...
@@ -279,7 +216,7 @@ struct hid_global {
__s32
logical_maximum
;
__s32
physical_minimum
;
__s32
physical_maximum
;
unsigned
unit_exponent
;
__s32
unit_exponent
;
unsigned
unit
;
unsigned
report_id
;
unsigned
report_size
;
...
...
@@ -336,7 +273,7 @@ struct hid_field {
__s32
logical_maximum
;
__s32
physical_minimum
;
__s32
physical_maximum
;
unsigned
unit_exponent
;
__s32
unit_exponent
;
unsigned
unit
;
struct
hid_report
*
report
;
/* associated report */
};
...
...
@@ -350,8 +287,6 @@ struct hid_report {
struct
hid_field
*
field
[
HID_MAX_FIELDS
];
/* fields of the report */
unsigned
maxfield
;
/* maximum valid field index */
unsigned
size
;
/* size of the report (bits) */
unsigned
idx
;
/* where we're in data */
unsigned
char
*
data
;
/* data for multi-packet reports */
struct
hid_device
*
device
;
/* associated device */
};
...
...
@@ -364,16 +299,20 @@ struct hid_report_enum {
#define HID_REPORT_TYPES 3
#define HID_BUFFER_SIZE 32
#define HID_CONTROL_FIFO_SIZE 8
#define HID_CONTROL_FIFO_SIZE 64
#define HID_OUTPUT_FIFO_SIZE 64
struct
hid_control_fifo
{
struct
usb_ctrlrequest
d
r
;
char
buffer
[
HID_BUFFER_SIZE
]
;
unsigned
char
di
r
;
struct
hid_report
*
report
;
};
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
#define HID_CTRL_RUNNING 1
#define HID_OUT_RUNNING 2
struct
hid_device
{
/* device report descriptor */
__u8
*
rdesc
;
unsigned
rsize
;
...
...
@@ -386,12 +325,23 @@ struct hid_device { /* device report descriptor */
struct
usb_device
*
dev
;
/* USB device */
int
ifnum
;
/* USB interface number */
struct
urb
urb
;
/* USB URB structure */
char
buffer
[
HID_BUFFER_SIZE
];
/* Rx buffer */
unsigned
long
iofl
;
/* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct
urb
*
urbin
;
/* Input URB */
char
inbuf
[
HID_BUFFER_SIZE
];
/* Input buffer */
struct
urb
urbout
;
/* Output URB */
struct
hid_control_fifo
out
[
HID_CONTROL_FIFO_SIZE
];
/* Transmit buffer */
unsigned
char
outhead
,
outtail
;
/* Tx buffer head & tail */
struct
urb
*
urbctrl
;
/* Control URB */
struct
usb_ctrlrequest
cr
;
/* Control request struct */
struct
hid_control_fifo
ctrl
[
HID_CONTROL_FIFO_SIZE
];
/* Control fifo */
unsigned
char
ctrlhead
,
ctrltail
;
/* Control fifo head & tail */
char
ctrlbuf
[
HID_BUFFER_SIZE
];
/* Control buffer */
spinlock_t
ctrllock
;
/* Control fifo spinlock */
struct
urb
*
urbout
;
/* Output URB */
struct
hid_report
*
out
[
HID_CONTROL_FIFO_SIZE
];
/* Output pipe fifo */
unsigned
char
outhead
,
outtail
;
/* Output pipe fifo head & tail */
char
outbuf
[
HID_BUFFER_SIZE
];
/* Output buffer */
spinlock_t
outlock
;
/* Output fifo spinlock */
unsigned
claimed
;
/* Claimed by hidinput, hiddev? */
unsigned
quirks
;
/* Various quirks the device can pull on us */
...
...
@@ -400,8 +350,12 @@ struct hid_device { /* device report descriptor */
void
*
hiddev
;
/* The hiddev structure */
int
minor
;
/* Hiddev minor number */
wait_queue_head_t
wait
;
/* For sleeping */
int
open
;
/* is the device open by anyone? */
char
name
[
128
];
/* Device name */
char
phys
[
64
];
/* Device physical location */
char
uniq
[
64
];
/* Device unique identifier (serial #) */
};
#define HID_GLOBAL_STACK_SIZE 4
...
...
@@ -441,19 +395,18 @@ void hidinput_disconnect(struct hid_device *);
#else
#define hid_dump_input(a,b) do { } while (0)
#define hid_dump_device(c) do { } while (0)
#endif
/* DEBUG */
#define hid_dump_field(a,b) do { } while (0)
#endif
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001))
#endif
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
int
hid_open
(
struct
hid_device
*
);
void
hid_close
(
struct
hid_device
*
);
int
hid_find_field
(
struct
hid_device
*
,
unsigned
int
,
unsigned
int
,
struct
hid_field
**
);
int
hid_set_field
(
struct
hid_field
*
,
unsigned
,
__s32
);
void
hid_write_report
(
struct
hid_device
*
,
struct
hid_report
*
);
void
hid_read_report
(
struct
hid_device
*
,
struct
hid_report
*
);
void
hid_submit_report
(
struct
hid_device
*
,
struct
hid_report
*
,
unsigned
char
dir
);
void
hid_init_reports
(
struct
hid_device
*
hid
);
#endif
/* !_HID_BOOT_PROTOCOL */
#endif
/* !__HID_H */
drivers/usb/hiddev.c
View file @
57d52f67
...
...
@@ -400,7 +400,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file,
if
((
report
=
hiddev_lookup_report
(
hid
,
&
rinfo
))
==
NULL
)
return
-
EINVAL
;
hid_
read_report
(
hid
,
report
);
hid_
submit_report
(
hid
,
report
,
USB_DIR_IN
);
return
0
;
...
...
@@ -414,7 +414,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file,
if
((
report
=
hiddev_lookup_report
(
hid
,
&
rinfo
))
==
NULL
)
return
-
EINVAL
;
hid_
write_report
(
hid
,
report
);
hid_
submit_report
(
hid
,
report
,
USB_DIR_OUT
);
return
0
;
...
...
drivers/usb/pegasus.h
View file @
57d52f67
...
...
@@ -134,9 +134,11 @@ struct usb_eth_dev {
#define VENDOR_ALLIEDTEL 0x07c9
#define VENDOR_BELKIN 0x050d
#define VENDOR_BILLIONTON 0x08dd
#define VENDOR_COMPAQ 0x049f
#define VENDOR_COREGA 0x07aa
#define VENDOR_DLINK 0x2001
#define VENDOR_ELSA 0x05cc
#define VENDOR_HAWKING 0x0e66
#define VENDOR_IODATA 0x04bb
#define VENDOR_KINGSTON 0x0951
#define VENDOR_LANEED 0x056e
...
...
@@ -190,6 +192,8 @@ PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"Billionton USBLP-100"
,
VENDOR_BILLIONTON
,
0x0987
,
DEFAULT_GPIO_RESET
|
HAS_HOME_PNA
)
PEGASUS_DEV
(
"iPAQ Networking 10/100 USB"
,
VENDOR_COMPAQ
,
0x8511
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"Billionton USBEL-100"
,
VENDOR_BILLIONTON
,
0x0988
,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"Billionton USBE-100"
,
VENDOR_BILLIONTON
,
0x8511
,
...
...
@@ -212,8 +216,12 @@ PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"Elsa Micolink USB2Ethernet"
,
VENDOR_ELSA
,
0x3000
,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"Hawking UF100 10/100 Ethernet"
,
VENDOR_HAWKING
,
0x400c
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"IO DATA USB ET/TX"
,
VENDOR_IODATA
,
0x0904
,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"IO DATA USB ET/TX-S"
,
VENDOR_IODATA
,
0x0913
,
DEFAULT_GPIO_RESET
|
PEGASUS_II
)
PEGASUS_DEV
(
"Kingston KNU101TX Ethernet"
,
VENDOR_KINGSTON
,
0x000a
,
DEFAULT_GPIO_RESET
)
PEGASUS_DEV
(
"LANEED USB Ethernet LD-USB/TX"
,
VENDOR_LANEED
,
0x4002
,
...
...
drivers/usb/usbkbd.c
View file @
57d52f67
/*
* $Id: usbkbd.c,v 1.2
0 2001/04/26 08:34:49
vojtech Exp $
* $Id: usbkbd.c,v 1.2
7 2001/12/27 10:37:41
vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* USB HIDBP Keyboard support
*
* Sponsored by SuSE
*/
/*
...
...
@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
...
...
@@ -35,19 +33,17 @@
#include <linux/init.h>
#include <linux/usb.h>
#define _HID_BOOT_PROTOCOL
#include "hid.h"
/*
* Version Information
*/
#define DRIVER_VERSION ""
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
suse
.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
ucw
.cz>"
#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
DRIVER_LICENSE
);
static
unsigned
char
usb_kbd_keycode
[
256
]
=
{
0
,
0
,
0
,
0
,
30
,
48
,
46
,
32
,
18
,
33
,
34
,
35
,
23
,
36
,
37
,
38
,
...
...
@@ -74,9 +70,10 @@ struct usb_kbd {
unsigned
char
new
[
8
];
unsigned
char
old
[
8
];
struct
urb
*
irq
,
*
led
;
struct
usb_ctrlrequest
d
r
;
struct
usb_ctrlrequest
c
r
;
unsigned
char
leds
,
newleds
;
char
name
[
128
];
char
phys
[
64
];
int
open
;
};
...
...
@@ -129,7 +126,7 @@ int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, i
kbd
->
leds
=
kbd
->
newleds
;
kbd
->
led
->
dev
=
kbd
->
usbdev
;
if
(
usb_submit_urb
(
kbd
->
led
,
GFP_
KERNEL
))
if
(
usb_submit_urb
(
kbd
->
led
,
GFP_
ATOMIC
))
err
(
"usb_submit_urb(leds) failed"
);
return
0
;
...
...
@@ -147,7 +144,7 @@ static void usb_kbd_led(struct urb *urb)
kbd
->
leds
=
kbd
->
newleds
;
kbd
->
led
->
dev
=
kbd
->
usbdev
;
if
(
usb_submit_urb
(
kbd
->
led
,
GFP_
KERNEL
))
if
(
usb_submit_urb
(
kbd
->
led
,
GFP_
ATOMIC
))
err
(
"usb_submit_urb(leds) failed"
);
}
...
...
@@ -181,6 +178,7 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
struct
usb_endpoint_descriptor
*
endpoint
;
struct
usb_kbd
*
kbd
;
int
i
,
pipe
,
maxp
;
char
path
[
64
];
char
*
buf
;
iface
=
&
dev
->
actconfig
->
interface
[
ifnum
];
...
...
@@ -195,9 +193,6 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
pipe
=
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
);
maxp
=
usb_maxpacket
(
dev
,
pipe
,
usb_pipeout
(
pipe
));
hid_set_protocol
(
dev
,
interface
->
bInterfaceNumber
,
0
);
hid_set_idle
(
dev
,
interface
->
bInterfaceNumber
,
0
,
0
);
if
(
!
(
kbd
=
kmalloc
(
sizeof
(
struct
usb_kbd
),
GFP_KERNEL
)))
return
NULL
;
memset
(
kbd
,
0
,
sizeof
(
struct
usb_kbd
));
...
...
@@ -230,13 +225,17 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
FILL_INT_URB
(
kbd
->
irq
,
dev
,
pipe
,
kbd
->
new
,
maxp
>
8
?
8
:
maxp
,
usb_kbd_irq
,
kbd
,
endpoint
->
bInterval
);
kbd
->
dr
.
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
kbd
->
dr
.
bRequest
=
HID_REQ_SET_REPORT
;
kbd
->
dr
.
wValue
=
0x200
;
kbd
->
dr
.
wIndex
=
interface
->
bInterfaceNumber
;
kbd
->
dr
.
wLength
=
1
;
kbd
->
cr
.
bRequestType
=
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
;
kbd
->
cr
.
bRequest
=
0x09
;
kbd
->
cr
.
wValue
=
0x200
;
kbd
->
cr
.
wIndex
=
interface
->
bInterfaceNumber
;
kbd
->
cr
.
wLength
=
1
;
usb_make_path
(
dev
,
path
,
64
);
sprintf
(
kbd
->
phys
,
"%s/input0"
,
path
);
kbd
->
dev
.
name
=
kbd
->
name
;
kbd
->
dev
.
phys
=
kbd
->
phys
;
kbd
->
dev
.
idbus
=
BUS_USB
;
kbd
->
dev
.
idvendor
=
dev
->
descriptor
.
idVendor
;
kbd
->
dev
.
idproduct
=
dev
->
descriptor
.
idProduct
;
...
...
@@ -261,12 +260,11 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
kfree
(
buf
);
FILL_CONTROL_URB
(
kbd
->
led
,
dev
,
usb_sndctrlpipe
(
dev
,
0
),
(
void
*
)
&
kbd
->
d
r
,
&
kbd
->
leds
,
1
,
usb_kbd_led
,
kbd
);
(
void
*
)
&
kbd
->
c
r
,
&
kbd
->
leds
,
1
,
usb_kbd_led
,
kbd
);
input_register_device
(
&
kbd
->
dev
);
printk
(
KERN_INFO
"input%d: %s on usb%d:%d.%d
\n
"
,
kbd
->
dev
.
number
,
kbd
->
name
,
dev
->
bus
->
busnum
,
dev
->
devnum
,
ifnum
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
kbd
->
name
,
path
);
return
kbd
;
}
...
...
drivers/usb/usbmouse.c
View file @
57d52f67
/*
* $Id: usbmouse.c,v 1.
6 2000/08/14 21:05:26
vojtech Exp $
* $Id: usbmouse.c,v 1.
15 2001/12/27 10:37:41
vojtech Exp $
*
* Copyright (c) 1999-200
0
Vojtech Pavlik
* Copyright (c) 1999-200
1
Vojtech Pavlik
*
* USB HIDBP Mouse support
*
* Sponsored by SuSE
*/
/*
...
...
@@ -24,8 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
...
...
@@ -35,23 +33,22 @@
#include <linux/init.h>
#include <linux/usb.h>
#define _HID_BOOT_PROTOCOL
#include "hid.h"
/*
* Version Information
*/
#define DRIVER_VERSION "v1.6"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
suse
.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
ucw
.cz>"
#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
DRIVER_LICENSE
);
struct
usb_mouse
{
signed
char
data
[
8
];
char
name
[
128
];
char
phys
[
64
];
struct
usb_device
*
usbdev
;
struct
input_dev
dev
;
struct
urb
*
irq
;
...
...
@@ -107,6 +104,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
struct
usb_endpoint_descriptor
*
endpoint
;
struct
usb_mouse
*
mouse
;
int
pipe
,
maxp
;
char
path
[
64
];
char
*
buf
;
iface
=
&
dev
->
actconfig
->
interface
[
ifnum
];
...
...
@@ -121,8 +119,6 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
pipe
=
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
);
maxp
=
usb_maxpacket
(
dev
,
pipe
,
usb_pipeout
(
pipe
));
hid_set_idle
(
dev
,
interface
->
bInterfaceNumber
,
0
,
0
);
if
(
!
(
mouse
=
kmalloc
(
sizeof
(
struct
usb_mouse
),
GFP_KERNEL
)))
return
NULL
;
memset
(
mouse
,
0
,
sizeof
(
struct
usb_mouse
));
...
...
@@ -144,7 +140,11 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
mouse
->
dev
.
open
=
usb_mouse_open
;
mouse
->
dev
.
close
=
usb_mouse_close
;
usb_make_path
(
dev
,
path
,
64
);
sprintf
(
mouse
->
phys
,
"%s/input0"
,
path
);
mouse
->
dev
.
name
=
mouse
->
name
;
mouse
->
dev
.
phys
=
mouse
->
phys
;
mouse
->
dev
.
idbus
=
BUS_USB
;
mouse
->
dev
.
idvendor
=
dev
->
descriptor
.
idVendor
;
mouse
->
dev
.
idproduct
=
dev
->
descriptor
.
idProduct
;
...
...
@@ -173,8 +173,7 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum,
input_register_device
(
&
mouse
->
dev
);
printk
(
KERN_INFO
"input%d: %s on usb%d:%d.%d
\n
"
,
mouse
->
dev
.
number
,
mouse
->
name
,
dev
->
bus
->
busnum
,
dev
->
devnum
,
ifnum
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
mouse
->
name
,
path
);
return
mouse
;
}
...
...
drivers/usb/wacom.c
View file @
57d52f67
/*
* $Id: wacom.c,v 1.2
2 2001/04/26 11:26:09
vojtech Exp $
* $Id: wacom.c,v 1.2
8 2001/09/25 10:12:07
vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@
suse
.cz>
* Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@
ucw
.cz>
* Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
* Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
* Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
...
...
@@ -11,8 +11,6 @@
*
* USB Wacom Graphire and Wacom Intuos tablet support
*
* Sponsored by SuSE
*
* ChangeLog:
* v0.1 (vp) - Initial release
* v0.2 (aba) - Support for all buttons / combinations
...
...
@@ -57,8 +55,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@
suse
.cz>, or by paper mail:
* Vojtech Pavlik,
Ucitelska 1576
, Prague 8, 182 00 Czech Republic
* e-mail - mail your message to <vojtech@
ucw
.cz>, or by paper mail:
* Vojtech Pavlik,
Simunkova 1594
, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
...
...
@@ -72,12 +70,13 @@
* Version Information
*/
#define DRIVER_VERSION "v1.21"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
suse
.cz>"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@
ucw
.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
DRIVER_LICENSE
);
#define USB_VENDOR_ID_WACOM 0x056a
...
...
@@ -106,6 +105,7 @@ struct wacom {
int
open
;
int
x
,
y
;
__u32
serial
[
2
];
char
phys
[
32
];
};
static
void
wacom_pl_irq
(
struct
urb
*
urb
)
...
...
@@ -354,6 +354,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
{
struct
usb_endpoint_descriptor
*
endpoint
;
struct
wacom
*
wacom
;
char
path
[
64
];
if
(
!
(
wacom
=
kmalloc
(
sizeof
(
struct
wacom
),
GFP_KERNEL
)))
return
NULL
;
memset
(
wacom
,
0
,
sizeof
(
struct
wacom
));
...
...
@@ -394,7 +395,11 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
wacom
->
dev
.
open
=
wacom_open
;
wacom
->
dev
.
close
=
wacom_close
;
usb_make_path
(
dev
,
path
,
64
);
sprintf
(
wacom
->
phys
,
"%s/input0"
,
path
);
wacom
->
dev
.
name
=
wacom
->
features
->
name
;
wacom
->
dev
.
phys
=
wacom
->
phys
;
wacom
->
dev
.
idbus
=
BUS_USB
;
wacom
->
dev
.
idvendor
=
dev
->
descriptor
.
idVendor
;
wacom
->
dev
.
idproduct
=
dev
->
descriptor
.
idProduct
;
...
...
@@ -408,8 +413,7 @@ static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struc
input_register_device
(
&
wacom
->
dev
);
printk
(
KERN_INFO
"input%d: %s on usb%d:%d.%d
\n
"
,
wacom
->
dev
.
number
,
wacom
->
features
->
name
,
dev
->
bus
->
busnum
,
dev
->
devnum
,
ifnum
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
wacom
->
features
->
name
,
path
);
return
wacom
;
}
...
...
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