[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#839616: linux: add support for chaoskey



Source: linux
Version: 3.16.36-1+deb8u1
Severity: important
Tags: patch
Control: fixed -1 4.1.1-1~exp1
User: debian-admin@lists.debian.org
Usertags: needed-by-DSA-Team

Hi,

the attached patch adds the chaoskey driver
(http://altusmetrum.org/ChaosKey/).  I've smoke tested it in qemu (with
usb passthrough).  This should include all patches touching
drivers/usb/misc/chaoskey.c since its introduction, with the only diff
from the upstream patches being context in Kconfig; there's an extra
patch to deal with the absence of
0f734e6e768b4b66737b3d3e13f1769a12ecff86 in 3.16.

Applies on top of 3.16.36-1+deb8u1, because the tip of the jessie branch
doesn't seem to build.

Cheers,
Julien
>From e9060d88141e2978d4acf31716a0502534fdf7b5 Mon Sep 17 00:00:00 2001
From: Julien Cristau <jcristau@debian.org>
Date: Sun, 2 Oct 2016 18:32:04 +0200
Subject: [PATCH] Add chaoskey driver, backported from 4.8.

---
 debian/changelog                                   |   7 +
 debian/config/config                               |   1 +
 .../chaoskey/USB-chaoskey-read-offset-bug.patch    |  31 +
 .../chaoskey/chaoskey-3.16-no-hwrng-quality.patch  |  28 +
 ...key-Add-support-for-Araneus-Alea-I-USB-RN.patch |  64 +++
 ...key-Fix-URB-warning-due-to-timeout-on-Ale.patch | 105 ++++
 ...river-for-Altus-Metrum-ChaosKey-device-v2.patch | 627 +++++++++++++++++++++
 .../usb-Fix-warnings-in-chaoskey-driver.patch      |  57 ++
 ...misc-chaoskey-Cleanup-probe-failure-paths.patch | 103 ++++
 ...aoskey-introduce-an-URB-for-asynchronous-.patch | 187 ++++++
 ...b-misc-fix-chaoskey-build-needs-HW_RANDOM.patch |  33 ++
 debian/patches/series                              |  11 +
 12 files changed, 1254 insertions(+)
 create mode 100644 debian/patches/features/all/chaoskey/USB-chaoskey-read-offset-bug.patch
 create mode 100644 debian/patches/features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
 create mode 100644 debian/patches/features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch
 create mode 100644 debian/patches/features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch
 create mode 100644 debian/patches/features/all/chaoskey/usb-Add-driver-for-Altus-Metrum-ChaosKey-device-v2.patch
 create mode 100644 debian/patches/features/all/chaoskey/usb-Fix-warnings-in-chaoskey-driver.patch
 create mode 100644 debian/patches/features/all/chaoskey/usb-misc-chaoskey-Cleanup-probe-failure-paths.patch
 create mode 100644 debian/patches/features/all/chaoskey/usb-misc-chaoskey-introduce-an-URB-for-asynchronous-.patch
 create mode 100644 debian/patches/features/all/chaoskey/usb-misc-fix-chaoskey-build-needs-HW_RANDOM.patch

diff --git a/debian/changelog b/debian/changelog
index dcf2adc..5cdf3b2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+linux (3.16.36-2) UNRELEASED; urgency=medium
+
+  [ Julien Cristau ]
+  * Add chaoskey driver, backported from 4.8.
+
+ -- Aurelien Jarno <aurel32@debian.org>  Tue, 09 Aug 2016 22:05:53 +0200
+
 linux (3.16.36-1+deb8u1) jessie-security; urgency=high
 
   [ Ben Hutchings ]
diff --git a/debian/config/config b/debian/config/config
index 0b70520..cc363ae 100644
--- a/debian/config/config
+++ b/debian/config/config
@@ -4107,6 +4107,7 @@ CONFIG_USB_EHSET_TEST_FIXTURE=m
 CONFIG_USB_ISIGHTFW=m
 CONFIG_USB_YUREX=m
 # CONFIG_USB_HSIC_USB3503 is not set
+CONFIG_USB_CHAOSKEY=m
 
 ##
 ## file: drivers/usb/misc/sisusbvga/Kconfig
diff --git a/debian/patches/features/all/chaoskey/USB-chaoskey-read-offset-bug.patch b/debian/patches/features/all/chaoskey/USB-chaoskey-read-offset-bug.patch
new file mode 100644
index 0000000..9ff8e32
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/USB-chaoskey-read-offset-bug.patch
@@ -0,0 +1,31 @@
+From 1d5c47f555c5ae050fad22e4a99f88856cae5d05 Mon Sep 17 00:00:00 2001
+From: Alexander Inyukhin <shurick@sectorb.msk.ru>
+Date: Sat, 26 Sep 2015 15:24:21 +0300
+Subject: [PATCH] USB: chaoskey read offset bug
+
+Rng reads in chaoskey driver could return the same data under
+the certain conditions.
+
+Signed-off-by: Alexander Inyukhin <shurick@sectorb.msk.ru>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/chaoskey.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 3ad5d19..23c7948 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -472,7 +472,7 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data,
+ 	if (this_time > max)
+ 		this_time = max;
+ 
+-	memcpy(data, dev->buf, this_time);
++	memcpy(data, dev->buf + dev->used, this_time);
+ 
+ 	dev->used += this_time;
+ 
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch b/debian/patches/features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
new file mode 100644
index 0000000..b20fdb0
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
@@ -0,0 +1,28 @@
+From: Julien Cristau <jcristau@debian.org>
+Date: Sun, 02 Oct 2016 17:52:02 +0000
+Subject: [PATCH] hwrng: chaoskey - don't set quality field
+
+struct hwrng doesn't have that field in 3.16.
+
+--- a/drivers/usb/misc/chaoskey.c	2016-10-02 17:01:56.419883204 +0000
++++ b/drivers/usb/misc/chaoskey.c	2016-10-02 17:50:44.605990596 +0000
+@@ -216,19 +216,6 @@
+ 	dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
+ 	dev->hwrng.read = chaoskey_rng_read;
+ 
+-	/* Set the 'quality' metric.  Quality is measured in units of
+-	 * 1/1024's of a bit ("mills"). This should be set to 1024,
+-	 * but there is a bug in the hwrng core which masks it with
+-	 * 1023.
+-	 *
+-	 * The patch that has been merged to the crypto development
+-	 * tree for that bug limits the value to 1024 at most, so by
+-	 * setting this to 1024 + 1023, we get 1023 before the fix is
+-	 * merged and 1024 afterwards. We'll patch this driver once
+-	 * both bits of code are in the same tree.
+-	 */
+-	dev->hwrng.quality = 1024 + 1023;
+-
+ 	dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0);
+ 	if (!dev->hwrng_registered)
+ 		usb_err(interface, "Unable to register with hwrng");
diff --git a/debian/patches/features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch b/debian/patches/features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch
new file mode 100644
index 0000000..2d8afb8
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch
@@ -0,0 +1,64 @@
+From d3ede2dba3d800912523838a6db35d562e042101 Mon Sep 17 00:00:00 2001
+From: Bob Ham <bob.ham@collabora.com>
+Date: Fri, 3 Jun 2016 12:13:07 +0100
+Subject: [PATCH] hwrng: chaoskey - Add support for Araneus Alea I USB RNG
+
+Adds support for the Araneus Alea I USB hardware Random Number
+Generator which is interfaced with in exactly the same way as the
+Altus Metrum ChaosKey.  We just add the appropriate device ID and
+modify the config help text.
+
+Signed-off-by: Bob Ham <bob.ham@collabora.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/usb/misc/Kconfig    | 11 ++++++-----
+ drivers/usb/misc/chaoskey.c |  4 ++++
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+index e9e5ae5..6e70597 100644
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -260,11 +260,12 @@ config USB_CHAOSKEY
+ 	tristate "ChaosKey random number generator driver support"
+ 	depends on HW_RANDOM
+ 	help
+-	  Say Y here if you want to connect an AltusMetrum ChaosKey to
+-	  your computer's USB port. The ChaosKey is a hardware random
+-	  number generator which hooks into the kernel entropy pool to
+-	  ensure a large supply of entropy for /dev/random and
+-	  /dev/urandom and also provides direct access via /dev/chaoskeyX
++	  Say Y here if you want to connect an AltusMetrum ChaosKey or
++	  Araneus Alea I to your computer's USB port. These devices
++	  are hardware random number generators which hook into the
++	  kernel entropy pool to ensure a large supply of entropy for
++	  /dev/random and /dev/urandom and also provides direct access
++	  via /dev/chaoskeyX
+ 
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called chaoskey.
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 76350e4..9aef46b 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -55,6 +55,9 @@ MODULE_LICENSE("GPL");
+ #define CHAOSKEY_VENDOR_ID	0x1d50	/* OpenMoko */
+ #define CHAOSKEY_PRODUCT_ID	0x60c6	/* ChaosKey */
+ 
++#define ALEA_VENDOR_ID		0x12d8	/* Araneus */
++#define ALEA_PRODUCT_ID		0x0001	/* Alea I */
++
+ #define CHAOSKEY_BUF_LEN	64	/* max size of USB full speed packet */
+ 
+ #define NAK_TIMEOUT (HZ)		/* stall/wait timeout for device */
+@@ -69,6 +72,7 @@ MODULE_LICENSE("GPL");
+ 
+ static const struct usb_device_id chaoskey_table[] = {
+ 	{ USB_DEVICE(CHAOSKEY_VENDOR_ID, CHAOSKEY_PRODUCT_ID) },
++	{ USB_DEVICE(ALEA_VENDOR_ID, ALEA_PRODUCT_ID) },
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(usb, chaoskey_table);
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch b/debian/patches/features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch
new file mode 100644
index 0000000..bfe99aa
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch
@@ -0,0 +1,105 @@
+From e4a886e811cd07dd5c6f389eae4d35870ec2a483 Mon Sep 17 00:00:00 2001
+From: Bob Ham <bob.ham@collabora.com>
+Date: Fri, 3 Jun 2016 12:13:08 +0100
+Subject: [PATCH] hwrng: chaoskey - Fix URB warning due to timeout on Alea
+
+The first read on an Alea takes about 1.8 seconds, more than the
+timeout value waiting for the read.  As a consequence, later URB reuse
+causes the warning given below.  To avoid this, we increase the wait
+time for the first read on the Alea.
+
+[   78.293247] WARNING: CPU: 3 PID: 1892 at drivers/usb/core/urb.c:338 usb_submit_urb+0x2b4/0x580 [usbcore]
+[   78.293250] URB ffff8802135be3c0 submitted while active
+[   78.293252] Modules linked in: chaoskey(+) rng_core rfcomm binfmt_misc bnep cfg80211 nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc bridge stp llc tun snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic iTCO_wdt iTCO_vendor_support nls_utf8 nls_cp437 vfat fat intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel efi_pstore kvm irqbypass pcspkr btusb btrtl btbcm btintel uvcvideo joydev bluetooth videobuf2_vmalloc videobuf2_memops efivars videobuf2_v4l2 serio_raw i2c_i801 videobuf2_core videodev cdc_mbim media lpc_ich shpchp mfd_core cdc_ncm usbnet mii cdc_wdm cdc_acm evdev snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core i915 snd_pcm snd_timer i2c_algo_bit drm_kms_helper wmi thinkpad_acpi drm nvram mei_me mei snd soundcore rfkill ac battery i2c_core
+[   78.293335]  video button tpm_tis tpm fuse parport_pc ppdev lp parport autofs4 ext4 crc16 jbd2 mbcache algif_skcipher af_alg hid_generic usbhid hid dm_crypt dm_mod sg sr_mod cdrom sd_mod crct10dif_pclmul crc32_pclmul crc32c_intel jitterentropy_rng sha256_generic hmac drbg aesni_intel xhci_pci aes_x86_64 ahci glue_helper xhci_hcd ehci_pci lrw libahci gf128mul ablk_helper cryptd libata sdhci_pci psmouse sdhci scsi_mod ehci_hcd mmc_core usbcore usb_common thermal
+[   78.293402] CPU: 3 PID: 1892 Comm: hwrng Not tainted 4.7.0-rc1-linux-14+ #16
+[   78.293405] Hardware name: LENOVO 232577G/232577G, BIOS G2ET92WW (2.52 ) 02/22/2013
+[   78.293408]  0000000000000000 ffffffff812dfa0f ffff8801fa5b3d68 0000000000000000
+[   78.293413]  ffffffff81072224 ffff8802135be3c0 ffff8801fa5b3db8 ffff880212e44210
+[   78.293418]  0000000000000040 ffff880209fb32c0 ffff880212e44200 ffffffff8107228f
+[   78.293422] Call Trace:
+[   78.293432]  [<ffffffff812dfa0f>] ? dump_stack+0x5c/0x7d
+[   78.293437]  [<ffffffff81072224>] ? __warn+0xc4/0xe0
+[   78.293441]  [<ffffffff8107228f>] ? warn_slowpath_fmt+0x4f/0x60
+[   78.293451]  [<ffffffff810a46a2>] ? enqueue_task_fair+0xcd2/0x1260
+[   78.293463]  [<ffffffffa001ec54>] ? usb_submit_urb+0x2b4/0x580 [usbcore]
+[   78.293474]  [<ffffffff8140c2e5>] ? __pm_runtime_resume+0x55/0x70
+[   78.293484]  [<ffffffffa0825212>] ? _chaoskey_fill+0x132/0x250 [chaoskey]
+[   78.293485] usbcore: registered new interface driver chaoskey
+[   78.293493]  [<ffffffff810aed50>] ? wait_woken+0x90/0x90
+[   78.293500]  [<ffffffffa06448c0>] ? devm_hwrng_register+0x80/0x80 [rng_core]
+[   78.293505]  [<ffffffffa0825907>] ? chaoskey_rng_read+0x127/0x140 [chaoskey]
+[   78.293511]  [<ffffffffa06448c0>] ? devm_hwrng_register+0x80/0x80 [rng_core]
+[   78.293515]  [<ffffffffa064492e>] ? hwrng_fillfn+0x6e/0x120 [rng_core]
+[   78.293520]  [<ffffffff8108fb5f>] ? kthread+0xcf/0xf0
+[   78.293529]  [<ffffffff81596d5f>] ? ret_from_fork+0x1f/0x40
+[   78.293535]  [<ffffffff8108fa90>] ? kthread_park+0x50/0x50
+
+Signed-off-by: Bob Ham <bob.ham@collabora.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/usb/misc/chaoskey.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 9aef46b..6ddd08a 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -60,7 +60,8 @@ MODULE_LICENSE("GPL");
+ 
+ #define CHAOSKEY_BUF_LEN	64	/* max size of USB full speed packet */
+ 
+-#define NAK_TIMEOUT (HZ)		/* stall/wait timeout for device */
++#define NAK_TIMEOUT (HZ)		/* normal stall/wait timeout */
++#define ALEA_FIRST_TIMEOUT (HZ*3)	/* first stall/wait timeout for Alea */
+ 
+ #ifdef CONFIG_USB_DYNAMIC_MINORS
+ #define USB_CHAOSKEY_MINOR_BASE 0
+@@ -88,6 +89,7 @@ struct chaoskey {
+ 	int open;			/* open count */
+ 	bool present;			/* device not disconnected */
+ 	bool reading;			/* ongoing IO */
++	bool reads_started;		/* track first read for Alea */
+ 	int size;			/* size of buf */
+ 	int valid;			/* bytes of buf read */
+ 	int used;			/* bytes of buf consumed */
+@@ -192,6 +194,9 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 
+ 	dev->in_ep = in_ep;
+ 
++	if (udev->descriptor.idVendor != ALEA_VENDOR_ID)
++		dev->reads_started = 1;
++
+ 	dev->size = size;
+ 	dev->present = 1;
+ 
+@@ -361,6 +366,7 @@ static int _chaoskey_fill(struct chaoskey *dev)
+ {
+ 	DEFINE_WAIT(wait);
+ 	int result;
++	bool started;
+ 
+ 	usb_dbg(dev->interface, "fill");
+ 
+@@ -393,10 +399,17 @@ static int _chaoskey_fill(struct chaoskey *dev)
+ 		goto out;
+ 	}
+ 
++	/* The first read on the Alea takes a little under 2 seconds.
++	 * Reads after the first read take only a few microseconds
++	 * though.  Presumably the entropy-generating circuit needs
++	 * time to ramp up.  So, we wait longer on the first read.
++	 */
++	started = dev->reads_started;
++	dev->reads_started = true;
+ 	result = wait_event_interruptible_timeout(
+ 		dev->wait_q,
+ 		!dev->reading,
+-		NAK_TIMEOUT);
++		(started ? NAK_TIMEOUT : ALEA_FIRST_TIMEOUT) );
+ 
+ 	if (result < 0)
+ 		goto out;
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/usb-Add-driver-for-Altus-Metrum-ChaosKey-device-v2.patch b/debian/patches/features/all/chaoskey/usb-Add-driver-for-Altus-Metrum-ChaosKey-device-v2.patch
new file mode 100644
index 0000000..c618084
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/usb-Add-driver-for-Altus-Metrum-ChaosKey-device-v2.patch
@@ -0,0 +1,627 @@
+From 66e3e591891da9899a8990792da080432531ffd4 Mon Sep 17 00:00:00 2001
+From: Keith Packard <keithp@keithp.com>
+Date: Thu, 19 Mar 2015 20:36:49 -0700
+Subject: [PATCH] usb: Add driver for Altus Metrum ChaosKey device (v2)
+
+This is a hardware random number generator. The driver provides both a
+/dev/chaoskeyX entry and hooks the entropy source up to the kernel
+hwrng interface. More information about the device can be found at
+http://chaoskey.org
+
+The USB ID for ChaosKey was allocated from the OpenMoko USB vendor
+space and is visible as 'USBtrng' here:
+
+http://wiki.openmoko.org/wiki/USB_Product_IDs
+
+v2: Respond to review from Oliver Neukum <oneukum@suse.de>
+
+ * Delete extensive debug infrastructure and replace it with calls to
+   dev_dbg.
+
+ * Allocate I/O buffer separately from device structure to obey
+   requirements for non-coherant architectures.
+
+ * Initialize mutexes before registering device to ensure that open
+   cannot be invoked before the device is ready to proceed.
+
+ * Return number of bytes read instead of -EINTR when partial read
+   operation is aborted due to a signal.
+
+ * Make sure device mutex is unlocked in read error paths.
+
+ * Add MAINTAINERS entry for the driver
+
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Cc: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS                 |   6 +
+ drivers/usb/misc/Kconfig    |  12 +
+ drivers/usb/misc/Makefile   |   1 +
+ drivers/usb/misc/chaoskey.c | 530 ++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 549 insertions(+)
+ create mode 100644 drivers/usb/misc/chaoskey.c
+
+Index: linux/MAINTAINERS
+===================================================================
+--- linux.orig/MAINTAINERS
++++ linux/MAINTAINERS
+@@ -9414,6 +9414,12 @@ S:	Maintained
+ F:	drivers/net/usb/cdc_*.c
+ F:	include/uapi/linux/usb/cdc.h
+ 
++USB CHAOSKEY DRIVER
++M:	Keith Packard <keithp@keithp.com>
++L:	linux-usb@vger.kernel.org
++S:	Maintained
++F:	drivers/usb/misc/chaoskey.c
++
+ USB CYPRESS C67X00 DRIVER
+ M:	Peter Korsgaard <jacmet@sunsite.dk>
+ L:	linux-usb@vger.kernel.org
+Index: linux/drivers/usb/misc/Kconfig
+===================================================================
+--- linux.orig/drivers/usb/misc/Kconfig
++++ linux/drivers/usb/misc/Kconfig
+@@ -248,3 +248,15 @@ config USB_HSIC_USB3503
+        select REGMAP_I2C
+        help
+          This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver.
++
++config USB_CHAOSKEY
++	tristate "ChaosKey random number generator driver support"
++	help
++	  Say Y here if you want to connect an AltusMetrum ChaosKey to
++	  your computer's USB port. The ChaosKey is a hardware random
++	  number generator which hooks into the kernel entropy pool to
++	  ensure a large supply of entropy for /dev/random and
++	  /dev/urandom and also provides direct access via /dev/chaoskeyX
++
++	  To compile this driver as a module, choose M here: the
++	  module will be called chaoskey.
+Index: linux/drivers/usb/misc/Makefile
+===================================================================
+--- linux.orig/drivers/usb/misc/Makefile
++++ linux/drivers/usb/misc/Makefile
+@@ -25,5 +25,6 @@ obj-$(CONFIG_USB_USS720)		+= uss720.o
+ obj-$(CONFIG_USB_SEVSEG)		+= usbsevseg.o
+ obj-$(CONFIG_USB_YUREX)			+= yurex.o
+ obj-$(CONFIG_USB_HSIC_USB3503)		+= usb3503.o
++obj-$(CONFIG_USB_CHAOSKEY)		+= chaoskey.o
+ 
+ obj-$(CONFIG_USB_SISUSBVGA)		+= sisusbvga/
+Index: linux/drivers/usb/misc/chaoskey.c
+===================================================================
+--- /dev/null
++++ linux/drivers/usb/misc/chaoskey.c
+@@ -0,0 +1,530 @@
++/*
++ * chaoskey - driver for ChaosKey device from Altus Metrum.
++ *
++ * This device provides true random numbers using a noise source based
++ * on a reverse-biased p-n junction in avalanche breakdown. More
++ * details can be found at http://chaoskey.org
++ *
++ * The driver connects to the kernel hardware RNG interface to provide
++ * entropy for /dev/random and other kernel activities. It also offers
++ * a separate /dev/ entry to allow for direct access to the random
++ * bit stream.
++ *
++ * Copyright © 2015 Keith Packard <keithp@keithp.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
++ * General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/usb.h>
++#include <linux/wait.h>
++#include <linux/hw_random.h>
++
++static struct usb_driver chaoskey_driver;
++static struct usb_class_driver chaoskey_class;
++static int chaoskey_rng_read(struct hwrng *rng, void *data,
++			     size_t max, bool wait);
++
++#define usb_dbg(usb_if, format, arg...) \
++	dev_dbg(&(usb_if)->dev, format, ## arg)
++
++#define usb_err(usb_if, format, arg...) \
++	dev_err(&(usb_if)->dev, format, ## arg)
++
++/* Version Information */
++#define DRIVER_VERSION	"v0.1"
++#define DRIVER_AUTHOR	"Keith Packard, keithp@keithp.com"
++#define DRIVER_DESC	"Altus Metrum ChaosKey driver"
++#define DRIVER_SHORT	"chaoskey"
++
++MODULE_VERSION(DRIVER_VERSION);
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_LICENSE("GPL");
++
++#define CHAOSKEY_VENDOR_ID	0x1d50	/* OpenMoko */
++#define CHAOSKEY_PRODUCT_ID	0x60c6	/* ChaosKey */
++
++#define CHAOSKEY_BUF_LEN	64	/* max size of USB full speed packet */
++
++#define NAK_TIMEOUT (HZ)		/* stall/wait timeout for device */
++
++#ifdef CONFIG_USB_DYNAMIC_MINORS
++#define USB_CHAOSKEY_MINOR_BASE 0
++#else
++
++/* IOWARRIOR_MINOR_BASE + 16, not official yet */
++#define USB_CHAOSKEY_MINOR_BASE 224
++#endif
++
++static const struct usb_device_id chaoskey_table[] = {
++	{ USB_DEVICE(CHAOSKEY_VENDOR_ID, CHAOSKEY_PRODUCT_ID) },
++	{ },
++};
++MODULE_DEVICE_TABLE(usb, chaoskey_table);
++
++/* Driver-local specific stuff */
++struct chaoskey {
++	struct usb_interface *interface;
++	char in_ep;
++	struct mutex lock;
++	struct mutex rng_lock;
++	int open;			/* open count */
++	int present;			/* device not disconnected */
++	int size;			/* size of buf */
++	int valid;			/* bytes of buf read */
++	int used;			/* bytes of buf consumed */
++	char *name;			/* product + serial */
++	struct hwrng hwrng;		/* Embedded struct for hwrng */
++	int hwrng_registered;		/* registered with hwrng API */
++	wait_queue_head_t wait_q;	/* for timeouts */
++	char *buf;
++};
++
++static void chaoskey_free(struct chaoskey *dev)
++{
++	usb_dbg(dev->interface, "free");
++	kfree(dev->name);
++	kfree(dev->buf);
++	kfree(dev);
++}
++
++static int chaoskey_probe(struct usb_interface *interface,
++			  const struct usb_device_id *id)
++{
++	struct usb_device *udev = interface_to_usbdev(interface);
++	struct usb_host_interface *altsetting = interface->cur_altsetting;
++	int i;
++	int in_ep = -1;
++	struct chaoskey *dev;
++	int result;
++	int size;
++
++	usb_dbg(interface, "probe %s-%s", udev->product, udev->serial);
++
++	/* Find the first bulk IN endpoint and its packet size */
++	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
++		if (usb_endpoint_is_bulk_in(&altsetting->endpoint[i].desc)) {
++			in_ep = altsetting->endpoint[i].desc.bEndpointAddress;
++			size = altsetting->endpoint[i].desc.wMaxPacketSize;
++			break;
++		}
++	}
++
++	/* Validate endpoint and size */
++	if (in_ep == -1) {
++		usb_dbg(interface, "no IN endpoint found");
++		return -ENODEV;
++	}
++	if (size <= 0) {
++		usb_dbg(interface, "invalid size (%d)", size);
++		return -ENODEV;
++	}
++
++	if (size > CHAOSKEY_BUF_LEN) {
++		usb_dbg(interface, "size reduced from %d to %d\n",
++			size, CHAOSKEY_BUF_LEN);
++		size = CHAOSKEY_BUF_LEN;
++	}
++
++	/* Looks good, allocate and initialize */
++
++	dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL);
++
++	if (dev == NULL)
++		return -ENOMEM;
++
++	dev->buf = kmalloc(size, GFP_KERNEL);
++
++	if (dev->buf == NULL) {
++		kfree(dev);
++		return -ENOMEM;
++	}
++
++	/* Construct a name using the product and serial values. Each
++	 * device needs a unique name for the hwrng code
++	 */
++
++	if (udev->product && udev->serial) {
++		dev->name = kmalloc(strlen(udev->product) + 1 +
++				    strlen(udev->serial) + 1, GFP_KERNEL);
++		if (dev->name == NULL) {
++			kfree(dev->buf);
++			kfree(dev);
++			return -ENOMEM;
++		}
++
++		strcpy(dev->name, udev->product);
++		strcat(dev->name, "-");
++		strcat(dev->name, udev->serial);
++	}
++
++	dev->interface = interface;
++
++	dev->in_ep = in_ep;
++
++	dev->size = size;
++	dev->present = 1;
++
++	init_waitqueue_head(&dev->wait_q);
++
++	mutex_init(&dev->lock);
++	mutex_init(&dev->rng_lock);
++
++	usb_set_intfdata(interface, dev);
++
++	result = usb_register_dev(interface, &chaoskey_class);
++	if (result) {
++		usb_err(interface, "Unable to allocate minor number.");
++		usb_set_intfdata(interface, NULL);
++		chaoskey_free(dev);
++		return result;
++	}
++
++	dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
++	dev->hwrng.read = chaoskey_rng_read;
++
++	/* Set the 'quality' metric.  Quality is measured in units of
++	 * 1/1024's of a bit ("mills"). This should be set to 1024,
++	 * but there is a bug in the hwrng core which masks it with
++	 * 1023.
++	 *
++	 * The patch that has been merged to the crypto development
++	 * tree for that bug limits the value to 1024 at most, so by
++	 * setting this to 1024 + 1023, we get 1023 before the fix is
++	 * merged and 1024 afterwards. We'll patch this driver once
++	 * both bits of code are in the same tree.
++	 */
++	dev->hwrng.quality = 1024 + 1023;
++
++	dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0);
++	if (!dev->hwrng_registered)
++		usb_err(interface, "Unable to register with hwrng");
++
++	usb_enable_autosuspend(udev);
++
++	usb_dbg(interface, "chaoskey probe success, size %d", dev->size);
++	return 0;
++}
++
++static void chaoskey_disconnect(struct usb_interface *interface)
++{
++	struct chaoskey	*dev;
++
++	usb_dbg(interface, "disconnect");
++	dev = usb_get_intfdata(interface);
++	if (!dev) {
++		usb_dbg(interface, "disconnect failed - no dev");
++		return;
++	}
++
++	if (dev->hwrng_registered)
++		hwrng_unregister(&dev->hwrng);
++
++	usb_deregister_dev(interface, &chaoskey_class);
++
++	usb_set_intfdata(interface, NULL);
++	mutex_lock(&dev->lock);
++
++	dev->present = 0;
++
++	if (!dev->open) {
++		mutex_unlock(&dev->lock);
++		chaoskey_free(dev);
++	} else
++		mutex_unlock(&dev->lock);
++
++	usb_dbg(interface, "disconnect done");
++}
++
++static int chaoskey_open(struct inode *inode, struct file *file)
++{
++	struct chaoskey *dev;
++	struct usb_interface *interface;
++
++	/* get the interface from minor number and driver information */
++	interface = usb_find_interface(&chaoskey_driver, iminor(inode));
++	if (!interface)
++		return -ENODEV;
++
++	usb_dbg(interface, "open");
++
++	dev = usb_get_intfdata(interface);
++	if (!dev) {
++		usb_dbg(interface, "open (dev)");
++		return -ENODEV;
++	}
++
++	file->private_data = dev;
++	mutex_lock(&dev->lock);
++	++dev->open;
++	mutex_unlock(&dev->lock);
++
++	usb_dbg(interface, "open success");
++	return 0;
++}
++
++static int chaoskey_release(struct inode *inode, struct file *file)
++{
++	struct chaoskey *dev = file->private_data;
++	struct usb_interface *interface;
++
++	if (dev == NULL)
++		return -ENODEV;
++
++	interface = dev->interface;
++
++	usb_dbg(interface, "release");
++
++	mutex_lock(&dev->lock);
++
++	usb_dbg(interface, "open count at release is %d", dev->open);
++
++	if (dev->open <= 0) {
++		usb_dbg(interface, "invalid open count (%d)", dev->open);
++		mutex_unlock(&dev->lock);
++		return -ENODEV;
++	}
++
++	--dev->open;
++
++	if (!dev->present) {
++		if (dev->open == 0) {
++			mutex_unlock(&dev->lock);
++			chaoskey_free(dev);
++		} else
++			mutex_unlock(&dev->lock);
++	} else
++		mutex_unlock(&dev->lock);
++
++	usb_dbg(interface, "release success");
++	return 0;
++}
++
++/* Fill the buffer. Called with dev->lock held
++ */
++static int _chaoskey_fill(struct chaoskey *dev)
++{
++	DEFINE_WAIT(wait);
++	int result;
++	int this_read;
++	struct usb_device *udev = interface_to_usbdev(dev->interface);
++
++	usb_dbg(dev->interface, "fill");
++
++	/* Return immediately if someone called before the buffer was
++	 * empty */
++	if (dev->valid != dev->used) {
++		usb_dbg(dev->interface, "not empty yet (valid %d used %d)",
++			dev->valid, dev->used);
++		return 0;
++	}
++
++	/* Bail if the device has been removed */
++	if (!dev->present) {
++		usb_dbg(dev->interface, "device not present");
++		return -ENODEV;
++	}
++
++	/* Make sure the device is awake */
++	result = usb_autopm_get_interface(dev->interface);
++	if (result) {
++		usb_dbg(dev->interface, "wakeup failed (result %d)", result);
++		return result;
++	}
++
++	result = usb_bulk_msg(udev,
++			      usb_rcvbulkpipe(udev, dev->in_ep),
++			      dev->buf, dev->size, &this_read,
++			      NAK_TIMEOUT);
++
++	/* Let the device go back to sleep eventually */
++	usb_autopm_put_interface(dev->interface);
++
++	if (result == 0) {
++		dev->valid = this_read;
++		dev->used = 0;
++	}
++
++	usb_dbg(dev->interface, "bulk_msg result %d this_read %d",
++		result, this_read);
++
++	return result;
++}
++
++static ssize_t chaoskey_read(struct file *file,
++			     char __user *buffer,
++			     size_t count,
++			     loff_t *ppos)
++{
++	struct chaoskey *dev;
++	ssize_t read_count = 0;
++	int this_time;
++	int result = 0;
++	unsigned long remain;
++
++	dev = file->private_data;
++
++	if (dev == NULL || !dev->present)
++		return -ENODEV;
++
++	usb_dbg(dev->interface, "read %zu", count);
++
++	while (count > 0) {
++
++		/* Grab the rng_lock briefly to ensure that the hwrng interface
++		 * gets priority over other user access
++		 */
++		result = mutex_lock_interruptible(&dev->rng_lock);
++		if (result)
++			goto bail;
++		mutex_unlock(&dev->rng_lock);
++
++		result = mutex_lock_interruptible(&dev->lock);
++		if (result)
++			goto bail;
++		if (dev->valid == dev->used) {
++			result = _chaoskey_fill(dev);
++			if (result) {
++				mutex_unlock(&dev->lock);
++				goto bail;
++			}
++
++			/* Read returned zero bytes */
++			if (dev->used == dev->valid) {
++				mutex_unlock(&dev->lock);
++				goto bail;
++			}
++		}
++
++		this_time = dev->valid - dev->used;
++		if (this_time > count)
++			this_time = count;
++
++		remain = copy_to_user(buffer, dev->buf + dev->used, this_time);
++		if (remain) {
++			result = -EFAULT;
++
++			/* Consume the bytes that were copied so we don't leak
++			 * data to user space
++			 */
++			dev->used += this_time - remain;
++			mutex_unlock(&dev->lock);
++			goto bail;
++		}
++
++		count -= this_time;
++		read_count += this_time;
++		buffer += this_time;
++		dev->used += this_time;
++		mutex_unlock(&dev->lock);
++	}
++bail:
++	if (read_count) {
++		usb_dbg(dev->interface, "read %zu bytes", read_count);
++		return read_count;
++	}
++	usb_dbg(dev->interface, "empty read, result %d", result);
++	return result;
++}
++
++static int chaoskey_rng_read(struct hwrng *rng, void *data,
++			     size_t max, bool wait)
++{
++	struct chaoskey *dev = container_of(rng, struct chaoskey, hwrng);
++	int this_time;
++
++	usb_dbg(dev->interface, "rng_read max %zu wait %d", max, wait);
++
++	if (!dev->present) {
++		usb_dbg(dev->interface, "device not present");
++		return 0;
++	}
++
++	/* Hold the rng_lock until we acquire the device lock so that
++	 * this operation gets priority over other user access to the
++	 * device
++	 */
++	mutex_lock(&dev->rng_lock);
++
++	mutex_lock(&dev->lock);
++
++	mutex_unlock(&dev->rng_lock);
++
++	/* Try to fill the buffer if empty. It doesn't actually matter
++	 * if _chaoskey_fill works; we'll just return zero bytes as
++	 * the buffer will still be empty
++	 */
++	if (dev->valid == dev->used)
++		(void) _chaoskey_fill(dev);
++
++	this_time = dev->valid - dev->used;
++	if (this_time > max)
++		this_time = max;
++
++	memcpy(data, dev->buf, this_time);
++
++	dev->used += this_time;
++
++	mutex_unlock(&dev->lock);
++
++	usb_dbg(dev->interface, "rng_read this_time %d\n", this_time);
++	return this_time;
++}
++
++#ifdef CONFIG_PM
++static int chaoskey_suspend(struct usb_interface *interface,
++			    pm_message_t message)
++{
++	usb_dbg(interface, "suspend");
++	return 0;
++}
++
++static int chaoskey_resume(struct usb_interface *interface)
++{
++	usb_dbg(interface, "resume");
++	return 0;
++}
++#else
++#define chaoskey_suspend NULL
++#define chaoskey_resume NULL
++#endif
++
++/* file operation pointers */
++static const struct file_operations chaoskey_fops = {
++	.owner = THIS_MODULE,
++	.read = chaoskey_read,
++	.open = chaoskey_open,
++	.release = chaoskey_release,
++	.llseek = default_llseek,
++};
++
++/* class driver information */
++static struct usb_class_driver chaoskey_class = {
++	.name = "chaoskey%d",
++	.fops = &chaoskey_fops,
++	.minor_base = USB_CHAOSKEY_MINOR_BASE,
++};
++
++/* usb specific object needed to register this driver with the usb subsystem */
++static struct usb_driver chaoskey_driver = {
++	.name = DRIVER_SHORT,
++	.probe = chaoskey_probe,
++	.disconnect = chaoskey_disconnect,
++	.suspend = chaoskey_suspend,
++	.resume = chaoskey_resume,
++	.reset_resume = chaoskey_resume,
++	.id_table = chaoskey_table,
++	.supports_autosuspend = 1,
++};
++
++module_usb_driver(chaoskey_driver);
++
diff --git a/debian/patches/features/all/chaoskey/usb-Fix-warnings-in-chaoskey-driver.patch b/debian/patches/features/all/chaoskey/usb-Fix-warnings-in-chaoskey-driver.patch
new file mode 100644
index 0000000..9655b68
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/usb-Fix-warnings-in-chaoskey-driver.patch
@@ -0,0 +1,57 @@
+From 8b86ed078a65433a60ff59091a136d23724bd6d3 Mon Sep 17 00:00:00 2001
+From: Keith Packard <keithp@keithp.com>
+Date: Thu, 26 Mar 2015 16:49:38 -0700
+Subject: [PATCH] usb: Fix warnings in chaoskey driver
+
+>    drivers/usb/misc/chaoskey.c: In function 'chaoskey_read':
+> >> drivers/usb/misc/chaoskey.c:412:3: error: implicit declaration of function 'copy_to_user'
+> >> [-Werror=implicit-function-declaration]
+>       remain = copy_to_user(buffer, dev->buf + dev->used, this_time);
+
+I was unable to reproduce this locally, but added an explicit
+
+	#include <linux/uaccess.h>
+
+which should ensure the definition on all architectures.
+
+> sparse warnings: (new ones prefixed by >>)
+>
+> >> drivers/usb/misc/chaoskey.c:117:30: sparse: incorrect type in assignment (different base types)
+>    drivers/usb/misc/chaoskey.c:117:30:    expected int [signed] size
+>    drivers/usb/misc/chaoskey.c:117:30:    got restricted __le16 [usertype] wMaxPacketSize
+
+Switched the code to using the USB descriptor accessor functions.
+
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/chaoskey.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index ef80ce9..3ad5d19 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -27,6 +27,8 @@
+ #include <linux/usb.h>
+ #include <linux/wait.h>
+ #include <linux/hw_random.h>
++#include <linux/mutex.h>
++#include <linux/uaccess.h>
+ 
+ static struct usb_driver chaoskey_driver;
+ static struct usb_class_driver chaoskey_class;
+@@ -113,8 +115,8 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	/* Find the first bulk IN endpoint and its packet size */
+ 	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
+ 		if (usb_endpoint_is_bulk_in(&altsetting->endpoint[i].desc)) {
+-			in_ep = altsetting->endpoint[i].desc.bEndpointAddress;
+-			size = altsetting->endpoint[i].desc.wMaxPacketSize;
++			in_ep = usb_endpoint_num(&altsetting->endpoint[i].desc);
++			size = usb_endpoint_maxp(&altsetting->endpoint[i].desc);
+ 			break;
+ 		}
+ 	}
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/usb-misc-chaoskey-Cleanup-probe-failure-paths.patch b/debian/patches/features/all/chaoskey/usb-misc-chaoskey-Cleanup-probe-failure-paths.patch
new file mode 100644
index 0000000..eb426ae
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/usb-misc-chaoskey-Cleanup-probe-failure-paths.patch
@@ -0,0 +1,103 @@
+From 0a15e24c2740b7db99fbe21642b33a3028700225 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Wed, 17 Feb 2016 09:58:11 -0800
+Subject: [PATCH] usb/misc/chaoskey: Cleanup probe failure paths
+
+Shares the cleanup code between all probe failure paths, instead of
+having per-failure cleanup at each point in the function.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/chaoskey.c | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index 23c7948..cb1c239 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -93,10 +93,12 @@ struct chaoskey {
+ 
+ static void chaoskey_free(struct chaoskey *dev)
+ {
+-	usb_dbg(dev->interface, "free");
+-	kfree(dev->name);
+-	kfree(dev->buf);
+-	kfree(dev);
++	if (dev) {
++		usb_dbg(dev->interface, "free");
++		kfree(dev->name);
++		kfree(dev->buf);
++		kfree(dev);
++	}
+ }
+ 
+ static int chaoskey_probe(struct usb_interface *interface,
+@@ -107,7 +109,7 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	int i;
+ 	int in_ep = -1;
+ 	struct chaoskey *dev;
+-	int result;
++	int result = -ENOMEM;
+ 	int size;
+ 
+ 	usb_dbg(interface, "probe %s-%s", udev->product, udev->serial);
+@@ -142,14 +144,12 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL);
+ 
+ 	if (dev == NULL)
+-		return -ENOMEM;
++		goto out;
+ 
+ 	dev->buf = kmalloc(size, GFP_KERNEL);
+ 
+-	if (dev->buf == NULL) {
+-		kfree(dev);
+-		return -ENOMEM;
+-	}
++	if (dev->buf == NULL)
++		goto out;
+ 
+ 	/* Construct a name using the product and serial values. Each
+ 	 * device needs a unique name for the hwrng code
+@@ -158,11 +158,8 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	if (udev->product && udev->serial) {
+ 		dev->name = kmalloc(strlen(udev->product) + 1 +
+ 				    strlen(udev->serial) + 1, GFP_KERNEL);
+-		if (dev->name == NULL) {
+-			kfree(dev->buf);
+-			kfree(dev);
+-			return -ENOMEM;
+-		}
++		if (dev->name == NULL)
++			goto out;
+ 
+ 		strcpy(dev->name, udev->product);
+ 		strcat(dev->name, "-");
+@@ -186,9 +183,7 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	result = usb_register_dev(interface, &chaoskey_class);
+ 	if (result) {
+ 		usb_err(interface, "Unable to allocate minor number.");
+-		usb_set_intfdata(interface, NULL);
+-		chaoskey_free(dev);
+-		return result;
++		goto out;
+ 	}
+ 
+ 	dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
+@@ -215,6 +210,11 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 
+ 	usb_dbg(interface, "chaoskey probe success, size %d", dev->size);
+ 	return 0;
++
++out:
++	usb_set_intfdata(interface, NULL);
++	chaoskey_free(dev);
++	return result;
+ }
+ 
+ static void chaoskey_disconnect(struct usb_interface *interface)
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/usb-misc-chaoskey-introduce-an-URB-for-asynchronous-.patch b/debian/patches/features/all/chaoskey/usb-misc-chaoskey-introduce-an-URB-for-asynchronous-.patch
new file mode 100644
index 0000000..3dd0883
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/usb-misc-chaoskey-introduce-an-URB-for-asynchronous-.patch
@@ -0,0 +1,187 @@
+From 0ca10122ca08d21e375b8c85bd7b498b1aeaf55d Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Wed, 17 Feb 2016 10:01:33 -0800
+Subject: [PATCH] usb/misc/chaoskey: introduce an URB for asynchronous reads
+
+To allow for and clean handling of signals an URB is introduced.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/chaoskey.c | 86 ++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 65 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c
+index cb1c239..76350e4 100644
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -73,6 +73,8 @@ static const struct usb_device_id chaoskey_table[] = {
+ };
+ MODULE_DEVICE_TABLE(usb, chaoskey_table);
+ 
++static void chaos_read_callback(struct urb *urb);
++
+ /* Driver-local specific stuff */
+ struct chaoskey {
+ 	struct usb_interface *interface;
+@@ -80,7 +82,8 @@ struct chaoskey {
+ 	struct mutex lock;
+ 	struct mutex rng_lock;
+ 	int open;			/* open count */
+-	int present;			/* device not disconnected */
++	bool present;			/* device not disconnected */
++	bool reading;			/* ongoing IO */
+ 	int size;			/* size of buf */
+ 	int valid;			/* bytes of buf read */
+ 	int used;			/* bytes of buf consumed */
+@@ -88,6 +91,7 @@ struct chaoskey {
+ 	struct hwrng hwrng;		/* Embedded struct for hwrng */
+ 	int hwrng_registered;		/* registered with hwrng API */
+ 	wait_queue_head_t wait_q;	/* for timeouts */
++	struct urb *urb;		/* for performing IO */
+ 	char *buf;
+ };
+ 
+@@ -95,6 +99,7 @@ static void chaoskey_free(struct chaoskey *dev)
+ {
+ 	if (dev) {
+ 		usb_dbg(dev->interface, "free");
++		usb_free_urb(dev->urb);
+ 		kfree(dev->name);
+ 		kfree(dev->buf);
+ 		kfree(dev);
+@@ -151,6 +156,19 @@ static int chaoskey_probe(struct usb_interface *interface,
+ 	if (dev->buf == NULL)
+ 		goto out;
+ 
++	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
++
++	if (!dev->urb)
++		goto out;
++
++	usb_fill_bulk_urb(dev->urb,
++		udev,
++		usb_rcvbulkpipe(udev, in_ep),
++		dev->buf,
++		size,
++		chaos_read_callback,
++		dev);
++
+ 	/* Construct a name using the product and serial values. Each
+ 	 * device needs a unique name for the hwrng code
+ 	 */
+@@ -237,6 +255,7 @@ static void chaoskey_disconnect(struct usb_interface *interface)
+ 	mutex_lock(&dev->lock);
+ 
+ 	dev->present = 0;
++	usb_poison_urb(dev->urb);
+ 
+ 	if (!dev->open) {
+ 		mutex_unlock(&dev->lock);
+@@ -311,14 +330,33 @@ static int chaoskey_release(struct inode *inode, struct file *file)
+ 	return 0;
+ }
+ 
++static void chaos_read_callback(struct urb *urb)
++{
++	struct chaoskey *dev = urb->context;
++	int status = urb->status;
++
++	usb_dbg(dev->interface, "callback status (%d)", status);
++
++	if (status == 0)
++		dev->valid = urb->actual_length;
++	else
++		dev->valid = 0;
++
++	dev->used = 0;
++
++	/* must be seen first before validity is announced */
++	smp_wmb();
++
++	dev->reading = false;
++	wake_up(&dev->wait_q);
++}
++
+ /* Fill the buffer. Called with dev->lock held
+  */
+ static int _chaoskey_fill(struct chaoskey *dev)
+ {
+ 	DEFINE_WAIT(wait);
+ 	int result;
+-	int this_read;
+-	struct usb_device *udev = interface_to_usbdev(dev->interface);
+ 
+ 	usb_dbg(dev->interface, "fill");
+ 
+@@ -343,21 +381,31 @@ static int _chaoskey_fill(struct chaoskey *dev)
+ 		return result;
+ 	}
+ 
+-	result = usb_bulk_msg(udev,
+-			      usb_rcvbulkpipe(udev, dev->in_ep),
+-			      dev->buf, dev->size, &this_read,
+-			      NAK_TIMEOUT);
++	dev->reading = true;
++	result = usb_submit_urb(dev->urb, GFP_KERNEL);
++	if (result < 0) {
++		result = usb_translate_errors(result);
++		dev->reading = false;
++		goto out;
++	}
++
++	result = wait_event_interruptible_timeout(
++		dev->wait_q,
++		!dev->reading,
++		NAK_TIMEOUT);
+ 
++	if (result < 0)
++		goto out;
++
++	if (result == 0)
++		result = -ETIMEDOUT;
++	else
++		result = dev->valid;
++out:
+ 	/* Let the device go back to sleep eventually */
+ 	usb_autopm_put_interface(dev->interface);
+ 
+-	if (result == 0) {
+-		dev->valid = this_read;
+-		dev->used = 0;
+-	}
+-
+-	usb_dbg(dev->interface, "bulk_msg result %d this_read %d",
+-		result, this_read);
++	usb_dbg(dev->interface, "read %d bytes", dev->valid);
+ 
+ 	return result;
+ }
+@@ -395,13 +443,7 @@ static ssize_t chaoskey_read(struct file *file,
+ 			goto bail;
+ 		if (dev->valid == dev->used) {
+ 			result = _chaoskey_fill(dev);
+-			if (result) {
+-				mutex_unlock(&dev->lock);
+-				goto bail;
+-			}
+-
+-			/* Read returned zero bytes */
+-			if (dev->used == dev->valid) {
++			if (result < 0) {
+ 				mutex_unlock(&dev->lock);
+ 				goto bail;
+ 			}
+@@ -435,6 +477,8 @@ bail:
+ 		return read_count;
+ 	}
+ 	usb_dbg(dev->interface, "empty read, result %d", result);
++	if (result == -ETIMEDOUT)
++		result = -EAGAIN;
+ 	return result;
+ }
+ 
+-- 
+2.9.3
+
diff --git a/debian/patches/features/all/chaoskey/usb-misc-fix-chaoskey-build-needs-HW_RANDOM.patch b/debian/patches/features/all/chaoskey/usb-misc-fix-chaoskey-build-needs-HW_RANDOM.patch
new file mode 100644
index 0000000..c4bff01
--- /dev/null
+++ b/debian/patches/features/all/chaoskey/usb-misc-fix-chaoskey-build-needs-HW_RANDOM.patch
@@ -0,0 +1,33 @@
+From d9aab404e60d122ded979fa0b81db42fb680d867 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Thu, 2 Apr 2015 17:10:55 -0700
+Subject: [PATCH] usb/misc: fix chaoskey build, needs HW_RANDOM
+
+Fix build errors when HW_RANDOM is not enabled:
+
+drivers/built-in.o: In function `chaoskey_disconnect':
+chaoskey.c:(.text+0x5f3f00): undefined reference to `hwrng_unregister'
+drivers/built-in.o: In function `chaoskey_probe':
+chaoskey.c:(.text+0x5f42a6): undefined reference to `hwrng_register'
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+index 8c331f1..f7a7fc2 100644
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -258,6 +258,7 @@ config USB_LINK_LAYER_TEST
+ 
+ config USB_CHAOSKEY
+ 	tristate "ChaosKey random number generator driver support"
++	depends on HW_RANDOM
+ 	help
+ 	  Say Y here if you want to connect an AltusMetrum ChaosKey to
+ 	  your computer's USB port. The ChaosKey is a hardware random
+-- 
+2.9.3
+
diff --git a/debian/patches/series b/debian/patches/series
index 3ab0d2d..75ade3f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -637,6 +637,17 @@ features/x86/ALSA-hda_controller-Separate-stream_tag-for-input-an.patch
 features/x86/ALSA-hda_intel-apply-the-Seperate-stream_tag-for-Sky.patch
 features/x86/ALSA-hda_intel-apply-the-Seperate-stream_tag-for-Sun.patch
 
+# chaoskey driver
+features/all/chaoskey/usb-Add-driver-for-Altus-Metrum-ChaosKey-device-v2.patch
+features/all/chaoskey/usb-Fix-warnings-in-chaoskey-driver.patch
+features/all/chaoskey/usb-misc-fix-chaoskey-build-needs-HW_RANDOM.patch
+features/all/chaoskey/USB-chaoskey-read-offset-bug.patch
+features/all/chaoskey/usb-misc-chaoskey-Cleanup-probe-failure-paths.patch
+features/all/chaoskey/usb-misc-chaoskey-introduce-an-URB-for-asynchronous-.patch
+features/all/chaoskey/hwrng-chaoskey-Add-support-for-Araneus-Alea-I-USB-RN.patch
+features/all/chaoskey/hwrng-chaoskey-Fix-URB-warning-due-to-timeout-on-Ale.patch
+features/all/chaoskey/chaoskey-3.16-no-hwrng-quality.patch
+
 # Security fixes
 bugfix/all/usb-usbfs-fix-potential-infoleak-in-devio.patch
 bugfix/all/alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch
-- 
2.1.4


Reply to: