drm/nouveau/nvif: return min/max versions for supported object classes
authorBen Skeggs <bskeggs@redhat.com>
Thu, 20 Aug 2015 04:54:16 +0000 (14:54 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 28 Aug 2015 02:40:32 +0000 (12:40 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/ioctl.h
drivers/gpu/drm/nouveau/include/nvif/object.h
drivers/gpu/drm/nouveau/include/nvkm/core/parent.h
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvif/object.c
drivers/gpu/drm/nouveau/nvkm/core/parent.c

index 7ac185c..b0ac021 100644 (file)
@@ -40,7 +40,11 @@ struct nvif_ioctl_sclass_v0 {
        __u8  version;
        __u8  count;
        __u8  pad02[6];
-       __s32 oclass[];
+       struct nvif_ioctl_sclass_oclass_v0 {
+               __s32 oclass;
+               __s16 minver;
+               __s16 maxver;
+       } oclass[];
 };
 
 struct nvif_ioctl_new_v0 {
index 66d3425..8d81596 100644 (file)
@@ -3,6 +3,12 @@
 
 #include <nvif/os.h>
 
+struct nvif_sclass {
+       s32 oclass;
+       int minver;
+       int maxver;
+};
+
 struct nvif_object {
        struct nvif_client *client;
        u32 handle;
@@ -18,7 +24,8 @@ int  nvif_object_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32,
                      struct nvif_object *);
 void nvif_object_fini(struct nvif_object *);
 int  nvif_object_ioctl(struct nvif_object *, void *, u32, void **);
-int  nvif_object_sclass(struct nvif_object *, s32 *, int);
+int  nvif_object_sclass_get(struct nvif_object *, struct nvif_sclass **);
+void nvif_object_sclass_put(struct nvif_sclass **);
 u32  nvif_object_rd(struct nvif_object *, int, u64);
 void nvif_object_wr(struct nvif_object *, int, u64, u32);
 int  nvif_object_mthd(struct nvif_object *, u32, void *, u32);
index bc4dc1f..45d2066 100644 (file)
@@ -47,5 +47,5 @@ void _nvkm_parent_dtor(struct nvkm_object *);
 int nvkm_parent_sclass(struct nvkm_object *, s32 handle,
                       struct nvkm_object **pengine,
                       struct nvkm_oclass **poclass);
-int nvkm_parent_lclass(struct nvkm_object *, s32 *, int);
+int nvkm_parent_lclass(struct nvkm_object *, void *, int);
 #endif
index 1b3067e..98c7498 100644 (file)
@@ -369,7 +369,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
        struct nouveau_abi16_chan *chan;
        struct nouveau_abi16_ntfy *ntfy;
        struct nvif_client *client;
-       u32 sclass[32];
+       struct nvif_sclass *sclass;
        s32 oclass = 0;
        int ret, i;
 
@@ -384,19 +384,19 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
        if (!chan)
                return nouveau_abi16_put(abi16, -ENOENT);
 
-       ret = nvif_object_sclass(&chan->chan->user, sclass, ARRAY_SIZE(sclass));
+       ret = nvif_object_sclass_get(&chan->chan->user, &sclass);
        if (ret < 0)
                return nouveau_abi16_put(abi16, ret);
 
        if ((init->class & 0x00ff) == 0x006e) {
                /* nvsw: compatibility with older 0x*6e class identifier */
                for (i = 0; !oclass && i < ret; i++) {
-                       switch (sclass[i]) {
+                       switch (sclass[i].oclass) {
                        case NVIF_IOCTL_NEW_V0_SW_NV04:
                        case NVIF_IOCTL_NEW_V0_SW_NV10:
                        case NVIF_IOCTL_NEW_V0_SW_NV50:
                        case NVIF_IOCTL_NEW_V0_SW_GF100:
-                               oclass = sclass[i];
+                               oclass = sclass[i].oclass;
                                break;
                        default:
                                break;
@@ -406,8 +406,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
        if ((init->class & 0x00ff) == 0x00b1) {
                /* msvld: compatibility with incorrect version exposure */
                for (i = 0; i < ret; i++) {
-                       if ((sclass[i] & 0x00ff) == 0x00b1) {
-                               oclass = sclass[i];
+                       if ((sclass[i].oclass & 0x00ff) == 0x00b1) {
+                               oclass = sclass[i].oclass;
                                break;
                        }
                }
@@ -415,8 +415,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
        if ((init->class & 0x00ff) == 0x00b2) { /* mspdec */
                /* mspdec: compatibility with incorrect version exposure */
                for (i = 0; i < ret; i++) {
-                       if ((sclass[i] & 0x00ff) == 0x00b2) {
-                               oclass = sclass[i];
+                       if ((sclass[i].oclass & 0x00ff) == 0x00b2) {
+                               oclass = sclass[i].oclass;
                                break;
                        }
                }
@@ -424,8 +424,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
        if ((init->class & 0x00ff) == 0x00b3) { /* msppp */
                /* msppp: compatibility with incorrect version exposure */
                for (i = 0; i < ret; i++) {
-                       if ((sclass[i] & 0x00ff) == 0x00b3) {
-                               oclass = sclass[i];
+                       if ((sclass[i].oclass & 0x00ff) == 0x00b3) {
+                               oclass = sclass[i].oclass;
                                break;
                        }
                }
@@ -433,6 +433,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
                oclass = init->class;
        }
 
+       nvif_object_sclass_put(&sclass);
        if (!oclass)
                return nouveau_abi16_put(abi16, -EINVAL);
 
index 65ceb6f..37dbd5e 100644 (file)
@@ -152,9 +152,9 @@ static void
 nouveau_accel_init(struct nouveau_drm *drm)
 {
        struct nvif_device *device = &drm->device;
+       struct nvif_sclass *sclass;
        u32 arg0, arg1;
-       s32 sclass[16];
-       int ret, i;
+       int ret, i, n;
 
        if (nouveau_noaccel)
                return;
@@ -163,12 +163,12 @@ nouveau_accel_init(struct nouveau_drm *drm)
        /*XXX: this is crap, but the fence/channel stuff is a little
         *     backwards in some places.  this will be fixed.
         */
-       ret = nvif_object_sclass(&device->object, sclass, ARRAY_SIZE(sclass));
+       ret = n = nvif_object_sclass_get(&device->object, &sclass);
        if (ret < 0)
                return;
 
-       for (ret = -ENOSYS, i = 0; ret && i < ARRAY_SIZE(sclass); i++) {
-               switch (sclass[i]) {
+       for (ret = -ENOSYS, i = 0; i < n; i++) {
+               switch (sclass[i].oclass) {
                case NV03_CHANNEL_DMA:
                        ret = nv04_fence_create(drm);
                        break;
@@ -195,6 +195,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
                }
        }
 
+       nvif_object_sclass_put(&sclass);
        if (ret) {
                NV_ERROR(drm, "failed to initialise sync subsystem, %d\n", ret);
                nouveau_accel_fini(drm);
Simple merge