summaryrefslogtreecommitdiff
path: root/bsd-core/drm_dma.c
AgeCommit message (Expand)Author
2005-08-05Rename the driver hooks in the DRM to something a little moreEric Anholt
2005-04-26Convert BSD code to mostly use bus_dma, the dma abstraction for dealingEric Anholt
2005-04-16Use /*- to begin license blocks in BSD code to reduce diffs against FreeBSDEric Anholt
2004-11-07Now that the memory debug code is gone, and all 3 BSDs have M_ZERO, stopEric Anholt
2004-11-06Get r128 basically working: Hook up the driver's dma ioctl, use the properEric Anholt
2004-11-06Commit WIP of BSD conversion to core model. Compiles for r128, radeon, butEric Anholt
2004-01-06Fix some misuse of NULL where 0 is intended.Eric Anholt
2003-10-19- SMPng lock the DRM. This is only partial -- there are a few code pathsEric Anholt
2003-10-19Clean up extra zeroing of dev->dma, and use calloc to take advantage ofEric Anholt
2003-10-17- Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle themEric Anholt
2003-10-03Stylistic preparation for SMPng locking work: DRM_LOCK/DRM_UNLOCK have sideEric Anholt
2003-10-02Mostly whitespace cleanups and style(9) fixes focused on "if(" -> "if ("Eric Anholt
2003-08-19- Remove $FreeBSD$ tags as they weren't too useful and merges are now beingEric Anholt
2003-07-29IRQ code cleanup suggested by Linus TorvaldsMichel Daenzer
2003-07-25Compile fixes for recent 2.5/2.6 Linux kernels. I hope this doesn't breakMichel Daenzer
2003-04-26MFL: Don't install irq handler unless the driver has been initialized.Eric Anholt
2003-04-26Add PCI DMA memory functions and make addbufs_pci and associated code useEric Anholt
2003-04-25Merge from FreeBSD-current.Eric Anholt
2003-04-24Remove more gamma DMA infrastructure. Most of this code was copied straightEric Anholt
2003-04-24Remove more gamma DMA code. This isn't all of it, but it's a major portion.Eric Anholt
2003-04-24Remove DRM_DMA_HISTOGRAM and associated code.Eric Anholt
2003-03-29Add DRMFILE definitions and supply filp for BSD in theEric Anholt
2003-03-11Merge back from FreeBSD-current, adding FreeBSD ID tags to aid futureEric Anholt
2003-03-06Remove the vbl signal code because it's untested (and has lock issues onEric Anholt
2003-03-04DRM_FREE/2 patch from Philip BrownKeith Whitwell
2003-02-21Merge from bsd-4-0-0-branch.Eric Anholt
2003-02-02don't inflate relative vblank sequence numbers on repeated calls (e.g. whenMichel Daenzer
2002-12-06Add vblank signal code for BSD DRM. Untested so far, but working with aEric Anholt
2002-10-29Use bus_alloc_resource/bus_release_resource more properly: save the ridEric Anholt
2002-09-29Move os-dependent stuff out of radeon_irq.cKeith Whitwell
2002-09-29Fix up BSD irq handling.Eric Anholt
2002-09-26BSD vblank framework.Eric Anholt
2002-07-05merged bsd-3-0-0-branchAlan Hourihane
2002-03-11fixups for *BSDAlan Hourihane
2002-03-06first pass at merging mesa 4.0 kernel drivers into new bsd-3-0-0 branch.Alan Hourihane
2002-01-27Initial revisionDavid Dawes
='#n295'>295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
 * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
 *
 * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
 * All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * 
 * Authors:
 *    Sung-Ching Lin <sclin@sis.com.tw>
 * 
 */

#include "sis.h"
#include "drmP.h"
#include "drm.h"
#include "sis_ds.h"

/* Set Data Structure, not check repeated value
 * temporarily used
 */

set_t *setInit(void)
{
	int i;
	set_t *set;

	set = (set_t *)DRM(alloc)(sizeof(set_t), DRM_MEM_DRIVER);
	if (set != NULL) {
		for (i = 0; i < SET_SIZE; i++) {
			set->list[i].free_next = i + 1;    
			set->list[i].alloc_next = -1;
		}
		set->list[SET_SIZE-1].free_next = -1;
		set->free = 0;
		set->alloc = -1;
		set->trace = -1;
	}
	return set;
}

int setAdd(set_t *set, ITEM_TYPE item)
{
	int free = set->free;
  
	if (free != -1) {
		set->list[free].val = item;
		set->free = set->list[free].free_next;
	} else {
		return 0;
	}

	set->list[free].alloc_next = set->alloc;
	set->alloc = free;  
	set->list[free].free_next = -1;    

	return 1;
}

int setDel(set_t *set, ITEM_TYPE item)
{
	int alloc = set->alloc;
	int prev = -1;  

	while (alloc != -1) {
		if (set->list[alloc].val == item) {
			if (prev != -1)
				set->list[prev].alloc_next =
				    set->list[alloc].alloc_next;
			else
				set->alloc = set->list[alloc].alloc_next;
			break;
		}
		prev = alloc;
		alloc = set->list[alloc].alloc_next;
	}

	if (alloc == -1)
		return 0;

	set->list[alloc].free_next = set->free;
	set->free = alloc;
	set->list[alloc].alloc_next = -1;

	return 1;
}

/* setFirst -> setAdd -> setNext is wrong */

int setFirst(set_t *set, ITEM_TYPE *item)
{
	if (set->alloc == -1)
		return 0;

	*item = set->list[set->alloc].val;
	set->trace = set->list[set->alloc].alloc_next;

	return 1;
}

