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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/bktr/bktr_os.c

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

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

Cache object: 3c5e1b858e529b25b0034822109d5d9e


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