The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/drm_irq.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* drm_dma.c -- DMA IOCTL and function support
    2  * Created: Fri Oct 18 2003 by anholt@FreeBSD.org */
    3 /*-
    4  * Copyright 2003 Eric Anholt
    5  * All Rights Reserved.
    6  *
    7  * Permission is hereby granted, free of charge, to any person obtaining a
    8  * copy of this software and associated documentation files (the "Software"),
    9  * to deal in the Software without restriction, including without limitation
   10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   11  * and/or sell copies of the Software, and to permit persons to whom the
   12  * Software is furnished to do so, subject to the following conditions:
   13  *
   14  * The above copyright notice and this permission notice (including the next
   15  * paragraph) shall be included in all copies or substantial portions of the
   16  * Software.
   17  *
   18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   21  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   24  * OTHER DEALINGS IN THE SOFTWARE.
   25  *
   26  * Authors:
   27  *    Eric Anholt <anholt@FreeBSD.org>
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 int DRM(irq_by_busid)( DRM_IOCTL_ARGS )
   33 {
   34         DRM_DEVICE;
   35         drm_irq_busid_t irq;
   36 
   37         DRM_COPY_FROM_USER_IOCTL(irq, (drm_irq_busid_t *)data, sizeof(irq));
   38 
   39         if ((irq.busnum >> 8) != dev->pci_domain ||
   40             (irq.busnum & 0xff) != dev->pci_bus ||
   41             irq.devnum != dev->pci_slot ||
   42             irq.funcnum != dev->pci_func)
   43                 return EINVAL;
   44 
   45         irq.irq = dev->irq;
   46 
   47         DRM_DEBUG("%d:%d:%d => IRQ %d\n",
   48                   irq.busnum, irq.devnum, irq.funcnum, irq.irq);
   49 
   50         DRM_COPY_TO_USER_IOCTL( (drm_irq_busid_t *)data, irq, sizeof(irq) );
   51 
   52         return 0;
   53 }
   54 
   55 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
   56 static irqreturn_t
   57 DRM(irq_handler_wrap)(DRM_IRQ_ARGS)
   58 {
   59         drm_device_t *dev = (drm_device_t *)arg;
   60 
   61         DRM_SPINLOCK(&dev->irq_lock);
   62         DRM(irq_handler)(arg);
   63         DRM_SPINUNLOCK(&dev->irq_lock);
   64 }
   65 #endif
   66 
   67 int DRM(irq_install)(drm_device_t *dev)
   68 {
   69         int retcode;
   70 
   71         if (dev->irq == 0 || dev->dev_private == NULL)
   72                 return DRM_ERR(EINVAL);
   73 
   74         DRM_LOCK();
   75         if (dev->irq_enabled) {
   76                 DRM_UNLOCK();
   77                 return DRM_ERR(EBUSY);
   78         }
   79         dev->irq_enabled = 1;
   80         DRM_UNLOCK();
   81 
   82         DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
   83 
   84         dev->context_flag = 0;
   85 
   86         dev->dma->next_buffer = NULL;
   87         dev->dma->this_buffer = NULL;
   88 
   89 #if __HAVE_IRQ_BH
   90         TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
   91 #endif
   92 
   93         DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
   94 
   95                                 /* Before installing handler */
   96         DRM(driver_irq_preinstall)( dev );
   97 
   98                                 /* Install handler */
   99 #ifdef __FreeBSD__
  100         dev->irqrid = 0;
  101         dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, 
  102                                       &dev->irqrid, RF_SHAREABLE);
  103         if (!dev->irqr) {
  104                 retcode = ENOENT;
  105                 goto err;
  106         }
  107 #if __FreeBSD_version < 500000
  108         retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
  109                                  DRM(irq_handler), dev, &dev->irqh);
  110 #else
  111         retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE,
  112                                  DRM(irq_handler_wrap), dev, &dev->irqh);
  113 #endif
  114         if (retcode != 0)
  115                 goto err;
  116 #elif defined(__NetBSD__)
  117         if (pci_intr_map(&dev->pa, &dev->ih) != 0) {
  118                 retcode = ENOENT;
  119                 goto err;
  120         }
  121         dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY,
  122             (irqreturn_t (*)(DRM_IRQ_ARGS))DRM(irq_handler), dev);
  123         if (!dev->irqh) {
  124                 retcode = ENOENT;
  125                 goto err;
  126         }
  127 #endif
  128 
  129                                 /* After installing handler */
  130         DRM(driver_irq_postinstall)( dev );
  131 
  132         return 0;
  133 err:
  134         DRM_LOCK();
  135         dev->irq_enabled = 0;
  136 #ifdef ___FreeBSD__
  137         if (dev->irqrid != 0) {
  138                 bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid,
  139                     dev->irqr);
  140                 dev->irqrid = 0;
  141         }
  142 #endif
  143         DRM_SPINUNINIT(dev->irq_lock);
  144         DRM_UNLOCK();
  145         return retcode;
  146 }
  147 
  148 /* XXX: This function needs to be called with the device lock held.  In some
  149  * cases it isn't, so far.
  150  */
  151 int DRM(irq_uninstall)( drm_device_t *dev )
  152 {
  153         int irqrid;
  154 
  155         if (!dev->irq_enabled)
  156                 return DRM_ERR(EINVAL);
  157 
  158         dev->irq_enabled = 0;
  159         irqrid = dev->irqrid;
  160         dev->irqrid = 0;
  161 
  162         DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
  163 
  164         DRM(driver_irq_uninstall)( dev );
  165 
  166 #ifdef __FreeBSD__
  167         bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
  168         bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
  169 #elif defined(__NetBSD__)
  170         pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
  171 #endif
  172         DRM_SPINUNINIT(dev->irq_lock);
  173 
  174         return 0;
  175 }
  176 
  177 int DRM(control)( DRM_IOCTL_ARGS )
  178 {
  179         DRM_DEVICE;
  180         drm_control_t ctl;
  181         int err;
  182 
  183         DRM_COPY_FROM_USER_IOCTL( ctl, (drm_control_t *) data, sizeof(ctl) );
  184 
  185         switch ( ctl.func ) {
  186         case DRM_INST_HANDLER:
  187                 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
  188                     ctl.irq != dev->irq)
  189                         return DRM_ERR(EINVAL);
  190                 return DRM(irq_install)(dev);
  191         case DRM_UNINST_HANDLER:
  192                 DRM_LOCK();
  193                 err = DRM(irq_uninstall)( dev );
  194                 DRM_UNLOCK();
  195                 return err;
  196         default:
  197                 return DRM_ERR(EINVAL);
  198         }
  199 }
  200 
  201 #if __HAVE_VBL_IRQ
  202 int DRM(wait_vblank)( DRM_IOCTL_ARGS )
  203 {
  204         DRM_DEVICE;
  205         drm_wait_vblank_t vblwait;
  206         struct timeval now;
  207         int ret;
  208 
  209         if (!dev->irq_enabled)
  210                 return DRM_ERR(EINVAL);
  211 
  212         DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
  213                                   sizeof(vblwait) );
  214 
  215         if (vblwait.request.type & _DRM_VBLANK_RELATIVE) {
  216                 vblwait.request.sequence += atomic_read(&dev->vbl_received);
  217                 vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
  218         }
  219 
  220         flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
  221         if (flags & _DRM_VBLANK_SIGNAL) {
  222 #if 0 /* disabled */
  223                 drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t));
  224                 if (vbl_sig == NULL)
  225                         return ENOMEM;
  226                 bzero(vbl_sig, sizeof(*vbl_sig));
  227                 
  228                 vbl_sig->sequence = vblwait.request.sequence;
  229                 vbl_sig->signo = vblwait.request.signal;
  230                 vbl_sig->pid = DRM_CURRENTPID;
  231 
  232                 vblwait.reply.sequence = atomic_read(&dev->vbl_received);
  233                 
  234                 DRM_SPINLOCK(&dev->irq_lock);
  235                 TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
  236                 DRM_SPINUNLOCK(&dev->irq_lock);
  237                 ret = 0;
  238 #endif
  239                 ret = EINVAL;
  240         } else {
  241                 ret = DRM(vblank_wait)(dev, &vblwait.request.sequence);
  242                 
  243                 microtime(&now);
  244                 vblwait.reply.tval_sec = now.tv_sec;
  245                 vblwait.reply.tval_usec = now.tv_usec;
  246         }
  247 
  248         DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
  249                                 sizeof(vblwait) );
  250 
  251         return ret;
  252 }
  253 
  254 void DRM(vbl_send_signals)(drm_device_t *dev)
  255 {
  256 }
  257 
  258 #if 0 /* disabled */
  259 void DRM(vbl_send_signals)( drm_device_t *dev )
  260 {
  261         drm_vbl_sig_t *vbl_sig;
  262         unsigned int vbl_seq = atomic_read( &dev->vbl_received );
  263         struct proc *p;
  264 
  265         vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list);
  266         while (vbl_sig != NULL) {
  267                 drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link);
  268 
  269                 if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
  270                         p = pfind(vbl_sig->pid);
  271                         if (p != NULL)
  272                                 psignal(p, vbl_sig->signo);
  273 
  274                         TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
  275                         DRM_FREE(vbl_sig,sizeof(*vbl_sig));
  276                 }
  277                 vbl_sig = next;
  278         }
  279 }
  280 #endif
  281 
  282 #endif /*  __HAVE_VBL_IRQ */

Cache object: c7175e5fc6f02d2825b1aaf7139436b2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.