diff options
Diffstat (limited to 'sys/dev/drm2/drm_dma.c')
-rw-r--r-- | sys/dev/drm2/drm_dma.c | 117 |
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); |