1282199Sdumbbell/** 2282199Sdumbbell * \file drm_dma.c 3282199Sdumbbell * DMA IOCTL and function support 4282199Sdumbbell * 5282199Sdumbbell * \author Rickard E. (Rik) Faith <faith@valinux.com> 6282199Sdumbbell * \author Gareth Hughes <gareth@valinux.com> 7282199Sdumbbell */ 8282199Sdumbbell 9235783Skib/*- 10282199Sdumbbell * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com 11282199Sdumbbell * 12235783Skib * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 13235783Skib * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 14235783Skib * All Rights Reserved. 15235783Skib * 16235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 17235783Skib * copy of this software and associated documentation files (the "Software"), 18235783Skib * to deal in the Software without restriction, including without limitation 19235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense, 20235783Skib * and/or sell copies of the Software, and to permit persons to whom the 21235783Skib * Software is furnished to do so, subject to the following conditions: 22235783Skib * 23235783Skib * The above copyright notice and this permission notice (including the next 24235783Skib * paragraph) shall be included in all copies or substantial portions of the 25235783Skib * Software. 26235783Skib * 27235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 30235783Skib * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 31235783Skib * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 32235783Skib * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 33235783Skib * OTHER DEALINGS IN THE SOFTWARE. 34235783Skib */ 35235783Skib 36235783Skib#include <sys/cdefs.h> 37235783Skib__FBSDID("$FreeBSD$"); 38235783Skib 39282199Sdumbbell#include <dev/drm2/drmP.h> 40282199Sdumbbell 41282199Sdumbbell/** 42282199Sdumbbell * Initialize the DMA data. 43235783Skib * 44282199Sdumbbell * \param dev DRM device. 45282199Sdumbbell * \return zero on success or a negative value on failure. 46282199Sdumbbell * 47282199Sdumbbell * Allocate and initialize a drm_device_dma structure. 48235783Skib */ 49235783Skibint drm_dma_setup(struct drm_device *dev) 50235783Skib{ 51282199Sdumbbell int i; 52235783Skib 53235783Skib dev->dma = malloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 54282199Sdumbbell if (!dev->dma) 55282199Sdumbbell return -ENOMEM; 56235783Skib 57282199Sdumbbell for (i = 0; i <= DRM_MAX_ORDER; i++) 58282199Sdumbbell memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); 59235783Skib 60235783Skib return 0; 61235783Skib} 62235783Skib 63282199Sdumbbell/** 64282199Sdumbbell * Cleanup the DMA resources. 65282199Sdumbbell * 66282199Sdumbbell * \param dev DRM device. 67282199Sdumbbell * 68282199Sdumbbell * Free all pages associated with DMA buffers, the buffers and pages lists, and 69282199Sdumbbell * finally the drm_device::dma structure itself. 70282199Sdumbbell */ 71235783Skibvoid drm_dma_takedown(struct drm_device *dev) 72235783Skib{ 73282199Sdumbbell struct drm_device_dma *dma = dev->dma; 74282199Sdumbbell int i, j; 75235783Skib 76282199Sdumbbell if (!dma) 77235783Skib return; 78235783Skib 79235783Skib /* Clear dma buffers */ 80235783Skib for (i = 0; i <= DRM_MAX_ORDER; i++) { 81235783Skib if (dma->bufs[i].seg_count) { 82235783Skib DRM_DEBUG("order %d: buf_count = %d," 83282199Sdumbbell " seg_count = %d\n", 84282199Sdumbbell i, 85282199Sdumbbell dma->bufs[i].buf_count, 86282199Sdumbbell dma->bufs[i].seg_count); 87235783Skib for (j = 0; j < dma->bufs[i].seg_count; j++) { 88282199Sdumbbell if (dma->bufs[i].seglist[j]) { 89282199Sdumbbell drm_pci_free(dev, dma->bufs[i].seglist[j]); 90282199Sdumbbell } 91235783Skib } 92235783Skib free(dma->bufs[i].seglist, DRM_MEM_SEGS); 93235783Skib } 94282199Sdumbbell if (dma->bufs[i].buf_count) { 95282199Sdumbbell for (j = 0; j < dma->bufs[i].buf_count; j++) { 96235783Skib free(dma->bufs[i].buflist[j].dev_private, 97235783Skib DRM_MEM_BUFS); 98235783Skib } 99282199Sdumbbell free(dma->bufs[i].buflist, DRM_MEM_BUFS); 100235783Skib } 101235783Skib } 102235783Skib 103235783Skib free(dma->buflist, DRM_MEM_BUFS); 104235783Skib free(dma->pagelist, DRM_MEM_PAGES); 105235783Skib free(dev->dma, DRM_MEM_DRIVER); 106235783Skib dev->dma = NULL; 107235783Skib} 108235783Skib 109282199Sdumbbell/** 110282199Sdumbbell * Free a buffer. 111282199Sdumbbell * 112282199Sdumbbell * \param dev DRM device. 113282199Sdumbbell * \param buf buffer to free. 114282199Sdumbbell * 115282199Sdumbbell * Resets the fields of \p buf. 116282199Sdumbbell */ 117282199Sdumbbellvoid drm_free_buffer(struct drm_device *dev, struct drm_buf * buf) 118235783Skib{ 119235783Skib if (!buf) 120235783Skib return; 121235783Skib 122282199Sdumbbell buf->waiting = 0; 123282199Sdumbbell buf->pending = 0; 124282199Sdumbbell buf->file_priv = NULL; 125282199Sdumbbell buf->used = 0; 126235783Skib} 127235783Skib 128282199Sdumbbell/** 129282199Sdumbbell * Reclaim the buffers. 130282199Sdumbbell * 131282199Sdumbbell * \param file_priv DRM file private. 132282199Sdumbbell * 133282199Sdumbbell * Frees each buffer associated with \p file_priv not already on the hardware. 134282199Sdumbbell */ 135282199Sdumbbellvoid drm_core_reclaim_buffers(struct drm_device *dev, 136282199Sdumbbell struct drm_file *file_priv) 137235783Skib{ 138282199Sdumbbell struct drm_device_dma *dma = dev->dma; 139282199Sdumbbell int i; 140235783Skib 141235783Skib if (!dma) 142235783Skib return; 143235783Skib for (i = 0; i < dma->buf_count; i++) { 144235783Skib if (dma->buflist[i]->file_priv == file_priv) { 145235783Skib switch (dma->buflist[i]->list) { 146235783Skib case DRM_LIST_NONE: 147235783Skib drm_free_buffer(dev, dma->buflist[i]); 148235783Skib break; 149235783Skib case DRM_LIST_WAIT: 150235783Skib dma->buflist[i]->list = DRM_LIST_RECLAIM; 151235783Skib break; 152235783Skib default: 153235783Skib /* Buffer already on hardware. */ 154235783Skib break; 155235783Skib } 156235783Skib } 157235783Skib } 158235783Skib} 159235783Skib 160282199SdumbbellEXPORT_SYMBOL(drm_core_reclaim_buffers); 161