nouveau: introduce object to represent the kernel client

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>
main
Ben Skeggs 2015-11-24 10:33:56 +10:00
parent f6b1b5b7c9
commit b845d61de9
3 changed files with 55 additions and 0 deletions

View File

@ -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

View 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

View 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;