From 8c90df66fdee3134b064a036e95b5404b34e0634 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Fri, 9 May 2008 10:06:17 +0800 Subject: [PATCH] fix kernel oops when removing fb drm_crtc->fb may point to NULL, f.e X server will allocate a new fb and assign it to the CRTC at startup, when X server exits, it will destroy the allocated fb, making drm_crtc->fb points to NULL. --- linux-core/drmP.h | 2 +- linux-core/drm_crtc.c | 2 +- linux-core/intel_drv.h | 2 +- linux-core/intel_fb.c | 4 +--- linux-core/radeon_ms_fb.c | 2 +- shared-core/radeon_ms.h | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 52d2782..60ae018 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -744,7 +744,7 @@ struct drm_driver { /* FB routines, if present */ int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); - int (*fb_remove)(struct drm_device *dev, struct drm_crtc *crtc); + int (*fb_remove)(struct drm_device *dev, struct drm_framebuffer *fb); int (*fb_resize)(struct drm_device *dev, struct drm_crtc *crtc); /* Master routines */ diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 2bc1c4e..c011db3 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1095,7 +1095,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) if (fb->bo->type != drm_bo_type_kernel) drm_framebuffer_destroy(fb); else - dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb)); + dev->driver->fb_remove(dev, fb); } list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index 6b89c00..e97117d 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -91,7 +91,7 @@ extern int intel_sdvo_supports_hotplug(struct drm_output *output); extern void intel_sdvo_set_hotplug(struct drm_output *output, int enable); extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); -extern int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc); +extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc); #endif /* __INTEL_DRV_H__ */ diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 50c24a7..9934e3a 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -767,9 +767,8 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_outp } EXPORT_SYMBOL(intelfb_probe); -int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc) +int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) { - struct drm_framebuffer *fb = crtc->fb; struct fb_info *info; if (!fb) @@ -784,7 +783,6 @@ int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc) drm_framebuffer_destroy(fb); framebuffer_release(info); } - crtc->fb = NULL; return 0; } EXPORT_SYMBOL(intelfb_remove); diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c index ae4f2da..082279e 100644 --- a/linux-core/radeon_ms_fb.c +++ b/linux-core/radeon_ms_fb.c @@ -438,7 +438,7 @@ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_out } EXPORT_SYMBOL(radeonfb_probe); -int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc) +int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *kern_fb) { struct drm_radeon_private *dev_priv = dev->dev_private; struct amd_fb *fb = dev_priv->fb; diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h index 1fdcd0a..f3bbc9a 100644 --- a/shared-core/radeon_ms.h +++ b/shared-core/radeon_ms.h @@ -436,7 +436,7 @@ int r3xx_fence_types(struct drm_buffer_object *bo, /* radeon_ms_fb.c */ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); -int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc); +int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); /* radeon_ms_gpu.c */ int radeon_ms_gpu_initialize(struct drm_device *dev); -- 1.5.0.5