FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/drm_dma.h
1 /* drm_dma.c -- DMA IOCTL and function support -*- linux-c -*-
2 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com */
3 /*-
4 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 *
31 * $FreeBSD$
32 */
33
34 #include "dev/drm/drmP.h"
35
36 #ifndef __HAVE_DMA_WAITQUEUE
37 #define __HAVE_DMA_WAITQUEUE 0
38 #endif
39 #ifndef __HAVE_DMA_RECLAIM
40 #define __HAVE_DMA_RECLAIM 0
41 #endif
42 #ifndef __HAVE_SHARED_IRQ
43 #define __HAVE_SHARED_IRQ 0
44 #endif
45
46 #if __HAVE_DMA
47
48 int DRM(dma_setup)( drm_device_t *dev )
49 {
50
51 dev->dma = DRM(calloc)(1, sizeof(*dev->dma), DRM_MEM_DRIVER);
52 if (dev->dma == NULL)
53 return DRM_ERR(ENOMEM);
54
55 DRM_SPININIT(dev->dma_lock, "drmdma");
56
57 return 0;
58 }
59
60 void DRM(dma_takedown)(drm_device_t *dev)
61 {
62 drm_device_dma_t *dma = dev->dma;
63 int i, j;
64
65 if (dma == NULL)
66 return;
67
68 /* Clear dma buffers */
69 for (i = 0; i <= DRM_MAX_ORDER; i++) {
70 #if __HAVE_PCI_DMA
71 if (dma->bufs[i].seg_count) {
72 DRM_DEBUG("order %d: buf_count = %d,"
73 " seg_count = %d\n",
74 i,
75 dma->bufs[i].buf_count,
76 dma->bufs[i].seg_count);
77 for (j = 0; j < dma->bufs[i].seg_count; j++) {
78 if (dma->bufs[i].seglist[j] != 0)
79 DRM(pci_free)(dev, dma->bufs[i].buf_size,
80 (void *)dma->bufs[i].seglist[j],
81 dma->bufs[i].seglist_bus[j]);
82 }
83 DRM(free)(dma->bufs[i].seglist,
84 dma->bufs[i].seg_count
85 * sizeof(*dma->bufs[0].seglist),
86 DRM_MEM_SEGS);
87 DRM(free)(dma->bufs[i].seglist_bus,
88 dma->bufs[i].seg_count
89 * sizeof(*dma->bufs[0].seglist_bus),
90 DRM_MEM_SEGS);
91 }
92 #endif /* __HAVE_PCI_DMA */
93
94 if (dma->bufs[i].buf_count) {
95 for (j = 0; j < dma->bufs[i].buf_count; j++) {
96 DRM(free)(dma->bufs[i].buflist[j].dev_private,
97 dma->bufs[i].buflist[j].dev_priv_size,
98 DRM_MEM_BUFS);
99 }
100 DRM(free)(dma->bufs[i].buflist,
101 dma->bufs[i].buf_count *
102 sizeof(*dma->bufs[0].buflist),
103 DRM_MEM_BUFS);
104 }
105 }
106
107 DRM(free)(dma->buflist, dma->buf_count * sizeof(*dma->buflist),
108 DRM_MEM_BUFS);
109 DRM(free)(dma->pagelist, dma->page_count * sizeof(*dma->pagelist),
110 DRM_MEM_PAGES);
111 DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
112 dev->dma = NULL;
113 DRM_SPINUNINIT(dev->dma_lock);
114 }
115
116
117 void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
118 {
119 if (!buf) return;
120
121 buf->pending = 0;
122 buf->filp = NULL;
123 buf->used = 0;
124 }
125
126 #if !__HAVE_DMA_RECLAIM
127 void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp)
128 {
129 drm_device_dma_t *dma = dev->dma;
130 int i;
131
132 if (!dma) return;
133 for (i = 0; i < dma->buf_count; i++) {
134 if (dma->buflist[i]->filp == filp) {
135 switch (dma->buflist[i]->list) {
136 case DRM_LIST_NONE:
137 DRM(free_buffer)(dev, dma->buflist[i]);
138 break;
139 case DRM_LIST_WAIT:
140 dma->buflist[i]->list = DRM_LIST_RECLAIM;
141 break;
142 default:
143 /* Buffer already on hardware. */
144 break;
145 }
146 }
147 }
148 }
149 #endif
150
151 #if !__HAVE_IRQ
152 /* This stub DRM_IOCTL_CONTROL handler is for the drivers that used to require
153 * IRQs for DMA but no longer do. It maintains compatibility with the X Servers
154 * that try to use the control ioctl by simply returning success.
155 */
156 int DRM(control)( DRM_IOCTL_ARGS )
157 {
158 drm_control_t ctl;
159
160 DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
161
162 switch ( ctl.func ) {
163 case DRM_INST_HANDLER:
164 case DRM_UNINST_HANDLER:
165 return 0;
166 default:
167 return DRM_ERR(EINVAL);
168 }
169 }
170 #endif
171
172 #endif /* __HAVE_DMA */
Cache object: 217e2c78d63fc7804507da593450ff19
|