data, size, hack);
}
+void
+nvif_object_sclass_put(struct nvif_sclass **psclass)
+{
+ kfree(*psclass);
+ *psclass = NULL;
+}
+
int
-nvif_object_sclass(struct nvif_object *object, u32 *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;
+ }
- memcpy(args->sclass.oclass, oclass, size);
- 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;
}
}
int
-nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass,
+nvif_object_init(struct nvif_object *parent, u32 handle, s32 oclass,
void *data, u32 size, struct nvif_object *object)
{
struct {