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
3371ac4b
Commit
3371ac4b
authored
Feb 17, 2014
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-3.15/hid-core-ll-transport-cleanup' into for-3.15/sony
parents
7db7504a
6fad42d5
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
606 additions
and
195 deletions
+606
-195
Documentation/hid/hid-transport.txt
Documentation/hid/hid-transport.txt
+316
-0
drivers/hid/hid-input.c
drivers/hid/hid-input.c
+5
-7
drivers/hid/hid-lg.c
drivers/hid/hid-lg.c
+4
-2
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-dj.c
+42
-64
drivers/hid/hid-magicmouse.c
drivers/hid/hid-magicmouse.c
+1
-1
drivers/hid/hid-sony.c
drivers/hid/hid-sony.c
+5
-4
drivers/hid/hid-thingm.c
drivers/hid/hid-thingm.c
+2
-2
drivers/hid/hid-wacom.c
drivers/hid/hid-wacom.c
+7
-9
drivers/hid/hid-wiimote-core.c
drivers/hid/hid-wiimote-core.c
+1
-1
drivers/hid/hidraw.c
drivers/hid/hidraw.c
+5
-4
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/i2c-hid/i2c-hid.c
+0
-1
drivers/hid/uhid.c
drivers/hid/uhid.c
+27
-1
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-core.c
+71
-36
include/linux/hid.h
include/linux/hid.h
+68
-8
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+52
-55
No files found.
Documentation/hid/hid-transport.txt
0 → 100644
View file @
3371ac4b
This diff is collapsed.
Click to expand it.
drivers/hid/hid-input.c
View file @
3371ac4b
...
...
@@ -350,9 +350,9 @@ static int hidinput_get_battery_property(struct power_supply *psy,
ret
=
-
ENOMEM
;
break
;
}
ret
=
dev
->
hid_get_raw_report
(
dev
,
dev
->
battery_report_id
,
buf
,
2
,
dev
->
battery_report_type
);
ret
=
hid_hw_raw_request
(
dev
,
dev
->
battery_report_id
,
buf
,
2
,
dev
->
battery_report_type
,
HID_REQ_GET_REPORT
);
if
(
ret
!=
2
)
{
ret
=
-
ENODATA
;
...
...
@@ -1184,7 +1184,7 @@ static void hidinput_led_worker(struct work_struct *work)
hid_output_report
(
report
,
buf
);
/* synchronous output report */
hid
->
hid
_output_raw_report
(
hid
,
buf
,
len
,
HID_OUTPUT_REPORT
);
hid_output_raw_report
(
hid
,
buf
,
len
,
HID_OUTPUT_REPORT
);
kfree
(
buf
);
}
...
...
@@ -1263,9 +1263,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
}
input_set_drvdata
(
input_dev
,
hid
);
if
(
hid
->
ll_driver
->
hidinput_input_event
)
input_dev
->
event
=
hid
->
ll_driver
->
hidinput_input_event
;
else
if
(
hid
->
ll_driver
->
request
||
hid
->
hid_output_raw_report
)
if
(
hid
->
ll_driver
->
request
||
hid
->
hid_output_raw_report
)
input_dev
->
event
=
hidinput_input_event
;
input_dev
->
open
=
hidinput_open
;
input_dev
->
close
=
hidinput_close
;
...
...
drivers/hid/hid-lg.c
View file @
3371ac4b
...
...
@@ -692,7 +692,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
if
(
hdev
->
product
==
USB_DEVICE_ID_LOGITECH_WII_WHEEL
)
{
unsigned
char
buf
[]
=
{
0x00
,
0xAF
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
ret
=
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
if
(
ret
>=
0
)
{
/* insert a little delay of 10 jiffies ~ 40ms */
...
...
@@ -704,7 +705,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
buf
[
1
]
=
0xB2
;
get_random_bytes
(
&
buf
[
2
],
2
);
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
ret
=
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
}
}
...
...
drivers/hid/hid-logitech-dj.c
View file @
3371ac4b
...
...
@@ -44,14 +44,6 @@ static const char kbd_descriptor[] = {
0x19
,
0xE0
,
/* USAGE_MINIMUM (Left Control) */
0x29
,
0xE7
,
/* USAGE_MAXIMUM (Right GUI) */
0x81
,
0x02
,
/* INPUT (Data,Var,Abs) */
0x95
,
0x05
,
/* REPORT COUNT (5) */
0x05
,
0x08
,
/* USAGE PAGE (LED page) */
0x19
,
0x01
,
/* USAGE MINIMUM (1) */
0x29
,
0x05
,
/* USAGE MAXIMUM (5) */
0x91
,
0x02
,
/* OUTPUT (Data, Variable, Absolute) */
0x95
,
0x01
,
/* REPORT COUNT (1) */
0x75
,
0x03
,
/* REPORT SIZE (3) */
0x91
,
0x01
,
/* OUTPUT (Constant) */
0x95
,
0x06
,
/* REPORT_COUNT (6) */
0x75
,
0x08
,
/* REPORT_SIZE (8) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
...
...
@@ -60,6 +52,18 @@ static const char kbd_descriptor[] = {
0x19
,
0x00
,
/* USAGE_MINIMUM (no event) */
0x2A
,
0xFF
,
0x00
,
/* USAGE_MAXIMUM (reserved) */
0x81
,
0x00
,
/* INPUT (Data,Ary,Abs) */
0x85
,
0x0e
,
/* REPORT_ID (14) */
0x05
,
0x08
,
/* USAGE PAGE (LED page) */
0x95
,
0x05
,
/* REPORT COUNT (5) */
0x75
,
0x01
,
/* REPORT SIZE (1) */
0x15
,
0x00
,
/* LOGICAL_MINIMUM (0) */
0x25
,
0x01
,
/* LOGICAL_MAXIMUM (1) */
0x19
,
0x01
,
/* USAGE MINIMUM (1) */
0x29
,
0x05
,
/* USAGE MAXIMUM (5) */
0x91
,
0x02
,
/* OUTPUT (Data, Variable, Absolute) */
0x95
,
0x01
,
/* REPORT COUNT (1) */
0x75
,
0x03
,
/* REPORT SIZE (3) */
0x91
,
0x01
,
/* OUTPUT (Constant) */
0xC0
};
...
...
@@ -544,10 +548,37 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
size_t
count
,
unsigned
char
report_type
)
{
/* Called by hid raw to send data */
dbg_hid
(
"%s
\n
"
,
__func__
);
struct
dj_device
*
djdev
=
hid
->
driver_data
;
struct
dj_receiver_dev
*
djrcv_dev
=
djdev
->
dj_receiver_dev
;
u8
*
out_buf
;
int
ret
;
return
0
;
if
(
buf
[
0
]
!=
REPORT_TYPE_LEDS
)
return
-
EINVAL
;
out_buf
=
kzalloc
(
DJREPORT_SHORT_LENGTH
,
GFP_ATOMIC
);
if
(
!
out_buf
)
return
-
ENOMEM
;
if
(
count
<
DJREPORT_SHORT_LENGTH
-
2
)
count
=
DJREPORT_SHORT_LENGTH
-
2
;
out_buf
[
0
]
=
REPORT_ID_DJ_SHORT
;
out_buf
[
1
]
=
djdev
->
device_index
;
memcpy
(
out_buf
+
2
,
buf
,
count
);
/*
* hid-generic calls us with hid_output_raw_report(), but the LEDs
* are set through a SET_REPORT command. It works for USB-HID devices
* because usbhid either calls a SET_REPORT or directly send the output
* report depending if the device presents an urbout.
* Let be simple, send a SET_REPORT request.
*/
ret
=
hid_hw_raw_request
(
djrcv_dev
->
hdev
,
out_buf
[
0
],
out_buf
,
DJREPORT_SHORT_LENGTH
,
report_type
,
HID_REQ_SET_REPORT
);
kfree
(
out_buf
);
return
ret
;
}
static
void
rdcat
(
char
*
rdesc
,
unsigned
int
*
rsize
,
const
char
*
data
,
unsigned
int
size
)
...
...
@@ -613,58 +644,6 @@ static int logi_dj_ll_parse(struct hid_device *hid)
return
retval
;
}
static
int
logi_dj_ll_input_event
(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
)
{
/* Sent by the input layer to handle leds and Force Feedback */
struct
hid_device
*
dj_hiddev
=
input_get_drvdata
(
dev
);
struct
dj_device
*
dj_dev
=
dj_hiddev
->
driver_data
;
struct
dj_receiver_dev
*
djrcv_dev
=
dev_get_drvdata
(
dj_hiddev
->
dev
.
parent
);
struct
hid_device
*
dj_rcv_hiddev
=
djrcv_dev
->
hdev
;
struct
hid_report_enum
*
output_report_enum
;
struct
hid_field
*
field
;
struct
hid_report
*
report
;
unsigned
char
*
data
;
int
offset
;
dbg_hid
(
"%s: %s, type:%d | code:%d | value:%d
\n
"
,
__func__
,
dev
->
phys
,
type
,
code
,
value
);
if
(
type
!=
EV_LED
)
return
-
1
;
offset
=
hidinput_find_field
(
dj_hiddev
,
type
,
code
,
&
field
);
if
(
offset
==
-
1
)
{
dev_warn
(
&
dev
->
dev
,
"event field not found
\n
"
);
return
-
1
;
}
hid_set_field
(
field
,
offset
,
value
);
data
=
hid_alloc_report_buf
(
field
->
report
,
GFP_ATOMIC
);
if
(
!
data
)
{
dev_warn
(
&
dev
->
dev
,
"failed to allocate report buf memory
\n
"
);
return
-
1
;
}
hid_output_report
(
field
->
report
,
&
data
[
0
]);
output_report_enum
=
&
dj_rcv_hiddev
->
report_enum
[
HID_OUTPUT_REPORT
];
report
=
output_report_enum
->
report_id_hash
[
REPORT_ID_DJ_SHORT
];
hid_set_field
(
report
->
field
[
0
],
0
,
dj_dev
->
device_index
);
hid_set_field
(
report
->
field
[
0
],
1
,
REPORT_TYPE_LEDS
);
hid_set_field
(
report
->
field
[
0
],
2
,
data
[
1
]);
hid_hw_request
(
dj_rcv_hiddev
,
report
,
HID_REQ_SET_REPORT
);
kfree
(
data
);
return
0
;
}
static
int
logi_dj_ll_start
(
struct
hid_device
*
hid
)
{
dbg_hid
(
"%s
\n
"
,
__func__
);
...
...
@@ -683,7 +662,6 @@ static struct hid_ll_driver logi_dj_ll_driver = {
.
stop
=
logi_dj_ll_stop
,
.
open
=
logi_dj_ll_open
,
.
close
=
logi_dj_ll_close
,
.
hidinput_input_event
=
logi_dj_ll_input_event
,
};
...
...
drivers/hid/hid-magicmouse.c
View file @
3371ac4b
...
...
@@ -538,7 +538,7 @@ static int magicmouse_probe(struct hid_device *hdev,
* but there seems to be no other way of switching the mode.
* Thus the super-ugly hacky success check below.
*/
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
feature
,
sizeof
(
feature
),
ret
=
hid_output_raw_report
(
hdev
,
feature
,
sizeof
(
feature
),
HID_FEATURE_REPORT
);
if
(
ret
!=
-
EIO
&&
ret
!=
sizeof
(
feature
))
{
hid_err
(
hdev
,
"unable to request touch data (%d)
\n
"
,
ret
);
...
...
drivers/hid/hid-sony.c
View file @
3371ac4b
...
...
@@ -810,7 +810,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
if
(
!
buf
)
return
-
ENOMEM
;
ret
=
hdev
->
hid_get_raw_report
(
hdev
,
0xf2
,
buf
,
17
,
HID_FEATURE_REPORT
);
ret
=
hid_hw_raw_request
(
hdev
,
0xf2
,
buf
,
17
,
HID_FEATURE_REPORT
,
HID_REQ_GET_REPORT
);
if
(
ret
<
0
)
hid_err
(
hdev
,
"can't set operational mode
\n
"
);
...
...
@@ -823,7 +824,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
static
int
sixaxis_set_operational_bt
(
struct
hid_device
*
hdev
)
{
unsigned
char
buf
[]
=
{
0xf4
,
0x42
,
0x03
,
0x00
,
0x00
};
return
hdev
->
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
return
hid_output_raw_report
(
hdev
,
buf
,
sizeof
(
buf
),
HID_FEATURE_REPORT
);
}
static
void
buzz_set_leds
(
struct
hid_device
*
hdev
,
const
__u8
*
leds
)
...
...
@@ -1042,8 +1044,7 @@ static void sixaxis_state_worker(struct work_struct *work)
buf
[
10
]
|=
sc
->
led_state
[
2
]
<<
3
;
buf
[
10
]
|=
sc
->
led_state
[
3
]
<<
4
;
sc
->
hdev
->
hid_output_raw_report
(
sc
->
hdev
,
buf
,
sizeof
(
buf
),
HID_OUTPUT_REPORT
);
hid_output_raw_report
(
sc
->
hdev
,
buf
,
sizeof
(
buf
),
HID_OUTPUT_REPORT
);
}
static
void
dualshock4_state_worker
(
struct
work_struct
*
work
)
...
...
drivers/hid/hid-thingm.c
View file @
3371ac4b
...
...
@@ -48,8 +48,8 @@ static int blink1_send_command(struct blink1_data *data,
buf
[
0
],
buf
[
1
],
buf
[
2
],
buf
[
3
],
buf
[
4
],
buf
[
5
],
buf
[
6
],
buf
[
7
],
buf
[
8
]);
ret
=
data
->
hdev
->
hid_output_raw_report
(
data
->
hdev
,
buf
,
BLINK1_CMD_SIZE
,
HID_FEATURE_REPORT
);
ret
=
hid_output_raw_report
(
data
->
hdev
,
buf
,
BLINK1_CMD_SIZE
,
HID_FEATURE_REPORT
);
return
ret
<
0
?
ret
:
0
;
}
...
...
drivers/hid/hid-wacom.c
View file @
3371ac4b
...
...
@@ -128,8 +128,7 @@ static void wacom_set_image(struct hid_device *hdev, const char *image,
rep_data
[
0
]
=
WAC_CMD_ICON_START_STOP
;
rep_data
[
1
]
=
0
;
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
if
(
ret
<
0
)
goto
err
;
...
...
@@ -143,15 +142,14 @@ static void wacom_set_image(struct hid_device *hdev, const char *image,
rep_data
[
j
+
3
]
=
p
[(
i
<<
6
)
+
j
];
rep_data
[
2
]
=
i
;
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
rep_data
,
67
,
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
67
,
HID_FEATURE_REPORT
);
}
rep_data
[
0
]
=
WAC_CMD_ICON_START_STOP
;
rep_data
[
1
]
=
0
;
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
err:
return
;
...
...
@@ -183,7 +181,7 @@ static void wacom_leds_set_brightness(struct led_classdev *led_dev,
buf
[
3
]
=
value
;
/* use fixed brightness for OLEDs */
buf
[
4
]
=
0x08
;
h
dev
->
h
id_output_raw_report
(
hdev
,
buf
,
9
,
HID_FEATURE_REPORT
);
hid_output_raw_report
(
hdev
,
buf
,
9
,
HID_FEATURE_REPORT
);
kfree
(
buf
);
}
...
...
@@ -339,7 +337,7 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data
[
0
]
=
0x03
;
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
rep_data
,
2
,
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
...
...
@@ -352,7 +350,7 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
...
...
@@ -378,7 +376,7 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data
[
0
]
=
0x03
;
rep_data
[
1
]
=
wdata
->
features
;
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
rep_data
,
2
,
ret
=
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
if
(
ret
>=
0
)
wdata
->
high_speed
=
speed
;
...
...
drivers/hid/hid-wiimote-core.c
View file @
3371ac4b
...
...
@@ -35,7 +35,7 @@ static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
if
(
!
buf
)
return
-
ENOMEM
;
ret
=
h
dev
->
h
id_output_raw_report
(
hdev
,
buf
,
count
,
HID_OUTPUT_REPORT
);
ret
=
hid_output_raw_report
(
hdev
,
buf
,
count
,
HID_OUTPUT_REPORT
);
kfree
(
buf
);
return
ret
;
...
...
drivers/hid/hidraw.c
View file @
3371ac4b
...
...
@@ -153,7 +153,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
goto
out_free
;
}
ret
=
dev
->
hid_output_raw_report
(
dev
,
buf
,
count
,
report_type
);
ret
=
hid_output_raw_report
(
dev
,
buf
,
count
,
report_type
);
out_free:
kfree
(
buf
);
out:
...
...
@@ -189,7 +189,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
dev
=
hidraw_table
[
minor
]
->
hid
;
if
(
!
dev
->
hid_get_raw_repor
t
)
{
if
(
!
dev
->
ll_driver
->
raw_reques
t
)
{
ret
=
-
ENODEV
;
goto
out
;
}
...
...
@@ -216,14 +216,15 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
/*
* Read the first byte from the user. This is the report number,
* which is passed to
dev->hid_get_raw_repor
t().
* which is passed to
hid_hw_raw_reques
t().
*/
if
(
copy_from_user
(
&
report_number
,
buffer
,
1
))
{
ret
=
-
EFAULT
;
goto
out_free
;
}
ret
=
dev
->
hid_get_raw_report
(
dev
,
report_number
,
buf
,
count
,
report_type
);
ret
=
hid_hw_raw_request
(
dev
,
report_number
,
buf
,
count
,
report_type
,
HID_REQ_GET_REPORT
);
if
(
ret
<
0
)
goto
out_free
;
...
...
drivers/hid/i2c-hid/i2c-hid.c
View file @
3371ac4b
...
...
@@ -1005,7 +1005,6 @@ static int i2c_hid_probe(struct i2c_client *client,
hid
->
driver_data
=
client
;
hid
->
ll_driver
=
&
i2c_hid_ll_driver
;
hid
->
hid_get_raw_report
=
i2c_hid_get_raw_report
;
hid
->
hid_output_raw_report
=
i2c_hid_output_raw_report
;
hid
->
dev
.
parent
=
&
client
->
dev
;
ACPI_COMPANION_SET
(
&
hid
->
dev
,
ACPI_COMPANION
(
&
client
->
dev
));
...
...
drivers/hid/uhid.c
View file @
3371ac4b
...
...
@@ -244,12 +244,39 @@ static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
return
count
;
}
static
int
uhid_hid_output_report
(
struct
hid_device
*
hid
,
__u8
*
buf
,
size_t
count
)
{
struct
uhid_device
*
uhid
=
hid
->
driver_data
;
unsigned
long
flags
;
struct
uhid_event
*
ev
;
if
(
count
<
1
||
count
>
UHID_DATA_MAX
)
return
-
EINVAL
;
ev
=
kzalloc
(
sizeof
(
*
ev
),
GFP_KERNEL
);
if
(
!
ev
)
return
-
ENOMEM
;
ev
->
type
=
UHID_OUTPUT
;
ev
->
u
.
output
.
size
=
count
;
ev
->
u
.
output
.
rtype
=
UHID_OUTPUT_REPORT
;
memcpy
(
ev
->
u
.
output
.
data
,
buf
,
count
);
spin_lock_irqsave
(
&
uhid
->
qlock
,
flags
);
uhid_queue
(
uhid
,
ev
);
spin_unlock_irqrestore
(
&
uhid
->
qlock
,
flags
);
return
count
;
}
static
struct
hid_ll_driver
uhid_hid_driver
=
{
.
start
=
uhid_hid_start
,
.
stop
=
uhid_hid_stop
,
.
open
=
uhid_hid_open
,
.
close
=
uhid_hid_close
,
.
parse
=
uhid_hid_parse
,
.
output_report
=
uhid_hid_output_report
,
};
#ifdef CONFIG_COMPAT
...
...
@@ -377,7 +404,6 @@ static int uhid_dev_create(struct uhid_device *uhid,
hid
->
uniq
[
63
]
=
0
;
hid
->
ll_driver
=
&
uhid_hid_driver
;
hid
->
hid_get_raw_report
=
uhid_hid_get_raw
;
hid
->
hid_output_raw_report
=
uhid_hid_output_raw
;
hid
->
bus
=
ev
->
u
.
create
.
bus
;
hid
->
vendor
=
ev
->
u
.
create
.
vendor
;
...
...
drivers/hid/usbhid/hid-core.c
View file @
3371ac4b
...
...
@@ -884,58 +884,78 @@ static int usbhid_get_raw_report(struct hid_device *hid,
return
ret
;
}
static
int
usbhid_
output_raw_report
(
struct
hid_device
*
hid
,
__u8
*
buf
,
size_t
count
,
unsigned
char
report_
type
)
static
int
usbhid_
set_raw_report
(
struct
hid_device
*
hid
,
unsigned
int
reportnum
,
__u8
*
buf
,
size_t
count
,
unsigned
char
r
type
)
{
struct
usbhid_device
*
usbhid
=
hid
->
driver_data
;
struct
usb_device
*
dev
=
hid_to_usb_dev
(
hid
);
struct
usb_interface
*
intf
=
usbhid
->
intf
;
struct
usb_host_interface
*
interface
=
intf
->
cur_altsetting
;
int
ret
;
int
ret
,
skipped_report_id
=
0
;
if
(
usbhid
->
urbout
&&
report_type
!=
HID_FEATURE_REPORT
)
{
int
actual_length
;
int
skipped_report_id
=
0
;
/* Byte 0 is the report number. Report data starts at byte 1.*/
buf
[
0
]
=
reportnum
;
if
(
buf
[
0
]
==
0x0
)
{
/* Don't send the Report ID */
buf
++
;
count
--
;
skipped_report_id
=
1
;
}
if
(
buf
[
0
]
==
0x0
)
{
/* Don't send the Report ID */
buf
++
;
count
--
;
skipped_report_id
=
1
;
}
ret
=
usb_interrupt_msg
(
dev
,
usbhid
->
urbout
->
pipe
,
buf
,
count
,
&
actual_length
,
USB_CTRL_SET_TIMEOUT
);
/* return the number of bytes transferred */
if
(
ret
==
0
)
{
ret
=
actual_length
;
/* count also the report id */
if
(
skipped_report_id
)
ret
++
;
}
}
else
{
int
skipped_report_id
=
0
;
int
report_id
=
buf
[
0
];
if
(
buf
[
0
]
==
0x0
)
{
/* Don't send the Report ID */
buf
++
;
count
--
;
skipped_report_id
=
1
;
}
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_REPORT
,
USB_DIR_OUT
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
((
r
eport_type
+
1
)
<<
8
)
|
report_id
,
((
r
type
+
1
)
<<
8
)
|
reportnum
,
interface
->
desc
.
bInterfaceNumber
,
buf
,
count
,
USB_CTRL_SET_TIMEOUT
);
/* count also the report id, if this was a numbered report. */
if
(
ret
>
0
&&
skipped_report_id
)
/* count also the report id, if this was a numbered report. */
if
(
ret
>
0
&&
skipped_report_id
)
ret
++
;
return
ret
;
}
static
int
usbhid_output_report
(
struct
hid_device
*
hid
,
__u8
*
buf
,
size_t
count
)
{
struct
usbhid_device
*
usbhid
=
hid
->
driver_data
;
struct
usb_device
*
dev
=
hid_to_usb_dev
(
hid
);
int
actual_length
,
skipped_report_id
=
0
,
ret
;
if
(
!
usbhid
->
urbout
)
return
-
EIO
;
if
(
buf
[
0
]
==
0x0
)
{
/* Don't send the Report ID */
buf
++
;
count
--
;
skipped_report_id
=
1
;
}
ret
=
usb_interrupt_msg
(
dev
,
usbhid
->
urbout
->
pipe
,
buf
,
count
,
&
actual_length
,
USB_CTRL_SET_TIMEOUT
);
/* return the number of bytes transferred */
if
(
ret
==
0
)
{
ret
=
actual_length
;
/* count also the report id */
if
(
skipped_report_id
)
ret
++
;
}
return
ret
;
}
static
int
usbhid_output_raw_report
(
struct
hid_device
*
hid
,
__u8
*
buf
,
size_t
count
,
unsigned
char
report_type
)
{
struct
usbhid_device
*
usbhid
=
hid
->
driver_data
;
if
(
usbhid
->
urbout
&&
report_type
!=
HID_FEATURE_REPORT
)
return
usbhid_output_report
(
hid
,
buf
,
count
);
return
usbhid_set_raw_report
(
hid
,
buf
[
0
],
buf
,
count
,
report_type
);
}
static
void
usbhid_restart_queues
(
struct
usbhid_device
*
usbhid
)
{
if
(
usbhid
->
urbout
&&
!
test_bit
(
HID_OUT_RUNNING
,
&
usbhid
->
iofl
))
...
...
@@ -1200,6 +1220,20 @@ static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int r
}
}
static
int
usbhid_raw_request
(
struct
hid_device
*
hid
,
unsigned
char
reportnum
,
__u8
*
buf
,
size_t
len
,
unsigned
char
rtype
,
int
reqtype
)
{
switch
(
reqtype
)
{
case
HID_REQ_GET_REPORT
:
return
usbhid_get_raw_report
(
hid
,
reportnum
,
buf
,
len
,
rtype
);
case
HID_REQ_SET_REPORT
:
return
usbhid_set_raw_report
(
hid
,
reportnum
,
buf
,
len
,
rtype
);
default:
return
-
EIO
;
}
}
static
int
usbhid_idle
(
struct
hid_device
*
hid
,
int
report
,
int
idle
,
int
reqtype
)
{
...
...
@@ -1223,6 +1257,8 @@ static struct hid_ll_driver usb_hid_driver = {
.
power
=
usbhid_power
,
.
request
=
usbhid_request
,
.
wait
=
usbhid_wait_io
,
.
raw_request
=
usbhid_raw_request
,
.
output_report
=
usbhid_output_report
,
.
idle
=
usbhid_idle
,
};
...
...
@@ -1253,7 +1289,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
usb_set_intfdata
(
intf
,
hid
);
hid
->
ll_driver
=
&
usb_hid_driver
;
hid
->
hid_get_raw_report
=
usbhid_get_raw_report
;
hid
->
hid_output_raw_report
=
usbhid_output_raw_report
;
hid
->
ff_init
=
hid_pidff_init
;
#ifdef CONFIG_USB_HIDDEV
...
...
include/linux/hid.h
View file @
3371ac4b
...
...
@@ -508,9 +508,6 @@ struct hid_device { /* device report descriptor */
struct
hid_usage
*
,
__s32
);
void
(
*
hiddev_report_event
)
(
struct
hid_device
*
,
struct
hid_report
*
);
/* handler for raw input (Get_Report) data, used by hidraw */
int
(
*
hid_get_raw_report
)
(
struct
hid_device
*
,
unsigned
char
,
__u8
*
,
size_t
,
unsigned
char
);
/* handler for raw output data, used by hidraw */
int
(
*
hid_output_raw_report
)
(
struct
hid_device
*
,
__u8
*
,
size_t
,
unsigned
char
);
...
...
@@ -675,11 +672,12 @@ struct hid_driver {
* @stop: called on remove
* @open: called by input layer on open
* @close: called by input layer on close
* @hidinput_input_event: event input event (e.g. ff or leds)
* @parse: this method is called only once to parse the device data,
* shouldn't allocate anything to not leak memory
* @request: send report request to device (e.g. feature report)
* @wait: wait for buffered io to complete (send/recv reports)
* @raw_request: send raw report request to device (e.g. feature report)
* @output_report: send output report to device
* @idle: send idle request to device
*/
struct
hid_ll_driver
{
...
...
@@ -691,17 +689,20 @@ struct hid_ll_driver {
int
(
*
power
)(
struct
hid_device
*
hdev
,
int
level
);
int
(
*
hidinput_input_event
)
(
struct
input_dev
*
idev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
);
int
(
*
parse
)(
struct
hid_device
*
hdev
);
void
(
*
request
)(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
,
int
reqtype
);
int
(
*
wait
)(
struct
hid_device
*
hdev
);
int
(
*
idle
)(
struct
hid_device
*
hdev
,
int
report
,
int
idle
,
int
reqtype
);
int
(
*
raw_request
)
(
struct
hid_device
*
hdev
,
unsigned
char
reportnum
,
__u8
*
buf
,
size_t
len
,
unsigned
char
rtype
,
int
reqtype
);
int
(
*
output_report
)
(
struct
hid_device
*
hdev
,
__u8
*
buf
,
size_t
len
);
int
(
*
idle
)(
struct
hid_device
*
hdev
,
int
report
,
int
idle
,
int
reqtype
);
};
#define PM_HINT_FULLON 1<<5
...
...
@@ -967,6 +968,65 @@ static inline void hid_hw_request(struct hid_device *hdev,
hdev
->
ll_driver
->
request
(
hdev
,
report
,
reqtype
);
}
/**
* hid_hw_raw_request - send report request to device
*
* @hdev: hid device
* @reportnum: report ID
* @buf: in/out data to transfer
* @len: length of buf
* @rtype: HID report type
* @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
*
* @return: count of data transfered, negative if error
*
* Same behavior as hid_hw_request, but with raw buffers instead.
*/
static
inline
int
hid_hw_raw_request
(
struct
hid_device
*
hdev
,
unsigned
char
reportnum
,
__u8
*
buf
,
size_t
len
,
unsigned
char
rtype
,
int
reqtype
)
{
if
(
hdev
->
ll_driver
->
raw_request
)
return
hdev
->
ll_driver
->
raw_request
(
hdev
,
reportnum
,
buf
,
len
,
rtype
,
reqtype
);
return
-
ENOSYS
;
}
/**
* hid_hw_output_report - send output report to device
*
* @hdev: hid device
* @buf: raw data to transfer
* @len: length of buf
*
* @return: count of data transfered, negative if error
*/
static
inline
int
hid_hw_output_report
(
struct
hid_device
*
hdev
,
__u8
*
buf
,
size_t
len
)
{
if
(
hdev
->
ll_driver
->
output_report
)
return
hdev
->
ll_driver
->
output_report
(
hdev
,
buf
,
len
);
return
-
ENOSYS
;
}
/**
* hid_output_raw_report - send an output or a feature report to the device
*
* @hdev: hid device
* @buf: raw data to transfer
* @len: length of buf
* @report_type: HID_FEATURE_REPORT or HID_OUTPUT_REPORT
*
* @return: count of data transfered, negative if error
*/
static
inline
int
hid_output_raw_report
(
struct
hid_device
*
hdev
,
__u8
*
buf
,
size_t
len
,
unsigned
char
report_type
)
{
return
hdev
->
hid_output_raw_report
(
hdev
,
buf
,
len
,
report_type
);
}
/**
* hid_hw_idle - send idle request to device
*
...
...
net/bluetooth/hidp/core.c
View file @
3371ac4b
...
...
@@ -223,51 +223,6 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
input_sync
(
dev
);
}
static
int
hidp_send_report
(
struct
hidp_session
*
session
,
struct
hid_report
*
report
)
{
unsigned
char
hdr
;
u8
*
buf
;
int
rsize
,
ret
;
buf
=
hid_alloc_report_buf
(
report
,
GFP_ATOMIC
);
if
(
!
buf
)
return
-
EIO
;
hid_output_report
(
report
,
buf
);
hdr
=
HIDP_TRANS_DATA
|
HIDP_DATA_RTYPE_OUPUT
;
rsize
=
((
report
->
size
-
1
)
>>
3
)
+
1
+
(
report
->
id
>
0
);
ret
=
hidp_send_intr_message
(
session
,
hdr
,
buf
,
rsize
);
kfree
(
buf
);
return
ret
;
}
static
int
hidp_hidinput_event
(
struct
input_dev
*
dev
,
unsigned
int
type
,
unsigned
int
code
,
int
value
)
{
struct
hid_device
*
hid
=
input_get_drvdata
(
dev
);
struct
hidp_session
*
session
=
hid
->
driver_data
;
struct
hid_field
*
field
;
int
offset
;
BT_DBG
(
"session %p type %d code %d value %d"
,
session
,
type
,
code
,
value
);
if
(
type
!=
EV_LED
)
return
-
1
;
offset
=
hidinput_find_field
(
hid
,
type
,
code
,
&
field
);
if
(
offset
==
-
1
)
{
hid_warn
(
dev
,
"event field not found
\n
"
);
return
-
1
;
}
hid_set_field
(
field
,
offset
,
value
);
return
hidp_send_report
(
session
,
field
->
report
);
}
static
int
hidp_get_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
report_number
,
unsigned
char
*
data
,
size_t
count
,
...
...
@@ -353,17 +308,24 @@ static int hidp_get_raw_report(struct hid_device *hid,
return
ret
;
}
static
int
hidp_output_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
*
data
,
size_t
count
,
unsigned
char
report_type
)
static
int
hidp_set_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
reportnum
,
unsigned
char
*
data
,
size_t
count
,
unsigned
char
report_type
)
{
struct
hidp_session
*
session
=
hid
->
driver_data
;
int
ret
;
if
(
report_type
==
HID_OUTPUT_REPORT
)
{
report_type
=
HIDP_TRANS_DATA
|
HIDP_DATA_RTYPE_OUPUT
;
return
hidp_send_intr_message
(
session
,
report_type
,
data
,
count
);
}
else
if
(
report_type
!=
HID_FEATURE_REPORT
)
{
switch
(
report_type
)
{
case
HID_FEATURE_REPORT
:
report_type
=
HIDP_TRANS_SET_REPORT
|
HIDP_DATA_RTYPE_FEATURE
;
break
;
case
HID_INPUT_REPORT
:
report_type
=
HIDP_TRANS_SET_REPORT
|
HIDP_DATA_RTYPE_INPUT
;
break
;
case
HID_OUTPUT_REPORT
:
report_type
=
HIDP_TRANS_SET_REPORT
|
HIDP_DATA_RTYPE_OUPUT
;
break
;
default:
return
-
EINVAL
;
}
...
...
@@ -371,8 +333,8 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
return
-
ERESTARTSYS
;
/* Set up our wait, and send the report request to the device. */
data
[
0
]
=
reportnum
;
set_bit
(
HIDP_WAITING_FOR_SEND_ACK
,
&
session
->
flags
);
report_type
=
HIDP_TRANS_SET_REPORT
|
HIDP_DATA_RTYPE_FEATURE
;
ret
=
hidp_send_ctrl_message
(
session
,
report_type
,
data
,
count
);
if
(
ret
)
goto
err
;
...
...
@@ -411,6 +373,41 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
return
ret
;
}
static
int
hidp_output_report
(
struct
hid_device
*
hid
,
__u8
*
data
,
size_t
count
)
{
struct
hidp_session
*
session
=
hid
->
driver_data
;
return
hidp_send_intr_message
(
session
,
HIDP_TRANS_DATA
|
HIDP_DATA_RTYPE_OUPUT
,
data
,
count
);
}
static
int
hidp_output_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
*
data
,
size_t
count
,
unsigned
char
report_type
)
{
if
(
report_type
==
HID_OUTPUT_REPORT
)
{
return
hidp_output_report
(
hid
,
data
,
count
);
}
else
if
(
report_type
!=
HID_FEATURE_REPORT
)
{
return
-
EINVAL
;
}
return
hidp_set_raw_report
(
hid
,
data
[
0
],
data
,
count
,
report_type
);
}
static
int
hidp_raw_request
(
struct
hid_device
*
hid
,
unsigned
char
reportnum
,
__u8
*
buf
,
size_t
len
,
unsigned
char
rtype
,
int
reqtype
)
{
switch
(
reqtype
)
{
case
HID_REQ_GET_REPORT
:
return
hidp_get_raw_report
(
hid
,
reportnum
,
buf
,
len
,
rtype
);
case
HID_REQ_SET_REPORT
:
return
hidp_set_raw_report
(
hid
,
reportnum
,
buf
,
len
,
rtype
);
default:
return
-
EIO
;
}
}
static
void
hidp_idle_timeout
(
unsigned
long
arg
)
{
struct
hidp_session
*
session
=
(
struct
hidp_session
*
)
arg
;
...
...
@@ -727,7 +724,8 @@ static struct hid_ll_driver hidp_hid_driver = {
.
stop
=
hidp_stop
,
.
open
=
hidp_open
,
.
close
=
hidp_close
,
.
hidinput_input_event
=
hidp_hidinput_event
,
.
raw_request
=
hidp_raw_request
,
.
output_report
=
hidp_output_report
,
};
/* This function sets up the hid device. It does not add it
...
...
@@ -775,7 +773,6 @@ static int hidp_setup_hid(struct hidp_session *session,
hid
->
dev
.
parent
=
&
session
->
conn
->
hcon
->
dev
;
hid
->
ll_driver
=
&
hidp_hid_driver
;
hid
->
hid_get_raw_report
=
hidp_get_raw_report
;
hid
->
hid_output_raw_report
=
hidp_output_raw_report
;
/* True if device is blacklisted in drivers/hid/hid-core.c */
...
...
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