aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_scatter.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/drm_scatter.c')
-rw-r--r--drivers/char/drm/drm_scatter.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
index 0c2188367e69..eb7fa437355e 100644
--- a/drivers/char/drm/drm_scatter.c
+++ b/drivers/char/drm/drm_scatter.c
@@ -62,12 +62,8 @@ void drm_sg_cleanup(struct drm_sg_mem * entry)
62# define ScatterHandle(x) (unsigned int)(x) 62# define ScatterHandle(x) (unsigned int)(x)
63#endif 63#endif
64 64
65int drm_sg_alloc(struct inode *inode, struct drm_file *file_priv, 65int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
66 unsigned int cmd, unsigned long arg)
67{ 66{
68 struct drm_device *dev = file_priv->head->dev;
69 struct drm_scatter_gather __user *argp = (void __user *)arg;
70 struct drm_scatter_gather request;
71 struct drm_sg_mem *entry; 67 struct drm_sg_mem *entry;
72 unsigned long pages, i, j; 68 unsigned long pages, i, j;
73 69
@@ -79,17 +75,13 @@ int drm_sg_alloc(struct inode *inode, struct drm_file *file_priv,
79 if (dev->sg) 75 if (dev->sg)
80 return -EINVAL; 76 return -EINVAL;
81 77
82 if (copy_from_user(&request, argp, sizeof(request)))
83 return -EFAULT;
84
85 entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); 78 entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
86 if (!entry) 79 if (!entry)
87 return -ENOMEM; 80 return -ENOMEM;
88 81
89 memset(entry, 0, sizeof(*entry)); 82 memset(entry, 0, sizeof(*entry));
90 83 pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
91 pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; 84 DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages);
92 DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages);
93 85
94 entry->pages = pages; 86 entry->pages = pages;
95 entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), 87 entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
@@ -141,12 +133,7 @@ int drm_sg_alloc(struct inode *inode, struct drm_file *file_priv,
141 SetPageReserved(entry->pagelist[j]); 133 SetPageReserved(entry->pagelist[j]);
142 } 134 }
143 135
144 request.handle = entry->handle; 136 request->handle = entry->handle;
145
146 if (copy_to_user(argp, &request, sizeof(request))) {
147 drm_sg_cleanup(entry);
148 return -EFAULT;
149 }
150 137
151 dev->sg = entry; 138 dev->sg = entry;
152 139
@@ -196,26 +183,31 @@ int drm_sg_alloc(struct inode *inode, struct drm_file *file_priv,
196 drm_sg_cleanup(entry); 183 drm_sg_cleanup(entry);
197 return -ENOMEM; 184 return -ENOMEM;
198} 185}
186EXPORT_SYMBOL(drm_sg_alloc);
187
199 188
200int drm_sg_free(struct inode *inode, struct drm_file *file_priv, 189int drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
201 unsigned int cmd, unsigned long arg) 190 struct drm_file *file_priv)
202{ 191{
203 struct drm_device *dev = file_priv->head->dev; 192 struct drm_scatter_gather *request = data;
204 struct drm_scatter_gather request; 193
194 return drm_sg_alloc(dev, request);
195
196}
197
198int drm_sg_free(struct drm_device *dev, void *data,
199 struct drm_file *file_priv)
200{
201 struct drm_scatter_gather *request = data;
205 struct drm_sg_mem *entry; 202 struct drm_sg_mem *entry;
206 203
207 if (!drm_core_check_feature(dev, DRIVER_SG)) 204 if (!drm_core_check_feature(dev, DRIVER_SG))
208 return -EINVAL; 205 return -EINVAL;
209 206
210 if (copy_from_user(&request,
211 (struct drm_scatter_gather __user *) arg,
212 sizeof(request)))
213 return -EFAULT;
214
215 entry = dev->sg; 207 entry = dev->sg;
216 dev->sg = NULL; 208 dev->sg = NULL;
217 209
218 if (!entry || entry->handle != request.handle) 210 if (!entry || entry->handle != request->handle)
219 return -EINVAL; 211 return -EINVAL;
220 212
221 DRM_DEBUG("sg free virtual = %p\n", entry->virtual); 213 DRM_DEBUG("sg free virtual = %p\n", entry->virtual);