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
d057fd4c
Commit
d057fd4c
authored
Oct 14, 2007
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'hidraw' into for-linus
parents
bb6c8d8f
709d27c0
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
565 additions
and
2 deletions
+565
-2
drivers/hid/Kconfig
drivers/hid/Kconfig
+19
-0
drivers/hid/Makefile
drivers/hid/Makefile
+2
-0
drivers/hid/hid-core.c
drivers/hid/hid-core.c
+16
-0
drivers/hid/hidraw.c
drivers/hid/hidraw.c
+401
-0
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-core.c
+36
-2
include/linux/hid.h
include/linux/hid.h
+5
-0
include/linux/hidraw.h
include/linux/hidraw.h
+86
-0
No files found.
drivers/hid/Kconfig
View file @
d057fd4c
...
...
@@ -46,6 +46,25 @@ config HID_DEBUG
If unsure, say N
config HIDRAW
bool "/dev/hidraw raw HID device support"
depends on HID
---help---
Say Y here if you want to support HID devices (from the USB
specification standpoint) that aren't strictly user interface
devices, like monitor controls and Uninterruptable Power Supplies.
This module supports these devices separately using a separate
event interface on /dev/hidraw.
There is also a /dev/hiddev configuration option in the USB HID
configuration menu. In comparison to hiddev, this device does not process
the hid events at all (no parsing, no lookups). This lets applications
to work on raw hid events when they want to, and avoid using transport-specific
userspace libhid/libusb libraries.
If unsure, say Y.
source "drivers/hid/usbhid/Kconfig"
endif # HID_SUPPORT
drivers/hid/Makefile
View file @
d057fd4c
...
...
@@ -4,7 +4,9 @@
hid-objs
:=
hid-core.o hid-input.o
obj-$(CONFIG_HID)
+=
hid.o
hid-$(CONFIG_HID_DEBUG)
+=
hid-debug.o
hid-$(CONFIG_HIDRAW)
+=
hidraw.o
obj-$(CONFIG_USB_HID)
+=
usbhid/
obj-$(CONFIG_USB_MOUSE)
+=
usbhid/
...
...
drivers/hid/hid-core.c
View file @
d057fd4c
...
...
@@ -30,6 +30,7 @@
#include <linux/hid.h>
#include <linux/hiddev.h>
#include <linux/hid-debug.h>
#include <linux/hidraw.h>
/*
* Version Information
...
...
@@ -979,6 +980,8 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
if
((
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
&&
hid
->
hiddev_report_event
)
hid
->
hiddev_report_event
(
hid
,
report
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDRAW
)
hidraw_report_event
(
hid
,
data
,
size
);
for
(
n
=
0
;
n
<
report
->
maxfield
;
n
++
)
hid_input_field
(
hid
,
report
->
field
[
n
],
data
,
interrupt
);
...
...
@@ -990,5 +993,18 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
}
EXPORT_SYMBOL_GPL
(
hid_input_report
);
static
int
__init
hid_init
(
void
)
{
return
hidraw_init
();
}
static
void
__exit
hid_exit
(
void
)
{
hidraw_exit
();
}
module_init
(
hid_init
);
module_exit
(
hid_exit
);
MODULE_LICENSE
(
DRIVER_LICENSE
);
drivers/hid/hidraw.c
0 → 100644
View file @
d057fd4c
/*
* HID raw devices, giving access to raw HID events.
*
* In comparison to hiddev, this device does not process the
* hid events at all (no parsing, no lookups). This lets applications
* to work on raw hid events as they want to, and avoids a need to
* use a transport-specific userspace libhid/libusb libraries.
*
* Copyright (c) 2007 Jiri Kosina
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/major.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/hidraw.h>
static
int
hidraw_major
;
static
struct
cdev
hidraw_cdev
;
static
struct
class
*
hidraw_class
;
static
struct
hidraw
*
hidraw_table
[
HIDRAW_MAX_DEVICES
];
static
DEFINE_SPINLOCK
(
minors_lock
);
static
ssize_t
hidraw_read
(
struct
file
*
file
,
char
__user
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
struct
hidraw_list
*
list
=
file
->
private_data
;
int
ret
=
0
,
len
;
char
*
report
;
DECLARE_WAITQUEUE
(
wait
,
current
);
while
(
ret
==
0
)
{
mutex_lock
(
&
list
->
read_mutex
);
if
(
list
->
head
==
list
->
tail
)
{
add_wait_queue
(
&
list
->
hidraw
->
wait
,
&
wait
);
set_current_state
(
TASK_INTERRUPTIBLE
);
while
(
list
->
head
==
list
->
tail
)
{
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
ret
=
-
EAGAIN
;
break
;
}
if
(
signal_pending
(
current
))
{
ret
=
-
ERESTARTSYS
;
break
;
}
if
(
!
list
->
hidraw
->
exist
)
{
ret
=
-
EIO
;
break
;
}
/* allow O_NONBLOCK to work well from other threads */
mutex_unlock
(
&
list
->
read_mutex
);
schedule
();
mutex_lock
(
&
list
->
read_mutex
);
set_current_state
(
TASK_INTERRUPTIBLE
);
}
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
list
->
hidraw
->
wait
,
&
wait
);
}
if
(
ret
)
goto
out
;
report
=
list
->
buffer
[
list
->
tail
].
value
;
len
=
list
->
buffer
[
list
->
tail
].
len
>
count
?
count
:
list
->
buffer
[
list
->
tail
].
len
;
if
(
copy_to_user
(
buffer
,
list
->
buffer
[
list
->
tail
].
value
,
len
))
{
ret
=
-
EFAULT
;
goto
out
;
}
ret
+=
len
;
kfree
(
list
->
buffer
[
list
->
tail
].
value
);
list
->
tail
=
(
list
->
tail
+
1
)
&
(
HIDRAW_BUFFER_SIZE
-
1
);
}
out:
mutex_unlock
(
&
list
->
read_mutex
);
return
ret
;
}
/* the first byte is expected to be a report number */
static
ssize_t
hidraw_write
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
unsigned
int
minor
=
iminor
(
file
->
f_path
.
dentry
->
d_inode
);
struct
hid_device
*
dev
=
hidraw_table
[
minor
]
->
hid
;
__u8
*
buf
;
int
ret
=
0
;
if
(
!
dev
->
hid_output_raw_report
)
return
-
ENODEV
;
if
(
count
>
HID_MIN_BUFFER_SIZE
)
{
printk
(
KERN_WARNING
"hidraw: pid %d passed too large report
\n
"
,
current
->
pid
);
return
-
EINVAL
;
}
if
(
count
<
2
)
{
printk
(
KERN_WARNING
"hidraw: pid %d passed too short report
\n
"
,
current
->
pid
);
return
-
EINVAL
;
}
buf
=
kmalloc
(
count
*
sizeof
(
__u8
),
GFP_KERNEL
);
if
(
!
buf
)
return
-
ENOMEM
;
if
(
copy_from_user
(
buf
,
buffer
,
count
))
{
ret
=
-
EFAULT
;
goto
out
;
}
ret
=
dev
->
hid_output_raw_report
(
dev
,
buf
,
count
);
out:
kfree
(
buf
);
return
ret
;
}
static
unsigned
int
hidraw_poll
(
struct
file
*
file
,
poll_table
*
wait
)
{
struct
hidraw_list
*
list
=
file
->
private_data
;
poll_wait
(
file
,
&
list
->
hidraw
->
wait
,
wait
);
if
(
list
->
head
!=
list
->
tail
)
return
POLLIN
|
POLLRDNORM
;
if
(
!
list
->
hidraw
->
exist
)
return
POLLERR
|
POLLHUP
;
return
0
;
}
static
int
hidraw_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
unsigned
int
minor
=
iminor
(
inode
);
struct
hidraw
*
dev
;
struct
hidraw_list
*
list
;
int
err
=
0
;
if
(
!
(
list
=
kzalloc
(
sizeof
(
struct
hidraw_list
),
GFP_KERNEL
)))
{
err
=
-
ENOMEM
;
goto
out
;
}
spin_lock
(
&
minors_lock
);
if
(
!
hidraw_table
[
minor
])
{
printk
(
KERN_EMERG
"hidraw device with minor %d doesn't exist
\n
"
,
minor
);
kfree
(
list
);
err
=
-
ENODEV
;
goto
out_unlock
;
}
list
->
hidraw
=
hidraw_table
[
minor
];
mutex_init
(
&
list
->
read_mutex
);
list_add_tail
(
&
list
->
node
,
&
hidraw_table
[
minor
]
->
list
);
file
->
private_data
=
list
;
dev
=
hidraw_table
[
minor
];
if
(
!
dev
->
open
++
)
dev
->
hid
->
hid_open
(
dev
->
hid
);
out_unlock:
spin_unlock
(
&
minors_lock
);
out:
return
err
;
}
static
int
hidraw_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
unsigned
int
minor
=
iminor
(
inode
);
struct
hidraw
*
dev
;
struct
hidraw_list
*
list
=
file
->
private_data
;
if
(
!
hidraw_table
[
minor
])
{
printk
(
KERN_EMERG
"hidraw device with minor %d doesn't exist
\n
"
,
minor
);
return
-
ENODEV
;
}
list_del
(
&
list
->
node
);
dev
=
hidraw_table
[
minor
];
if
(
!
dev
->
open
--
)
{
if
(
list
->
hidraw
->
exist
)
dev
->
hid
->
hid_close
(
dev
->
hid
);
else
kfree
(
list
->
hidraw
);
}
return
0
;
}
static
int
hidraw_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
unsigned
int
minor
=
iminor
(
inode
);
struct
hidraw
*
dev
=
hidraw_table
[
minor
];
void
__user
*
user_arg
=
(
void
__user
*
)
arg
;
switch
(
cmd
)
{
case
HIDIOCGRDESCSIZE
:
if
(
put_user
(
dev
->
hid
->
rsize
,
(
int
__user
*
)
arg
))
return
-
EFAULT
;
return
0
;
case
HIDIOCGRDESC
:
{
__u32
len
;
if
(
get_user
(
len
,
(
int
__user
*
)
arg
))
return
-
EFAULT
;
if
(
copy_to_user
(
*
((
__u8
**
)(
user_arg
+
sizeof
(
__u32
))),
dev
->
hid
->
rdesc
,
len
))
return
-
EFAULT
;
return
0
;
}
case
HIDIOCGRAWINFO
:
{
struct
hidraw_devinfo
dinfo
;
dinfo
.
bustype
=
dev
->
hid
->
bus
;
dinfo
.
vendor
=
dev
->
hid
->
vendor
;
dinfo
.
product
=
dev
->
hid
->
product
;
if
(
copy_to_user
(
user_arg
,
&
dinfo
,
sizeof
(
dinfo
)))
return
-
EFAULT
;
return
0
;
}
default:
printk
(
KERN_EMERG
"hidraw: unsupported ioctl() %x
\n
"
,
cmd
);
}
return
-
EINVAL
;
}
static
const
struct
file_operations
hidraw_ops
=
{
.
owner
=
THIS_MODULE
,
.
read
=
hidraw_read
,
.
write
=
hidraw_write
,
.
poll
=
hidraw_poll
,
.
open
=
hidraw_open
,
.
release
=
hidraw_release
,
.
ioctl
=
hidraw_ioctl
,
};
void
hidraw_report_event
(
struct
hid_device
*
hid
,
u8
*
data
,
int
len
)
{
struct
hidraw
*
dev
=
hid
->
hidraw
;
struct
hidraw_list
*
list
;
list_for_each_entry
(
list
,
&
dev
->
list
,
node
)
{
list
->
buffer
[
list
->
head
].
value
=
kmemdup
(
data
,
len
,
GFP_ATOMIC
);
list
->
buffer
[
list
->
head
].
len
=
len
;
list
->
head
=
(
list
->
head
+
1
)
&
(
HIDRAW_BUFFER_SIZE
-
1
);
kill_fasync
(
&
list
->
fasync
,
SIGIO
,
POLL_IN
);
}
wake_up_interruptible
(
&
dev
->
wait
);
}
EXPORT_SYMBOL_GPL
(
hidraw_report_event
);
int
hidraw_connect
(
struct
hid_device
*
hid
)
{
int
minor
,
result
;
struct
hidraw
*
dev
;
/* TODO currently we accept any HID device. This should later
* probably be fixed to accept only those devices which provide
* non-input applications
*/
dev
=
kzalloc
(
sizeof
(
struct
hidraw
),
GFP_KERNEL
);
if
(
!
dev
)
return
-
ENOMEM
;
result
=
-
EINVAL
;
spin_lock
(
&
minors_lock
);
for
(
minor
=
0
;
minor
<
HIDRAW_MAX_DEVICES
;
minor
++
)
{
if
(
hidraw_table
[
minor
])
continue
;
hidraw_table
[
minor
]
=
dev
;
result
=
0
;
break
;
}
spin_unlock
(
&
minors_lock
);
if
(
result
)
{
kfree
(
dev
);
goto
out
;
}
dev
->
dev
=
device_create
(
hidraw_class
,
NULL
,
MKDEV
(
hidraw_major
,
minor
),
"%s%d"
,
"hidraw"
,
minor
);
if
(
IS_ERR
(
dev
->
dev
))
{
spin_lock
(
&
minors_lock
);
hidraw_table
[
minor
]
=
NULL
;
spin_unlock
(
&
minors_lock
);
result
=
PTR_ERR
(
dev
->
dev
);
kfree
(
dev
);
goto
out
;
}
init_waitqueue_head
(
&
dev
->
wait
);
INIT_LIST_HEAD
(
&
dev
->
list
);
dev
->
hid
=
hid
;
dev
->
minor
=
minor
;
dev
->
exist
=
1
;
hid
->
hidraw
=
dev
;
out:
return
result
;
}
EXPORT_SYMBOL_GPL
(
hidraw_connect
);
void
hidraw_disconnect
(
struct
hid_device
*
hid
)
{
struct
hidraw
*
hidraw
=
hid
->
hidraw
;
hidraw
->
exist
=
0
;
spin_lock
(
&
minors_lock
);
hidraw_table
[
hidraw
->
minor
]
=
NULL
;
spin_unlock
(
&
minors_lock
);
device_destroy
(
hidraw_class
,
MKDEV
(
hidraw_major
,
hidraw
->
minor
));
if
(
hidraw
->
open
)
{
hid
->
hid_close
(
hid
);
wake_up_interruptible
(
&
hidraw
->
wait
);
}
else
{
kfree
(
hidraw
);
}
}
EXPORT_SYMBOL_GPL
(
hidraw_disconnect
);
int
__init
hidraw_init
(
void
)
{
int
result
;
dev_t
dev_id
;
result
=
alloc_chrdev_region
(
&
dev_id
,
HIDRAW_FIRST_MINOR
,
HIDRAW_MAX_DEVICES
,
"hidraw"
);
hidraw_major
=
MAJOR
(
dev_id
);
if
(
result
<
0
)
{
printk
(
KERN_WARNING
"hidraw: can't get major number
\n
"
);
result
=
0
;
goto
out
;
}
hidraw_class
=
class_create
(
THIS_MODULE
,
"hidraw"
);
if
(
IS_ERR
(
hidraw_class
))
{
result
=
PTR_ERR
(
hidraw_class
);
unregister_chrdev
(
hidraw_major
,
"hidraw"
);
goto
out
;
}
cdev_init
(
&
hidraw_cdev
,
&
hidraw_ops
);
cdev_add
(
&
hidraw_cdev
,
dev_id
,
HIDRAW_MAX_DEVICES
);
out:
return
result
;
}
void
__exit
hidraw_exit
(
void
)
{
dev_t
dev_id
=
MKDEV
(
hidraw_major
,
0
);
cdev_del
(
&
hidraw_cdev
);
class_destroy
(
hidraw_class
);
unregister_chrdev_region
(
dev_id
,
HIDRAW_MAX_DEVICES
);
}
drivers/hid/usbhid/hid-core.c
View file @
d057fd4c
...
...
@@ -32,6 +32,7 @@
#include <linux/hid.h>
#include <linux/hiddev.h>
#include <linux/hid-debug.h>
#include <linux/hidraw.h>
#include "usbhid.h"
/*
...
...
@@ -639,6 +640,28 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
return
0
;
}
static
int
usbhid_output_raw_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
);
struct
usb_interface
*
intf
=
usbhid
->
intf
;
struct
usb_host_interface
*
interface
=
intf
->
cur_altsetting
;
int
ret
;
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_REPORT
,
USB_DIR_OUT
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
cpu_to_le16
(((
HID_OUTPUT_REPORT
+
1
)
<<
8
)
|
*
buf
),
interface
->
desc
.
bInterfaceNumber
,
buf
+
1
,
count
-
1
,
USB_CTRL_SET_TIMEOUT
);
/* count also the report id */
if
(
ret
>
0
)
ret
++
;
return
ret
;
}
static
void
hid_free_buffers
(
struct
usb_device
*
dev
,
struct
hid_device
*
hid
)
{
struct
usbhid_device
*
usbhid
=
hid
->
driver_data
;
...
...
@@ -882,6 +905,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
hid
->
hiddev_hid_event
=
hiddev_hid_event
;
hid
->
hiddev_report_event
=
hiddev_report_event
;
#endif
hid
->
hid_output_raw_report
=
usbhid_output_raw_report
;
return
hid
;
fail:
...
...
@@ -920,6 +944,8 @@ static void hid_disconnect(struct usb_interface *intf)
hidinput_disconnect
(
hid
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
hiddev_disconnect
(
hid
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDRAW
)
hidraw_disconnect
(
hid
);
usb_free_urb
(
usbhid
->
urbin
);
usb_free_urb
(
usbhid
->
urbctrl
);
...
...
@@ -952,11 +978,13 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
hid
->
claimed
|=
HID_CLAIMED_INPUT
;
if
(
!
hiddev_connect
(
hid
))
hid
->
claimed
|=
HID_CLAIMED_HIDDEV
;
if
(
!
hidraw_connect
(
hid
))
hid
->
claimed
|=
HID_CLAIMED_HIDRAW
;
usb_set_intfdata
(
intf
,
hid
);
if
(
!
hid
->
claimed
)
{
printk
(
"HID device
not claimed by input or hiddev
\n
"
);
printk
(
"HID device
claimed by neither input, hiddev nor hidraw
\n
"
);
hid_disconnect
(
intf
);
return
-
ENODEV
;
}
...
...
@@ -972,10 +1000,16 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
if
(
hid
->
claimed
&
HID_CLAIMED_INPUT
)
printk
(
"input"
);
if
(
hid
->
claimed
==
(
HID_CLAIMED_INPUT
|
HID_CLAIMED_HIDDEV
))
if
((
hid
->
claimed
&
HID_CLAIMED_INPUT
)
&&
((
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
||
hid
->
claimed
&
HID_CLAIMED_HIDRAW
))
printk
(
","
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
printk
(
"hiddev%d"
,
hid
->
minor
);
if
((
hid
->
claimed
&
HID_CLAIMED_INPUT
)
&&
(
hid
->
claimed
&
HID_CLAIMED_HIDDEV
)
&&
(
hid
->
claimed
&
HID_CLAIMED_HIDRAW
))
printk
(
","
);
if
(
hid
->
claimed
&
HID_CLAIMED_HIDRAW
)
printk
(
"hidraw%d"
,
((
struct
hidraw
*
)
hid
->
hidraw
)
->
minor
);
c
=
"Device"
;
for
(
i
=
0
;
i
<
hid
->
maxcollection
;
i
++
)
{
...
...
include/linux/hid.h
View file @
d057fd4c
...
...
@@ -405,6 +405,7 @@ struct hid_control_fifo {
#define HID_CLAIMED_INPUT 1
#define HID_CLAIMED_HIDDEV 2
#define HID_CLAIMED_HIDRAW 4
#define HID_CTRL_RUNNING 1
#define HID_OUT_RUNNING 2
...
...
@@ -440,6 +441,7 @@ struct hid_device { /* device report descriptor */
struct
list_head
inputs
;
/* The list of inputs */
void
*
hiddev
;
/* The hiddev structure */
void
*
hidraw
;
int
minor
;
/* Hiddev minor number */
wait_queue_head_t
wait
;
/* For sleeping */
...
...
@@ -460,6 +462,9 @@ struct hid_device { /* device report descriptor */
void
(
*
hiddev_hid_event
)
(
struct
hid_device
*
,
struct
hid_field
*
field
,
struct
hid_usage
*
,
__s32
);
void
(
*
hiddev_report_event
)
(
struct
hid_device
*
,
struct
hid_report
*
);
/* handler for raw output data, used by hidraw */
int
(
*
hid_output_raw_report
)
(
struct
hid_device
*
,
__u8
*
,
size_t
);
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
unsigned
long
pb_pressed_fn
[
NBITS
(
KEY_MAX
)];
unsigned
long
pb_pressed_numlock
[
NBITS
(
KEY_MAX
)];
...
...
include/linux/hidraw.h
0 → 100644
View file @
d057fd4c
#ifndef _HIDRAW_H
#define _HIDRAW_H
/*
* Copyright (c) 2007 Jiri Kosina
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
struct
hidraw_report_descriptor
{
__u32
size
;
__u8
*
value
;
};
struct
hidraw_devinfo
{
__u32
bustype
;
__s16
vendor
;
__s16
product
;
};
/* ioctl interface */
#define HIDIOCGRDESCSIZE _IOR('H', 0x01, int)
#define HIDIOCGRDESC _IOR('H', 0x02, struct hidraw_report_descriptor)
#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
#define HIDRAW_FIRST_MINOR 0
#define HIDRAW_MAX_DEVICES 64
/* number of reports to buffer */
#define HIDRAW_BUFFER_SIZE 64
/* kernel-only API declarations */
#ifdef __KERNEL__
#include <linux/hid.h>
struct
hidraw
{
unsigned
int
minor
;
int
exist
;
int
open
;
wait_queue_head_t
wait
;
struct
hid_device
*
hid
;
struct
device
*
dev
;
struct
list_head
list
;
};
struct
hidraw_report
{
__u8
*
value
;
int
len
;
};
struct
hidraw_list
{
struct
hidraw_report
buffer
[
HIDRAW_BUFFER_SIZE
];
int
head
;
int
tail
;
struct
fasync_struct
*
fasync
;
struct
hidraw
*
hidraw
;
struct
list_head
node
;
struct
mutex
read_mutex
;
};
#ifdef CONFIG_HIDRAW
int
hidraw_init
(
void
);
void
hidraw_exit
(
void
);
void
hidraw_report_event
(
struct
hid_device
*
,
u8
*
,
int
);
int
hidraw_connect
(
struct
hid_device
*
);
void
hidraw_disconnect
(
struct
hid_device
*
);
#else
static
inline
int
hidraw_init
(
void
)
{
return
0
;
}
static
inline
void
hidraw_exit
(
void
)
{
}
static
inline
void
hidraw_report_event
(
struct
hid_device
*
hid
,
u8
*
data
,
int
len
)
{
}
static
inline
int
hidraw_connect
(
struct
hid_device
*
hid
)
{
return
-
1
;
}
static
inline
void
hidraw_disconnect
(
struct
hid_device
*
hid
)
{
}
#endif
#endif
#endif
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