2011-02-16 04:06:47

by Alan Ott

[permalink] [raw]
Subject: [PATCH v4 0/2] HID: hidraw Documentation

So I messed up a minute ago and sent just one of these out. Please disregard
the one I just sent that says v2. It should have been v3, and it should have
had 2 patches in the set instead of just 1. Sorry for the noise....

These patches add the hidraw.txt file to a new Documentation/hid/ directory.

The example program has been moved out of the document and fixed up for style
(it's now checkpatch.pl clean), and a Makefile has been created for it.

I integrated the comments provided.

hiddev.txt has been moved from Documentation/usb/ to Documentation/hid/

This is rebased against .37+



Alan Ott (2):
HID: Documentation for hidraw
HID: Move hiddev.txt to the new Documentation/HID directory

Documentation/hid/Makefile | 8 ++
Documentation/hid/hid-example.c | 167 +++++++++++++++++++++++++++++++++
Documentation/{usb => hid}/hiddev.txt | 0
Documentation/hid/hidraw.txt | 119 +++++++++++++++++++++++
4 files changed, 294 insertions(+), 0 deletions(-)
create mode 100644 Documentation/hid/Makefile
create mode 100644 Documentation/hid/hid-example.c
rename Documentation/{usb => hid}/hiddev.txt (100%)
create mode 100644 Documentation/hid/hidraw.txt




2011-02-17 00:56:03

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] HID: Documentation for hidraw

On Wed, 16 Feb 2011 14:06:19 -0500 Alan Ott wrote:

> On 02/16/2011 09:12 AM, Jonathan Corbet wrote:
> >> Documentation/hid/Makefile | 8 ++
> >> Documentation/hid/hid-example.c | 167 +++++++++++++++++++++++++++++++++++++++
> >>
> > I believe we're trying to get code - especially runnable code - out of the
> > Documentation tree. Should this go under samples/ or, if it's useful
> > enough, under tools/?
> >
>
> Hi Jon,
>
> Not a problem. I'd say samples/ over tools/ for this stuff. I'll re-spin
> and re-submit.

and then
Acked-by: Randy Dunlap <[email protected]>

Thanks.
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

2011-02-16 19:10:57

by Jiri Kosina

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] HID: Documentation for hidraw

On Wed, 16 Feb 2011, Alan Ott wrote:

> > > Documentation/hid/Makefile | 8 ++
> > > Documentation/hid/hid-example.c | 167
> > > +++++++++++++++++++++++++++++++++++++++
> > >
> > I believe we're trying to get code - especially runnable code - out of the
> > Documentation tree. Should this go under samples/ or, if it's useful
> > enough, under tools/?
> >
>
> Not a problem. I'd say samples/ over tools/ for this stuff. I'll re-spin
> and re-submit.

Perfect, thanks, I'd prefer samples/ as well.

Otherwise I like the hidraw documentation, thanks a lot for putting it
together.

--
Jiri Kosina
SUSE Labs, Novell Inc.

2011-02-16 19:06:19

by Alan Ott

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] HID: Documentation for hidraw

On 02/16/2011 09:12 AM, Jonathan Corbet wrote:
>> Documentation/hid/Makefile | 8 ++
>> Documentation/hid/hid-example.c | 167 +++++++++++++++++++++++++++++++++++++++
>>
> I believe we're trying to get code - especially runnable code - out of the
> Documentation tree. Should this go under samples/ or, if it's useful
> enough, under tools/?
>

Hi Jon,

Not a problem. I'd say samples/ over tools/ for this stuff. I'll re-spin
and re-submit.

Alan.



2011-02-16 14:12:00

by Jonathan Corbet

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] HID: Documentation for hidraw

On Tue, 15 Feb 2011 23:06:48 -0500
Alan Ott <[email protected]> wrote:

> Documentation/hid/Makefile | 8 ++
> Documentation/hid/hid-example.c | 167 +++++++++++++++++++++++++++++++++++++++

I believe we're trying to get code - especially runnable code - out of the
Documentation tree. Should this go under samples/ or, if it's useful
enough, under tools/?

Thanks,

jon

2011-02-16 04:06:49

by Alan Ott

[permalink] [raw]
Subject: [PATCH v4 2/2] HID: Move hiddev.txt to the new Documentation/HID directory

With the new Documentation/hid directory, it makes sense to have
hiddev.txt here as well.

Signed-off-by: Alan Ott <[email protected]>
---
Documentation/{usb => hid}/hiddev.txt | 0
1 files changed, 0 insertions(+), 0 deletions(-)
rename Documentation/{usb => hid}/hiddev.txt (100%)

diff --git a/Documentation/usb/hiddev.txt b/Documentation/hid/hiddev.txt
similarity index 100%
rename from Documentation/usb/hiddev.txt
rename to Documentation/hid/hiddev.txt
--
1.7.0.4



2011-02-16 04:06:48

by Alan Ott

[permalink] [raw]
Subject: [PATCH v4 1/2] HID: Documentation for hidraw

Documenation for the hidraw driver, with example program.

