[Nouveau] [libdrm v2 07/14] nouveau: introduce object to represent the kernel client

Ben Skeggs skeggsb at gmail.com
Thu Nov 26 17:02:46 PST 2015


From: Ben Skeggs <bskeggs at 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 <bskeggs at 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



More information about the Nouveau mailing list