From 41a634064db489713945e228e216336080ba57f8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 20 Aug 2015 14:54:16 +1000 Subject: drm/nouveau/nvif: return min/max versions for supported object classes Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvif/object.c | 53 ++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/nouveau/nvif') diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index 0c09e6433fbb..c3fb6a20f567 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -48,26 +48,53 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) data, size, hack); } +void +nvif_object_sclass_put(struct nvif_sclass **psclass) +{ + kfree(*psclass); + *psclass = NULL; +} + int -nvif_object_sclass(struct nvif_object *object, s32 *oclass, int count) +nvif_object_sclass_get(struct nvif_object *object, struct nvif_sclass **psclass) { struct { struct nvif_ioctl_v0 ioctl; struct nvif_ioctl_sclass_v0 sclass; - } *args; - u32 size = count * sizeof(args->sclass.oclass[0]); - int ret; + } *args = NULL; + int ret, cnt = 0, i; + u32 size; - if (!(args = kmalloc(sizeof(*args) + size, GFP_KERNEL))) - return -ENOMEM; - args->ioctl.version = 0; - args->ioctl.type = NVIF_IOCTL_V0_SCLASS; - args->sclass.version = 0; - args->sclass.count = count; + while (1) { + size = sizeof(*args) + cnt * sizeof(args->sclass.oclass[0]); + if (!(args = kmalloc(size, GFP_KERNEL))) + return -ENOMEM; + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_SCLASS; + args->sclass.version = 0; + args->sclass.count = cnt; + + ret = nvif_object_ioctl(object, args, size, NULL); + if (ret == 0 && args->sclass.count <= cnt) + break; + cnt = args->sclass.count; + kfree(args); + if (ret != 0) + return ret; + } + + *psclass = kzalloc(sizeof(**psclass) * args->sclass.count, GFP_KERNEL); + if (*psclass) { + for (i = 0; i < args->sclass.count; i++) { + (*psclass)[i].oclass = args->sclass.oclass[i].oclass; + (*psclass)[i].minver = args->sclass.oclass[i].minver; + (*psclass)[i].maxver = args->sclass.oclass[i].maxver; + } + ret = args->sclass.count; + } else { + ret = -ENOMEM; + } - ret = nvif_object_ioctl(object, args, sizeof(*args) + size, NULL); - ret = ret ? ret : args->sclass.count; - memcpy(oclass, args->sclass.oclass, size); kfree(args); return ret; } -- cgit v1.2.3-59-g8ed1b