All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] HID: hidraw Documentation
@ 2011-02-16  4:06 Alan Ott
  2011-02-16  4:06 ` [PATCH v4 1/2] HID: Documentation for hidraw Alan Ott
                   ` (14 more replies)
  0 siblings, 15 replies; 24+ messages in thread
From: Alan Ott @ 2011-02-16  4:06 UTC (permalink / raw)
  To: Randy Dunlap, Alan Ott, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood
  Cc: Alan Ott

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v4 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
@ 2011-02-16  4:06 ` Alan Ott
  2011-02-16 14:12   ` Jonathan Corbet
  2011-02-16  4:06 ` Alan Ott
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Alan Ott @ 2011-02-16  4:06 UTC (permalink / raw)
  To: Randy Dunlap, Alan Ott, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood
  Cc: Alan Ott

Documenation for the hidraw driver, with example program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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 <alan@signal11.us>
+ * 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 <alan@signal11.us>, Signal 11 Software
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v4 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
  2011-02-16  4:06 ` [PATCH v4 1/2] HID: Documentation for hidraw Alan Ott
@ 2011-02-16  4:06 ` Alan Ott
  2011-02-16  4:06   ` Alan Ott
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-02-16  4:06 UTC (permalink / raw)
  To: Randy Dunlap, linux-doc, linux-kernel, jkosina, ospite, linux-input
  Cc: Alan Ott

Documenation for the hidraw driver, with example program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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 <alan@signal11.us>
+ * 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 <alan@signal11.us>, Signal 11 Software
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v4 2/2] HID: Move hiddev.txt to the new Documentation/HID directory
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
@ 2011-02-16  4:06   ` Alan Ott
  2011-02-16  4:06 ` Alan Ott
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-02-16  4:06 UTC (permalink / raw)
  To: Randy Dunlap, Alan Ott, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood
  Cc: Alan Ott

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

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v4 2/2] HID: Move hiddev.txt to the new Documentation/HID directory
@ 2011-02-16  4:06   ` Alan Ott
  0 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-02-16  4:06 UTC (permalink / raw)
  To: Randy Dunlap, linux-doc, linux-kernel, jkosina, ospite, linux-input
  Cc: Alan Ott

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

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v4 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 ` [PATCH v4 1/2] HID: Documentation for hidraw Alan Ott
@ 2011-02-16 14:12   ` Jonathan Corbet
  2011-02-16 19:06     ` Alan Ott
  0 siblings, 1 reply; 24+ messages in thread
From: Jonathan Corbet @ 2011-02-16 14:12 UTC (permalink / raw)
  To: Alan Ott
  Cc: Randy Dunlap, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood

On Tue, 15 Feb 2011 23:06:48 -0500
Alan Ott <alan@signal11.us> 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v4 1/2] HID: Documentation for hidraw
  2011-02-16 14:12   ` Jonathan Corbet
@ 2011-02-16 19:06     ` Alan Ott
  2011-02-16 19:10         ` Jiri Kosina
  2011-02-17  0:56       ` Randy Dunlap
  0 siblings, 2 replies; 24+ messages in thread
From: Alan Ott @ 2011-02-16 19:06 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Randy Dunlap, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood

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.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v4 1/2] HID: Documentation for hidraw
@ 2011-02-16 19:10         ` Jiri Kosina
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Kosina @ 2011-02-16 19:10 UTC (permalink / raw)
  To: Alan Ott
  Cc: Jonathan Corbet, Randy Dunlap, linux-doc, linux-kernel, ospite,
	linux-input, linux-bluetooth, bgood

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.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v4 1/2] HID: Documentation for hidraw
@ 2011-02-16 19:10         ` Jiri Kosina
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Kosina @ 2011-02-16 19:10 UTC (permalink / raw)
  To: Alan Ott
  Cc: Jonathan Corbet, Randy Dunlap, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	ospite-aNJ+ML1ZbiP93QAQaVx+gl6hYfS7NtTn,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
	bgood-mO0wGsvBftXk1uMJSBkQmQ

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.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v4 1/2] HID: Documentation for hidraw
  2011-02-16 19:06     ` Alan Ott
  2011-02-16 19:10         ` Jiri Kosina
