diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:15 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:40:32 +1000 |
commit | a01ca78c8f118e5a24f1527ecf078ab56ddd4805 (patch) | |
tree | 34ccaf8913fcdf3a9be2794b27a30a52e8449bb0 /drivers/gpu/drm/nouveau/nvif/object.c | |
parent | 4e7e62d607a711bc8e8576a0fc7d8f242d25c9b3 (diff) | |
download | op-kernel-dev-a01ca78c8f118e5a24f1527ecf078ab56ddd4805.zip op-kernel-dev-a01ca78c8f118e5a24f1527ecf078ab56ddd4805.tar.gz |
drm/nouveau/nvif: simplify and tidy library interfaces
A variety of tweaks to the NVIF library interfaces, mostly ripping out
things that turned out to be not so useful.
- Removed refcounting from nvif_object, callers are expected to not be
stupid instead.
- nvif_client is directly reachable from anything derived from nvif_object,
removing the need for heuristics to locate it
- _new() versions of interfaces, that allocate memory for the object
they construct, have been removed. The vast majority of callers used
the embedded _init() interfaces.
- No longer storing constructor arguments (and the data returned from
nvkm) inside nvif_object, it's more or less unused and just wastes
memory.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvif/object.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/object.c | 135 |
1 files changed, 41 insertions, 94 deletions
diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index 3ab4e2f..a727f72 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -30,7 +30,7 @@ int nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; union { struct nvif_ioctl_v0 v0; } *args = data; @@ -47,7 +47,8 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) } else return -ENOSYS; - return client->driver->ioctl(client->base.priv, client->super, data, size, hack); + return client->driver->ioctl(client->object.priv, client->super, + data, size, hack); } int @@ -145,7 +146,7 @@ void nvif_object_unmap(struct nvif_object *object) { if (object->map.size) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; struct { struct nvif_ioctl_v0 ioctl; struct nvif_ioctl_unmap unmap; @@ -167,7 +168,7 @@ nvif_object_unmap(struct nvif_object *object) int nvif_object_map(struct nvif_object *object) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; struct { struct nvif_ioctl_v0 ioctl; struct nvif_ioctl_map_v0 map; @@ -186,119 +187,65 @@ nvif_object_map(struct nvif_object *object) return ret; } -struct ctor { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_new_v0 new; -}; - void nvif_object_fini(struct nvif_object *object) { - struct ctor *ctor = container_of(object->data, typeof(*ctor), new.data); - if (object->parent) { - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_del del; - } args = { - .ioctl.type = NVIF_IOCTL_V0_DEL, - }; + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_del del; + } args = { + .ioctl.type = NVIF_IOCTL_V0_DEL, + }; - nvif_object_unmap(object); - nvif_object_ioctl(object, &args, sizeof(args), NULL); - if (object->data) { - object->size = 0; - object->data = NULL; - kfree(ctor); - } - nvif_object_ref(NULL, &object->parent); - } + if (!object->client) + return; + + nvif_object_unmap(object); + nvif_object_ioctl(object, &args, sizeof(args), NULL); + object->client = NULL; } int -nvif_object_init(struct nvif_object *parent, void (*dtor)(struct nvif_object *), - u32 handle, u32 oclass, void *data, u32 size, - struct nvif_object *object) +nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass, + void *data, u32 size, struct nvif_object *object) { - struct ctor *ctor; + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_new_v0 new; + } *args; int ret = 0; - object->parent = NULL; - object->object = object; - nvif_object_ref(parent, &object->parent); - kref_init(&object->refcount); + object->client = NULL; + object->parent = parent; object->handle = handle; object->oclass = oclass; - object->data = NULL; - object->size = 0; - object->dtor = dtor; object->map.ptr = NULL; object->map.size = 0; if (object->parent) { - if (!(ctor = kmalloc(sizeof(*ctor) + size, GFP_KERNEL))) { + if (!(args = kmalloc(sizeof(*args) + size, GFP_KERNEL))) { nvif_object_fini(object); return -ENOMEM; } - object->data = ctor->new.data; - object->size = size; - memcpy(object->data, data, size); - ctor->ioctl.version = 0; - ctor->ioctl.type = NVIF_IOCTL_V0_NEW; - ctor->new.version = 0; - ctor->new.route = NVIF_IOCTL_V0_ROUTE_NVIF; - ctor->new.token = (unsigned long)(void *)object; - ctor->new.handle = handle; - ctor->new.oclass = oclass; - - ret = nvif_object_ioctl(parent, ctor, sizeof(*ctor) + - object->size, &object->priv); + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_NEW; + args->new.version = 0; + args->new.route = parent->client->route; + args->new.token = (unsigned long)(void *)object; + args->new.handle = handle; + args->new.oclass = oclass; + + memcpy(args->new.data, data, size); + ret = nvif_object_ioctl(parent, args, sizeof(*args) + size, + &object->priv); + memcpy(data, args->new.data, size); + kfree(args); + if (ret == 0) + object->client = parent->client; } if (ret) nvif_object_fini(object); return ret; } - -static void -nvif_object_del(struct nvif_object *object) -{ - nvif_object_fini(object); - kfree(object); -} - -int -nvif_object_new(struct nvif_object *parent, u32 handle, u32 oclass, - void *data, u32 size, struct nvif_object **pobject) -{ - struct nvif_object *object = kzalloc(sizeof(*object), GFP_KERNEL); - if (object) { - int ret = nvif_object_init(parent, nvif_object_del, handle, - oclass, data, size, object); - if (ret) { - kfree(object); - object = NULL; - } - *pobject = object; - return ret; - } - return -ENOMEM; -} - -static void -nvif_object_put(struct kref *kref) -{ - struct nvif_object *object = - container_of(kref, typeof(*object), refcount); - object->dtor(object); -} - -void -nvif_object_ref(struct nvif_object *object, struct nvif_object **pobject) -{ - if (object) - kref_get(&object->refcount); - if (*pobject) - kref_put(&(*pobject)->refcount, nvif_object_put); - *pobject = object; -} |