aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/drm2/drm_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/drm2/drm_dma.c')
-rw-r--r--sys/dev/drm2/drm_dma.c117
1 files changed, 69 insertions, 48 deletions
diff --git a/sys/dev/drm2/drm_dma.c b/sys/dev/drm2/drm_dma.c
index c0a1c809bf96..380be2b8ca31 100644
--- a/sys/dev/drm2/drm_dma.c
+++ b/sys/dev/drm2/drm_dma.c
@@ -1,4 +1,14 @@
+/**
+ * \file drm_dma.c
+ * DMA IOCTL and function support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
/*-
+ * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
+ *
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
@@ -21,64 +31,72 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- *
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/** @file drm_dma.c
- * Support code for DMA buffer management.
- *
- * The implementation used to be significantly more complicated, but the
- * complexity has been moved into the drivers as different buffer management
- * schemes evolved.
- */
-
#include <dev/drm2/drmP.h>
+/**
+ * Initialize the DMA data.
+ *
+ * \param dev DRM device.
+ * \return zero on success or a negative value on failure.
+ *
+ * Allocate and initialize a drm_device_dma structure.
+ */
int drm_dma_setup(struct drm_device *dev)
{
+ int i;
dev->dma = malloc(sizeof(*dev->dma), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
- if (dev->dma == NULL)
- return ENOMEM;
+ if (!dev->dma)
+ return -ENOMEM;
- DRM_SPININIT(&dev->dma_lock, "drmdma");
+ for (i = 0; i <= DRM_MAX_ORDER; i++)
+ memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
return 0;
}
+/**
+ * Cleanup the DMA resources.
+ *
+ * \param dev DRM device.
+ *
+ * Free all pages associated with DMA buffers, the buffers and pages lists, and
+ * finally the drm_device::dma structure itself.
+ */
void drm_dma_takedown(struct drm_device *dev)
{
- drm_device_dma_t *dma = dev->dma;
- int i, j;
+ struct drm_device_dma *dma = dev->dma;
+ int i, j;
- if (dma == NULL)
+ if (!dma)
return;
/* Clear dma buffers */
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].seg_count) {
DRM_DEBUG("order %d: buf_count = %d,"
- " seg_count = %d\n", i, dma->bufs[i].buf_count,
- dma->bufs[i].seg_count);
+ " seg_count = %d\n",
+ i,
+ dma->bufs[i].buf_count,
+ dma->bufs[i].seg_count);
for (j = 0; j < dma->bufs[i].seg_count; j++) {
- drm_pci_free(dev, dma->bufs[i].seglist[j]);
+ if (dma->bufs[i].seglist[j]) {
+ drm_pci_free(dev, dma->bufs[i].seglist[j]);
+ }
}
free(dma->bufs[i].seglist, DRM_MEM_SEGS);
}
-
- if (dma->bufs[i].buf_count) {
- for (j = 0; j < dma->bufs[i].buf_count; j++) {
+ if (dma->bufs[i].buf_count) {
+ for (j = 0; j < dma->bufs[i].buf_count; j++) {
free(dma->bufs[i].buflist[j].dev_private,
DRM_MEM_BUFS);
}
- free(dma->bufs[i].buflist, DRM_MEM_BUFS);
+ free(dma->bufs[i].buflist, DRM_MEM_BUFS);
}
}
@@ -86,28 +104,42 @@ void drm_dma_takedown(struct drm_device *dev)
free(dma->pagelist, DRM_MEM_PAGES);
free(dev->dma, DRM_MEM_DRIVER);
dev->dma = NULL;
- DRM_SPINUNINIT(&dev->dma_lock);
}
-
-void drm_free_buffer(struct drm_device *dev, drm_buf_t *buf)
+/**
+ * Free a buffer.
+ *
+ * \param dev DRM device.
+ * \param buf buffer to free.
+ *
+ * Resets the fields of \p buf.
+ */
+void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf)
{
if (!buf)
return;
- buf->pending = 0;
- buf->file_priv= NULL;
- buf->used = 0;
+ buf->waiting = 0;
+ buf->pending = 0;
+ buf->file_priv = NULL;
+ buf->used = 0;
}
-void drm_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
+/**
+ * Reclaim the buffers.
+ *
+ * \param file_priv DRM file private.
+ *
+ * Frees each buffer associated with \p file_priv not already on the hardware.
+ */
+void drm_core_reclaim_buffers(struct drm_device *dev,
+ struct drm_file *file_priv)
{
- drm_device_dma_t *dma = dev->dma;
- int i;
+ struct drm_device_dma *dma = dev->dma;
+ int i;
if (!dma)
return;
-
for (i = 0; i < dma->buf_count; i++) {
if (dma->buflist[i]->file_priv == file_priv) {
switch (dma->buflist[i]->list) {
@@ -125,15 +157,4 @@ void drm_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
}
}
-/* Call into the driver-specific DMA handler */
-int drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
-
- if (dev->driver->dma_ioctl) {
- /* shared code returns -errno */
- return -dev->driver->dma_ioctl(dev, data, file_priv);
- } else {
- DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
- return EINVAL;
- }
-}
+EXPORT_SYMBOL(drm_core_reclaim_buffers);