* [libdrm v2 02/14] nouveau: move more abi16-specific logic into abi16.c
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 03/14] nouveau: move object functions up, to avoid future foward decls Ben Skeggs
` (11 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
v2.
- add a comment about the (ab)use of nouveau_object::length
- add a comment about abi16_object() return values
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/abi16.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
nouveau/nouveau.c | 56 +++++++----------------------------------------
nouveau/private.h | 7 ++----
3 files changed, 70 insertions(+), 58 deletions(-)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index 59bc436..615aea2 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -33,7 +33,7 @@
#include "private.h"
-drm_private int
+static int
abi16_chan_nv04(struct nouveau_object *obj)
{
struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
@@ -57,7 +57,7 @@ abi16_chan_nv04(struct nouveau_object *obj)
return 0;
}
-drm_private int
+static int
abi16_chan_nvc0(struct nouveau_object *obj)
{
struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
@@ -78,7 +78,7 @@ abi16_chan_nvc0(struct nouveau_object *obj)
return 0;
}
-drm_private int
+static int
abi16_chan_nve0(struct nouveau_object *obj)
{
struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
@@ -104,7 +104,7 @@ abi16_chan_nve0(struct nouveau_object *obj)
return 0;
}
-drm_private int
+static int
abi16_engobj(struct nouveau_object *obj)
{
struct drm_nouveau_grobj_alloc req = {
@@ -125,7 +125,7 @@ abi16_engobj(struct nouveau_object *obj)
return 0;
}
-drm_private int
+static int
abi16_ntfy(struct nouveau_object *obj)
{
struct nv04_notify *ntfy = obj->data;
@@ -149,6 +149,61 @@ abi16_ntfy(struct nouveau_object *obj)
}
drm_private void
+abi16_delete(struct nouveau_object *obj)
+{
+ struct nouveau_device *dev =
+ nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
+ struct drm_nouveau_channel_free req;
+ req.channel = obj->handle;
+ drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE,
+ &req, sizeof(req));
+ } else {
+ struct drm_nouveau_gpuobj_free req;
+ req.channel = obj->parent->handle;
+ req.handle = obj->handle;
+ drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
+ &req, sizeof(req));
+ }
+}
+
+drm_private bool
+abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *))
+{
+ struct nouveau_object *parent = obj->parent;
+
+ /* nouveau_object::length is (ab)used to determine whether the
+ * object is a legacy object (!=0), or a real NVIF object.
+ */
+ if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS)) {
+ if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
+ struct nouveau_device *dev = (void *)parent;
+ if (dev->chipset < 0xc0)
+ *func = abi16_chan_nv04;
+ else
+ if (dev->chipset < 0xe0)
+ *func = abi16_chan_nvc0;
+ else
+ *func = abi16_chan_nve0;
+ return true;
+ }
+ } else
+ if ((parent->length != 0 &&
+ parent->oclass == NOUVEAU_FIFO_CHANNEL_CLASS)) {
+ if (obj->oclass == NOUVEAU_NOTIFIER_CLASS) {
+ *func = abi16_ntfy;
+ return true;
+ }
+
+ *func = abi16_engobj;
+ return false; /* try NVIF, if supported, before calling func */
+ }
+
+ *func = NULL;
+ return false;
+}
+
+drm_private void
abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 97fd77b..8a0be2f 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -135,6 +135,7 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
nvdev->gart_limit_percent = 80;
DRMINITLISTHEAD(&nvdev->bo_list);
nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
+ nvdev->base.object.length = ~0;
nvdev->base.lib_version = 0x01000000;
nvdev->base.chipset = chipset;
nvdev->base.vram_size = vram;
@@ -251,8 +252,8 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
uint32_t oclass, void *data, uint32_t length,
struct nouveau_object **pobj)
{
- struct nouveau_device *dev;
struct nouveau_object *obj;
+ int (*func)(struct nouveau_object *);
int ret = -EINVAL;
if (length == 0)
@@ -267,37 +268,9 @@ nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
memcpy(obj->data, data, length);
*(struct nouveau_object **)obj->data = obj;
- dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
- switch (parent->oclass) {
- case NOUVEAU_DEVICE_CLASS:
- switch (obj->oclass) {
- case NOUVEAU_FIFO_CHANNEL_CLASS:
- {
- if (dev->chipset < 0xc0)
- ret = abi16_chan_nv04(obj);
- else
- if (dev->chipset < 0xe0)
- ret = abi16_chan_nvc0(obj);
- else
- ret = abi16_chan_nve0(obj);
- }
- break;
- default:
- break;
- }
- break;
- case NOUVEAU_FIFO_CHANNEL_CLASS:
- switch (obj->oclass) {
- case NOUVEAU_NOTIFIER_CLASS:
- ret = abi16_ntfy(obj);
- break;
- default:
- ret = abi16_engobj(obj);
- break;
- }
- default:
- break;
- }
+ abi16_object(obj, &func);
+ if (func)
+ ret = func(obj);
if (ret) {
free(obj);
@@ -312,24 +285,11 @@ void
nouveau_object_del(struct nouveau_object **pobj)
{
struct nouveau_object *obj = *pobj;
- struct nouveau_device *dev;
if (obj) {
- dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
- if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
- struct drm_nouveau_channel_free req;
- req.channel = obj->handle;
- drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE,
- &req, sizeof(req));
- } else {
- struct drm_nouveau_gpuobj_free req;
- req.channel = obj->parent->handle;
- req.handle = obj->handle;
- drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
- &req, sizeof(req));
- }
+ abi16_delete(obj);
+ free(obj);
+ *pobj = NULL;
}
- free(obj);
- *pobj = NULL;
}
void *
diff --git a/nouveau/private.h b/nouveau/private.h
index e9439f3..5f352a4 100644
--- a/nouveau/private.h
+++ b/nouveau/private.h
@@ -114,11 +114,8 @@ int
nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t);
/* abi16.c */
-drm_private int abi16_chan_nv04(struct nouveau_object *);
-drm_private int abi16_chan_nvc0(struct nouveau_object *);
-drm_private int abi16_chan_nve0(struct nouveau_object *);
-drm_private int abi16_engobj(struct nouveau_object *);
-drm_private int abi16_ntfy(struct nouveau_object *);
+drm_private bool abi16_object(struct nouveau_object *, int (**)(struct nouveau_object *));
+drm_private void abi16_delete(struct nouveau_object *);
drm_private void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *);
drm_private int abi16_bo_init(struct nouveau_bo *, uint32_t alignment,
union nouveau_bo_config *);
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 03/14] nouveau: move object functions up, to avoid future foward decls
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-11-27 1:02 ` [libdrm v2 02/14] nouveau: move more abi16-specific logic into abi16.c Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 04/14] nouveau: make it possible to init object in pre-allocated memory Ben Skeggs
` (10 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau.c | 112 +++++++++++++++++++++++++++---------------------------
1 file changed, 56 insertions(+), 56 deletions(-)
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 8a0be2f..8035c6a 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -59,6 +59,62 @@ 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)
+{
+ struct nouveau_object *obj;
+ int (*func)(struct nouveau_object *);
+ int ret = -EINVAL;
+
+ 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;
+
+ abi16_object(obj, &func);
+ if (func)
+ ret = func(obj);
+
+ if (ret) {
+ free(obj);
+ return ret;
+ }
+
+ *pobj = obj;
+ return 0;
+}
+
+void
+nouveau_object_del(struct nouveau_object **pobj)
+{
+ struct nouveau_object *obj = *pobj;
+ if (obj) {
+ abi16_delete(obj);
+ free(obj);
+ *pobj = NULL;
+ }
+}
+
+void *
+nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
+{
+ while (obj && obj->oclass != pclass) {
+ obj = obj->parent;
+ if (pclass == NOUVEAU_PARENT_CLASS)
+ break;
+ }
+ return obj;
+}
+
/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
* is kept here to prevent AIGLX from crashing if the DDX is linked against
* the new libdrm, but the DRI driver against the old
@@ -247,62 +303,6 @@ nouveau_client_del(struct nouveau_client **pclient)
}
}
-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 (*func)(struct nouveau_object *);
- int ret = -EINVAL;
-
- 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;
-
- abi16_object(obj, &func);
- if (func)
- ret = func(obj);
-
- if (ret) {
- free(obj);
- return ret;
- }
-
- *pobj = obj;
- return 0;
-}
-
-void
-nouveau_object_del(struct nouveau_object **pobj)
-{
- struct nouveau_object *obj = *pobj;
- if (obj) {
- abi16_delete(obj);
- free(obj);
- *pobj = NULL;
- }
-}
-
-void *
-nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
-{
- while (obj && obj->oclass != pclass) {
- obj = obj->parent;
- if (pclass == NOUVEAU_PARENT_CLASS)
- break;
- }
- return obj;
-}
-
static void
nouveau_bo_del(struct nouveau_bo *bo)
{
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 04/14] nouveau: make it possible to init object in pre-allocated memory
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-11-27 1:02 ` [libdrm v2 02/14] nouveau: move more abi16-specific logic into abi16.c Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 03/14] nouveau: move object functions up, to avoid future foward decls Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 05/14] nouveau: add interface to call an object's methods Ben Skeggs
` (9 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Required for an upcoming patch, not exposed to library clients.
Signed-off-by: Ben Skeggs <bskeggs@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
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 05/14] nouveau: add interface to call an object's methods
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (2 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 04/14] nouveau: make it possible to init object in pre-allocated memory Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 06/14] nouveau: add interfaces to query information about supported classes Ben Skeggs
` (8 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
This will expose functionality supported by newer kernel interfaces,
giving access to things such as ZBC controls, perfmon, etc.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau-symbol-check | 1 +
nouveau/nouveau.c | 7 +++++++
nouveau/nouveau.h | 2 ++
3 files changed, 10 insertions(+)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 0fef563..7330170 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -33,6 +33,7 @@ nouveau_device_wrap
nouveau_getparam
nouveau_object_del
nouveau_object_find
+nouveau_object_mthd
nouveau_object_new
nouveau_pushbuf_bufctx
nouveau_pushbuf_data
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index eb741c7..1871e8c 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -59,6 +59,13 @@ debug_init(char *args)
}
#endif
+int
+nouveau_object_mthd(struct nouveau_object *obj,
+ uint32_t mthd, void *data, uint32_t size)
+{
+ return -ENODEV;
+}
+
static void
nouveau_object_fini(struct nouveau_object *obj)
{
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index 4adda0e..4c95409 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -67,6 +67,8 @@ int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
uint32_t oclass, void *data, uint32_t length,
struct nouveau_object **);
void nouveau_object_del(struct nouveau_object **);
+int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
+ void *data, uint32_t size);
void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
struct nouveau_device {
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 06/14] nouveau: add interfaces to query information about supported classes
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (3 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 05/14] nouveau: add interface to call an object's methods Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 07/14] nouveau: introduce object to represent the kernel client Ben Skeggs
` (7 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
This will expose functionality supported by newer kernel interfaces.
Current userspace uses the chipset to determine which classes are likely
exposed, which generally works pretty well, but isn't as flexible as it
could be.
Unfortunately, the G98:GF100 video code in Mesa is still relying on the
kernel exposing incorrect vdec classes on some chipsets. The ABI16
kernel interfaces have a workaround for this in place, but that will no
longer be available once libdrm supports NVIF.
To prevent a regression when NVIF support is added, if there's no kernel
support for NVIF, libdrm will magic up a class list containing correct
vdec classes anyway instead of failing with -ENODEV.
v2.
- add description of abi16/vdec workaround
- add description of sclass/mclass
- leave client-provided pointer unmodified on abi16_sclass() failure
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
sclassmod
---
nouveau/abi16.c | 51 ++++++++++++++++++++++++++++++++++++++++++++
nouveau/nouveau-symbol-check | 3 +++
nouveau/nouveau.c | 41 +++++++++++++++++++++++++++++++++++
nouveau/nouveau.h | 22 +++++++++++++++++++
nouveau/private.h | 1 +
5 files changed, 118 insertions(+)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index 615aea2..a2da474 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -29,9 +29,11 @@
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
+#include <errno.h>
#include "private.h"
+#include "nvif/class.h"
static int
abi16_chan_nv04(struct nouveau_object *obj)
@@ -148,6 +150,55 @@ abi16_ntfy(struct nouveau_object *obj)
return 0;
}
+drm_private int
+abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass)
+{
+ struct nouveau_sclass *sclass;
+ struct nouveau_device *dev;
+
+ if (!(sclass = calloc(8, sizeof(*sclass))))
+ return -ENOMEM;
+ *psclass = sclass;
+
+ switch (obj->oclass) {
+ case NOUVEAU_FIFO_CHANNEL_CLASS:
+ /* Older kernel versions were exposing the wrong video engine
+ * classes on certain G98:GF100 boards. This has since been
+ * corrected, but ABI16 has compatibility in place to avoid
+ * breaking older userspace.
+ *
+ * Clients that have been updated to use NVIF are required to
+ * use the correct classes, which means that they'll break if
+ * running on an older kernel.
+ *
+ * To handle this issue, if using the older kernel interfaces,
+ * we'll magic up a list containing the vdec classes that the
+ * kernel will accept for these boards. Clients should make
+ * use of this information instead of hardcoding classes for
+ * specific chipsets.
+ */
+ dev = (struct nouveau_device *)obj->parent;
+ if (dev->chipset >= 0x98 &&
+ dev->chipset != 0xa0 &&
+ dev->chipset < 0xc0) {
+ *sclass++ = (struct nouveau_sclass){
+ GT212_MSVLD, -1, -1
+ };
+ *sclass++ = (struct nouveau_sclass){
+ GT212_MSPDEC, -1, -1
+ };
+ *sclass++ = (struct nouveau_sclass){
+ GT212_MSPPP, -1, -1
+ };
+ }
+ break;
+ default:
+ break;
+ }
+
+ return sclass - *psclass;
+}
+
drm_private void
abi16_delete(struct nouveau_object *obj)
{
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 7330170..38b6ec5 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -33,8 +33,11 @@ nouveau_device_wrap
nouveau_getparam
nouveau_object_del
nouveau_object_find
+nouveau_object_mclass
nouveau_object_mthd
nouveau_object_new
+nouveau_object_sclass_get
+nouveau_object_sclass_put
nouveau_pushbuf_bufctx
nouveau_pushbuf_data
nouveau_pushbuf_del
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 1871e8c..0017303 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -66,6 +66,47 @@ nouveau_object_mthd(struct nouveau_object *obj,
return -ENODEV;
}
+void
+nouveau_object_sclass_put(struct nouveau_sclass **psclass)
+{
+ free(*psclass);
+ *psclass = NULL;
+}
+
+int
+nouveau_object_sclass_get(struct nouveau_object *obj,
+ struct nouveau_sclass **psclass)
+{
+ return abi16_sclass(obj, psclass);
+}
+
+int
+nouveau_object_mclass(struct nouveau_object *obj,
+ const struct nouveau_mclass *mclass)
+{
+ struct nouveau_sclass *sclass;
+ int ret = -ENODEV;
+ int cnt, i, j;
+
+ cnt = nouveau_object_sclass_get(obj, &sclass);
+ if (cnt < 0)
+ return cnt;
+
+ for (i = 0; ret < 0 && mclass[i].oclass; i++) {
+ for (j = 0; j < cnt; j++) {
+ if (mclass[i].oclass == sclass[j].oclass &&
+ mclass[i].version >= sclass[j].minver &&
+ mclass[i].version <= sclass[j].maxver) {
+ ret = i;
+ break;
+ }
+ }
+ }
+
+ nouveau_object_sclass_put(&sclass);
+ return ret;
+}
+
static void
nouveau_object_fini(struct nouveau_object *obj)
{
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index 4c95409..24cda6f 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -63,12 +63,34 @@ struct nv04_notify {
uint32_t length;
};
+/* Supported class information, provided by the kernel */
+struct nouveau_sclass {
+ int32_t oclass;
+ int minver;
+ int maxver;
+};
+
+/* Client-provided array describing class versions that are desired.
+ *
+ * These are used to match against the kernel's list of supported classes.
+ */
+struct nouveau_mclass {
+ int32_t oclass; /* 0 == EOL */
+ int version;
+ void *data;
+};
+
int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
uint32_t oclass, void *data, uint32_t length,
struct nouveau_object **);
void nouveau_object_del(struct nouveau_object **);
int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
void *data, uint32_t size);
+int nouveau_object_sclass_get(struct nouveau_object *,
+ struct nouveau_sclass **);
+void nouveau_object_sclass_put(struct nouveau_sclass **);
+int nouveau_object_mclass(struct nouveau_object *,
+ const struct nouveau_mclass *);
void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
struct nouveau_device {
diff --git a/nouveau/private.h b/nouveau/private.h
index 5f352a4..83060f9 100644
--- a/nouveau/private.h
+++ b/nouveau/private.h
@@ -116,6 +116,7 @@ nouveau_device_open_existing(struct nouveau_device **, int, int, drm_context_t);
/* abi16.c */
drm_private bool abi16_object(struct nouveau_object *, int (**)(struct nouveau_object *));
drm_private void abi16_delete(struct nouveau_object *);
+drm_private int abi16_sclass(struct nouveau_object *, struct nouveau_sclass **);
drm_private void abi16_bo_info(struct nouveau_bo *, struct drm_nouveau_gem_info *);
drm_private int abi16_bo_init(struct nouveau_bo *, uint32_t alignment,
union nouveau_bo_config *);
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 07/14] nouveau: introduce object to represent the kernel client
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (4 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 06/14] nouveau: add interfaces to query information about supported classes Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 08/14] nouveau: stack legacy nouveau_device on top of nouveau_drm Ben Skeggs
` (6 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Because NVIF intentionally lacks some of the paths necessary to be
compatible with various mistakes we've made over the years, libdrm
needs to know whether a client has been updated and that it's safe
to make use of the new kernel interfaces.
Clients still using nouveau_device_open()/wrap() will be forced to
make use of ABI16 instead of NVIF.
v2.
- remove lib_version, nothing used it
- leave client-provided pointer unmodified on failure
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau-symbol-check | 2 ++
nouveau/nouveau.c | 35 +++++++++++++++++++++++++++++++++++
nouveau/nouveau.h | 18 ++++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 38b6ec5..e360b92 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -30,6 +30,8 @@ nouveau_device_del
nouveau_device_open
nouveau_device_open_existing
nouveau_device_wrap
+nouveau_drm_del
+nouveau_drm_new
nouveau_getparam
nouveau_object_del
nouveau_object_find
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 0017303..2b16351 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -195,6 +195,41 @@ nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
return obj;
}
+void
+nouveau_drm_del(struct nouveau_drm **pdrm)
+{
+ free(*pdrm);
+ *pdrm = NULL;
+}
+
+int
+nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
+{
+ struct nouveau_drm *drm;
+ drmVersionPtr ver;
+
+#ifdef DEBUG
+ debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
+#endif
+
+ if (!(drm = calloc(1, sizeof(*drm))))
+ return -ENOMEM;
+ drm->fd = fd;
+
+ if (!(ver = drmGetVersion(fd))) {
+ nouveau_drm_del(&drm);
+ return -EINVAL;
+ }
+ *pdrm = drm;
+
+ drm->version = (ver->version_major << 24) |
+ (ver->version_minor << 8) |
+ ver->version_patchlevel;
+ drm->nvif = false;
+ drmFreeVersion(ver);
+ return 0;
+}
+
/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
* is kept here to prevent AIGLX from crashing if the DDX is linked against
* the new libdrm, but the DRI driver against the old
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index 24cda6f..2287eba 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -22,6 +22,24 @@ struct nouveau_object {
void *data;
};
+struct nouveau_drm {
+ struct nouveau_object client;
+ int fd;
+ uint32_t version;
+ bool nvif;
+};
+
+static inline struct nouveau_drm *
+nouveau_drm(struct nouveau_object *obj)
+{
+ while (obj && obj->parent)
+ obj = obj->parent;
+ return (struct nouveau_drm *)obj;
+}
+
+int nouveau_drm_new(int fd, struct nouveau_drm **);
+void nouveau_drm_del(struct nouveau_drm **);
+
struct nouveau_fifo {
struct nouveau_object *object;
uint32_t channel;
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 08/14] nouveau: stack legacy nouveau_device on top of nouveau_drm
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (5 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 07/14] nouveau: introduce object to represent the kernel client Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 09/14] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd Ben Skeggs
` (5 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau.c | 46 +++++++++++++++++++++-------------------------
1 file changed, 21 insertions(+), 25 deletions(-)
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 2b16351..d129ae8 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -244,39 +244,36 @@ nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
int
nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
{
- struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev));
- struct nouveau_device *dev = &nvdev->base;
+ struct nouveau_drm *drm;
+ struct nouveau_device_priv *nvdev;
+ struct nouveau_device *dev;
uint64_t chipset, vram, gart, bousage;
- drmVersionPtr ver;
int ret;
char *tmp;
-#ifdef DEBUG
- debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
-#endif
-
- if (!nvdev)
+ if (!(nvdev = calloc(1, sizeof(*nvdev))))
return -ENOMEM;
+ dev = &nvdev->base;
+
ret = pthread_mutex_init(&nvdev->lock, NULL);
if (ret) {
free(nvdev);
return ret;
}
- nvdev->base.fd = fd;
-
- ver = drmGetVersion(fd);
- if (ver) dev->drm_version = (ver->version_major << 24) |
- (ver->version_minor << 8) |
- ver->version_patchlevel;
- drmFreeVersion(ver);
-
- if ( dev->drm_version != 0x00000010 &&
- (dev->drm_version < 0x01000000 ||
- dev->drm_version >= 0x02000000)) {
+ ret = nouveau_drm_new(fd, &drm);
+ if (ret) {
nouveau_device_del(&dev);
- return -EINVAL;
+ return ret;
}
+ drm->nvif = false;
+
+ nvdev->base.object.parent = &drm->client;
+ nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
+ nvdev->base.object.length = ~0;
+ nvdev->base.fd = drm->fd;
+ nvdev->base.drm_version = drm->drm_version;
+ nvdev->base.lib_version = drm->lib_version;
ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset);
if (ret == 0)
@@ -305,9 +302,6 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
else
nvdev->gart_limit_percent = 80;
DRMINITLISTHEAD(&nvdev->bo_list);
- nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
- nvdev->base.object.length = ~0;
- nvdev->base.lib_version = 0x01000000;
nvdev->base.chipset = chipset;
nvdev->base.vram_size = vram;
nvdev->base.gart_size = gart;
@@ -337,10 +331,12 @@ nouveau_device_del(struct nouveau_device **pdev)
{
struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
if (nvdev) {
- if (nvdev->close)
- drmClose(nvdev->base.fd);
+ struct nouveau_drm *drm = nouveau_drm(&nvdev->base.object);
free(nvdev->client);
+ nouveau_drm_del(&drm);
pthread_mutex_destroy(&nvdev->lock);
+ if (nvdev->close)
+ drmClose(nvdev->base.fd);
free(nvdev);
*pdev = NULL;
}
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 09/14] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (6 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 08/14] nouveau: stack legacy nouveau_device on top of nouveau_drm Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 10/14] nouveau: remove nouveau_object_find() Ben Skeggs
` (4 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
The latter is deprecated, and will not be valid for newer clients.
v2.
- split out nouveau_object_find removal
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/abi16.c | 32 +++++++++++++++-----------------
nouveau/nouveau.c | 32 +++++++++++++++++++++-----------
nouveau/pushbuf.c | 7 ++++---
3 files changed, 40 insertions(+), 31 deletions(-)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index a2da474..df89952 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -38,7 +38,7 @@
static int
abi16_chan_nv04(struct nouveau_object *obj)
{
- struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+ struct nouveau_drm *drm = nouveau_drm(obj);
struct nv04_fifo *nv04 = obj->data;
struct drm_nouveau_channel_alloc req = {
.fb_ctxdma_handle = nv04->vram,
@@ -46,7 +46,7 @@ abi16_chan_nv04(struct nouveau_object *obj)
};
int ret;
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
&req, sizeof(req));
if (ret)
return ret;
@@ -62,12 +62,12 @@ abi16_chan_nv04(struct nouveau_object *obj)
static int
abi16_chan_nvc0(struct nouveau_object *obj)
{
- struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+ struct nouveau_drm *drm = nouveau_drm(obj);
struct drm_nouveau_channel_alloc req = {};
struct nvc0_fifo *nvc0 = obj->data;
int ret;
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
&req, sizeof(req));
if (ret)
return ret;
@@ -83,7 +83,7 @@ abi16_chan_nvc0(struct nouveau_object *obj)
static int
abi16_chan_nve0(struct nouveau_object *obj)
{
- struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
+ struct nouveau_drm *drm = nouveau_drm(obj);
struct drm_nouveau_channel_alloc req = {};
struct nve0_fifo *nve0 = obj->data;
int ret;
@@ -93,7 +93,7 @@ abi16_chan_nve0(struct nouveau_object *obj)
req.tt_ctxdma_handle = nve0->engine;
}
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
&req, sizeof(req));
if (ret)
return ret;
@@ -109,16 +109,15 @@ abi16_chan_nve0(struct nouveau_object *obj)
static int
abi16_engobj(struct nouveau_object *obj)
{
+ struct nouveau_drm *drm = nouveau_drm(obj);
struct drm_nouveau_grobj_alloc req = {
.channel = obj->parent->handle,
.handle = obj->handle,
.class = obj->oclass,
};
- struct nouveau_device *dev;
int ret;
- dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
- ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
+ ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GROBJ_ALLOC,
&req, sizeof(req));
if (ret)
return ret;
@@ -130,17 +129,16 @@ abi16_engobj(struct nouveau_object *obj)
static int
abi16_ntfy(struct nouveau_object *obj)
{
+ struct nouveau_drm *drm = nouveau_drm(obj);
struct nv04_notify *ntfy = obj->data;
struct drm_nouveau_notifierobj_alloc req = {
.channel = obj->parent->handle,
.handle = ntfy->object->handle,
.size = ntfy->length,
};
- struct nouveau_device *dev;
int ret;
- dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
&req, sizeof(req));
if (ret)
return ret;
@@ -202,18 +200,17 @@ abi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass)
drm_private void
abi16_delete(struct nouveau_object *obj)
{
- struct nouveau_device *dev =
- nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
+ struct nouveau_drm *drm = nouveau_drm(obj);
if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
struct drm_nouveau_channel_free req;
req.channel = obj->handle;
- drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE,
+ drmCommandWrite(drm->fd, DRM_NOUVEAU_CHANNEL_FREE,
&req, sizeof(req));
} else {
struct drm_nouveau_gpuobj_free req;
req.channel = obj->parent->handle;
req.handle = obj->handle;
- drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
+ drmCommandWrite(drm->fd, DRM_NOUVEAU_GPUOBJ_FREE,
&req, sizeof(req));
}
}
@@ -293,6 +290,7 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
union nouveau_bo_config *config)
{
struct nouveau_device *dev = bo->device;
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct drm_nouveau_gem_new req = {};
struct drm_nouveau_gem_info *info = &req.info;
int ret;
@@ -335,7 +333,7 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
if (!nouveau_device(dev)->have_bo_usage)
info->tile_flags &= 0x0000ff00;
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_NEW,
&req, sizeof(req));
if (ret == 0)
abi16_bo_info(bo, &req.info);
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index d129ae8..b474c77 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -345,8 +345,9 @@ nouveau_device_del(struct nouveau_device **pdev)
int
nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
{
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct drm_nouveau_getparam r = { .param = param };
- int fd = dev->fd, ret =
+ int fd = drm->fd, ret =
drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
*value = r.value;
return ret;
@@ -355,8 +356,9 @@ nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
int
nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
{
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct drm_nouveau_setparam r = { .param = param, .value = value };
- return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
+ return drmCommandWrite(drm->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
}
int
@@ -417,6 +419,7 @@ nouveau_client_del(struct nouveau_client **pclient)
static void
nouveau_bo_del(struct nouveau_bo *bo)
{
+ struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
struct drm_gem_close req = { .handle = bo->handle };
@@ -433,11 +436,11 @@ nouveau_bo_del(struct nouveau_bo *bo)
* might cause the bo to be closed accidentally while
* re-importing.
*/
- drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
+ drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
}
pthread_mutex_unlock(&nvdev->lock);
} else {
- drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
+ drmIoctl(drm->fd, DRM_IOCTL_GEM_CLOSE, &req);
}
if (bo->map)
drm_munmap(bo->map, bo->size);
@@ -474,6 +477,7 @@ static int
nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
struct nouveau_bo **pbo, int name)
{
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct nouveau_device_priv *nvdev = nouveau_device(dev);
struct drm_nouveau_gem_info req = { .handle = handle };
struct nouveau_bo_priv *nvbo;
@@ -503,7 +507,7 @@ nouveau_bo_wrap_locked(struct nouveau_device *dev, uint32_t handle,
}
}
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_INFO,
&req, sizeof(req));
if (ret)
return ret;
@@ -550,6 +554,7 @@ int
nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
struct nouveau_bo **pbo)
{
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct nouveau_device_priv *nvdev = nouveau_device(dev);
struct nouveau_bo_priv *nvbo;
struct drm_gem_open req = { .name = name };
@@ -565,7 +570,7 @@ nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
}
}
- ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req);
+ ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &req);
if (ret == 0) {
ret = nouveau_bo_wrap_locked(dev, req.handle, pbo, name);
}
@@ -578,11 +583,12 @@ int
nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
{
struct drm_gem_flink req = { .handle = bo->handle };
+ struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
*name = nvbo->name;
if (!*name) {
- int ret = drmIoctl(bo->device->fd, DRM_IOCTL_GEM_FLINK, &req);
+ int ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &req);
if (ret) {
*name = 0;
@@ -613,6 +619,7 @@ int
nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
struct nouveau_bo **bo)
{
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct nouveau_device_priv *nvdev = nouveau_device(dev);
int ret;
unsigned int handle;
@@ -620,7 +627,7 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
nouveau_bo_ref(NULL, bo);
pthread_mutex_lock(&nvdev->lock);
- ret = drmPrimeFDToHandle(dev->fd, prime_fd, &handle);
+ ret = drmPrimeFDToHandle(drm->fd, prime_fd, &handle);
if (ret == 0) {
ret = nouveau_bo_wrap_locked(dev, handle, bo, 0);
}
@@ -631,10 +638,11 @@ nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
int
nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
{
+ struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
int ret;
- ret = drmPrimeHandleToFD(bo->device->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd);
+ ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, DRM_CLOEXEC, prime_fd);
if (ret)
return ret;
@@ -646,6 +654,7 @@ int
nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
struct nouveau_client *client)
{
+ struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
struct drm_nouveau_gem_cpu_prep req;
struct nouveau_pushbuf *push;
@@ -669,7 +678,7 @@ nouveau_bo_wait(struct nouveau_bo *bo, uint32_t access,
if (access & NOUVEAU_BO_NOBLOCK)
req.flags |= NOUVEAU_GEM_CPU_PREP_NOWAIT;
- ret = drmCommandWrite(bo->device->fd, DRM_NOUVEAU_GEM_CPU_PREP,
+ ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GEM_CPU_PREP,
&req, sizeof(req));
if (ret == 0)
nvbo->access = 0;
@@ -680,10 +689,11 @@ int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t access,
struct nouveau_client *client)
{
+ struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
if (bo->map == NULL) {
bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE,
- MAP_SHARED, bo->device->fd, nvbo->map_handle);
+ MAP_SHARED, drm->fd, nvbo->map_handle);
if (bo->map == MAP_FAILED) {
bo->map = NULL;
return -errno;
diff --git a/nouveau/pushbuf.c b/nouveau/pushbuf.c
index 8e7dcdf..035e301 100644
--- a/nouveau/pushbuf.c
+++ b/nouveau/pushbuf.c
@@ -312,6 +312,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan)
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(push);
struct nouveau_pushbuf_krec *krec = nvpb->list;
struct nouveau_device *dev = push->client->device;
+ struct nouveau_drm *drm = nouveau_drm(&dev->object);
struct drm_nouveau_gem_pushbuf_bo_presumed *info;
struct drm_nouveau_gem_pushbuf_bo *kref;
struct drm_nouveau_gem_pushbuf req;
@@ -345,7 +346,7 @@ pushbuf_submit(struct nouveau_pushbuf *push, struct nouveau_object *chan)
pushbuf_dump(krec, krec_id++, fifo->channel);
#ifndef SIMULATE
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF,
&req, sizeof(req));
nvpb->suffix0 = req.suffix0;
nvpb->suffix1 = req.suffix1;
@@ -536,7 +537,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
int nr, uint32_t size, bool immediate,
struct nouveau_pushbuf **ppush)
{
- struct nouveau_device *dev = client->device;
+ struct nouveau_drm *drm = nouveau_drm(&client->device->object);
struct nouveau_fifo *fifo = chan->data;
struct nouveau_pushbuf_priv *nvpb;
struct nouveau_pushbuf *push;
@@ -551,7 +552,7 @@ nouveau_pushbuf_new(struct nouveau_client *client, struct nouveau_object *chan,
*/
req.channel = fifo->channel;
req.nr_push = 0;
- ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_PUSHBUF,
+ ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF,
&req, sizeof(req));
if (ret)
return ret;
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 10/14] nouveau: remove nouveau_object_find()
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (7 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 09/14] nouveau: make use of nouveau_drm::fd instead of nouveau_device::fd Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 11/14] nouveau: add new interface to create a nouveau_device Ben Skeggs
` (3 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
No more internal users, and there's never been external users.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau-symbol-check | 1 -
nouveau/nouveau.c | 11 -----------
nouveau/nouveau.h | 1 -
3 files changed, 13 deletions(-)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index e360b92..275b6e7 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -34,7 +34,6 @@ nouveau_drm_del
nouveau_drm_new
nouveau_getparam
nouveau_object_del
-nouveau_object_find
nouveau_object_mclass
nouveau_object_mthd
nouveau_object_new
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index b474c77..56e00ac 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -184,17 +184,6 @@ nouveau_object_del(struct nouveau_object **pobj)
}
}
-void *
-nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
-{
- while (obj && obj->oclass != pclass) {
- obj = obj->parent;
- if (pclass == NOUVEAU_PARENT_CLASS)
- break;
- }
- return obj;
-}
-
void
nouveau_drm_del(struct nouveau_drm **pdrm)
{
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index 2287eba..a693acf 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -109,7 +109,6 @@ int nouveau_object_sclass_get(struct nouveau_object *,
void nouveau_object_sclass_put(struct nouveau_sclass **);
int nouveau_object_mclass(struct nouveau_object *,
const struct nouveau_mclass *);
-void *nouveau_object_find(struct nouveau_object *, uint32_t parent_class);
struct nouveau_device {
struct nouveau_object object;
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 11/14] nouveau: add new interface to create a nouveau_device
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (8 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 10/14] nouveau: remove nouveau_object_find() Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 12/14] nouveau: add support for newer kernel interfaces Ben Skeggs
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau-symbol-check | 1 +
nouveau/nouveau.c | 133 ++++++++++++++++++++++++++++---------------
nouveau/nouveau.h | 2 +
3 files changed, 89 insertions(+), 47 deletions(-)
diff --git a/nouveau/nouveau-symbol-check b/nouveau/nouveau-symbol-check
index 275b6e7..b265cea 100755
--- a/nouveau/nouveau-symbol-check
+++ b/nouveau/nouveau-symbol-check
@@ -27,6 +27,7 @@ nouveau_bufctx_reset
nouveau_client_del
nouveau_client_new
nouveau_device_del
+nouveau_device_new
nouveau_device_open
nouveau_device_open_existing
nouveau_device_wrap
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index 56e00ac..fef338b 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -45,6 +45,10 @@
#include "nouveau.h"
#include "private.h"
+#include "nvif/class.h"
+#include "nvif/cl0080.h"
+#include "nvif/unpack.h"
+
#ifdef DEBUG
drm_private uint32_t nouveau_debug = 0;
@@ -231,75 +235,107 @@ nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
}
int
-nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
+nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
+ void *data, uint32_t size, struct nouveau_device **pdev)
{
- struct nouveau_drm *drm;
+ union {
+ struct nv_device_v0 v0;
+ } *args = data;
+ struct nouveau_drm *drm = nouveau_drm(parent);
struct nouveau_device_priv *nvdev;
struct nouveau_device *dev;
- uint64_t chipset, vram, gart, bousage;
- int ret;
+ uint64_t v;
char *tmp;
+ int ret = -ENOSYS;
+
+ if (oclass != NV_DEVICE ||
+ nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))
+ return ret;
if (!(nvdev = calloc(1, sizeof(*nvdev))))
return -ENOMEM;
- dev = &nvdev->base;
+ dev = *pdev = &nvdev->base;
+ dev->fd = -1;
- ret = pthread_mutex_init(&nvdev->lock, NULL);
- if (ret) {
- free(nvdev);
- return ret;
- }
-
- ret = nouveau_drm_new(fd, &drm);
- if (ret) {
- nouveau_device_del(&dev);
- return ret;
- }
- drm->nvif = false;
+ if (args->v0.device == ~0ULL) {
+ nvdev->base.object.parent = &drm->client;
+ nvdev->base.object.handle = ~0ULL;
+ nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
+ nvdev->base.object.length = ~0;
- nvdev->base.object.parent = &drm->client;
- nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
- nvdev->base.object.length = ~0;
- nvdev->base.fd = drm->fd;
- nvdev->base.drm_version = drm->drm_version;
- nvdev->base.lib_version = drm->lib_version;
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &v);
+ if (ret)
+ goto done;
+ nvdev->base.chipset = v;
- ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset);
- if (ret == 0)
- ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram);
- if (ret == 0)
- ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart);
- if (ret) {
- nouveau_device_del(&dev);
- return ret;
- }
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &v);
+ if (ret == 0)
+ nvdev->have_bo_usage = (v != 0);
+ } else
+ return -ENOSYS;
- ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage);
- if (ret == 0)
- nvdev->have_bo_usage = (bousage != 0);
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &v);
+ if (ret)
+ goto done;
+ nvdev->base.vram_size = v;
- nvdev->close = close;
+ ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &v);
+ if (ret)
+ goto done;
+ nvdev->base.gart_size = v;
tmp = getenv("NOUVEAU_LIBDRM_VRAM_LIMIT_PERCENT");
if (tmp)
nvdev->vram_limit_percent = atoi(tmp);
else
nvdev->vram_limit_percent = 80;
+
+ nvdev->base.vram_limit =
+ (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
+
tmp = getenv("NOUVEAU_LIBDRM_GART_LIMIT_PERCENT");
if (tmp)
nvdev->gart_limit_percent = atoi(tmp);
else
nvdev->gart_limit_percent = 80;
- DRMINITLISTHEAD(&nvdev->bo_list);
- nvdev->base.chipset = chipset;
- nvdev->base.vram_size = vram;
- nvdev->base.gart_size = gart;
- nvdev->base.vram_limit =
- (nvdev->base.vram_size * nvdev->vram_limit_percent) / 100;
+
nvdev->base.gart_limit =
(nvdev->base.gart_size * nvdev->gart_limit_percent) / 100;
- *pdev = &nvdev->base;
+ ret = pthread_mutex_init(&nvdev->lock, NULL);
+ DRMINITLISTHEAD(&nvdev->bo_list);
+done:
+ if (ret)
+ nouveau_device_del(pdev);
+ return ret;
+}
+
+int
+nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
+{
+ struct nouveau_drm *drm;
+ struct nouveau_device_priv *nvdev;
+ int ret;
+
+ ret = nouveau_drm_new(fd, &drm);
+ if (ret)
+ return ret;
+ drm->nvif = false;
+
+ ret = nouveau_device_new(&drm->client, NV_DEVICE,
+ &(struct nv_device_v0) {
+ .device = ~0ULL,
+ }, sizeof(struct nv_device_v0), pdev);
+ if (ret) {
+ nouveau_drm_del(&drm);
+ return ret;
+ }
+
+ nvdev = nouveau_device(*pdev);
+ nvdev->base.fd = drm->fd;
+ nvdev->base.drm_version = drm->drm_version;
+ nvdev->base.lib_version = drm->lib_version;
+ nvdev->close = close;
return 0;
}
@@ -320,12 +356,15 @@ nouveau_device_del(struct nouveau_device **pdev)
{
struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
if (nvdev) {
- struct nouveau_drm *drm = nouveau_drm(&nvdev->base.object);
free(nvdev->client);
- nouveau_drm_del(&drm);
pthread_mutex_destroy(&nvdev->lock);
- if (nvdev->close)
- drmClose(nvdev->base.fd);
+ if (nvdev->base.fd >= 0) {
+ struct nouveau_drm *drm =
+ nouveau_drm(&nvdev->base.object);
+ nouveau_drm_del(&drm);
+ if (nvdev->close)
+ drmClose(nvdev->base.fd);
+ }
free(nvdev);
*pdev = NULL;
}
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index a693acf..f3cf8f5 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -122,6 +122,8 @@ struct nouveau_device {
uint64_t gart_limit;
};
+int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
+ void *data, uint32_t size, struct nouveau_device **);
int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
int nouveau_device_open(const char *busid, struct nouveau_device **);
void nouveau_device_del(struct nouveau_device **);
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 12/14] nouveau: add support for newer kernel interfaces
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (9 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 11/14] nouveau: add new interface to create a nouveau_device Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 13/14] nouveau: clean up nouveau.h, noting deprecated members/functions Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 14/14] Bump version for release Ben Skeggs
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
v2.
- leave client-provided pointer unmodified on sclass_get() failure
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/abi16.c | 3 +-
nouveau/nouveau.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 155 insertions(+), 7 deletions(-)
diff --git a/nouveau/abi16.c b/nouveau/abi16.c
index df89952..bcdfd1f 100644
--- a/nouveau/abi16.c
+++ b/nouveau/abi16.c
@@ -223,7 +223,8 @@ abi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *))
/* nouveau_object::length is (ab)used to determine whether the
* object is a legacy object (!=0), or a real NVIF object.
*/
- if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS)) {
+ if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS) ||
+ (parent->length == 0 && parent->oclass == NV_DEVICE)) {
if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
struct nouveau_device *dev = (void *)parent;
if (dev->chipset < 0xc0)
diff --git a/nouveau/nouveau.c b/nouveau/nouveau.c
index fef338b..e113a8f 100644
--- a/nouveau/nouveau.c
+++ b/nouveau/nouveau.c
@@ -47,6 +47,7 @@
#include "nvif/class.h"
#include "nvif/cl0080.h"
+#include "nvif/ioctl.h"
#include "nvif/unpack.h"
#ifdef DEBUG
@@ -63,11 +64,67 @@ debug_init(char *args)
}
#endif
+static int
+nouveau_object_ioctl(struct nouveau_object *obj, void *data, uint32_t size)
+{
+ struct nouveau_drm *drm = nouveau_drm(obj);
+ union {
+ struct nvif_ioctl_v0 v0;
+ } *args = data;
+ uint32_t argc = size;
+ int ret = -ENOSYS;
+
+ if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
+ if (!obj->length) {
+ if (obj != &drm->client)
+ args->v0.object = (unsigned long)(void *)obj;
+ else
+ args->v0.object = 0;
+ args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
+ args->v0.route = 0x00;
+ } else {
+ args->v0.route = 0xff;
+ args->v0.token = obj->handle;
+ }
+ } else
+ return ret;
+
+ return drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NVIF, args, argc);
+}
+
int
nouveau_object_mthd(struct nouveau_object *obj,
uint32_t mthd, void *data, uint32_t size)
{
- return -ENODEV;
+ struct nouveau_drm *drm = nouveau_drm(obj);
+ struct {
+ struct nvif_ioctl_v0 ioctl;
+ struct nvif_ioctl_mthd_v0 mthd;
+ } *args;
+ uint32_t argc = sizeof(*args) + size;
+ uint8_t stack[128];
+ int ret;
+
+ if (!drm->nvif)
+ return -ENOSYS;
+
+ if (argc > sizeof(stack)) {
+ if (!(args = malloc(argc)))
+ return -ENOMEM;
+ } else {
+ args = (void *)stack;
+ }
+ args->ioctl.version = 0;
+ args->ioctl.type = NVIF_IOCTL_V0_MTHD;
+ args->mthd.version = 0;
+ args->mthd.method = mthd;
+
+ memcpy(args->mthd.data, data, size);
+ ret = nouveau_object_ioctl(obj, args, argc);
+ memcpy(data, args->mthd.data, size);
+ if (args != (void *)stack)
+ free(args);
+ return ret;
}
void
@@ -81,7 +138,50 @@ int
nouveau_object_sclass_get(struct nouveau_object *obj,
struct nouveau_sclass **psclass)
{
- return abi16_sclass(obj, psclass);
+ struct nouveau_drm *drm = nouveau_drm(obj);
+ struct {
+ struct nvif_ioctl_v0 ioctl;
+ struct nvif_ioctl_sclass_v0 sclass;
+ } *args = NULL;
+ struct nouveau_sclass *sclass;
+ int ret, cnt = 0, i;
+ uint32_t size;
+
+ if (!drm->nvif)
+ return abi16_sclass(obj, psclass);
+
+ while (1) {
+ size = sizeof(*args) + cnt * sizeof(args->sclass.oclass[0]);
+ if (!(args = malloc(size)))
+ return -ENOMEM;
+ args->ioctl.version = 0;
+ args->ioctl.type = NVIF_IOCTL_V0_SCLASS;
+ args->sclass.version = 0;
+ args->sclass.count = cnt;
+
+ ret = nouveau_object_ioctl(obj, args, size);
+ if (ret == 0 && args->sclass.count <= cnt)
+ break;
+ cnt = args->sclass.count;
+ free(args);
+ if (ret != 0)
+ return ret;
+ }
+
+ if ((sclass = calloc(args->sclass.count, sizeof(*sclass)))) {
+ for (i = 0; i < args->sclass.count; i++) {
+ sclass[i].oclass = args->sclass.oclass[i].oclass;
+ sclass[i].minver = args->sclass.oclass[i].minver;
+ sclass[i].maxver = args->sclass.oclass[i].maxver;
+ }
+ *psclass = sclass;
+ ret = args->sclass.count;
+ } else {
+ ret = -ENOMEM;
+ }
+
+ free(args);
+ return ret;
}
int
@@ -114,12 +214,21 @@ nouveau_object_mclass(struct nouveau_object *obj,
static void
nouveau_object_fini(struct nouveau_object *obj)
{
+ struct {
+ struct nvif_ioctl_v0 ioctl;
+ struct nvif_ioctl_del del;
+ } args = {
+ .ioctl.type = NVIF_IOCTL_V0_DEL,
+ };
+
if (obj->data) {
abi16_delete(obj);
free(obj->data);
obj->data = NULL;
return;
}
+
+ nouveau_object_ioctl(obj, &args, sizeof(args));
}
static int
@@ -127,6 +236,12 @@ nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
int32_t oclass, void *data, uint32_t size,
struct nouveau_object *obj)
{
+ struct nouveau_drm *drm = nouveau_drm(parent);
+ struct {
+ struct nvif_ioctl_v0 ioctl;
+ struct nvif_ioctl_new_v0 new;
+ } *args;
+ uint32_t argc = sizeof(*args) + size;
int (*func)(struct nouveau_object *);
int ret = -ENOSYS;
@@ -136,7 +251,22 @@ nouveau_object_init(struct nouveau_object *parent, uint32_t handle,
obj->length = 0;
obj->data = NULL;
- abi16_object(obj, &func);
+ if (!abi16_object(obj, &func) && drm->nvif) {
+ if (!(args = malloc(argc)))
+ return -ENOMEM;
+ args->ioctl.version = 0;
+ args->ioctl.type = NVIF_IOCTL_V0_NEW;
+ args->new.version = 0;
+ args->new.route = NVIF_IOCTL_V0_ROUTE_NVIF;
+ args->new.token = (unsigned long)(void *)obj;
+ args->new.object = (unsigned long)(void *)obj;
+ args->new.handle = handle;
+ args->new.oclass = oclass;
+ memcpy(args->new.data, data, size);
+ ret = nouveau_object_ioctl(parent, args, argc);
+ memcpy(data, args->new.data, size);
+ free(args);
+ } else
if (func) {
obj->length = size ? size : sizeof(struct nouveau_object *);
if (!(obj->data = malloc(obj->length)))
@@ -218,7 +348,7 @@ nouveau_drm_new(int fd, struct nouveau_drm **pdrm)
drm->version = (ver->version_major << 24) |
(ver->version_minor << 8) |
ver->version_patchlevel;
- drm->nvif = false;
+ drm->nvif = (drm->version >= 0x01000301);
drmFreeVersion(ver);
return 0;
}
@@ -238,9 +368,11 @@ int
nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
void *data, uint32_t size, struct nouveau_device **pdev)
{
+ struct nv_device_info_v0 info = {};
union {
struct nv_device_v0 v0;
} *args = data;
+ uint32_t argc = size;
struct nouveau_drm *drm = nouveau_drm(parent);
struct nouveau_device_priv *nvdev;
struct nouveau_device *dev;
@@ -257,6 +389,22 @@ nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
dev = *pdev = &nvdev->base;
dev->fd = -1;
+ if (drm->nvif) {
+ ret = nouveau_object_init(parent, 0, oclass, args, argc,
+ &dev->object);
+ if (ret)
+ goto done;
+
+ info.version = 0;
+
+ ret = nouveau_object_mthd(&dev->object, NV_DEVICE_V0_INFO,
+ &info, sizeof(info));
+ if (ret)
+ goto done;
+
+ nvdev->base.chipset = info.chipset;
+ nvdev->have_bo_usage = true;
+ } else
if (args->v0.device == ~0ULL) {
nvdev->base.object.parent = &drm->client;
nvdev->base.object.handle = ~0ULL;
@@ -333,8 +481,7 @@ nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
nvdev = nouveau_device(*pdev);
nvdev->base.fd = drm->fd;
- nvdev->base.drm_version = drm->drm_version;
- nvdev->base.lib_version = drm->lib_version;
+ nvdev->base.drm_version = drm->version;
nvdev->close = close;
return 0;
}
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 13/14] nouveau: clean up nouveau.h, noting deprecated members/functions
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (10 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 12/14] nouveau: add support for newer kernel interfaces Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
2015-11-27 1:02 ` [libdrm v2 14/14] Bump version for release Ben Skeggs
12 siblings, 0 replies; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
nouveau/nouveau.h | 230 +++++++++++++++++++++++++++---------------------------
1 file changed, 115 insertions(+), 115 deletions(-)
diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h
index f3cf8f5..e3f2813 100644
--- a/nouveau/nouveau.h
+++ b/nouveau/nouveau.h
@@ -1,27 +1,45 @@
#ifndef __NOUVEAU_H__
#define __NOUVEAU_H__
-
-#include <stdint.h>
#include <stdbool.h>
+#include <xf86drm.h>
-#define NOUVEAU_DEVICE_CLASS 0x80000000
-#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
-#define NOUVEAU_NOTIFIER_CLASS 0x80000002
-#define NOUVEAU_PARENT_CLASS 0xffffffff
+/* Supported class information, provided by the kernel */
+struct nouveau_sclass {
+ int32_t oclass;
+ int minver;
+ int maxver;
+};
-struct nouveau_list {
- struct nouveau_list *prev;
- struct nouveau_list *next;
+/* Client-provided array describing class versions that are desired.
+ *
+ * These are used to match against the kernel's list of supported classes.
+ */
+struct nouveau_mclass {
+ int32_t oclass;
+ int version;
+ void *data;
};
struct nouveau_object {
struct nouveau_object *parent;
uint64_t handle;
uint32_t oclass;
- uint32_t length;
- void *data;
+ uint32_t length; /* deprecated */
+ void *data; /* deprecated */
};
+int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
+ uint32_t oclass, void *data, uint32_t length,
+ struct nouveau_object **);
+void nouveau_object_del(struct nouveau_object **);
+int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
+ void *data, uint32_t size);
+int nouveau_object_sclass_get(struct nouveau_object *,
+ struct nouveau_sclass **);
+void nouveau_object_sclass_put(struct nouveau_sclass **);
+int nouveau_object_mclass(struct nouveau_object *,
+ const struct nouveau_mclass *);
+
struct nouveau_drm {
struct nouveau_object client;
int fd;
@@ -40,81 +58,11 @@ nouveau_drm(struct nouveau_object *obj)
int nouveau_drm_new(int fd, struct nouveau_drm **);
void nouveau_drm_del(struct nouveau_drm **);
-struct nouveau_fifo {
- struct nouveau_object *object;
- uint32_t channel;
- uint32_t pushbuf;
- uint64_t unused1[3];
-};
-
-struct nv04_fifo {
- struct nouveau_fifo base;
- uint32_t vram;
- uint32_t gart;
- uint32_t notify;
-};
-
-struct nvc0_fifo {
- struct nouveau_fifo base;
- uint32_t notify;
-};
-
-#define NVE0_FIFO_ENGINE_GR 0x00000001
-#define NVE0_FIFO_ENGINE_VP 0x00000002
-#define NVE0_FIFO_ENGINE_PPP 0x00000004
-#define NVE0_FIFO_ENGINE_BSP 0x00000008
-#define NVE0_FIFO_ENGINE_CE0 0x00000010
-#define NVE0_FIFO_ENGINE_CE1 0x00000020
-#define NVE0_FIFO_ENGINE_ENC 0x00000040
-
-struct nve0_fifo {
- struct {
- struct nouveau_fifo base;
- uint32_t notify;
- };
- uint32_t engine;
-};
-
-struct nv04_notify {
- struct nouveau_object *object;
- uint32_t offset;
- uint32_t length;
-};
-
-/* Supported class information, provided by the kernel */
-struct nouveau_sclass {
- int32_t oclass;
- int minver;
- int maxver;
-};
-
-/* Client-provided array describing class versions that are desired.
- *
- * These are used to match against the kernel's list of supported classes.
- */
-struct nouveau_mclass {
- int32_t oclass; /* 0 == EOL */
- int version;
- void *data;
-};
-
-int nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
- uint32_t oclass, void *data, uint32_t length,
- struct nouveau_object **);
-void nouveau_object_del(struct nouveau_object **);
-int nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
- void *data, uint32_t size);
-int nouveau_object_sclass_get(struct nouveau_object *,
- struct nouveau_sclass **);
-void nouveau_object_sclass_put(struct nouveau_sclass **);
-int nouveau_object_mclass(struct nouveau_object *,
- const struct nouveau_mclass *);
-
struct nouveau_device {
struct nouveau_object object;
- int fd;
- uint32_t lib_version;
- uint32_t drm_version;
+ int fd; /* deprecated */
+ uint32_t lib_version; /* deprecated */
+ uint32_t drm_version; /* deprecated */
uint32_t chipset;
uint64_t vram_size;
uint64_t gart_size;
@@ -122,20 +70,23 @@ struct nouveau_device {
uint64_t gart_limit;
};
-int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
- void *data, uint32_t size, struct nouveau_device **);
-int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
-int nouveau_device_open(const char *busid, struct nouveau_device **);
+int nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
+ void *data, uint32_t size, struct nouveau_device **);
void nouveau_device_del(struct nouveau_device **);
-int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
-int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
+
+int nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
+int nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);
+
+/* deprecated */
+int nouveau_device_wrap(int fd, int close, struct nouveau_device **);
+int nouveau_device_open(const char *busid, struct nouveau_device **);
struct nouveau_client {
struct nouveau_device *device;
int id;
};
-int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
+int nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
void nouveau_client_del(struct nouveau_client **);
union nouveau_bo_config {
@@ -182,22 +133,27 @@ struct nouveau_bo {
union nouveau_bo_config config;
};
-int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
- uint64_t size, union nouveau_bo_config *,
+int nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
+ uint64_t size, union nouveau_bo_config *,
+ struct nouveau_bo **);
+int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
struct nouveau_bo **);
-int nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
- struct nouveau_bo **);
-int nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
- struct nouveau_bo **);
-int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
+int nouveau_bo_name_ref(struct nouveau_device *v, uint32_t name,
+ struct nouveau_bo **);
+int nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
-int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
+int nouveau_bo_map(struct nouveau_bo *, uint32_t access,
+ struct nouveau_client *);
+int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
struct nouveau_client *);
-int nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
- struct nouveau_client *);
-int nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
- struct nouveau_bo **);
-int nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd);
+int nouveau_bo_prime_handle_ref(struct nouveau_device *, int prime_fd,
+ struct nouveau_bo **);
+int nouveau_bo_set_prime(struct nouveau_bo *, int *prime_fd);
+
+struct nouveau_list {
+ struct nouveau_list *prev;
+ struct nouveau_list *next;
+};
struct nouveau_bufref {
struct nouveau_list thead;
@@ -219,8 +175,8 @@ struct nouveau_bufctx {
int relocs;
};
-int nouveau_bufctx_new(struct nouveau_client *, int bins,
- struct nouveau_bufctx **);
+int nouveau_bufctx_new(struct nouveau_client *, int bins,
+ struct nouveau_bufctx **);
void nouveau_bufctx_del(struct nouveau_bufctx **);
struct nouveau_bufref *
nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
@@ -249,16 +205,16 @@ struct nouveau_pushbuf_refn {
uint32_t flags;
};
-int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel,
- int nr, uint32_t size, bool immediate,
- struct nouveau_pushbuf **);
+int nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *chan,
+ int nr, uint32_t size, bool immediate,
+ struct nouveau_pushbuf **);
void nouveau_pushbuf_del(struct nouveau_pushbuf **);
-int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
- uint32_t relocs, uint32_t pushes);
+int nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
+ uint32_t relocs, uint32_t pushes);
void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
uint64_t offset, uint64_t length);
-int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
- struct nouveau_pushbuf_refn *, int nr);
+int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
+ struct nouveau_pushbuf_refn *, int nr);
/* Emits a reloc into the push buffer at the current position, you *must*
* have previously added the referenced buffer to a buffer context, and
* validated it against the current push buffer.
@@ -266,10 +222,54 @@ int nouveau_pushbuf_refn(struct nouveau_pushbuf *,
void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
uint32_t data, uint32_t flags,
uint32_t vor, uint32_t tor);
-int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
+int nouveau_pushbuf_validate(struct nouveau_pushbuf *);
uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
-int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel);
+int nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *chan);
struct nouveau_bufctx *
nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);
+#define NOUVEAU_DEVICE_CLASS 0x80000000
+#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
+#define NOUVEAU_NOTIFIER_CLASS 0x80000002
+
+struct nouveau_fifo {
+ struct nouveau_object *object;
+ uint32_t channel;
+ uint32_t pushbuf;
+ uint64_t unused1[3];
+};
+
+struct nv04_fifo {
+ struct nouveau_fifo base;
+ uint32_t vram;
+ uint32_t gart;
+ uint32_t notify;
+};
+
+struct nvc0_fifo {
+ struct nouveau_fifo base;
+ uint32_t notify;
+};
+
+#define NVE0_FIFO_ENGINE_GR 0x00000001
+#define NVE0_FIFO_ENGINE_VP 0x00000002
+#define NVE0_FIFO_ENGINE_PPP 0x00000004
+#define NVE0_FIFO_ENGINE_BSP 0x00000008
+#define NVE0_FIFO_ENGINE_CE0 0x00000010
+#define NVE0_FIFO_ENGINE_CE1 0x00000020
+#define NVE0_FIFO_ENGINE_ENC 0x00000040
+
+struct nve0_fifo {
+ struct {
+ struct nouveau_fifo base;
+ uint32_t notify;
+ };
+ uint32_t engine;
+};
+
+struct nv04_notify {
+ struct nouveau_object *object;
+ uint32_t offset;
+ uint32_t length;
+};
#endif
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread* [libdrm v2 14/14] Bump version for release
[not found] ` <1448586173-8289-1-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (11 preceding siblings ...)
2015-11-27 1:02 ` [libdrm v2 13/14] nouveau: clean up nouveau.h, noting deprecated members/functions Ben Skeggs
@ 2015-11-27 1:02 ` Ben Skeggs
[not found] ` <1448586173-8289-14-git-send-email-skeggsb-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
12 siblings, 1 reply; 18+ messages in thread
From: Ben Skeggs @ 2015-11-27 1:02 UTC (permalink / raw)
To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Ben Skeggs
From: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index b929d36..7678572 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ([2.63])
AC_INIT([libdrm],
- [2.4.65],
+ [2.4.66],
[https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
[libdrm])
--
2.6.3
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related [flat|nested] 18+ messages in thread