]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/drm_fops.c
drm: don't call ->firstopen for KMS drivers
[karo-tx-linux.git] / drivers / gpu / drm / drm_fops.c
1 /**
2  * \file drm_fops.c
3  * File operations for DRM
4  *
5  * \author Rickard E. (Rik) Faith <faith@valinux.com>
6  * \author Daryll Strauss <daryll@valinux.com>
7  * \author Gareth Hughes <gareth@valinux.com>
8  */
9
10 /*
11  * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
12  *
13  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
14  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
15  * All Rights Reserved.
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining a
18  * copy of this software and associated documentation files (the "Software"),
19  * to deal in the Software without restriction, including without limitation
20  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21  * and/or sell copies of the Software, and to permit persons to whom the
22  * Software is furnished to do so, subject to the following conditions:
23  *
24  * The above copyright notice and this permission notice (including the next
25  * paragraph) shall be included in all copies or substantial portions of the
26  * Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
31  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
32  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
33  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
34  * OTHER DEALINGS IN THE SOFTWARE.
35  */
36
37 #include <drm/drmP.h>
38 #include <linux/poll.h>
39 #include <linux/slab.h>
40 #include <linux/module.h>
41
42 /* from BKL pushdown: note that nothing else serializes idr_find() */
43 DEFINE_MUTEX(drm_global_mutex);
44 EXPORT_SYMBOL(drm_global_mutex);
45
46 static int drm_open_helper(struct inode *inode, struct file *filp,
47                            struct drm_device * dev);
48
49 static int drm_setup(struct drm_device * dev)
50 {
51         int i;
52         int ret;
53
54         if (dev->driver->firstopen &&
55             !drm_core_check_feature(dev, DRIVER_MODESET)) {
56                 ret = dev->driver->firstopen(dev);
57                 if (ret != 0)
58                         return ret;
59         }
60
61         atomic_set(&dev->ioctl_count, 0);
62         atomic_set(&dev->vma_count, 0);
63
64         i = drm_legacy_dma_setup(dev);
65         if (i < 0)
66                 return i;
67
68         for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
69                 atomic_set(&dev->counts[i], 0);
70
71         dev->sigdata.lock = NULL;
72
73         dev->context_flag = 0;
74         dev->last_context = 0;
75         dev->if_version = 0;
76
77         DRM_DEBUG("\n");
78
79         /*
80          * The kernel's context could be created here, but is now created
81          * in drm_dma_enqueue.  This is more resource-efficient for
82          * hardware that does not do DMA, but may mean that
83          * drm_select_queue fails between the time the interrupt is
84          * initialized and the time the queues are initialized.
85          */
86
87         return 0;
88 }
89
90 /**
91  * Open file.
92  *
93  * \param inode device inode
94  * \param filp file pointer.
95  * \return zero on success or a negative number on failure.
96  *
97  * Searches the DRM device with the same minor number, calls open_helper(), and
98  * increments the device open count. If the open count was previous at zero,
99  * i.e., it's the first that the device is open, then calls setup().
100  */
101 int drm_open(struct inode *inode, struct file *filp)
102 {
103         struct drm_device *dev = NULL;
104         int minor_id = iminor(inode);
105         struct drm_minor *minor;
106         int retcode = 0;
107         int need_setup = 0;
108         struct address_space *old_mapping;
109         struct address_space *old_imapping;
110
111         minor = idr_find(&drm_minors_idr, minor_id);
112         if (!minor)
113                 return -ENODEV;
114
115         if (!(dev = minor->dev))
116                 return -ENODEV;
117
118         if (drm_device_is_unplugged(dev))
119                 return -ENODEV;
120
121         if (!dev->open_count++)
122                 need_setup = 1;
123         mutex_lock(&dev->struct_mutex);
124         old_imapping = inode->i_mapping;
125         old_mapping = dev->dev_mapping;
126         if (old_mapping == NULL)
127                 dev->dev_mapping = &inode->i_data;
128         /* ihold ensures nobody can remove inode with our i_data */
129         ihold(container_of(dev->dev_mapping, struct inode, i_data));
130         inode->i_mapping = dev->dev_mapping;
131         filp->f_mapping = dev->dev_mapping;
132         mutex_unlock(&dev->struct_mutex);
133
134         retcode = drm_open_helper(inode, filp, dev);
135         if (retcode)
136                 goto err_undo;
137         atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
138         if (need_setup) {
139                 retcode = drm_setup(dev);
140                 if (retcode)
141                         goto err_undo;
142         }
143         return 0;
144
145 err_undo:
146         mutex_lock(&dev->struct_mutex);
147         filp->f_mapping = old_imapping;
148         inode->i_mapping = old_imapping;
149         iput(container_of(dev->dev_mapping, struct inode, i_data));
150         dev->dev_mapping = old_mapping;
151         mutex_unlock(&dev->struct_mutex);
152         dev->open_count--;
153         return retcode;
154 }
155 EXPORT_SYMBOL(drm_open);
156
157 /**
158  * File \c open operation.
159  *
160  * \param inode device inode.
161  * \param filp file pointer.
162  *
163  * Puts the dev->fops corresponding to the device minor number into
164  * \p filp, call the \c open method, and restore the file operations.
165  */
166 int drm_stub_open(struct inode *inode, struct file *filp)
167 {
168         struct drm_device *dev = NULL;
169         struct drm_minor *minor;
170         int minor_id = iminor(inode);
171         int err = -ENODEV;
172         const struct file_operations *old_fops;
173
174         DRM_DEBUG("\n");
175
176         mutex_lock(&drm_global_mutex);
177         minor = idr_find(&drm_minors_idr, minor_id);
178         if (!minor)
179                 goto out;
180
181         if (!(dev = minor->dev))
182                 goto out;
183
184         if (drm_device_is_unplugged(dev))
185                 goto out;
186
187         old_fops = filp->f_op;
188         filp->f_op = fops_get(dev->driver->fops);
189         if (filp->f_op == NULL) {
190                 filp->f_op = old_fops;
191                 goto out;
192         }
193         if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
194                 fops_put(filp->f_op);
195                 filp->f_op = fops_get(old_fops);
196         }
197         fops_put(old_fops);
198
199 out:
200         mutex_unlock(&drm_global_mutex);
201         return err;
202 }
203
204 /**
205  * Check whether DRI will run on this CPU.
206  *
207  * \return non-zero if the DRI will run on this CPU, or zero otherwise.
208  */
209 static int drm_cpu_valid(void)
210 {
211 #if defined(__i386__)
212         if (boot_cpu_data.x86 == 3)
213                 return 0;       /* No cmpxchg on a 386 */
214 #endif
215 #if defined(__sparc__) && !defined(__sparc_v9__)
216         return 0;               /* No cmpxchg before v9 sparc. */
217 #endif
218         return 1;
219 }
220
221 /**
222  * Called whenever a process opens /dev/drm.
223  *
224  * \param inode device inode.
225  * \param filp file pointer.
226  * \param dev device.
227  * \return zero on success or a negative number on failure.
228  *
229  * Creates and initializes a drm_file structure for the file private data in \p
230  * filp and add it into the double linked list in \p dev.
231  */
232 static int drm_open_helper(struct inode *inode, struct file *filp,
233                            struct drm_device * dev)
234 {
235         int minor_id = iminor(inode);
236         struct drm_file *priv;
237         int ret;
238
239         if (filp->f_flags & O_EXCL)
240                 return -EBUSY;  /* No exclusive opens */
241         if (!drm_cpu_valid())
242                 return -EINVAL;
243         if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
244                 return -EINVAL;
245
246         DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);
247
248         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
249         if (!priv)
250                 return -ENOMEM;
251
252         filp->private_data = priv;
253         priv->filp = filp;
254         priv->uid = current_euid();
255         priv->pid = get_pid(task_pid(current));
256         priv->minor = idr_find(&drm_minors_idr, minor_id);
257         if (!priv->minor) {
258                 ret = -ENODEV;
259                 goto out_put_pid;
260         }
261
262         priv->ioctl_count = 0;
263         /* for compatibility root is always authenticated */
264         priv->authenticated = capable(CAP_SYS_ADMIN);
265         priv->lock_count = 0;
266
267         INIT_LIST_HEAD(&priv->lhead);
268         INIT_LIST_HEAD(&priv->fbs);
269         mutex_init(&priv->fbs_lock);
270         INIT_LIST_HEAD(&priv->event_list);
271         init_waitqueue_head(&priv->event_wait);
272         priv->event_space = 4096; /* set aside 4k for event buffer */
273
274         if (dev->driver->driver_features & DRIVER_GEM)
275                 drm_gem_open(dev, priv);
276
277         if (drm_core_check_feature(dev, DRIVER_PRIME))
278                 drm_prime_init_file_private(&priv->prime);
279
280         if (dev->driver->open) {
281                 ret = dev->driver->open(dev, priv);
282                 if (ret < 0)
283                         goto out_prime_destroy;
284         }
285
286
287         /* if there is no current master make this fd it */
288         mutex_lock(&dev->struct_mutex);
289         if (!priv->minor->master) {
290                 /* create a new master */
291                 priv->minor->master = drm_master_create(priv->minor);
292                 if (!priv->minor->master) {
293                         mutex_unlock(&dev->struct_mutex);
294                         ret = -ENOMEM;
295                         goto out_close;
296                 }
297
298                 priv->is_master = 1;
299                 /* take another reference for the copy in the local file priv */
300                 priv->master = drm_master_get(priv->minor->master);
301
302                 priv->authenticated = 1;
303
304                 mutex_unlock(&dev->struct_mutex);
305                 if (dev->driver->master_create) {
306                         ret = dev->driver->master_create(dev, priv->master);
307                         if (ret) {
308                                 mutex_lock(&dev->struct_mutex);
309                                 /* drop both references if this fails */
310                                 drm_master_put(&priv->minor->master);
311                                 drm_master_put(&priv->master);
312                                 mutex_unlock(&dev->struct_mutex);
313                                 goto out_close;
314                         }
315                 }
316                 mutex_lock(&dev->struct_mutex);
317                 if (dev->driver->master_set) {
318                         ret = dev->driver->master_set(dev, priv, true);
319                         if (ret) {
320                                 /* drop both references if this fails */
321                                 drm_master_put(&priv->minor->master);
322                                 drm_master_put(&priv->master);
323                                 mutex_unlock(&dev->struct_mutex);
324                                 goto out_close;
325                         }
326                 }
327                 mutex_unlock(&dev->struct_mutex);
328         } else {
329                 /* get a reference to the master */
330                 priv->master = drm_master_get(priv->minor->master);
331                 mutex_unlock(&dev->struct_mutex);
332         }
333
334         mutex_lock(&dev->struct_mutex);
335         list_add(&priv->lhead, &dev->filelist);
336         mutex_unlock(&dev->struct_mutex);
337
338 #ifdef __alpha__
339         /*
340          * Default the hose
341          */
342         if (!dev->hose) {
343                 struct pci_dev *pci_dev;
344                 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
345                 if (pci_dev) {
346                         dev->hose = pci_dev->sysdata;
347                         pci_dev_put(pci_dev);
348                 }
349                 if (!dev->hose) {
350                         struct pci_bus *b = pci_bus_b(pci_root_buses.next);
351                         if (b)
352                                 dev->hose = b->sysdata;
353                 }
354         }
355 #endif
356
357         return 0;
358
359 out_close:
360         if (dev->driver->postclose)
361                 dev->driver->postclose(dev, priv);
362 out_prime_destroy:
363         if (drm_core_check_feature(dev, DRIVER_PRIME))
364                 drm_prime_destroy_file_private(&priv->prime);
365         if (dev->driver->driver_features & DRIVER_GEM)
366                 drm_gem_release(dev, priv);
367 out_put_pid:
368         put_pid(priv->pid);
369         kfree(priv);
370         filp->private_data = NULL;
371         return ret;
372 }
373
374 static void drm_master_release(struct drm_device *dev, struct file *filp)
375 {
376         struct drm_file *file_priv = filp->private_data;
377
378         if (drm_i_have_hw_lock(dev, file_priv)) {
379                 DRM_DEBUG("File %p released, freeing lock for context %d\n",
380                           filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock));
381                 drm_lock_free(&file_priv->master->lock,
382                               _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock));
383         }
384 }
385
386 static void drm_events_release(struct drm_file *file_priv)
387 {
388         struct drm_device *dev = file_priv->minor->dev;
389         struct drm_pending_event *e, *et;
390         struct drm_pending_vblank_event *v, *vt;
391         unsigned long flags;
392
393         spin_lock_irqsave(&dev->event_lock, flags);
394
395         /* Remove pending flips */
396         list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link)
397                 if (v->base.file_priv == file_priv) {
398                         list_del(&v->base.link);
399                         drm_vblank_put(dev, v->pipe);
400                         v->base.destroy(&v->base);
401                 }
402
403         /* Remove unconsumed events */
404         list_for_each_entry_safe(e, et, &file_priv->event_list, link)
405                 e->destroy(e);
406
407         spin_unlock_irqrestore(&dev->event_lock, flags);
408 }
409
410 /**
411  * Release file.
412  *
413  * \param inode device inode
414  * \param file_priv DRM file private.
415  * \return zero on success or a negative number on failure.
416  *
417  * If the hardware lock is held then free it, and take it again for the kernel
418  * context since it's necessary to reclaim buffers. Unlink the file private
419  * data from its list and free it. Decreases the open count and if it reaches
420  * zero calls drm_lastclose().
421  */
422 int drm_release(struct inode *inode, struct file *filp)
423 {
424         struct drm_file *file_priv = filp->private_data;
425         struct drm_device *dev = file_priv->minor->dev;
426         int retcode = 0;
427
428         mutex_lock(&drm_global_mutex);
429
430         DRM_DEBUG("open_count = %d\n", dev->open_count);
431
432         if (dev->driver->preclose)
433                 dev->driver->preclose(dev, file_priv);
434
435         /* ========================================================
436          * Begin inline drm_release
437          */
438
439         DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
440                   task_pid_nr(current),
441                   (long)old_encode_dev(file_priv->minor->device),
442                   dev->open_count);
443
444         /* Release any auth tokens that might point to this file_priv,
445            (do that under the drm_global_mutex) */
446         if (file_priv->magic)
447                 (void) drm_remove_magic(file_priv->master, file_priv->magic);
448
449         /* if the master has gone away we can't do anything with the lock */
450         if (file_priv->minor->master)
451                 drm_master_release(dev, filp);
452
453         if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
454                 drm_core_reclaim_buffers(dev, file_priv);
455
456         drm_events_release(file_priv);
457
458         if (dev->driver->driver_features & DRIVER_MODESET)
459                 drm_fb_release(file_priv);
460
461         if (dev->driver->driver_features & DRIVER_GEM)
462                 drm_gem_release(dev, file_priv);
463
464         drm_legacy_ctxbitmap_release(dev, file_priv);
465
466         mutex_lock(&dev->struct_mutex);
467
468         if (file_priv->is_master) {
469                 struct drm_master *master = file_priv->master;
470                 struct drm_file *temp;
471                 list_for_each_entry(temp, &dev->filelist, lhead) {
472                         if ((temp->master == file_priv->master) &&
473                             (temp != file_priv))
474                                 temp->authenticated = 0;
475                 }
476
477                 /**
478                  * Since the master is disappearing, so is the
479                  * possibility to lock.
480                  */
481
482                 if (master->lock.hw_lock) {
483                         if (dev->sigdata.lock == master->lock.hw_lock)
484                                 dev->sigdata.lock = NULL;
485                         master->lock.hw_lock = NULL;
486                         master->lock.file_priv = NULL;
487                         wake_up_interruptible_all(&master->lock.lock_queue);
488                 }
489
490                 if (file_priv->minor->master == file_priv->master) {
491                         /* drop the reference held my the minor */
492                         if (dev->driver->master_drop)
493                                 dev->driver->master_drop(dev, file_priv, true);
494                         drm_master_put(&file_priv->minor->master);
495                 }
496         }
497
498         BUG_ON(dev->dev_mapping == NULL);
499         iput(container_of(dev->dev_mapping, struct inode, i_data));
500
501         /* drop the reference held my the file priv */
502         drm_master_put(&file_priv->master);
503         file_priv->is_master = 0;
504         list_del(&file_priv->lhead);
505         mutex_unlock(&dev->struct_mutex);
506
507         if (dev->driver->postclose)
508                 dev->driver->postclose(dev, file_priv);
509
510         if (drm_core_check_feature(dev, DRIVER_PRIME))
511                 drm_prime_destroy_file_private(&file_priv->prime);
512
513         put_pid(file_priv->pid);
514         kfree(file_priv);
515
516         /* ========================================================
517          * End inline drm_release
518          */
519
520         atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
521         if (!--dev->open_count) {
522                 if (atomic_read(&dev->ioctl_count)) {
523                         DRM_ERROR("Device busy: %d\n",
524                                   atomic_read(&dev->ioctl_count));
525                         retcode = -EBUSY;
526                 } else
527                         retcode = drm_lastclose(dev);
528                 if (drm_device_is_unplugged(dev))
529                         drm_put_dev(dev);
530         }
531         mutex_unlock(&drm_global_mutex);
532
533         return retcode;
534 }
535 EXPORT_SYMBOL(drm_release);
536
537 static bool
538 drm_dequeue_event(struct drm_file *file_priv,
539                   size_t total, size_t max, struct drm_pending_event **out)
540 {
541         struct drm_device *dev = file_priv->minor->dev;
542         struct drm_pending_event *e;
543         unsigned long flags;
544         bool ret = false;
545
546         spin_lock_irqsave(&dev->event_lock, flags);
547
548         *out = NULL;
549         if (list_empty(&file_priv->event_list))
550                 goto out;
551         e = list_first_entry(&file_priv->event_list,
552                              struct drm_pending_event, link);
553         if (e->event->length + total > max)
554                 goto out;
555
556         file_priv->event_space += e->event->length;
557         list_del(&e->link);
558         *out = e;
559         ret = true;
560
561 out:
562         spin_unlock_irqrestore(&dev->event_lock, flags);
563         return ret;
564 }
565
566 ssize_t drm_read(struct file *filp, char __user *buffer,
567                  size_t count, loff_t *offset)
568 {
569         struct drm_file *file_priv = filp->private_data;
570         struct drm_pending_event *e;
571         size_t total;
572         ssize_t ret;
573
574         ret = wait_event_interruptible(file_priv->event_wait,
575                                        !list_empty(&file_priv->event_list));
576         if (ret < 0)
577                 return ret;
578
579         total = 0;
580         while (drm_dequeue_event(file_priv, total, count, &e)) {
581                 if (copy_to_user(buffer + total,
582                                  e->event, e->event->length)) {
583                         total = -EFAULT;
584                         break;
585                 }
586
587                 total += e->event->length;
588                 e->destroy(e);
589         }
590
591         return total;
592 }
593 EXPORT_SYMBOL(drm_read);
594
595 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
596 {
597         struct drm_file *file_priv = filp->private_data;
598         unsigned int mask = 0;
599
600         poll_wait(filp, &file_priv->event_wait, wait);
601
602         if (!list_empty(&file_priv->event_list))
603                 mask |= POLLIN | POLLRDNORM;
604
605         return mask;
606 }
607 EXPORT_SYMBOL(drm_poll);