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

Cache object: 4f05e39c6c25020fac56d4e8d64c0285


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