From: Ben Skeggs Date: Fri, 5 Dec 2014 01:26:23 +0000 (+1000) Subject: drm/nouveau/core: fix subdev/engine/device lookup to not require engine pointer X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=490d595f321d16f34040836c494d7875eb8f66a4;p=deliverable%2Flinux.git drm/nouveau/core: fix subdev/engine/device lookup to not require engine pointer It's about to not be valid for objects that aren't in the client object tree. Signed-off-by: Ben Skeggs --- diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/core/core/engine.c index 4835056b0689..85bf4b3d1fe4 100644 --- a/drivers/gpu/drm/nouveau/core/core/engine.c +++ b/drivers/gpu/drm/nouveau/core/core/engine.c @@ -27,11 +27,11 @@ #include struct nouveau_engine * -nouveau_engine(void *obj, int sub) +nouveau_engine(void *obj, int idx) { - struct nouveau_subdev *subdev = nouveau_subdev(obj, sub); - if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS)) - return nv_engine(subdev); + obj = nouveau_subdev(obj, idx); + if (obj && nv_iclass(obj, NV_ENGINE_CLASS)) + return nv_engine(obj); return NULL; } diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c index edae535406e5..69ba1482c3f5 100644 --- a/drivers/gpu/drm/nouveau/core/core/subdev.c +++ b/drivers/gpu/drm/nouveau/core/core/subdev.c @@ -28,11 +28,14 @@ #include struct nouveau_subdev * -nouveau_subdev(void *obj, int sub) +nouveau_subdev(void *obj, int idx) { - if (nv_device(obj)->subdev[sub]) - return nv_subdev(nv_device(obj)->subdev[sub]); - return NULL; + struct nouveau_object *object = nv_object(obj); + while (object && !nv_iclass(object, NV_SUBDEV_CLASS)) + object = object->parent; + if (object == NULL || nv_subidx(object) != idx) + object = nv_device(obj)->subdev[idx]; + return object ? nv_subdev(object) : NULL; } void diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index e2da1d4029cd..7c0cbcde7b2f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -511,22 +511,18 @@ nouveau_devobj_ofuncs = { struct nouveau_device * nv_device(void *obj) { - struct nouveau_object *object = nv_object(obj); - struct nouveau_object *device = object; - - if (device->engine) - device = device->engine; - if (device->parent) + struct nouveau_object *device = nv_object(obj); + while (device && device->parent) device = device->parent; - -#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA - if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) || - (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) { - nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x", - nv_hclass(object), nv_hclass(device)); + if (!nv_iclass(device, NV_ENGINE_CLASS)) { + device = nv_object(obj)->engine; + if (device && device->parent) + device = device->parent; } +#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA + if (unlikely(!device)) + nv_assert("BAD CAST -> NvDevice, 0x%08x\n", nv_hclass(obj)); #endif - return (void *)device; }