1235783Skib/*- 2235783Skib * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 3235783Skib * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4235783Skib * All Rights Reserved. 5235783Skib * 6235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 7235783Skib * copy of this software and associated documentation files (the "Software"), 8235783Skib * to deal in the Software without restriction, including without limitation 9235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10235783Skib * and/or sell copies of the Software, and to permit persons to whom the 11235783Skib * Software is furnished to do so, subject to the following conditions: 12235783Skib * 13235783Skib * The above copyright notice and this permission notice (including the next 14235783Skib * paragraph) shall be included in all copies or substantial portions of the 15235783Skib * Software. 16235783Skib * 17235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20235783Skib * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21235783Skib * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22235783Skib * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23235783Skib * OTHER DEALINGS IN THE SOFTWARE. 24235783Skib * 25235783Skib * Authors: 26235783Skib * Rickard E. (Rik) Faith <faith@valinux.com> 27235783Skib * Gareth Hughes <gareth@valinux.com> 28235783Skib * 29235783Skib */ 30235783Skib 31235783Skib#include <sys/cdefs.h> 32235783Skib__FBSDID("$FreeBSD$"); 33235783Skib 34235783Skib/** @file drm_dma.c 35235783Skib * Support code for DMA buffer management. 36235783Skib * 37235783Skib * The implementation used to be significantly more complicated, but the 38235783Skib * complexity has been moved into the drivers as different buffer management 39235783Skib * schemes evolved. 40235783Skib */ 41235783Skib 42235783Skib#include <dev/drm2/drmP.h> 43235783Skib 44235783Skibint drm_dma_setup(struct drm_device *dev) 45235783Skib{ 46235783Skib 47235783Skib dev->dma = malloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 48235783Skib if (dev->dma == NULL) 49235783Skib return ENOMEM; 50235783Skib 51235783Skib DRM_SPININIT(&dev->dma_lock, "drmdma"); 52235783Skib 53235783Skib return 0; 54235783Skib} 55235783Skib 56235783Skibvoid drm_dma_takedown(struct drm_device *dev) 57235783Skib{ 58235783Skib drm_device_dma_t *dma = dev->dma; 59235783Skib int i, j; 60235783Skib 61235783Skib if (dma == NULL) 62235783Skib return; 63235783Skib 64235783Skib /* Clear dma buffers */ 65235783Skib for (i = 0; i <= DRM_MAX_ORDER; i++) { 66235783Skib if (dma->bufs[i].seg_count) { 67235783Skib DRM_DEBUG("order %d: buf_count = %d," 68235783Skib " seg_count = %d\n", i, dma->bufs[i].buf_count, 69235783Skib dma->bufs[i].seg_count); 70235783Skib for (j = 0; j < dma->bufs[i].seg_count; j++) { 71235783Skib drm_pci_free(dev, dma->bufs[i].seglist[j]); 72235783Skib } 73235783Skib free(dma->bufs[i].seglist, DRM_MEM_SEGS); 74235783Skib } 75235783Skib 76235783Skib if (dma->bufs[i].buf_count) { 77235783Skib for (j = 0; j < dma->bufs[i].buf_count; j++) { 78235783Skib free(dma->bufs[i].buflist[j].dev_private, 79235783Skib DRM_MEM_BUFS); 80235783Skib } 81235783Skib free(dma->bufs[i].buflist, DRM_MEM_BUFS); 82235783Skib } 83235783Skib } 84235783Skib 85235783Skib free(dma->buflist, DRM_MEM_BUFS); 86235783Skib free(dma->pagelist, DRM_MEM_PAGES); 87235783Skib free(dev->dma, DRM_MEM_DRIVER); 88235783Skib dev->dma = NULL; 89235783Skib DRM_SPINUNINIT(&dev->dma_lock); 90235783Skib} 91235783Skib 92235783Skib 93235783Skibvoid drm_free_buffer(struct drm_device *dev, drm_buf_t *buf) 94235783Skib{ 95235783Skib if (!buf) 96235783Skib return; 97235783Skib 98235783Skib buf->pending = 0; 99235783Skib buf->file_priv= NULL; 100235783Skib buf->used = 0; 101235783Skib} 102235783Skib 103235783Skibvoid drm_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) 104235783Skib{ 105235783Skib drm_device_dma_t *dma = dev->dma; 106235783Skib int i; 107235783Skib 108235783Skib if (!dma) 109235783Skib return; 110235783Skib 111235783Skib for (i = 0; i < dma->buf_count; i++) { 112235783Skib if (dma->buflist[i]->file_priv == file_priv) { 113235783Skib switch (dma->buflist[i]->list) { 114235783Skib case DRM_LIST_NONE: 115235783Skib drm_free_buffer(dev, dma->buflist[i]); 116235783Skib break; 117235783Skib case DRM_LIST_WAIT: 118235783Skib dma->buflist[i]->list = DRM_LIST_RECLAIM; 119235783Skib break; 120235783Skib default: 121235783Skib /* Buffer already on hardware. */ 122235783Skib break; 123235783Skib } 124235783Skib } 125235783Skib } 126235783Skib} 127235783Skib 128235783Skib/* Call into the driver-specific DMA handler */ 129235783Skibint drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv) 130235783Skib{ 131235783Skib 132235783Skib if (dev->driver->dma_ioctl) { 133235783Skib /* shared code returns -errno */ 134235783Skib return -dev->driver->dma_ioctl(dev, data, file_priv); 135235783Skib } else { 136235783Skib DRM_DEBUG("DMA ioctl on driver with no dma handler\n"); 137235783Skib return EINVAL; 138235783Skib } 139235783Skib} 140