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/bktr/bktr_os.c

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 /* $FreeBSD: releng/5.0/sys/dev/bktr/bktr_os.c 107699 2002-12-09 09:04:09Z roger $ */
    2 
    3 /*
    4  * This is part of the Driver for Video Capture Cards (Frame grabbers)
    5  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
    6  * chipset.
    7  * Copyright Roger Hardiman and Amancio Hasty.
    8  *
    9  * bktr_os : This has all the Operating System dependant code,
   10  *             probe/attach and open/close/ioctl/read/mmap
   11  *             memory allocation
   12  *             PCI bus interfacing
   13  *             
   14  *
   15  */
   16 
   17 /*
   18  * 1. Redistributions of source code must retain the 
   19  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
   20  * All rights reserved.
   21  *
   22  * Redistribution and use in source and binary forms, with or without
   23  * modification, are permitted provided that the following conditions
   24  * are met:
   25  * 1. Redistributions of source code must retain the above copyright
   26  *    notice, this list of conditions and the following disclaimer.
   27  * 2. Redistributions in binary form must reproduce the above copyright
   28  *    notice, this list of conditions and the following disclaimer in the
   29  *    documentation and/or other materials provided with the distribution.
   30  * 3. All advertising materials mentioning features or use of this software
   31  *    must display the following acknowledgement:
   32  *      This product includes software developed by Amancio Hasty and
   33  *      Roger Hardiman
   34  * 4. The name of the author may not be used to endorse or promote products 
   35  *    derived from this software without specific prior written permission.
   36  *
   37  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   38  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   39  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   40  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   41  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   42  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   43  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   46  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   47  * POSSIBILITY OF SUCH DAMAGE.
   48  */
   49 
   50 
   51 #include "opt_bktr.h"           /* include any kernel config options */
   52 
   53 #define FIFO_RISC_DISABLED      0
   54 #define ALL_INTS_DISABLED       0
   55 
   56 
   57 /*******************/
   58 /* *** FreeBSD *** */
   59 /*******************/
   60 #ifdef __FreeBSD__
   61 
   62 #include <sys/param.h>
   63 #include <sys/systm.h>
   64 #include <sys/conf.h>
   65 #include <sys/uio.h>
   66 #include <sys/kernel.h>
   67 #include <sys/signalvar.h>
   68 #include <sys/mman.h>
   69 #include <sys/poll.h>
   70 #if __FreeBSD_version >= 500014
   71 #include <sys/selinfo.h>
   72 #else
   73 #include <sys/select.h>
   74 #endif
   75 #include <sys/vnode.h>
   76 
   77 #include <vm/vm.h>
   78 #include <vm/vm_kern.h>
   79 #include <vm/pmap.h>
   80 #include <vm/vm_extern.h>
   81 
   82 #if (__FreeBSD_version >=400000)
   83 #include <sys/bus.h>            /* used by smbus and newbus */
   84 #endif
   85 
   86 #if (__FreeBSD_version >=300000)
   87 #include <machine/bus_memio.h>  /* used by bus space */
   88 #include <machine/bus.h>        /* used by bus space and newbus */
   89 #include <sys/bus.h>
   90 #endif
   91 
   92 #if (__FreeBSD_version >=400000)
   93 #include <sys/rman.h>           /* used by newbus */
   94 #include <machine/resource.h>   /* used by newbus */
   95 #endif
   96 
   97 #if (__FreeBSD_version < 500000)
   98 #include <machine/clock.h>              /* for DELAY */
   99 #endif
  100 
  101 #include <pci/pcivar.h>
  102 #include <pci/pcireg.h>
  103 
  104 #include <sys/sysctl.h>
  105 int bt848_card = -1; 
  106 int bt848_tuner = -1;
  107 int bt848_reverse_mute = -1; 
  108 int bt848_format = -1;
  109 int bt848_slow_msp_audio = -1;
  110 
  111 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
  112 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
  113 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
  114 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
  115 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
  116 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
  117 
  118 #endif /* end freebsd section */
  119 
  120 
  121 
  122 /****************/
  123 /* *** BSDI *** */
  124 /****************/
  125 #ifdef __bsdi__
  126 #endif /* __bsdi__ */
  127 
  128 
  129 /**************************/
  130 /* *** OpenBSD/NetBSD *** */
  131 /**************************/
  132 #if defined(__NetBSD__) || defined(__OpenBSD__)
  133 
  134 #include <sys/param.h>
  135 #include <sys/systm.h>
  136 #include <sys/conf.h>
  137 #include <sys/uio.h>
  138 #include <sys/kernel.h>
  139 #include <sys/signalvar.h>
  140 #include <sys/mman.h>
  141 #include <sys/poll.h>
  142 #include <sys/select.h>
  143 #include <sys/vnode.h>
  144 
  145 #include <vm/vm.h>
  146 
  147 #ifndef __NetBSD__
  148 #include <vm/vm_kern.h>
  149 #include <vm/pmap.h>
  150 #include <vm/vm_extern.h>
  151 #endif
  152 
  153 #include <sys/device.h>
  154 #include <dev/pci/pcivar.h>
  155 #include <dev/pci/pcireg.h>
  156 #include <dev/pci/pcidevs.h>
  157 
  158 #define BKTR_DEBUG
  159 #ifdef BKTR_DEBUG
  160 int bktr_debug = 0;
  161 #define DPR(x)  (bktr_debug ? printf x : 0)
  162 #else
  163 #define DPR(x)
  164 #endif
  165 #endif /* __NetBSD__ || __OpenBSD__ */
  166 
  167 
  168 #ifdef __NetBSD__
  169 #include <dev/ic/bt8xx.h>       /* NetBSD location for .h files */
  170 #include <dev/pci/bktr/bktr_reg.h>
  171 #include <dev/pci/bktr/bktr_tuner.h>
  172 #include <dev/pci/bktr/bktr_card.h>
  173 #include <dev/pci/bktr/bktr_audio.h>
  174 #include <dev/pci/bktr/bktr_core.h>
  175 #include <dev/pci/bktr/bktr_os.h>
  176 #else                                   /* Traditional location for .h files */
  177 #include <machine/ioctl_meteor.h>
  178 #include <machine/ioctl_bt848.h>        /* extensions to ioctl_meteor.h */
  179 #include <dev/bktr/bktr_reg.h>
  180 #include <dev/bktr/bktr_tuner.h>
  181 #include <dev/bktr/bktr_card.h>
  182 #include <dev/bktr/bktr_audio.h>
  183 #include <dev/bktr/bktr_core.h>
  184 #include <dev/bktr/bktr_os.h>
  185 
  186 #if defined(BKTR_USE_FREEBSD_SMBUS)
  187 #include <dev/bktr/bktr_i2c.h>
  188 
  189 #include "iicbb_if.h"
  190 #include "smbus_if.h"
  191 #endif
  192 #endif
  193 
  194 
  195 /****************************/
  196 /* *** FreeBSD 4.x code *** */
  197 /****************************/
  198 #if (__FreeBSD_version >= 400000)
  199 
  200 static int      bktr_probe( device_t dev );
  201 static int      bktr_attach( device_t dev );
  202 static int      bktr_detach( device_t dev );
  203 static int      bktr_shutdown( device_t dev );
  204 static void     bktr_intr(void *arg) { common_bktr_intr(arg); }
  205 
  206 static device_method_t bktr_methods[] = {
  207         /* Device interface */
  208         DEVMETHOD(device_probe,         bktr_probe),
  209         DEVMETHOD(device_attach,        bktr_attach),
  210         DEVMETHOD(device_detach,        bktr_detach),
  211         DEVMETHOD(device_shutdown,      bktr_shutdown),
  212 
  213 #if defined(BKTR_USE_FREEBSD_SMBUS)
  214         /* iicbb interface */
  215         DEVMETHOD(iicbb_callback,       bti2c_iic_callback),
  216         DEVMETHOD(iicbb_setsda,         bti2c_iic_setsda),
  217         DEVMETHOD(iicbb_setscl,         bti2c_iic_setscl),
  218         DEVMETHOD(iicbb_getsda,         bti2c_iic_getsda),
  219         DEVMETHOD(iicbb_getscl,         bti2c_iic_getscl),
  220         DEVMETHOD(iicbb_reset,          bti2c_iic_reset),
  221         
  222         /* smbus interface */
  223         DEVMETHOD(smbus_callback,       bti2c_smb_callback),
  224         DEVMETHOD(smbus_writeb,         bti2c_smb_writeb),
  225         DEVMETHOD(smbus_writew,         bti2c_smb_writew),
  226         DEVMETHOD(smbus_readb,          bti2c_smb_readb),
  227 #endif
  228 
  229         { 0, 0 }
  230 };
  231 
  232 static driver_t bktr_driver = {
  233         "bktr",
  234         bktr_methods,
  235         sizeof(struct bktr_softc),
  236 };
  237 
  238 static devclass_t bktr_devclass;
  239 
  240 static  d_open_t        bktr_open;
  241 static  d_close_t       bktr_close;
  242 static  d_read_t        bktr_read;
  243 static  d_write_t       bktr_write;
  244 static  d_ioctl_t       bktr_ioctl;
  245 static  d_mmap_t        bktr_mmap;
  246 static  d_poll_t        bktr_poll;
  247 
  248 #define CDEV_MAJOR 92 
  249 static struct cdevsw bktr_cdevsw = {
  250         /* open */      bktr_open,
  251         /* close */     bktr_close,
  252         /* read */      bktr_read,
  253         /* write */     bktr_write,
  254         /* ioctl */     bktr_ioctl,
  255         /* poll */      bktr_poll,
  256         /* mmap */      bktr_mmap,
  257         /* strategy */  nostrategy,
  258         /* name */      "bktr",
  259         /* maj */       CDEV_MAJOR,
  260         /* dump */      nodump,
  261         /* psize */     nopsize,
  262         /* flags */     0,
  263 };
  264 
  265 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0);
  266 #if (__FreeBSD_version > 410000)
  267 MODULE_DEPEND(bktr, bktr_mem, 1,1,1);
  268 MODULE_VERSION(bktr, 1);
  269 #endif
  270 
  271 
  272 /*
  273  * the boot time probe routine.
  274  */
  275 static int
  276 bktr_probe( device_t dev )
  277 {
  278         unsigned int type = pci_get_devid(dev);
  279         unsigned int rev  = pci_get_revid(dev);
  280 
  281         if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
  282         {
  283                 switch (PCI_PRODUCT(type)) {
  284                 case PCI_PRODUCT_BROOKTREE_BT848:
  285                         if (rev == 0x12)
  286                                 device_set_desc(dev, "BrookTree 848A");
  287                         else
  288                                 device_set_desc(dev, "BrookTree 848");
  289                         return 0;
  290                 case PCI_PRODUCT_BROOKTREE_BT849:
  291                         device_set_desc(dev, "BrookTree 849A");
  292                         return 0;
  293                 case PCI_PRODUCT_BROOKTREE_BT878:
  294                         device_set_desc(dev, "BrookTree 878");
  295                         return 0;
  296                 case PCI_PRODUCT_BROOKTREE_BT879:
  297                         device_set_desc(dev, "BrookTree 879");
  298                         return 0;
  299                 }
  300         };
  301 
  302         return ENXIO;
  303 }
  304 
  305 
  306 /*
  307  * the attach routine.
  308  */
  309 static int
  310 bktr_attach( device_t dev )
  311 {
  312         u_long          latency;
  313         u_long          fun;
  314         u_long          val;
  315         unsigned int    rev;
  316         unsigned int    unit;
  317         int             error = 0;
  318 #ifdef BROOKTREE_IRQ
  319         u_long          old_irq, new_irq;
  320 #endif 
  321 
  322         struct bktr_softc *bktr = device_get_softc(dev);
  323 
  324         unit = device_get_unit(dev);
  325 
  326         /* build the device name for bktr_name() */
  327         snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
  328 
  329         /*
  330          * Enable bus mastering and Memory Mapped device
  331          */
  332         val = pci_read_config(dev, PCIR_COMMAND, 4);
  333         val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
  334         pci_write_config(dev, PCIR_COMMAND, val, 4);
  335 
  336         /*
  337          * Map control/status registers.
  338          */
  339         bktr->mem_rid = PCIR_MAPS;
  340         bktr->res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &bktr->mem_rid,
  341                                         0, ~0, 1, RF_ACTIVE);
  342 
  343 
  344         if (!bktr->res_mem) {
  345                 device_printf(dev, "could not map memory\n");
  346                 error = ENXIO;
  347                 goto fail;
  348         }
  349         bktr->memt = rman_get_bustag(bktr->res_mem);
  350         bktr->memh = rman_get_bushandle(bktr->res_mem);
  351 
  352 
  353         /*
  354          * Disable the brooktree device
  355          */
  356         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  357         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  358 
  359 
  360 #ifdef BROOKTREE_IRQ            /* from the configuration file */
  361         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
  362         pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
  363         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
  364         printf("bktr%d: attach: irq changed from %d to %d\n",
  365                 unit, (old_irq & 0xff), (new_irq & 0xff));
  366 #endif 
  367 
  368         /*
  369          * Allocate our interrupt.
  370          */
  371         bktr->irq_rid = 0;
  372         bktr->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &bktr->irq_rid,
  373                                 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
  374         if (bktr->res_irq == NULL) {
  375                 device_printf(dev, "could not map interrupt\n");
  376                 error = ENXIO;
  377                 goto fail;
  378         }
  379 
  380         error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_TTY,
  381                                bktr_intr, bktr, &bktr->res_ih);
  382         if (error) {
  383                 device_printf(dev, "could not setup irq\n");
  384                 goto fail;
  385 
  386         }
  387 
  388 
  389         /* Update the Device Control Register */
  390         /* on Bt878 and Bt879 cards           */
  391         fun = pci_read_config( dev, 0x40, 2);
  392         fun = fun | 1;  /* Enable writes to the sub-system vendor ID */
  393 
  394 #if defined( BKTR_430_FX_MODE )
  395         if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
  396         fun = fun | 2;  /* Enable Intel 430 FX compatibility mode */
  397 #endif
  398 
  399 #if defined( BKTR_SIS_VIA_MODE )
  400         if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
  401         fun = fun | 4;  /* Enable SiS/VIA compatibility mode (usefull for
  402                            OPTi chipset motherboards too */
  403 #endif
  404         pci_write_config(dev, 0x40, fun, 2);
  405 
  406 #if defined(BKTR_USE_FREEBSD_SMBUS)
  407         if (bt848_i2c_attach(dev))
  408                 printf("bktr%d: i2c_attach: can't attach\n", unit);
  409 #endif
  410 
  411 /*
  412  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
  413  * you have more than four, then 16 would probably be a better value.
  414  */
  415 #ifndef BROOKTREE_DEF_LATENCY_VALUE
  416 #define BROOKTREE_DEF_LATENCY_VALUE     10
  417 #endif
  418         latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
  419         latency = (latency >> 8) & 0xff;
  420         if ( bootverbose ) {
  421                 if (latency)
  422                         printf("brooktree%d: PCI bus latency is", unit);
  423                 else
  424                         printf("brooktree%d: PCI bus latency was 0 changing to",
  425                                 unit);
  426         }
  427         if ( !latency ) {
  428                 latency = BROOKTREE_DEF_LATENCY_VALUE;
  429                 pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
  430         }
  431         if ( bootverbose ) {
  432                 printf(" %d.\n", (int) latency);
  433         }
  434 
  435         /* read the pci device id and revision id */
  436         fun = pci_get_devid(dev);
  437         rev = pci_get_revid(dev);
  438 
  439         /* call the common attach code */
  440         common_bktr_attach( bktr, unit, fun, rev );
  441 
  442         /* make the device entries */
  443         bktr->bktrdev = make_dev(&bktr_cdevsw, unit,    
  444                                 0, 0, 0444, "bktr%d",  unit);
  445         bktr->tunerdev= make_dev(&bktr_cdevsw, unit+16,
  446                                 0, 0, 0444, "tuner%d", unit);
  447         bktr->vbidev  = make_dev(&bktr_cdevsw, unit+32,
  448                                 0, 0, 0444, "vbi%d"  , unit);
  449 
  450 
  451         /* if this is unit 0 (/dev/bktr0, /dev/tuner0, /dev/vbi0) then make */
  452         /* alias entries to /dev/bktr /dev/tuner and /dev/vbi */
  453 #if (__FreeBSD_version >=500000)
  454         if (unit == 0) {
  455                 bktr->bktrdev_alias = make_dev_alias(bktr->bktrdev,  "bktr");
  456                 bktr->tunerdev_alias= make_dev_alias(bktr->tunerdev, "tuner");
  457                 bktr->vbidev_alias  = make_dev_alias(bktr->vbidev,   "vbi");
  458         }
  459 #endif
  460 
  461         return 0;
  462 
  463 fail:
  464         if (bktr->res_irq)
  465                 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
  466         if (bktr->res_mem)
  467                 bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem);
  468         return error;
  469 
  470 }
  471 
  472 /*
  473  * the detach routine.
  474  */
  475 static int
  476 bktr_detach( device_t dev )
  477 {
  478         unsigned int    unit;
  479 
  480         struct bktr_softc *bktr = device_get_softc(dev);
  481 
  482         unit = device_get_unit(dev);
  483 
  484         /* Disable the brooktree device */
  485         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  486         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  487 
  488 #if defined(BKTR_USE_FREEBSD_SMBUS)
  489         if (bt848_i2c_detach(dev))
  490                 printf("bktr%d: i2c_attach: can't attach\n", unit);
  491 #endif
  492 
  493         /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
  494         /* The memory is retained by the bktr_mem module so we can unload and */
  495         /* then reload the main bktr driver module */
  496 
  497         /* Unregister the /dev/bktrN, tunerN and vbiN devices,
  498          * the aliases for unit 0 are automatically destroyed */
  499         destroy_dev(bktr->vbidev);
  500         destroy_dev(bktr->tunerdev);
  501         destroy_dev(bktr->bktrdev);
  502 
  503         /*
  504          * Deallocate resources.
  505          */
  506         bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
  507         bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
  508         bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
  509          
  510         return 0;
  511 }
  512 
  513 /*
  514  * the shutdown routine.
  515  */
  516 static int
  517 bktr_shutdown( device_t dev )
  518 {
  519         struct bktr_softc *bktr = device_get_softc(dev);
  520 
  521         /* Disable the brooktree device */
  522         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  523         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  524 
  525         return 0;
  526 }
  527 
  528 
  529 /*
  530  * Special Memory Allocation
  531  */
  532 vm_offset_t
  533 get_bktr_mem( int unit, unsigned size )
  534 {
  535         vm_offset_t     addr = 0;
  536 
  537         addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24);
  538         if (addr == 0)
  539                 addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE);
  540         if (addr == 0) {
  541                 printf("bktr%d: Unable to allocate %d bytes of memory.\n",
  542                         unit, size);
  543         }
  544 
  545         return( addr );
  546 }
  547 
  548 
  549 /*---------------------------------------------------------
  550 **
  551 **      BrookTree 848 character device driver routines
  552 **
  553 **---------------------------------------------------------
  554 */
  555 
  556 #define VIDEO_DEV       0x00
  557 #define TUNER_DEV       0x01
  558 #define VBI_DEV         0x02
  559 
  560 #define UNIT(x)         ((x) & 0x0f)
  561 #define FUNCTION(x)     (x >> 4)
  562 
  563 /*
  564  * 
  565  */
  566 static int
  567 bktr_open( dev_t dev, int flags, int fmt, struct thread *td )
  568 {
  569         bktr_ptr_t      bktr;
  570         int             unit;
  571         int             result;
  572 
  573         unit = UNIT( minor(dev) );
  574 
  575         /* Get the device data */
  576         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  577         if (bktr == NULL) {
  578                 /* the device is no longer valid/functioning */
  579                 return (ENXIO);
  580         }
  581 
  582         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
  583                 return( ENXIO );        
  584 
  585         /* Record that the device is now busy */
  586         device_busy(devclass_get_device(bktr_devclass, unit)); 
  587 
  588 
  589         if (bt848_card != -1) {
  590           if ((bt848_card >> 8   == unit ) &&
  591              ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
  592             if ( bktr->bt848_card != (bt848_card & 0xff) ) {
  593               bktr->bt848_card = (bt848_card & 0xff);
  594               probeCard(bktr, FALSE, unit);
  595             }
  596           }
  597         }
  598 
  599         if (bt848_tuner != -1) {
  600           if ((bt848_tuner >> 8   == unit ) &&
  601              ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
  602             if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
  603               bktr->bt848_tuner = (bt848_tuner & 0xff);
  604               probeCard(bktr, FALSE, unit);
  605             }
  606           }
  607         }
  608 
  609         if (bt848_reverse_mute != -1) {
  610           if ((bt848_reverse_mute >> 8)   == unit ) {
  611             bktr->reverse_mute = bt848_reverse_mute & 0xff;
  612           }
  613         }
  614 
  615         if (bt848_slow_msp_audio != -1) {
  616           if ((bt848_slow_msp_audio >> 8) == unit ) {
  617               bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
  618           }
  619         }
  620 
  621         switch ( FUNCTION( minor(dev) ) ) {
  622         case VIDEO_DEV:
  623                 result = video_open( bktr );
  624                 break;
  625         case TUNER_DEV:
  626                 result = tuner_open( bktr );
  627                 break;
  628         case VBI_DEV:
  629                 result = vbi_open( bktr );
  630                 break;
  631         default:
  632                 result = ENXIO;
  633                 break;
  634         }
  635 
  636         /* If there was an error opening the device, undo the busy status */
  637         if (result != 0)
  638                 device_unbusy(devclass_get_device(bktr_devclass, unit)); 
  639         return( result );
  640 }
  641 
  642 
  643 /*
  644  * 
  645  */
  646 static int
  647 bktr_close( dev_t dev, int flags, int fmt, struct thread *td )
  648 {
  649         bktr_ptr_t      bktr;
  650         int             unit;
  651         int             result;
  652 
  653         unit = UNIT( minor(dev) );
  654 
  655         /* Get the device data */
  656         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  657         if (bktr == NULL) {
  658                 /* the device is no longer valid/functioning */
  659                 return (ENXIO);
  660         }
  661 
  662         switch ( FUNCTION( minor(dev) ) ) {
  663         case VIDEO_DEV:
  664                 result = video_close( bktr );
  665                 break;
  666         case TUNER_DEV:
  667                 result = tuner_close( bktr );
  668                 break;
  669         case VBI_DEV:
  670                 result = vbi_close( bktr );
  671                 break;
  672         default:
  673                 return (ENXIO);
  674                 break;
  675         }
  676 
  677         device_unbusy(devclass_get_device(bktr_devclass, unit)); 
  678         return( result );
  679 }
  680 
  681 
  682 /*
  683  * 
  684  */
  685 static int
  686 bktr_read( dev_t dev, struct uio *uio, int ioflag )
  687 {
  688         bktr_ptr_t      bktr;
  689         int             unit;
  690         
  691         unit = UNIT(minor(dev));
  692 
  693         /* Get the device data */
  694         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  695         if (bktr == NULL) {
  696                 /* the device is no longer valid/functioning */
  697                 return (ENXIO);
  698         }
  699 
  700         switch ( FUNCTION( minor(dev) ) ) {
  701         case VIDEO_DEV:
  702                 return( video_read( bktr, unit, dev, uio ) );
  703         case VBI_DEV:
  704                 return( vbi_read( bktr, uio, ioflag ) );
  705         }
  706         return( ENXIO );
  707 }
  708 
  709 
  710 /*
  711  * 
  712  */
  713 static int
  714 bktr_write( dev_t dev, struct uio *uio, int ioflag )
  715 {
  716         return( EINVAL ); /* XXX or ENXIO ? */
  717 }
  718 
  719 
  720 /*
  721  * 
  722  */
  723 static int
  724 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td )
  725 {
  726         bktr_ptr_t      bktr;
  727         int             unit;
  728 
  729         unit = UNIT(minor(dev));
  730 
  731         /* Get the device data */
  732         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  733         if (bktr == NULL) {
  734                 /* the device is no longer valid/functioning */
  735                 return (ENXIO);
  736         }
  737 
  738         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
  739                 return( ENOMEM );
  740 
  741         switch ( FUNCTION( minor(dev) ) ) {
  742         case VIDEO_DEV:
  743                 return( video_ioctl( bktr, unit, cmd, arg, td ) );
  744         case TUNER_DEV:
  745                 return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
  746         }
  747 
  748         return( ENXIO );
  749 }
  750 
  751 
  752 /*
  753  * 
  754  */
  755 static int
  756 bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
  757 {
  758         int             unit;
  759         bktr_ptr_t      bktr;
  760 
  761         unit = UNIT(minor(dev));
  762 
  763         if (FUNCTION(minor(dev)) > 0)   /* only allow mmap on /dev/bktr[n] */
  764                 return( -1 );
  765 
  766         /* Get the device data */
  767         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  768         if (bktr == NULL) {
  769                 /* the device is no longer valid/functioning */
  770                 return (ENXIO);
  771         }
  772 
  773         if (nprot & PROT_EXEC)
  774                 return( -1 );
  775 
  776         if (offset < 0)
  777                 return( -1 );
  778 
  779         if (offset >= bktr->alloc_pages * PAGE_SIZE)
  780                 return( -1 );
  781 
  782         return( atop(vtophys(bktr->bigbuf) + offset) );
  783 }
  784 
  785 static int
  786 bktr_poll( dev_t dev, int events, struct thread *td)
  787 {
  788         int             unit;
  789         bktr_ptr_t      bktr;
  790         int revents = 0; 
  791         DECLARE_INTR_MASK(s);
  792 
  793         unit = UNIT(minor(dev));
  794 
  795         /* Get the device data */
  796         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
  797         if (bktr == NULL) {
  798                 /* the device is no longer valid/functioning */
  799                 return (ENXIO);
  800         }
  801 
  802         DISABLE_INTR(s);
  803 
  804         if (events & (POLLIN | POLLRDNORM)) {
  805 
  806                 switch ( FUNCTION( minor(dev) ) ) {
  807                 case VBI_DEV:
  808                         if(bktr->vbisize == 0)
  809                                 selrecord(td, &bktr->vbi_select);
  810                         else
  811                                 revents |= events & (POLLIN | POLLRDNORM);
  812                         break;
  813                 }
  814         }
  815 
  816         ENABLE_INTR(s);
  817 
  818         return (revents);
  819 }
  820 
  821 #endif          /* FreeBSD 4.x specific kernel interface routines */
  822 
  823 /*****************/
  824 /* *** BSDI  *** */
  825 /*****************/
  826 
  827 #if defined(__bsdi__)
  828 #endif          /* __bsdi__ BSDI specific kernel interface routines */
  829 
  830 
  831 /*****************************/
  832 /* *** OpenBSD / NetBSD  *** */
  833 /*****************************/
  834 #if defined(__NetBSD__) || defined(__OpenBSD__)
  835 
  836 #define IPL_VIDEO       IPL_BIO         /* XXX */
  837 
  838 static  int             bktr_intr(void *arg) { return common_bktr_intr(arg); }
  839 
  840 #define bktr_open       bktropen
  841 #define bktr_close      bktrclose
  842 #define bktr_read       bktrread
  843 #define bktr_write      bktrwrite
  844 #define bktr_ioctl      bktrioctl
  845 #define bktr_mmap       bktrmmap
  846 
  847 vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t,
  848                                  vm_offset_t, vm_offset_t);
  849 
  850 #if defined(__OpenBSD__)
  851 static int      bktr_probe(struct device *, void *, void *);
  852 #else
  853 static int      bktr_probe(struct device *, struct cfdata *, void *);
  854 #endif
  855 static void     bktr_attach(struct device *, struct device *, void *);
  856 
  857 struct cfattach bktr_ca = {
  858         sizeof(struct bktr_softc), bktr_probe, bktr_attach
  859 };
  860 
  861 #if defined(__NetBSD__)
  862 extern struct cfdriver bktr_cd;
  863 #else
  864 struct cfdriver bktr_cd = {
  865         NULL, "bktr", DV_DULL
  866 };
  867 #endif
  868 
  869 int
  870 bktr_probe(parent, match, aux)
  871         struct device *parent;
  872 #if defined(__OpenBSD__)
  873         void *match;
  874 #else
  875         struct cfdata *match;
  876 #endif
  877         void *aux;
  878 {
  879         struct pci_attach_args *pa = aux;
  880 
  881         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
  882             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
  883              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
  884              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
  885              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
  886                 return 1;
  887 
  888         return 0;
  889 }
  890 
  891 
  892 /*
  893  * the attach routine.
  894  */
  895 static void
  896 bktr_attach(struct device *parent, struct device *self, void *aux)
  897 {
  898         bktr_ptr_t      bktr;
  899         u_long          latency;
  900         u_long          fun;
  901         unsigned int    rev;
  902 
  903 #if defined(__OpenBSD__)
  904         struct pci_attach_args *pa = aux;
  905         pci_chipset_tag_t pc = pa->pa_pc;
  906 
  907         pci_intr_handle_t ih;
  908         const char *intrstr;
  909         int retval;
  910         int unit;
  911 
  912         bktr = (bktr_ptr_t)self;
  913         unit = bktr->bktr_dev.dv_unit;
  914 
  915         bktr->pc = pa->pa_pc;
  916         bktr->tag = pa->pa_tag;
  917         bktr->dmat = pa->pa_dmat;
  918 
  919         /*
  920          * map memory
  921          */
  922         bktr->memt = pa->pa_memt;
  923         retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START, 
  924                               &bktr->phys_base, &bktr->obmemsz, NULL);
  925         if (!retval)
  926                 retval = bus_space_map(pa->pa_memt, bktr->phys_base,
  927                                        bktr->obmemsz, 0, &bktr->memh);
  928         if (retval) {
  929                 printf(": couldn't map memory\n");
  930                 return;
  931         }
  932 
  933 
  934         /*
  935          * map interrupt
  936          */
  937         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
  938                          pa->pa_intrline, &ih)) {
  939                 printf(": couldn't map interrupt\n");
  940                 return;
  941         }
  942         intrstr = pci_intr_string(pa->pa_pc, ih);
  943 
  944         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
  945                                       bktr_intr, bktr, bktr->bktr_dev.dv_xname);
  946         if (bktr->ih == NULL) {
  947                 printf(": couldn't establish interrupt");
  948                 if (intrstr != NULL)    
  949                         printf(" at %s", intrstr);
  950                 printf("\n");
  951                 return;
  952         }
  953 
  954         if (intrstr != NULL)
  955                 printf(": %s\n", intrstr);
  956 #endif /* __OpenBSD__ */
  957 
  958 #if defined(__NetBSD__) 
  959         struct pci_attach_args *pa = aux;
  960         pci_intr_handle_t ih;
  961         const char *intrstr;
  962         int retval;
  963         int unit;
  964 
  965         bktr = (bktr_ptr_t)self;
  966         unit = bktr->bktr_dev.dv_unit;
  967         bktr->dmat = pa->pa_dmat;
  968 
  969         printf("\n");
  970 
  971         /*
  972          * map memory
  973          */
  974         retval = pci_mapreg_map(pa, PCI_MAPREG_START,
  975                                 PCI_MAPREG_TYPE_MEM
  976                                 | PCI_MAPREG_MEM_TYPE_32BIT, 0,
  977                                 &bktr->memt, &bktr->memh, NULL,
  978                                 &bktr->obmemsz);
  979         DPR(("pci_mapreg_map: memt %x, memh %x, size %x\n",
  980              bktr->memt, (u_int)bktr->memh, (u_int)bktr->obmemsz));
  981         if (retval) {
  982                 printf("%s: couldn't map memory\n", bktr_name(bktr));
  983                 return;
  984         }
  985 
  986         /*
  987          * Disable the brooktree device
  988          */
  989         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
  990         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
  991         
  992         /*
  993          * map interrupt
  994          */
  995         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
  996                          pa->pa_intrline, &ih)) {
  997                 printf("%s: couldn't map interrupt\n",
  998                        bktr_name(bktr));
  999                 return;
 1000         }
 1001         intrstr = pci_intr_string(pa->pa_pc, ih);
 1002         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
 1003                                       bktr_intr, bktr);
 1004         if (bktr->ih == NULL) {
 1005                 printf("%s: couldn't establish interrupt",
 1006                        bktr_name(bktr));
 1007                 if (intrstr != NULL)
 1008                         printf(" at %s", intrstr);
 1009                 printf("\n");
 1010                 return;
 1011         }
 1012         if (intrstr != NULL)
 1013                 printf("%s: interrupting at %s\n", bktr_name(bktr),
 1014                        intrstr);
 1015 #endif /* __NetBSD__ */
 1016         
 1017 /*
 1018  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
 1019  * you have more than four, then 16 would probably be a better value.
 1020  */
 1021 #ifndef BROOKTREE_DEF_LATENCY_VALUE
 1022 #define BROOKTREE_DEF_LATENCY_VALUE     10
 1023 #endif
 1024         latency = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER);
 1025         latency = (latency >> 8) & 0xff;
 1026 
 1027         if (!latency) {
 1028                 if (bootverbose) {
 1029                         printf("%s: PCI bus latency was 0 changing to %d",
 1030                                bktr_name(bktr), BROOKTREE_DEF_LATENCY_VALUE);
 1031                 }
 1032                 latency = BROOKTREE_DEF_LATENCY_VALUE;
 1033                 pci_conf_write(pa->pa_pc, pa->pa_tag, 
 1034                                PCI_LATENCY_TIMER, latency<<8);
 1035         }
 1036 
 1037 
 1038         /* Enabled Bus Master
 1039            XXX: check if all old DMA is stopped first (e.g. after warm
 1040            boot) */
 1041         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
 1042         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
 1043                        fun | PCI_COMMAND_MASTER_ENABLE);
 1044 
 1045         /* read the pci id and determine the card type */
 1046         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
 1047         rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff;
 1048 
 1049         common_bktr_attach(bktr, unit, fun, rev);
 1050 }
 1051 
 1052 
 1053 /*
 1054  * Special Memory Allocation
 1055  */
 1056 vm_offset_t
 1057 get_bktr_mem(bktr, dmapp, size)
 1058         bktr_ptr_t bktr;
 1059         bus_dmamap_t *dmapp;
 1060         unsigned int size;
 1061 {
 1062         bus_dma_tag_t dmat = bktr->dmat;
 1063         bus_dma_segment_t seg;
 1064         bus_size_t align;
 1065         int rseg;
 1066         caddr_t kva;
 1067 
 1068         /*
 1069          * Allocate a DMA area
 1070          */
 1071         align = 1 << 24;
 1072         if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
 1073                              &rseg, BUS_DMA_NOWAIT)) {
 1074                 align = PAGE_SIZE;
 1075                 if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
 1076                                      &rseg, BUS_DMA_NOWAIT)) {
 1077                         printf("%s: Unable to dmamem_alloc of %d bytes\n",
 1078                                bktr_name(bktr), size);
 1079                         return 0;
 1080                 }
 1081         }
 1082         if (bus_dmamem_map(dmat, &seg, rseg, size,
 1083                            &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
 1084                 printf("%s: Unable to dmamem_map of %d bytes\n",
 1085                         bktr_name(bktr), size);
 1086                 bus_dmamem_free(dmat, &seg, rseg);
 1087                 return 0;
 1088         }
 1089 #ifdef __OpenBSD__
 1090         bktr->dm_mapsize = size;
 1091 #endif
 1092         /*
 1093          * Create and locd the DMA map for the DMA area
 1094          */
 1095         if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) {
 1096                 printf("%s: Unable to dmamap_create of %d bytes\n",
 1097                         bktr_name(bktr), size);
 1098                 bus_dmamem_unmap(dmat, kva, size);
 1099                 bus_dmamem_free(dmat, &seg, rseg);
 1100                 return 0;
 1101         }
 1102         if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) {
 1103                 printf("%s: Unable to dmamap_load of %d bytes\n",
 1104                         bktr_name(bktr), size);
 1105                 bus_dmamem_unmap(dmat, kva, size);
 1106                 bus_dmamem_free(dmat, &seg, rseg);
 1107                 bus_dmamap_destroy(dmat, *dmapp);
 1108                 return 0;
 1109         }
 1110         return (vm_offset_t)kva;
 1111 }
 1112 
 1113 void
 1114 free_bktr_mem(bktr, dmap, kva)
 1115         bktr_ptr_t bktr;
 1116         bus_dmamap_t dmap;
 1117         vm_offset_t kva;
 1118 {
 1119         bus_dma_tag_t dmat = bktr->dmat;
 1120 
 1121 #ifdef __NetBSD__ 
 1122         bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize);
 1123 #else
 1124         bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize);
 1125 #endif
 1126         bus_dmamem_free(dmat, dmap->dm_segs, 1);
 1127         bus_dmamap_destroy(dmat, dmap);
 1128 }
 1129 
 1130 
 1131 /*---------------------------------------------------------
 1132 **
 1133 **      BrookTree 848 character device driver routines
 1134 **
 1135 **---------------------------------------------------------
 1136 */
 1137 
 1138 
 1139 #define VIDEO_DEV       0x00
 1140 #define TUNER_DEV       0x01
 1141 #define VBI_DEV         0x02
 1142 
 1143 #define UNIT(x)         (minor((x) & 0x0f))
 1144 #define FUNCTION(x)     (minor((x >> 4) & 0x0f))
 1145 
 1146 /*
 1147  * 
 1148  */
 1149 int
 1150 bktr_open(dev_t dev, int flags, int fmt, struct thread *td)
 1151 {
 1152         bktr_ptr_t      bktr;
 1153         int             unit;
 1154 
 1155         unit = UNIT(dev);
 1156 
 1157         /* unit out of range */
 1158         if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
 1159                 return(ENXIO);
 1160 
 1161         bktr = bktr_cd.cd_devs[unit];
 1162 
 1163         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
 1164                 return(ENXIO);  
 1165 
 1166         switch (FUNCTION(dev)) {
 1167         case VIDEO_DEV:
 1168                 return(video_open(bktr));
 1169         case TUNER_DEV:
 1170                 return(tuner_open(bktr));
 1171         case VBI_DEV:
 1172                 return(vbi_open(bktr));
 1173         }
 1174 
 1175         return(ENXIO);
 1176 }
 1177 
 1178 
 1179 /*
 1180  * 
 1181  */
 1182 int
 1183 bktr_close(dev_t dev, int flags, int fmt, struct thread *td)
 1184 {
 1185         bktr_ptr_t      bktr;
 1186         int             unit;
 1187 
 1188         unit = UNIT(dev);
 1189 
 1190         bktr = bktr_cd.cd_devs[unit];
 1191 
 1192         switch (FUNCTION(dev)) {
 1193         case VIDEO_DEV:
 1194                 return(video_close(bktr));
 1195         case TUNER_DEV:
 1196                 return(tuner_close(bktr));
 1197         case VBI_DEV:
 1198                 return(vbi_close(bktr));
 1199         }
 1200 
 1201         return(ENXIO);
 1202 }
 1203 
 1204 /*
 1205  * 
 1206  */
 1207 int
 1208 bktr_read(dev_t dev, struct uio *uio, int ioflag)
 1209 {
 1210         bktr_ptr_t      bktr;
 1211         int             unit;
 1212         
 1213         unit = UNIT(dev);
 1214 
 1215         bktr = bktr_cd.cd_devs[unit];
 1216 
 1217         switch (FUNCTION(dev)) {
 1218         case VIDEO_DEV:
 1219                 return(video_read(bktr, unit, dev, uio));
 1220         case VBI_DEV:
 1221                 return(vbi_read(bktr, uio, ioflag));
 1222         }
 1223 
 1224         return(ENXIO);
 1225 }
 1226 
 1227 
 1228 /*
 1229  * 
 1230  */
 1231 int
 1232 bktr_write(dev_t dev, struct uio *uio, int ioflag)
 1233 {
 1234         /* operation not supported */
 1235         return(EOPNOTSUPP);
 1236 }
 1237 
 1238 /*
 1239  * 
 1240  */
 1241 int
 1242 bktr_ioctl(dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td)
 1243 {
 1244         bktr_ptr_t      bktr;
 1245         int             unit;
 1246 
 1247         unit = UNIT(dev);
 1248 
 1249         bktr = bktr_cd.cd_devs[unit];
 1250 
 1251         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
 1252                 return(ENOMEM);
 1253 
 1254         switch (FUNCTION(dev)) {
 1255         case VIDEO_DEV:
 1256                 return(video_ioctl(bktr, unit, cmd, arg, pr));
 1257         case TUNER_DEV:
 1258                 return(tuner_ioctl(bktr, unit, cmd, arg, pr));
 1259         }
 1260 
 1261         return(ENXIO);
 1262 }
 1263 
 1264 /*
 1265  * 
 1266  */
 1267 paddr_t
 1268 bktr_mmap(dev_t dev, off_t offset, int nprot)
 1269 {
 1270         int             unit;
 1271         bktr_ptr_t      bktr;
 1272 
 1273         unit = UNIT(dev);
 1274 
 1275         if (FUNCTION(dev) > 0)  /* only allow mmap on /dev/bktr[n] */
 1276                 return(-1);
 1277 
 1278         bktr = bktr_cd.cd_devs[unit];
 1279 
 1280         if ((vaddr_t)offset < 0)
 1281                 return(-1);
 1282 
 1283         if ((vaddr_t)offset >= bktr->alloc_pages * PAGE_SIZE)
 1284                 return(-1);
 1285 
 1286 #ifdef __NetBSD__
 1287         return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1,
 1288                                 (vaddr_t)offset, nprot, BUS_DMA_WAITOK));
 1289 #else
 1290         return(i386_btop(vtophys(bktr->bigbuf) + offset));
 1291 #endif
 1292 }
 1293 
 1294 #endif /* __NetBSD__ || __OpenBSD__ */

Cache object: 0115234ead5e30c21c001100d43425c6


[ 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.