Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Feb 2015 19:54:03 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278277 - in head/sys: arm/broadcom/bcm2835 conf contrib/vchiq contrib/vchiq/interface contrib/vchiq/interface/compat contrib/vchiq/interface/vchi contrib/vchiq/interface/vchi/connectio...
Message-ID:  <201502051954.t15Js3Rw013083@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Thu Feb  5 19:54:03 2015
New Revision: 278277
URL: https://svnweb.freebsd.org/changeset/base/278277

Log:
  Import VCHI driver for Broadcom's VideoCore IV GPU
  
  Differential Revision:	D1753

Added:
  head/sys/contrib/vchiq/
  head/sys/contrib/vchiq/interface/
  head/sys/contrib/vchiq/interface/compat/
  head/sys/contrib/vchiq/interface/compat/list.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/compat/vchi_bsd.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/compat/vchi_bsd.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/
  head/sys/contrib/vchiq/interface/vchi/connections/
  head/sys/contrib/vchiq/interface/vchi/connections/connection.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/message_drivers/
  head/sys/contrib/vchiq/interface/vchi/message_drivers/message.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/vchi.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/vchi_cfg.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/vchi_cfg_internal.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/vchi_common.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchi/vchi_mh.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_build_info.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_cfg.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_connected.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_core.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_if.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_memdrv.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_proc.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_shim.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.h   (contents, props changed)
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_version.c   (contents, props changed)
Modified:
  head/sys/arm/broadcom/bcm2835/files.bcm2835
  head/sys/conf/kern.pre.mk

Modified: head/sys/arm/broadcom/bcm2835/files.bcm2835
==============================================================================
--- head/sys/arm/broadcom/bcm2835/files.bcm2835	Thu Feb  5 19:36:29 2015	(r278276)
+++ head/sys/arm/broadcom/bcm2835/files.bcm2835	Thu Feb  5 19:54:03 2015	(r278277)
@@ -27,3 +27,23 @@ kern/kern_clocksource.c                 
 
 dev/mbox/mbox_if.m				standard
 dev/ofw/ofw_cpu.c				standard
+
+# VideoCore driver
+contrib/vchiq/interface/compat/vchi_bsd.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c	standard \
+	compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_arm.c	standard \
+	compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_connected.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_core.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_shim.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
+contrib/vchiq/interface/vchiq_arm/vchiq_util.c	standard \
+	compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"

Modified: head/sys/conf/kern.pre.mk
==============================================================================
--- head/sys/conf/kern.pre.mk	Thu Feb  5 19:36:29 2015	(r278276)
+++ head/sys/conf/kern.pre.mk	Thu Feb  5 19:54:03 2015	(r278277)
@@ -79,6 +79,9 @@ INCLUDES+= -I$S/dev/ath -I$S/dev/ath/ath
 # ... and the same for the NgATM stuff
 INCLUDES+= -I$S/contrib/ngatm
 
+# ... and the same for vchiq
+INCLUDES+= -I$S/contrib/vchiq
+
 # ... and the same for twa
 INCLUDES+= -I$S/dev/twa
 

