aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_drv.c')
-rw-r--r--drivers/gpu/drm/drm_drv.c107
1 files changed, 49 insertions, 58 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3ab1e9cc4692..14c7a23dc157 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -74,6 +74,9 @@ static struct drm_ioctl_desc drm_ioctls[] = {
74 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 74 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
75 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), 75 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
76 76
77 DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
78 DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
79
77 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), 80 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
78 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 81 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
79 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 82 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -123,6 +126,23 @@ static struct drm_ioctl_desc drm_ioctls[] = {
123 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0), 126 DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
124 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH), 127 DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
125 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH), 128 DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
129
130 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW),
131 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
132 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
133 DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
134 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER),
135 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
136 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW),
137 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),
138 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
139 DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
140 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW),
141 DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
142 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
143 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
144 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
145 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
126}; 146};
127 147
128#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) 148#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
@@ -138,8 +158,6 @@ static struct drm_ioctl_desc drm_ioctls[] = {
138 */ 158 */
139int drm_lastclose(struct drm_device * dev) 159int drm_lastclose(struct drm_device * dev)
140{ 160{
141 struct drm_magic_entry *pt, *next;
142 struct drm_map_list *r_list, *list_t;
143 struct drm_vma_entry *vma, *vma_temp; 161 struct drm_vma_entry *vma, *vma_temp;
144 int i; 162 int i;
145 163
@@ -149,13 +167,7 @@ int drm_lastclose(struct drm_device * dev)
149 dev->driver->lastclose(dev); 167 dev->driver->lastclose(dev);
150 DRM_DEBUG("driver lastclose completed\n"); 168 DRM_DEBUG("driver lastclose completed\n");
151 169
152 if (dev->unique) { 170 if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
153 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
154 dev->unique = NULL;
155 dev->unique_len = 0;
156 }
157
158 if (dev->irq_enabled)
159 drm_irq_uninstall(dev); 171 drm_irq_uninstall(dev);
160 172
161 mutex_lock(&dev->struct_mutex); 173 mutex_lock(&dev->struct_mutex);
@@ -164,18 +176,9 @@ int drm_lastclose(struct drm_device * dev)
164 drm_drawable_free_all(dev); 176 drm_drawable_free_all(dev);
165 del_timer(&dev->timer); 177 del_timer(&dev->timer);
166 178
167 /* Clear pid list */
168 if (dev->magicfree.next) {
169 list_for_each_entry_safe(pt, next, &dev->magicfree, head) {
170 list_del(&pt->head);
171 drm_ht_remove_item(&dev->magiclist, &pt->hash_item);
172 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
173 }
174 drm_ht_remove(&dev->magiclist);
175 }
176
177 /* Clear AGP information */ 179 /* Clear AGP information */
178 if (drm_core_has_AGP(dev) && dev->agp) { 180 if (drm_core_has_AGP(dev) && dev->agp &&
181 !drm_core_check_feature(dev, DRIVER_MODESET)) {
179 struct drm_agp_mem *entry, *tempe; 182 struct drm_agp_mem *entry, *tempe;
180 183
181 /* Remove AGP resources, but leave dev->agp 184 /* Remove AGP resources, but leave dev->agp
@@ -194,7 +197,8 @@ int drm_lastclose(struct drm_device * dev)
194 dev->agp->acquired = 0; 197 dev->agp->acquired = 0;
195 dev->agp->enabled = 0; 198 dev->agp->enabled = 0;
196 } 199 }
197 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) { 200 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg &&
201 !drm_core_check_feature(dev, DRIVER_MODESET)) {
198 drm_sg_cleanup(dev->sg); 202 drm_sg_cleanup(dev->sg);
199 dev->sg = NULL; 203 dev->sg = NULL;
200 } 204 }
@@ -205,13 +209,6 @@ int drm_lastclose(struct drm_device * dev)
205 drm_free(vma, sizeof(*vma), DRM_MEM_VMAS); 209 drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
206 } 210 }
207 211
208 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
209 if (!(r_list->map->flags & _DRM_DRIVER)) {
210 drm_rmmap_locked(dev, r_list->map);
211 r_list = NULL;
212 }
213 }
214
215 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { 212 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
216 for (i = 0; i < dev->queue_count; i++) { 213 for (i = 0; i < dev->queue_count; i++) {
217 if (dev->queuelist[i]) { 214 if (dev->queuelist[i]) {
@@ -228,14 +225,11 @@ int drm_lastclose(struct drm_device * dev)
228 } 225 }
229 dev->queue_count = 0; 226 dev->queue_count = 0;
230 227
231 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 228 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
229 !drm_core_check_feature(dev, DRIVER_MODESET))
232 drm_dma_takedown(dev); 230 drm_dma_takedown(dev);
233 231
234 if (dev->lock.hw_lock) { 232 dev->dev_mapping = NULL;
235 dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
236 dev->lock.file_priv = NULL;
237 wake_up_interruptible(&dev->lock.lock_queue);
238 }
239 mutex_unlock(&dev->struct_mutex); 233 mutex_unlock(&dev->struct_mutex);
240 234
241 DRM_DEBUG("lastclose completed\n"); 235 DRM_DEBUG("lastclose completed\n");
@@ -263,6 +257,8 @@ int drm_init(struct drm_driver *driver)
263 257
264 DRM_DEBUG("\n"); 258 DRM_DEBUG("\n");
265 259
260 INIT_LIST_HEAD(&driver->device_list);
261
266 for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { 262 for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
267 pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; 263 pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
268 264
@@ -298,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
298 */ 294 */
299static void drm_cleanup(struct drm_device * dev) 295static void drm_cleanup(struct drm_device * dev)
300{ 296{
297 struct drm_map_list *r_list, *list_temp;
301 DRM_DEBUG("\n"); 298 DRM_DEBUG("\n");
302 299
303 if (!dev) { 300 if (!dev) {
@@ -305,6 +302,8 @@ static void drm_cleanup(struct drm_device * dev)
305 return; 302 return;
306 } 303 }
307 304
305 drm_vblank_cleanup(dev);
306
308 drm_lastclose(dev); 307 drm_lastclose(dev);
309 308
310 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 309 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -316,46 +315,38 @@ static void drm_cleanup(struct drm_device * dev)
316 DRM_DEBUG("mtrr_del=%d\n", retval); 315 DRM_DEBUG("mtrr_del=%d\n", retval);
317 } 316 }
318 317
318 if (dev->driver->unload)
319 dev->driver->unload(dev);
320
319 if (drm_core_has_AGP(dev) && dev->agp) { 321 if (drm_core_has_AGP(dev) && dev->agp) {
320 drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); 322 drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
321 dev->agp = NULL; 323 dev->agp = NULL;
322 } 324 }
323 325
324 if (dev->driver->unload)
325 dev->driver->unload(dev);
326
327 drm_ht_remove(&dev->map_hash); 326 drm_ht_remove(&dev->map_hash);
328 drm_ctxbitmap_cleanup(dev); 327 drm_ctxbitmap_cleanup(dev);
329 328
330 drm_put_minor(&dev->primary); 329 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
331 if (drm_put_dev(dev)) 330 drm_rmmap(dev, r_list->map);
332 DRM_ERROR("Cannot unload module\n");
333}
334
335static int drm_minors_cleanup(int id, void *ptr, void *data)
336{
337 struct drm_minor *minor = ptr;
338 struct drm_device *dev;
339 struct drm_driver *driver = data;
340 331
341 dev = minor->dev; 332 if (drm_core_check_feature(dev, DRIVER_MODESET))
342 if (minor->dev->driver != driver) 333 drm_put_minor(&dev->control);
343 return 0;
344 334
345 if (minor->type != DRM_MINOR_LEGACY) 335 if (dev->driver->driver_features & DRIVER_GEM)
346 return 0; 336 drm_gem_destroy(dev);
347 337
348 if (dev) 338 drm_put_minor(&dev->primary);
349 pci_dev_put(dev->pdev); 339 if (drm_put_dev(dev))
350 drm_cleanup(dev); 340 DRM_ERROR("Cannot unload module\n");
351 return 1;
352} 341}
353 342
354void drm_exit(struct drm_driver *driver) 343void drm_exit(struct drm_driver *driver)
355{ 344{
345 struct drm_device *dev, *tmp;
356 DRM_DEBUG("\n"); 346 DRM_DEBUG("\n");
357 347
358 idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); 348 list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
349 drm_cleanup(dev);
359 350
360 DRM_INFO("Module unloaded\n"); 351 DRM_INFO("Module unloaded\n");
361} 352}
@@ -501,7 +492,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
501 retcode = -EINVAL; 492 retcode = -EINVAL;
502 } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || 493 } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
503 ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || 494 ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
504 ((ioctl->flags & DRM_MASTER) && !file_priv->master)) { 495 ((ioctl->flags & DRM_MASTER) && !file_priv->is_master)) {
505 retcode = -EACCES; 496 retcode = -EACCES;
506 } else { 497 } else {
507 if (cmd & (IOC_IN | IOC_OUT)) { 498 if (cmd & (IOC_IN | IOC_OUT)) {