From 2950f9e6823d43abae151966ae808d1a63e6659c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 17 Oct 2003 05:13:48 +0000 Subject: - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from __HAVE_DMA. This will be useful for adding vblank sync support to sis and tdfx. Rename dma_service to irq_handler, which is more accurately what it is. - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have the right number of underscores. This may have been a problem in the case that the server died without doing its DRM_IOCTL_CONTROL to uninit. --- bsd-core/drmP.h | 20 +++-- bsd-core/drm_dma.c | 227 ++-------------------------------------------- bsd-core/drm_drv.c | 12 +-- bsd-core/drm_irq.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++ bsd-core/mga_drv.c | 1 + bsd-core/r128_drv.c | 1 + bsd-core/radeon_drv.c | 1 + 7 files changed, 268 insertions(+), 236 deletions(-) create mode 100644 bsd-core/drm_irq.c (limited to 'bsd-core') diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 0a93ef32..c39df162 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -49,8 +49,8 @@ #ifndef __HAVE_DMA #define __HAVE_DMA 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #define DRM_DEBUG_CODE 0 /* Include debugging code (if > 1, then @@ -437,19 +437,21 @@ extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); extern void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp); -#if __HAVE_DMA_IRQ +#endif + +#if __HAVE_IRQ + /* IRQ support (drm_irq.h) */ extern int DRM(irq_install)( drm_device_t *dev, int irq ); extern int DRM(irq_uninstall)( drm_device_t *dev ); -extern irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ); +extern irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ); extern void DRM(driver_irq_preinstall)( drm_device_t *dev ); extern void DRM(driver_irq_postinstall)( drm_device_t *dev ); extern void DRM(driver_irq_uninstall)( drm_device_t *dev ); -#if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS ); +#if __HAVE_IRQ_BH +extern void DRM(irq_immediate_bh)( DRM_TASKQUEUE_ARGS ); #endif #endif -#endif /* __HAVE_DMA */ #if __HAVE_VBL_IRQ extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); extern void DRM(vbl_send_signals)( drm_device_t *dev ); @@ -524,8 +526,8 @@ extern int DRM(freebufs)(DRM_IOCTL_ARGS); extern int DRM(mapbufs)(DRM_IOCTL_ARGS); #endif -/* DMA support (drm_dma.h) */ -#if __HAVE_DMA +/* IRQ support (drm_irq.h) */ +#if __HAVE_IRQ || __HAVE_DMA extern int DRM(control)(DRM_IOCTL_ARGS); #endif #if __HAVE_VBL_IRQ diff --git a/bsd-core/drm_dma.c b/bsd-core/drm_dma.c index 6c502efb..877fd4e1 100644 --- a/bsd-core/drm_dma.c +++ b/bsd-core/drm_dma.c @@ -149,224 +149,11 @@ void DRM(reclaim_buffers)(drm_device_t *dev, DRMFILE filp) } #endif - -#if __HAVE_DMA_IRQ - -int DRM(irq_install)( drm_device_t *dev, int irq ) -{ - int retcode; - - if ( irq == 0 || dev->dev_private == NULL) - return DRM_ERR(EINVAL); - - DRM_LOCK(); - if ( dev->irq ) { - DRM_UNLOCK(); - return DRM_ERR(EBUSY); - } - dev->irq = irq; - DRM_UNLOCK(); - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - dev->context_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->this_buffer = NULL; - -#if __HAVE_DMA_IRQ_BH - TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); -#endif - -#if __HAVE_VBL_IRQ && 0 /* disabled */ - DRM_SPININIT( dev->vbl_lock, "vblsig" ); - TAILQ_INIT( &dev->vbl_sig_list ); -#endif - - /* Before installing handler */ - DRM(driver_irq_preinstall)( dev ); - - /* Install handler */ - dev->irqrid = 0; -#ifdef __FreeBSD__ - dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, - 0, ~0, 1, RF_SHAREABLE); - if (!dev->irqr) { -#elif defined(__NetBSD__) - if (pci_intr_map(&dev->pa, &dev->ih) != 0) { -#endif - DRM_LOCK(); - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK(); - return ENOENT; - } - -#ifdef __FreeBSD__ -#if __FreeBSD_version < 500000 - retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, - DRM(dma_service), dev, &dev->irqh); -#else - retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, - DRM(dma_service), dev, &dev->irqh); -#endif - if ( retcode ) { -#elif defined(__NetBSD__) - dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, - (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(dma_service), dev); - if ( !dev->irqh ) { -#endif - DRM_LOCK(); -#ifdef __FreeBSD__ - bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); -#endif - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK(); - return retcode; - } - - /* After installing handler */ - DRM(driver_irq_postinstall)( dev ); - - return 0; -} - -int DRM(irq_uninstall)( drm_device_t *dev ) -{ - int irq; - int irqrid; - - DRM_LOCK(); - irq = dev->irq; - irqrid = dev->irqrid; - dev->irq = 0; - dev->irqrid = 0; - DRM_UNLOCK(); - - if ( !irq ) - return DRM_ERR(EINVAL); - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - DRM(driver_irq_uninstall)( dev ); - -#ifdef __FreeBSD__ - bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); -#elif defined(__NetBSD__) - pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); -#endif - - return 0; -} - -int DRM(control)( DRM_IOCTL_ARGS ) -{ - DRM_DEVICE; - drm_control_t ctl; - - DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); - - switch ( ctl.func ) { - case DRM_INST_HANDLER: - return DRM(irq_install)( dev, ctl.irq ); - case DRM_UNINST_HANDLER: - return DRM(irq_uninstall)( dev ); - default: - return DRM_ERR(EINVAL); - } -} - -#if __HAVE_VBL_IRQ -int DRM(wait_vblank)( DRM_IOCTL_ARGS ) -{ - DRM_DEVICE; - drm_wait_vblank_t vblwait; - struct timeval now; - int ret; - - if (!dev->irq) - return DRM_ERR(EINVAL); - - DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, - sizeof(vblwait) ); - - if (vblwait.request.type & _DRM_VBLANK_RELATIVE) { - vblwait.request.sequence += atomic_read(&dev->vbl_received); - vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; - } - - flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; - if (flags & _DRM_VBLANK_SIGNAL) { -#if 0 /* disabled */ - drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); - if (vbl_sig == NULL) - return ENOMEM; - bzero(vbl_sig, sizeof(*vbl_sig)); - - vbl_sig->sequence = vblwait.request.sequence; - vbl_sig->signo = vblwait.request.signal; - vbl_sig->pid = DRM_CURRENTPID; - - vblwait.reply.sequence = atomic_read(&dev->vbl_received); - - DRM_SPINLOCK(&dev->vbl_lock); - TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); - DRM_SPINUNLOCK(&dev->vbl_lock); - ret = 0; -#endif - ret = EINVAL; - } else { - ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); - - microtime(&now); - vblwait.reply.tval_sec = now.tv_sec; - vblwait.reply.tval_usec = now.tv_usec; - } - - DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, - sizeof(vblwait) ); - - return ret; -} - -void DRM(vbl_send_signals)(drm_device_t *dev) -{ -} - -#if 0 /* disabled */ -void DRM(vbl_send_signals)( drm_device_t *dev ) -{ - drm_vbl_sig_t *vbl_sig; - unsigned int vbl_seq = atomic_read( &dev->vbl_received ); - struct proc *p; - - DRM_SPINLOCK(&dev->vbl_lock); - - vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); - while (vbl_sig != NULL) { - drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); - - if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { - p = pfind(vbl_sig->pid); - if (p != NULL) - psignal(p, vbl_sig->signo); - - TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); - DRM_FREE(vbl_sig,sizeof(*vbl_sig)); - } - vbl_sig = next; - } - - DRM_SPINUNLOCK(&dev->vbl_lock); -} -#endif - -#endif /* __HAVE_VBL_IRQ */ - -#else - +#if !__HAVE_IRQ +/* This stub DRM_IOCTL_CONTROL handler is for the drivers that used to require + * IRQs for DMA but no longer do. It maintains compatibility with the X Servers + * that try to use the control ioctl by simply returning success. + */ int DRM(control)( DRM_IOCTL_ARGS ) { drm_control_t ctl; @@ -381,8 +168,6 @@ int DRM(control)( DRM_IOCTL_ARGS ) return DRM_ERR(EINVAL); } } - -#endif /* __HAVE_DMA_IRQ */ +#endif #endif /* __HAVE_DMA */ - diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index bfded6bb..8a9e3036 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -55,8 +55,8 @@ #ifndef __HAVE_CTX_BITMAP #define __HAVE_CTX_BITMAP 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #ifndef __HAVE_DMA_QUEUE #define __HAVE_DMA_QUEUE 0 @@ -170,9 +170,9 @@ static drm_ioctl_desc_t DRM(ioctls)[] = { [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 }, - - /* The DRM_IOCTL_DMA ioctl should be defined by the driver. - */ + /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ +#endif +#if __HAVE_IRQ || __HAVE_DMA [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif @@ -510,7 +510,7 @@ static int DRM(takedown)( drm_device_t *dev ) DRM_DEBUG( "\n" ); DRIVER_PRETAKEDOWN(); -#if __HAVE_DMA_IRQ +#if __HAVE_IRQ if (dev->irq != 0) DRM(irq_uninstall)( dev ); #endif diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c new file mode 100644 index 00000000..3366ff1c --- /dev/null +++ b/bsd-core/drm_irq.c @@ -0,0 +1,242 @@ +/* drm_dma.c -- DMA IOCTL and function support + * Created: Fri Oct 18 2003 by anholt@FreeBSD.org + * + * Copyright 2003 Eric Anholt + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +int DRM(irq_install)( drm_device_t *dev, int irq ) +{ + int retcode; + + if ( irq == 0 || dev->dev_private == NULL) + return DRM_ERR(EINVAL); + + DRM_LOCK(); + if ( dev->irq ) { + DRM_UNLOCK(); + return DRM_ERR(EBUSY); + } + dev->irq = irq; + DRM_UNLOCK(); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + dev->context_flag = 0; + + dev->dma->next_buffer = NULL; + dev->dma->this_buffer = NULL; + +#if __HAVE_IRQ_BH + TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); +#endif + +#if __HAVE_VBL_IRQ && 0 /* disabled */ + DRM_SPININIT( dev->vbl_lock, "vblsig" ); + TAILQ_INIT( &dev->vbl_sig_list ); +#endif + + /* Before installing handler */ + DRM(driver_irq_preinstall)( dev ); + + /* Install handler */ + dev->irqrid = 0; +#ifdef __FreeBSD__ + dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid, + 0, ~0, 1, RF_SHAREABLE); + if (!dev->irqr) { +#elif defined(__NetBSD__) + if (pci_intr_map(&dev->pa, &dev->ih) != 0) { +#endif + DRM_LOCK(); + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + return ENOENT; + } + +#ifdef __FreeBSD__ +#if __FreeBSD_version < 500000 + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY, + DRM(irq_handler), dev, &dev->irqh); +#else + retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE, + DRM(irq_handler), dev, &dev->irqh); +#endif + if ( retcode ) { +#elif defined(__NetBSD__) + dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY, + (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(irq_handler), dev); + if ( !dev->irqh ) { +#endif + DRM_LOCK(); +#ifdef __FreeBSD__ + bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr); +#endif + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + return retcode; + } + + /* After installing handler */ + DRM(driver_irq_postinstall)( dev ); + + return 0; +} + +int DRM(irq_uninstall)( drm_device_t *dev ) +{ + int irq; + int irqrid; + + DRM_LOCK(); + irq = dev->irq; + irqrid = dev->irqrid; + dev->irq = 0; + dev->irqrid = 0; + DRM_UNLOCK(); + + if ( !irq ) + return DRM_ERR(EINVAL); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + DRM(driver_irq_uninstall)( dev ); + +#ifdef __FreeBSD__ + bus_teardown_intr(dev->device, dev->irqr, dev->irqh); + bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr); +#elif defined(__NetBSD__) + pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh); +#endif + + return 0; +} + +int DRM(control)( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_control_t ctl; + + DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) ); + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + return DRM(irq_install)( dev, ctl.irq ); + case DRM_UNINST_HANDLER: + return DRM(irq_uninstall)( dev ); + default: + return DRM_ERR(EINVAL); + } +} + +#if __HAVE_VBL_IRQ +int DRM(wait_vblank)( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret; + + if (!dev->irq) + return DRM_ERR(EINVAL); + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + if (vblwait.request.type & _DRM_VBLANK_RELATIVE) { + vblwait.request.sequence += atomic_read(&dev->vbl_received); + vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; + } + + flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; + if (flags & _DRM_VBLANK_SIGNAL) { +#if 0 /* disabled */ + drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); + if (vbl_sig == NULL) + return ENOMEM; + bzero(vbl_sig, sizeof(*vbl_sig)); + + vbl_sig->sequence = vblwait.request.sequence; + vbl_sig->signo = vblwait.request.signal; + vbl_sig->pid = DRM_CURRENTPID; + + vblwait.reply.sequence = atomic_read(&dev->vbl_received); + + DRM_SPINLOCK(&dev->vbl_lock); + TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); + DRM_SPINUNLOCK(&dev->vbl_lock); + ret = 0; +#endif + ret = EINVAL; + } else { + ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); + + microtime(&now); + vblwait.reply.tval_sec = now.tv_sec; + vblwait.reply.tval_usec = now.tv_usec; + } + + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +void DRM(vbl_send_signals)(drm_device_t *dev) +{ +} + +#if 0 /* disabled */ +void DRM(vbl_send_signals)( drm_device_t *dev ) +{ + drm_vbl_sig_t *vbl_sig; + unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + struct proc *p; + + DRM_SPINLOCK(&dev->vbl_lock); + + vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list); + while (vbl_sig != NULL) { + drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link); + + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + p = pfind(vbl_sig->pid); + if (p != NULL) + psignal(p, vbl_sig->signo); + + TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); + DRM_FREE(vbl_sig,sizeof(*vbl_sig)); + } + vbl_sig = next; + } + + DRM_SPINUNLOCK(&dev->vbl_lock); +} +#endif + +#endif /* __HAVE_VBL_IRQ */ diff --git a/bsd-core/mga_drv.c b/bsd-core/mga_drv.c index 4eaf5edb..477086e2 100644 --- a/bsd-core/mga_drv.c +++ b/bsd-core/mga_drv.c @@ -45,6 +45,7 @@ #include "drm_drv.h" #include "drm_fops.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_vm.h" diff --git a/bsd-core/r128_drv.c b/bsd-core/r128_drv.c index e656f60d..a9af3694 100644 --- a/bsd-core/r128_drv.c +++ b/bsd-core/r128_drv.c @@ -48,6 +48,7 @@ #include "drm_drv.h" #include "drm_fops.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_pci.h" diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index 3b699768..df941f9e 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -46,6 +46,7 @@ #include "drm_drv.h" #include "drm_fops.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_pci.h" -- cgit v1.2.3