OSDN Git Service

nouveau: introduce object to represent the kernel client
authorBen Skeggs <bskeggs@redhat.com>
Tue, 24 Nov 2015 00:33:56 +0000 (10:33 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 22 Dec 2015 03:22:20 +0000 (13:22 +1000)
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 <bskeggs@redhat.com>
Tested-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
nouveau/nouveau-symbol-check
nouveau/nouveau.c
nouveau/nouveau.h

index 38b6ec5..e360b92 100755 (executable)
@@ -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
index 0017303..2b16351 100644 (file)
@@ -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
index 24cda6f..2287eba 100644 (file)
@@ -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;