11b13d190SFrançois Tigeot /**
21b13d190SFrançois Tigeot * \file drm_dma.c
31b13d190SFrançois Tigeot * DMA IOCTL and function support
41b13d190SFrançois Tigeot *
51b13d190SFrançois Tigeot * \author Rickard E. (Rik) Faith <faith@valinux.com>
61b13d190SFrançois Tigeot * \author Gareth Hughes <gareth@valinux.com>
71b13d190SFrançois Tigeot */
81b13d190SFrançois Tigeot
91b13d190SFrançois Tigeot /*
101b13d190SFrançois Tigeot * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
111b13d190SFrançois Tigeot *
127f3c3d6fSHasso Tepper * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
137f3c3d6fSHasso Tepper * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
147f3c3d6fSHasso Tepper * All Rights Reserved.
157f3c3d6fSHasso Tepper *
167f3c3d6fSHasso Tepper * Permission is hereby granted, free of charge, to any person obtaining a
177f3c3d6fSHasso Tepper * copy of this software and associated documentation files (the "Software"),
187f3c3d6fSHasso Tepper * to deal in the Software without restriction, including without limitation
197f3c3d6fSHasso Tepper * the rights to use, copy, modify, merge, publish, distribute, sublicense,
207f3c3d6fSHasso Tepper * and/or sell copies of the Software, and to permit persons to whom the
217f3c3d6fSHasso Tepper * Software is furnished to do so, subject to the following conditions:
227f3c3d6fSHasso Tepper *
237f3c3d6fSHasso Tepper * The above copyright notice and this permission notice (including the next
247f3c3d6fSHasso Tepper * paragraph) shall be included in all copies or substantial portions of the
257f3c3d6fSHasso Tepper * Software.
267f3c3d6fSHasso Tepper *
277f3c3d6fSHasso Tepper * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
287f3c3d6fSHasso Tepper * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
297f3c3d6fSHasso Tepper * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
307f3c3d6fSHasso Tepper * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
317f3c3d6fSHasso Tepper * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
327f3c3d6fSHasso Tepper * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
337f3c3d6fSHasso Tepper * OTHER DEALINGS IN THE SOFTWARE.
347f3c3d6fSHasso Tepper */
357f3c3d6fSHasso Tepper
361b13d190SFrançois Tigeot #include <linux/export.h>
3718e26a6dSFrançois Tigeot #include <drm/drmP.h>
381b13d190SFrançois Tigeot #include "drm_legacy.h"
397f3c3d6fSHasso Tepper
401b13d190SFrançois Tigeot /**
411b13d190SFrançois Tigeot * Initialize the DMA data.
421b13d190SFrançois Tigeot *
431b13d190SFrançois Tigeot * \param dev DRM device.
441b13d190SFrançois Tigeot * \return zero on success or a negative value on failure.
451b13d190SFrançois Tigeot *
461b13d190SFrançois Tigeot * Allocate and initialize a drm_device_dma structure.
471b13d190SFrançois Tigeot */
drm_legacy_dma_setup(struct drm_device * dev)481b13d190SFrançois Tigeot int drm_legacy_dma_setup(struct drm_device *dev)
497f3c3d6fSHasso Tepper {
50394ce297SFrançois Tigeot int i;
517f3c3d6fSHasso Tepper
521b13d190SFrançois Tigeot if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
53*1dedbd3bSFrançois Tigeot !drm_core_check_feature(dev, DRIVER_LEGACY))
541b13d190SFrançois Tigeot return 0;
551b13d190SFrançois Tigeot
561b13d190SFrançois Tigeot dev->buf_use = 0;
571b13d190SFrançois Tigeot atomic_set(&dev->buf_alloc, 0);
581b13d190SFrançois Tigeot
591b13d190SFrançois Tigeot dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL);
601b13d190SFrançois Tigeot if (!dev->dma)
611b13d190SFrançois Tigeot return -ENOMEM;
627f3c3d6fSHasso Tepper
63394ce297SFrançois Tigeot for (i = 0; i <= DRM_MAX_ORDER; i++)
64394ce297SFrançois Tigeot memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
657f3c3d6fSHasso Tepper
667f3c3d6fSHasso Tepper return 0;
677f3c3d6fSHasso Tepper }
687f3c3d6fSHasso Tepper
691b13d190SFrançois Tigeot /**
701b13d190SFrançois Tigeot * Cleanup the DMA resources.
711b13d190SFrançois Tigeot *
721b13d190SFrançois Tigeot * \param dev DRM device.
731b13d190SFrançois Tigeot *
741b13d190SFrançois Tigeot * Free all pages associated with DMA buffers, the buffers and pages lists, and
751b13d190SFrançois Tigeot * finally the drm_device::dma structure itself.
761b13d190SFrançois Tigeot */
drm_legacy_dma_takedown(struct drm_device * dev)771b13d190SFrançois Tigeot void drm_legacy_dma_takedown(struct drm_device *dev)
787f3c3d6fSHasso Tepper {
794250aa95Szrj struct drm_device_dma *dma = dev->dma;
807f3c3d6fSHasso Tepper int i, j;
817f3c3d6fSHasso Tepper
82394ce297SFrançois Tigeot if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA) ||
83*1dedbd3bSFrançois Tigeot !drm_core_check_feature(dev, DRIVER_LEGACY))
84394ce297SFrançois Tigeot return;
85394ce297SFrançois Tigeot
86394ce297SFrançois Tigeot if (!dma)
877f3c3d6fSHasso Tepper return;
887f3c3d6fSHasso Tepper
897f3c3d6fSHasso Tepper /* Clear dma buffers */
907f3c3d6fSHasso Tepper for (i = 0; i <= DRM_MAX_ORDER; i++) {
917f3c3d6fSHasso Tepper if (dma->bufs[i].seg_count) {
927f3c3d6fSHasso Tepper DRM_DEBUG("order %d: buf_count = %d,"
93394ce297SFrançois Tigeot " seg_count = %d\n",
94394ce297SFrançois Tigeot i,
95394ce297SFrançois Tigeot dma->bufs[i].buf_count,
967f3c3d6fSHasso Tepper dma->bufs[i].seg_count);
977f3c3d6fSHasso Tepper for (j = 0; j < dma->bufs[i].seg_count; j++) {
98394ce297SFrançois Tigeot if (dma->bufs[i].seglist[j]) {
997f3c3d6fSHasso Tepper drm_pci_free(dev, dma->bufs[i].seglist[j]);
1007f3c3d6fSHasso Tepper }
101394ce297SFrançois Tigeot }
1024250aa95Szrj kfree(dma->bufs[i].seglist);
1037f3c3d6fSHasso Tepper }
1047f3c3d6fSHasso Tepper if (dma->bufs[i].buf_count) {
1057f3c3d6fSHasso Tepper for (j = 0; j < dma->bufs[i].buf_count; j++) {
1064250aa95Szrj kfree(dma->bufs[i].buflist[j].dev_private);
1077f3c3d6fSHasso Tepper }
1084250aa95Szrj kfree(dma->bufs[i].buflist);
1097f3c3d6fSHasso Tepper }
1107f3c3d6fSHasso Tepper }
1117f3c3d6fSHasso Tepper
1124250aa95Szrj kfree(dma->buflist);
1134250aa95Szrj kfree(dma->pagelist);
1144250aa95Szrj kfree(dev->dma);
1157f3c3d6fSHasso Tepper dev->dma = NULL;
1167f3c3d6fSHasso Tepper }
1177f3c3d6fSHasso Tepper
1184250aa95Szrj /**
1194250aa95Szrj * Free a buffer.
1204250aa95Szrj *
1214250aa95Szrj * \param dev DRM device.
1224250aa95Szrj * \param buf buffer to free.
1234250aa95Szrj *
1244250aa95Szrj * Resets the fields of \p buf.
1254250aa95Szrj */
drm_legacy_free_buffer(struct drm_device * dev,struct drm_buf * buf)1261b13d190SFrançois Tigeot void drm_legacy_free_buffer(struct drm_device *dev, struct drm_buf * buf)
1277f3c3d6fSHasso Tepper {
128b3705d71SHasso Tepper if (!buf)
129b3705d71SHasso Tepper return;
1307f3c3d6fSHasso Tepper
131394ce297SFrançois Tigeot buf->waiting = 0;
1327f3c3d6fSHasso Tepper buf->pending = 0;
1337f3c3d6fSHasso Tepper buf->file_priv = NULL;
1347f3c3d6fSHasso Tepper buf->used = 0;
1357f3c3d6fSHasso Tepper }
1367f3c3d6fSHasso Tepper
1374250aa95Szrj /**
1384250aa95Szrj * Reclaim the buffers.
1394250aa95Szrj *
1404250aa95Szrj * \param file_priv DRM file private.
1414250aa95Szrj *
1424250aa95Szrj * Frees each buffer associated with \p file_priv not already on the hardware.
1434250aa95Szrj */
drm_legacy_reclaim_buffers(struct drm_device * dev,struct drm_file * file_priv)1441b13d190SFrançois Tigeot void drm_legacy_reclaim_buffers(struct drm_device *dev,
1451b13d190SFrançois Tigeot struct drm_file *file_priv)
1467f3c3d6fSHasso Tepper {
1474250aa95Szrj struct drm_device_dma *dma = dev->dma;
1487f3c3d6fSHasso Tepper int i;
1497f3c3d6fSHasso Tepper
150b3705d71SHasso Tepper if (!dma)
151b3705d71SHasso Tepper return;
1527f3c3d6fSHasso Tepper for (i = 0; i < dma->buf_count; i++) {
1537f3c3d6fSHasso Tepper if (dma->buflist[i]->file_priv == file_priv) {
1547f3c3d6fSHasso Tepper switch (dma->buflist[i]->list) {
1557f3c3d6fSHasso Tepper case DRM_LIST_NONE:
1561b13d190SFrançois Tigeot drm_legacy_free_buffer(dev, dma->buflist[i]);
1577f3c3d6fSHasso Tepper break;
1587f3c3d6fSHasso Tepper case DRM_LIST_WAIT:
1597f3c3d6fSHasso Tepper dma->buflist[i]->list = DRM_LIST_RECLAIM;
1607f3c3d6fSHasso Tepper break;
1617f3c3d6fSHasso Tepper default:
1627f3c3d6fSHasso Tepper /* Buffer already on hardware. */
1637f3c3d6fSHasso Tepper break;
1647f3c3d6fSHasso Tepper }
1657f3c3d6fSHasso Tepper }
1667f3c3d6fSHasso Tepper }
1677f3c3d6fSHasso Tepper }
168