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.4 _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau