1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Greybus driver for the Raw protocol
4 *
5 * Copyright 2015 Google Inc.
6 * Copyright 2015 Linaro Ltd.
7 */
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/slab.h>
11#include <linux/sizes.h>
12#include <linux/cdev.h>
13#include <linux/fs.h>
14#include <linux/idr.h>
15#include <linux/uaccess.h>
16#include <linux/greybus.h>
17
18struct gb_raw {
19	struct gb_connection *connection;
20
21	struct list_head list;
22	int list_data;
23	struct mutex list_lock;
24	dev_t dev;
25	struct cdev cdev;
26	struct device *device;
27};
28
29struct raw_data {
30	struct list_head entry;
31	u32 len;
32	u8 data[] __counted_by(len);
33};
34
35static const struct class raw_class = {
36	.name = "gb_raw",
37};
38
39static int raw_major;
40static const struct file_operations raw_fops;
41static DEFINE_IDA(minors);
42
43/* Number of minor devices this driver supports */
44#define NUM_MINORS	256
45
46/* Maximum size of any one send data buffer we support */
47#define MAX_PACKET_SIZE	(PAGE_SIZE * 2)
48
49/*
50 * Maximum size of the data in the receive buffer we allow before we start to
51 * drop messages on the floor
52 */
53#define MAX_DATA_SIZE	(MAX_PACKET_SIZE * 8)
54
55/*
56 * Add the raw data message to the list of received messages.
57 */
58static int receive_data(struct gb_raw *raw, u32 len, u8 *data)
59{
60	struct raw_data *raw_data;
61	struct device *dev = &raw->connection->bundle->dev;
62	int retval = 0;
63
64	if (len > MAX_PACKET_SIZE) {
65		dev_err(dev, "Too big of a data packet, rejected\n");
66		return -EINVAL;
67	}
68
69	mutex_lock(&raw->list_lock);
70	if ((raw->list_data + len) > MAX_DATA_SIZE) {
71		dev_err(dev, "Too much data in receive buffer, now dropping packets\n");
72		retval = -EINVAL;
73		goto exit;
74	}
75
76	raw_data = kmalloc(struct_size(raw_data, data, len), GFP_KERNEL);
77	if (!raw_data) {
78		retval = -ENOMEM;
79		goto exit;
80	}
81
82	raw->list_data += len;
83	raw_data->len = len;
84	memcpy(&raw_data->data[0], data, len);
85
86	list_add_tail(&raw_data->entry, &raw->list);
87exit:
88	mutex_unlock(&raw->list_lock);
89	return retval;
90}
91
92static int gb_raw_request_handler(struct gb_operation *op)
93{
94	struct gb_connection *connection = op->connection;
95	struct device *dev = &connection->bundle->dev;
96	struct gb_raw *raw = greybus_get_drvdata(connection->bundle);
97	struct gb_raw_send_request *receive;
98	u32 len;
99
100	if (op->type != GB_RAW_TYPE_SEND) {
101		dev_err(dev, "unknown request type 0x%02x\n", op->type);
102		return -EINVAL;
103	}
104
105	/* Verify size of payload */
106	if (op->request->payload_size < sizeof(*receive)) {
107		dev_err(dev, "raw receive request too small (%zu < %zu)\n",
108			op->request->payload_size, sizeof(*receive));
109		return -EINVAL;
110	}
111	receive = op->request->payload;
112	len = le32_to_cpu(receive->len);
113	if (len != (int)(op->request->payload_size - sizeof(__le32))) {
114		dev_err(dev, "raw receive request wrong size %d vs %d\n", len,
115			(int)(op->request->payload_size - sizeof(__le32)));
116		return -EINVAL;
117	}
118	if (len == 0) {
119		dev_err(dev, "raw receive request of 0 bytes?\n");
120		return -EINVAL;
121	}
122
123	return receive_data(raw, len, receive->data);
124}
125
126static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
127{
128	struct gb_connection *connection = raw->connection;
129	struct gb_raw_send_request *request;
130	int retval;
131
132	request = kmalloc(len + sizeof(*request), GFP_KERNEL);
133	if (!request)
134		return -ENOMEM;
135
136	if (copy_from_user(&request->data[0], data, len)) {
137		kfree(request);
138		return -EFAULT;
139	}
140
141	request->len = cpu_to_le32(len);
142
143	retval = gb_operation_sync(connection, GB_RAW_TYPE_SEND,
144				   request, len + sizeof(*request),
145				   NULL, 0);
146
147	kfree(request);
148	return retval;
149}
150
151static int gb_raw_probe(struct gb_bundle *bundle,
152			const struct greybus_bundle_id *id)
153{
154	struct greybus_descriptor_cport *cport_desc;
155	struct gb_connection *connection;
156	struct gb_raw *raw;
157	int retval;
158	int minor;
159
160	if (bundle->num_cports != 1)
161		return -ENODEV;
162
163	cport_desc = &bundle->cport_desc[0];
164	if (cport_desc->protocol_id != GREYBUS_PROTOCOL_RAW)
165		return -ENODEV;
166
167	raw = kzalloc(sizeof(*raw), GFP_KERNEL);
168	if (!raw)
169		return -ENOMEM;
170
171	connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
172					  gb_raw_request_handler);
173	if (IS_ERR(connection)) {
174		retval = PTR_ERR(connection);
175		goto error_free;
176	}
177
178	INIT_LIST_HEAD(&raw->list);
179	mutex_init(&raw->list_lock);
180
181	raw->connection = connection;
182	greybus_set_drvdata(bundle, raw);
183
184	minor = ida_alloc(&minors, GFP_KERNEL);
185	if (minor < 0) {
186		retval = minor;
187		goto error_connection_destroy;
188	}
189
190	raw->dev = MKDEV(raw_major, minor);
191	cdev_init(&raw->cdev, &raw_fops);
192
193	retval = gb_connection_enable(connection);
194	if (retval)
195		goto error_remove_ida;
196
197	retval = cdev_add(&raw->cdev, raw->dev, 1);
198	if (retval)
199		goto error_connection_disable;
200
201	raw->device = device_create(&raw_class, &connection->bundle->dev,
202				    raw->dev, raw, "gb!raw%d", minor);
203	if (IS_ERR(raw->device)) {
204		retval = PTR_ERR(raw->device);
205		goto error_del_cdev;
206	}
207
208	return 0;
209
210error_del_cdev:
211	cdev_del(&raw->cdev);
212
213error_connection_disable:
214	gb_connection_disable(connection);
215
216error_remove_ida:
217	ida_free(&minors, minor);
218
219error_connection_destroy:
220	gb_connection_destroy(connection);
221
222error_free:
223	kfree(raw);
224	return retval;
225}
226
227static void gb_raw_disconnect(struct gb_bundle *bundle)
228{
229	struct gb_raw *raw = greybus_get_drvdata(bundle);
230	struct gb_connection *connection = raw->connection;
231	struct raw_data *raw_data;
232	struct raw_data *temp;
233
234	// FIXME - handle removing a connection when the char device node is open.
235	device_destroy(&raw_class, raw->dev);
236	cdev_del(&raw->cdev);
237	gb_connection_disable(connection);
238	ida_free(&minors, MINOR(raw->dev));
239	gb_connection_destroy(connection);
240
241	mutex_lock(&raw->list_lock);
242	list_for_each_entry_safe(raw_data, temp, &raw->list, entry) {
243		list_del(&raw_data->entry);
244		kfree(raw_data);
245	}
246	mutex_unlock(&raw->list_lock);
247
248	kfree(raw);
249}
250
251/*
252 * Character device node interfaces.
253 *
254 * Note, we are using read/write to only allow a single read/write per message.
255 * This means for read(), you have to provide a big enough buffer for the full
256 * message to be copied into.  If the buffer isn't big enough, the read() will
257 * fail with -ENOSPC.
258 */
259
260static int raw_open(struct inode *inode, struct file *file)
261{
262	struct cdev *cdev = inode->i_cdev;
263	struct gb_raw *raw = container_of(cdev, struct gb_raw, cdev);
264
265	file->private_data = raw;
266	return 0;
267}
268
269static ssize_t raw_write(struct file *file, const char __user *buf,
270			 size_t count, loff_t *ppos)
271{
272	struct gb_raw *raw = file->private_data;
273	int retval;
274
275	if (!count)
276		return 0;
277
278	if (count > MAX_PACKET_SIZE)
279		return -E2BIG;
280
281	retval = gb_raw_send(raw, count, buf);
282	if (retval)
283		return retval;
284
285	return count;
286}
287
288static ssize_t raw_read(struct file *file, char __user *buf, size_t count,
289			loff_t *ppos)
290{
291	struct gb_raw *raw = file->private_data;
292	int retval = 0;
293	struct raw_data *raw_data;
294
295	mutex_lock(&raw->list_lock);
296	if (list_empty(&raw->list))
297		goto exit;
298
299	raw_data = list_first_entry(&raw->list, struct raw_data, entry);
300	if (raw_data->len > count) {
301		retval = -ENOSPC;
302		goto exit;
303	}
304
305	if (copy_to_user(buf, &raw_data->data[0], raw_data->len)) {
306		retval = -EFAULT;
307		goto exit;
308	}
309
310	list_del(&raw_data->entry);
311	raw->list_data -= raw_data->len;
312	retval = raw_data->len;
313	kfree(raw_data);
314
315exit:
316	mutex_unlock(&raw->list_lock);
317	return retval;
318}
319
320static const struct file_operations raw_fops = {
321	.owner		= THIS_MODULE,
322	.write		= raw_write,
323	.read		= raw_read,
324	.open		= raw_open,
325	.llseek		= noop_llseek,
326};
327
328static const struct greybus_bundle_id gb_raw_id_table[] = {
329	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_RAW) },
330	{ }
331};
332MODULE_DEVICE_TABLE(greybus, gb_raw_id_table);
333
334static struct greybus_driver gb_raw_driver = {
335	.name		= "raw",
336	.probe		= gb_raw_probe,
337	.disconnect	= gb_raw_disconnect,
338	.id_table	= gb_raw_id_table,
339};
340
341static int raw_init(void)
342{
343	dev_t dev;
344	int retval;
345
346	retval = class_register(&raw_class);
347	if (retval)
348		goto error_class;
349
350	retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw");
351	if (retval < 0)
352		goto error_chrdev;
353
354	raw_major = MAJOR(dev);
355
356	retval = greybus_register(&gb_raw_driver);
357	if (retval)
358		goto error_gb;
359
360	return 0;
361
362error_gb:
363	unregister_chrdev_region(dev, NUM_MINORS);
364error_chrdev:
365	class_unregister(&raw_class);
366error_class:
367	return retval;
368}
369module_init(raw_init);
370
371static void __exit raw_exit(void)
372{
373	greybus_deregister(&gb_raw_driver);
374	unregister_chrdev_region(MKDEV(raw_major, 0), NUM_MINORS);
375	class_unregister(&raw_class);
376	ida_destroy(&minors);
377}
378module_exit(raw_exit);
379
380MODULE_LICENSE("GPL v2");
381