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

Cache object: 417bff65392d1d32548d8ecf01453900


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