drm_dma.c revision 152909
15191Swollman/* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*- 25191Swollman * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com 35191Swollman */ 45191Swollman/*- 55191Swollman * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 65191Swollman * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 75191Swollman * All Rights Reserved. 85191Swollman * 95191Swollman * Permission is hereby granted, free of charge, to any person obtaining a 105191Swollman * copy of this software and associated documentation files (the "Software"), 115191Swollman * to deal in the Software without restriction, including without limitation 125191Swollman * the rights to use, copy, modify, merge, publish, distribute, sublicense, 135191Swollman * and/or sell copies of the Software, and to permit persons to whom the 145191Swollman * Software is furnished to do so, subject to the following conditions: 155191Swollman * 165191Swollman * The above copyright notice and this permission notice (including the next 175191Swollman * paragraph) shall be included in all copies or substantial portions of the 185191Swollman * Software. 195191Swollman * 205191Swollman * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 215191Swollman * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 225191Swollman * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 235191Swollman * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 245191Swollman * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 255191Swollman * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 265191Swollman * OTHER DEALINGS IN THE SOFTWARE. 275191Swollman * 285191Swollman * Authors: 295191Swollman * Rickard E. (Rik) Faith <faith@valinux.com> 305191Swollman * Gareth Hughes <gareth@valinux.com> 315191Swollman * 325191Swollman */ 335191Swollman 3450477Speter#include <sys/cdefs.h> 355191Swollman__FBSDID("$FreeBSD: head/sys/dev/drm/drm_dma.c 152909 2005-11-28 23:13:57Z anholt $"); 365191Swollman 375191Swollman#include "dev/drm/drmP.h" 385191Swollman 395191Swollmanint drm_dma_setup(drm_device_t *dev) 405191Swollman{ 415191Swollman 425191Swollman dev->dma = malloc(sizeof(*dev->dma), M_DRM, M_NOWAIT | M_ZERO); 435191Swollman if (dev->dma == NULL) 445191Swollman return DRM_ERR(ENOMEM); 455191Swollman 465191Swollman DRM_SPININIT(dev->dma_lock, "drmdma"); 4724204Sbde 485191Swollman return 0; 495191Swollman} 505191Swollman 515191Swollmanvoid drm_dma_takedown(drm_device_t *dev) 525191Swollman{ 535191Swollman drm_device_dma_t *dma = dev->dma; 5432350Seivind int i, j; 5554263Sshin 565191Swollman if (dma == NULL) 575191Swollman return; 585191Swollman 595191Swollman /* Clear dma buffers */ 605191Swollman for (i = 0; i <= DRM_MAX_ORDER; i++) { 615191Swollman if (dma->bufs[i].seg_count) { 625191Swollman DRM_DEBUG("order %d: buf_count = %d," 6312569Sbde " seg_count = %d\n", 6410429Sbde i, 6510429Sbde dma->bufs[i].buf_count, 6641757Seivind dma->bufs[i].seg_count); 6741757Seivind for (j = 0; j < dma->bufs[i].seg_count; j++) { 685191Swollman drm_pci_free(dev, dma->bufs[i].seglist[j]); 6941757Seivind } 7041757Seivind free(dma->bufs[i].seglist, M_DRM); 715191Swollman } 725191Swollman 735191Swollman if (dma->bufs[i].buf_count) { 7412569Sbde for (j = 0; j < dma->bufs[i].buf_count; j++) { 7512569Sbde free(dma->bufs[i].buflist[j].dev_private, 765191Swollman M_DRM); 7741757Seivind } 785191Swollman free(dma->bufs[i].buflist, M_DRM); 795191Swollman } 805191Swollman } 815191Swollman 8241757Seivind free(dma->buflist, M_DRM); 8341757Seivind free(dma->pagelist, M_DRM); 845191Swollman free(dev->dma, M_DRM); 855191Swollman dev->dma = NULL; 865191Swollman DRM_SPINUNINIT(dev->dma_lock); 8753115Sphk} 885191Swollman 8913937Swollman 905191Swollmanvoid drm_free_buffer(drm_device_t *dev, drm_buf_t *buf) 915191Swollman{ 925191Swollman if (!buf) return; 9341757Seivind 945191Swollman buf->pending = 0; 955191Swollman buf->filp = NULL; 965191Swollman buf->used = 0; 975191Swollman} 985191Swollman 995191Swollmanvoid drm_reclaim_buffers(drm_device_t *dev, DRMFILE filp) 10041757Seivind{ 10110957Swollman drm_device_dma_t *dma = dev->dma; 10210957Swollman int i; 10310957Swollman 10410957Swollman if (!dma) return; 10510957Swollman for (i = 0; i < dma->buf_count; i++) { 10610957Swollman if (dma->buflist[i]->filp == filp) { 10710957Swollman switch (dma->buflist[i]->list) { 10810957Swollman case DRM_LIST_NONE: 10941757Seivind drm_free_buffer(dev, dma->buflist[i]); 1105191Swollman break; 1115191Swollman case DRM_LIST_WAIT: 1125191Swollman dma->buflist[i]->list = DRM_LIST_RECLAIM; 1135191Swollman break; 1145191Swollman default: 1155191Swollman /* Buffer already on hardware. */ 1165191Swollman break; 1175191Swollman } 1185191Swollman } 1195191Swollman } 1205191Swollman} 1215191Swollman 1225191Swollman/* Call into the driver-specific DMA handler */ 1238876Srgrimesint drm_dma(DRM_IOCTL_ARGS) 12441757Seivind{ 1255191Swollman DRM_DEVICE; 1265191Swollman 1275191Swollman if (dev->driver.dma_ioctl) { 1285191Swollman return dev->driver.dma_ioctl(kdev, cmd, data, flags, p, filp); 1295191Swollman } else { 1305191Swollman DRM_DEBUG("DMA ioctl on driver with no dma handler\n"); 1315191Swollman return EINVAL; 1325191Swollman } 1335191Swollman} 1345191Swollman