diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-03-26 22:40:07 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-03-26 22:40:07 +0000 |
commit | 85c8218e99687c48bae95db5a7c94dd609cdceae (patch) | |
tree | 44a38805cc2e1903a5654f791b0feb096086ac87 /sys/dev/pci/drm/drm_drv.c | |
parent | b9f76961c20db5cb675a565ea0ac95751d792354 (diff) |
Rework how we deal with the list of per-open datastructures, and the
auth list. now we only need the one tree. Makes things a little neater,
and smaller.
Diffstat (limited to 'sys/dev/pci/drm/drm_drv.c')
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 155 |
1 files changed, 108 insertions, 47 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 04d7eb1ed90..7e6a7821c40 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -57,7 +57,12 @@ int drm_activate(struct device *, enum devact); int drmprint(void *, const char *); int drm_getunique(struct drm_device *, void *, struct drm_file *); +int drm_version(struct drm_device *, void *, struct drm_file *); int drm_setversion(struct drm_device *, void *, struct drm_file *); +int drm_getmagic(struct drm_device *, void *, struct drm_file *); +int drm_authmagic(struct drm_device *, void *, struct drm_file *); +int drm_file_cmp(struct drm_file *, struct drm_file *); +SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp); /* * attach drm to a pci-based driver. @@ -137,7 +142,7 @@ drm_attach(struct device *parent, struct device *self, void *aux) mtx_init(&dev->lock.spinlock, IPL_NONE); TAILQ_INIT(&dev->maplist); - TAILQ_INIT(&dev->files); + SPLAY_INIT(&dev->files); if (dev->driver->vblank_pipes != 0 && drm_vblank_init(dev, dev->driver->vblank_pipes)) { @@ -249,17 +254,21 @@ drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist) return NULL; } +int +drm_file_cmp(struct drm_file *f1, struct drm_file *f2) +{ + return (f1->minor < f2->minor ? -1 : f1->minor > f2->minor); +} + +SPLAY_GENERATE(drm_file_tree, drm_file, link, drm_file_cmp); + struct drm_file * drm_find_file_by_minor(struct drm_device *dev, int minor) { - struct drm_file *priv; - - DRM_SPINLOCK_ASSERT(&dev->dev_lock); + struct drm_file key; - TAILQ_FOREACH(priv, &dev->files, link) - if (priv->minor == minor) - break; - return (priv); + key.minor = minor; + return (SPLAY_FIND(drm_file_tree, &dev->files, &key)); } int @@ -284,7 +293,6 @@ drm_firstopen(struct drm_device *dev) } dev->magicid = 1; - SPLAY_INIT(&dev->magiclist); dev->irq_enabled = 0; dev->if_version = 0; @@ -299,7 +307,6 @@ drm_firstopen(struct drm_device *dev) int drm_lastclose(struct drm_device *dev) { - struct drm_magic_entry *pt; drm_local_map_t *map, *mapsave; DRM_DEBUG("\n"); @@ -314,12 +321,6 @@ drm_lastclose(struct drm_device *dev) drm_dma_takedown(dev); DRM_LOCK(); - /* Clear pid list */ - while ((pt = SPLAY_ROOT(&dev->magiclist)) != NULL) { - SPLAY_REMOVE(drm_magic_tree, &dev->magiclist, pt); - drm_free(pt); - } - if (dev->sg != NULL) { struct drm_sg_mem *sg = dev->sg; dev->sg = NULL; @@ -332,7 +333,7 @@ drm_lastclose(struct drm_device *dev) for (map = TAILQ_FIRST(&dev->maplist); map != TAILQ_END(&dev->maplist); map = mapsave) { mapsave = TAILQ_NEXT(map, link); - if (!(map->flags & _DRM_DRIVER)) + if ((map->flags & _DRM_DRIVER) == 0) drm_rmmap_locked(dev, map); } @@ -347,32 +348,6 @@ drm_lastclose(struct drm_device *dev) } int -drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_version *version = data; - int len; - -#define DRM_COPY(name, value) \ - len = strlen( value ); \ - if ( len > name##_len ) len = name##_len; \ - name##_len = strlen( value ); \ - if ( len && name ) { \ - if ( DRM_COPY_TO_USER( name, value, len ) ) \ - return EFAULT; \ - } - - version->version_major = dev->driver->major; - version->version_minor = dev->driver->minor; - version->version_patchlevel = dev->driver->patchlevel; - - DRM_COPY(version->name, dev->driver->name); - DRM_COPY(version->date, dev->driver->date); - DRM_COPY(version->desc, dev->driver->desc); - - return 0; -} - -int drmopen(dev_t kdev, int flags, int fmt, struct proc *p) { struct drm_device *dev = NULL; @@ -422,15 +397,15 @@ drmopen(dev_t kdev, int flags, int fmt, struct proc *p) DRM_LOCK(); /* first opener automatically becomes master if root */ - if (TAILQ_EMPTY(&dev->files) && !DRM_SUSER(p)) { + if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) { DRM_UNLOCK(); ret = EPERM; goto free_priv; } - priv->master = TAILQ_EMPTY(&dev->files); + priv->master = SPLAY_EMPTY(&dev->files); - TAILQ_INSERT_TAIL(&dev->files, priv, link); + SPLAY_INSERT(drm_file_tree, &dev->files, priv); DRM_UNLOCK(); return (0); @@ -516,7 +491,7 @@ drmclose(dev_t kdev, int flags, int fmt, struct proc *p) dev->buf_pgid = 0; DRM_LOCK(); - TAILQ_REMOVE(&dev->files, file_priv, link); + SPLAY_REMOVE(drm_file_tree, &dev->files, file_priv); drm_free(file_priv); done: @@ -817,6 +792,32 @@ drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) #define DRM_IF_MINOR 2 int +drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_version *version = data; + int len; + +#define DRM_COPY(name, value) \ + len = strlen( value ); \ + if ( len > name##_len ) len = name##_len; \ + name##_len = strlen( value ); \ + if ( len && name ) { \ + if ( DRM_COPY_TO_USER( name, value, len ) ) \ + return EFAULT; \ + } + + version->version_major = dev->driver->major; + version->version_minor = dev->driver->minor; + version->version_patchlevel = dev->driver->patchlevel; + + DRM_COPY(version->name, dev->driver->name); + DRM_COPY(version->date, dev->driver->date); + DRM_COPY(version->desc, dev->driver->desc); + + return 0; +} + +int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_set_version ver, *sv = data; @@ -915,3 +916,63 @@ drm_dmamem_free(bus_dma_tag_t dmat, struct drm_dmamem *mem) bus_dmamap_destroy(dmat, mem->map); free(mem, M_DRM); } + +/** + * Called by the client, this returns a unique magic number to be authorized + * by the master. + * + * The master may use its own knowledge of the client (such as the X + * connection that the magic is passed over) to determine if the magic number + * should be authenticated. + */ +int +drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_auth *auth = data; + + if (dev->magicid == 0) + dev->magicid = 1; + + /* Find unique magic */ + if (file_priv->magic) { + auth->magic = file_priv->magic; + } else { + DRM_LOCK(); + file_priv->magic = auth->magic = dev->magicid++; + DRM_UNLOCK(); + DRM_DEBUG("%d\n", auth->magic); + } + + DRM_DEBUG("%u\n", auth->magic); + + return (0); +} + +/** + * Marks the client associated with the given magic number as authenticated. + */ +int +drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) +{ + struct drm_file *p; + struct drm_auth *auth = data; + int ret = EINVAL; + + DRM_DEBUG("%u\n", auth->magic); + + if (auth->magic == 0) + return (ret); + + DRM_LOCK(); + SPLAY_FOREACH(p, drm_file_tree, &dev->files) { + if (p->magic == auth->magic) { + p->authenticated = 1; + p->magic = 0; + ret = 0; + break; + } + } + DRM_UNLOCK(); + + return (ret); +} |