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

Cache object: dd04ada0bc4e730be926a3cae4e94e51


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