1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
4  * Copyright (c) 2010-2012 Broadcom. All rights reserved.
5  */
6 
7 #include <linux/cdev.h>
8 #include <linux/fs.h>
9 #include <linux/device.h>
10 #include <linux/slab.h>
11 #include <linux/compat.h>
12 #include <linux/miscdevice.h>
13 
14 #include "vchiq_core.h"
15 #include "vchiq_ioctl.h"
16 #include "vchiq_arm.h"
17 #include "vchiq_debugfs.h"
18 
19 static const char *const ioctl_names[] = {
20 	"CONNECT",
21 	"SHUTDOWN",
22 	"CREATE_SERVICE",
23 	"REMOVE_SERVICE",
24 	"QUEUE_MESSAGE",
25 	"QUEUE_BULK_TRANSMIT",
26 	"QUEUE_BULK_RECEIVE",
27 	"AWAIT_COMPLETION",
28 	"DEQUEUE_MESSAGE",
29 	"GET_CLIENT_ID",
30 	"GET_CONFIG",
31 	"CLOSE_SERVICE",
32 	"USE_SERVICE",
33 	"RELEASE_SERVICE",
34 	"SET_SERVICE_OPTION",
35 	"DUMP_PHYS_MEM",
36 	"LIB_VERSION",
37 	"CLOSE_DELIVERED"
38 };
39 
40 static_assert(ARRAY_SIZE(ioctl_names) == (VCHIQ_IOC_MAX + 1));
41 
42 static void
user_service_free(void * userdata)43 user_service_free(void *userdata)
44 {
45 	kfree(userdata);
46 }
47 
close_delivered(struct user_service * user_service)48 static void close_delivered(struct user_service *user_service)
49 {
50 	dev_dbg(user_service->service->state->dev,
51 		"arm: (handle=%x)\n", user_service->service->handle);
52 
53 	if (user_service->close_pending) {
54 		/* Allow the underlying service to be culled */
55 		vchiq_service_put(user_service->service);
56 
57 		/* Wake the user-thread blocked in close_ or remove_service */
58 		complete(&user_service->close_event);
59 
60 		user_service->close_pending = 0;
61 	}
62 }
63 
64 struct vchiq_io_copy_callback_context {
65 	struct vchiq_element *element;
66 	size_t element_offset;
67 	unsigned long elements_to_go;
68 };
69 
vchiq_ioc_copy_element_data(void * context,void * dest,size_t offset,size_t maxsize)70 static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest,
71 					   size_t offset, size_t maxsize)
72 {
73 	struct vchiq_io_copy_callback_context *cc = context;
74 	size_t total_bytes_copied = 0;
75 	size_t bytes_this_round;
76 
77 	while (total_bytes_copied < maxsize) {
78 		if (!cc->elements_to_go)
79 			return total_bytes_copied;
80 
81 		if (!cc->element->size) {
82 			cc->elements_to_go--;
83 			cc->element++;
84 			cc->element_offset = 0;
85 			continue;
86 		}
87 
88 		bytes_this_round = min(cc->element->size - cc->element_offset,
89 				       maxsize - total_bytes_copied);
90 
91 		if (copy_from_user(dest + total_bytes_copied,
92 				   cc->element->data + cc->element_offset,
93 				   bytes_this_round))
94 			return -EFAULT;
95 
96 		cc->element_offset += bytes_this_round;
97 		total_bytes_copied += bytes_this_round;
98 
99 		if (cc->element_offset == cc->element->size) {
100 			cc->elements_to_go--;
101 			cc->element++;
102 			cc->element_offset = 0;
103 		}
104 	}
105 
106 	return maxsize;
107 }
108 
109 static int
vchiq_ioc_queue_message(struct vchiq_instance * instance,unsigned int handle,struct vchiq_element * elements,unsigned long count)110 vchiq_ioc_queue_message(struct vchiq_instance *instance, unsigned int handle,
111 			struct vchiq_element *elements, unsigned long count)
112 {
113 	struct vchiq_io_copy_callback_context context;
114 	int status = 0;
115 	unsigned long i;
116 	size_t total_size = 0;
117 
118 	context.element = elements;
119 	context.element_offset = 0;
120 	context.elements_to_go = count;
121 
122 	for (i = 0; i < count; i++) {
123 		if (!elements[i].data && elements[i].size != 0)
124 			return -EFAULT;
125 
126 		total_size += elements[i].size;
127 	}
128 
129 	status = vchiq_queue_message(instance, handle, vchiq_ioc_copy_element_data,
130 				     &context, total_size);
131 
132 	if (status == -EINVAL)
133 		return -EIO;
134 	else if (status == -EAGAIN)
135 		return -EINTR;
136 	return 0;
137 }
138 
vchiq_ioc_create_service(struct vchiq_instance * instance,struct vchiq_create_service * args)139 static int vchiq_ioc_create_service(struct vchiq_instance *instance,
140 				    struct vchiq_create_service *args)
141 {
142 	struct user_service *user_service = NULL;
143 	struct vchiq_service *service;
144 	int status = 0;
145 	struct vchiq_service_params_kernel params;
146 	int srvstate;
147 
148 	if (args->is_open && !instance->connected)
149 		return -ENOTCONN;
150 
151 	user_service = kmalloc(sizeof(*user_service), GFP_KERNEL);
152 	if (!user_service)
153 		return -ENOMEM;
154 
155 	if (args->is_open) {
156 		srvstate = VCHIQ_SRVSTATE_OPENING;
157 	} else {
158 		srvstate = instance->connected ?
159 			 VCHIQ_SRVSTATE_LISTENING : VCHIQ_SRVSTATE_HIDDEN;
160 	}
161 
162 	params = (struct vchiq_service_params_kernel) {
163 		.fourcc   = args->params.fourcc,
164 		.callback = service_callback,
165 		.userdata = user_service,
166 		.version  = args->params.version,
167 		.version_min = args->params.version_min,
168 	};
169 	service = vchiq_add_service_internal(instance->state, &params,
170 					     srvstate, instance,
171 					     user_service_free);
172 	if (!service) {
173 		kfree(user_service);
174 		return -EEXIST;
175 	}
176 
177 	user_service->service = service;
178 	user_service->userdata = args->params.userdata;
179 	user_service->instance = instance;
180 	user_service->is_vchi = (args->is_vchi != 0);
181 	user_service->dequeue_pending = 0;
182 	user_service->close_pending = 0;
183 	user_service->message_available_pos = instance->completion_remove - 1;
184 	user_service->msg_insert = 0;
185 	user_service->msg_remove = 0;
186 	init_completion(&user_service->insert_event);
187 	init_completion(&user_service->remove_event);
188 	init_completion(&user_service->close_event);
189 
190 	if (args->is_open) {
191 		status = vchiq_open_service_internal(service, instance->pid);
192 		if (status) {
193 			vchiq_remove_service(instance, service->handle);
194 			return (status == -EAGAIN) ?
195 				-EINTR : -EIO;
196 		}
197 	}
198 	args->handle = service->handle;
199 
200 	return 0;
201 }
202 
vchiq_ioc_dequeue_message(struct vchiq_instance * instance,struct vchiq_dequeue_message * args)203 static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance,
204 				     struct vchiq_dequeue_message *args)
205 {
206 	struct user_service *user_service;
207 	struct vchiq_service *service;
208 	struct vchiq_header *header;
209 	int ret;
210 
211 	DEBUG_INITIALISE(instance->state->local);
212 	DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
213 	service = find_service_for_instance(instance, args->handle);
214 	if (!service)
215 		return -EINVAL;
216 
217 	user_service = (struct user_service *)service->base.userdata;
218 	if (user_service->is_vchi == 0) {
219 		ret = -EINVAL;
220 		goto out;
221 	}
222 
223 	spin_lock(&service->state->msg_queue_spinlock);
224 	if (user_service->msg_remove == user_service->msg_insert) {
225 		if (!args->blocking) {
226 			spin_unlock(&service->state->msg_queue_spinlock);
227 			DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
228 			ret = -EWOULDBLOCK;
229 			goto out;
230 		}
231 		user_service->dequeue_pending = 1;
232 		ret = 0;
233 		do {
234 			spin_unlock(&service->state->msg_queue_spinlock);
235 			DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
236 			if (wait_for_completion_interruptible(&user_service->insert_event)) {
237 				dev_dbg(service->state->dev, "arm: DEQUEUE_MESSAGE interrupted\n");
238 				ret = -EINTR;
239 				break;
240 			}
241 			spin_lock(&service->state->msg_queue_spinlock);
242 		} while (user_service->msg_remove == user_service->msg_insert);
243 
244 		if (ret)
245 			goto out;
246 	}
247 
248 	if (WARN_ON_ONCE((int)(user_service->msg_insert -
249 			 user_service->msg_remove) < 0)) {
250 		spin_unlock(&service->state->msg_queue_spinlock);
251 		ret = -EINVAL;
252 		goto out;
253 	}
254 
255 	header = user_service->msg_queue[user_service->msg_remove &
256 		(MSG_QUEUE_SIZE - 1)];
257 	user_service->msg_remove++;
258 	spin_unlock(&service->state->msg_queue_spinlock);
259 
260 	complete(&user_service->remove_event);
261 	if (!header) {
262 		ret = -ENOTCONN;
263 	} else if (header->size <= args->bufsize) {
264 		/* Copy to user space if msgbuf is not NULL */
265 		if (!args->buf || (copy_to_user(args->buf, header->data, header->size) == 0)) {
266 			ret = header->size;
267 			vchiq_release_message(instance, service->handle, header);
268 		} else {
269 			ret = -EFAULT;
270 		}
271 	} else {
272 		dev_err(service->state->dev,
273 			"arm: header %pK: bufsize %x < size %x\n",
274 			header, args->bufsize, header->size);
275 		WARN(1, "invalid size\n");
276 		ret = -EMSGSIZE;
277 	}
278 	DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
279 out:
280 	vchiq_service_put(service);
281 	return ret;
282 }
283 
vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance * instance,struct vchiq_queue_bulk_transfer * args,enum vchiq_bulk_dir dir,enum vchiq_bulk_mode __user * mode)284 static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
285 				      struct vchiq_queue_bulk_transfer *args,
286 				      enum vchiq_bulk_dir dir,
287 				      enum vchiq_bulk_mode __user *mode)
288 {
289 	struct vchiq_service *service;
290 	struct bulk_waiter_node *waiter = NULL, *iter;
291 	struct vchiq_bulk bulk_params = {};
292 	int status = 0;
293 	int ret;
294 
295 	service = find_service_for_instance(instance, args->handle);
296 	if (!service)
297 		return -EINVAL;
298 
299 	if (args->mode == VCHIQ_BULK_MODE_BLOCKING) {
300 		waiter = kzalloc(sizeof(*waiter), GFP_KERNEL);
301 		if (!waiter) {
302 			ret = -ENOMEM;
303 			goto out;
304 		}
305 
306 		bulk_params.uoffset = args->data;
307 		bulk_params.mode = args->mode;
308 		bulk_params.size = args->size;
309 		bulk_params.dir = dir;
310 		bulk_params.waiter = &waiter->bulk_waiter;
311 
312 		status = vchiq_bulk_xfer_blocking(instance, args->handle,
313 						  &bulk_params);
314 	} else if (args->mode == VCHIQ_BULK_MODE_WAITING) {
315 		mutex_lock(&instance->bulk_waiter_list_mutex);
316 		list_for_each_entry(iter, &instance->bulk_waiter_list,
317 				    list) {
318 			if (iter->pid == current->pid) {
319 				list_del(&iter->list);
320 				waiter = iter;
321 				break;
322 			}
323 		}
324 		mutex_unlock(&instance->bulk_waiter_list_mutex);
325 		if (!waiter) {
326 			dev_err(service->state->dev,
327 				"arm: no bulk_waiter found for pid %d\n", current->pid);
328 			ret = -ESRCH;
329 			goto out;
330 		}
331 		dev_dbg(service->state->dev, "arm: found bulk_waiter %pK for pid %d\n",
332 			waiter, current->pid);
333 
334 		status = vchiq_bulk_xfer_waiting(instance, args->handle,
335 						 &waiter->bulk_waiter);
336 	} else {
337 		bulk_params.uoffset = args->data;
338 		bulk_params.mode = args->mode;
339 		bulk_params.size = args->size;
340 		bulk_params.dir = dir;
341 		bulk_params.cb_userdata = args->userdata;
342 
343 		status = vchiq_bulk_xfer_callback(instance, args->handle,
344 						  &bulk_params);
345 	}
346 
347 	if (!waiter) {
348 		ret = 0;
349 		goto out;
350 	}
351 
352 	if ((status != -EAGAIN) || fatal_signal_pending(current) ||
353 	    !waiter->bulk_waiter.bulk) {
354 		if (waiter->bulk_waiter.bulk) {
355 			/* Cancel the signal when the transfer completes. */
356 			spin_lock(&service->state->bulk_waiter_spinlock);
357 			waiter->bulk_waiter.bulk->waiter = NULL;
358 			spin_unlock(&service->state->bulk_waiter_spinlock);
359 		}
360 		kfree(waiter);
361 		ret = 0;
362 	} else {
363 		const enum vchiq_bulk_mode mode_waiting =
364 			VCHIQ_BULK_MODE_WAITING;
365 		waiter->pid = current->pid;
366 		mutex_lock(&instance->bulk_waiter_list_mutex);
367 		list_add(&waiter->list, &instance->bulk_waiter_list);
368 		mutex_unlock(&instance->bulk_waiter_list_mutex);
369 		dev_dbg(service->state->dev, "arm: saved bulk_waiter %pK for pid %d\n",
370 			waiter, current->pid);
371 
372 		ret = put_user(mode_waiting, mode);
373 	}
374 out:
375 	vchiq_service_put(service);
376 	if (ret)
377 		return ret;
378 	else if (status == -EINVAL)
379 		return -EIO;
380 	else if (status == -EAGAIN)
381 		return -EINTR;
382 	return 0;
383 }
384 
385 /* read a user pointer value from an array pointers in user space */
vchiq_get_user_ptr(void __user ** buf,void __user * ubuf,int index)386 static inline int vchiq_get_user_ptr(void __user **buf, void __user *ubuf, int index)
387 {
388 	int ret;
389 
390 	if (in_compat_syscall()) {
391 		compat_uptr_t ptr32;
392 		compat_uptr_t __user *uptr = ubuf;
393 
394 		ret = get_user(ptr32, uptr + index);
395 		if (ret)
396 			return ret;
397 
398 		*buf = compat_ptr(ptr32);
399 	} else {
400 		uintptr_t ptr, __user *uptr = ubuf;
401 
402 		ret = get_user(ptr, uptr + index);
403 
404 		if (ret)
405 			return ret;
406 
407 		*buf = (void __user *)ptr;
408 	}
409 
410 	return 0;
411 }
412 
413 struct vchiq_completion_data32 {
414 	enum vchiq_reason reason;
415 	compat_uptr_t header;
416 	compat_uptr_t service_userdata;
417 	compat_uptr_t cb_data;
418 };
419 
vchiq_put_completion(struct vchiq_completion_data __user * buf,struct vchiq_completion_data * completion,int index)420 static int vchiq_put_completion(struct vchiq_completion_data __user *buf,
421 				struct vchiq_completion_data *completion,
422 				int index)
423 {
424 	struct vchiq_completion_data32 __user *buf32 = (void __user *)buf;
425 
426 	if (in_compat_syscall()) {
427 		struct vchiq_completion_data32 tmp = {
428 			.reason		  = completion->reason,
429 			.header		  = ptr_to_compat(completion->header),
430 			.service_userdata = ptr_to_compat(completion->service_userdata),
431 			.cb_data	  = ptr_to_compat(completion->cb_userdata),
432 		};
433 		if (copy_to_user(&buf32[index], &tmp, sizeof(tmp)))
434 			return -EFAULT;
435 	} else {
436 		if (copy_to_user(&buf[index], completion, sizeof(*completion)))
437 			return -EFAULT;
438 	}
439 
440 	return 0;
441 }
442 
vchiq_ioc_await_completion(struct vchiq_instance * instance,struct vchiq_await_completion * args,int __user * msgbufcountp)443 static int vchiq_ioc_await_completion(struct vchiq_instance *instance,
444 				      struct vchiq_await_completion *args,
445 				      int __user *msgbufcountp)
446 {
447 	int msgbufcount;
448 	int remove;
449 	int ret;
450 
451 	DEBUG_INITIALISE(instance->state->local);
452 
453 	DEBUG_TRACE(AWAIT_COMPLETION_LINE);
454 	if (!instance->connected)
455 		return -ENOTCONN;
456 
457 	mutex_lock(&instance->completion_mutex);
458 
459 	DEBUG_TRACE(AWAIT_COMPLETION_LINE);
460 	while ((instance->completion_remove == instance->completion_insert) && !instance->closing) {
461 		int rc;
462 
463 		DEBUG_TRACE(AWAIT_COMPLETION_LINE);
464 		mutex_unlock(&instance->completion_mutex);
465 		rc = wait_for_completion_interruptible(&instance->insert_event);
466 		mutex_lock(&instance->completion_mutex);
467 		if (rc) {
468 			DEBUG_TRACE(AWAIT_COMPLETION_LINE);
469 			dev_dbg(instance->state->dev, "arm: AWAIT_COMPLETION interrupted\n");
470 			ret = -EINTR;
471 			goto out;
472 		}
473 	}
474 	DEBUG_TRACE(AWAIT_COMPLETION_LINE);
475 
476 	msgbufcount = args->msgbufcount;
477 	remove = instance->completion_remove;
478 
479 	for (ret = 0; ret < args->count; ret++) {
480 		struct vchiq_completion_data_kernel *completion;
481 		struct vchiq_completion_data user_completion;
482 		struct vchiq_service *service;
483 		struct user_service *user_service;
484 		struct vchiq_header *header;
485 
486 		if (remove == instance->completion_insert)
487 			break;
488 
489 		completion = &instance->completions[remove & (MAX_COMPLETIONS - 1)];
490 
491 		/*
492 		 * A read memory barrier is needed to stop
493 		 * prefetch of a stale completion record
494 		 */
495 		rmb();
496 
497 		service = completion->service_userdata;
498 		user_service = service->base.userdata;
499 
500 		memset(&user_completion, 0, sizeof(user_completion));
501 		user_completion = (struct vchiq_completion_data) {
502 			.reason = completion->reason,
503 			.service_userdata = user_service->userdata,
504 		};
505 
506 		header = completion->header;
507 		if (header) {
508 			void __user *msgbuf;
509 			int msglen;
510 
511 			msglen = header->size + sizeof(struct vchiq_header);
512 			/* This must be a VCHIQ-style service */
513 			if (args->msgbufsize < msglen) {
514 				dev_err(service->state->dev,
515 					"arm: header %pK: msgbufsize %x < msglen %x\n",
516 					header, args->msgbufsize, msglen);
517 				WARN(1, "invalid message size\n");
518 				if (ret == 0)
519 					ret = -EMSGSIZE;
520 				break;
521 			}
522 			if (msgbufcount <= 0)
523 				/* Stall here for lack of a buffer for the message. */
524 				break;
525 			/* Get the pointer from user space */
526 			msgbufcount--;
527 			if (vchiq_get_user_ptr(&msgbuf, args->msgbufs,
528 					       msgbufcount)) {
529 				if (ret == 0)
530 					ret = -EFAULT;
531 				break;
532 			}
533 
534 			/* Copy the message to user space */
535 			if (copy_to_user(msgbuf, header, msglen)) {
536 				if (ret == 0)
537 					ret = -EFAULT;
538 				break;
539 			}
540 
541 			/* Now it has been copied, the message can be released. */
542 			vchiq_release_message(instance, service->handle, header);
543 
544 			/* The completion must point to the msgbuf. */
545 			user_completion.header = msgbuf;
546 		}
547 
548 		if ((completion->reason == VCHIQ_SERVICE_CLOSED) &&
549 		    !instance->use_close_delivered)
550 			vchiq_service_put(service);
551 
552 		user_completion.cb_userdata = completion->cb_userdata;
553 
554 		if (vchiq_put_completion(args->buf, &user_completion, ret)) {
555 			if (ret == 0)
556 				ret = -EFAULT;
557 			break;
558 		}
559 
560 		/*
561 		 * Ensure that the above copy has completed
562 		 * before advancing the remove pointer.
563 		 */
564 		mb();
565 		remove++;
566 		instance->completion_remove = remove;
567 	}
568 
569 	if (msgbufcount != args->msgbufcount) {
570 		if (put_user(msgbufcount, msgbufcountp))
571 			ret = -EFAULT;
572 	}
573 out:
574 	if (ret)
575 		complete(&instance->remove_event);
576 	mutex_unlock(&instance->completion_mutex);
577 	DEBUG_TRACE(AWAIT_COMPLETION_LINE);
578 
579 	return ret;
580 }
581 
582 static long
vchiq_ioctl(struct file * file,unsigned int cmd,unsigned long arg)583 vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
584 {
585 	struct vchiq_instance *instance = file->private_data;
586 	int status = 0;
587 	struct vchiq_service *service = NULL;
588 	long ret = 0;
589 	int i, rc;
590 
591 	dev_dbg(instance->state->dev, "arm: instance %pK, cmd %s, arg %lx\n", instance,
592 		((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
593 		ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
594 
595 	switch (cmd) {
596 	case VCHIQ_IOC_SHUTDOWN:
597 		if (!instance->connected)
598 			break;
599 
600 		/* Remove all services */
601 		i = 0;
602 		while ((service = next_service_by_instance(instance->state,
603 							   instance, &i))) {
604 			status = vchiq_remove_service(instance, service->handle);
605 			vchiq_service_put(service);
606 			if (status)
607 				break;
608 		}
609 		service = NULL;
610 
611 		if (!status) {
612 			/* Wake the completion thread and ask it to exit */
613 			instance->closing = 1;
614 			complete(&instance->insert_event);
615 		}
616 
617 		break;
618 
619 	case VCHIQ_IOC_CONNECT:
620 		if (instance->connected) {
621 			ret = -EINVAL;
622 			break;
623 		}
624 		rc = mutex_lock_killable(&instance->state->mutex);
625 		if (rc) {
626 			dev_err(instance->state->dev,
627 				"arm: vchiq: connect: could not lock mutex for state %d: %d\n",
628 				instance->state->id, rc);
629 			ret = -EINTR;
630 			break;
631 		}
632 		status = vchiq_connect_internal(instance->state, instance);
633 		mutex_unlock(&instance->state->mutex);
634 
635 		if (!status)
636 			instance->connected = 1;
637 		else
638 			dev_err(instance->state->dev,
639 				"arm: vchiq: could not connect: %d\n", status);
640 		break;
641 
642 	case VCHIQ_IOC_CREATE_SERVICE: {
643 		struct vchiq_create_service __user *argp;
644 		struct vchiq_create_service args;
645 
646 		argp = (void __user *)arg;
647 		if (copy_from_user(&args, argp, sizeof(args))) {
648 			ret = -EFAULT;
649 			break;
650 		}
651 
652 		ret = vchiq_ioc_create_service(instance, &args);
653 		if (ret < 0)
654 			break;
655 
656 		if (put_user(args.handle, &argp->handle)) {
657 			vchiq_remove_service(instance, args.handle);
658 			ret = -EFAULT;
659 		}
660 	} break;
661 
662 	case VCHIQ_IOC_CLOSE_SERVICE:
663 	case VCHIQ_IOC_REMOVE_SERVICE: {
664 		unsigned int handle = (unsigned int)arg;
665 		struct user_service *user_service;
666 
667 		service = find_service_for_instance(instance, handle);
668 		if (!service) {
669 			ret = -EINVAL;
670 			break;
671 		}
672 
673 		user_service = service->base.userdata;
674 
675 		/*
676 		 * close_pending is false on first entry, and when the
677 		 * wait in vchiq_close_service has been interrupted.
678 		 */
679 		if (!user_service->close_pending) {
680 			status = (cmd == VCHIQ_IOC_CLOSE_SERVICE) ?
681 				 vchiq_close_service(instance, service->handle) :
682 				 vchiq_remove_service(instance, service->handle);
683 			if (status)
684 				break;
685 		}
686 
687 		/*
688 		 * close_pending is true once the underlying service
689 		 * has been closed until the client library calls the
690 		 * CLOSE_DELIVERED ioctl, signalling close_event.
691 		 */
692 		if (user_service->close_pending &&
693 		    wait_for_completion_interruptible(&user_service->close_event))
694 			status = -EAGAIN;
695 		break;
696 	}
697 
698 	case VCHIQ_IOC_USE_SERVICE:
699 	case VCHIQ_IOC_RELEASE_SERVICE:	{
700 		unsigned int handle = (unsigned int)arg;
701 
702 		service = find_service_for_instance(instance, handle);
703 		if (service) {
704 			ret = (cmd == VCHIQ_IOC_USE_SERVICE) ?
705 				vchiq_use_service_internal(service) :
706 				vchiq_release_service_internal(service);
707 			if (ret) {
708 				dev_err(instance->state->dev,
709 					"suspend: cmd %s returned error %ld for service %p4cc:%03d\n",
710 					(cmd == VCHIQ_IOC_USE_SERVICE) ?
711 					"VCHIQ_IOC_USE_SERVICE" :
712 					"VCHIQ_IOC_RELEASE_SERVICE",
713 					ret, &service->base.fourcc,
714 					service->client_id);
715 			}
716 		} else {
717 			ret = -EINVAL;
718 		}
719 	} break;
720 
721 	case VCHIQ_IOC_QUEUE_MESSAGE: {
722 		struct vchiq_queue_message args;
723 
724 		if (copy_from_user(&args, (const void __user *)arg,
725 				   sizeof(args))) {
726 			ret = -EFAULT;
727 			break;
728 		}
729 
730 		service = find_service_for_instance(instance, args.handle);
731 
732 		if (service && (args.count <= MAX_ELEMENTS)) {
733 			/* Copy elements into kernel space */
734 			struct vchiq_element elements[MAX_ELEMENTS];
735 
736 			if (copy_from_user(elements, args.elements,
737 					   args.count * sizeof(struct vchiq_element)) == 0)
738 				ret = vchiq_ioc_queue_message(instance, args.handle, elements,
739 							      args.count);
740 			else
741 				ret = -EFAULT;
742 		} else {
743 			ret = -EINVAL;
744 		}
745 	} break;
746 
747 	case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
748 	case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
749 		struct vchiq_queue_bulk_transfer args;
750 		struct vchiq_queue_bulk_transfer __user *argp;
751 
752 		enum vchiq_bulk_dir dir =
753 			(cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
754 			VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
755 
756 		argp = (void __user *)arg;
757 		if (copy_from_user(&args, argp, sizeof(args))) {
758 			ret = -EFAULT;
759 			break;
760 		}
761 
762 		ret = vchiq_irq_queue_bulk_tx_rx(instance, &args,
763 						 dir, &argp->mode);
764 	} break;
765 
766 	case VCHIQ_IOC_AWAIT_COMPLETION: {
767 		struct vchiq_await_completion args;
768 		struct vchiq_await_completion __user *argp;
769 
770 		argp = (void __user *)arg;
771 		if (copy_from_user(&args, argp, sizeof(args))) {
772 			ret = -EFAULT;
773 			break;
774 		}
775 
776 		ret = vchiq_ioc_await_completion(instance, &args,
777 						 &argp->msgbufcount);
778 	} break;
779 
780 	case VCHIQ_IOC_DEQUEUE_MESSAGE: {
781 		struct vchiq_dequeue_message args;
782 
783 		if (copy_from_user(&args, (const void __user *)arg,
784 				   sizeof(args))) {
785 			ret = -EFAULT;
786 			break;
787 		}
788 
789 		ret = vchiq_ioc_dequeue_message(instance, &args);
790 	} break;
791 
792 	case VCHIQ_IOC_GET_CLIENT_ID: {
793 		unsigned int handle = (unsigned int)arg;
794 
795 		ret = vchiq_get_client_id(instance, handle);
796 	} break;
797 
798 	case VCHIQ_IOC_GET_CONFIG: {
799 		struct vchiq_get_config args;
800 		struct vchiq_config config;
801 
802 		if (copy_from_user(&args, (const void __user *)arg,
803 				   sizeof(args))) {
804 			ret = -EFAULT;
805 			break;
806 		}
807 		if (args.config_size > sizeof(config)) {
808 			ret = -EINVAL;
809 			break;
810 		}
811 
812 		vchiq_get_config(&config);
813 		if (copy_to_user(args.pconfig, &config, args.config_size)) {
814 			ret = -EFAULT;
815 			break;
816 		}
817 	} break;
818 
819 	case VCHIQ_IOC_SET_SERVICE_OPTION: {
820 		struct vchiq_set_service_option args;
821 
822 		if (copy_from_user(&args, (const void __user *)arg,
823 				   sizeof(args))) {
824 			ret = -EFAULT;
825 			break;
826 		}
827 
828 		service = find_service_for_instance(instance, args.handle);
829 		if (!service) {
830 			ret = -EINVAL;
831 			break;
832 		}
833 
834 		ret = vchiq_set_service_option(instance, args.handle, args.option,
835 					       args.value);
836 	} break;
837 
838 	case VCHIQ_IOC_LIB_VERSION: {
839 		unsigned int lib_version = (unsigned int)arg;
840 
841 		if (lib_version < VCHIQ_VERSION_MIN)
842 			ret = -EINVAL;
843 		else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
844 			instance->use_close_delivered = 1;
845 	} break;
846 
847 	case VCHIQ_IOC_CLOSE_DELIVERED: {
848 		unsigned int handle = (unsigned int)arg;
849 
850 		service = find_closed_service_for_instance(instance, handle);
851 		if (service) {
852 			struct user_service *user_service =
853 				(struct user_service *)service->base.userdata;
854 			close_delivered(user_service);
855 		} else {
856 			ret = -EINVAL;
857 		}
858 	} break;
859 
860 	default:
861 		ret = -ENOTTY;
862 		break;
863 	}
864 
865 	if (service)
866 		vchiq_service_put(service);
867 
868 	if (ret == 0) {
869 		if (status == -EINVAL)
870 			ret = -EIO;
871 		else if (status == -EAGAIN)
872 			ret = -EINTR;
873 	}
874 
875 	if (!status && (ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK)) {
876 		dev_dbg(instance->state->dev,
877 			"arm: ioctl instance %pK, cmd %s -> status %d, %ld\n",
878 			instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
879 			ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
880 	} else {
881 		dev_dbg(instance->state->dev,
882 			"arm: ioctl instance %pK, cmd %s -> status %d\n, %ld\n",
883 			instance, (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
884 			ioctl_names[_IOC_NR(cmd)] : "<invalid>", status, ret);
885 	}
886 
887 	return ret;
888 }
889 
890 #if defined(CONFIG_COMPAT)
891 
892 struct vchiq_service_params32 {
893 	int fourcc;
894 	compat_uptr_t callback;
895 	compat_uptr_t userdata;
896 	short version; /* Increment for non-trivial changes */
897 	short version_min; /* Update for incompatible changes */
898 };
899 
900 struct vchiq_create_service32 {
901 	struct vchiq_service_params32 params;
902 	int is_open;
903 	int is_vchi;
904 	unsigned int handle; /* OUT */
905 };
906 
907 #define VCHIQ_IOC_CREATE_SERVICE32 \
908 	_IOWR(VCHIQ_IOC_MAGIC, 2, struct vchiq_create_service32)
909 
910 static long
vchiq_compat_ioctl_create_service(struct file * file,unsigned int cmd,struct vchiq_create_service32 __user * ptrargs32)911 vchiq_compat_ioctl_create_service(struct file *file, unsigned int cmd,
912 				  struct vchiq_create_service32 __user *ptrargs32)
913 {
914 	struct vchiq_create_service args;
915 	struct vchiq_create_service32 args32;
916 	struct vchiq_instance *instance = file->private_data;
917 	long ret;
918 
919 	if (copy_from_user(&args32, ptrargs32, sizeof(args32)))
920 		return -EFAULT;
921 
922 	args = (struct vchiq_create_service) {
923 		.params = {
924 			.fourcc	     = args32.params.fourcc,
925 			.callback    = compat_ptr(args32.params.callback),
926 			.userdata    = compat_ptr(args32.params.userdata),
927 			.version     = args32.params.version,
928 			.version_min = args32.params.version_min,
929 		},
930 		.is_open = args32.is_open,
931 		.is_vchi = args32.is_vchi,
932 		.handle  = args32.handle,
933 	};
934 
935 	ret = vchiq_ioc_create_service(instance, &args);
936 	if (ret < 0)
937 		return ret;
938 
939 	if (put_user(args.handle, &ptrargs32->handle)) {
940 		vchiq_remove_service(instance, args.handle);
941 		return -EFAULT;
942 	}
943 
944 	return 0;
945 }
946 
947 struct vchiq_element32 {
948 	compat_uptr_t data;
949 	unsigned int size;
950 };
951 
952 struct vchiq_queue_message32 {
953 	unsigned int handle;
954 	unsigned int count;
955 	compat_uptr_t elements;
956 };
957 
958 #define VCHIQ_IOC_QUEUE_MESSAGE32 \
959 	_IOW(VCHIQ_IOC_MAGIC,  4, struct vchiq_queue_message32)
960 
961 static long
vchiq_compat_ioctl_queue_message(struct file * file,unsigned int cmd,struct vchiq_queue_message32 __user * arg)962 vchiq_compat_ioctl_queue_message(struct file *file,
963 				 unsigned int cmd,
964 				 struct vchiq_queue_message32 __user *arg)
965 {
966 	struct vchiq_queue_message args;
967 	struct vchiq_queue_message32 args32;
968 	struct vchiq_service *service;
969 	struct vchiq_instance *instance = file->private_data;
970 	int ret;
971 
972 	if (copy_from_user(&args32, arg, sizeof(args32)))
973 		return -EFAULT;
974 
975 	args = (struct vchiq_queue_message) {
976 		.handle   = args32.handle,
977 		.count    = args32.count,
978 		.elements = compat_ptr(args32.elements),
979 	};
980 
981 	if (args32.count > MAX_ELEMENTS)
982 		return -EINVAL;
983 
984 	service = find_service_for_instance(instance, args.handle);
985 	if (!service)
986 		return -EINVAL;
987 
988 	if (args32.elements && args32.count) {
989 		struct vchiq_element32 element32[MAX_ELEMENTS];
990 		struct vchiq_element elements[MAX_ELEMENTS];
991 		unsigned int count;
992 
993 		if (copy_from_user(&element32, args.elements,
994 				   sizeof(element32))) {
995 			vchiq_service_put(service);
996 			return -EFAULT;
997 		}
998 
999 		for (count = 0; count < args32.count; count++) {
1000 			elements[count].data =
1001 				compat_ptr(element32[count].data);
1002 			elements[count].size = element32[count].size;
1003 		}
1004 		ret = vchiq_ioc_queue_message(instance, args.handle, elements,
1005 					      args.count);
1006 	} else {
1007 		ret = -EINVAL;
1008 	}
1009 	vchiq_service_put(service);
1010 
1011 	return ret;
1012 }
1013 
1014 struct vchiq_queue_bulk_transfer32 {
1015 	unsigned int handle;
1016 	compat_uptr_t data;
1017 	unsigned int size;
1018 	compat_uptr_t userdata;
1019 	enum vchiq_bulk_mode mode;
1020 };
1021 
1022 #define VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 \
1023 	_IOWR(VCHIQ_IOC_MAGIC, 5, struct vchiq_queue_bulk_transfer32)
1024 #define VCHIQ_IOC_QUEUE_BULK_RECEIVE32 \
1025 	_IOWR(VCHIQ_IOC_MAGIC, 6, struct vchiq_queue_bulk_transfer32)
1026 
1027 static long
vchiq_compat_ioctl_queue_bulk(struct file * file,unsigned int cmd,struct vchiq_queue_bulk_transfer32 __user * argp)1028 vchiq_compat_ioctl_queue_bulk(struct file *file,
1029 			      unsigned int cmd,
1030 			      struct vchiq_queue_bulk_transfer32 __user *argp)
1031 {
1032 	struct vchiq_queue_bulk_transfer32 args32;
1033 	struct vchiq_queue_bulk_transfer args;
1034 	enum vchiq_bulk_dir dir = (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32) ?
1035 				  VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
1036 
1037 	if (copy_from_user(&args32, argp, sizeof(args32)))
1038 		return -EFAULT;
1039 
1040 	args = (struct vchiq_queue_bulk_transfer) {
1041 		.handle   = args32.handle,
1042 		.data	  = compat_ptr(args32.data),
1043 		.size	  = args32.size,
1044 		.userdata = compat_ptr(args32.userdata),
1045 		.mode	  = args32.mode,
1046 	};
1047 
1048 	return vchiq_irq_queue_bulk_tx_rx(file->private_data, &args,
1049 					  dir, &argp->mode);
1050 }
1051 
1052 struct vchiq_await_completion32 {
1053 	unsigned int count;
1054 	compat_uptr_t buf;
1055 	unsigned int msgbufsize;
1056 	unsigned int msgbufcount; /* IN/OUT */
1057 	compat_uptr_t msgbufs;
1058 };
1059 
1060 #define VCHIQ_IOC_AWAIT_COMPLETION32 \
1061 	_IOWR(VCHIQ_IOC_MAGIC, 7, struct vchiq_await_completion32)
1062 
1063 static long
vchiq_compat_ioctl_await_completion(struct file * file,unsigned int cmd,struct vchiq_await_completion32 __user * argp)1064 vchiq_compat_ioctl_await_completion(struct file *file,
1065 				    unsigned int cmd,
1066 				    struct vchiq_await_completion32 __user *argp)
1067 {
1068 	struct vchiq_await_completion args;
1069 	struct vchiq_await_completion32 args32;
1070 
1071 	if (copy_from_user(&args32, argp, sizeof(args32)))
1072 		return -EFAULT;
1073 
1074 	args = (struct vchiq_await_completion) {
1075 		.count		= args32.count,
1076 		.buf		= compat_ptr(args32.buf),
1077 		.msgbufsize	= args32.msgbufsize,
1078 		.msgbufcount	= args32.msgbufcount,
1079 		.msgbufs	= compat_ptr(args32.msgbufs),
1080 	};
1081 
1082 	return vchiq_ioc_await_completion(file->private_data, &args,
1083 					  &argp->msgbufcount);
1084 }
1085 
1086 struct vchiq_dequeue_message32 {
1087 	unsigned int handle;
1088 	int blocking;
1089 	unsigned int bufsize;
1090 	compat_uptr_t buf;
1091 };
1092 
1093 #define VCHIQ_IOC_DEQUEUE_MESSAGE32 \
1094 	_IOWR(VCHIQ_IOC_MAGIC, 8, struct vchiq_dequeue_message32)
1095 
1096 static long
vchiq_compat_ioctl_dequeue_message(struct file * file,unsigned int cmd,struct vchiq_dequeue_message32 __user * arg)1097 vchiq_compat_ioctl_dequeue_message(struct file *file,
1098 				   unsigned int cmd,
1099 				   struct vchiq_dequeue_message32 __user *arg)
1100 {
1101 	struct vchiq_dequeue_message32 args32;
1102 	struct vchiq_dequeue_message args;
1103 
1104 	if (copy_from_user(&args32, arg, sizeof(args32)))
1105 		return -EFAULT;
1106 
1107 	args = (struct vchiq_dequeue_message) {
1108 		.handle		= args32.handle,
1109 		.blocking	= args32.blocking,
1110 		.bufsize	= args32.bufsize,
1111 		.buf		= compat_ptr(args32.buf),
1112 	};
1113 
1114 	return vchiq_ioc_dequeue_message(file->private_data, &args);
1115 }
1116 
1117 struct vchiq_get_config32 {
1118 	unsigned int config_size;
1119 	compat_uptr_t pconfig;
1120 };
1121 
1122 #define VCHIQ_IOC_GET_CONFIG32 \
1123 	_IOWR(VCHIQ_IOC_MAGIC, 10, struct vchiq_get_config32)
1124 
1125 static long
vchiq_compat_ioctl_get_config(struct file * file,unsigned int cmd,struct vchiq_get_config32 __user * arg)1126 vchiq_compat_ioctl_get_config(struct file *file,
1127 			      unsigned int cmd,
1128 			      struct vchiq_get_config32 __user *arg)
1129 {
1130 	struct vchiq_get_config32 args32;
1131 	struct vchiq_config config;
1132 	void __user *ptr;
1133 
1134 	if (copy_from_user(&args32, arg, sizeof(args32)))
1135 		return -EFAULT;
1136 	if (args32.config_size > sizeof(config))
1137 		return -EINVAL;
1138 
1139 	vchiq_get_config(&config);
1140 	ptr = compat_ptr(args32.pconfig);
1141 	if (copy_to_user(ptr, &config, args32.config_size))
1142 		return -EFAULT;
1143 
1144 	return 0;
1145 }
1146 
1147 static long
vchiq_compat_ioctl(struct file * file,unsigned int cmd,unsigned long arg)1148 vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1149 {
1150 	void __user *argp = compat_ptr(arg);
1151 
1152 	switch (cmd) {
1153 	case VCHIQ_IOC_CREATE_SERVICE32:
1154 		return vchiq_compat_ioctl_create_service(file, cmd, argp);
1155 	case VCHIQ_IOC_QUEUE_MESSAGE32:
1156 		return vchiq_compat_ioctl_queue_message(file, cmd, argp);
1157 	case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32:
1158 	case VCHIQ_IOC_QUEUE_BULK_RECEIVE32:
1159 		return vchiq_compat_ioctl_queue_bulk(file, cmd, argp);
1160 	case VCHIQ_IOC_AWAIT_COMPLETION32:
1161 		return vchiq_compat_ioctl_await_completion(file, cmd, argp);
1162 	case VCHIQ_IOC_DEQUEUE_MESSAGE32:
1163 		return vchiq_compat_ioctl_dequeue_message(file, cmd, argp);
1164 	case VCHIQ_IOC_GET_CONFIG32:
1165 		return vchiq_compat_ioctl_get_config(file, cmd, argp);
1166 	default:
1167 		return vchiq_ioctl(file, cmd, (unsigned long)argp);
1168 	}
1169 }
1170 
1171 #endif
1172 
vchiq_open(struct inode * inode,struct file * file)1173 static int vchiq_open(struct inode *inode, struct file *file)
1174 {
1175 	struct miscdevice *vchiq_miscdev = file->private_data;
1176 	struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(vchiq_miscdev->parent);
1177 	struct vchiq_state *state = &mgmt->state;
1178 	struct vchiq_instance *instance;
1179 
1180 	dev_dbg(state->dev, "arm: vchiq open\n");
1181 
1182 	if (!vchiq_remote_initialised(state)) {
1183 		dev_dbg(state->dev, "arm: vchiq has no connection to VideoCore\n");
1184 		return -ENOTCONN;
1185 	}
1186 
1187 	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
1188 	if (!instance)
1189 		return -ENOMEM;
1190 
1191 	instance->state = state;
1192 	instance->pid = current->tgid;
1193 
1194 	vchiq_debugfs_add_instance(instance);
1195 
1196 	init_completion(&instance->insert_event);
1197 	init_completion(&instance->remove_event);
1198 	mutex_init(&instance->completion_mutex);
1199 	mutex_init(&instance->bulk_waiter_list_mutex);
1200 	INIT_LIST_HEAD(&instance->bulk_waiter_list);
1201 
1202 	file->private_data = instance;
1203 
1204 	return 0;
1205 }
1206 
vchiq_release(struct inode * inode,struct file * file)1207 static int vchiq_release(struct inode *inode, struct file *file)
1208 {
1209 	struct vchiq_instance *instance = file->private_data;
1210 	struct vchiq_state *state = instance->state;
1211 	struct vchiq_service *service;
1212 	int ret = 0;
1213 	int i;
1214 
1215 	dev_dbg(state->dev, "arm: instance=%p\n", instance);
1216 
1217 	if (!vchiq_remote_initialised(state)) {
1218 		ret = -EPERM;
1219 		goto out;
1220 	}
1221 
1222 	/* Ensure videocore is awake to allow termination. */
1223 	vchiq_use_internal(instance->state, NULL, USE_TYPE_VCHIQ);
1224 
1225 	mutex_lock(&instance->completion_mutex);
1226 
1227 	/* Wake the completion thread and ask it to exit */
1228 	instance->closing = 1;
1229 	complete(&instance->insert_event);
1230 
1231 	mutex_unlock(&instance->completion_mutex);
1232 
1233 	/* Wake the slot handler if the completion queue is full. */
1234 	complete(&instance->remove_event);
1235 
1236 	/* Mark all services for termination... */
1237 	i = 0;
1238 	while ((service = next_service_by_instance(state, instance, &i))) {
1239 		struct user_service *user_service = service->base.userdata;
1240 
1241 		/* Wake the slot handler if the msg queue is full. */
1242 		complete(&user_service->remove_event);
1243 
1244 		vchiq_terminate_service_internal(service);
1245 		vchiq_service_put(service);
1246 	}
1247 
1248 	/* ...and wait for them to die */
1249 	i = 0;
1250 	while ((service = next_service_by_instance(state, instance, &i))) {
1251 		struct user_service *user_service = service->base.userdata;
1252 
1253 		wait_for_completion(&service->remove_event);
1254 
1255 		if (WARN_ON(service->srvstate != VCHIQ_SRVSTATE_FREE)) {
1256 			vchiq_service_put(service);
1257 			break;
1258 		}
1259 
1260 		spin_lock(&service->state->msg_queue_spinlock);
1261 
1262 		while (user_service->msg_remove != user_service->msg_insert) {
1263 			struct vchiq_header *header;
1264 			int m = user_service->msg_remove & (MSG_QUEUE_SIZE - 1);
1265 
1266 			header = user_service->msg_queue[m];
1267 			user_service->msg_remove++;
1268 			spin_unlock(&service->state->msg_queue_spinlock);
1269 
1270 			if (header)
1271 				vchiq_release_message(instance, service->handle, header);
1272 			spin_lock(&service->state->msg_queue_spinlock);
1273 		}
1274 
1275 		spin_unlock(&service->state->msg_queue_spinlock);
1276 
1277 		vchiq_service_put(service);
1278 	}
1279 
1280 	/* Release any closed services */
1281 	while (instance->completion_remove != instance->completion_insert) {
1282 		struct vchiq_completion_data_kernel *completion;
1283 		struct vchiq_service *service;
1284 
1285 		completion = &instance->completions[instance->completion_remove
1286 						    & (MAX_COMPLETIONS - 1)];
1287 		service = completion->service_userdata;
1288 		if (completion->reason == VCHIQ_SERVICE_CLOSED) {
1289 			struct user_service *user_service =
1290 							service->base.userdata;
1291 
1292 			/* Wake any blocked user-thread */
1293 			if (instance->use_close_delivered)
1294 				complete(&user_service->close_event);
1295 			vchiq_service_put(service);
1296 		}
1297 		instance->completion_remove++;
1298 	}
1299 
1300 	/* Release the PEER service count. */
1301 	vchiq_release_internal(instance->state, NULL);
1302 
1303 	free_bulk_waiter(instance);
1304 
1305 	vchiq_debugfs_remove_instance(instance);
1306 
1307 	kfree(instance);
1308 	file->private_data = NULL;
1309 
1310 out:
1311 	return ret;
1312 }
1313 
1314 static const struct file_operations
1315 vchiq_fops = {
1316 	.owner = THIS_MODULE,
1317 	.unlocked_ioctl = vchiq_ioctl,
1318 #if defined(CONFIG_COMPAT)
1319 	.compat_ioctl = vchiq_compat_ioctl,
1320 #endif
1321 	.open = vchiq_open,
1322 	.release = vchiq_release,
1323 };
1324 
1325 static struct miscdevice vchiq_miscdev = {
1326 	.fops = &vchiq_fops,
1327 	.minor = MISC_DYNAMIC_MINOR,
1328 	.name = "vchiq",
1329 
1330 };
1331 
1332 /**
1333  *	vchiq_register_chrdev - Register the char driver for vchiq
1334  *				and create the necessary class and
1335  *				device files in userspace.
1336  *	@parent:	The parent of the char device.
1337  *
1338  *	Returns 0 on success else returns the error code.
1339  */
vchiq_register_chrdev(struct device * parent)1340 int vchiq_register_chrdev(struct device *parent)
1341 {
1342 	vchiq_miscdev.parent = parent;
1343 
1344 	return misc_register(&vchiq_miscdev);
1345 }
1346 
1347 /**
1348  *	vchiq_deregister_chrdev	- Deregister and cleanup the vchiq char
1349  *				  driver and device files
1350  */
vchiq_deregister_chrdev(void)1351 void vchiq_deregister_chrdev(void)
1352 {
1353 	misc_deregister(&vchiq_miscdev);
1354 }
1355