summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs2015-11-23 17:28:23 -0600
committerBen Skeggs2015-12-21 21:22:10 -0600
commit343d1ee83e8bf833b575cc1df097d5202e11b8e8 (patch)
tree2629c09ecac05b825017025e4eb18a6ede14110c
parent0996ad0e12a25841f350b8c5cacccff3d0aa24d2 (diff)
downloadexternal-libdrm-343d1ee83e8bf833b575cc1df097d5202e11b8e8.tar.gz
external-libdrm-343d1ee83e8bf833b575cc1df097d5202e11b8e8.tar.xz
external-libdrm-343d1ee83e8bf833b575cc1df097d5202e11b8e8.zip
nouveau: make it possible to init object in pre-allocated memory
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>
-rw-r--r--nouveau/nouveau.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 8035c6a0..eb741c7d 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -59,31 +59,63 @@ debug_init(char *args)
59} 59}
60#endif 60#endif
61 61
62int 62static void
63nouveau_object_new(struct nouveau_object *parent, uint64_t handle, 63nouveau_object_fini(struct nouveau_object *obj)
64 uint32_t oclass, void *data, uint32_t length, 64{
65 struct nouveau_object **pobj) 65 if (obj->data) {
66 abi16_delete(obj);
67 free(obj->data);
68 obj->data = NULL;
69 return;
70 }
71}
72
73static int
74nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
75 int32_t oclass, void *data, uint32_t size,
76 struct nouveau_object *obj)
66{ 77{
67 struct nouveau_object *obj;
68 int (*func)(struct nouveau_object *); 78 int (*func)(struct nouveau_object *);
69 int ret = -EINVAL; 79 int ret = -ENOSYS;
70 80
71 if (length == 0)
72 length = sizeof(struct nouveau_object *);
73 obj = malloc(sizeof(*obj) + length);
74 obj->parent = parent; 81 obj->parent = parent;
75 obj->handle = handle; 82 obj->handle = handle;
76 obj->oclass = oclass; 83 obj->oclass = oclass;
77 obj->length = length; 84 obj->length = 0;
78 obj->data = obj + 1; 85 obj->data = NULL;
79 if (data)
80 memcpy(obj->data, data, length);
81 *(struct nouveau_object **)obj->data = obj;
82 86
83 abi16_object(obj, &func); 87 abi16_object(obj, &func);
84 if (func) 88 if (func) {
89 obj->length = size ? size : sizeof(struct nouveau_object *);
90 if (!(obj->data = malloc(obj->length)))
91 return -ENOMEM;
92 if (data)
93 memcpy(obj->data, data, obj->length);
94 *(struct nouveau_object **)obj->data = obj;
95
85 ret = func(obj); 96 ret = func(obj);
97 }
98
99 if (ret) {
100 nouveau_object_fini(obj);
101 return ret;
102 }
103
104 return 0;
105}
106
107int
108nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
109 uint32_t oclass, void *data, uint32_t length,
110 struct nouveau_object **pobj)
111{
112 struct nouveau_object *obj;
113 int ret;
114
115 if (!(obj = malloc(sizeof(*obj))))
116 return -ENOMEM;
86 117
118 ret = nouveau_object_init(parent, handle, oclass, data, length, obj);
87 if (ret) { 119 if (ret) {
88 free(obj); 120 free(obj);
89 return ret; 121 return ret;
@@ -98,7 +130,7 @@ nouveau_object_del(struct nouveau_object **pobj)
98{ 130{
99 struct nouveau_object *obj = *pobj; 131 struct nouveau_object *obj = *pobj;
100 if (obj) { 132 if (obj) {
101 abi16_delete(obj); 133 nouveau_object_fini(obj);
102 free(obj); 134 free(obj);
103 *pobj = NULL; 135 *pobj = NULL;
104 } 136 }