[Nouveau] [libdrm v2 04/14] nouveau: make it possible to init object in pre-allocated memory

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


From: Ben Skeggs <bskeggs at redhat.com>

Required for an upcoming patch, not exposed to library clients.

Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
---
 nouveau/nouveau.c | 64 +++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 8035c6a..eb741c7 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -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;
 	}
-- 
2.6.3



More information about the Nouveau mailing list