cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

drm_dma.c (4580B)


      1/*
      2 * \file drm_dma.c
      3 * DMA IOCTL and function support
      4 *
      5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
      6 * \author Gareth Hughes <gareth@valinux.com>
      7 */
      8
      9/*
     10 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
     11 *
     12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
     13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
     14 * All Rights Reserved.
     15 *
     16 * Permission is hereby granted, free of charge, to any person obtaining a
     17 * copy of this software and associated documentation files (the "Software"),
     18 * to deal in the Software without restriction, including without limitation
     19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     20 * and/or sell copies of the Software, and to permit persons to whom the
     21 * Software is furnished to do so, subject to the following conditions:
     22 *
     23 * The above copyright notice and this permission notice (including the next
     24 * paragraph) shall be included in all copies or substantial portions of the
     25 * Software.
     26 *
     27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     33 * OTHER DEALINGS IN THE SOFTWARE.
     34 */
     35
     36#include <linux/export.h>
     37#include <linux/pci.h>
     38
     39#include <drm/drm_drv.h>
     40#include <drm/drm_print.h>
     41
     42#include "drm_legacy.h"
     43
     44/**
     45 * drm_legacy_dma_setup() - Initialize the DMA data.
     46 *
     47 * @dev: DRM device.
     48 * Return: zero on success or a negative value on failure.
     49 *
     50 * Allocate and initialize a drm_device_dma structure.
     51 */
     52int drm_legacy_dma_setup(struct drm_device *dev)
     53{
     54	int i;
     55
     56	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
     57	    !drm_core_check_feature(dev, DRIVER_LEGACY))
     58		return 0;
     59
     60	dev->buf_use = 0;
     61	atomic_set(&dev->buf_alloc, 0);
     62
     63	dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL);
     64	if (!dev->dma)
     65		return -ENOMEM;
     66
     67	for (i = 0; i <= DRM_MAX_ORDER; i++)
     68		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
     69
     70	return 0;
     71}
     72
     73/**
     74 * drm_legacy_dma_takedown() - Cleanup the DMA resources.
     75 *
     76 * @dev: DRM device.
     77 *
     78 * Free all pages associated with DMA buffers, the buffers and pages lists, and
     79 * finally the drm_device::dma structure itself.
     80 */
     81void drm_legacy_dma_takedown(struct drm_device *dev)
     82{
     83	struct drm_device_dma *dma = dev->dma;
     84	drm_dma_handle_t *dmah;
     85	int i, j;
     86
     87	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
     88	    !drm_core_check_feature(dev, DRIVER_LEGACY))
     89		return;
     90
     91	if (!dma)
     92		return;
     93
     94	/* Clear dma buffers */
     95	for (i = 0; i <= DRM_MAX_ORDER; i++) {
     96		if (dma->bufs[i].seg_count) {
     97			DRM_DEBUG("order %d: buf_count = %d,"
     98				  " seg_count = %d\n",
     99				  i,
    100				  dma->bufs[i].buf_count,
    101				  dma->bufs[i].seg_count);
    102			for (j = 0; j < dma->bufs[i].seg_count; j++) {
    103				if (dma->bufs[i].seglist[j]) {
    104					dmah = dma->bufs[i].seglist[j];
    105					dma_free_coherent(dev->dev,
    106							  dmah->size,
    107							  dmah->vaddr,
    108							  dmah->busaddr);
    109					kfree(dmah);
    110				}
    111			}
    112			kfree(dma->bufs[i].seglist);
    113		}
    114		if (dma->bufs[i].buf_count) {
    115			for (j = 0; j < dma->bufs[i].buf_count; j++) {
    116				kfree(dma->bufs[i].buflist[j].dev_private);
    117			}
    118			kfree(dma->bufs[i].buflist);
    119		}
    120	}
    121
    122	kfree(dma->buflist);
    123	kfree(dma->pagelist);
    124	kfree(dev->dma);
    125	dev->dma = NULL;
    126}
    127
    128/**
    129 * drm_legacy_free_buffer() - Free a buffer.
    130 *
    131 * @dev: DRM device.
    132 * @buf: buffer to free.
    133 *
    134 * Resets the fields of \p buf.
    135 */
    136void drm_legacy_free_buffer(struct drm_device *dev, struct drm_buf * buf)
    137{
    138	if (!buf)
    139		return;
    140
    141	buf->waiting = 0;
    142	buf->pending = 0;
    143	buf->file_priv = NULL;
    144	buf->used = 0;
    145}
    146
    147/**
    148 * drm_legacy_reclaim_buffers() - Reclaim the buffers.
    149 *
    150 * @dev: DRM device.
    151 * @file_priv: DRM file private.
    152 *
    153 * Frees each buffer associated with \p file_priv not already on the hardware.
    154 */
    155void drm_legacy_reclaim_buffers(struct drm_device *dev,
    156				struct drm_file *file_priv)
    157{
    158	struct drm_device_dma *dma = dev->dma;
    159	int i;
    160
    161	if (!dma)
    162		return;
    163	for (i = 0; i < dma->buf_count; i++) {
    164		if (dma->buflist[i]->file_priv == file_priv) {
    165			switch (dma->buflist[i]->list) {
    166			case DRM_LIST_NONE:
    167				drm_legacy_free_buffer(dev, dma->buflist[i]);
    168				break;
    169			case DRM_LIST_WAIT:
    170				dma->buflist[i]->list = DRM_LIST_RECLAIM;
    171				break;
    172			default:
    173				/* Buffer already on hardware. */
    174				break;
    175			}
    176		}
    177	}
    178}