summaryrefslogtreecommitdiff
path: root/schulung_tools/drivers/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch
blob: a67bf9851bf058ecc73b6992528dba879cbf90a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From be59ddb43fbf039ed0bc848ac56b7f72f7a619c8 Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Fri, 15 Feb 2019 11:07:10 +0106
Subject: [PATCH 5/7] hello: add led toggling via chardev ioctl

Compile userspace application with:

$ gcc -Wall -Werror hello-led.c -ohello-led

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 hello-led.c | 38 ++++++++++++++++++++++++++++++++++++++
 hello.c     | 22 ++++++++++++++++++++++
 hello.h     |  7 +++++++
 3 files changed, 67 insertions(+)
 create mode 100644 hello-led.c
 create mode 100644 hello.h

diff --git a/hello-led.c b/hello-led.c
new file mode 100644
index 0000000..43230cd
--- /dev/null
+++ b/hello-led.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "hello.h"
+
+int main(int argc, char *argv[])
+{
+	int fd;
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s <device> <led>\n", argv[0]);
+		return 1;
+	}
+
+	fd = open(argv[1], O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "open() failed: %s\n", strerror(errno));
+		return 1;
+	}
+
+	if (strcmp(argv[2], "heartbeat") == 0)
+		ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 0);
+	else if (strcmp(argv[2], "net") == 0)
+		ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 1);
+	else if (strcmp(argv[2], "disk") == 0)
+		ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 2);
+	else
+		fprintf(stderr, "unknown led\n");
+
+	close(fd);
+
+	return 0;
+}
diff --git a/hello.c b/hello.c
index f664121..c42c75f 100644
--- a/hello.c
+++ b/hello.c
@@ -7,6 +7,7 @@
 #include <linux/device.h>
 #include <linux/pci.h>
 #include <linux/cdev.h>
+#include "hello.h"
 
 struct hello_dev {
 	struct device *dev;
@@ -95,12 +96,33 @@ static ssize_t hello_write(struct file *f, const char __user *u, size_t s,
 	return s;
 }
 
+static long hello_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+	struct hello_dev *hello = f->private_data;
+	u32 val;
+
+	dev_info(hello->dev, "%s: cmd=%u arg=%lu\n", __func__, cmd, arg);
+
+	switch (cmd) {
+	case HELLO_IOCTL_TOGGLE_LED:
+		val = arg;
+		if (val >= 0 && val <= 2)
+			toggle_led(hello, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct file_operations hello_fops = {
 	.owner = THIS_MODULE,
 	.open = hello_open,
 	.release = hello_release,
 	.read = hello_read,
 	.write = hello_write,
+	.unlocked_ioctl = hello_ioctl,
 };
 
 static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
diff --git a/hello.h b/hello.h
new file mode 100644
index 0000000..cb172d9
--- /dev/null
+++ b/hello.h
@@ -0,0 +1,7 @@
+#ifndef HELLO_H
+#define HELLO_H
+
+#define HELLO_BASE		0x9F
+#define HELLO_IOCTL_TOGGLE_LED	_IOW(HELLO_BASE, 0x00, unsigned int)
+
+#endif /* HELLO_H */
-- 
2.11.0