Logo Search packages:      
Sourcecode: linux version File versions  Download package

int drm_lastclose ( struct drm_device *  dev  ) 

Take down the DRM device.

Parameters:
dev DRM device structure.
Frees every resource in dev.

See also:
drm_device

Definition at line 133 of file drm_drv.c.

References drm_dma_takedown(), drm_irq_uninstall(), and drm_rmmap_locked().

Referenced by drm_cleanup(), and drm_release().

{
      struct drm_magic_entry *pt, *next;
      struct drm_map_list *r_list, *list_t;
      struct drm_vma_entry *vma, *vma_temp;
      int i;

      DRM_DEBUG("\n");

      if (dev->driver->lastclose)
            dev->driver->lastclose(dev);
      DRM_DEBUG("driver lastclose completed\n");

      if (dev->unique) {
            drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
            dev->unique = NULL;
            dev->unique_len = 0;
      }

      if (dev->irq_enabled)
            drm_irq_uninstall(dev);

      mutex_lock(&dev->struct_mutex);

      /* Free drawable information memory */
      drm_drawable_free_all(dev);
      del_timer(&dev->timer);

      /* Clear pid list */
      if (dev->magicfree.next) {
            list_for_each_entry_safe(pt, next, &dev->magicfree, head) {
                  list_del(&pt->head);
                  drm_ht_remove_item(&dev->magiclist, &pt->hash_item);
                  drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
            }
            drm_ht_remove(&dev->magiclist);
      }

      /* Clear AGP information */
      if (drm_core_has_AGP(dev) && dev->agp) {
            struct drm_agp_mem *entry, *tempe;

            /* Remove AGP resources, but leave dev->agp
               intact until drv_cleanup is called. */
            list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
                  if (entry->bound)
                        drm_unbind_agp(entry->memory);
                  drm_free_agp(entry->memory, entry->pages);
                  drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
            }
            INIT_LIST_HEAD(&dev->agp->memory);

            if (dev->agp->acquired)
                  drm_agp_release(dev);

            dev->agp->acquired = 0;
            dev->agp->enabled = 0;
      }
      if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
            drm_sg_cleanup(dev->sg);
            dev->sg = NULL;
      }

      /* Clear vma list (only built for debugging) */
      list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
            list_del(&vma->head);
            drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
      }

      list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
            drm_rmmap_locked(dev, r_list->map);
            r_list = NULL;
      }

      if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
            for (i = 0; i < dev->queue_count; i++) {
                  if (dev->queuelist[i]) {
                        drm_free(dev->queuelist[i],
                               sizeof(*dev->queuelist[0]),
                               DRM_MEM_QUEUES);
                        dev->queuelist[i] = NULL;
                  }
            }
            drm_free(dev->queuelist,
                   dev->queue_slots * sizeof(*dev->queuelist),
                   DRM_MEM_QUEUES);
            dev->queuelist = NULL;
      }
      dev->queue_count = 0;

      if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
            drm_dma_takedown(dev);

      if (dev->lock.hw_lock) {
            dev->sigdata.lock = dev->lock.hw_lock = NULL;   /* SHM removed */
            dev->lock.file_priv = NULL;
            wake_up_interruptible(&dev->lock.lock_queue);
      }
      mutex_unlock(&dev->struct_mutex);

      DRM_DEBUG("lastclose completed\n");
      return 0;
}


Generated by  Doxygen 1.6.0   Back to index