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...
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Thu Feb 5 19:54:05 UTC 2015
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 at 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 at freebsd.org>
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at bluezbox.com>
+ * Copyright (c) 2013 Jared D. McNeill <jmcneill at 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 ***
More information about the svn-src-all
mailing list