summaryrefslogtreecommitdiff
AgeCommit message (Expand)Author
2003-04-24Remove the ioctl_count variable from the device. A reference is held to theEric Anholt
2003-04-24Remove a bunch of dead code and fix spelling of a couple of comments.Eric Anholt
2003-04-24Single/dual rasterizer quiescence patch for the glint/gamma DRI driverDavid Dawes
2003-04-24break long lineDavid Dawes
2003-04-24Move one definition to drm_drv.h and remove the rest of drm_init.h whichEric Anholt
2003-04-24Remove DRM_DMA_HISTOGRAM and associated code.Eric Anholt
2003-04-24Make DRM(read) and DRM(poll) stubs and remove DRM(write) andEric Anholt
2003-04-23Install dummy/noop read & poll fops unless the driver has replacements.Keith Whitwell
2003-04-23deal correctly with read() from the DRM failingMichel Daenzer
2003-04-22get rid of superfluous fields in struct drm_radeon_ring_bufferMichel Daenzer
2003-04-22Remove AGP dependency in kernel config for radeon, sis. RemoveLeif Delgass
2003-04-22Only mga, i810, i830 require AGP (should mga define __MUST_HAVE_AGP?)Leif Delgass
2003-04-22change PREINSTALL/POSTINSTALL/UNINSTALL irq code to real functions as perAlan Hourihane
2003-04-22remove unused variableAlan Hourihane
2003-04-22fix gamma headersAlan Hourihane
2003-04-22Rename drm_lists.h to gamma_lists.hKeith Whitwell
2003-04-22new fileKeith Whitwell
2003-04-22Move the excitingly named DRM(flush_block_and_flush) and friends toKeith Whitwell
2003-04-22remove unused __HAVE_KERNEL_CTX_SWITCH codeKeith Whitwell
2003-04-22Move a chunk of gamma-specific code out of drm_dma.h. Remove unusedKeith Whitwell
2003-04-22remove unused dma histogram codeKeith Whitwell
2003-04-22Move a bunch of gamma-specific code into a gamma-specific file. Restore theKeith Whitwell
2003-04-22add more get_param queries for embedded projectKeith Whitwell
2003-04-22remove DRM read, poll and write_stringKeith Whitwell
2003-04-21Check for NULL map before calling DRM(ioremapfree) on cleanup. Prevents anLeif Delgass
2003-04-17Add a Kconfig file as used in recent 2.5.x kernels.David Dawes
2003-04-17Make Config.in look more like a recent 2.4.x kernel version.David Dawes
2003-04-17Rework the Linux drm kernel module build to leverage off the standardDavid Dawes
2003-04-17Bring some drm module changes over from the XFree86 trunk:David Dawes
2003-04-17Fix DRM module build on 2.5.41 and later kernels (tqueue -> workqueue).David Dawes
2003-04-10file drm_pci.h was initially added on branch mach64-0-0-5-branch.Jose Fonseca
2003-04-08file mach64_drv.c was initially added on branch mach64-0-0-6-branch.Eric Anholt
2003-04-08file Makefile was initially added on branch mach64-0-0-6-branch.Eric Anholt
2003-04-08file drm_linux_list.h was initially added on branch mach64-0-0-6-branch.Eric Anholt
2003-04-08Use list_entry() to get container struct from struct list_head pointers.Leif Delgass
2003-04-05add 'SG' map type identifier string (pci scatter/gather) to /proc vm infoLeif Delgass
2003-04-01Whitespace and remove a dead commented line.Eric Anholt
2003-03-31Warning fix (use %p format for filp)Leif Delgass
2003-03-30Spelling fixes in comments.Eric Anholt
2003-03-29Remove dead vma code and remove the unused devstate struct definition.Eric Anholt
2003-03-29Add DRMFILE definitions and supply filp for BSD in theEric Anholt
2003-03-29buf->filp is a pointer, so make printf format args be %p not %dEric Anholt
2003-03-28merged drm-filp-0-1-branchKeith Whitwell
2003-03-26Add 2nd arg for DRM_FREEKeith Whitwell
2003-03-25linux merge for drmAlan Hourihane
2003-03-25XFree86 4.3.0 mergeAlan Hourihane
2003-03-11Merge back from FreeBSD-current, adding FreeBSD ID tags to aid futureEric Anholt
2003-03-08Make dma_addr_t an unsigned long not a uint32, don't try to use memrangeEric Anholt
2003-03-06Remove the vbl signal code because it's untested (and has lock issues onEric Anholt
2003-03-05Put cdevsw initialization in line with FreeBSD-current. (From r1.10,r1.11Eric Anholt
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> */ #include "drmP.h" int drm_add_user_object(struct drm_file * priv, struct drm_user_object * item, int shareable) { struct drm_device *dev = priv->head->dev; int ret; DRM_ASSERT_LOCKED(&dev->struct_mutex); atomic_set(&item->refcount, 1); item->shareable = shareable; item->owner = priv; ret = drm_ht_just_insert_please(&dev->object_hash, &item->hash, (unsigned long)item, 32, 0, 0); if (ret) return ret; list_add_tail(&item->list, &priv->user_objects); return 0; } struct drm_user_object *drm_lookup_user_object(struct drm_file * priv, uint32_t key) { struct drm_device *dev = priv->head->dev; struct drm_hash_item *hash; int ret; struct drm_user_object *item; DRM_ASSERT_LOCKED(&dev->struct_mutex); ret = drm_ht_find_item(&dev->object_hash, key, &hash); if (ret) { return NULL; } item = drm_hash_entry(hash, struct drm_user_object, hash); if (priv != item->owner) { struct drm_open_hash *ht = &priv->refd_object_hash[_DRM_REF_USE]; ret = drm_ht_find_item(ht, (unsigned long)item, &hash); if (ret) { DRM_ERROR("Object not registered for usage\n"); return NULL; } } return item; } static void drm_deref_user_object(struct drm_file * priv, struct drm_user_object * item) { struct drm_device *dev = priv->head->dev; int ret; if (atomic_dec_and_test(&item->refcount)) { ret = drm_ht_remove_item(&dev->object_hash, &item->hash); BUG_ON(ret); list_del_init(&item->list); item->remove(priv, item); } } int drm_remove_user_object(struct drm_file * priv, struct drm_user_object * item) { DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); if (item->owner != priv) { DRM_ERROR("Cannot destroy object not owned by you.\n"); return -EINVAL; } item->owner = 0; item->shareable = 0; list_del_init(&item->list); drm_deref_user_object(priv, item); return 0; } static int drm_object_ref_action(struct drm_file * priv, struct drm_user_object * ro, enum drm_ref_type action) { int ret = 0; switch (action) { case _DRM_REF_USE: atomic_inc(&ro->refcount); break; default: if (!ro->ref_struct_locked) { break; } else { ro->ref_struct_locked(priv, ro, action); } } return ret; } int drm_add_ref_object(struct drm_file * priv, struct drm_user_object * referenced_object, enum drm_ref_type ref_action) { int ret = 0; struct drm_ref_object *item; struct drm_open_hash *ht = &priv->refd_object_hash[ref_action]; DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); if (!referenced_object->shareable && priv != referenced_object->owner) { DRM_ERROR("Not allowed to reference this object\n"); return -EINVAL; } /* * If this is not a usage reference, Check that usage has been registered * first. Otherwise strange things may happen on destruction. */ if ((ref_action != _DRM_REF_USE) && priv != referenced_object->owner) { item = drm_lookup_ref_object(priv, referenced_object, _DRM_REF_USE); if (!item) { DRM_ERROR ("Object not registered for usage by this client\n"); return -EINVAL; } } if (NULL != (item = drm_lookup_ref_object(priv, referenced_object, ref_action))) { atomic_inc(&item->refcount); return drm_object_ref_action(priv, referenced_object, ref_action); } item = drm_ctl_calloc(1, sizeof(*item), DRM_MEM_OBJECTS); if (item == NULL) { DRM_ERROR("Could not allocate reference object\n"); return -ENOMEM; } atomic_set(&item->refcount, 1); item->hash.key = (unsigned long)referenced_object; ret = drm_ht_insert_item(ht, &item->hash); item->unref_action = ref_action; if (ret) goto out; list_add(&item->list, &priv->refd_objects); ret = drm_object_ref_action(priv, referenced_object, ref_action); out: return ret; } struct drm_ref_object *drm_lookup_ref_object(struct drm_file * priv, struct drm_user_object * referenced_object, enum drm_ref_type ref_action) { struct drm_hash_item *hash; int ret; DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); ret = drm_ht_find_item(&priv->refd_object_hash[ref_action], (unsigned long)referenced_object, &hash); if (ret) return NULL; return drm_hash_entry(hash, struct drm_ref_object, hash); } static void drm_remove_other_references(struct drm_file * priv, struct drm_user_object * ro) { int i; struct drm_open_hash *ht; struct drm_hash_item *hash; struct drm_ref_object *item; for (i = _DRM_REF_USE + 1; i < _DRM_NO_REF_TYPES; ++i) { ht = &priv->refd_object_hash[i]; while (!drm_ht_find_item(ht, (unsigned long)ro, &hash)) { item = drm_hash_entry(hash, struct drm_ref_object, hash); drm_remove_ref_object(priv, item); } } } void drm_remove_ref_object(struct drm_file * priv, struct drm_ref_object * item) { int ret; struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key; struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action]; enum drm_ref_type unref_action; DRM_ASSERT_LOCKED(&priv->head->dev->struct_mutex); unref_action = item->unref_action; if (atomic_dec_and_test(&item->refcount)) { ret = drm_ht_remove_item(ht, &item->hash); BUG_ON(ret); list_del_init(&item->list); if (unref_action == _DRM_REF_USE) drm_remove_other_references(priv, user_object); drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS); } switch (unref_action) { case _DRM_REF_USE: drm_deref_user_object(priv, user_object); break; default: BUG_ON(!user_object->unref); user_object->unref(priv, user_object, unref_action); break; } } int drm_user_object_ref(struct drm_file * priv, uint32_t user_token, enum drm_object_type type, struct drm_user_object ** object) { struct drm_device *dev = priv->head->dev; struct drm_user_object *uo; struct drm_hash_item *hash; int ret; mutex_lock(&dev->struct_mutex); ret = drm_ht_find_item(&dev->object_hash, user_token, &hash); if (ret) { DRM_ERROR("Could not find user object to reference.\n"); goto out_err; } uo = drm_hash_entry(hash, struct drm_user_object, hash); if (uo->type != type) { ret = -EINVAL; goto out_err; } ret = drm_add_ref_object(priv, uo, _DRM_REF_USE); if (ret) goto out_err; mutex_unlock(&dev->struct_mutex); *object = uo; return 0; out_err: mutex_unlock(&dev->struct_mutex); return ret; } int drm_user_object_unref(struct drm_file * priv, uint32_t user_token, enum drm_object_type type) { struct drm_device *dev = priv->head->dev; struct drm_user_object *uo; struct drm_ref_object *ro; int ret; mutex_lock(&dev->struct_mutex); uo = drm_lookup_user_object(priv, user_token); if (!uo || (uo->type != type)) { ret = -EINVAL; goto out_err; } ro = drm_lookup_ref_object(priv, uo, _DRM_REF_USE); if (!ro) { ret = -EINVAL; goto out_err; } drm_remove_ref_object(priv, ro); mutex_unlock(&dev->struct_mutex); return 0; out_err: mutex_unlock(&dev->struct_mutex); return ret; }