diff options
author | Ben Skeggs | 2015-11-23 17:28:23 -0600 |
---|---|---|
committer | Ben Skeggs | 2015-12-21 21:22:10 -0600 |
commit | 343d1ee83e8bf833b575cc1df097d5202e11b8e8 (patch) | |
tree | 2629c09ecac05b825017025e4eb18a6ede14110c | |
parent | 0996ad0e12a25841f350b8c5cacccff3d0aa24d2 (diff) | |
download | external-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.c | 64 |
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 | ||
62 | int | 62 | static void |
63 | nouveau_object_new(struct nouveau_object *parent, uint64_t handle, | 63 | nouveau_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 | |||
73 | static int | ||
74 | nouveau_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 | |||
107 | int | ||
108 | nouveau_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 | } |