Commit 7a1c2f6c authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie

vmwgfx: Enable use of the vblank system

This is to avoid accessing uninitialized data during
drm_irq_uninstall and vblank ioctls. At the same time, enable error check from
drm_kms_init which previously appeared to ignore all errors.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 30c78bb8
...@@ -374,17 +374,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -374,17 +374,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
dev->dev_private = dev_priv; dev->dev_private = dev_priv;
if (!dev->devname)
dev->devname = vmw_devname;
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
ret = drm_irq_install(dev);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed installing irq: %d\n", ret);
goto out_no_irq;
}
}
ret = pci_request_regions(dev->pdev, "vmwgfx probe"); ret = pci_request_regions(dev->pdev, "vmwgfx probe");
dev_priv->stealth = (ret != 0); dev_priv->stealth = (ret != 0);
if (dev_priv->stealth) { if (dev_priv->stealth) {
...@@ -400,7 +389,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -400,7 +389,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
goto out_no_device; goto out_no_device;
} }
} }
vmw_kms_init(dev_priv); ret = vmw_kms_init(dev_priv);
if (unlikely(ret != 0))
goto out_no_kms;
vmw_overlay_init(dev_priv); vmw_overlay_init(dev_priv);
if (dev_priv->enable_fb) { if (dev_priv->enable_fb) {
ret = vmw_3d_resource_inc(dev_priv); ret = vmw_3d_resource_inc(dev_priv);
...@@ -416,24 +407,37 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -416,24 +407,37 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
"running the device in SVGA mode yet.\n"); "running the device in SVGA mode yet.\n");
} }
if (!dev->devname)
dev->devname = vmw_devname;
if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
ret = drm_irq_install(dev);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed installing irq: %d\n", ret);
goto out_no_irq;
}
}
dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
register_pm_notifier(&dev_priv->pm_nb); register_pm_notifier(&dev_priv->pm_nb);
return 0; return 0;
out_no_irq:
if (dev_priv->enable_fb) {
vmw_fb_close(dev_priv);
vmw_kms_restore_vga(dev_priv);
vmw_3d_resource_dec(dev_priv);
}
out_no_fifo: out_no_fifo:
vmw_overlay_close(dev_priv); vmw_overlay_close(dev_priv);
vmw_kms_close(dev_priv); vmw_kms_close(dev_priv);
out_no_kms:
if (dev_priv->stealth) if (dev_priv->stealth)
pci_release_region(dev->pdev, 2); pci_release_region(dev->pdev, 2);
else else
pci_release_regions(dev->pdev); pci_release_regions(dev->pdev);
out_no_device: out_no_device:
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
drm_irq_uninstall(dev_priv->dev);
if (dev->devname == vmw_devname)
dev->devname = NULL;
out_no_irq:
ttm_object_device_release(&dev_priv->tdev); ttm_object_device_release(&dev_priv->tdev);
out_err4: out_err4:
iounmap(dev_priv->mmio_virt); iounmap(dev_priv->mmio_virt);
...@@ -460,6 +464,10 @@ static int vmw_driver_unload(struct drm_device *dev) ...@@ -460,6 +464,10 @@ static int vmw_driver_unload(struct drm_device *dev)
unregister_pm_notifier(&dev_priv->pm_nb); unregister_pm_notifier(&dev_priv->pm_nb);
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
drm_irq_uninstall(dev_priv->dev);
if (dev->devname == vmw_devname)
dev->devname = NULL;
if (dev_priv->enable_fb) { if (dev_priv->enable_fb) {
vmw_fb_close(dev_priv); vmw_fb_close(dev_priv);
vmw_kms_restore_vga(dev_priv); vmw_kms_restore_vga(dev_priv);
...@@ -472,10 +480,6 @@ static int vmw_driver_unload(struct drm_device *dev) ...@@ -472,10 +480,6 @@ static int vmw_driver_unload(struct drm_device *dev)
else else
pci_release_regions(dev->pdev); pci_release_regions(dev->pdev);
if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
drm_irq_uninstall(dev_priv->dev);
if (dev->devname == vmw_devname)
dev->devname = NULL;
ttm_object_device_release(&dev_priv->tdev); ttm_object_device_release(&dev_priv->tdev);
iounmap(dev_priv->mmio_virt); iounmap(dev_priv->mmio_virt);
drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
...@@ -798,6 +802,7 @@ static struct drm_driver driver = { ...@@ -798,6 +802,7 @@ static struct drm_driver driver = {
.irq_postinstall = vmw_irq_postinstall, .irq_postinstall = vmw_irq_postinstall,
.irq_uninstall = vmw_irq_uninstall, .irq_uninstall = vmw_irq_uninstall,
.irq_handler = vmw_irq_handler, .irq_handler = vmw_irq_handler,
.get_vblank_counter = vmw_get_vblank_counter,
.reclaim_buffers_locked = NULL, .reclaim_buffers_locked = NULL,
.get_map_ofs = drm_core_get_map_ofs, .get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs, .get_reg_ofs = drm_core_get_reg_ofs,
......
...@@ -518,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, ...@@ -518,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv,
unsigned bbp, unsigned depth); unsigned bbp, unsigned depth);
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc);
/** /**
* Overlay control - vmwgfx_overlay.c * Overlay control - vmwgfx_overlay.c
......
...@@ -996,3 +996,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, ...@@ -996,3 +996,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
ttm_read_unlock(&vmaster->lock); ttm_read_unlock(&vmaster->lock);
return ret; return ret;
} }
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
{
return 0;
}
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "vmwgfx_kms.h" #include "vmwgfx_kms.h"
#define VMWGFX_LDU_NUM_DU 8
#define vmw_crtc_to_ldu(x) \ #define vmw_crtc_to_ldu(x) \
container_of(x, struct vmw_legacy_display_unit, base.crtc) container_of(x, struct vmw_legacy_display_unit, base.crtc)
#define vmw_encoder_to_ldu(x) \ #define vmw_encoder_to_ldu(x) \
...@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
{ {
struct drm_device *dev = dev_priv->dev;
int i;
int ret;
if (dev_priv->ldu_priv) { if (dev_priv->ldu_priv) {
DRM_INFO("ldu system already on\n"); DRM_INFO("ldu system already on\n");
return -EINVAL; return -EINVAL;
...@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) ...@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
drm_mode_create_dirty_info_property(dev_priv->dev); drm_mode_create_dirty_info_property(dev_priv->dev);
vmw_ldu_init(dev_priv, 0);
/* for old hardware without multimon only enable one display */
if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
vmw_ldu_init(dev_priv, 1); for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i)
vmw_ldu_init(dev_priv, 2); vmw_ldu_init(dev_priv, i);
vmw_ldu_init(dev_priv, 3); ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU);
vmw_ldu_init(dev_priv, 4); } else {
vmw_ldu_init(dev_priv, 5); /* for old hardware without multimon only enable one display */
vmw_ldu_init(dev_priv, 6); vmw_ldu_init(dev_priv, 0);
vmw_ldu_init(dev_priv, 7); ret = drm_vblank_init(dev, 1);
} }
return 0; return ret;
} }
int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv)
{ {
struct drm_device *dev = dev_priv->dev;
drm_vblank_cleanup(dev);
if (!dev_priv->ldu_priv) if (!dev_priv->ldu_priv)
return -ENOSYS; return -ENOSYS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment