mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/3] input: console: skip unmappable keys
@ 2021-03-29  6:18 Ahmad Fatoum
  2021-03-29  6:18 ` [PATCH 2/3] input: add virtio input driver Ahmad Fatoum
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-29  6:18 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

The input console is in charge of turning input events to barebox
console keycodes. The keymap array it uses to do so has NR_KEYS
entries. Keycodes with values >= NR_KEYS can thus not be mapped.
Ignore them instead of evaluating arbitrary memory contents beyond
the buffer.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/input/input.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index bcc8667417d9..1df52f56c84d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -165,6 +165,9 @@ static void input_console_notify(struct input_notifier *in,
 	if (ic->modstate[4] || ic->modstate[5])
 		modstate |= 1 << 2;
 
+	if (ev->code >= NR_KEYS)
+		return;
+
 	if (modstate & (1 << 1)) {
 		ascii = keycode_bb_keys[ev->code];
 		ascii = ascii >= 'a' ? CTL_CH(ascii) : 0;
-- 
2.30.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 2/3] input: add virtio input driver
  2021-03-29  6:18 [PATCH 1/3] input: console: skip unmappable keys Ahmad Fatoum
@ 2021-03-29  6:18 ` Ahmad Fatoum
  2021-03-29  6:18 ` [PATCH 3/3] input: virtio_input: add sound support Ahmad Fatoum
  2021-03-30  5:27 ` [PATCH 1/3] input: console: skip unmappable keys Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-29  6:18 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

We already support Linux event codes, because they are used in the
device tree bindings for e.g. gpio-keys.

Virtio input devices report events using the same codes, so a driver
just has to shovel the codes from virtqueue into the input layer. Do so.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/input/Kconfig             |   7 ++
 drivers/input/Makefile            |   1 +
 drivers/input/virtio_input.c      | 191 ++++++++++++++++++++++++++++++
 include/linux/virtio.h            |   7 ++
 include/linux/virtio_config.h     |  62 ++++++++++
 include/linux/virtio_ring.h       |  34 ++++++
 include/uapi/linux/virtio_input.h |  76 ++++++++++++
 7 files changed, 378 insertions(+)
 create mode 100644 drivers/input/virtio_input.c
 create mode 100644 include/uapi/linux/virtio_input.h

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 95aa51ebfc9e..ff3e9d33f6d7 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -71,4 +71,11 @@ config INPUT_SPECIALKEYS
 	help
 	  Say Y here to handle key events like KEY_RESTART and KEY_POWER.
 
+config VIRTIO_INPUT
+	bool "Virtio input driver"
+	depends on VIRTIO && BTHREAD
+	select INPUT
+	help
+	 This driver supports virtio keyboard input devices.
+
 endmenu
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 36a4204d5308..6c8acc618427 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_KEYBOARD_TWL6030) += twl6030_pwrbtn.o
 obj-$(CONFIG_KEYBOARD_IMX_KEYPAD) += imx_keypad.o
 obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o
 obj-$(CONFIG_INPUT_SPECIALKEYS)	+= specialkeys.o
+obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
diff --git a/drivers/input/virtio_input.c b/drivers/input/virtio_input.c
new file mode 100644
index 000000000000..406dc613dc37
--- /dev/null
+++ b/drivers/input/virtio_input.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <bthread.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
+#include <input/input.h>
+#include <dt-bindings/input/linux-event-codes.h>
+
+#include <uapi/linux/virtio_ids.h>
+#include <uapi/linux/virtio_input.h>
+
+struct virtio_input {
+	struct input_device        idev;
+	struct virtio_device       *vdev;
+	struct virtqueue           *evt;
+	struct virtio_input_event  evts[64];
+	struct bthread             *bthread;
+};
+
+static void virtinput_queue_evtbuf(struct virtio_input *vi,
+				   struct virtio_input_event *evtbuf)
+{
+	struct virtio_sg sg[1];
+	virtio_sg_init_one(sg, evtbuf, sizeof(*evtbuf));
+	virtqueue_add_inbuf(vi->evt, sg, 1);
+}
+
+static int virtinput_recv_events(struct virtio_input *vi)
+{
+	struct device_d *dev = &vi->vdev->dev;
+	struct virtio_input_event *event;
+	unsigned int len;
+	int i = 0;
+
+	while ((event = virtqueue_get_buf(vi->evt, &len)) != NULL) {
+		if (le16_to_cpu(event->type) == EV_KEY)
+			input_report_key_event(&vi->idev, le16_to_cpu(event->code),
+					       le32_to_cpu(event->value));
+
+		pr_debug("\n%s: input event #%td received (type=%u, code=%u, value=%u)\n",
+			 dev_name(dev),
+			 event - &vi->evts[0],
+			 le16_to_cpu(event->type), le16_to_cpu(event->code),
+			 le32_to_cpu(event->value));
+
+		virtinput_queue_evtbuf(vi, event);
+		i++;
+	}
+
+	return i;
+}
+
+static int virtinput_poll_vqs(void *_vi)
+{
+	struct virtio_input *vi = _vi;
+
+	while (!bthread_should_stop()) {
+		int bufs = 0;
+
+		bufs += virtinput_recv_events(vi);
+
+		if (bufs)
+			virtqueue_kick(vi->evt);
+	}
+
+	return 0;
+}
+
+static u8 virtinput_cfg_select(struct virtio_input *vi,
+			       u8 select, u8 subsel)
+{
+	u8 size;
+
+	virtio_cwrite_le(vi->vdev, struct virtio_input_config, select, &select);
+	virtio_cwrite_le(vi->vdev, struct virtio_input_config, subsel, &subsel);
+	virtio_cread_le(vi->vdev, struct virtio_input_config, size, &size);
+	return size;
+}
+
+static void virtinput_fill_evt(struct virtio_input *vi)
+{
+	int i, size;
+
+	size = virtqueue_get_vring_size(vi->evt);
+	if (size > ARRAY_SIZE(vi->evts))
+		size = ARRAY_SIZE(vi->evts);
+	for (i = 0; i < size; i++)
+		virtinput_queue_evtbuf(vi, &vi->evts[i]);
+	virtqueue_kick(vi->evt);
+}
+
+static int virtinput_init_vqs(struct virtio_input *vi)
+{
+	struct virtqueue *vqs[1];
+	int err;
+
+
+	err = virtio_find_vqs(vi->vdev, 1, vqs);
+	if (err)
+		return err;
+
+	vi->evt = vqs[0];
+
+	return 0;
+}
+
+static int virtinput_probe(struct virtio_device *vdev)
+{
+	struct virtio_input *vi;
+	char name[64];
+	size_t size;
+	int err;
+
+	if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
+		return -ENODEV;
+
+	vi = kzalloc(sizeof(*vi), GFP_KERNEL);
+	if (!vi)
+		return -ENOMEM;
+
+	vdev->priv = vi;
+	vi->vdev = vdev;
+
+	err = virtinput_init_vqs(vi);
+	if (err)
+		goto err_init_vq;
+
+	size = virtinput_cfg_select(vi, VIRTIO_INPUT_CFG_ID_NAME, 0);
+	virtio_cread_bytes(vi->vdev, offsetof(struct virtio_input_config, u.string),
+			   name, min(size, sizeof(name)));
+	name[size] = '\0';
+
+	virtio_device_ready(vdev);
+
+	err = input_device_register(&vi->idev);
+	if (err)
+		goto err_input_register;
+
+	virtinput_fill_evt(vi);
+
+	vi->bthread = bthread_run(virtinput_poll_vqs, vi,
+				  "%s/input0", dev_name(&vdev->dev));
+	if (!vi->bthread) {
+		err = -ENOMEM;
+		goto err_bthread_run;
+	}
+
+	dev_info(&vdev->dev, "'%s' probed\n", name);
+
+	return 0;
+
+err_bthread_run:
+	bthread_free(vi->bthread);
+err_input_register:
+	vdev->config->del_vqs(vdev);
+err_init_vq:
+	kfree(vi);
+	return err;
+}
+
+static void virtinput_remove(struct virtio_device *vdev)
+{
+	struct virtio_input *vi = vdev->priv;
+
+	bthread_stop(vi->bthread);
+	bthread_free(vi->bthread);
+
+	vdev->config->reset(vdev);
+	vdev->config->del_vqs(vdev);
+	kfree(vi);
+}
+
+static const struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_INPUT, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct virtio_driver virtio_input_driver = {
+	.driver.name         = "virtio_input",
+	.id_table            = id_table,
+	.probe               = virtinput_probe,
+	.remove              = virtinput_remove,
+};
+device_virtio_driver(virtio_input_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Virtio input device driver");
+MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
+MODULE_AUTHOR("Ahmad Fatoum <a.fatoum@pengutronix.de>");
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 8a1a80ddc820..719f45c97560 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -24,6 +24,13 @@ struct virtio_sg {
 	size_t length;
 };
 
+static inline void virtio_sg_init_one(struct virtio_sg *sg,
+				      void *addr, size_t length)
+{
+	sg[0].addr = addr;
+	sg[0].length = length;
+}
+
 struct virtio_config_ops;
 
 /**
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index f33cfdacaa2c..8160f0952f13 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -458,6 +458,68 @@ static inline void virtio_cwrite64(struct virtio_device *vdev,
 		_r;							\
 	})
 
+/*
+ * Nothing virtio-specific about these, but let's worry about generalizing
+ * these later.
+ */
+#define virtio_le_to_cpu(x) \
+	_Generic((x), \
+		__u8: (u8)(x), \
+		 __le16: (u16)le16_to_cpu(x), \
+		 __le32: (u32)le32_to_cpu(x), \
+		 __le64: (u64)le64_to_cpu(x) \
+		)
+
+#define virtio_cpu_to_le(x, m) \
+	_Generic((m), \
+		 __u8: (x), \
+		 __le16: cpu_to_le16(x), \
+		 __le32: cpu_to_le32(x), \
+		 __le64: cpu_to_le64(x) \
+		)
+
+/* LE (e.g. modern) Config space accessors. */
+#define virtio_cread_le(vdev, structname, member, ptr)			\
+	do {								\
+		typeof(((structname*)0)->member) virtio_cread_v;	\
+									\
+		/* Sanity check: must match the member's type */	\
+		typecheck(typeof(virtio_le_to_cpu(virtio_cread_v)), *(ptr)); \
+									\
+		switch (sizeof(virtio_cread_v)) {			\
+		case 1:							\
+		case 2:							\
+		case 4:							\
+			vdev->config->get_config((vdev),		\
+					  offsetof(structname, member), \
+					  &virtio_cread_v,		\
+					  sizeof(virtio_cread_v));	\
+			break;						\
+		default:						\
+			__virtio_cread_many((vdev), 			\
+					  offsetof(structname, member), \
+					  &virtio_cread_v,		\
+					  1,				\
+					  sizeof(virtio_cread_v));	\
+			break;						\
+		}							\
+		*(ptr) = virtio_le_to_cpu(virtio_cread_v);		\
+	} while(0)
+
+#define virtio_cwrite_le(vdev, structname, member, ptr)			\
+	do {								\
+		typeof(((structname*)0)->member) virtio_cwrite_v =	\
+			virtio_cpu_to_le(*(ptr), ((structname*)0)->member); \
+									\
+		/* Sanity check: must match the member's type */	\
+		typecheck(typeof(virtio_le_to_cpu(virtio_cwrite_v)), *(ptr)); \
+									\
+		vdev->config->set_config((vdev), offsetof(structname, member),	\
+				  &virtio_cwrite_v,			\
+				  sizeof(virtio_cwrite_v));		\
+	} while(0)
+
+
 #ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS
 int arch_has_restricted_virtio_memory_access(void);
 #else
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index c349af90ce50..bdef47b0fa6c 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -180,6 +180,40 @@ struct virtio_sg;
 int virtqueue_add(struct virtqueue *vq, struct virtio_sg *sgs[],
 		  unsigned int out_sgs, unsigned int in_sgs);
 
+/**
+ * virtqueue_add_outbuf - expose output buffers to other end
+ * @vq: the struct virtqueue we're talking about.
+ * @sg: scatterlist (must be well-formed and terminated!)
+ * @num: the number of entries in @sg readable by other side
+ *
+ * Caller must ensure we don't call this with other virtqueue operations
+ * at the same time (except where noted).
+ *
+ * Returns zero or a negative error (ie. ENOSPC, ENOMEM, EIO).
+ */
+static inline int virtqueue_add_outbuf(struct virtqueue *vq,
+                                      struct virtio_sg *sg, unsigned int num)
+{
+	return virtqueue_add(vq, &sg, num, 0);
+}
+
+/**
+ * virtqueue_add_inbuf - expose input buffers to other end
+ * @vq: the struct virtqueue we're talking about.
+ * @sg: scatterlist (must be well-formed and terminated!)
+ * @num: the number of entries in @sg writable by other side
+ *
+ * Caller must ensure we don't call this with other virtqueue operations
+ * at the same time (except where noted).
+ *
+ * Returns zero or a negative error (ie. ENOSPC, ENOMEM, EIO).
+ */
+static inline int virtqueue_add_inbuf(struct virtqueue *vq,
+                                     struct virtio_sg *sg, unsigned int num)
+{
+	return virtqueue_add(vq, &sg, 0, num);
+}
+
 /**
  * virtqueue_kick - update after add_buf
  *
diff --git a/include/uapi/linux/virtio_input.h b/include/uapi/linux/virtio_input.h
new file mode 100644
index 000000000000..52084b1fb965
--- /dev/null
+++ b/include/uapi/linux/virtio_input.h
@@ -0,0 +1,76 @@
+#ifndef _LINUX_VIRTIO_INPUT_H
+#define _LINUX_VIRTIO_INPUT_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+#include <linux/types.h>
+
+enum virtio_input_config_select {
+	VIRTIO_INPUT_CFG_UNSET      = 0x00,
+	VIRTIO_INPUT_CFG_ID_NAME    = 0x01,
+	VIRTIO_INPUT_CFG_ID_SERIAL  = 0x02,
+	VIRTIO_INPUT_CFG_ID_DEVIDS  = 0x03,
+	VIRTIO_INPUT_CFG_PROP_BITS  = 0x10,
+	VIRTIO_INPUT_CFG_EV_BITS    = 0x11,
+	VIRTIO_INPUT_CFG_ABS_INFO   = 0x12,
+};
+
+struct virtio_input_absinfo {
+	__le32 min;
+	__le32 max;
+	__le32 fuzz;
+	__le32 flat;
+	__le32 res;
+};
+
+struct virtio_input_devids {
+	__le16 bustype;
+	__le16 vendor;
+	__le16 product;
+	__le16 version;
+};
+
+struct virtio_input_config {
+	__u8    select;
+	__u8    subsel;
+	__u8    size;
+	__u8    reserved[5];
+	union {
+		char string[128];
+		__u8 bitmap[128];
+		struct virtio_input_absinfo abs;
+		struct virtio_input_devids ids;
+	} u;
+};
+
+struct virtio_input_event {
+	__le16 type;
+	__le16 code;
+	__le32 value;
+};
+
+#endif /* _LINUX_VIRTIO_INPUT_H */
-- 
2.30.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 3/3] input: virtio_input: add sound support
  2021-03-29  6:18 [PATCH 1/3] input: console: skip unmappable keys Ahmad Fatoum
  2021-03-29  6:18 ` [PATCH 2/3] input: add virtio input driver Ahmad Fatoum
@ 2021-03-29  6:18 ` Ahmad Fatoum
  2021-03-30  5:27 ` [PATCH 1/3] input: console: skip unmappable keys Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2021-03-29  6:18 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

Virtio input devices have an output channel for LEDs and a beeper.
Register a sound card for the beeper if sound support is compiled
in and the virtualized device reports sound support via the event
config bits.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 drivers/input/virtio_input.c | 105 ++++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 3 deletions(-)

diff --git a/drivers/input/virtio_input.c b/drivers/input/virtio_input.c
index 406dc613dc37..9c2e4d923f8d 100644
--- a/drivers/input/virtio_input.c
+++ b/drivers/input/virtio_input.c
@@ -6,6 +6,7 @@
 #include <linux/virtio_config.h>
 #include <linux/virtio_ring.h>
 #include <input/input.h>
+#include <sound.h>
 #include <dt-bindings/input/linux-event-codes.h>
 
 #include <uapi/linux/virtio_ids.h>
@@ -14,9 +15,11 @@
 struct virtio_input {
 	struct input_device        idev;
 	struct virtio_device       *vdev;
-	struct virtqueue           *evt;
+	struct virtqueue           *evt, *sts;
 	struct virtio_input_event  evts[64];
 	struct bthread             *bthread;
+	struct sound_card          beeper;
+	unsigned long              sndbit[BITS_TO_LONGS(SND_CNT)];
 };
 
 static void virtinput_queue_evtbuf(struct virtio_input *vi,
@@ -52,6 +55,51 @@ static int virtinput_recv_events(struct virtio_input *vi)
 	return i;
 }
 
+/*
+ * On error we are losing the status update, which isn't critical as
+ * this is used for the bell.
+ */
+static int virtinput_send_status(struct sound_card *beeper, unsigned freq, unsigned duration)
+{
+	struct virtio_input *vi = container_of(beeper, struct virtio_input, beeper);
+	struct virtio_input_event *stsbuf;
+	struct virtio_sg sg[1];
+	u16 code;
+	int rc;
+
+	stsbuf = kzalloc(sizeof(*stsbuf), 0);
+	if (!stsbuf)
+		return -ENOMEM;
+
+	code = vi->sndbit[0] & BIT_MASK(SND_TONE) ? SND_TONE : SND_BELL;
+
+	stsbuf->type  = cpu_to_le16(EV_SND);
+	stsbuf->code  = cpu_to_le16(code);
+	stsbuf->value = cpu_to_le32(freq);
+	virtio_sg_init_one(sg, stsbuf, sizeof(*stsbuf));
+
+	rc = virtqueue_add_outbuf(vi->sts, sg, 1);
+	virtqueue_kick(vi->sts);
+
+	if (rc != 0)
+		kfree(stsbuf);
+	return rc;
+}
+
+static int virtinput_recv_status(struct virtio_input *vi)
+{
+	struct virtio_input_event *stsbuf;
+	unsigned int len;
+	int i = 0;
+
+	while ((stsbuf = virtqueue_get_buf(vi->sts, &len)) != NULL) {
+		kfree(stsbuf);
+		i++;
+	}
+
+	return i;
+}
+
 static int virtinput_poll_vqs(void *_vi)
 {
 	struct virtio_input *vi = _vi;
@@ -60,6 +108,7 @@ static int virtinput_poll_vqs(void *_vi)
 		int bufs = 0;
 
 		bufs += virtinput_recv_events(vi);
+		bufs += virtinput_recv_status(vi);
 
 		if (bufs)
 			virtqueue_kick(vi->evt);
@@ -79,6 +128,37 @@ static u8 virtinput_cfg_select(struct virtio_input *vi,
 	return size;
 }
 
+static void virtinput_cfg_bits(struct virtio_input *vi, int select, int subsel,
+			       unsigned long *bits, unsigned int bitcount)
+{
+	unsigned int bit;
+	u8 *virtio_bits;
+	u8 bytes;
+
+	bytes = virtinput_cfg_select(vi, select, subsel);
+	if (!bytes)
+		return;
+	if (bitcount > bytes * 8)
+		bitcount = bytes * 8;
+
+	/*
+	 * Bitmap in virtio config space is a simple stream of bytes,
+	 * with the first byte carrying bits 0-7, second bits 8-15 and
+	 * so on.
+	 */
+	virtio_bits = kzalloc(bytes, GFP_KERNEL);
+	if (!virtio_bits)
+		return;
+	virtio_cread_bytes(vi->vdev, offsetof(struct virtio_input_config,
+					      u.bitmap),
+			   virtio_bits, bytes);
+	for (bit = 0; bit < bitcount; bit++) {
+		if (virtio_bits[bit / 8] & (1 << (bit % 8)))
+			__set_bit(bit, bits);
+	}
+	kfree(virtio_bits);
+}
+
 static void virtinput_fill_evt(struct virtio_input *vi)
 {
 	int i, size;
@@ -93,15 +173,16 @@ static void virtinput_fill_evt(struct virtio_input *vi)
 
 static int virtinput_init_vqs(struct virtio_input *vi)
 {
-	struct virtqueue *vqs[1];
+	struct virtqueue *vqs[2];
 	int err;
 
 
-	err = virtio_find_vqs(vi->vdev, 1, vqs);
+	err = virtio_find_vqs(vi->vdev, 2, vqs);
 	if (err)
 		return err;
 
 	vi->evt = vqs[0];
+	vi->sts = vqs[1];
 
 	return 0;
 }
@@ -132,6 +213,9 @@ static int virtinput_probe(struct virtio_device *vdev)
 			   name, min(size, sizeof(name)));
 	name[size] = '\0';
 
+	virtinput_cfg_bits(vi, VIRTIO_INPUT_CFG_EV_BITS, EV_SND,
+			   vi->sndbit, SND_CNT);
+
 	virtio_device_ready(vdev);
 
 	err = input_device_register(&vi->idev);
@@ -147,6 +231,21 @@ static int virtinput_probe(struct virtio_device *vdev)
 		goto err_bthread_run;
 	}
 
+	if (IS_ENABLED(CONFIG_SOUND) &&
+	    (vi->sndbit[0] & (BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE)))) {
+		struct sound_card *beeper;
+
+		beeper = &vi->beeper;
+		beeper->name = basprintf("%s/beeper0", dev_name(&vdev->dev));
+		beeper->beep = virtinput_send_status;
+
+		err = sound_card_register(&vi->beeper);
+		if (err)
+			dev_warn(&vdev->dev, "bell registration failed: %pe\n", ERR_PTR(err));
+		else
+			dev_info(&vdev->dev, "bell registered\n");
+	}
+
 	dev_info(&vdev->dev, "'%s' probed\n", name);
 
 	return 0;
-- 
2.30.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 1/3] input: console: skip unmappable keys
  2021-03-29  6:18 [PATCH 1/3] input: console: skip unmappable keys Ahmad Fatoum
  2021-03-29  6:18 ` [PATCH 2/3] input: add virtio input driver Ahmad Fatoum
  2021-03-29  6:18 ` [PATCH 3/3] input: virtio_input: add sound support Ahmad Fatoum
@ 2021-03-30  5:27 ` Sascha Hauer
  2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2021-03-30  5:27 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On Mon, Mar 29, 2021 at 08:18:08AM +0200, Ahmad Fatoum wrote:
> The input console is in charge of turning input events to barebox
> console keycodes. The keymap array it uses to do so has NR_KEYS
> entries. Keycodes with values >= NR_KEYS can thus not be mapped.
> Ignore them instead of evaluating arbitrary memory contents beyond
> the buffer.
> 
> Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
> ---
>  drivers/input/input.c | 3 +++
>  1 file changed, 3 insertions(+)

Applied, thanks

Sascha

> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index bcc8667417d9..1df52f56c84d 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -165,6 +165,9 @@ static void input_console_notify(struct input_notifier *in,
>  	if (ic->modstate[4] || ic->modstate[5])
>  		modstate |= 1 << 2;
>  
> +	if (ev->code >= NR_KEYS)
> +		return;
> +
>  	if (modstate & (1 << 1)) {
>  		ascii = keycode_bb_keys[ev->code];
>  		ascii = ascii >= 'a' ? CTL_CH(ascii) : 0;
> -- 
> 2.30.0
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

end of thread, other threads:[~2021-03-30  5:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-29  6:18 [PATCH 1/3] input: console: skip unmappable keys Ahmad Fatoum
2021-03-29  6:18 ` [PATCH 2/3] input: add virtio input driver Ahmad Fatoum
2021-03-29  6:18 ` [PATCH 3/3] input: virtio_input: add sound support Ahmad Fatoum
2021-03-30  5:27 ` [PATCH 1/3] input: console: skip unmappable keys Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox