Index: bsd/drm/kernel/drmP.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v retrieving revision 1.34 diff -u -r1.34 drmP.h --- bsd/drm/kernel/drmP.h 17 Oct 2003 03:14:38 -0000 1.34 +++ bsd/drm/kernel/drmP.h 17 Oct 2003 03:30:54 -0000 @@ -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,20 @@ 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 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 ); @@ -528,6 +529,7 @@ #if __HAVE_DMA extern int DRM(control)(DRM_IOCTL_ARGS); #endif +/* IRQ support (drm_dma.h) */ #if __HAVE_VBL_IRQ extern int DRM(wait_vblank)(DRM_IOCTL_ARGS); #endif Index: bsd/drm/kernel/drm_dma.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_dma.h,v retrieving revision 1.26 diff -u -r1.26 drm_dma.h --- bsd/drm/kernel/drm_dma.h 3 Oct 2003 07:02:51 -0000 1.26 +++ bsd/drm/kernel/drm_dma.h 17 Oct 2003 04:40:28 -0000 @@ -149,224 +149,11 @@ } #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 @@ return DRM_ERR(EINVAL); } } - -#endif /* __HAVE_DMA_IRQ */ +#endif #endif /* __HAVE_DMA */ - Index: bsd/drm/kernel/drm_drv.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm_drv.h,v retrieving revision 1.31 diff -u -r1.31 drm_drv.h --- bsd/drm/kernel/drm_drv.h 17 Oct 2003 03:14:38 -0000 1.31 +++ bsd/drm/kernel/drm_drv.h 17 Oct 2003 04:34:15 -0000 @@ -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 @@ [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 @@ DRM_DEBUG( "\n" ); DRIVER_PRETAKEDOWN(); -#if __HAVE_DMA_IRQ +#if __HAVE_IRQ if (dev->irq != 0) DRM(irq_uninstall)( dev ); #endif Index: bsd/drm/kernel/drm_irq.h =================================================================== RCS file: bsd/drm/kernel/drm_irq.h diff -N bsd/drm/kernel/drm_irq.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ bsd/drm/kernel/drm_irq.h 17 Oct 2003 04:40:06 -0000 @@ -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 */ Index: bsd/drm/kernel/mga_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/mga_drv.c,v retrieving revision 1.8 diff -u -r1.8 mga_drv.c --- bsd/drm/kernel/mga_drv.c 17 Oct 2003 03:14:38 -0000 1.8 +++ bsd/drm/kernel/mga_drv.c 17 Oct 2003 04:38:22 -0000 @@ -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" Index: bsd/drm/kernel/r128_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/r128_drv.c,v retrieving revision 1.9 diff -u -r1.9 r128_drv.c --- bsd/drm/kernel/r128_drv.c 17 Oct 2003 03:14:38 -0000 1.9 +++ bsd/drm/kernel/r128_drv.c 17 Oct 2003 04:38:12 -0000 @@ -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" Index: bsd/drm/kernel/radeon_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/radeon_drv.c,v retrieving revision 1.11 diff -u -r1.11 radeon_drv.c --- bsd/drm/kernel/radeon_drv.c 17 Oct 2003 03:14:38 -0000 1.11 +++ bsd/drm/kernel/radeon_drv.c 17 Oct 2003 04:38:06 -0000 @@ -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" Index: linux/drm/kernel/Doxyfile =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Doxyfile,v retrieving revision 1.1 diff -u -r1.1 Doxyfile --- linux/drm/kernel/Doxyfile 3 Jun 2003 23:50:22 -0000 1.1 +++ linux/drm/kernel/Doxyfile 17 Oct 2003 04:18:04 -0000 @@ -852,7 +852,7 @@ __HAVE_SG=0 \ __HAVE_PCI_DMA=0 \ __HAVE_DMA=1 \ - __HAVE_DMA_IRQ=1 \ + __HAVE_IRQ=1 \ __HAVE_VBL_IRQ=1 \ __HAVE_SHARED_IRQ=1 Index: linux/drm/kernel/Makefile.linux =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux,v retrieving revision 1.57 diff -u -r1.57 Makefile.linux --- linux/drm/kernel/Makefile.linux 17 Oct 2003 03:14:38 -0000 1.57 +++ linux/drm/kernel/Makefile.linux 17 Oct 2003 04:26:32 -0000 @@ -59,7 +59,7 @@ # These definitions are for handling dependencies in the out of kernel build. DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ - drm_drv.h drm_fops.h drm_init.h drm_ioctl.h \ + drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_irq.h \ drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h DRMSHARED = drm_sarea.h Index: linux/drm/kernel/drmP.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v retrieving revision 1.81 diff -u -r1.81 drmP.h --- linux/drm/kernel/drmP.h 17 Oct 2003 03:14:38 -0000 1.81 +++ linux/drm/kernel/drmP.h 17 Oct 2003 04:06:00 -0000 @@ -102,8 +102,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 #ifndef __HAVE_DMA_WAITLIST #define __HAVE_DMA_WAITLIST 0 @@ -937,12 +937,17 @@ 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)( struct file *filp ); -#if __HAVE_DMA_IRQ +#endif /* __HAVE_DMA */ + +#if __HAVE_IRQ || __HAVE_DMA extern int DRM(control)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +#endif + +#if __HAVE_IRQ 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 ); @@ -952,12 +957,11 @@ extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); extern void DRM(vbl_send_signals)( drm_device_t *dev ); #endif -#if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( void *dev ); +#if __HAVE_IRQ_BH +extern void DRM(irq_immediate_bh)( void *dev ); #endif #endif -#endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP /* AGP/GART support (drm_agpsupport.h) */ Index: linux/drm/kernel/drm_dma.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_dma.h,v retrieving revision 1.25 diff -u -r1.25 drm_dma.h --- linux/drm/kernel/drm_dma.h 15 Aug 2003 10:31:54 -0000 1.25 +++ linux/drm/kernel/drm_dma.h 17 Oct 2003 04:22:27 -0000 @@ -36,7 +36,6 @@ #define __NO_VERSION__ #include "drmP.h" -#include /* For task queue support */ #ifndef __HAVE_DMA_WAITQUEUE #define __HAVE_DMA_WAITQUEUE 0 @@ -44,15 +43,6 @@ #ifndef __HAVE_DMA_RECLAIM #define __HAVE_DMA_RECLAIM 0 #endif -#ifndef __HAVE_SHARED_IRQ -#define __HAVE_SHARED_IRQ 0 -#endif - -#if __HAVE_SHARED_IRQ -#define DRM_IRQ_TYPE SA_SHIRQ -#else -#define DRM_IRQ_TYPE 0 -#endif #if __HAVE_DMA @@ -215,303 +205,14 @@ } #endif - - - -#if __HAVE_DMA_IRQ - -/** - * Install IRQ handler. - * - * \param dev DRM device. - * \param irq IRQ number. - * - * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver - * \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions - * before and after the installation. - */ -int DRM(irq_install)( drm_device_t *dev, int irq ) -{ - int ret; - - if ( !irq ) - return -EINVAL; - - down( &dev->struct_sem ); - - /* Driver must have been initialized */ - if ( !dev->dev_private ) { - up( &dev->struct_sem ); - return -EINVAL; - } - - if ( dev->irq ) { - up( &dev->struct_sem ); - return -EBUSY; - } - dev->irq = irq; - up( &dev->struct_sem ); - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - -#if __HAVE_DMA_IRQ_BH -#if !HAS_WORKQUEUE - INIT_LIST_HEAD( &dev->tq.list ); - dev->tq.sync = 0; - dev->tq.routine = DRM(dma_immediate_bh); - dev->tq.data = dev; -#else - INIT_WORK(&dev->work, DRM(dma_immediate_bh), dev); -#endif -#endif - -#if __HAVE_VBL_IRQ - init_waitqueue_head(&dev->vbl_queue); - - spin_lock_init( &dev->vbl_lock ); - - INIT_LIST_HEAD( &dev->vbl_sigs.head ); - - dev->vbl_pending = 0; -#endif - - /* Before installing handler */ - DRM(driver_irq_preinstall)(dev); - - /* Install handler */ - ret = request_irq( dev->irq, DRM(dma_service), - DRM_IRQ_TYPE, dev->devname, dev ); - if ( ret < 0 ) { - down( &dev->struct_sem ); - dev->irq = 0; - up( &dev->struct_sem ); - return ret; - } - - /* After installing handler */ - DRM(driver_irq_postinstall)(dev); - - return 0; -} - -/** - * Uninstall the IRQ handler. - * - * \param dev DRM device. - * - * Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq. - */ -int DRM(irq_uninstall)( drm_device_t *dev ) -{ - int irq; - - down( &dev->struct_sem ); - irq = dev->irq; - dev->irq = 0; - up( &dev->struct_sem ); - - if ( !irq ) - return -EINVAL; - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - DRM(driver_irq_uninstall)( dev ); - - free_irq( irq, dev ); - - return 0; -} - -/** - * IRQ control ioctl. - * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param arg user argument, pointing to a drm_control structure. - * \return zero on success or a negative number on failure. - * - * Calls irq_install() or irq_uninstall() according to \p arg. +#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)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_control_t ctl; - - if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) - return -EFAULT; - - 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 -EINVAL; - } -} - -#if __HAVE_VBL_IRQ - -/** - * Wait for VBLANK. - * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param data user argument, pointing to a drm_wait_vblank structure. - * \return zero on success or a negative number on failure. - * - * Verifies the IRQ is installed. - * - * If a signal is requested checks if this task has already scheduled the same signal - * for the same vblank sequence number - nothing to be done in - * that case. If the number of tasks waiting for the interrupt exceeds 100 the - * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this - * task. - * - * If a signal is not requested, then calls vblank_wait(). - */ -int DRM(wait_vblank)( DRM_IOCTL_ARGS ) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_wait_vblank_t vblwait; - struct timeval now; - int ret = 0; - unsigned int flags; - - if (!dev->irq) - return -EINVAL; - - DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, - sizeof(vblwait) ); - - switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) { - case _DRM_VBLANK_RELATIVE: - vblwait.request.sequence += atomic_read( &dev->vbl_received ); - vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; - case _DRM_VBLANK_ABSOLUTE: - break; - default: - return -EINVAL; - } - - flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; - - if ( flags & _DRM_VBLANK_SIGNAL ) { - unsigned long irqflags; - drm_vbl_sig_t *vbl_sig; - - vblwait.reply.sequence = atomic_read( &dev->vbl_received ); - - spin_lock_irqsave( &dev->vbl_lock, irqflags ); - - /* Check if this task has already scheduled the same signal - * for the same vblank sequence number; nothing to be done in - * that case - */ - list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) { - if (vbl_sig->sequence == vblwait.request.sequence - && vbl_sig->info.si_signo == vblwait.request.signal - && vbl_sig->task == current) - { - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); - goto done; - } - } - - if ( dev->vbl_pending >= 100 ) { - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); - return -EBUSY; - } - - dev->vbl_pending++; - - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); - - if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) { - return -ENOMEM; - } - - memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) ); - - vbl_sig->sequence = vblwait.request.sequence; - vbl_sig->info.si_signo = vblwait.request.signal; - vbl_sig->task = current; - - spin_lock_irqsave( &dev->vbl_lock, irqflags ); - - list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head ); - - spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); - } else { - ret = DRM(vblank_wait)( dev, &vblwait.request.sequence ); - - do_gettimeofday( &now ); - vblwait.reply.tval_sec = now.tv_sec; - vblwait.reply.tval_usec = now.tv_usec; - } - -done: - DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, - sizeof(vblwait) ); - - return ret; -} - -/** - * Send the VBLANK signals. - * - * \param dev DRM device. - * - * Sends a signal for each task in drm_device::vbl_sigs and empties the list. - * - * If a signal is not requested, then calls vblank_wait(). - */ -void DRM(vbl_send_signals)( drm_device_t *dev ) -{ - struct list_head *list, *tmp; - drm_vbl_sig_t *vbl_sig; - unsigned int vbl_seq = atomic_read( &dev->vbl_received ); - unsigned long flags; - - spin_lock_irqsave( &dev->vbl_lock, flags ); - - list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) { - vbl_sig = list_entry( list, drm_vbl_sig_t, head ); - if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { - vbl_sig->info.si_code = vbl_seq; - send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); - - list_del( list ); - - DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); - - dev->vbl_pending--; - } - } - - spin_unlock_irqrestore( &dev->vbl_lock, flags ); -} - -#endif /* __HAVE_VBL_IRQ */ - -#else - -int DRM(control)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) -{ drm_control_t ctl; if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) @@ -525,7 +226,6 @@ return -EINVAL; } } - -#endif /* __HAVE_DMA_IRQ */ +#endif #endif /* __HAVE_DMA */ Index: linux/drm/kernel/drm_drv.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h,v retrieving revision 1.44 diff -u -r1.44 drm_drv.h --- linux/drm/kernel/drm_drv.h 17 Oct 2003 03:14:38 -0000 1.44 +++ linux/drm/kernel/drm_drv.h 17 Oct 2003 04:01:04 -0000 @@ -58,8 +58,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 @@ -215,9 +215,9 @@ [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 @@ -384,7 +384,7 @@ DRM_DEBUG( "\n" ); DRIVER_PRETAKEDOWN(); -#if __HAVE_DMA_IRQ +#if __HAVE_IRQ if ( dev->irq ) DRM(irq_uninstall)( dev ); #endif Index: linux/drm/kernel/drm_irq.h =================================================================== RCS file: linux/drm/kernel/drm_irq.h diff -N linux/drm/kernel/drm_irq.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ linux/drm/kernel/drm_irq.h 17 Oct 2003 04:18:59 -0000 @@ -0,0 +1,340 @@ +/** + * \file drm_irq.h + * DMA IRQ support + * + * \author Rickard E. (Rik) Faith + * \author Gareth Hughes + */ + +/* + * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * 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. + */ + +#define __NO_VERSION__ +#include "drmP.h" + +#include /* For task queue support */ + +#ifndef __HAVE_SHARED_IRQ +#define __HAVE_SHARED_IRQ 0 +#endif + +#if __HAVE_SHARED_IRQ +#define DRM_IRQ_TYPE SA_SHIRQ +#else +#define DRM_IRQ_TYPE 0 +#endif + +#if __HAVE_IRQ + +/** + * Install IRQ handler. + * + * \param dev DRM device. + * \param irq IRQ number. + * + * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver + * \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions + * before and after the installation. + */ +int DRM(irq_install)( drm_device_t *dev, int irq ) +{ + int ret; + + if ( !irq ) + return -EINVAL; + + down( &dev->struct_sem ); + + /* Driver must have been initialized */ + if ( !dev->dev_private ) { + up( &dev->struct_sem ); + return -EINVAL; + } + + if ( dev->irq ) { + up( &dev->struct_sem ); + return -EBUSY; + } + dev->irq = irq; + up( &dev->struct_sem ); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + dev->context_flag = 0; + dev->interrupt_flag = 0; + dev->dma_flag = 0; + + dev->dma->next_buffer = NULL; + dev->dma->next_queue = NULL; + dev->dma->this_buffer = NULL; + +#if __HAVE_IRQ_BH +#if !HAS_WORKQUEUE + INIT_LIST_HEAD( &dev->tq.list ); + dev->tq.sync = 0; + dev->tq.routine = DRM(irq_immediate_bh); + dev->tq.data = dev; +#else + INIT_WORK(&dev->work, DRM(irq_immediate_bh), dev); +#endif +#endif + +#if __HAVE_VBL_IRQ + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init( &dev->vbl_lock ); + + INIT_LIST_HEAD( &dev->vbl_sigs.head ); + + dev->vbl_pending = 0; +#endif + + /* Before installing handler */ + DRM(driver_irq_preinstall)(dev); + + /* Install handler */ + ret = request_irq( dev->irq, DRM(irq_handler), + DRM_IRQ_TYPE, dev->devname, dev ); + if ( ret < 0 ) { + down( &dev->struct_sem ); + dev->irq = 0; + up( &dev->struct_sem ); + return ret; + } + + /* After installing handler */ + DRM(driver_irq_postinstall)(dev); + + return 0; +} + +/** + * Uninstall the IRQ handler. + * + * \param dev DRM device. + * + * Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq. + */ +int DRM(irq_uninstall)( drm_device_t *dev ) +{ + int irq; + + down( &dev->struct_sem ); + irq = dev->irq; + dev->irq = 0; + up( &dev->struct_sem ); + + if ( !irq ) + return -EINVAL; + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + DRM(driver_irq_uninstall)( dev ); + + free_irq( irq, dev ); + + return 0; +} + +/** + * IRQ control ioctl. + * + * \param inode device inode. + * \param filp file pointer. + * \param cmd command. + * \param arg user argument, pointing to a drm_control structure. + * \return zero on success or a negative number on failure. + * + * Calls irq_install() or irq_uninstall() according to \p arg. + */ +int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_control_t ctl; + + if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + 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 -EINVAL; + } +} + +#if __HAVE_VBL_IRQ + +/** + * Wait for VBLANK. + * + * \param inode device inode. + * \param filp file pointer. + * \param cmd command. + * \param data user argument, pointing to a drm_wait_vblank structure. + * \return zero on success or a negative number on failure. + * + * Verifies the IRQ is installed. + * + * If a signal is requested checks if this task has already scheduled the same signal + * for the same vblank sequence number - nothing to be done in + * that case. If the number of tasks waiting for the interrupt exceeds 100 the + * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this + * task. + * + * If a signal is not requested, then calls vblank_wait(). + */ +int DRM(wait_vblank)( DRM_IOCTL_ARGS ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_wait_vblank_t vblwait; + struct timeval now; + int ret = 0; + unsigned int flags; + + if (!dev->irq) + return -EINVAL; + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + sizeof(vblwait) ); + + switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) { + case _DRM_VBLANK_RELATIVE: + vblwait.request.sequence += atomic_read( &dev->vbl_received ); + vblwait.request.type &= ~_DRM_VBLANK_RELATIVE; + case _DRM_VBLANK_ABSOLUTE: + break; + default: + return -EINVAL; + } + + flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; + + if ( flags & _DRM_VBLANK_SIGNAL ) { + unsigned long irqflags; + drm_vbl_sig_t *vbl_sig; + + vblwait.reply.sequence = atomic_read( &dev->vbl_received ); + + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + /* Check if this task has already scheduled the same signal + * for the same vblank sequence number; nothing to be done in + * that case + */ + list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) { + if (vbl_sig->sequence == vblwait.request.sequence + && vbl_sig->info.si_signo == vblwait.request.signal + && vbl_sig->task == current) + { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + goto done; + } + } + + if ( dev->vbl_pending >= 100 ) { + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + return -EBUSY; + } + + dev->vbl_pending++; + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + + if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) { + return -ENOMEM; + } + + memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) ); + + vbl_sig->sequence = vblwait.request.sequence; + vbl_sig->info.si_signo = vblwait.request.signal; + vbl_sig->task = current; + + spin_lock_irqsave( &dev->vbl_lock, irqflags ); + + list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head ); + + spin_unlock_irqrestore( &dev->vbl_lock, irqflags ); + } else { + ret = DRM(vblank_wait)( dev, &vblwait.request.sequence ); + + do_gettimeofday( &now ); + vblwait.reply.tval_sec = now.tv_sec; + vblwait.reply.tval_usec = now.tv_usec; + } + +done: + DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait, + sizeof(vblwait) ); + + return ret; +} + +/** + * Send the VBLANK signals. + * + * \param dev DRM device. + * + * Sends a signal for each task in drm_device::vbl_sigs and empties the list. + * + * If a signal is not requested, then calls vblank_wait(). + */ +void DRM(vbl_send_signals)( drm_device_t *dev ) +{ + struct list_head *list, *tmp; + drm_vbl_sig_t *vbl_sig; + unsigned int vbl_seq = atomic_read( &dev->vbl_received ); + unsigned long flags; + + spin_lock_irqsave( &dev->vbl_lock, flags ); + + list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) { + vbl_sig = list_entry( list, drm_vbl_sig_t, head ); + if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) { + vbl_sig->info.si_code = vbl_seq; + send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task ); + + list_del( list ); + + DRM_FREE( vbl_sig, sizeof(*vbl_sig) ); + + dev->vbl_pending--; + } + } + + spin_unlock_irqrestore( &dev->vbl_lock, flags ); +} + +#endif /* __HAVE_VBL_IRQ */ + +#endif /* __HAVE_IRQ */ Index: linux/drm/kernel/gamma.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma.h,v retrieving revision 1.12 diff -u -r1.12 gamma.h --- linux/drm/kernel/gamma.h 17 Oct 2003 03:14:38 -0000 1.12 +++ linux/drm/kernel/gamma.h 17 Oct 2003 04:17:21 -0000 @@ -108,8 +108,8 @@ return 0; \ } while (0) -#define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 +#define __HAVE_IRQ 1 +#define __HAVE_IRQ_BH 1 #define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_gamma_private_t *)((dev)->dev_private))->buffers Index: linux/drm/kernel/gamma_dma.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v retrieving revision 1.29 diff -u -r1.29 gamma_dma.c --- linux/drm/kernel/gamma_dma.c 29 Jul 2003 10:11:48 -0000 1.29 +++ linux/drm/kernel/gamma_dma.c 17 Oct 2003 04:30:50 -0000 @@ -105,7 +105,7 @@ return(!GAMMA_READ(GAMMA_DMACOUNT)); } -irqreturn_t gamma_dma_service( DRM_IRQ_ARGS ) +irqreturn_t gamma_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *)arg; drm_device_dma_t *dma = dev->dma; @@ -253,7 +253,7 @@ gamma_dma_schedule((drm_device_t *)dev, 0); } -void gamma_dma_immediate_bh(void *dev) +void gamma_irq_immediate_bh(void *dev) { gamma_dma_schedule(dev, 0); } @@ -647,7 +647,7 @@ { DRM_DEBUG( "%s\n", __FUNCTION__ ); -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: linux/drm/kernel/gamma_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c,v retrieving revision 1.38 diff -u -r1.38 gamma_drv.c --- linux/drm/kernel/gamma_drv.c 19 Jun 2003 00:09:52 -0000 1.38 +++ linux/drm/kernel/gamma_drv.c 17 Oct 2003 04:24:12 -0000 @@ -48,6 +48,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "gamma_lists.h" /* NOTE */ #include "drm_lock.h" #include "gamma_lock.h" /* NOTE */ Index: linux/drm/kernel/i810.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810.h,v retrieving revision 1.13 diff -u -r1.13 i810.h --- linux/drm/kernel/i810.h 17 Oct 2003 03:14:38 -0000 1.13 +++ linux/drm/kernel/i810.h 17 Oct 2003 04:16:53 -0000 @@ -119,7 +119,7 @@ * a noop stub is generated for compatibility. */ /* XXX: Add vblank support? */ -#define __HAVE_DMA_IRQ 0 +#define __HAVE_IRQ 0 /* Buffer customization: */ Index: linux/drm/kernel/i810_dma.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c,v retrieving revision 1.53 diff -u -r1.53 i810_dma.c --- linux/drm/kernel/i810_dma.c 25 Sep 2003 23:04:10 -0000 1.53 +++ linux/drm/kernel/i810_dma.c 17 Oct 2003 04:17:48 -0000 @@ -239,7 +239,7 @@ { drm_device_dma_t *dma = dev->dma; -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: linux/drm/kernel/i830.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i830.h,v retrieving revision 1.8 diff -u -r1.8 i830.h --- linux/drm/kernel/i830.h 17 Oct 2003 03:14:38 -0000 1.8 +++ linux/drm/kernel/i830.h 17 Oct 2003 04:16:42 -0000 @@ -120,10 +120,10 @@ #define USE_IRQS 0 #if USE_IRQS -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_SHARED_IRQ 1 #else -#define __HAVE_DMA_IRQ 0 +#define __HAVE_IRQ 0 #endif Index: linux/drm/kernel/i830_dma.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i830_dma.c,v retrieving revision 1.21 diff -u -r1.21 i830_dma.c --- linux/drm/kernel/i830_dma.c 16 May 2003 23:41:27 -0000 1.21 +++ linux/drm/kernel/i830_dma.c 17 Oct 2003 04:17:06 -0000 @@ -238,7 +238,7 @@ { drm_device_dma_t *dma = dev->dma; -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: linux/drm/kernel/i830_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i830_drv.c,v retrieving revision 1.7 diff -u -r1.7 i830_drv.c --- linux/drm/kernel/i830_drv.c 19 Jun 2003 00:09:52 -0000 1.7 +++ linux/drm/kernel/i830_drv.c 17 Oct 2003 04:23:56 -0000 @@ -50,6 +50,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" Index: linux/drm/kernel/i830_irq.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i830_irq.c,v retrieving revision 1.5 diff -u -r1.5 i830_irq.c --- linux/drm/kernel/i830_irq.c 29 Jul 2003 10:11:48 -0000 1.5 +++ linux/drm/kernel/i830_irq.c 17 Oct 2003 03:52:21 -0000 @@ -36,7 +36,7 @@ #include -irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ) +irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *)arg; drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; Index: linux/drm/kernel/mga_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.c,v retrieving revision 1.38 diff -u -r1.38 mga_drv.c --- linux/drm/kernel/mga_drv.c 19 Jun 2003 00:09:52 -0000 1.38 +++ linux/drm/kernel/mga_drv.c 17 Oct 2003 04:24:50 -0000 @@ -45,6 +45,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" Index: linux/drm/kernel/r128_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c,v retrieving revision 1.46 diff -u -r1.46 r128_drv.c --- linux/drm/kernel/r128_drv.c 19 Jun 2003 00:09:52 -0000 1.46 +++ linux/drm/kernel/r128_drv.c 17 Oct 2003 04:24:40 -0000 @@ -47,6 +47,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" Index: linux/drm/kernel/radeon_drv.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c,v retrieving revision 1.20 diff -u -r1.20 radeon_drv.c --- linux/drm/kernel/radeon_drv.c 19 Jun 2003 00:09:52 -0000 1.20 +++ linux/drm/kernel/radeon_drv.c 17 Oct 2003 04:24:31 -0000 @@ -48,6 +48,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" Index: shared/drm/kernel/mga.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga.h,v retrieving revision 1.5 diff -u -r1.5 mga.h --- shared/drm/kernel/mga.h 17 Oct 2003 03:14:39 -0000 1.5 +++ shared/drm/kernel/mga.h 17 Oct 2003 04:02:44 -0000 @@ -84,7 +84,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 Index: shared/drm/kernel/mga_dma.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_dma.c,v retrieving revision 1.10 diff -u -r1.10 mga_dma.c --- shared/drm/kernel/mga_dma.c 16 May 2003 23:41:27 -0000 1.10 +++ shared/drm/kernel/mga_dma.c 17 Oct 2003 04:01:56 -0000 @@ -639,7 +639,7 @@ { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: shared/drm/kernel/mga_irq.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/mga_irq.c,v retrieving revision 1.7 diff -u -r1.7 mga_irq.c --- shared/drm/kernel/mga_irq.c 29 Jul 2003 10:11:48 -0000 1.7 +++ shared/drm/kernel/mga_irq.c 17 Oct 2003 03:51:40 -0000 @@ -36,7 +36,7 @@ #include "mga_drm.h" #include "mga_drv.h" -irqreturn_t mga_dma_service( DRM_IRQ_ARGS ) +irqreturn_t mga_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_mga_private_t *dev_priv = Index: shared/drm/kernel/r128.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128.h,v retrieving revision 1.9 diff -u -r1.9 r128.h --- shared/drm/kernel/r128.h 17 Oct 2003 03:14:39 -0000 1.9 +++ shared/drm/kernel/r128.h 17 Oct 2003 04:15:06 -0000 @@ -117,7 +117,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 Index: shared/drm/kernel/r128_cce.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_cce.c,v retrieving revision 1.12 diff -u -r1.12 r128_cce.c --- shared/drm/kernel/r128_cce.c 16 Oct 2003 14:18:52 -0000 1.12 +++ shared/drm/kernel/r128_cce.c 17 Oct 2003 04:15:15 -0000 @@ -594,7 +594,7 @@ int r128_do_cleanup_cce( drm_device_t *dev ) { -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: shared/drm/kernel/r128_irq.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_irq.c,v retrieving revision 1.7 diff -u -r1.7 r128_irq.c --- shared/drm/kernel/r128_irq.c 29 Jul 2003 10:11:48 -0000 1.7 +++ shared/drm/kernel/r128_irq.c 17 Oct 2003 03:51:49 -0000 @@ -36,7 +36,7 @@ #include "r128_drm.h" #include "r128_drv.h" -irqreturn_t r128_dma_service( DRM_IRQ_ARGS ) +irqreturn_t r128_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_r128_private_t *dev_priv = Index: shared/drm/kernel/radeon.h =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon.h,v retrieving revision 1.21 diff -u -r1.21 radeon.h --- shared/drm/kernel/radeon.h 17 Oct 2003 03:14:39 -0000 1.21 +++ shared/drm/kernel/radeon.h 17 Oct 2003 04:15:50 -0000 @@ -179,7 +179,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 Index: shared/drm/kernel/radeon_cp.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_cp.c,v retrieving revision 1.29 diff -u -r1.29 radeon_cp.c --- shared/drm/kernel/radeon_cp.c 26 Aug 2003 15:44:00 -0000 1.29 +++ shared/drm/kernel/radeon_cp.c 17 Oct 2003 04:15:58 -0000 @@ -1271,7 +1271,7 @@ { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if _HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. Index: shared/drm/kernel/radeon_irq.c =================================================================== RCS file: /home/ncvs/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/radeon_irq.c,v retrieving revision 1.16 diff -u -r1.16 radeon_irq.c --- shared/drm/kernel/radeon_irq.c 29 Jul 2003 10:11:48 -0000 1.16 +++ shared/drm/kernel/radeon_irq.c 17 Oct 2003 03:51:58 -0000 @@ -54,7 +54,7 @@ * tied to dma at all, this is just a hangover from dri prehistory. */ -irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ) +irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_radeon_private_t *dev_priv =