Added: head/sys/contrib/vchiq/interface/compat/list.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/contrib/vchiq/interface/compat/list.h	Thu Feb  5 19:54:03 2015	(r278277)
@@ -0,0 +1,256 @@
+/*	$NetBSD: list.h,v 1.5 2014/08/20 15:26:52 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION 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.
+ */
+
+/*
+ * Notes on porting:
+ *
+ * - LIST_HEAD(x) means a declaration `struct list_head x =
+ *   LIST_HEAD_INIT(x)' in Linux, but something else in NetBSD.
+ *   Replace by the expansion.
+ *
+ * - The `_rcu' routines here are not actually pserialize(9)-safe.
+ *   They need dependent read memory barriers added.  Please fix this
+ *   if you need to use them with pserialize(9).
+ */
+
+#ifndef _LINUX_LIST_H_
+#define _LINUX_LIST_H_
+
+#include <sys/queue.h>
+
+#define container_of(ptr, type, member)				\
+({								\
+	__typeof(((type *)0)->member) *_p = (ptr);		\
+	(type *)((char *)_p - offsetof(type, member));		\
+})
+
+/*
+ * Doubly-linked lists.
+ */
+
+struct list_head {
+	struct list_head *prev;
+	struct list_head *next;
+};
+
+#define	LIST_HEAD_INIT(name)	{ .prev = &(name), .next = &(name) }
+
+static inline void
+INIT_LIST_HEAD(struct list_head *head)
+{
+	head->prev = head;
+	head->next = head;
+}
+
+static inline struct list_head *
+list_first(const struct list_head *head)
+{
+	return head->next;
+}
+
+static inline struct list_head *
+list_last(const struct list_head *head)
+{
+	return head->prev;
+}
+
+static inline struct list_head *
+list_next(const struct list_head *node)
+{
+	return node->next;
+}
+
+static inline struct list_head *
+list_prev(const struct list_head *node)
+{
+	return node->prev;
+}
+
+static inline int
+list_empty(const struct list_head *head)
+{
+	return (head->next == head);
+}
+
+static inline int
+list_is_singular(const struct list_head *head)
+{
+
+	if (list_empty(head))
+		return false;
+	if (head->next != head->prev)
+		return false;
+	return true;
+}
+
+static inline void
+__list_add_between(struct list_head *prev, struct list_head *node,
+    struct list_head *next)
+{
+	prev->next = node;
+	node->prev = prev;
+	node->next = next;
+	next->prev = node;
+}
+
+static inline void
+list_add(struct list_head *node, struct list_head *head)
+{
+	__list_add_between(head, node, head->next);
+}
+
+static inline void
+list_add_tail(struct list_head *node, struct list_head *head)
+{
+	__list_add_between(head->prev, node, head);
+}
+
+static inline void
+list_del(struct list_head *entry)
+{
+	entry->prev->next = entry->next;
+	entry->next->prev = entry->prev;
+}
+
+static inline void
+__list_splice_between(struct list_head *prev, const struct list_head *list,
+    struct list_head *next)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+
+	first->prev = prev;
+	prev->next = first;
+
+	last->next = next;
+	next->prev = last;
+}
+
+static inline void
+list_splice(const struct list_head *list, struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice_between(head, list, head->next);
+}
+
+static inline void
+list_splice_tail(const struct list_head *list, struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice_between(head->prev, list, head);
+}
+
+static inline void
+list_move(struct list_head *node, struct list_head *head)
+{
+	list_del(node);
+	list_add(node, head);
+}
+
+static inline void
+list_move_tail(struct list_head *node, struct list_head *head)
+{
+	list_del(node);
+	list_add_tail(node, head);
+}
+
+static inline void
+list_replace(struct list_head *old, struct list_head *new)
+{
+	new->prev = old->prev;
+	old->prev->next = new;
+	new->next = old->next;
+	old->next->prev = new;
+}
+
+static inline void
+list_del_init(struct list_head *node)
+{
+	list_del(node);
+	INIT_LIST_HEAD(node);
+}
+
+#define	list_entry(PTR, TYPE, FIELD)	container_of(PTR, TYPE, FIELD)
+#define	list_first_entry(PTR, TYPE, FIELD)				\
+	list_entry(list_first((PTR)), TYPE, FIELD)
+#define	list_last_entry(PTR, TYPE, FIELD)				\
+	list_entry(list_last((PTR)), TYPE, FIELD)
+#define	list_next_entry(ENTRY, FIELD)					\
+	list_entry(list_next(&(ENTRY)->FIELD), typeof(*(ENTRY)), FIELD)
+#define	list_prev_entry(ENTRY, FIELD)					\
+	list_entry(list_prev(&(ENTRY)->FIELD), typeof(*(ENTRY)), FIELD)
+
+#define	list_for_each(VAR, HEAD)					\
+	for ((VAR) = list_first((HEAD));				\
+		(VAR) != (HEAD);					\
+		(VAR) = list_next((VAR)))
+
+#define	list_for_each_safe(VAR, NEXT, HEAD)				\
+	for ((VAR) = list_first((HEAD));				\
+		((VAR) != (HEAD)) && ((NEXT) = list_next((VAR)), 1);	\
+		(VAR) = (NEXT))
+
+#define	list_for_each_entry(VAR, HEAD, FIELD)				\
+	for ((VAR) = list_entry(list_first((HEAD)), typeof(*(VAR)), FIELD); \
+		&(VAR)->FIELD != (HEAD);				\
+		(VAR) = list_entry(list_next(&(VAR)->FIELD), typeof(*(VAR)), \
+		    FIELD))
+
+#define	list_for_each_entry_reverse(VAR, HEAD, FIELD)			\
+	for ((VAR) = list_entry(list_last((HEAD)), typeof(*(VAR)), FIELD); \
+		&(VAR)->FIELD != (HEAD);				\
+		(VAR) = list_entry(list_prev(&(VAR)->FIELD), typeof(*(VAR)), \
+		    FIELD))
+
+#define	list_for_each_entry_safe(VAR, NEXT, HEAD, FIELD)		\
+	for ((VAR) = list_entry(list_first((HEAD)), typeof(*(VAR)), FIELD); \
+		(&(VAR)->FIELD != (HEAD)) &&				\
+		    ((NEXT) = list_entry(list_next(&(VAR)->FIELD),	\
+			typeof(*(VAR)), FIELD), 1);			\
+		(VAR) = (NEXT))
+
+#define	list_for_each_entry_continue(VAR, HEAD, FIELD)			\
+	for ((VAR) = list_next_entry((VAR), FIELD);			\
+		&(VAR)->FIELD != (HEAD);				\
+		(VAR) = list_next_entry((VAR), FIELD))
+
+#define	list_for_each_entry_continue_reverse(VAR, HEAD, FIELD)		\
+	for ((VAR) = list_prev_entry((VAR), FIELD);			\
+		&(VAR)->FIELD != (HEAD);				\
+		(VAR) = list_prev_entry((VAR), FIELD))
+
+#define	list_for_each_entry_safe_from(VAR, NEXT, HEAD, FIELD)		\
+	for (;								\
+		(&(VAR)->FIELD != (HEAD)) &&				\
+		    ((NEXT) = list_next_entry((VAR), FIELD));		\
+		(VAR) = (NEXT))
+
+#endif  /* _LINUX_LIST_H_ */