int setNext(set_t *set, ITEM_TYPE *item)
{
	if (set->trace == -1)
		return 0;

	*item = set->list[set->trace].val;
	set->trace = set->list[set->trace].alloc_next;

	return 1;
}

int setDestroy(set_t *set)
{
	DRM(free)(set, sizeof(set_t), DRM_MEM_DRIVER);

	return 1;
}

/*
 * GLX Hardware Device Driver common code
 * Copyright (C) 1999 Keith Whitwell
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#define ISFREE(bptr) ((bptr)->free)

memHeap_t *mmInit(int ofs,
		  int size)
{
	PMemBlock blocks;

	if (size <= 0)
		return 0;

	blocks = (TMemBlock *)DRM(calloc)(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
	if (blocks != NULL) {
		blocks->ofs = ofs;
		blocks->size = size;
		blocks->free = 1;
		return (memHeap_t *)blocks;
	} else
		return 0;
}

/* Checks if a pointer 'b' is part of the heap 'heap' */
int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
{
	TMemBlock *p;

	if (heap == NULL || b == NULL)
		return 0;

	p = heap;
	while (p != NULL && p != b) {
		p = p->next;
	}
	if (p == b)
		return 1;
	else
		return 0;
}

/* Kludgey workaround for existing i810 server.  Remove soon.
 */
memHeap_t *mmAddRange( memHeap_t *heap,
		       int ofs,
		       int size )
{
	PMemBlock blocks;
	blocks = (TMemBlock *)DRM(calloc)(2, sizeof(TMemBlock), DRM_MEM_DRIVER);
	if (blocks != NULL) {
		blocks[0].size = size;
		blocks[0].free = 1;
		blocks[0].ofs = ofs;
		blocks[0].next = &blocks[1];

		/* Discontinuity - stops JoinBlock from trying to join
		 * non-adjacent ranges.
		 */
		blocks[1].size = 0;
		blocks[1].free = 0;
		blocks[1].ofs = ofs+size;
		blocks[1].next = (PMemBlock)heap;
		return (memHeap_t *)blocks;
	} else
		return heap;
}

static TMemBlock* SliceBlock(TMemBlock *p, 
			     int startofs, int size, 
			     int reserved, int alignment)
{
	TMemBlock *newblock;

	/* break left */
	if (startofs > p->ofs) {
		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
		    DRM_MEM_DRIVER);
		newblock->ofs = startofs;
		newblock->size = p->size - (startofs - p->ofs);
		newblock->free = 1;
		newblock->next = p->next;
		p->size -= newblock->size;
		p->next = newblock;
		p = newblock;
	}

	/* break right */
	if (size < p->size) {
		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
		    DRM_MEM_DRIVER);
		newblock->ofs = startofs + size;
		newblock->size = p->size - size;
		newblock->free = 1;
		newblock->next = p->next;
		p->size = size;
		p->next = newblock;
	}

	/* p = middle block */
	p->align = alignment;
	p->free = 0;
	p->reserved = reserved;
	return p;
}

PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
{
	int mask,startofs, endofs;
	TMemBlock *p;
	
	if (heap == NULL || align2 < 0 || size <= 0)
		return NULL;

	mask = (1 << align2)-1;
	startofs = 0;
	p = (TMemBlock *)heap;
	while (p != NULL) {
		if (ISFREE(p)) {
			startofs = (p->ofs + mask) & ~mask;
			if ( startofs < startSearch ) {
				startofs = startSearch;
			}
			endofs = startofs+size;
			if (endofs <= (p->ofs+p->size))
				break;
		}
		p = p->next;
	}
	if (p == NULL)
		return NULL;
	p = SliceBlock(p,startofs,size,0,mask+1);
	p->heap = heap;
	return p;
}

static __inline__ int Join2Blocks(TMemBlock *p)
{
	if (p->free && p->next && p->next->free) {
		TMemBlock *q = p->next;
		p->size += q->size;
		p->next = q->next;
		DRM(free)(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
		return 1;
	}
	return 0;
}

int mmFreeMem(PMemBlock b)
{
	TMemBlock *p, *prev;

	if (b == NULL)
		return 0;
	if (b->heap == NULL)
		return -1;

	p = b->heap;
	prev = NULL;
	while (p != NULL && p != b) {
		prev = p;
		p = p->next;
	}
	if (p == NULL || p->free || p->reserved)
		return -1;

	p->free = 1;
	Join2Blocks(p);
	if (prev)
	Join2Blocks(prev);
	return 0;
}

int mmReserveMem(memHeap_t *heap, int offset,int size)
{
	int endofs;
	TMemBlock *p;

	if (heap == NULL || size <= 0)
		return -1;

	endofs = offset + size;
	p = (TMemBlock *)heap;
	while (p && p->ofs <= offset) {
		if (ISFREE(p) && endofs <= (p->ofs+p->size)) {
			SliceBlock(p,offset,size,1,1);
			return 0;
		}
		p = p->next;
	}
	return -1;
}

int mmFreeReserved(memHeap_t *heap, int offset)
{
	TMemBlock *p,*prev;

	if (heap == NULL)
		return -1;

	p = (TMemBlock *)heap;
	prev = NULL;
	while (p != NULL && p->ofs != offset) {
		prev = p;
		p = p->next;
	}
	if (p == NULL || !p->reserved)
		return -1;

	p->free = 1;
	p->reserved = 0;
	Join2Blocks(p);
	if (prev != NULL)
		Join2Blocks(prev);
	return 0;
}

void mmDestroy(memHeap_t *heap)
{
	TMemBlock *p,*q;

	if (heap == NULL)
		return;

	p = (TMemBlock *)heap;
	while (p != NULL) {
		q = p->next;
		DRM(free)(p, sizeof(TMemBlock), DRM_MEM_DRIVER);
		p = q;
	}
}