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

Cache object: 7420cb45cdedadb5e1553ca51d12daf2


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