#include <nvif/os.h>
+struct nvif_sclass {
+ s32 oclass;
+ int minver;
+ int maxver;
+};
+
struct nvif_object {
struct nvif_client *client;
u32 handle;
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);
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;
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;
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;
}
}
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;
}
}
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;
}
}
oclass = init->class;
}
+ nvif_object_sclass_put(&sclass);
if (!oclass)
return nouveau_abi16_put(abi16, -EINVAL);
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;
/*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;
}
}
+ nvif_object_sclass_put(&sclass);
if (ret) {
NV_ERROR(drm, "failed to initialise sync subsystem, %d\n", ret);
nouveau_accel_fini(drm);