Index: drm_irq.c =================================================================== --- drm_irq.c (revision 183574) +++ drm_irq.c (working copy) @@ -175,13 +175,6 @@ DRM_UNLOCK(); /* Install handler */ - dev->irqrid = 0; - dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, - &dev->irqrid, RF_SHAREABLE); - if (!dev->irqr) { - retcode = ENOENT; - goto err; - } #if __FreeBSD_version >= 700031 retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, @@ -204,25 +197,17 @@ err: DRM_LOCK(); dev->irq_enabled = 0; - if (dev->irqrid != 0) { - bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, - dev->irqr); - dev->irqrid = 0; - } DRM_UNLOCK(); + return retcode; } int drm_irq_uninstall(struct drm_device *dev) { - int irqrid; - if (!dev->irq_enabled) return EINVAL; dev->irq_enabled = 0; - irqrid = dev->irqrid; - dev->irqrid = 0; DRM_DEBUG("irq=%d\n", dev->irq); @@ -230,7 +215,6 @@ DRM_UNLOCK(); bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); DRM_LOCK(); drm_vblank_cleanup(dev); Index: i915_irq.c =================================================================== --- i915_irq.c (revision 183574) +++ i915_irq.c (working copy) @@ -435,22 +435,20 @@ u32 iir; u32 pipea_stats = 0, pipeb_stats = 0; int vblank = 0; -#ifdef __linux__ - if (dev->pdev->msi_enabled) + + if (dev->msi_enabled) I915_WRITE(IMR, ~0); -#endif + iir = I915_READ(IIR); #if 0 DRM_DEBUG("flag=%08x\n", iir); #endif atomic_inc(&dev_priv->irq_received); if (iir == 0) { -#ifdef __linux__ - if (dev->pdev->msi_enabled) { + if (dev->msi_enabled) { I915_WRITE(IMR, dev_priv->irq_mask_reg); (void) I915_READ(IMR); } -#endif return IRQ_NONE; } @@ -505,10 +503,8 @@ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); I915_WRITE(IIR, iir); -#ifdef __linux__ - if (dev->pdev->msi_enabled) + if (dev->msi_enabled) I915_WRITE(IMR, dev_priv->irq_mask_reg); -#endif (void) I915_READ(IIR); /* Flush posted writes */ if (iir & I915_USER_INTERRUPT) { Index: drmP.h =================================================================== --- drmP.h (revision 183574) +++ drmP.h (working copy) @@ -668,6 +668,7 @@ /* Context support */ int irq; /* Interrupt used by board */ int irq_enabled; /* True if the irq handler is enabled */ + int msi_enabled; /* MSI enabled */ int irqrid; /* Interrupt used by board */ struct resource *irqr; /* Resource for interrupt used by board */ void *irqh; /* Handle from bus_setup_intr */ Index: drm_drv.c =================================================================== --- drm_drv.c (revision 183574) +++ drm_drv.c (working copy) @@ -165,7 +165,7 @@ { struct drm_device *dev; drm_pci_id_list_t *id_entry; - int unit; + int unit, msicount; unit = device_get_unit(nbdev); dev = device_get_softc(nbdev); @@ -185,6 +185,25 @@ DRM_DEV_MODE, "dri/card%d", unit); + msicount = pci_msi_count(dev->device); + DRM_DEBUG("MSI count = %d\n", msicount); + if (msicount > 1) + msicount = 1; + + if (pci_alloc_msi(dev->device, &msicount) == 0) { + DRM_INFO("MSI enabled %d message(s)\n", msicount); + dev->msi_enabled = 1; + dev->irqrid = 1; + } + + dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, + &dev->irqrid, RF_SHAREABLE); + if (!dev->irqr) { + return ENOENT; + } + + dev->irq = (int) rman_get_start(dev->irqr); + mtx_init(&dev->dev_lock, "drmdev", NULL, MTX_DEF); mtx_init(&dev->irq_lock, "drmirq", NULL, MTX_DEF); mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); @@ -198,9 +217,21 @@ return drm_load(dev); } -int drm_detach(device_t dev) +int drm_detach(device_t nbdev) { - drm_unload(device_get_softc(dev)); + struct drm_device *dev; + + dev = device_get_softc(nbdev); + + drm_unload(dev); + + bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); + + if (dev->msi_enabled) { + pci_release_msi(dev->device); + DRM_INFO("MSI released\n"); + } + return 0; } @@ -349,7 +380,6 @@ DRM_DEBUG("\n"); - dev->irq = pci_get_irq(dev->device); #if __FreeBSD_version >= 700053 dev->pci_domain = pci_get_domain(dev->device); #else @@ -506,7 +536,6 @@ mtx_destroy(&dev->dev_lock); } - int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_version *version = data;