From: Ben Skeggs <bske...@redhat.com>

Because NVIF intentionally lacks some of the paths necessary to be
compatible with various mistakes we've made over the years, libdrm
needs to know whether a client has been updated and that it's safe
to make use of the new kernel interfaces.

Clients still using nouveau_device_open()/wrap() will be forced to
make use of ABI16 instead of NVIF.

v2.
- remove lib_version, nothing used it
- leave client-provided pointer unmodified on failure

Signed-off-by: Ben Skeggs <bske...@redhat.com>
---
 nouveau/nouveau-symbol-check |  2 ++
 nouveau/nouveau.c            | 35 +++++++++++++++++++++++++++++++++++
 nouveau/nouveau.h            | 18 ++++++++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 38b6ec5..e360b92 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -30,6 +30,8 @@ nouveau_device_del
 nouveau_device_open
 nouveau_device_open_existing
 nouveau_device_wrap
+nouveau_drm_del
+nouveau_drm_new
 nouveau_getparam
 nouveau_object_del
 nouveau_object_find
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 0017303..2b16351 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -195,6 +195,41 @@ nouveau_object_find(struct nouveau_object *obj, uint32_t 
pclass)
        return obj;
 }
 
+void
+nouveau_drm_del(struct nouveau_drm **pdrm)
+{
+       free(*pdrm);
+       *pdrm = NULL;
+}
+
+int
+nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
+{
+       struct nouveau_drm *drm;
+       drmVersionPtr ver;
+
+#ifdef DEBUG
+       debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
+#endif
+
+       if (!(drm = calloc(1, sizeof(*drm))))
+               return -ENOMEM;
+       drm->fd = fd;
+
+       if (!(ver = drmGetVersion(fd))) {
+               nouveau_drm_del(&drm);
+               return -EINVAL;
+       }
+       *pdrm = drm;
+
+       drm->version = (ver->version_major << 24) |
+                      (ver->version_minor << 8) |
+                       ver->version_patchlevel;
+       drm->nvif = false;
+       drmFreeVersion(ver);
+       return 0;
+}
+
 /* this is the old libdrm's version of nouveau_device_wrap(), the symbol
  * is kept here to prevent AIGLX from crashing if the DDX is linked against
  * the new libdrm, but the DRI driver against the old
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index 24cda6f..2287eba 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -22,6 +22,24 @@ struct nouveau_object {
        void *data;
 };
 
+struct nouveau_drm {
+       struct nouveau_object client;
+       int fd;
+       uint32_t version;
+       bool nvif;
+};
+
+static inline struct nouveau_drm *
+nouveau_drm(struct nouveau_object *obj)
+{
+       while (obj && obj->parent)
+               obj = obj->parent;
+       return (struct nouveau_drm *)obj;
+}
+
+int nouveau_drm_new(int fd, struct nouveau_drm **);
+void nouveau_drm_del(struct nouveau_drm **);
+
 struct nouveau_fifo {
        struct nouveau_object *object;
        uint32_t channel;
-- 
2.6.3

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to