183827f40a2d97261528087331b0bee6ce2cf27c5root/**************************************************************************
283827f40a2d97261528087331b0bee6ce2cf27c5root *
383827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
483827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved.
583827f40a2d97261528087331b0bee6ce2cf27c5root * Copyright 2009 Vmware, Inc., Palo Alto, CA., USA
683827f40a2d97261528087331b0bee6ce2cf27c5root * All Rights Reserved.
783827f40a2d97261528087331b0bee6ce2cf27c5root *
883827f40a2d97261528087331b0bee6ce2cf27c5root * Permission is hereby granted, free of charge, to any person obtaining a
983827f40a2d97261528087331b0bee6ce2cf27c5root * copy of this software and associated documentation files (the
1083827f40a2d97261528087331b0bee6ce2cf27c5root * "Software"), to deal in the Software without restriction, including
1183827f40a2d97261528087331b0bee6ce2cf27c5root * without limitation the rights to use, copy, modify, merge, publish,
1283827f40a2d97261528087331b0bee6ce2cf27c5root * distribute, sub license, and/or sell copies of the Software, and to
1383827f40a2d97261528087331b0bee6ce2cf27c5root * permit persons to whom the Software is furnished to do so, subject to
1483827f40a2d97261528087331b0bee6ce2cf27c5root * the following conditions:
1583827f40a2d97261528087331b0bee6ce2cf27c5root *
1683827f40a2d97261528087331b0bee6ce2cf27c5root * The above copyright notice and this permission notice (including the
1783827f40a2d97261528087331b0bee6ce2cf27c5root * next paragraph) shall be included in all copies or substantial portions
1883827f40a2d97261528087331b0bee6ce2cf27c5root * of the Software.
1983827f40a2d97261528087331b0bee6ce2cf27c5root *
2083827f40a2d97261528087331b0bee6ce2cf27c5root * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2183827f40a2d97261528087331b0bee6ce2cf27c5root * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2283827f40a2d97261528087331b0bee6ce2cf27c5root * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2383827f40a2d97261528087331b0bee6ce2cf27c5root * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
2483827f40a2d97261528087331b0bee6ce2cf27c5root * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2583827f40a2d97261528087331b0bee6ce2cf27c5root * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2683827f40a2d97261528087331b0bee6ce2cf27c5root * USE OR OTHER DEALINGS IN THE SOFTWARE.
2783827f40a2d97261528087331b0bee6ce2cf27c5root *
2883827f40a2d97261528087331b0bee6ce2cf27c5root **************************************************************************/
2983827f40a2d97261528087331b0bee6ce2cf27c5root/*
3083827f40a2d97261528087331b0bee6ce2cf27c5root * Authors: Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com>
3183827f40a2d97261528087331b0bee6ce2cf27c5root *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
3283827f40a2d97261528087331b0bee6ce2cf27c5root */
3383827f40a2d97261528087331b0bee6ce2cf27c5root
3483827f40a2d97261528087331b0bee6ce2cf27c5root#ifdef HAVE_CONFIG_H
3583827f40a2d97261528087331b0bee6ce2cf27c5root#include "config.h"
3683827f40a2d97261528087331b0bee6ce2cf27c5root#endif
3783827f40a2d97261528087331b0bee6ce2cf27c5root
3883827f40a2d97261528087331b0bee6ce2cf27c5root#include <stdlib.h>
3983827f40a2d97261528087331b0bee6ce2cf27c5root#include "errno.h"
4083827f40a2d97261528087331b0bee6ce2cf27c5root#include "string.h"
4183827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_pool.h"
4283827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_manager.h"
4383827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_fencemgr.h"
4483827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_driver.h"
4583827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_priv.h"
4683827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_util.h"
4783827f40a2d97261528087331b0bee6ce2cf27c5root#include "wsbm_atomic.h"
4883827f40a2d97261528087331b0bee6ce2cf27c5root#include "assert.h"
4983827f40a2d97261528087331b0bee6ce2cf27c5root
5083827f40a2d97261528087331b0bee6ce2cf27c5root#define WSBM_BODATA_SIZE_ACCEPT 4096
5183827f40a2d97261528087331b0bee6ce2cf27c5root
5283827f40a2d97261528087331b0bee6ce2cf27c5root#define WSBM_BUFFER_COMPLEX 0
5383827f40a2d97261528087331b0bee6ce2cf27c5root#define WSBM_BUFFER_SIMPLE  1
5483827f40a2d97261528087331b0bee6ce2cf27c5root#define WSBM_BUFFER_REF     2
5583827f40a2d97261528087331b0bee6ce2cf27c5root
5683827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _ValidateList
5783827f40a2d97261528087331b0bee6ce2cf27c5root{
5883827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned numTarget;
5983827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned numCurrent;
6083827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned numOnList;
6183827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned hashSize;
6283827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t hashMask;
6383827f40a2d97261528087331b0bee6ce2cf27c5root    int driverData;
6483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead list;
6583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead free;
6683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *hashTable;
6783827f40a2d97261528087331b0bee6ce2cf27c5root};
6883827f40a2d97261528087331b0bee6ce2cf27c5root
6983827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferObject
7083827f40a2d97261528087331b0bee6ce2cf27c5root{
7183827f40a2d97261528087331b0bee6ce2cf27c5root    /* Left to the client to protect this data for now. */
7283827f40a2d97261528087331b0bee6ce2cf27c5root
7383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmAtomic refCount;
7483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
7583827f40a2d97261528087331b0bee6ce2cf27c5root
7683827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t placement;
7783827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned alignment;
7883827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned bufferType;
7983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *pool;
8083827f40a2d97261528087331b0bee6ce2cf27c5root};
8183827f40a2d97261528087331b0bee6ce2cf27c5root
8283827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferList
8383827f40a2d97261528087331b0bee6ce2cf27c5root{
8483827f40a2d97261528087331b0bee6ce2cf27c5root    int hasKernelBuffers;
8583827f40a2d97261528087331b0bee6ce2cf27c5root
8683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateList kernelBuffers;	/* List of kernel buffers needing validation */
8783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateList userBuffers;  /* List of user-space buffers needing validation */
8883827f40a2d97261528087331b0bee6ce2cf27c5root};
8983827f40a2d97261528087331b0bee6ce2cf27c5root
9083827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmMutex bmMutex;
9183827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmCond bmCond;
9283827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int initialized = 0;
9383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void *commonData = NULL;
9483827f40a2d97261528087331b0bee6ce2cf27c5root
9583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int kernelReaders = 0;
9683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int kernelLocked = 0;
9783827f40a2d97261528087331b0bee6ce2cf27c5root
9883827f40a2d97261528087331b0bee6ce2cf27c5rootint
9983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmInit(struct _WsbmThreadFuncs *tf, struct _WsbmVNodeFuncs *vf)
10083827f40a2d97261528087331b0bee6ce2cf27c5root{
10183827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
10283827f40a2d97261528087331b0bee6ce2cf27c5root
10383827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmCurThreadFunc = tf;
10483827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmCurVNodeFunc = vf;
10583827f40a2d97261528087331b0bee6ce2cf27c5root
10683827f40a2d97261528087331b0bee6ce2cf27c5root    ret = WSBM_MUTEX_INIT(&bmMutex);
10783827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
10883827f40a2d97261528087331b0bee6ce2cf27c5root	return -ENOMEM;
10983827f40a2d97261528087331b0bee6ce2cf27c5root    ret = WSBM_COND_INIT(&bmCond);
11083827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret) {
11183827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_MUTEX_FREE(&bmMutex);
11283827f40a2d97261528087331b0bee6ce2cf27c5root	return -ENOMEM;
11383827f40a2d97261528087331b0bee6ce2cf27c5root    }
11483827f40a2d97261528087331b0bee6ce2cf27c5root
11583827f40a2d97261528087331b0bee6ce2cf27c5root    initialized = 1;
11683827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
11783827f40a2d97261528087331b0bee6ce2cf27c5root}
11883827f40a2d97261528087331b0bee6ce2cf27c5root
11983827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
12083827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmCommonDataSet(void *d)
12183827f40a2d97261528087331b0bee6ce2cf27c5root{
12283827f40a2d97261528087331b0bee6ce2cf27c5root    commonData = d;
12383827f40a2d97261528087331b0bee6ce2cf27c5root}
12483827f40a2d97261528087331b0bee6ce2cf27c5root
12583827f40a2d97261528087331b0bee6ce2cf27c5rootvoid *
12683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmCommonDataGet(void)
12783827f40a2d97261528087331b0bee6ce2cf27c5root{
12883827f40a2d97261528087331b0bee6ce2cf27c5root    return commonData;
12983827f40a2d97261528087331b0bee6ce2cf27c5root}
13083827f40a2d97261528087331b0bee6ce2cf27c5root
13183827f40a2d97261528087331b0bee6ce2cf27c5rootint
13283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmIsInitialized(void)
13383827f40a2d97261528087331b0bee6ce2cf27c5root{
13483827f40a2d97261528087331b0bee6ce2cf27c5root    return initialized;
13583827f40a2d97261528087331b0bee6ce2cf27c5root}
13683827f40a2d97261528087331b0bee6ce2cf27c5root
13783827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
13883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmTakedown(void)
13983827f40a2d97261528087331b0bee6ce2cf27c5root{
14083827f40a2d97261528087331b0bee6ce2cf27c5root    initialized = 0;
14183827f40a2d97261528087331b0bee6ce2cf27c5root    commonData = NULL;
14283827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_COND_FREE(&bmCond);
14383827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_FREE(&bmMutex);
14483827f40a2d97261528087331b0bee6ce2cf27c5root}
14583827f40a2d97261528087331b0bee6ce2cf27c5root
14683827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _ValidateNode *
14783827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateListAddNode(struct _ValidateList *list, void *item,
14883827f40a2d97261528087331b0bee6ce2cf27c5root		    uint32_t hash, uint64_t flags, uint64_t mask)
14983827f40a2d97261528087331b0bee6ce2cf27c5root{
15083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
15183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l;
15283827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *hashHead;
15383827f40a2d97261528087331b0bee6ce2cf27c5root
15483827f40a2d97261528087331b0bee6ce2cf27c5root    l = list->free.next;
15583827f40a2d97261528087331b0bee6ce2cf27c5root    if (l == &list->free) {
15683827f40a2d97261528087331b0bee6ce2cf27c5root	node = wsbmVNodeFuncs()->alloc(wsbmVNodeFuncs(), 0);
15783827f40a2d97261528087331b0bee6ce2cf27c5root	if (!node) {
15883827f40a2d97261528087331b0bee6ce2cf27c5root	    return NULL;
15983827f40a2d97261528087331b0bee6ce2cf27c5root	}
16083827f40a2d97261528087331b0bee6ce2cf27c5root	list->numCurrent++;
16183827f40a2d97261528087331b0bee6ce2cf27c5root    } else {
16283827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(l);
16383827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, head);
16483827f40a2d97261528087331b0bee6ce2cf27c5root    }
16583827f40a2d97261528087331b0bee6ce2cf27c5root    node->buf = item;
16683827f40a2d97261528087331b0bee6ce2cf27c5root    node->set_flags = flags & mask;
16783827f40a2d97261528087331b0bee6ce2cf27c5root    node->clr_flags = (~flags) & mask;
16883827f40a2d97261528087331b0bee6ce2cf27c5root    node->listItem = list->numOnList;
16983827f40a2d97261528087331b0bee6ce2cf27c5root    WSBMLISTADDTAIL(&node->head, &list->list);
17083827f40a2d97261528087331b0bee6ce2cf27c5root    list->numOnList++;
17183827f40a2d97261528087331b0bee6ce2cf27c5root    hashHead = list->hashTable + hash;
17283827f40a2d97261528087331b0bee6ce2cf27c5root    WSBMLISTADDTAIL(&node->hashHead, hashHead);
17383827f40a2d97261528087331b0bee6ce2cf27c5root
17483827f40a2d97261528087331b0bee6ce2cf27c5root    return node;
17583827f40a2d97261528087331b0bee6ce2cf27c5root}
17683827f40a2d97261528087331b0bee6ce2cf27c5root
17783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic uint32_t
17883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmHashFunc(uint8_t * key, uint32_t len, uint32_t mask)
17983827f40a2d97261528087331b0bee6ce2cf27c5root{
18083827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t hash, i;
18183827f40a2d97261528087331b0bee6ce2cf27c5root
18283827f40a2d97261528087331b0bee6ce2cf27c5root    for (hash = 0, i = 0; i < len; ++i) {
18383827f40a2d97261528087331b0bee6ce2cf27c5root	hash += *key++;
18483827f40a2d97261528087331b0bee6ce2cf27c5root	hash += (hash << 10);
18583827f40a2d97261528087331b0bee6ce2cf27c5root	hash ^= (hash >> 6);
18683827f40a2d97261528087331b0bee6ce2cf27c5root    }
18783827f40a2d97261528087331b0bee6ce2cf27c5root
18883827f40a2d97261528087331b0bee6ce2cf27c5root    hash += (hash << 3);
18983827f40a2d97261528087331b0bee6ce2cf27c5root    hash ^= (hash >> 11);
19083827f40a2d97261528087331b0bee6ce2cf27c5root    hash += (hash << 15);
19183827f40a2d97261528087331b0bee6ce2cf27c5root
19283827f40a2d97261528087331b0bee6ce2cf27c5root    return hash & mask;
19383827f40a2d97261528087331b0bee6ce2cf27c5root}
19483827f40a2d97261528087331b0bee6ce2cf27c5root
19583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic void
19683827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateFreeList(struct _ValidateList *list)
19783827f40a2d97261528087331b0bee6ce2cf27c5root{
19883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
19983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l;
20083827f40a2d97261528087331b0bee6ce2cf27c5root
20183827f40a2d97261528087331b0bee6ce2cf27c5root    l = list->list.next;
20283827f40a2d97261528087331b0bee6ce2cf27c5root    while (l != &list->list) {
20383827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(l);
20483827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, head);
20583827f40a2d97261528087331b0bee6ce2cf27c5root
20683827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(&node->hashHead);
20783827f40a2d97261528087331b0bee6ce2cf27c5root	node->func->free(node);
20883827f40a2d97261528087331b0bee6ce2cf27c5root	l = list->list.next;
20983827f40a2d97261528087331b0bee6ce2cf27c5root	list->numCurrent--;
21083827f40a2d97261528087331b0bee6ce2cf27c5root	list->numOnList--;
21183827f40a2d97261528087331b0bee6ce2cf27c5root    }
21283827f40a2d97261528087331b0bee6ce2cf27c5root
21383827f40a2d97261528087331b0bee6ce2cf27c5root    l = list->free.next;
21483827f40a2d97261528087331b0bee6ce2cf27c5root    while (l != &list->free) {
21583827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(l);
21683827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, head);
21783827f40a2d97261528087331b0bee6ce2cf27c5root
21883827f40a2d97261528087331b0bee6ce2cf27c5root	node->func->free(node);
21983827f40a2d97261528087331b0bee6ce2cf27c5root	l = list->free.next;
22083827f40a2d97261528087331b0bee6ce2cf27c5root	list->numCurrent--;
22183827f40a2d97261528087331b0bee6ce2cf27c5root    }
22283827f40a2d97261528087331b0bee6ce2cf27c5root    free(list->hashTable);
22383827f40a2d97261528087331b0bee6ce2cf27c5root}
22483827f40a2d97261528087331b0bee6ce2cf27c5root
22583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
22683827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateListAdjustNodes(struct _ValidateList *list)
22783827f40a2d97261528087331b0bee6ce2cf27c5root{
22883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
22983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l;
23083827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
23183827f40a2d97261528087331b0bee6ce2cf27c5root
23283827f40a2d97261528087331b0bee6ce2cf27c5root    while (list->numCurrent < list->numTarget) {
23383827f40a2d97261528087331b0bee6ce2cf27c5root	node = wsbmVNodeFuncs()->alloc(wsbmVNodeFuncs(), list->driverData);
23483827f40a2d97261528087331b0bee6ce2cf27c5root	if (!node) {
23583827f40a2d97261528087331b0bee6ce2cf27c5root	    ret = -ENOMEM;
23683827f40a2d97261528087331b0bee6ce2cf27c5root	    break;
23783827f40a2d97261528087331b0bee6ce2cf27c5root	}
23883827f40a2d97261528087331b0bee6ce2cf27c5root	list->numCurrent++;
23983827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTADD(&node->head, &list->free);
24083827f40a2d97261528087331b0bee6ce2cf27c5root    }
24183827f40a2d97261528087331b0bee6ce2cf27c5root
24283827f40a2d97261528087331b0bee6ce2cf27c5root    while (list->numCurrent > list->numTarget) {
24383827f40a2d97261528087331b0bee6ce2cf27c5root	l = list->free.next;
24483827f40a2d97261528087331b0bee6ce2cf27c5root	if (l == &list->free)
24583827f40a2d97261528087331b0bee6ce2cf27c5root	    break;
24683827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(l);
24783827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, head);
24883827f40a2d97261528087331b0bee6ce2cf27c5root
24983827f40a2d97261528087331b0bee6ce2cf27c5root	node->func->free(node);
25083827f40a2d97261528087331b0bee6ce2cf27c5root	list->numCurrent--;
25183827f40a2d97261528087331b0bee6ce2cf27c5root    }
25283827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
25383827f40a2d97261528087331b0bee6ce2cf27c5root}
25483827f40a2d97261528087331b0bee6ce2cf27c5root
25583827f40a2d97261528087331b0bee6ce2cf27c5rootstatic inline int
25683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmPot(unsigned int val)
25783827f40a2d97261528087331b0bee6ce2cf27c5root{
25883827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int shift = 0;
2593795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel    while(val > (unsigned int)(1 << shift))
26083827f40a2d97261528087331b0bee6ce2cf27c5root	shift++;
26183827f40a2d97261528087331b0bee6ce2cf27c5root
26283827f40a2d97261528087331b0bee6ce2cf27c5root    return shift;
26383827f40a2d97261528087331b0bee6ce2cf27c5root}
26483827f40a2d97261528087331b0bee6ce2cf27c5root
26583827f40a2d97261528087331b0bee6ce2cf27c5root
26683827f40a2d97261528087331b0bee6ce2cf27c5root
26783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
26883827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateCreateList(int numTarget, struct _ValidateList *list, int driverData)
26983827f40a2d97261528087331b0bee6ce2cf27c5root{
2703795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel    unsigned int i;
27183827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned int shift = wsbmPot(numTarget);
27283827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
27383827f40a2d97261528087331b0bee6ce2cf27c5root
27483827f40a2d97261528087331b0bee6ce2cf27c5root    list->hashSize = (1 << shift);
27583827f40a2d97261528087331b0bee6ce2cf27c5root    list->hashMask = list->hashSize - 1;
27683827f40a2d97261528087331b0bee6ce2cf27c5root
27783827f40a2d97261528087331b0bee6ce2cf27c5root    list->hashTable = malloc(list->hashSize * sizeof(*list->hashTable));
27883827f40a2d97261528087331b0bee6ce2cf27c5root    if (!list->hashTable)
27983827f40a2d97261528087331b0bee6ce2cf27c5root	return -ENOMEM;
28083827f40a2d97261528087331b0bee6ce2cf27c5root
28183827f40a2d97261528087331b0bee6ce2cf27c5root    for (i = 0; i < list->hashSize; ++i)
28283827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMINITLISTHEAD(&list->hashTable[i]);
28383827f40a2d97261528087331b0bee6ce2cf27c5root
28483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBMINITLISTHEAD(&list->list);
28583827f40a2d97261528087331b0bee6ce2cf27c5root    WSBMINITLISTHEAD(&list->free);
28683827f40a2d97261528087331b0bee6ce2cf27c5root    list->numTarget = numTarget;
28783827f40a2d97261528087331b0bee6ce2cf27c5root    list->numCurrent = 0;
28883827f40a2d97261528087331b0bee6ce2cf27c5root    list->numOnList = 0;
28983827f40a2d97261528087331b0bee6ce2cf27c5root    list->driverData = driverData;
29083827f40a2d97261528087331b0bee6ce2cf27c5root    ret = validateListAdjustNodes(list);
29183827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret != 0)
29283827f40a2d97261528087331b0bee6ce2cf27c5root	free(list->hashTable);
29383827f40a2d97261528087331b0bee6ce2cf27c5root
29483827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
29583827f40a2d97261528087331b0bee6ce2cf27c5root}
29683827f40a2d97261528087331b0bee6ce2cf27c5root
29783827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
29883827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateResetList(struct _ValidateList *list)
29983827f40a2d97261528087331b0bee6ce2cf27c5root{
30083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l;
30183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
30283827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
30383827f40a2d97261528087331b0bee6ce2cf27c5root
30483827f40a2d97261528087331b0bee6ce2cf27c5root    ret = validateListAdjustNodes(list);
30583827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
30683827f40a2d97261528087331b0bee6ce2cf27c5root	return ret;
30783827f40a2d97261528087331b0bee6ce2cf27c5root
30883827f40a2d97261528087331b0bee6ce2cf27c5root    l = list->list.next;
30983827f40a2d97261528087331b0bee6ce2cf27c5root    while (l != &list->list) {
31083827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(l);
31183827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, head);
31283827f40a2d97261528087331b0bee6ce2cf27c5root
31383827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTDEL(&node->hashHead);
31483827f40a2d97261528087331b0bee6ce2cf27c5root	WSBMLISTADD(l, &list->free);
31583827f40a2d97261528087331b0bee6ce2cf27c5root	list->numOnList--;
31683827f40a2d97261528087331b0bee6ce2cf27c5root	l = list->list.next;
31783827f40a2d97261528087331b0bee6ce2cf27c5root    }
31883827f40a2d97261528087331b0bee6ce2cf27c5root    return validateListAdjustNodes(list);
31983827f40a2d97261528087331b0bee6ce2cf27c5root}
32083827f40a2d97261528087331b0bee6ce2cf27c5root
32183827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
32283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmWriteLockKernelBO(void)
32383827f40a2d97261528087331b0bee6ce2cf27c5root{
32483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&bmMutex);
32583827f40a2d97261528087331b0bee6ce2cf27c5root    while (kernelReaders != 0)
32683827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_COND_WAIT(&bmCond, &bmMutex);
32783827f40a2d97261528087331b0bee6ce2cf27c5root    kernelLocked = 1;
32883827f40a2d97261528087331b0bee6ce2cf27c5root}
32983827f40a2d97261528087331b0bee6ce2cf27c5root
33083827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
33183827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmWriteUnlockKernelBO(void)
33283827f40a2d97261528087331b0bee6ce2cf27c5root{
33383827f40a2d97261528087331b0bee6ce2cf27c5root    kernelLocked = 0;
33483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&bmMutex);
33583827f40a2d97261528087331b0bee6ce2cf27c5root}
33683827f40a2d97261528087331b0bee6ce2cf27c5root
33783827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
33883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmReadLockKernelBO(void)
33983827f40a2d97261528087331b0bee6ce2cf27c5root{
34083827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&bmMutex);
34183827f40a2d97261528087331b0bee6ce2cf27c5root    if (kernelReaders++ == 0)
34283827f40a2d97261528087331b0bee6ce2cf27c5root	kernelLocked = 1;
34383827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&bmMutex);
34483827f40a2d97261528087331b0bee6ce2cf27c5root}
34583827f40a2d97261528087331b0bee6ce2cf27c5root
34683827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
34783827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmReadUnlockKernelBO(void)
34883827f40a2d97261528087331b0bee6ce2cf27c5root{
34983827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_LOCK(&bmMutex);
35083827f40a2d97261528087331b0bee6ce2cf27c5root    if (--kernelReaders == 0) {
35183827f40a2d97261528087331b0bee6ce2cf27c5root	kernelLocked = 0;
35283827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_COND_BROADCAST(&bmCond);
35383827f40a2d97261528087331b0bee6ce2cf27c5root    }
35483827f40a2d97261528087331b0bee6ce2cf27c5root    WSBM_MUTEX_UNLOCK(&bmMutex);
35583827f40a2d97261528087331b0bee6ce2cf27c5root}
35683827f40a2d97261528087331b0bee6ce2cf27c5root
35783827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
35883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOWaitIdle(struct _WsbmBufferObject *buf, int lazy)
35983827f40a2d97261528087331b0bee6ce2cf27c5root{
36083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
36183827f40a2d97261528087331b0bee6ce2cf27c5root
36283827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
36383827f40a2d97261528087331b0bee6ce2cf27c5root    if (!storage)
36483827f40a2d97261528087331b0bee6ce2cf27c5root	return;
36583827f40a2d97261528087331b0bee6ce2cf27c5root
36683827f40a2d97261528087331b0bee6ce2cf27c5root    (void)storage->pool->waitIdle(storage, lazy);
36783827f40a2d97261528087331b0bee6ce2cf27c5root}
36883827f40a2d97261528087331b0bee6ce2cf27c5root
36983827f40a2d97261528087331b0bee6ce2cf27c5rootvoid *
37083827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOMap(struct _WsbmBufferObject *buf, unsigned mode)
37183827f40a2d97261528087331b0bee6ce2cf27c5root{
37283827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
37383827f40a2d97261528087331b0bee6ce2cf27c5root    void *virtual;
37483827f40a2d97261528087331b0bee6ce2cf27c5root    int retval;
37583827f40a2d97261528087331b0bee6ce2cf27c5root
37683827f40a2d97261528087331b0bee6ce2cf27c5root    retval = storage->pool->map(storage, mode, &virtual);
37783827f40a2d97261528087331b0bee6ce2cf27c5root
37883827f40a2d97261528087331b0bee6ce2cf27c5root    return (retval == 0) ? virtual : NULL;
37983827f40a2d97261528087331b0bee6ce2cf27c5root}
38083827f40a2d97261528087331b0bee6ce2cf27c5root
38183827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
38283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOUnmap(struct _WsbmBufferObject *buf)
38383827f40a2d97261528087331b0bee6ce2cf27c5root{
38483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
38583827f40a2d97261528087331b0bee6ce2cf27c5root
38683827f40a2d97261528087331b0bee6ce2cf27c5root    if (!storage)
38783827f40a2d97261528087331b0bee6ce2cf27c5root	return;
38883827f40a2d97261528087331b0bee6ce2cf27c5root
38983827f40a2d97261528087331b0bee6ce2cf27c5root    storage->pool->unmap(storage);
39083827f40a2d97261528087331b0bee6ce2cf27c5root}
39183827f40a2d97261528087331b0bee6ce2cf27c5root
39283827f40a2d97261528087331b0bee6ce2cf27c5rootint
39383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOSyncForCpu(struct _WsbmBufferObject *buf, unsigned mode)
39483827f40a2d97261528087331b0bee6ce2cf27c5root{
39583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
39683827f40a2d97261528087331b0bee6ce2cf27c5root
39783827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->syncforcpu(storage, mode);
39883827f40a2d97261528087331b0bee6ce2cf27c5root}
39983827f40a2d97261528087331b0bee6ce2cf27c5root
40083827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
40183827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOReleaseFromCpu(struct _WsbmBufferObject *buf, unsigned mode)
40283827f40a2d97261528087331b0bee6ce2cf27c5root{
40383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
40483827f40a2d97261528087331b0bee6ce2cf27c5root
40583827f40a2d97261528087331b0bee6ce2cf27c5root    storage->pool->releasefromcpu(storage, mode);
40683827f40a2d97261528087331b0bee6ce2cf27c5root}
40783827f40a2d97261528087331b0bee6ce2cf27c5root
40883827f40a2d97261528087331b0bee6ce2cf27c5rootunsigned long
40983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOOffsetHint(struct _WsbmBufferObject *buf)
41083827f40a2d97261528087331b0bee6ce2cf27c5root{
41183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
41283827f40a2d97261528087331b0bee6ce2cf27c5root
41383827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->offset(storage);
41483827f40a2d97261528087331b0bee6ce2cf27c5root}
41583827f40a2d97261528087331b0bee6ce2cf27c5root
41683827f40a2d97261528087331b0bee6ce2cf27c5rootunsigned long
41783827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOPoolOffset(struct _WsbmBufferObject *buf)
41883827f40a2d97261528087331b0bee6ce2cf27c5root{
41983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
42083827f40a2d97261528087331b0bee6ce2cf27c5root
42183827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->poolOffset(storage);
42283827f40a2d97261528087331b0bee6ce2cf27c5root}
42383827f40a2d97261528087331b0bee6ce2cf27c5root
42483827f40a2d97261528087331b0bee6ce2cf27c5rootuint32_t
42583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOPlacementHint(struct _WsbmBufferObject * buf)
42683827f40a2d97261528087331b0bee6ce2cf27c5root{
42783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
42883827f40a2d97261528087331b0bee6ce2cf27c5root
42983827f40a2d97261528087331b0bee6ce2cf27c5root    assert(buf->storage != NULL);
43083827f40a2d97261528087331b0bee6ce2cf27c5root
43183827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->placement(storage);
43283827f40a2d97261528087331b0bee6ce2cf27c5root}
43383827f40a2d97261528087331b0bee6ce2cf27c5root
43483827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferObject *
43583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOReference(struct _WsbmBufferObject *buf)
43683827f40a2d97261528087331b0bee6ce2cf27c5root{
43783827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->bufferType == WSBM_BUFFER_SIMPLE) {
43883827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicInc(&buf->storage->refCount);
43983827f40a2d97261528087331b0bee6ce2cf27c5root    } else {
44083827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicInc(&buf->refCount);
44183827f40a2d97261528087331b0bee6ce2cf27c5root    }
44283827f40a2d97261528087331b0bee6ce2cf27c5root    return buf;
44383827f40a2d97261528087331b0bee6ce2cf27c5root}
44483827f40a2d97261528087331b0bee6ce2cf27c5root
44583827f40a2d97261528087331b0bee6ce2cf27c5rootint
44683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOSetStatus(struct _WsbmBufferObject *buf,
44783827f40a2d97261528087331b0bee6ce2cf27c5root		uint32_t setFlags, uint32_t clrFlags)
44883827f40a2d97261528087331b0bee6ce2cf27c5root{
44983827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
45083827f40a2d97261528087331b0bee6ce2cf27c5root
45183827f40a2d97261528087331b0bee6ce2cf27c5root    if (!storage)
45283827f40a2d97261528087331b0bee6ce2cf27c5root	return 0;
45383827f40a2d97261528087331b0bee6ce2cf27c5root
45483827f40a2d97261528087331b0bee6ce2cf27c5root    if (storage->pool->setStatus == NULL)
45583827f40a2d97261528087331b0bee6ce2cf27c5root	return -EINVAL;
45683827f40a2d97261528087331b0bee6ce2cf27c5root
45783827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->setStatus(storage, setFlags, clrFlags);
45883827f40a2d97261528087331b0bee6ce2cf27c5root}
45983827f40a2d97261528087331b0bee6ce2cf27c5root
46083827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
46183827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOUnreference(struct _WsbmBufferObject **p_buf)
46283827f40a2d97261528087331b0bee6ce2cf27c5root{
46383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferObject *buf = *p_buf;
46483827f40a2d97261528087331b0bee6ce2cf27c5root
46583827f40a2d97261528087331b0bee6ce2cf27c5root    *p_buf = NULL;
46683827f40a2d97261528087331b0bee6ce2cf27c5root
46783827f40a2d97261528087331b0bee6ce2cf27c5root    if (!buf)
46883827f40a2d97261528087331b0bee6ce2cf27c5root	return;
46983827f40a2d97261528087331b0bee6ce2cf27c5root
47083827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->bufferType == WSBM_BUFFER_SIMPLE) {
47183827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *dummy = buf->storage;
47283827f40a2d97261528087331b0bee6ce2cf27c5root
47383827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&dummy);
47483827f40a2d97261528087331b0bee6ce2cf27c5root	return;
47583827f40a2d97261528087331b0bee6ce2cf27c5root    }
47683827f40a2d97261528087331b0bee6ce2cf27c5root
47783827f40a2d97261528087331b0bee6ce2cf27c5root    if (wsbmAtomicDecZero(&buf->refCount)) {
47883827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&buf->storage);
47983827f40a2d97261528087331b0bee6ce2cf27c5root	free(buf);
48083827f40a2d97261528087331b0bee6ce2cf27c5root    }
48183827f40a2d97261528087331b0bee6ce2cf27c5root}
48283827f40a2d97261528087331b0bee6ce2cf27c5root
48383827f40a2d97261528087331b0bee6ce2cf27c5rootint
48483827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOData(struct _WsbmBufferObject *buf,
48583827f40a2d97261528087331b0bee6ce2cf27c5root	   unsigned size, const void *data,
48683827f40a2d97261528087331b0bee6ce2cf27c5root	   struct _WsbmBufferPool *newPool, uint32_t placement)
48783827f40a2d97261528087331b0bee6ce2cf27c5root{
48883827f40a2d97261528087331b0bee6ce2cf27c5root    void *virtual = NULL;
48983827f40a2d97261528087331b0bee6ce2cf27c5root    int newBuffer;
49083827f40a2d97261528087331b0bee6ce2cf27c5root    int retval = 0;
49183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
49283827f40a2d97261528087331b0bee6ce2cf27c5root    int synced = 0;
49383827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t placement_diff;
49483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *curPool;
49583827f40a2d97261528087331b0bee6ce2cf27c5root
49683827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->bufferType == WSBM_BUFFER_SIMPLE)
49783827f40a2d97261528087331b0bee6ce2cf27c5root	return -EINVAL;
49883827f40a2d97261528087331b0bee6ce2cf27c5root
49983827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
50083827f40a2d97261528087331b0bee6ce2cf27c5root
50183827f40a2d97261528087331b0bee6ce2cf27c5root    if (newPool == NULL)
50283827f40a2d97261528087331b0bee6ce2cf27c5root	newPool = buf->pool;
50383827f40a2d97261528087331b0bee6ce2cf27c5root
50483827f40a2d97261528087331b0bee6ce2cf27c5root    if (newPool == NULL)
50583827f40a2d97261528087331b0bee6ce2cf27c5root	return -EINVAL;
50683827f40a2d97261528087331b0bee6ce2cf27c5root
50783827f40a2d97261528087331b0bee6ce2cf27c5root    newBuffer = (!storage || storage->pool != newPool ||
50883827f40a2d97261528087331b0bee6ce2cf27c5root		 storage->pool->size(storage) < size ||
50983827f40a2d97261528087331b0bee6ce2cf27c5root		 storage->pool->size(storage) >
51083827f40a2d97261528087331b0bee6ce2cf27c5root		 size + WSBM_BODATA_SIZE_ACCEPT);
51183827f40a2d97261528087331b0bee6ce2cf27c5root
51283827f40a2d97261528087331b0bee6ce2cf27c5root    if (!placement)
51383827f40a2d97261528087331b0bee6ce2cf27c5root	placement = buf->placement;
51483827f40a2d97261528087331b0bee6ce2cf27c5root
51583827f40a2d97261528087331b0bee6ce2cf27c5root    if (newBuffer) {
51683827f40a2d97261528087331b0bee6ce2cf27c5root	if (buf->bufferType == WSBM_BUFFER_REF)
51783827f40a2d97261528087331b0bee6ce2cf27c5root	    return -EINVAL;
51883827f40a2d97261528087331b0bee6ce2cf27c5root
51983827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&buf->storage);
52083827f40a2d97261528087331b0bee6ce2cf27c5root
52183827f40a2d97261528087331b0bee6ce2cf27c5root	if (size == 0) {
52283827f40a2d97261528087331b0bee6ce2cf27c5root	    buf->pool = newPool;
52383827f40a2d97261528087331b0bee6ce2cf27c5root	    buf->placement = placement;
52483827f40a2d97261528087331b0bee6ce2cf27c5root	    retval = 0;
52583827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
52683827f40a2d97261528087331b0bee6ce2cf27c5root	}
52783827f40a2d97261528087331b0bee6ce2cf27c5root
52883827f40a2d97261528087331b0bee6ce2cf27c5root	buf->storage =
52983827f40a2d97261528087331b0bee6ce2cf27c5root	    newPool->create(newPool, size, placement, buf->alignment);
53083827f40a2d97261528087331b0bee6ce2cf27c5root	if (!buf->storage) {
53183827f40a2d97261528087331b0bee6ce2cf27c5root	    retval = -ENOMEM;
53283827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
53383827f40a2d97261528087331b0bee6ce2cf27c5root	}
53483827f40a2d97261528087331b0bee6ce2cf27c5root
53583827f40a2d97261528087331b0bee6ce2cf27c5root	buf->placement = placement;
53683827f40a2d97261528087331b0bee6ce2cf27c5root	buf->pool = newPool;
53783827f40a2d97261528087331b0bee6ce2cf27c5root    } else if (wsbmAtomicRead(&storage->onList) ||
53883827f40a2d97261528087331b0bee6ce2cf27c5root	       0 != storage->pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE |
53983827f40a2d97261528087331b0bee6ce2cf27c5root					      WSBM_SYNCCPU_DONT_BLOCK)) {
54083827f40a2d97261528087331b0bee6ce2cf27c5root	/*
54183827f40a2d97261528087331b0bee6ce2cf27c5root	 * Buffer is busy. need to create a new one.
54283827f40a2d97261528087331b0bee6ce2cf27c5root	 */
54383827f40a2d97261528087331b0bee6ce2cf27c5root
54483827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *tmp_storage;
54583827f40a2d97261528087331b0bee6ce2cf27c5root
54683827f40a2d97261528087331b0bee6ce2cf27c5root	curPool = storage->pool;
54783827f40a2d97261528087331b0bee6ce2cf27c5root
54883827f40a2d97261528087331b0bee6ce2cf27c5root	tmp_storage =
54983827f40a2d97261528087331b0bee6ce2cf27c5root	    curPool->create(curPool, size, placement, buf->alignment);
55083827f40a2d97261528087331b0bee6ce2cf27c5root
55183827f40a2d97261528087331b0bee6ce2cf27c5root	if (tmp_storage) {
55283827f40a2d97261528087331b0bee6ce2cf27c5root	    wsbmBufStorageUnref(&buf->storage);
55383827f40a2d97261528087331b0bee6ce2cf27c5root	    buf->storage = tmp_storage;
55483827f40a2d97261528087331b0bee6ce2cf27c5root	    buf->placement = placement;
55583827f40a2d97261528087331b0bee6ce2cf27c5root	} else {
55683827f40a2d97261528087331b0bee6ce2cf27c5root	    retval = curPool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
55783827f40a2d97261528087331b0bee6ce2cf27c5root	    if (retval)
55883827f40a2d97261528087331b0bee6ce2cf27c5root		goto out;
55983827f40a2d97261528087331b0bee6ce2cf27c5root	    synced = 1;
56083827f40a2d97261528087331b0bee6ce2cf27c5root	}
56183827f40a2d97261528087331b0bee6ce2cf27c5root    } else
56283827f40a2d97261528087331b0bee6ce2cf27c5root	synced = 1;
56383827f40a2d97261528087331b0bee6ce2cf27c5root
56483827f40a2d97261528087331b0bee6ce2cf27c5root    placement_diff = placement ^ buf->placement;
56583827f40a2d97261528087331b0bee6ce2cf27c5root
56683827f40a2d97261528087331b0bee6ce2cf27c5root    /*
56783827f40a2d97261528087331b0bee6ce2cf27c5root     * We might need to change buffer placement.
56883827f40a2d97261528087331b0bee6ce2cf27c5root     */
56983827f40a2d97261528087331b0bee6ce2cf27c5root
57083827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
57183827f40a2d97261528087331b0bee6ce2cf27c5root    curPool = storage->pool;
57283827f40a2d97261528087331b0bee6ce2cf27c5root
57383827f40a2d97261528087331b0bee6ce2cf27c5root    if (placement_diff) {
57483827f40a2d97261528087331b0bee6ce2cf27c5root	assert(curPool->setStatus != NULL);
57583827f40a2d97261528087331b0bee6ce2cf27c5root	curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
57683827f40a2d97261528087331b0bee6ce2cf27c5root	retval = curPool->setStatus(storage,
57783827f40a2d97261528087331b0bee6ce2cf27c5root				    placement_diff & placement,
57883827f40a2d97261528087331b0bee6ce2cf27c5root				    placement_diff & ~placement);
57983827f40a2d97261528087331b0bee6ce2cf27c5root	if (retval)
58083827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
58183827f40a2d97261528087331b0bee6ce2cf27c5root
58283827f40a2d97261528087331b0bee6ce2cf27c5root	buf->placement = placement;
58383827f40a2d97261528087331b0bee6ce2cf27c5root
58483827f40a2d97261528087331b0bee6ce2cf27c5root    }
58583827f40a2d97261528087331b0bee6ce2cf27c5root
58683827f40a2d97261528087331b0bee6ce2cf27c5root    if (!synced) {
58783827f40a2d97261528087331b0bee6ce2cf27c5root	retval = curPool->syncforcpu(buf->storage, WSBM_SYNCCPU_WRITE);
58883827f40a2d97261528087331b0bee6ce2cf27c5root
58983827f40a2d97261528087331b0bee6ce2cf27c5root	if (retval)
59083827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
59183827f40a2d97261528087331b0bee6ce2cf27c5root	synced = 1;
59283827f40a2d97261528087331b0bee6ce2cf27c5root    }
59383827f40a2d97261528087331b0bee6ce2cf27c5root
59483827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
59583827f40a2d97261528087331b0bee6ce2cf27c5root    curPool = storage->pool;
59683827f40a2d97261528087331b0bee6ce2cf27c5root
59783827f40a2d97261528087331b0bee6ce2cf27c5root    if (data) {
59883827f40a2d97261528087331b0bee6ce2cf27c5root	retval = curPool->map(storage, WSBM_ACCESS_WRITE, &virtual);
59983827f40a2d97261528087331b0bee6ce2cf27c5root	if (retval)
60083827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
60183827f40a2d97261528087331b0bee6ce2cf27c5root	memcpy(virtual, data, size);
60283827f40a2d97261528087331b0bee6ce2cf27c5root	curPool->unmap(storage);
60383827f40a2d97261528087331b0bee6ce2cf27c5root    }
60483827f40a2d97261528087331b0bee6ce2cf27c5root
60583827f40a2d97261528087331b0bee6ce2cf27c5root  out:
60683827f40a2d97261528087331b0bee6ce2cf27c5root
60783827f40a2d97261528087331b0bee6ce2cf27c5root    if (synced)
60883827f40a2d97261528087331b0bee6ce2cf27c5root	curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
60983827f40a2d97261528087331b0bee6ce2cf27c5root
61083827f40a2d97261528087331b0bee6ce2cf27c5root    return retval;
61183827f40a2d97261528087331b0bee6ce2cf27c5root}
61283827f40a2d97261528087331b0bee6ce2cf27c5root
6138acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiangint
6148acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei JiangwsbmBODataUB(struct _WsbmBufferObject *buf,
6158acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        unsigned size, const void *data, struct _WsbmBufferPool *newPool,
616ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelil        uint32_t placement, const unsigned long *user_ptr, int fd)
6178acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang{
6188acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    int newBuffer;
6198acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    int retval = 0;
6208acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    struct _WsbmBufStorage *storage;
6218acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    int synced = 0;
6228acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    uint32_t placement_diff;
6238acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    struct _WsbmBufferPool *curPool;
6248acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    extern struct _WsbmBufStorage *
6258acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    ttm_pool_ub_create(struct _WsbmBufferPool *pool,
6268acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        unsigned long size, uint32_t placement, unsigned alignment,
627ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelil        const unsigned long *user_ptr, int fd);
6288acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6298acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (buf->bufferType == WSBM_BUFFER_SIMPLE)
6308acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        return -EINVAL;
6318acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6328acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    storage = buf->storage;
6338acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6348acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (newPool == NULL)
6358acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        newPool = buf->pool;
6368acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6378acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (newPool == NULL)
6388acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        return -EINVAL;
6398acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6408acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    newBuffer = (!storage || storage->pool != newPool ||
6418acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        storage->pool->size(storage) < size ||
6428acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        storage->pool->size(storage) >
6438acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        size + WSBM_BODATA_SIZE_ACCEPT);
6448acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6458acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (!placement)
6468acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        placement = buf->placement;
6478acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6488acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (newBuffer) {
6498acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (buf->bufferType == WSBM_BUFFER_REF)
6508acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            return -EINVAL;
6518acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6528acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        wsbmBufStorageUnref(&buf->storage);
6538acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6548acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (size == 0) {
6558acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            buf->pool = newPool;
6568acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            buf->placement = placement;
6578acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            retval = 0;
6588acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            goto out;
6598acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        }
6608acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6618acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        buf->storage =
662ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelil            ttm_pool_ub_create(newPool, size, placement, buf->alignment, user_ptr, fd);
6638acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (!buf->storage) {
6648acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            retval = -ENOMEM;
6658acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            goto out;
6668acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        }
6678acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6688acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        buf->placement = placement;
6698acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        buf->pool = newPool;
6708acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    } else if (wsbmAtomicRead(&storage->onList) ||
6718acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        0 != storage->pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE |
6728acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        WSBM_SYNCCPU_DONT_BLOCK)) {
6738acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        /*
6748acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        * Buffer is busy. need to create a new one.
6758acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        * Actually such case will not be encountered for current ICS implementation
6768acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        * TODO: maybe need refine the following code when such usage case is required
6778acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        */
6788acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6798acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        struct _WsbmBufStorage *tmp_storage;
6808acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6818acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        curPool = storage->pool;
6828acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6838acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        tmp_storage =
684ac747113d4f6739b1462ca7fb40f2091691e209bVinil Cheeramvelil            ttm_pool_ub_create(curPool, size, placement, buf->alignment, user_ptr, fd);
6858acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
6868acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (tmp_storage) {
6878acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            wsbmBufStorageUnref(&buf->storage);
6888acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            buf->storage = tmp_storage;
6898acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            buf->placement = placement;
6908acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        } else {
6918acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            retval = curPool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
6928acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            if (retval)
6938acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang                goto out;
6948acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            synced = 1;
6958acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        }
6968acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    } else {
6978acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        synced = 1;
6988acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    }
6998acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7008acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    placement_diff = placement ^ buf->placement;
7018acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7028acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    /*
7038acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    * We might need to change buffer placement.
7048acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    */
7058acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7068acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    storage = buf->storage;
7078acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    curPool = storage->pool;
7088acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7098acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (placement_diff) {
7108acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        assert(curPool->setStatus != NULL);
7118acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
7128acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        retval = curPool->setStatus(storage,
7138acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            placement_diff & placement,
7148acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            placement_diff & ~placement);
7158acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (retval)
7168acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            goto out;
7178acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7188acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        buf->placement = placement;
7198acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    }
7208acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7218acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (!synced) {
7228acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        retval = curPool->syncforcpu(buf->storage, WSBM_SYNCCPU_WRITE);
7238acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        if (retval)
7248acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang            goto out;
7258acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        synced = 1;
7268acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    }
7278acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7288acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    storage = buf->storage;
7298acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    curPool = storage->pool;
7308acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7318acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (data) {
7323795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel        memcpy((unsigned long *) user_ptr, data, size);
7338acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    }
7348acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7358acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    out:
7368acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7378acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    if (synced)
7388acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang        curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
7398acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
7408acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang    return retval;
7418acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang}
7428acea2d0d04b7aff3fb59bb071cc7a69c47b9929Fei Jiang
74383827f40a2d97261528087331b0bee6ce2cf27c5rootstatic struct _WsbmBufStorage *
74483827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmStorageClone(struct _WsbmBufferObject *buf)
74583827f40a2d97261528087331b0bee6ce2cf27c5root{
74683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
74783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferPool *pool = storage->pool;
74883827f40a2d97261528087331b0bee6ce2cf27c5root
74983827f40a2d97261528087331b0bee6ce2cf27c5root    return pool->create(pool, pool->size(storage), buf->placement,
75083827f40a2d97261528087331b0bee6ce2cf27c5root			buf->alignment);
75183827f40a2d97261528087331b0bee6ce2cf27c5root}
75283827f40a2d97261528087331b0bee6ce2cf27c5root
75383827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferObject *
75483827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOClone(struct _WsbmBufferObject *buf,
75583827f40a2d97261528087331b0bee6ce2cf27c5root	    int (*accelCopy) (struct _WsbmBufferObject *,
75683827f40a2d97261528087331b0bee6ce2cf27c5root			      struct _WsbmBufferObject *))
75783827f40a2d97261528087331b0bee6ce2cf27c5root{
75883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferObject *newBuf;
75983827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
76083827f40a2d97261528087331b0bee6ce2cf27c5root
76183827f40a2d97261528087331b0bee6ce2cf27c5root    newBuf = malloc(sizeof(*newBuf));
76283827f40a2d97261528087331b0bee6ce2cf27c5root    if (!newBuf)
76383827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
76483827f40a2d97261528087331b0bee6ce2cf27c5root
76583827f40a2d97261528087331b0bee6ce2cf27c5root    *newBuf = *buf;
76683827f40a2d97261528087331b0bee6ce2cf27c5root    newBuf->storage = wsbmStorageClone(buf);
76783827f40a2d97261528087331b0bee6ce2cf27c5root    if (!newBuf->storage)
76883827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err0;
76983827f40a2d97261528087331b0bee6ce2cf27c5root
77083827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmAtomicSet(&newBuf->refCount, 1);
77183827f40a2d97261528087331b0bee6ce2cf27c5root    if (!accelCopy || accelCopy(newBuf, buf) != 0) {
77283827f40a2d97261528087331b0bee6ce2cf27c5root
77383827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufferPool *pool = buf->storage->pool;
77483827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *storage = buf->storage;
77583827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *newStorage = newBuf->storage;
77683827f40a2d97261528087331b0bee6ce2cf27c5root	void *virtual;
77783827f40a2d97261528087331b0bee6ce2cf27c5root	void *nVirtual;
77883827f40a2d97261528087331b0bee6ce2cf27c5root
77983827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->syncforcpu(storage, WSBM_SYNCCPU_READ);
78083827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
78183827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out_err1;
78283827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->map(storage, WSBM_ACCESS_READ, &virtual);
78383827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
78483827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out_err2;
78583827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->map(newStorage, WSBM_ACCESS_WRITE, &nVirtual);
78683827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
78783827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out_err3;
78883827f40a2d97261528087331b0bee6ce2cf27c5root
78983827f40a2d97261528087331b0bee6ce2cf27c5root	memcpy(nVirtual, virtual, pool->size(storage));
79083827f40a2d97261528087331b0bee6ce2cf27c5root	pool->unmap(newBuf->storage);
79183827f40a2d97261528087331b0bee6ce2cf27c5root	pool->unmap(buf->storage);
79283827f40a2d97261528087331b0bee6ce2cf27c5root	pool->releasefromcpu(storage, WSBM_SYNCCPU_READ);
79383827f40a2d97261528087331b0bee6ce2cf27c5root    }
79483827f40a2d97261528087331b0bee6ce2cf27c5root
79583827f40a2d97261528087331b0bee6ce2cf27c5root    return newBuf;
79683827f40a2d97261528087331b0bee6ce2cf27c5root  out_err3:
79783827f40a2d97261528087331b0bee6ce2cf27c5root    buf->pool->unmap(buf->storage);
79883827f40a2d97261528087331b0bee6ce2cf27c5root  out_err2:
79983827f40a2d97261528087331b0bee6ce2cf27c5root    buf->pool->releasefromcpu(buf->storage, WSBM_SYNCCPU_READ);
80083827f40a2d97261528087331b0bee6ce2cf27c5root  out_err1:
80183827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmBufStorageUnref(&newBuf->storage);
80283827f40a2d97261528087331b0bee6ce2cf27c5root  out_err0:
80383827f40a2d97261528087331b0bee6ce2cf27c5root    free(newBuf);
80483827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
80583827f40a2d97261528087331b0bee6ce2cf27c5root}
80683827f40a2d97261528087331b0bee6ce2cf27c5root
80783827f40a2d97261528087331b0bee6ce2cf27c5rootint
80883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOSubData(struct _WsbmBufferObject *buf,
80983827f40a2d97261528087331b0bee6ce2cf27c5root	      unsigned long offset, unsigned long size, const void *data,
81083827f40a2d97261528087331b0bee6ce2cf27c5root	      int (*accelCopy) (struct _WsbmBufferObject *,
81183827f40a2d97261528087331b0bee6ce2cf27c5root				struct _WsbmBufferObject *))
81283827f40a2d97261528087331b0bee6ce2cf27c5root{
81383827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
81483827f40a2d97261528087331b0bee6ce2cf27c5root
81583827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->bufferType == WSBM_BUFFER_SIMPLE)
81683827f40a2d97261528087331b0bee6ce2cf27c5root	return -EINVAL;
81783827f40a2d97261528087331b0bee6ce2cf27c5root
81883827f40a2d97261528087331b0bee6ce2cf27c5root    if (size && data) {
81983827f40a2d97261528087331b0bee6ce2cf27c5root	void *virtual;
82083827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *storage = buf->storage;
82183827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufferPool *pool = storage->pool;
82283827f40a2d97261528087331b0bee6ce2cf27c5root
82383827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
82483827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
82583827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
82683827f40a2d97261528087331b0bee6ce2cf27c5root
82783827f40a2d97261528087331b0bee6ce2cf27c5root	if (wsbmAtomicRead(&storage->onList)) {
82883827f40a2d97261528087331b0bee6ce2cf27c5root
82983827f40a2d97261528087331b0bee6ce2cf27c5root	    struct _WsbmBufferObject *newBuf;
83083827f40a2d97261528087331b0bee6ce2cf27c5root
83183827f40a2d97261528087331b0bee6ce2cf27c5root	    /*
83283827f40a2d97261528087331b0bee6ce2cf27c5root	     * Another context has this buffer on its validate list.
83383827f40a2d97261528087331b0bee6ce2cf27c5root	     * This should be a very rare situation, but it can be valid,
83483827f40a2d97261528087331b0bee6ce2cf27c5root	     * and therefore we must deal with it by cloning the storage.
83583827f40a2d97261528087331b0bee6ce2cf27c5root	     */
83683827f40a2d97261528087331b0bee6ce2cf27c5root
83783827f40a2d97261528087331b0bee6ce2cf27c5root	    pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
83883827f40a2d97261528087331b0bee6ce2cf27c5root	    newBuf = wsbmBOClone(buf, accelCopy);
83983827f40a2d97261528087331b0bee6ce2cf27c5root
84083827f40a2d97261528087331b0bee6ce2cf27c5root	    /*
84183827f40a2d97261528087331b0bee6ce2cf27c5root	     * If clone fails we have the choice of either bailing.
84283827f40a2d97261528087331b0bee6ce2cf27c5root	     * (The other context will be happy), or go on and update
84383827f40a2d97261528087331b0bee6ce2cf27c5root	     * the old buffer anyway. (We will be happy). We choose the
84483827f40a2d97261528087331b0bee6ce2cf27c5root	     * latter.
84583827f40a2d97261528087331b0bee6ce2cf27c5root	     */
84683827f40a2d97261528087331b0bee6ce2cf27c5root
84783827f40a2d97261528087331b0bee6ce2cf27c5root	    if (newBuf) {
84883827f40a2d97261528087331b0bee6ce2cf27c5root		storage = newBuf->storage;
84983827f40a2d97261528087331b0bee6ce2cf27c5root		wsbmAtomicInc(&storage->refCount);
85083827f40a2d97261528087331b0bee6ce2cf27c5root		wsbmBufStorageUnref(&buf->storage);
85183827f40a2d97261528087331b0bee6ce2cf27c5root		buf->storage = storage;
85283827f40a2d97261528087331b0bee6ce2cf27c5root		wsbmBOUnreference(&newBuf);
85383827f40a2d97261528087331b0bee6ce2cf27c5root		pool = storage->pool;
85483827f40a2d97261528087331b0bee6ce2cf27c5root	    }
85583827f40a2d97261528087331b0bee6ce2cf27c5root
85683827f40a2d97261528087331b0bee6ce2cf27c5root	    ret = pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
85783827f40a2d97261528087331b0bee6ce2cf27c5root	    if (ret)
85883827f40a2d97261528087331b0bee6ce2cf27c5root		goto out;
85983827f40a2d97261528087331b0bee6ce2cf27c5root	}
86083827f40a2d97261528087331b0bee6ce2cf27c5root
86183827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->map(storage, WSBM_ACCESS_WRITE, &virtual);
86283827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret) {
86383827f40a2d97261528087331b0bee6ce2cf27c5root	    pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
86483827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
86583827f40a2d97261528087331b0bee6ce2cf27c5root	}
86683827f40a2d97261528087331b0bee6ce2cf27c5root
86783827f40a2d97261528087331b0bee6ce2cf27c5root	memcpy((unsigned char *)virtual + offset, data, size);
86883827f40a2d97261528087331b0bee6ce2cf27c5root	pool->unmap(storage);
86983827f40a2d97261528087331b0bee6ce2cf27c5root	pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
87083827f40a2d97261528087331b0bee6ce2cf27c5root    }
87183827f40a2d97261528087331b0bee6ce2cf27c5root  out:
87283827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
87383827f40a2d97261528087331b0bee6ce2cf27c5root}
87483827f40a2d97261528087331b0bee6ce2cf27c5root
87583827f40a2d97261528087331b0bee6ce2cf27c5rootint
87683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOGetSubData(struct _WsbmBufferObject *buf,
87783827f40a2d97261528087331b0bee6ce2cf27c5root		 unsigned long offset, unsigned long size, void *data)
87883827f40a2d97261528087331b0bee6ce2cf27c5root{
87983827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
88083827f40a2d97261528087331b0bee6ce2cf27c5root
88183827f40a2d97261528087331b0bee6ce2cf27c5root    if (size && data) {
88283827f40a2d97261528087331b0bee6ce2cf27c5root	void *virtual;
88383827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufStorage *storage = buf->storage;
88483827f40a2d97261528087331b0bee6ce2cf27c5root	struct _WsbmBufferPool *pool = storage->pool;
88583827f40a2d97261528087331b0bee6ce2cf27c5root
88683827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->syncforcpu(storage, WSBM_SYNCCPU_READ);
88783827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
88883827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
88983827f40a2d97261528087331b0bee6ce2cf27c5root	ret = pool->map(storage, WSBM_ACCESS_READ, &virtual);
89083827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret) {
89183827f40a2d97261528087331b0bee6ce2cf27c5root	    pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
89283827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out;
89383827f40a2d97261528087331b0bee6ce2cf27c5root	}
89483827f40a2d97261528087331b0bee6ce2cf27c5root	memcpy(data, (unsigned char *)virtual + offset, size);
89583827f40a2d97261528087331b0bee6ce2cf27c5root	pool->unmap(storage);
89683827f40a2d97261528087331b0bee6ce2cf27c5root	pool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
89783827f40a2d97261528087331b0bee6ce2cf27c5root    }
89883827f40a2d97261528087331b0bee6ce2cf27c5root  out:
89983827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
90083827f40a2d97261528087331b0bee6ce2cf27c5root}
90183827f40a2d97261528087331b0bee6ce2cf27c5root
90283827f40a2d97261528087331b0bee6ce2cf27c5rootint
90383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOSetReferenced(struct _WsbmBufferObject *buf, unsigned long handle)
90483827f40a2d97261528087331b0bee6ce2cf27c5root{
90583827f40a2d97261528087331b0bee6ce2cf27c5root    int ret = 0;
90683827f40a2d97261528087331b0bee6ce2cf27c5root
90783827f40a2d97261528087331b0bee6ce2cf27c5root    wsbmBufStorageUnref(&buf->storage);
90883827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->pool->createByReference == NULL) {
90983827f40a2d97261528087331b0bee6ce2cf27c5root	ret = -EINVAL;
91083827f40a2d97261528087331b0bee6ce2cf27c5root	goto out;
91183827f40a2d97261528087331b0bee6ce2cf27c5root    }
91283827f40a2d97261528087331b0bee6ce2cf27c5root    buf->storage = buf->pool->createByReference(buf->pool, handle);
91383827f40a2d97261528087331b0bee6ce2cf27c5root    if (!buf->storage) {
91483827f40a2d97261528087331b0bee6ce2cf27c5root	ret = -EINVAL;
91583827f40a2d97261528087331b0bee6ce2cf27c5root	goto out;
91683827f40a2d97261528087331b0bee6ce2cf27c5root    }
91783827f40a2d97261528087331b0bee6ce2cf27c5root    buf->bufferType = WSBM_BUFFER_REF;
91883827f40a2d97261528087331b0bee6ce2cf27c5root  out:
91983827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
92083827f40a2d97261528087331b0bee6ce2cf27c5root}
92183827f40a2d97261528087331b0bee6ce2cf27c5root
92283827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
92383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOFreeSimple(void *ptr)
92483827f40a2d97261528087331b0bee6ce2cf27c5root{
92583827f40a2d97261528087331b0bee6ce2cf27c5root    free(ptr);
92683827f40a2d97261528087331b0bee6ce2cf27c5root}
92783827f40a2d97261528087331b0bee6ce2cf27c5root
92883827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferObject *
92983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOCreateSimple(struct _WsbmBufferPool *pool,
93083827f40a2d97261528087331b0bee6ce2cf27c5root		   unsigned long size,
93183827f40a2d97261528087331b0bee6ce2cf27c5root		   uint32_t placement,
93283827f40a2d97261528087331b0bee6ce2cf27c5root		   unsigned alignment, size_t extra_size, size_t * offset)
93383827f40a2d97261528087331b0bee6ce2cf27c5root{
93483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferObject *buf;
93583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
93683827f40a2d97261528087331b0bee6ce2cf27c5root
93783827f40a2d97261528087331b0bee6ce2cf27c5root    *offset = (sizeof(*buf) + 15) & ~15;
93883827f40a2d97261528087331b0bee6ce2cf27c5root
93983827f40a2d97261528087331b0bee6ce2cf27c5root    if (extra_size) {
94083827f40a2d97261528087331b0bee6ce2cf27c5root	extra_size += *offset - sizeof(*buf);
94183827f40a2d97261528087331b0bee6ce2cf27c5root    }
94283827f40a2d97261528087331b0bee6ce2cf27c5root
94383827f40a2d97261528087331b0bee6ce2cf27c5root    buf = (struct _WsbmBufferObject *)calloc(1, sizeof(*buf) + extra_size);
94483827f40a2d97261528087331b0bee6ce2cf27c5root    if (!buf)
94583827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
94683827f40a2d97261528087331b0bee6ce2cf27c5root
94783827f40a2d97261528087331b0bee6ce2cf27c5root    storage = pool->create(pool, size, placement, alignment);
94883827f40a2d97261528087331b0bee6ce2cf27c5root    if (!storage)
94983827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_err0;
95083827f40a2d97261528087331b0bee6ce2cf27c5root
95183827f40a2d97261528087331b0bee6ce2cf27c5root    storage->destroyContainer = &wsbmBOFreeSimple;
95283827f40a2d97261528087331b0bee6ce2cf27c5root    storage->destroyArg = buf;
95383827f40a2d97261528087331b0bee6ce2cf27c5root
95483827f40a2d97261528087331b0bee6ce2cf27c5root    buf->storage = storage;
95583827f40a2d97261528087331b0bee6ce2cf27c5root    buf->alignment = alignment;
95683827f40a2d97261528087331b0bee6ce2cf27c5root    buf->pool = pool;
95783827f40a2d97261528087331b0bee6ce2cf27c5root    buf->placement = placement;
95883827f40a2d97261528087331b0bee6ce2cf27c5root    buf->bufferType = WSBM_BUFFER_SIMPLE;
95983827f40a2d97261528087331b0bee6ce2cf27c5root
96083827f40a2d97261528087331b0bee6ce2cf27c5root    return buf;
96183827f40a2d97261528087331b0bee6ce2cf27c5root
96283827f40a2d97261528087331b0bee6ce2cf27c5root  out_err0:
96383827f40a2d97261528087331b0bee6ce2cf27c5root    free(buf);
96483827f40a2d97261528087331b0bee6ce2cf27c5root    return NULL;
96583827f40a2d97261528087331b0bee6ce2cf27c5root}
96683827f40a2d97261528087331b0bee6ce2cf27c5root
96783827f40a2d97261528087331b0bee6ce2cf27c5rootint
96883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmGenBuffers(struct _WsbmBufferPool *pool,
96983827f40a2d97261528087331b0bee6ce2cf27c5root	       unsigned n,
97083827f40a2d97261528087331b0bee6ce2cf27c5root	       struct _WsbmBufferObject *buffers[],
97183827f40a2d97261528087331b0bee6ce2cf27c5root	       unsigned alignment, uint32_t placement)
97283827f40a2d97261528087331b0bee6ce2cf27c5root{
97383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferObject *buf;
9743795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel    unsigned int i;
97583827f40a2d97261528087331b0bee6ce2cf27c5root
97683827f40a2d97261528087331b0bee6ce2cf27c5root    placement = (placement) ? placement :
97783827f40a2d97261528087331b0bee6ce2cf27c5root	WSBM_PL_FLAG_SYSTEM | WSBM_PL_FLAG_CACHED;
97883827f40a2d97261528087331b0bee6ce2cf27c5root
97983827f40a2d97261528087331b0bee6ce2cf27c5root    for (i = 0; i < n; ++i) {
98083827f40a2d97261528087331b0bee6ce2cf27c5root	buf = (struct _WsbmBufferObject *)calloc(1, sizeof(*buf));
98183827f40a2d97261528087331b0bee6ce2cf27c5root	if (!buf)
98283827f40a2d97261528087331b0bee6ce2cf27c5root	    return -ENOMEM;
98383827f40a2d97261528087331b0bee6ce2cf27c5root
98483827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicSet(&buf->refCount, 1);
98583827f40a2d97261528087331b0bee6ce2cf27c5root	buf->placement = placement;
98683827f40a2d97261528087331b0bee6ce2cf27c5root	buf->alignment = alignment;
98783827f40a2d97261528087331b0bee6ce2cf27c5root	buf->pool = pool;
98883827f40a2d97261528087331b0bee6ce2cf27c5root	buf->bufferType = WSBM_BUFFER_COMPLEX;
98983827f40a2d97261528087331b0bee6ce2cf27c5root	buffers[i] = buf;
99083827f40a2d97261528087331b0bee6ce2cf27c5root    }
99183827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
99283827f40a2d97261528087331b0bee6ce2cf27c5root}
99383827f40a2d97261528087331b0bee6ce2cf27c5root
99483827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
99583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmDeleteBuffers(unsigned n, struct _WsbmBufferObject *buffers[])
99683827f40a2d97261528087331b0bee6ce2cf27c5root{
9973795b36d0c937666a5bddc352c781d5e0beec26bThierry Strudel    unsigned int i;
99883827f40a2d97261528087331b0bee6ce2cf27c5root
99983827f40a2d97261528087331b0bee6ce2cf27c5root    for (i = 0; i < n; ++i) {
100083827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBOUnreference(&buffers[i]);
100183827f40a2d97261528087331b0bee6ce2cf27c5root    }
100283827f40a2d97261528087331b0bee6ce2cf27c5root}
100383827f40a2d97261528087331b0bee6ce2cf27c5root
100483827f40a2d97261528087331b0bee6ce2cf27c5root/*
100583827f40a2d97261528087331b0bee6ce2cf27c5root * Note that lists are per-context and don't need mutex protection.
100683827f40a2d97261528087331b0bee6ce2cf27c5root */
100783827f40a2d97261528087331b0bee6ce2cf27c5root
100883827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _WsbmBufferList *
100983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOCreateList(int target, int hasKernelBuffers)
101083827f40a2d97261528087331b0bee6ce2cf27c5root{
101183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufferList *list = calloc(sizeof(*list), 1);
101283827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
101383827f40a2d97261528087331b0bee6ce2cf27c5root
10146f2c71fc4f82da090495374fd3386f237192743cElaine Wang    if (!list)
10156f2c71fc4f82da090495374fd3386f237192743cElaine Wang        return NULL;
101683827f40a2d97261528087331b0bee6ce2cf27c5root    list->hasKernelBuffers = hasKernelBuffers;
101783827f40a2d97261528087331b0bee6ce2cf27c5root    if (hasKernelBuffers) {
1018ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        ret = validateCreateList(target, &list->kernelBuffers, 0);
1019ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        if (ret) {
1020ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu            free(list);
1021ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu            return NULL;
1022ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        }
102383827f40a2d97261528087331b0bee6ce2cf27c5root    }
102483827f40a2d97261528087331b0bee6ce2cf27c5root
102583827f40a2d97261528087331b0bee6ce2cf27c5root    ret = validateCreateList(target, &list->userBuffers, 1);
102683827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret) {
1027ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        validateFreeList(&list->kernelBuffers);
1028ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        free(list);
1029ba6cd22cc9dbadb14dad331ef6ddc8b1e403a654Austin Hu        return NULL;
103083827f40a2d97261528087331b0bee6ce2cf27c5root    }
103183827f40a2d97261528087331b0bee6ce2cf27c5root
103283827f40a2d97261528087331b0bee6ce2cf27c5root    return list;
103383827f40a2d97261528087331b0bee6ce2cf27c5root}
103483827f40a2d97261528087331b0bee6ce2cf27c5root
103583827f40a2d97261528087331b0bee6ce2cf27c5rootint
103683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOResetList(struct _WsbmBufferList *list)
103783827f40a2d97261528087331b0bee6ce2cf27c5root{
103883827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
103983827f40a2d97261528087331b0bee6ce2cf27c5root
104083827f40a2d97261528087331b0bee6ce2cf27c5root    if (list->hasKernelBuffers) {
104183827f40a2d97261528087331b0bee6ce2cf27c5root	ret = validateResetList(&list->kernelBuffers);
104283827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
104383827f40a2d97261528087331b0bee6ce2cf27c5root	    return ret;
104483827f40a2d97261528087331b0bee6ce2cf27c5root    }
104583827f40a2d97261528087331b0bee6ce2cf27c5root    ret = validateResetList(&list->userBuffers);
104683827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
104783827f40a2d97261528087331b0bee6ce2cf27c5root}
104883827f40a2d97261528087331b0bee6ce2cf27c5root
104983827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
105083827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOFreeList(struct _WsbmBufferList *list)
105183827f40a2d97261528087331b0bee6ce2cf27c5root{
105283827f40a2d97261528087331b0bee6ce2cf27c5root    if (list->hasKernelBuffers)
105383827f40a2d97261528087331b0bee6ce2cf27c5root	validateFreeList(&list->kernelBuffers);
105483827f40a2d97261528087331b0bee6ce2cf27c5root    validateFreeList(&list->userBuffers);
105583827f40a2d97261528087331b0bee6ce2cf27c5root    free(list);
105683827f40a2d97261528087331b0bee6ce2cf27c5root}
105783827f40a2d97261528087331b0bee6ce2cf27c5root
105883827f40a2d97261528087331b0bee6ce2cf27c5rootstatic int
105983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmAddValidateItem(struct _ValidateList *list, void *buf, uint64_t flags,
106083827f40a2d97261528087331b0bee6ce2cf27c5root		    uint64_t mask, int *itemLoc,
106183827f40a2d97261528087331b0bee6ce2cf27c5root		    struct _ValidateNode **pnode, int *newItem)
106283827f40a2d97261528087331b0bee6ce2cf27c5root{
106383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node, *cur;
106483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l;
106583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *hashHead;
106683827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t hash;
106783827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t count = 0;
106883827f40a2d97261528087331b0bee6ce2cf27c5root    uint32_t key = (unsigned long) buf;
106983827f40a2d97261528087331b0bee6ce2cf27c5root
107083827f40a2d97261528087331b0bee6ce2cf27c5root    cur = NULL;
107183827f40a2d97261528087331b0bee6ce2cf27c5root    hash = wsbmHashFunc((uint8_t *) &key, 4, list->hashMask);
107283827f40a2d97261528087331b0bee6ce2cf27c5root    hashHead = list->hashTable + hash;
107383827f40a2d97261528087331b0bee6ce2cf27c5root    *newItem = 0;
107483827f40a2d97261528087331b0bee6ce2cf27c5root
107583827f40a2d97261528087331b0bee6ce2cf27c5root    for (l = hashHead->next; l != hashHead; l = l->next) {
107683827f40a2d97261528087331b0bee6ce2cf27c5root        count++;
107783827f40a2d97261528087331b0bee6ce2cf27c5root	node = WSBMLISTENTRY(l, struct _ValidateNode, hashHead);
107883827f40a2d97261528087331b0bee6ce2cf27c5root
107983827f40a2d97261528087331b0bee6ce2cf27c5root	if (node->buf == buf) {
108083827f40a2d97261528087331b0bee6ce2cf27c5root	    cur = node;
108183827f40a2d97261528087331b0bee6ce2cf27c5root	    break;
108283827f40a2d97261528087331b0bee6ce2cf27c5root	}
108383827f40a2d97261528087331b0bee6ce2cf27c5root    }
108483827f40a2d97261528087331b0bee6ce2cf27c5root
108583827f40a2d97261528087331b0bee6ce2cf27c5root    if (!cur) {
108683827f40a2d97261528087331b0bee6ce2cf27c5root	cur = validateListAddNode(list, buf, hash, flags, mask);
108783827f40a2d97261528087331b0bee6ce2cf27c5root	if (!cur)
108883827f40a2d97261528087331b0bee6ce2cf27c5root	    return -ENOMEM;
108983827f40a2d97261528087331b0bee6ce2cf27c5root	*newItem = 1;
109083827f40a2d97261528087331b0bee6ce2cf27c5root	cur->func->clear(cur);
109183827f40a2d97261528087331b0bee6ce2cf27c5root    } else {
109283827f40a2d97261528087331b0bee6ce2cf27c5root	uint64_t set_flags = flags & mask;
109383827f40a2d97261528087331b0bee6ce2cf27c5root	uint64_t clr_flags = (~flags) & mask;
109483827f40a2d97261528087331b0bee6ce2cf27c5root
109583827f40a2d97261528087331b0bee6ce2cf27c5root	if (((cur->clr_flags | clr_flags) & WSBM_PL_MASK_MEM) ==
109683827f40a2d97261528087331b0bee6ce2cf27c5root	    WSBM_PL_MASK_MEM) {
109783827f40a2d97261528087331b0bee6ce2cf27c5root	    /*
109883827f40a2d97261528087331b0bee6ce2cf27c5root	     * No available memory type left. Bail.
109983827f40a2d97261528087331b0bee6ce2cf27c5root	     */
110083827f40a2d97261528087331b0bee6ce2cf27c5root	    return -EINVAL;
110183827f40a2d97261528087331b0bee6ce2cf27c5root	}
110283827f40a2d97261528087331b0bee6ce2cf27c5root
110383827f40a2d97261528087331b0bee6ce2cf27c5root	if ((cur->set_flags | set_flags) &
110483827f40a2d97261528087331b0bee6ce2cf27c5root	    (cur->clr_flags | clr_flags) & ~WSBM_PL_MASK_MEM) {
110583827f40a2d97261528087331b0bee6ce2cf27c5root	    /*
110683827f40a2d97261528087331b0bee6ce2cf27c5root	     * Conflicting flags. Bail.
110783827f40a2d97261528087331b0bee6ce2cf27c5root	     */
110883827f40a2d97261528087331b0bee6ce2cf27c5root	    return -EINVAL;
110983827f40a2d97261528087331b0bee6ce2cf27c5root	}
111083827f40a2d97261528087331b0bee6ce2cf27c5root
111183827f40a2d97261528087331b0bee6ce2cf27c5root	cur->set_flags &= ~(clr_flags & WSBM_PL_MASK_MEM);
111283827f40a2d97261528087331b0bee6ce2cf27c5root	cur->set_flags |= (set_flags & ~WSBM_PL_MASK_MEM);
111383827f40a2d97261528087331b0bee6ce2cf27c5root	cur->clr_flags |= clr_flags;
111483827f40a2d97261528087331b0bee6ce2cf27c5root    }
111583827f40a2d97261528087331b0bee6ce2cf27c5root    *itemLoc = cur->listItem;
111683827f40a2d97261528087331b0bee6ce2cf27c5root    if (pnode)
111783827f40a2d97261528087331b0bee6ce2cf27c5root	*pnode = cur;
111883827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
111983827f40a2d97261528087331b0bee6ce2cf27c5root}
112083827f40a2d97261528087331b0bee6ce2cf27c5root
112183827f40a2d97261528087331b0bee6ce2cf27c5rootint
112283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOAddListItem(struct _WsbmBufferList *list,
112383827f40a2d97261528087331b0bee6ce2cf27c5root		  struct _WsbmBufferObject *buf,
112483827f40a2d97261528087331b0bee6ce2cf27c5root		  uint64_t flags, uint64_t mask, int *itemLoc,
112583827f40a2d97261528087331b0bee6ce2cf27c5root		  struct _ValidateNode **node)
112683827f40a2d97261528087331b0bee6ce2cf27c5root{
112783827f40a2d97261528087331b0bee6ce2cf27c5root    int newItem;
112883827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
112983827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
113083827f40a2d97261528087331b0bee6ce2cf27c5root    int dummy;
113183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *dummyNode;
113283827f40a2d97261528087331b0bee6ce2cf27c5root
113383827f40a2d97261528087331b0bee6ce2cf27c5root    if (list->hasKernelBuffers) {
113483827f40a2d97261528087331b0bee6ce2cf27c5root	ret = wsbmAddValidateItem(&list->kernelBuffers,
113583827f40a2d97261528087331b0bee6ce2cf27c5root				  storage->pool->kernel(storage),
113683827f40a2d97261528087331b0bee6ce2cf27c5root				  flags, mask, itemLoc, node, &dummy);
113783827f40a2d97261528087331b0bee6ce2cf27c5root	if (ret)
113883827f40a2d97261528087331b0bee6ce2cf27c5root	    goto out_unlock;
113983827f40a2d97261528087331b0bee6ce2cf27c5root    } else {
114083827f40a2d97261528087331b0bee6ce2cf27c5root	*node = NULL;
114183827f40a2d97261528087331b0bee6ce2cf27c5root	*itemLoc = -1000;
114283827f40a2d97261528087331b0bee6ce2cf27c5root    }
114383827f40a2d97261528087331b0bee6ce2cf27c5root
114483827f40a2d97261528087331b0bee6ce2cf27c5root    ret = wsbmAddValidateItem(&list->userBuffers, storage,
114583827f40a2d97261528087331b0bee6ce2cf27c5root			      flags, mask, &dummy, &dummyNode, &newItem);
114683827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret)
114783827f40a2d97261528087331b0bee6ce2cf27c5root	goto out_unlock;
114883827f40a2d97261528087331b0bee6ce2cf27c5root
114983827f40a2d97261528087331b0bee6ce2cf27c5root    if (newItem) {
115083827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicInc(&storage->refCount);
115183827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicInc(&storage->onList);
115283827f40a2d97261528087331b0bee6ce2cf27c5root    }
115383827f40a2d97261528087331b0bee6ce2cf27c5root
115483827f40a2d97261528087331b0bee6ce2cf27c5root  out_unlock:
115583827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
115683827f40a2d97261528087331b0bee6ce2cf27c5root}
115783827f40a2d97261528087331b0bee6ce2cf27c5root
115883827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
115983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOFence(struct _WsbmBufferObject *buf, struct _WsbmFenceObject *fence)
116083827f40a2d97261528087331b0bee6ce2cf27c5root{
116183827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
116283827f40a2d97261528087331b0bee6ce2cf27c5root
116383827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
116483827f40a2d97261528087331b0bee6ce2cf27c5root    if (storage->pool->fence)
116583827f40a2d97261528087331b0bee6ce2cf27c5root	storage->pool->fence(storage, fence);
116683827f40a2d97261528087331b0bee6ce2cf27c5root
116783827f40a2d97261528087331b0bee6ce2cf27c5root}
116883827f40a2d97261528087331b0bee6ce2cf27c5root
116983827f40a2d97261528087331b0bee6ce2cf27c5rootint
117083827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOOnList(const struct _WsbmBufferObject *buf)
117183827f40a2d97261528087331b0bee6ce2cf27c5root{
117283827f40a2d97261528087331b0bee6ce2cf27c5root    if (buf->storage == NULL)
117383827f40a2d97261528087331b0bee6ce2cf27c5root	return 0;
117483827f40a2d97261528087331b0bee6ce2cf27c5root    return wsbmAtomicRead(&buf->storage->onList);
117583827f40a2d97261528087331b0bee6ce2cf27c5root}
117683827f40a2d97261528087331b0bee6ce2cf27c5root
117783827f40a2d97261528087331b0bee6ce2cf27c5rootint
117883827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOUnrefUserList(struct _WsbmBufferList *list)
117983827f40a2d97261528087331b0bee6ce2cf27c5root{
118083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
118183827f40a2d97261528087331b0bee6ce2cf27c5root    void *curBuf;
118283827f40a2d97261528087331b0bee6ce2cf27c5root
118383827f40a2d97261528087331b0bee6ce2cf27c5root    curBuf = validateListIterator(&list->userBuffers);
118483827f40a2d97261528087331b0bee6ce2cf27c5root
118583827f40a2d97261528087331b0bee6ce2cf27c5root    while (curBuf) {
118683827f40a2d97261528087331b0bee6ce2cf27c5root	storage = (struct _WsbmBufStorage *)(validateListNode(curBuf)->buf);
118783827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicDec(&storage->onList);
118883827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&storage);
118983827f40a2d97261528087331b0bee6ce2cf27c5root	curBuf = validateListNext(&list->userBuffers, curBuf);
119083827f40a2d97261528087331b0bee6ce2cf27c5root    }
119183827f40a2d97261528087331b0bee6ce2cf27c5root
119283827f40a2d97261528087331b0bee6ce2cf27c5root    return wsbmBOResetList(list);
119383827f40a2d97261528087331b0bee6ce2cf27c5root}
119483827f40a2d97261528087331b0bee6ce2cf27c5root
119583827f40a2d97261528087331b0bee6ce2cf27c5root
119683827f40a2d97261528087331b0bee6ce2cf27c5rootint
119783827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOFenceUserList(struct _WsbmBufferList *list,
119883827f40a2d97261528087331b0bee6ce2cf27c5root		    struct _WsbmFenceObject *fence)
119983827f40a2d97261528087331b0bee6ce2cf27c5root{
120083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
120183827f40a2d97261528087331b0bee6ce2cf27c5root    void *curBuf;
120283827f40a2d97261528087331b0bee6ce2cf27c5root
120383827f40a2d97261528087331b0bee6ce2cf27c5root    curBuf = validateListIterator(&list->userBuffers);
120483827f40a2d97261528087331b0bee6ce2cf27c5root
120583827f40a2d97261528087331b0bee6ce2cf27c5root    /*
120683827f40a2d97261528087331b0bee6ce2cf27c5root     * User-space fencing callbacks.
120783827f40a2d97261528087331b0bee6ce2cf27c5root     */
120883827f40a2d97261528087331b0bee6ce2cf27c5root
120983827f40a2d97261528087331b0bee6ce2cf27c5root    while (curBuf) {
121083827f40a2d97261528087331b0bee6ce2cf27c5root	storage = (struct _WsbmBufStorage *)(validateListNode(curBuf)->buf);
121183827f40a2d97261528087331b0bee6ce2cf27c5root
121283827f40a2d97261528087331b0bee6ce2cf27c5root	storage->pool->fence(storage, fence);
121383827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicDec(&storage->onList);
121483827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&storage);
121583827f40a2d97261528087331b0bee6ce2cf27c5root	curBuf = validateListNext(&list->userBuffers, curBuf);
121683827f40a2d97261528087331b0bee6ce2cf27c5root    }
121783827f40a2d97261528087331b0bee6ce2cf27c5root
121883827f40a2d97261528087331b0bee6ce2cf27c5root    return wsbmBOResetList(list);
121983827f40a2d97261528087331b0bee6ce2cf27c5root}
122083827f40a2d97261528087331b0bee6ce2cf27c5root
122183827f40a2d97261528087331b0bee6ce2cf27c5rootint
122283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOValidateUserList(struct _WsbmBufferList *list)
122383827f40a2d97261528087331b0bee6ce2cf27c5root{
122483827f40a2d97261528087331b0bee6ce2cf27c5root    void *curBuf;
122583827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
122683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
122783827f40a2d97261528087331b0bee6ce2cf27c5root    int ret;
122883827f40a2d97261528087331b0bee6ce2cf27c5root
122983827f40a2d97261528087331b0bee6ce2cf27c5root    curBuf = validateListIterator(&list->userBuffers);
123083827f40a2d97261528087331b0bee6ce2cf27c5root
123183827f40a2d97261528087331b0bee6ce2cf27c5root    /*
123283827f40a2d97261528087331b0bee6ce2cf27c5root     * User-space validation callbacks.
123383827f40a2d97261528087331b0bee6ce2cf27c5root     */
123483827f40a2d97261528087331b0bee6ce2cf27c5root
123583827f40a2d97261528087331b0bee6ce2cf27c5root    while (curBuf) {
123683827f40a2d97261528087331b0bee6ce2cf27c5root	node = validateListNode(curBuf);
123783827f40a2d97261528087331b0bee6ce2cf27c5root	storage = (struct _WsbmBufStorage *)node->buf;
123883827f40a2d97261528087331b0bee6ce2cf27c5root	if (storage->pool->validate) {
123983827f40a2d97261528087331b0bee6ce2cf27c5root	    ret = storage->pool->validate(storage, node->set_flags,
124083827f40a2d97261528087331b0bee6ce2cf27c5root					  node->clr_flags);
124183827f40a2d97261528087331b0bee6ce2cf27c5root	    if (ret)
124283827f40a2d97261528087331b0bee6ce2cf27c5root		return ret;
124383827f40a2d97261528087331b0bee6ce2cf27c5root	}
124483827f40a2d97261528087331b0bee6ce2cf27c5root	curBuf = validateListNext(&list->userBuffers, curBuf);
124583827f40a2d97261528087331b0bee6ce2cf27c5root    }
124683827f40a2d97261528087331b0bee6ce2cf27c5root    return 0;
124783827f40a2d97261528087331b0bee6ce2cf27c5root}
124883827f40a2d97261528087331b0bee6ce2cf27c5root
124983827f40a2d97261528087331b0bee6ce2cf27c5rootint
125083827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOUnvalidateUserList(struct _WsbmBufferList *list)
125183827f40a2d97261528087331b0bee6ce2cf27c5root{
125283827f40a2d97261528087331b0bee6ce2cf27c5root    void *curBuf;
125383827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
125483827f40a2d97261528087331b0bee6ce2cf27c5root    struct _ValidateNode *node;
125583827f40a2d97261528087331b0bee6ce2cf27c5root
125683827f40a2d97261528087331b0bee6ce2cf27c5root    curBuf = validateListIterator(&list->userBuffers);
125783827f40a2d97261528087331b0bee6ce2cf27c5root
125883827f40a2d97261528087331b0bee6ce2cf27c5root    /*
125983827f40a2d97261528087331b0bee6ce2cf27c5root     * User-space validation callbacks.
126083827f40a2d97261528087331b0bee6ce2cf27c5root     */
126183827f40a2d97261528087331b0bee6ce2cf27c5root
126283827f40a2d97261528087331b0bee6ce2cf27c5root    while (curBuf) {
126383827f40a2d97261528087331b0bee6ce2cf27c5root	node = validateListNode(curBuf);
126483827f40a2d97261528087331b0bee6ce2cf27c5root	storage = (struct _WsbmBufStorage *)node->buf;
126583827f40a2d97261528087331b0bee6ce2cf27c5root	if (storage->pool->unvalidate) {
126683827f40a2d97261528087331b0bee6ce2cf27c5root	    storage->pool->unvalidate(storage);
126783827f40a2d97261528087331b0bee6ce2cf27c5root	}
126883827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmAtomicDec(&storage->onList);
126983827f40a2d97261528087331b0bee6ce2cf27c5root	wsbmBufStorageUnref(&storage);
127083827f40a2d97261528087331b0bee6ce2cf27c5root	curBuf = validateListNext(&list->userBuffers, curBuf);
127183827f40a2d97261528087331b0bee6ce2cf27c5root    }
127283827f40a2d97261528087331b0bee6ce2cf27c5root    return wsbmBOResetList(list);
127383827f40a2d97261528087331b0bee6ce2cf27c5root}
127483827f40a2d97261528087331b0bee6ce2cf27c5root
127583827f40a2d97261528087331b0bee6ce2cf27c5rootvoid
127683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmPoolTakeDown(struct _WsbmBufferPool *pool)
127783827f40a2d97261528087331b0bee6ce2cf27c5root{
127883827f40a2d97261528087331b0bee6ce2cf27c5root    pool->takeDown(pool);
127983827f40a2d97261528087331b0bee6ce2cf27c5root
128083827f40a2d97261528087331b0bee6ce2cf27c5root}
128183827f40a2d97261528087331b0bee6ce2cf27c5root
128283827f40a2d97261528087331b0bee6ce2cf27c5rootunsigned long
128383827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmBOSize(struct _WsbmBufferObject *buf)
128483827f40a2d97261528087331b0bee6ce2cf27c5root{
128583827f40a2d97261528087331b0bee6ce2cf27c5root    unsigned long size;
128683827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage;
128783827f40a2d97261528087331b0bee6ce2cf27c5root
128883827f40a2d97261528087331b0bee6ce2cf27c5root    storage = buf->storage;
128983827f40a2d97261528087331b0bee6ce2cf27c5root    size = storage->pool->size(storage);
129083827f40a2d97261528087331b0bee6ce2cf27c5root
129183827f40a2d97261528087331b0bee6ce2cf27c5root    return size;
129283827f40a2d97261528087331b0bee6ce2cf27c5root
129383827f40a2d97261528087331b0bee6ce2cf27c5root}
129483827f40a2d97261528087331b0bee6ce2cf27c5root
129583827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _ValidateList *
129683827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmGetKernelValidateList(struct _WsbmBufferList *list)
129783827f40a2d97261528087331b0bee6ce2cf27c5root{
129883827f40a2d97261528087331b0bee6ce2cf27c5root    return (list->hasKernelBuffers) ? &list->kernelBuffers : NULL;
129983827f40a2d97261528087331b0bee6ce2cf27c5root}
130083827f40a2d97261528087331b0bee6ce2cf27c5root
130183827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _ValidateList *
130283827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmGetUserValidateList(struct _WsbmBufferList *list)
130383827f40a2d97261528087331b0bee6ce2cf27c5root{
130483827f40a2d97261528087331b0bee6ce2cf27c5root    return &list->userBuffers;
130583827f40a2d97261528087331b0bee6ce2cf27c5root}
130683827f40a2d97261528087331b0bee6ce2cf27c5root
130783827f40a2d97261528087331b0bee6ce2cf27c5rootstruct _ValidateNode *
130883827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateListNode(void *iterator)
130983827f40a2d97261528087331b0bee6ce2cf27c5root{
131083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l = (struct _WsbmListHead *)iterator;
131183827f40a2d97261528087331b0bee6ce2cf27c5root
131283827f40a2d97261528087331b0bee6ce2cf27c5root    return WSBMLISTENTRY(l, struct _ValidateNode, head);
131383827f40a2d97261528087331b0bee6ce2cf27c5root}
131483827f40a2d97261528087331b0bee6ce2cf27c5root
131583827f40a2d97261528087331b0bee6ce2cf27c5rootvoid *
131683827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateListIterator(struct _ValidateList *list)
131783827f40a2d97261528087331b0bee6ce2cf27c5root{
131883827f40a2d97261528087331b0bee6ce2cf27c5root    void *ret = list->list.next;
131983827f40a2d97261528087331b0bee6ce2cf27c5root
132083827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret == &list->list)
132183827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
132283827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
132383827f40a2d97261528087331b0bee6ce2cf27c5root}
132483827f40a2d97261528087331b0bee6ce2cf27c5root
132583827f40a2d97261528087331b0bee6ce2cf27c5rootvoid *
132683827f40a2d97261528087331b0bee6ce2cf27c5rootvalidateListNext(struct _ValidateList *list, void *iterator)
132783827f40a2d97261528087331b0bee6ce2cf27c5root{
132883827f40a2d97261528087331b0bee6ce2cf27c5root    void *ret;
132983827f40a2d97261528087331b0bee6ce2cf27c5root
133083827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmListHead *l = (struct _WsbmListHead *)iterator;
133183827f40a2d97261528087331b0bee6ce2cf27c5root
133283827f40a2d97261528087331b0bee6ce2cf27c5root    ret = l->next;
133383827f40a2d97261528087331b0bee6ce2cf27c5root    if (ret == &list->list)
133483827f40a2d97261528087331b0bee6ce2cf27c5root	return NULL;
133583827f40a2d97261528087331b0bee6ce2cf27c5root    return ret;
133683827f40a2d97261528087331b0bee6ce2cf27c5root}
133783827f40a2d97261528087331b0bee6ce2cf27c5root
133883827f40a2d97261528087331b0bee6ce2cf27c5rootuint32_t
133983827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmKBufHandle(const struct _WsbmKernelBuf * kBuf)
134083827f40a2d97261528087331b0bee6ce2cf27c5root{
134183827f40a2d97261528087331b0bee6ce2cf27c5root    return kBuf->handle;
134283827f40a2d97261528087331b0bee6ce2cf27c5root}
134383827f40a2d97261528087331b0bee6ce2cf27c5root
134483827f40a2d97261528087331b0bee6ce2cf27c5rootextern void
134583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmUpdateKBuf(struct _WsbmKernelBuf *kBuf,
134683827f40a2d97261528087331b0bee6ce2cf27c5root	       uint64_t gpuOffset, uint32_t placement,
134783827f40a2d97261528087331b0bee6ce2cf27c5root	       uint32_t fence_type_mask)
134883827f40a2d97261528087331b0bee6ce2cf27c5root{
134983827f40a2d97261528087331b0bee6ce2cf27c5root    kBuf->gpuOffset = gpuOffset;
135083827f40a2d97261528087331b0bee6ce2cf27c5root    kBuf->placement = placement;
135183827f40a2d97261528087331b0bee6ce2cf27c5root    kBuf->fence_type_mask = fence_type_mask;
135283827f40a2d97261528087331b0bee6ce2cf27c5root}
135383827f40a2d97261528087331b0bee6ce2cf27c5root
135483827f40a2d97261528087331b0bee6ce2cf27c5rootextern struct _WsbmKernelBuf *
135583827f40a2d97261528087331b0bee6ce2cf27c5rootwsbmKBuf(const struct _WsbmBufferObject *buf)
135683827f40a2d97261528087331b0bee6ce2cf27c5root{
135783827f40a2d97261528087331b0bee6ce2cf27c5root    struct _WsbmBufStorage *storage = buf->storage;
135883827f40a2d97261528087331b0bee6ce2cf27c5root
135983827f40a2d97261528087331b0bee6ce2cf27c5root    return storage->pool->kernel(storage);
136083827f40a2d97261528087331b0bee6ce2cf27c5root}
1361