OSDN Git Service

nouveau: make it possible to init object in pre-allocated memory
authorBen Skeggs <bskeggs@redhat.com>
Mon, 23 Nov 2015 23:28:23 +0000 (09:28 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 22 Dec 2015 03:22:10 +0000 (13:22 +1000)
Required for an upcoming patch, not exposed to library clients.

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.c

index 8035c6a..eb741c7 100644 (file)
@@ -59,31 +59,63 @@ debug_init(char *args)
 }
 #endif
 
-int
-nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
-                  uint32_t oclass, void *data, uint32_t length,
-                  struct nouveau_object **pobj)
+static void
+nouveau_object_fini(struct nouveau_object *obj)
+{
+       if (obj->data) {
+               abi16_delete(obj);
+               free(obj->data);
+               obj->data = NULL;
+               return;
+       }
+}
+
+static int
+nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
+                   int32_t oclass, void *data, uint32_t size,
+                   struct nouveau_object *obj)
 {
-       struct nouveau_object *obj;
        int (*func)(struct nouveau_object *);
-       int ret = -EINVAL;
+       int ret = -ENOSYS;
 
-       if (length == 0)
-               length = sizeof(struct nouveau_object *);
-       obj = malloc(sizeof(*obj) + length);
        obj->parent = parent;
        obj->handle = handle;
        obj->oclass = oclass;
-       obj->length = length;
-       obj->data = obj + 1;
-       if (data)
-               memcpy(obj->data, data, length);
-       *(struct nouveau_object **)obj->data = obj;
+       obj->length = 0;
+       obj->data = NULL;
 
        abi16_object(obj, &func);
-       if (func)
+       if (func) {
+               obj->length = size ? size : sizeof(struct nouveau_object *);
+               if (!(obj->data = malloc(obj->length)))
+                       return -ENOMEM;
+               if (data)
+                       memcpy(obj->data, data, obj->length);
+               *(struct nouveau_object **)obj->data = obj;
+
                ret = func(obj);
+       }
+
+       if (ret) {
+               nouveau_object_fini(obj);
+               return ret;
+       }
+
+       return 0;
+}
+
+int
+nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
+                  uint32_t oclass, void *data, uint32_t length,
+                  struct nouveau_object **pobj)
+{
+       struct nouveau_object *obj;
+       int ret;
+
+       if (!(obj = malloc(sizeof(*obj))))
+               return -ENOMEM;
 
+       ret = nouveau_object_init(parent, handle, oclass, data, length, obj);
        if (ret) {
                free(obj);
                return ret;
@@ -98,7 +130,7 @@ nouveau_object_del(struct nouveau_object **pobj)
 {
        struct nouveau_object *obj = *pobj;
        if (obj) {
-               abi16_delete(obj);
+               nouveau_object_fini(obj);
                free(obj);
                *pobj = NULL;
        }