From owner-svn-src-head@FreeBSD.ORG Thu Feb 5 19:54:05 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1FC1DE91; Thu, 5 Feb 2015 19:54:05 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 083C6B1; Thu, 5 Feb 2015 19:54:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t15Js46g013090; Thu, 5 Feb 2015 19:54:04 GMT (envelope-from gonzo@FreeBSD.org) Received: (from gonzo@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t15Js3Rw013083; Thu, 5 Feb 2015 19:54:03 GMT (envelope-from gonzo@FreeBSD.org) Message-Id: <201502051954.t15Js3Rw013083@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: gonzo set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko Date: Thu, 5 Feb 2015 19:54:03 +0000 (UTC) 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... X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Feb 2015 19:54:05 -0000 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 + +#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 + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mbox_if.h" + +#include + +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 + * Copyright (c) 2012 Oleksandr Tymoshenko + * Copyright (c) 2013 Jared D. McNeill + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 ***