Blame view
drivers/gpu/drm/drm_scatter.c
5.32 KB
45b2fda3d gpu/drm: fix a fe... |
1 |
/* |
b5e89ed53 drm: lindent the ... |
2 |
* \file drm_scatter.c |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
* IOCTLs to manage scatter/gather memory * * \author Gareth Hughes <gareth@valinux.com> */ /* * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com * * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * 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. */ |
0500c04ea drm: drop use of ... |
33 |
#include <linux/mm.h> |
5a0e3ad6a include cleanup: ... |
34 |
#include <linux/slab.h> |
0500c04ea drm: drop use of ... |
35 36 37 38 39 |
#include <linux/vmalloc.h> #include <drm/drm.h> #include <drm/drm_drv.h> #include <drm/drm_print.h> |
9ec4e2ff3 drm: Move sg func... |
40 |
#include "drm_legacy.h" |
1da177e4c Linux-2.6.12-rc2 |
41 42 |
#define DEBUG_SCATTER 0 |
3d914e835 drm: hide legacy ... |
43 |
static void drm_sg_cleanup(struct drm_sg_mem * entry) |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 |
{ struct page *page; int i; |
b5e89ed53 drm: lindent the ... |
47 |
for (i = 0; i < entry->pages; i++) { |
1da177e4c Linux-2.6.12-rc2 |
48 |
page = entry->pagelist[i]; |
b5e89ed53 drm: lindent the ... |
49 50 |
if (page) ClearPageReserved(page); |
1da177e4c Linux-2.6.12-rc2 |
51 |
} |
b5e89ed53 drm: lindent the ... |
52 |
vfree(entry->virtual); |
9a298b2ac drm: Remove memor... |
53 54 55 |
kfree(entry->busaddr); kfree(entry->pagelist); kfree(entry); |
1da177e4c Linux-2.6.12-rc2 |
56 |
} |
3d914e835 drm: hide legacy ... |
57 58 59 |
void drm_legacy_sg_cleanup(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && |
fa5386459 drm: Used DRM_LEG... |
60 |
drm_core_check_feature(dev, DRIVER_LEGACY)) { |
3d914e835 drm: hide legacy ... |
61 62 63 64 |
drm_sg_cleanup(dev->sg); dev->sg = NULL; } } |
d1f2b55ad drm: updated DRM ... |
65 66 67 68 69 |
#ifdef _LP64 # define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1))) #else # define ScatterHandle(x) (unsigned int)(x) #endif |
9ec4e2ff3 drm: Move sg func... |
70 71 |
int drm_legacy_sg_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) |
1da177e4c Linux-2.6.12-rc2 |
72 |
{ |
1d8d29cf2 drm: fold in drm_... |
73 |
struct drm_scatter_gather *request = data; |
55910517a drm: detypedeffin... |
74 |
struct drm_sg_mem *entry; |
1da177e4c Linux-2.6.12-rc2 |
75 |
unsigned long pages, i, j; |
3e684eae5 drm: cleanup DRM_... |
76 77 |
DRM_DEBUG(" "); |
1da177e4c Linux-2.6.12-rc2 |
78 |
|
fa5386459 drm: Used DRM_LEG... |
79 |
if (!drm_core_check_feature(dev, DRIVER_LEGACY)) |
69fdf4206 drm: Differentiat... |
80 |
return -EOPNOTSUPP; |
8e194bbf9 drm: disallow leg... |
81 |
|
1da177e4c Linux-2.6.12-rc2 |
82 |
if (!drm_core_check_feature(dev, DRIVER_SG)) |
69fdf4206 drm: Differentiat... |
83 |
return -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
84 |
|
abdd768e9 drm: prevent a ha... |
85 86 |
if (request->size > SIZE_MAX - PAGE_SIZE) return -EINVAL; |
b5e89ed53 drm: lindent the ... |
87 |
if (dev->sg) |
1da177e4c Linux-2.6.12-rc2 |
88 |
return -EINVAL; |
f35119d66 drivers: use kzal... |
89 |
entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
b5e89ed53 drm: lindent the ... |
90 |
if (!entry) |
1da177e4c Linux-2.6.12-rc2 |
91 |
return -ENOMEM; |
c153f45f9 drm: Replace DRM_... |
92 |
pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
3e684eae5 drm: cleanup DRM_... |
93 94 |
DRM_DEBUG("size=%ld pages=%ld ", request->size, pages); |
1da177e4c Linux-2.6.12-rc2 |
95 96 |
entry->pages = pages; |
f35119d66 drivers: use kzal... |
97 |
entry->pagelist = kcalloc(pages, sizeof(*entry->pagelist), GFP_KERNEL); |
b5e89ed53 drm: lindent the ... |
98 |
if (!entry->pagelist) { |
9a298b2ac drm: Remove memor... |
99 |
kfree(entry); |
1da177e4c Linux-2.6.12-rc2 |
100 101 |
return -ENOMEM; } |
f35119d66 drivers: use kzal... |
102 |
entry->busaddr = kcalloc(pages, sizeof(*entry->busaddr), GFP_KERNEL); |
b5e89ed53 drm: lindent the ... |
103 |
if (!entry->busaddr) { |
9a298b2ac drm: Remove memor... |
104 105 |
kfree(entry->pagelist); kfree(entry); |
1da177e4c Linux-2.6.12-rc2 |
106 107 |
return -ENOMEM; } |
b5e89ed53 drm: lindent the ... |
108 |
|
d28ff991b gpu/drm: remove t... |
109 |
entry->virtual = vmalloc_32(pages << PAGE_SHIFT); |
b5e89ed53 drm: lindent the ... |
110 |
if (!entry->virtual) { |
9a298b2ac drm: Remove memor... |
111 112 113 |
kfree(entry->busaddr); kfree(entry->pagelist); kfree(entry); |
1da177e4c Linux-2.6.12-rc2 |
114 115 116 117 118 119 |
return -ENOMEM; } /* This also forces the mapping of COW pages, so our page list * will be valid. Please don't remove it... */ |
b5e89ed53 drm: lindent the ... |
120 |
memset(entry->virtual, 0, pages << PAGE_SHIFT); |
1da177e4c Linux-2.6.12-rc2 |
121 |
|
d1f2b55ad drm: updated DRM ... |
122 |
entry->handle = ScatterHandle((unsigned long)entry->virtual); |
1da177e4c Linux-2.6.12-rc2 |
123 |
|
3e684eae5 drm: cleanup DRM_... |
124 125 126 127 |
DRM_DEBUG("handle = %08lx ", entry->handle); DRM_DEBUG("virtual = %p ", entry->virtual); |
1da177e4c Linux-2.6.12-rc2 |
128 |
|
b5e89ed53 drm: lindent the ... |
129 130 |
for (i = (unsigned long)entry->virtual, j = 0; j < pages; i += PAGE_SIZE, j++) { |
1da177e4c Linux-2.6.12-rc2 |
131 132 133 134 135 |
entry->pagelist[j] = vmalloc_to_page((void *)i); if (!entry->pagelist[j]) goto failed; SetPageReserved(entry->pagelist[j]); } |
c153f45f9 drm: Replace DRM_... |
136 |
request->handle = entry->handle; |
1da177e4c Linux-2.6.12-rc2 |
137 138 139 140 141 142 143 144 |
dev->sg = entry; #if DEBUG_SCATTER /* Verify that each page points to its virtual address, and vice * versa. */ { |
b5e89ed53 drm: lindent the ... |
145 |
int error = 0; |
1da177e4c Linux-2.6.12-rc2 |
146 |
|
b5e89ed53 drm: lindent the ... |
147 148 |
for (i = 0; i < pages; i++) { unsigned long *tmp; |
1da177e4c Linux-2.6.12-rc2 |
149 |
|
b5e89ed53 drm: lindent the ... |
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
tmp = page_address(entry->pagelist[i]); for (j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) { *tmp = 0xcafebabe; } tmp = (unsigned long *)((u8 *) entry->virtual + (PAGE_SIZE * i)); for (j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) { if (*tmp != 0xcafebabe && error == 0) { error = 1; DRM_ERROR("Scatter allocation error, " "pagelist does not match " "virtual mapping "); } } tmp = page_address(entry->pagelist[i]); for (j = 0; j < PAGE_SIZE / sizeof(unsigned long); j++, tmp++) { *tmp = 0; |
1da177e4c Linux-2.6.12-rc2 |
174 175 |
} } |
b5e89ed53 drm: lindent the ... |
176 177 178 |
if (error == 0) DRM_ERROR("Scatter allocation matches pagelist "); |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 182 |
} #endif return 0; |
b5e89ed53 drm: lindent the ... |
183 184 |
failed: drm_sg_cleanup(entry); |
1da177e4c Linux-2.6.12-rc2 |
185 186 |
return -ENOMEM; } |
9ec4e2ff3 drm: Move sg func... |
187 188 |
int drm_legacy_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv) |
c153f45f9 drm: Replace DRM_... |
189 190 |
{ struct drm_scatter_gather *request = data; |
55910517a drm: detypedeffin... |
191 |
struct drm_sg_mem *entry; |
1da177e4c Linux-2.6.12-rc2 |
192 |
|
fa5386459 drm: Used DRM_LEG... |
193 |
if (!drm_core_check_feature(dev, DRIVER_LEGACY)) |
69fdf4206 drm: Differentiat... |
194 |
return -EOPNOTSUPP; |
8e194bbf9 drm: disallow leg... |
195 |
|
1da177e4c Linux-2.6.12-rc2 |
196 |
if (!drm_core_check_feature(dev, DRIVER_SG)) |
69fdf4206 drm: Differentiat... |
197 |
return -EOPNOTSUPP; |
1da177e4c Linux-2.6.12-rc2 |
198 |
|
1da177e4c Linux-2.6.12-rc2 |
199 200 |
entry = dev->sg; dev->sg = NULL; |
c153f45f9 drm: Replace DRM_... |
201 |
if (!entry || entry->handle != request->handle) |
1da177e4c Linux-2.6.12-rc2 |
202 |
return -EINVAL; |
3e684eae5 drm: cleanup DRM_... |
203 204 |
DRM_DEBUG("virtual = %p ", entry->virtual); |
1da177e4c Linux-2.6.12-rc2 |
205 |
|
b5e89ed53 drm: lindent the ... |
206 |
drm_sg_cleanup(entry); |
1da177e4c Linux-2.6.12-rc2 |
207 208 209 |
return 0; } |