Signed-off-by: Alan Ott <[email protected]>
---
Documentation/hid/Makefile | 8 ++
Documentation/hid/hid-example.c | 167 +++++++++++++++++++++++++++++++++++++++
Documentation/hid/hidraw.txt | 119 ++++++++++++++++++++++++++++
3 files changed, 294 insertions(+), 0 deletions(-)
create mode 100644 Documentation/hid/Makefile
create mode 100644 Documentation/hid/hid-example.c
create mode 100644 Documentation/hid/hidraw.txt

diff --git a/Documentation/hid/Makefile b/Documentation/hid/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/Documentation/hid/Makefile
@@ -0,0 +1,8 @@
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
+
+# List of programs to build
+hostprogs-y := hid-example
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
diff --git a/Documentation/hid/hid-example.c b/Documentation/hid/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/Documentation/hid/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <[email protected]>
+ * Copyright (c) 2010 Signal 11 Software
+ *
+ * The code may be used by anyone for any purpose,
+ * and can serve as a starting point for developing
+ * applications using hidraw.
+ */
+
+/* Linux */
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/hidraw.h>
+
+/* Unix */
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* C */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+const char *bus_str(int bus);
+
+int main(int argc, char **argv)
+{
+ int fd;
+ int i, res, desc_size = 0;
+ char buf[256];
+ struct hidraw_report_descriptor rpt_desc;
+ struct hidraw_devinfo info;
+
+ /* Open the Device with non-blocking reads. In real life,
+ don't use a hard coded path; use libudev instead. */
+ fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK);
+
+ if (fd < 0) {
+ perror("Unable to open device");
+ return 1;
+ }
+
+ memset(&rpt_desc, 0x0, sizeof(rpt_desc));
+ memset(&info, 0x0, sizeof(info));
+ memset(buf, 0x0, sizeof(buf));
+
+ /* Get Report Descriptor Size */
+ res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
+ if (res < 0)
+ perror("HIDIOCGRDESCSIZE");
+ else
+ printf("Report Descriptor Size: %d\n", desc_size);
+
+ /* Get Report Descriptor */
+ rpt_desc.size = desc_size;
+ res = ioctl(fd, HIDIOCGRDESC, &rpt_desc);
+ if (res < 0) {
+ perror("HIDIOCGRDESC");
+ } else {
+ printf("Report Descriptor:\n");
+ for (i = 0; i < rpt_desc.size; i++)
+ printf("%hhx ", rpt_desc.value[i]);
+ puts("\n");
+ }
+
+ /* Get Raw Name */
+ res = ioctl(fd, HIDIOCGRAWNAME(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWNAME");
+ else
+ printf("Raw Name: %s\n", buf);
+
+ /* Get Physical Location */
+ res = ioctl(fd, HIDIOCGRAWPHYS(256), buf);
+ if (res < 0)
+ perror("HIDIOCGRAWPHYS");
+ else
+ printf("Raw Phys: %s\n", buf);
+
+ /* Get Raw Info */
+ res = ioctl(fd, HIDIOCGRAWINFO, &info);
+ if (res < 0) {
+ perror("HIDIOCGRAWINFO");
+ } else {
+ printf("Raw Info:\n");
+ printf("\tbustype: %d (%s)\n",
+ info.bustype, bus_str(info.bustype));
+ printf("\tvendor: 0x%04hx\n", info.vendor);
+ printf("\tproduct: 0x%04hx\n", info.product);
+ }
+
+ /* Set Feature */
+ buf[0] = 0x9; /* Report Number */
+ buf[1] = 0xff;
+ buf[2] = 0xff;
+ buf[3] = 0xff;
+ res = ioctl(fd, HIDIOCSFEATURE(4), buf);
+ if (res < 0)
+ perror("HIDIOCSFEATURE");
+ else
+ printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
+
+ /* Get Feature */
+ buf[0] = 0x9; /* Report Number */
+ res = ioctl(fd, HIDIOCGFEATURE(256), buf);
+ if (res < 0) {
+ perror("HIDIOCGFEATURE");
+ } else {
+ printf("ioctl HIDIOCGFEATURE returned: %d\n", res);
+ printf("Report data (not containing the report number):\n\t");
+ for (i = 0; i < res; i++)
+ printf("%hhx ", buf[i]);
+ puts("\n");
+ }
+
+ /* Send a Report to the Device */
+ buf[0] = 0x1; /* Report Number */
+ buf[1] = 0x77;
+ res = write(fd, buf, 2);
+ if (res < 0) {
+ printf("Error: %d\n", errno);
+ perror("write");
+ } else {
+ printf("write() wrote %d bytes\n", res);
+ }
+
+ /* Get a report from the device */
+ res = read(fd, buf, 16);
+ if (res < 0) {
+ perror("read");
+ } else {
+ printf("read() read %d bytes:\n\t", res);
+ for (i = 0; i < res; i++)
+ printf("%hhx ", buf[i]);
+ puts("\n");
+ }
+ close(fd);
+ return 0;
+}
+
+const char *
+bus_str(int bus)
+{
+ switch (bus) {
+ case BUS_USB:
+ return "USB";
+ break;
+ case BUS_HIL:
+ return "HIL";
+ break;
+ case BUS_BLUETOOTH:
+ return "Bluetooth";
+ break;
+ case BUS_VIRTUAL:
+ return "Virtual";
+ break;
+ default:
+ return "Other";
+ break;
+ }
+}
diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..2e0d39a
--- /dev/null
+++ b/Documentation/hid/hidraw.txt
@@ -0,0 +1,119 @@
+ HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
+ ==================================================================
+
+The hidraw driver provides a raw interface to USB and Bluetooth Human
+Interface Devices (HIDs). It differs from hiddev in that reports sent and
+received are not parsed by the HID parser, but are sent to and received from
+the device unmodified.
+
+Hidraw should be used if the userspace application knows exactly how to
+communicate with the hardware device, and is able to construct the HID
+reports manually. This is often the case when making userspace drivers for
+custom HID devices.
+
+Hidraw is also useful for communicating with non-conformant HID devices
+which send and receive data in a way that is inconsistent with their report
+descriptors. Because hiddev parses reports which are sent and received
+through it, checking them against the device's report descriptor, such
+communication with these non-conformant devices is impossible using hiddev.
+Hidraw is the only alternative, short of writing a custom kernel driver, for
+these non-conformant devices.
+
+A benefit of hidraw is that its use by userspace applications is independent
+of the underlying hardware type. Currently, Hidraw is implemented for USB
+and Bluetooth. In the future, as new hardware bus types are developed which
+use the HID specification, hidraw will be expanded to add support for these
+new bus types.
+
+Hidraw uses a dynamic major number, meaning that udev should be relied on to
+create hidraw device nodes. Udev will typically create the device nodes
+directly under /dev (eg: /dev/hidraw0). As this location is distribution-
+and udev rule-dependent, applications should use libudev to locate hidraw
+devices attached to the system. There is a tutorial on libudev with a
+working example at:
+ http://www.signal11.us/oss/udev/
+
+The HIDRAW API
+---------------
+
+read()
+-------
+read() will read a queued report received from the HID device. On USB
+devices, the reports read using read() are the reports sent from the device
+on the INTERRUPT IN endpoint. By default, read() will block until there is
+a report available to be read. read() can be made non-blocking, by passing
+the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using
+fcntl().
+
+On a device which uses numbered reports, the first byte of the returned data
+will be the report number; the report data follows, beginning in the second
+byte. For devices which do not use numbered reports, the report data
+will begin at the first byte.
+
+write()
+--------
+The write() function will write a report to the device. For USB devices, if
+the device has an INTERRUPT OUT endpoint, the report will be sent on that
+endpoint. If it does not, the report will be sent over the control endpoint,
+using a SET_REPORT transfer.
+
+The first byte of the buffer passed to write() should be set to the report
+number. If the device does not use numbered reports, the first byte should
+be set to 0. The report data itself should begin at the second byte.
+
+ioctl()
+--------
+Hidraw supports the following ioctls:
+
+HIDIOCGRDESCSIZE: Get Report Descriptor Size
+This ioctl will get the size of the device's report descriptor.
+
+HIDIOCGRDESC: Get Report Descriptor
+This ioctl returns the device's report descriptor using a
+hidraw_report_descriptor struct. Make sure to set the size field of the
+hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE.
+
+HIDIOCGRAWINFO: Get Raw Info
+This ioctl will return a hidraw_devinfo struct containing the bus type, the
+vendor ID (VID), and product ID (PID) of the device. The bus type can be one
+of:
+ BUS_USB
+ BUS_HIL
+ BUS_BLUETOOTH
+ BUS_VIRTUAL
+which are defined in linux/input.h.
+
+HIDIOCGRAWNAME(len): Get Raw Name
+This ioctl returns a string containing the vendor and product strings of
+the device. The returned string is Unicode, UTF-8 encoded.
+
+HIDIOCGRAWPHYS(len): Get Physical Address
+This ioctl returns a string representing the physical address of the device.
+For USB devices, the string contains the physical path to the device (the
+USB controller, hubs, ports, etc). For Bluetooth devices, the string
+contains the hardware (MAC) address of the device.
+
+HIDIOCSFEATURE(len): Send a Feature Report
+This ioctl will send a feature report to the device. Per the HID
+specification, feature reports are always sent using the control endpoint.
+Set the first byte of the supplied buffer to the report number. For devices
+which do not use numbered reports, set the first byte to 0. The report data
+begins in the second byte. Make sure to set len accordingly, to one more
+than the length of the report (to account for the report number).
+
+HIDIOCGFEATURE(len): Get a Feature Report
+This ioctl will request a feature report from the device using the control
+endpoint. The first byte of the supplied buffer should be set to the report
+number of the requested report. For devices which do not use numbered
+reports, set the first byte to 0. The report will be returned starting at
+the first byte of the buffer (ie: the report number is not returned).
+
+Example
+---------
+In this directory, find hid-example.c, which shows examples of read(),
+write(), and all the ioctls for hidraw. The code may be used by anyone for
+any purpose, and can serve as a starting point for developing applications
+using hidraw.
+
+Document by:
+ Alan Ott <[email protected]>, Signal 11 Software
--
1.7.0.4