@ 2011-02-17  0:56       ` Randy Dunlap
  1 sibling, 0 replies; 24+ messages in thread
From: Randy Dunlap @ 2011-02-17  0:56 UTC (permalink / raw)
  To: Alan Ott
  Cc: Jonathan Corbet, linux-doc, linux-kernel, jkosina, ospite,
	linux-input, linux-bluetooth, bgood

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 <rdunlap@xenotime.net>

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (5 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-21 20:17   ` Randy Dunlap
  2011-03-20  0:29 ` Alan Ott
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina,
	Alan Ott, Jason Wessel, Andrew Morton, Stefani Seibold,
	linux-doc, linux-kernel, linux-input
  Cc: Alan Ott

Sorry I've been slack in getting v5 of this patch out. Because
it's been so long, I'll recap what happened last time:

 * Jon Corbet suggested that the example programs be moved into samples/ .
 * Randy Dunlap indicated his acked-by when this was done.

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

It creates an example program which is now in samples/ with a Kconfig item.

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

This is based on .38+

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

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (6 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` [PATCH v5 1/2] HID: Documentation " Alan Ott
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Sorry I've been slack in getting v5 of this patch out. Because
it's been so long, I'll recap what happened last time:

 * Jon Corbet suggested that the example programs be moved into samples/ .
 * Randy Dunlap indicated his acked-by when this was done.

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

It creates an example program which is now in samples/ with a Kconfig item.

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

This is based on .38+

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

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (3 preceding siblings ...)
  2011-03-20  0:29 ` [PATCH v5 0/2] Documentation and Sample for hidraw Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Sorry I've been slack in getting v5 of this patch out. Because
it's been so long, I'll recap what happened last time:

 * Jon Corbet suggested that the example programs be moved into samples/ .
 * Randy Dunlap indicated his acked-by when this was done.

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

It creates an example program which is now in samples/ with a Kconfig item.

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

This is based on .38+

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

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (4 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Sorry I've been slack in getting v5 of this patch out. Because
it's been so long, I'll recap what happened last time:

 * Jon Corbet suggested that the example programs be moved into samples/ .
 * Randy Dunlap indicated his acked-by when this was done.

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

It creates an example program which is now in samples/ with a Kconfig item.

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

This is based on .38+

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

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (2 preceding siblings ...)
  2011-02-16  4:06   ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Sorry I've been slack in getting v5 of this patch out. Because
it's been so long, I'll recap what happened last time:

 * Jon Corbet suggested that the example programs be moved into samples/ .
 * Randy Dunlap indicated his acked-by when this was done.

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

It creates an example program which is now in samples/ with a Kconfig item.

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

This is based on .38+

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

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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (8 preceding siblings ...)
  2011-03-20  0:29 ` [PATCH v5 1/2] HID: Documentation " Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina,
	Alan Ott, Jason Wessel, Andrew Morton, Stefani Seibold,
	linux-doc, linux-kernel, linux-input
  Cc: Alan Ott

Documenation for the hidraw driver, with sample program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 Documentation/hid/hidraw.txt |  119 ++++++++++++++++++++++++++++++
 samples/Kconfig              |    6 ++
 samples/Makefile             |    2 +-
 samples/hidraw/Makefile      |    8 ++
 samples/hidraw/hid-example.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 301 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/hid/hidraw.txt
 create mode 100644 samples/hidraw/Makefile
 create mode 100644 samples/hidraw/hid-example.c

diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..029e6cb
--- /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 samples/, 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 <alan@signal11.us>, Signal 11 Software
diff --git a/samples/Kconfig b/samples/Kconfig
index e03cf0e..52f4264 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,10 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_HIDRAW
+	tristate "Build simple hidraw example"
+	depends on HIDRAW
+	help
+	  Build an example of how to use hidraw from userspace.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c095..6280817 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/samples/hidraw/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/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/samples/hidraw/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * 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;
+	}
+}
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (10 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Documenation for the hidraw driver, with sample program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 Documentation/hid/hidraw.txt |  119 ++++++++++++++++++++++++++++++
 samples/Kconfig              |    6 ++
 samples/Makefile             |    2 +-
 samples/hidraw/Makefile      |    8 ++
 samples/hidraw/hid-example.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 301 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/hid/hidraw.txt
 create mode 100644 samples/hidraw/Makefile
 create mode 100644 samples/hidraw/hid-example.c

diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..029e6cb
--- /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 samples/, 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 <alan@signal11.us>, Signal 11 Software
diff --git a/samples/Kconfig b/samples/Kconfig
index e03cf0e..52f4264 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,10 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_HIDRAW
+	tristate "Build simple hidraw example"
+	depends on HIDRAW
+	help
+	  Build an example of how to use hidraw from userspace.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c095..6280817 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/samples/hidraw/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/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/samples/hidraw/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * 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;
+	}
+}
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (7 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Documenation for the hidraw driver, with sample program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 Documentation/hid/hidraw.txt |  119 ++++++++++++++++++++++++++++++
 samples/Kconfig              |    6 ++
 samples/Makefile             |    2 +-
 samples/hidraw/Makefile      |    8 ++
 samples/hidraw/hid-example.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 301 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/hid/hidraw.txt
 create mode 100644 samples/hidraw/Makefile
 create mode 100644 samples/hidraw/hid-example.c

diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..029e6cb
--- /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 samples/, 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 <alan@signal11.us>, Signal 11 Software
diff --git a/samples/Kconfig b/samples/Kconfig
index e03cf0e..52f4264 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,10 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_HIDRAW
+	tristate "Build simple hidraw example"
+	depends on HIDRAW
+	help
+	  Build an example of how to use hidraw from userspace.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c095..6280817 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/samples/hidraw/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/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/samples/hidraw/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * 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;
+	}
+}
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (9 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Documenation for the hidraw driver, with sample program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 Documentation/hid/hidraw.txt |  119 ++++++++++++++++++++++++++++++
 samples/Kconfig              |    6 ++
 samples/Makefile             |    2 +-
 samples/hidraw/Makefile      |    8 ++
 samples/hidraw/hid-example.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 301 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/hid/hidraw.txt
 create mode 100644 samples/hidraw/Makefile
 create mode 100644 samples/hidraw/hid-example.c

diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..029e6cb
--- /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 samples/, 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 <alan@signal11.us>, Signal 11 Software
diff --git a/samples/Kconfig b/samples/Kconfig
index e03cf0e..52f4264 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,10 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_HIDRAW
+	tristate "Build simple hidraw example"
+	depends on HIDRAW
+	help
+	  Build an example of how to use hidraw from userspace.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c095..6280817 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/samples/hidraw/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/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/samples/hidraw/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * 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;
+	}
+}
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 1/2] HID: Documentation for hidraw
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (11 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` [PATCH v5 2/2] HID: Move hiddev.txt to the new Documentation/HID directory Alan Ott
  2011-03-20  0:29 ` Alan Ott
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

Documenation for the hidraw driver, with sample program.

Signed-off-by: Alan Ott <alan@signal11.us>
---
 Documentation/hid/hidraw.txt |  119 ++++++++++++++++++++++++++++++
 samples/Kconfig              |    6 ++
 samples/Makefile             |    2 +-
 samples/hidraw/Makefile      |    8 ++
 samples/hidraw/hid-example.c |  167 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 301 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/hid/hidraw.txt
 create mode 100644 samples/hidraw/Makefile
 create mode 100644 samples/hidraw/hid-example.c

diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt
new file mode 100644
index 0000000..029e6cb
--- /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 samples/, 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 <alan@signal11.us>, Signal 11 Software
diff --git a/samples/Kconfig b/samples/Kconfig
index e03cf0e..52f4264 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,10 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_HIDRAW
+	tristate "Build simple hidraw example"
+	depends on HIDRAW
+	help
+	  Build an example of how to use hidraw from userspace.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index f26c095..6280817 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/
diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile
new file mode 100644
index 0000000..7811cb0
--- /dev/null
+++ b/samples/hidraw/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/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c
new file mode 100644
index 0000000..40e3d62
--- /dev/null
+++ b/samples/hidraw/hid-example.c
@@ -0,0 +1,167 @@
+/*
+ * Hidraw Userspace Example
+ *
+ * Copyright (c) 2010 Alan Ott <alan@signal11.us>
+ * 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;
+	}
+}
-- 
1.7.0.4



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v5 2/2] HID: Move hiddev.txt to the new Documentation/HID directory
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (13 preceding siblings ...)
  2011-03-20  0:29 ` [PATCH v5 2/2] HID: Move hiddev.txt to the new Documentation/HID directory Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina,
	Alan Ott, Jason Wessel, Andrew Morton, Stefani Seibold,
	linux-doc, linux-kernel, linux-input
  Cc: Alan Ott

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

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v5 2/2] HID: Move hiddev.txt to the new Documentation/HID directory
  2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
                   ` (12 preceding siblings ...)
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-20  0:29 ` Alan Ott
  2011-03-20  0:29 ` Alan Ott
  14 siblings, 0 replies; 24+ messages in thread
From: Alan Ott @ 2011-03-20  0:29 UTC (permalink / raw)
  To: Randy Dunlap, Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason
  Cc: Alan Ott

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

Signed-off-by: Alan Ott <alan@signal11.us>
---
 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



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-03-20  0:29 ` Alan Ott
@ 2011-03-21 20:17   ` Randy Dunlap
  2011-03-22 10:44     ` Jiri Kosina
  0 siblings, 1 reply; 24+ messages in thread
From: Randy Dunlap @ 2011-03-21 20:17 UTC (permalink / raw)
  To: Alan Ott
  Cc: Jonathan Corbet, Antonio Ospite, Jiri Kosina, Jason Wessel,
	Andrew Morton, Stefani Seibold, linux-doc, linux-kernel,
	linux-input

On Sat, 19 Mar 2011 20:29:43 -0400 Alan Ott wrote:

> Sorry I've been slack in getting v5 of this patch out. Because
> it's been so long, I'll recap what happened last time:
> 
>  * Jon Corbet suggested that the example programs be moved into samples/ .
>  * Randy Dunlap indicated his acked-by when this was done.
> 
> These patches add hidraw.txt to a new Documentation/hid/ directory.
> 
> It creates an example program which is now in samples/ with a Kconfig item.
> 
> The existing hiddev.txt has been moved from Documentation/usb/ to
> Documentation/hid/

Jiri,

I suppose that you will merge these patches?
or did you want me to do it?


> This is based on .38+
> 
> Alan Ott (2):
>   HID: Documentation for hidraw
>   HID: Move hiddev.txt to the new Documentation/HID directory
> 
>  Documentation/{usb => hid}/hiddev.txt |    0
>  Documentation/hid/hidraw.txt          |  119 +++++++++++++++++++++++
>  samples/Kconfig                       |    6 +
>  samples/Makefile                      |    2 +-
>  samples/hidraw/Makefile               |    8 ++
>  samples/hidraw/hid-example.c          |  167 +++++++++++++++++++++++++++++++++
>  6 files changed, 301 insertions(+), 1 deletions(-)
>  rename Documentation/{usb => hid}/hiddev.txt (100%)
>  create mode 100644 Documentation/hid/hidraw.txt
>  create mode 100644 samples/hidraw/Makefile
>  create mode 100644 samples/hidraw/hid-example.c
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v5 0/2] Documentation and Sample for hidraw
  2011-03-21 20:17   ` Randy Dunlap
@ 2011-03-22 10:44     ` Jiri Kosina
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Kosina @ 2011-03-22 10:44 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Alan Ott, Jonathan Corbet, Antonio Ospite, Jason Wessel,
	Andrew Morton, Stefani Seibold, linux-doc, linux-kernel,
	linux-input

On Mon, 21 Mar 2011, Randy Dunlap wrote:

> > Sorry I've been slack in getting v5 of this patch out. Because
> > it's been so long, I'll recap what happened last time:
> > 
> >  * Jon Corbet suggested that the example programs be moved into samples/ .
> >  * Randy Dunlap indicated his acked-by when this was done.
> > 
> > These patches add hidraw.txt to a new Documentation/hid/ directory.
> > 
> > It creates an example program which is now in samples/ with a Kconfig item.
> > 
> > The existing hiddev.txt has been moved from Documentation/usb/ to
> > Documentation/hid/
> 
> Jiri,
> 
> I suppose that you will merge these patches?
> or did you want me to do it?

Yeah, I am taking it through hid.git tree. Thanks!

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2011-03-22 10:44 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-16  4:06 [PATCH v4 0/2] HID: hidraw Documentation Alan Ott
2011-02-16  4:06 ` [PATCH v4 1/2] HID: Documentation for hidraw Alan Ott
2011-02-16 14:12   ` Jonathan Corbet
2011-02-16 19:06     ` Alan Ott
2011-02-16 19:10       ` Jiri Kosina
2011-02-16 19:10         ` Jiri Kosina
2011-02-17  0:56       ` Randy Dunlap
2011-02-16  4:06 ` Alan Ott
2011-02-16  4:06 ` [PATCH v4 2/2] HID: Move hiddev.txt to the new Documentation/HID directory Alan Ott
2011-02-16  4:06   ` Alan Ott
2011-03-20  0:29 ` [PATCH v5 0/2] Documentation and Sample for hidraw Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-21 20:17   ` Randy Dunlap
2011-03-22 10:44     ` Jiri Kosina
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` [PATCH v5 1/2] HID: Documentation " Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` Alan Ott
2011-03-20  0:29 ` [PATCH v5 2/2] HID: Move hiddev.txt to the new Documentation/HID directory Alan Ott
2011-03-20  0:29 ` Alan Ott

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.