Added: head/sys/contrib/vchiq/interface/compat/vchi_bsd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/contrib/vchiq/interface/compat/vchi_bsd.c	Thu Feb  5 19:54:03 2015	(r278277)
@@ -0,0 +1,532 @@
+/*-
+ * Copyright (c) 2010 Max Khon <fjoe@freebsd.org>
+ * All rights reserved.
+ *
+ * This software was developed by Max Khon under sponsorship from
+ * the FreeBSD Foundation and Ethon Technologies GmbH.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ *
+ * $Id: bsd-compat.c 9253 2010-09-02 10:12:09Z fjoe $
+ */
+
+#include <sys/types.h>
+#include <sys/limits.h>
+#include <sys/bus.h>
+#include <sys/callout.h>
+#include <sys/firmware.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/syscallsubr.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
+#include <machine/stdarg.h>
+
+#include "mbox_if.h"
+
+#include <interface/compat/vchi_bsd.h>
+
+MALLOC_DEFINE(M_VCHI, "VCHI", "VCHI");
+
+/*
+ * Timer API
+ */
+static void
+run_timer(void *arg)
+{
+	struct timer_list *t = (struct timer_list *) arg;
+	void (*function)(unsigned long);
+
+	mtx_lock_spin(&t->mtx);
+	if (callout_pending(&t->callout)) {
+		/* callout was reset */
+		mtx_unlock_spin(&t->mtx);
+		return;
+	}
+	if (!callout_active(&t->callout)) {
+		/* callout was stopped */
+		mtx_unlock_spin(&t->mtx);
+		return;
+	}
+	callout_deactivate(&t->callout);
+
+	function = t->function;
+	mtx_unlock_spin(&t->mtx);
+
+	function(t->data);
+}
+
+void
+init_timer(struct timer_list *t)
+{
+	mtx_init(&t->mtx, "dahdi timer lock", NULL, MTX_SPIN);
+	callout_init(&t->callout, CALLOUT_MPSAFE);
+	t->expires = 0;
+	/*
+	 * function and data are not initialized intentionally:
+	 * they are not initialized by Linux implementation too
+	 */
+}
+
+void
+setup_timer(struct timer_list *t, void (*function)(unsigned long), unsigned long data)
+{
+	t->function = function;
+	t->data = data;
+	init_timer(t);
+}
+
+void
+mod_timer(struct timer_list *t, unsigned long expires)
+{
+	mtx_lock_spin(&t->mtx);
+	callout_reset(&t->callout, expires - jiffies, run_timer, t);
+	mtx_unlock_spin(&t->mtx);
+}
+
+void
+add_timer(struct timer_list *t)
+{
+	mod_timer(t, t->expires);
+}
+
+int
+del_timer_sync(struct timer_list *t)
+{
+	mtx_lock_spin(&t->mtx);
+	callout_stop(&t->callout);
+	mtx_unlock_spin(&t->mtx);
+
+	mtx_destroy(&t->mtx);
+	return 0;
+}
+
+int
+del_timer(struct timer_list *t)
+{
+	del_timer_sync(t);
+	return 0;
+}
+
+/*
+ * Completion API
+ */
+void
+init_completion(struct completion *c)
+{
+	cv_init(&c->cv, "VCHI completion cv");
+	mtx_init(&c->lock, "VCHI completion lock", "condvar", MTX_DEF);
+	c->done = 0;
+}
+
+void
+destroy_completion(struct completion *c)
+{
+	cv_destroy(&c->cv);
+	mtx_destroy(&c->lock);
+}
+
+void
+complete(struct completion *c)
+{
+	mtx_lock(&c->lock);
+
+	if (c->done >= 0) {
+		KASSERT(c->done < INT_MAX, ("c->done overflow")); /* XXX check */
+		c->done++;
+		cv_signal(&c->cv);
+	} else {
+		KASSERT(c->done == -1, ("Invalid value of c->done: %d", c->done));
+	}
+
+	mtx_unlock(&c->lock);
+}
+
+void
+complete_all(struct completion *c)
+{
+	mtx_lock(&c->lock);
+
+	if (c->done >= 0) {
+		KASSERT(c->done < INT_MAX, ("c->done overflow")); /* XXX check */
+		c->done = -1;
+		cv_broadcast(&c->cv);
+	} else {
+		KASSERT(c->done == -1, ("Invalid value of c->done: %d", c->done));
+	}
+
+	mtx_unlock(&c->lock);
+}
+
+void
+INIT_COMPLETION_locked(struct completion *c)
+{
+	mtx_lock(&c->lock);
+
+	c->done = 0;
+
+	mtx_unlock(&c->lock);
+}
+
+static void
+_completion_claim(struct completion *c)
+{
+
+	KASSERT(mtx_owned(&c->lock),
+	    ("_completion_claim should be called with acquired lock"));
+	KASSERT(c->done != 0, ("_completion_claim on non-waited completion"));
+	if (c->done > 0)
+		c->done--;
+	else
+		KASSERT(c->done == -1, ("Invalid value of c->done: %d", c->done));
+}
+
+void
+wait_for_completion(struct completion *c)
+{
+	mtx_lock(&c->lock);
+	if (!c->done)
+		cv_wait(&c->cv, &c->lock);
+	c->done--;
+	mtx_unlock(&c->lock);
+}
+
+int
+try_wait_for_completion(struct completion *c)
+{
+	int res = 0;
+
+	mtx_lock(&c->lock);
+	if (!c->done)
+		res = 1;
+	else
+		c->done--;
+	mtx_unlock(&c->lock);
+	return res == 0;
+}
+
+int
+wait_for_completion_interruptible_timeout(struct completion *c, unsigned long timeout)
+{
+	int res = 0;
+	unsigned long start, now;
+	start = jiffies;
+
+	mtx_lock(&c->lock);
+	while (c->done == 0) {
+		res = cv_timedwait_sig(&c->cv, &c->lock, timeout);
+		if (res)
+			goto out;
+		now = jiffies;
+		if (timeout < (now - start)) {
+			res = EWOULDBLOCK;
+			goto out;
+		}
+
+		timeout -= (now - start);
+		start = now;
+	}
+
+	_completion_claim(c);
+	res = 0;
+
+out:
+	mtx_unlock(&c->lock);
+
+	if (res == EWOULDBLOCK) {
+		return 0;
+	} else if ((res == EINTR) || (res == ERESTART)) {
+		return -ERESTART;
+	} else {
+		KASSERT((res == 0), ("res = %d", res));
+		return timeout;
+	}
+}
+
+int
+wait_for_completion_interruptible(struct completion *c)
+{
+	int res = 0;
+
+	mtx_lock(&c->lock);
+	while (c->done == 0) {
+		res = cv_wait_sig(&c->cv, &c->lock);
+		if (res)
+			goto out;
+	}
+
+	_completion_claim(c);
+
+out:
+	mtx_unlock(&c->lock);
+
+	if ((res == EINTR) || (res == ERESTART))
+		res = -ERESTART;
+	return res;
+}
+
+int
+wait_for_completion_killable(struct completion *c)
+{
+
+	return wait_for_completion_interruptible(c);
+}
+
+/*
+ * Semaphore API
+ */
+
+void sema_sysinit(void *arg)
+{
+	struct semaphore *s = arg;
+
+	printf("sema_sysinit\n");
+	_sema_init(s, 1);
+}
+
+void
+_sema_init(struct semaphore *s, int value)
+{
+	bzero(s, sizeof(*s));
+	mtx_init(&s->mtx, "sema lock", "VCHIQ sepmaphore backing lock",
+		MTX_DEF | MTX_NOWITNESS | MTX_QUIET);
+	cv_init(&s->cv, "sema cv");
+	s->value = value;
+}
+
+void
+_sema_destroy(struct semaphore *s)
+{
+	mtx_destroy(&s->mtx);
+	cv_destroy(&s->cv);
+}
+
+void
+down(struct semaphore *s)
+{
+
+	mtx_lock(&s->mtx);
+	while (s->value == 0) {
+		s->waiters++;
+		cv_wait(&s->cv, &s->mtx);
+		s->waiters--;
+	}
+
+	s->value--;
+	mtx_unlock(&s->mtx);
+}
+
+int
+down_interruptible(struct semaphore *s)
+{
+	int ret ;
+
+	ret = 0;
+
+	mtx_lock(&s->mtx);
+
+	while (s->value == 0) {
+		s->waiters++;
+		ret = cv_wait_sig(&s->cv, &s->mtx);
+		s->waiters--;
+
+		if (ret == EINTR) {
+			mtx_unlock(&s->mtx);
+			return (-EINTR);
+		}
+
+		if (ret == ERESTART)
+			continue;
+	}
+
+	s->value--;
+	mtx_unlock(&s->mtx);
+
+	return (0);
+}
+
+int
+down_trylock(struct semaphore *s)
+{
+	int ret;
+
+	ret = 0;
+
+	mtx_lock(&s->mtx);
+
+	if (s->value > 0) {
+		/* Success. */
+		s->value--;
+		ret = 0;
+	} else {
+		ret = -EAGAIN;
+	}
+
+	mtx_unlock(&s->mtx);
+
+	return (ret);
+}
+
+void
+up(struct semaphore *s)
+{
+	mtx_lock(&s->mtx);
+	s->value++;
+	if (s->waiters && s->value > 0)
+		cv_signal(&s->cv);
+
+	mtx_unlock(&s->mtx);
+}
+
+/*
+ * Logging API
+ */
+void
+rlprintf(int pps, const char *fmt, ...)
+{
+	va_list ap;
+	static struct timeval last_printf;
+	static int count;
+
+	if (ppsratecheck(&last_printf, &count, pps)) {
+		va_start(ap, fmt);
+		vprintf(fmt, ap);
+		va_end(ap);
+	}
+}
+
+void
+device_rlprintf(int pps, device_t dev, const char *fmt, ...)
+{
+	va_list ap;
+	static struct timeval last_printf;
+	static int count;
+
+	if (ppsratecheck(&last_printf, &count, pps)) {
+		va_start(ap, fmt);
+		device_print_prettyname(dev);
+		vprintf(fmt, ap);
+		va_end(ap);
+	}
+}
+
+/*
+ * Signals API
+ */
+
+void
+flush_signals(VCHIQ_THREAD_T thr)
+{
+	printf("Implement ME: %s\n", __func__);
+}
+
+int
+fatal_signal_pending(VCHIQ_THREAD_T thr)
+{
+	printf("Implement ME: %s\n", __func__);
+	return (0);
+}
+
+/*
+ * kthread API
+ */
+
+/*
+ *  This is a hack to avoid memory leak
+ */
+#define MAX_THREAD_DATA_SLOTS	32
+static int thread_data_slot = 0;
+
+struct thread_data {
+	void *data;
+	int (*threadfn)(void *);
+};
+
+static struct thread_data thread_slots[MAX_THREAD_DATA_SLOTS];
+
+static void
+kthread_wrapper(void *data)
+{
+	struct thread_data *slot;
+
+	slot = data;
+	slot->threadfn(slot->data);
+}
+
+VCHIQ_THREAD_T
+vchiq_thread_create(int (*threadfn)(void *data),
+	void *data,
+	const char namefmt[], ...)
+{
+	VCHIQ_THREAD_T newp;
+	va_list ap;
+	char name[MAXCOMLEN+1];
+	struct thread_data *slot;
+
+	if (thread_data_slot >= MAX_THREAD_DATA_SLOTS) {
+		printf("kthread_create: out of thread data slots\n");
+		return (NULL);
+	}
+
+	slot = &thread_slots[thread_data_slot];
+	slot->data = data;
+	slot->threadfn = threadfn;
+
+	va_start(ap, namefmt);
+	vsnprintf(name, sizeof(name), namefmt, ap);
+	va_end(ap);
+	
+	newp = NULL;
+	if (kproc_create(kthread_wrapper, (void*)slot, &newp, 0, 0,
+	    "%s", name) != 0) {
+		/* Just to be sure */
+		newp = NULL;
+	}
+	else
+		thread_data_slot++;
+
+	return newp;
+}
+
+void
+set_user_nice(VCHIQ_THREAD_T thr, int nice)
+{
+	/* NOOP */
+}
+
+void
+wake_up_process(VCHIQ_THREAD_T thr)
+{
+	/* NOOP */
+}
+
+void
+bcm_mbox_write(int channel, uint32_t data)
+{
+	device_t mbox;
+
+        mbox = devclass_get_device(devclass_find("mbox"), 0);
+
+        if (mbox)
+                MBOX_WRITE(mbox, channel, data);
+}

