1 // SPDX-License-Identifier: GPL-2.0
3 * Greybus driver for the Raw protocol
5 * Copyright 2015 Google Inc.
6 * Copyright 2015 Linaro Ltd.
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>
14 #include <linux/idr.h>
15 #include <linux/uaccess.h>
16 #include <linux/greybus.h>
19 struct gb_connection *connection;
21 struct list_head list;
23 struct mutex list_lock;
26 struct device *device;
30 struct list_head entry;
32 u8 data[] __counted_by(len);
35 static const struct class raw_class = {
40 static const struct file_operations raw_fops;
41 static DEFINE_IDA(minors);
43 /* Number of minor devices this driver supports */
44 #define NUM_MINORS 256
46 /* Maximum size of any one send data buffer we support */
47 #define MAX_PACKET_SIZE (PAGE_SIZE * 2)
50 * Maximum size of the data in the receive buffer we allow before we start to
51 * drop messages on the floor
53 #define MAX_DATA_SIZE (MAX_PACKET_SIZE * 8)
56 * Add the raw data message to the list of received messages.
58 static int receive_data(struct gb_raw *raw, u32 len, u8 *data)
60 struct raw_data *raw_data;
61 struct device *dev = &raw->connection->bundle->dev;
64 if (len > MAX_PACKET_SIZE) {
65 dev_err(dev, "Too big of a data packet, rejected\n");
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");
76 raw_data = kmalloc(struct_size(raw_data, data, len), GFP_KERNEL);
82 raw->list_data += len;
84 memcpy(&raw_data->data[0], data, len);
86 list_add_tail(&raw_data->entry, &raw->list);
88 mutex_unlock(&raw->list_lock);
92 static int gb_raw_request_handler(struct gb_operation *op)
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;
100 if (op->type != GB_RAW_TYPE_SEND) {
101 dev_err(dev, "unknown request type 0x%02x\n", op->type);
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));
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)));
119 dev_err(dev, "raw receive request of 0 bytes?\n");
123 return receive_data(raw, len, receive->data);
126 static int gb_raw_send(struct gb_raw *raw, u32 len, const char __user *data)
128 struct gb_connection *connection = raw->connection;
129 struct gb_raw_send_request *request;
132 request = kmalloc(len + sizeof(*request), GFP_KERNEL);
136 if (copy_from_user(&request->data[0], data, len)) {
141 request->len = cpu_to_le32(len);
143 retval = gb_operation_sync(connection, GB_RAW_TYPE_SEND,
144 request, len + sizeof(*request),
151 static int gb_raw_probe(struct gb_bundle *bundle,
152 const struct greybus_bundle_id *id)
154 struct greybus_descriptor_cport *cport_desc;
155 struct gb_connection *connection;
160 if (bundle->num_cports != 1)
163 cport_desc = &bundle->cport_desc[0];
164 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_RAW)
167 raw = kzalloc(sizeof(*raw), GFP_KERNEL);
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);
178 INIT_LIST_HEAD(&raw->list);
179 mutex_init(&raw->list_lock);
181 raw->connection = connection;
182 greybus_set_drvdata(bundle, raw);
184 minor = ida_alloc(&minors, GFP_KERNEL);
187 goto error_connection_destroy;
190 raw->dev = MKDEV(raw_major, minor);
191 cdev_init(&raw->cdev, &raw_fops);
193 retval = gb_connection_enable(connection);
195 goto error_remove_ida;
197 retval = cdev_add(&raw->cdev, raw->dev, 1);
199 goto error_connection_disable;
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);
211 cdev_del(&raw->cdev);
213 error_connection_disable:
214 gb_connection_disable(connection);
217 ida_free(&minors, minor);
219 error_connection_destroy:
220 gb_connection_destroy(connection);
227 static void gb_raw_disconnect(struct gb_bundle *bundle)
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;
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);
241 mutex_lock(&raw->list_lock);
242 list_for_each_entry_safe(raw_data, temp, &raw->list, entry) {
243 list_del(&raw_data->entry);
246 mutex_unlock(&raw->list_lock);
252 * Character device node interfaces.
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
260 static int raw_open(struct inode *inode, struct file *file)
262 struct cdev *cdev = inode->i_cdev;
263 struct gb_raw *raw = container_of(cdev, struct gb_raw, cdev);
265 file->private_data = raw;
269 static ssize_t raw_write(struct file *file, const char __user *buf,
270 size_t count, loff_t *ppos)
272 struct gb_raw *raw = file->private_data;
278 if (count > MAX_PACKET_SIZE)
281 retval = gb_raw_send(raw, count, buf);
288 static ssize_t raw_read(struct file *file, char __user *buf, size_t count,
291 struct gb_raw *raw = file->private_data;
293 struct raw_data *raw_data;
295 mutex_lock(&raw->list_lock);
296 if (list_empty(&raw->list))
299 raw_data = list_first_entry(&raw->list, struct raw_data, entry);
300 if (raw_data->len > count) {
305 if (copy_to_user(buf, &raw_data->data[0], raw_data->len)) {
310 list_del(&raw_data->entry);
311 raw->list_data -= raw_data->len;
312 retval = raw_data->len;
316 mutex_unlock(&raw->list_lock);
320 static const struct file_operations raw_fops = {
321 .owner = THIS_MODULE,
325 .llseek = noop_llseek,
328 static const struct greybus_bundle_id gb_raw_id_table[] = {
329 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_RAW) },
332 MODULE_DEVICE_TABLE(greybus, gb_raw_id_table);
334 static struct greybus_driver gb_raw_driver = {
336 .probe = gb_raw_probe,
337 .disconnect = gb_raw_disconnect,
338 .id_table = gb_raw_id_table,
341 static int raw_init(void)
346 retval = class_register(&raw_class);
350 retval = alloc_chrdev_region(&dev, 0, NUM_MINORS, "gb_raw");
354 raw_major = MAJOR(dev);
356 retval = greybus_register(&gb_raw_driver);
363 unregister_chrdev_region(dev, NUM_MINORS);
365 class_unregister(&raw_class);
369 module_init(raw_init);
371 static void __exit raw_exit(void)
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);
378 module_exit(raw_exit);
380 MODULE_LICENSE("GPL v2");