Added: head/sys/contrib/vchiq/interface/compat/vchi_bsd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/contrib/vchiq/interface/compat/vchi_bsd.h	Thu Feb  5 19:54:03 2015	(r278277)
@@ -0,0 +1,434 @@
+/*-
+ * Copyright (c) 2010 Max Khon <fjoe@freebsd.org>
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+ * Copyright (c) 2013 Jared D. McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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.
+ */
+#ifndef __VCHI_BSD_H__
+#define __VCHI_BSD_H__
+
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/sema.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+#include <sys/ioccom.h>
+
+/*
+ * Copy from/to user API
+ */
+#define copy_from_user(to, from, n)	copyin((from), (to), (n))
+#define copy_to_user(to, from, n)	copyout((from), (to), (n))
+
+/*
+ * Bit API
+ */
+
+static __inline int
+test_and_set_bit(int nr, volatile void *addr)
+{
+	int val;
+
+	do {
+		val = *(volatile int *) addr;
+	} while (atomic_cmpset_int(addr, val, val | (1 << nr)) == 0);
+	return (val & (1 << nr));
+}
+
+static __inline__
+int test_and_clear_bit(int nr, volatile void *addr)
+{
+	int val;
+
+	do {
+		val = *(volatile int *) addr;
+	} while (atomic_cmpset_int(addr, val, val & ~(1 << nr)) == 0);
+	return (val & (1 << nr));
+}
+
+/*
+ * Atomic API
+ */
+typedef volatile unsigned atomic_t;
+
+#define atomic_set(p, v)	(*(p) = (v))
+#define atomic_read(p)		(*(p))
+#define atomic_inc(p)		atomic_add_int(p, 1)
+#define atomic_dec(p)		atomic_subtract_int(p, 1)
+#define atomic_dec_and_test(p)	(atomic_fetchadd_int(p, -1) == 1)
+#define	atomic_inc_return(v)	atomic_add_return(1, (v))
+#define	atomic_dec_return(v)	atomic_sub_return(1, (v))
+#define atomic_add(v, p)	atomic_add_int(p, v)
+#define atomic_sub(v, p)	atomic_subtract_int(p, v)
+
+#define ATOMIC_INIT(v)		(v)
+
+static inline int
+atomic_add_return(int i, atomic_t *v)
+{
+	return i + atomic_fetchadd_int(v, i);
+}
+
+static inline int
+atomic_sub_return(int i, atomic_t *v)
+{
+	return atomic_fetchadd_int(v, -i) - i;
+}
+
+static inline int
+atomic_cmpxchg(atomic_t *v, int oldv, int newv)
+{
+	if (atomic_cmpset_rel_int(v, oldv, newv))
+		return newv;
+	else
+		return *v;
+}
+
+static inline int
+atomic_xchg(atomic_t *v, int newv)
+{
+	int oldv;
+	if (newv == 0)
+		return atomic_readandclear_int(v);
+	else {
+		do {
+			oldv = atomic_load_acq_int(v);
+		} while (!atomic_cmpset_rel_int(v, oldv, newv));
+	}
+
+	return (oldv);
+}
+
+/*
+ * Spinlock API
+ */
+typedef struct mtx spinlock_t;
+
+#define DEFINE_SPINLOCK(name)				\
+	struct mtx name
+#define spin_lock_init(lock)	mtx_init(lock, "VCHI spinlock " # lock, NULL, MTX_DEF)
+#define spin_lock_destroy(lock)	mtx_destroy(lock)
+#define spin_lock(lock)		mtx_lock(lock)
+#define spin_unlock(lock)	mtx_unlock(lock)
+#define spin_lock_bh(lock)	spin_lock(lock)
+#define spin_unlock_bh(lock)	spin_unlock(lock)
+
+/*
+ * Mutex API
+ */
+struct mutex {
+	struct mtx	mtx;
+};
+
+#define	lmutex_init(lock)	mtx_init(&(lock)->mtx, #lock, NULL, MTX_DEF)
+#define lmutex_lock(lock)	mtx_lock(&(lock)->mtx)
+#define	lmutex_lock_interruptible(lock)	(mtx_lock(&(lock)->mtx),0)
+#define	lmutex_unlock(lock)	mtx_unlock(&(lock)->mtx)
+#define	lmutex_destroy(lock)	mtx_destroy(&(lock)->mtx)
+
+/*
+ * Rwlock API
+ */
+typedef struct sx rwlock_t;
+
+#if defined(SX_ADAPTIVESPIN) && !defined(SX_NOADAPTIVE)
+#define SX_NOADAPTIVE SX_ADAPTIVESPIN
+#endif

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502051954.t15Js3Rw013083>