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 * $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.45 2004/03/17 17:50:28 njl Exp $ 34 * $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.10 2004/05/19 22:52:52 dillon Exp $ 35 */ 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 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/conf.h> 57 #include <sys/uio.h> 58 #include <sys/kernel.h> 59 #include <sys/signalvar.h> 60 #include <sys/malloc.h> 61 #include <sys/mman.h> 62 #include <sys/poll.h> 63 #include <sys/select.h> 64 #include <sys/vnode.h> 65 66 #include <vm/vm.h> 67 #include <vm/vm_kern.h> 68 #include <vm/pmap.h> 69 #include <vm/vm_extern.h> 70 71 #include <sys/bus.h> /* used by smbus and newbus */ 72 73 #include <machine/bus_memio.h> /* used by bus space */ 74 #include <machine/bus.h> /* used by bus space and newbus */ 75 #include <sys/bus.h> 76 77 #include <sys/rman.h> /* used by newbus */ 78 #include <machine/resource.h> /* used by newbus */ 79 #include <bus/pci/pcivar.h> 80 #include <bus/pci/pcireg.h> 81 #include <bus/pci/pcidevs.h> 82 83 #include <sys/sysctl.h> 84 int bt848_card = -1; 85 int bt848_tuner = -1; 86 int bt848_reverse_mute = -1; 87 int bt848_format = -1; 88 int bt848_slow_msp_audio = -1; 89 #ifdef BKTR_NEW_MSP34XX_DRIVER 90 int bt848_stereo_once = 0; /* no continuous stereo monitoring */ 91 int bt848_amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), 92 the autoscan seems work well only with FM... */ 93 int bt848_dolby = 0; 94 #endif 95 96 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt"); 97 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, ""); 98 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, ""); 99 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, ""); 100 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, ""); 101 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, ""); 102 #ifdef BKTR_NEW_MSP34XX_DRIVER 103 SYSCTL_INT(_hw_bt848, OID_AUTO, stereo_once, CTLFLAG_RW, &bt848_stereo_once, 0, ""); 104 SYSCTL_INT(_hw_bt848, OID_AUTO, amsound, CTLFLAG_RW, &bt848_amsound, 0, ""); 105 SYSCTL_INT(_hw_bt848, OID_AUTO, dolby, CTLFLAG_RW, &bt848_dolby, 0, ""); 106 #endif 107 108 #include <dev/video/meteor/ioctl_meteor.h> 109 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 110 #include <dev/video/bktr/bktr_reg.h> 111 #include <dev/video/bktr/bktr_tuner.h> 112 #include <dev/video/bktr/bktr_card.h> 113 #include <dev/video/bktr/bktr_audio.h> 114 #include <dev/video/bktr/bktr_core.h> 115 #include <dev/video/bktr/bktr_os.h> 116 117 #if defined(BKTR_USE_FREEBSD_SMBUS) 118 #include <dev/video/bktr/bktr_i2c.h> 119 120 #include "iicbb_if.h" 121 #include "smbus_if.h" 122 #endif 123 124 static int bktr_probe( device_t dev ); 125 static int bktr_attach( device_t dev ); 126 static int bktr_detach( device_t dev ); 127 static int bktr_shutdown( device_t dev ); 128 static void bktr_intr(void *arg) { common_bktr_intr(arg); } 129 130 static device_method_t bktr_methods[] = { 131 /* Device interface */ 132 DEVMETHOD(device_probe, bktr_probe), 133 DEVMETHOD(device_attach, bktr_attach), 134 DEVMETHOD(device_detach, bktr_detach), 135 DEVMETHOD(device_shutdown, bktr_shutdown), 136 137 #if defined(BKTR_USE_FREEBSD_SMBUS) 138 /* iicbb interface */ 139 DEVMETHOD(iicbb_callback, bti2c_iic_callback), 140 DEVMETHOD(iicbb_setsda, bti2c_iic_setsda), 141 DEVMETHOD(iicbb_setscl, bti2c_iic_setscl), 142 DEVMETHOD(iicbb_getsda, bti2c_iic_getsda), 143 DEVMETHOD(iicbb_getscl, bti2c_iic_getscl), 144 DEVMETHOD(iicbb_reset, bti2c_iic_reset), 145 146 /* smbus interface */ 147 DEVMETHOD(smbus_callback, bti2c_smb_callback), 148 DEVMETHOD(smbus_writeb, bti2c_smb_writeb), 149 DEVMETHOD(smbus_writew, bti2c_smb_writew), 150 DEVMETHOD(smbus_readb, bti2c_smb_readb), 151 #endif 152 153 { 0, 0 } 154 }; 155 156 static driver_t bktr_driver = { 157 "bktr", 158 bktr_methods, 159 sizeof(struct bktr_softc), 160 }; 161 162 static devclass_t bktr_devclass; 163 164 static d_open_t bktr_open; 165 static d_close_t bktr_close; 166 static d_read_t bktr_read; 167 static d_write_t bktr_write; 168 static d_ioctl_t bktr_ioctl; 169 static d_mmap_t bktr_mmap; 170 static d_poll_t bktr_poll; 171 172 #define CDEV_MAJOR 92 173 static struct cdevsw bktr_cdevsw = { 174 /* name */ "bktr", 175 /* maj */ CDEV_MAJOR, 176 /* flags */ 0, 177 /* port */ NULL, 178 /* clone */ NULL, 179 180 /* open */ bktr_open, 181 /* close */ bktr_close, 182 /* read */ bktr_read, 183 /* write */ bktr_write, 184 /* ioctl */ bktr_ioctl, 185 /* poll */ bktr_poll, 186 /* mmap */ bktr_mmap, 187 /* strategy */ nostrategy, 188 /* dump */ nodump, 189 /* psize */ nopsize 190 }; 191 192 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0); 193 MODULE_DEPEND(bktr, bktr_mem, 1,1,1); 194 MODULE_VERSION(bktr, 1); 195 196 /* 197 * the boot time probe routine. 198 */ 199 static int 200 bktr_probe( device_t dev ) 201 { 202 unsigned int type = pci_get_devid(dev); 203 unsigned int rev = pci_get_revid(dev); 204 205 if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE) 206 { 207 switch (PCI_PRODUCT(type)) { 208 case PCI_PRODUCT_BROOKTREE_BT848: 209 if (rev == 0x12) 210 device_set_desc(dev, "BrookTree 848A"); 211 else 212 device_set_desc(dev, "BrookTree 848"); 213 return 0; 214 case PCI_PRODUCT_BROOKTREE_BT849: 215 device_set_desc(dev, "BrookTree 849A"); 216 return 0; 217 case PCI_PRODUCT_BROOKTREE_BT878: 218 device_set_desc(dev, "BrookTree 878"); 219 return 0; 220 case PCI_PRODUCT_BROOKTREE_BT879: 221 device_set_desc(dev, "BrookTree 879"); 222 return 0; 223 } 224 }; 225 226 return ENXIO; 227 } 228 229 230 /* 231 * the attach routine. 232 */ 233 static int 234 bktr_attach( device_t dev ) 235 { 236 u_long latency; 237 u_long fun; 238 u_long val; 239 unsigned int rev; 240 unsigned int unit; 241 int error = 0; 242 #ifdef BROOKTREE_IRQ 243 u_long old_irq, new_irq; 244 #endif 245 246 struct bktr_softc *bktr = device_get_softc(dev); 247 248 unit = device_get_unit(dev); 249 250 /* build the device name for bktr_name() */ 251 snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit); 252 253 /* 254 * Enable bus mastering and Memory Mapped device 255 */ 256 val = pci_read_config(dev, PCIR_COMMAND, 4); 257 val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 258 pci_write_config(dev, PCIR_COMMAND, val, 4); 259 260 /* 261 * Map control/status registers. 262 */ 263 bktr->mem_rid = PCIR_BAR(0); 264 bktr->res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 265 &bktr->mem_rid, RF_ACTIVE); 266 267 if (!bktr->res_mem) { 268 device_printf(dev, "could not map memory\n"); 269 error = ENXIO; 270 goto fail; 271 } 272 bktr->memt = rman_get_bustag(bktr->res_mem); 273 bktr->memh = rman_get_bushandle(bktr->res_mem); 274 275 276 /* 277 * Disable the brooktree device 278 */ 279 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 280 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 281 282 283 #ifdef BROOKTREE_IRQ /* from the configuration file */ 284 old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); 285 pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ); 286 new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG); 287 printf("bktr%d: attach: irq changed from %d to %d\n", 288 unit, (old_irq & 0xff), (new_irq & 0xff)); 289 #endif 290 291 /* 292 * Allocate our interrupt. 293 */ 294 bktr->irq_rid = 0; 295 bktr->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 296 &bktr->irq_rid, RF_SHAREABLE | RF_ACTIVE); 297 if (bktr->res_irq == NULL) { 298 device_printf(dev, "could not map interrupt\n"); 299 error = ENXIO; 300 goto fail; 301 } 302 303 error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_TTY, 304 bktr_intr, bktr, &bktr->res_ih); 305 if (error) { 306 device_printf(dev, "could not setup irq\n"); 307 goto fail; 308 309 } 310 311 312 /* Update the Device Control Register */ 313 /* on Bt878 and Bt879 cards */ 314 fun = pci_read_config( dev, 0x40, 2); 315 fun = fun | 1; /* Enable writes to the sub-system vendor ID */ 316 317 #if defined( BKTR_430_FX_MODE ) 318 if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n"); 319 fun = fun | 2; /* Enable Intel 430 FX compatibility mode */ 320 #endif 321 322 #if defined( BKTR_SIS_VIA_MODE ) 323 if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n"); 324 fun = fun | 4; /* Enable SiS/VIA compatibility mode (usefull for 325 OPTi chipset motherboards too */ 326 #endif 327 pci_write_config(dev, 0x40, fun, 2); 328 329 #if defined(BKTR_USE_FREEBSD_SMBUS) 330 if (bt848_i2c_attach(dev)) 331 printf("bktr%d: i2c_attach: can't attach\n", unit); 332 #endif 333 334 /* 335 * PCI latency timer. 32 is a good value for 4 bus mastering slots, if 336 * you have more than four, then 16 would probably be a better value. 337 */ 338 #ifndef BROOKTREE_DEF_LATENCY_VALUE 339 #define BROOKTREE_DEF_LATENCY_VALUE 10 340 #endif 341 latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4); 342 latency = (latency >> 8) & 0xff; 343 if ( bootverbose ) { 344 if (latency) 345 printf("brooktree%d: PCI bus latency is", unit); 346 else 347 printf("brooktree%d: PCI bus latency was 0 changing to", 348 unit); 349 } 350 if ( !latency ) { 351 latency = BROOKTREE_DEF_LATENCY_VALUE; 352 pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4); 353 } 354 if ( bootverbose ) { 355 printf(" %d.\n", (int) latency); 356 } 357 358 /* read the pci device id and revision id */ 359 fun = pci_get_devid(dev); 360 rev = pci_get_revid(dev); 361 362 /* call the common attach code */ 363 common_bktr_attach( bktr, unit, fun, rev ); 364 365 /* make the device entries */ 366 cdevsw_add(&bktr_cdevsw, 0x0f, unit); 367 make_dev(&bktr_cdevsw, unit, 0, 0, 0444, "bktr%d", unit); 368 make_dev(&bktr_cdevsw, unit+16, 0, 0, 0444, "tuner%d", unit); 369 make_dev(&bktr_cdevsw, unit+32, 0, 0, 0444, "vbi%d" , unit); 370 371 372 return 0; 373 374 fail: 375 if (bktr->res_irq) 376 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq); 377 if (bktr->res_mem) 378 bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem); 379 return error; 380 381 } 382 383 /* 384 * the detach routine. 385 */ 386 static int 387 bktr_detach( device_t dev ) 388 { 389 struct bktr_softc *bktr = device_get_softc(dev); 390 391 #ifdef BKTR_NEW_MSP34XX_DRIVER 392 /* Disable the soundchip and kernel thread */ 393 if (bktr->msp3400c_info != NULL) 394 msp_detach(bktr); 395 #endif 396 397 /* Disable the brooktree device */ 398 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 399 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 400 401 #if defined(BKTR_USE_FREEBSD_SMBUS) 402 if (bt848_i2c_detach(dev)) 403 printf("bktr%d: i2c_attach: can't attach\n", 404 device_get_unit(dev)); 405 #endif 406 #ifdef USE_VBIMUTEX 407 mtx_destroy(&bktr->vbimutex); 408 #endif 409 410 /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */ 411 /* The memory is retained by the bktr_mem module so we can unload and */ 412 /* then reload the main bktr driver module */ 413 414 /* removing the cdevsw automatically destroys all related devices */ 415 cdevsw_remove(&bktr_cdevsw, 0x0f, device_get_unit(dev)); 416 417 /* 418 * Deallocate resources. 419 */ 420 bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih); 421 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq); 422 bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem); 423 424 return 0; 425 } 426 427 /* 428 * the shutdown routine. 429 */ 430 static int 431 bktr_shutdown( device_t dev ) 432 { 433 struct bktr_softc *bktr = device_get_softc(dev); 434 435 /* Disable the brooktree device */ 436 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED); 437 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED); 438 439 return 0; 440 } 441 442 443 /* 444 * Special Memory Allocation 445 */ 446 vm_offset_t 447 get_bktr_mem( int unit, unsigned size ) 448 { 449 vm_offset_t addr = 0; 450 451 addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, 452 0xffffffff, 1<<24, 0); 453 if (addr == 0) 454 addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0, 455 0xffffffff, PAGE_SIZE, 0); 456 if (addr == 0) { 457 printf("bktr%d: Unable to allocate %d bytes of memory.\n", 458 unit, size); 459 } 460 461 return( addr ); 462 } 463 464 465 /*--------------------------------------------------------- 466 ** 467 ** BrookTree 848 character device driver routines 468 ** 469 **--------------------------------------------------------- 470 */ 471 472 #define VIDEO_DEV 0x00 473 #define TUNER_DEV 0x01 474 #define VBI_DEV 0x02 475 476 #define UNIT(x) ((x) & 0x0f) 477 #define FUNCTION(x) (x >> 4) 478 479 /* 480 * 481 */ 482 static int 483 bktr_open( dev_t dev, int flags, int fmt, struct thread *td ) 484 { 485 bktr_ptr_t bktr; 486 int unit; 487 int result; 488 489 unit = UNIT( minor(dev) ); 490 491 /* Get the device data */ 492 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 493 if (bktr == NULL) { 494 /* the device is no longer valid/functioning */ 495 return (ENXIO); 496 } 497 498 if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */ 499 return( ENXIO ); 500 501 /* Record that the device is now busy */ 502 device_busy(devclass_get_device(bktr_devclass, unit)); 503 504 505 if (bt848_card != -1) { 506 if ((bt848_card >> 8 == unit ) && 507 ( (bt848_card & 0xff) < Bt848_MAX_CARD )) { 508 if ( bktr->bt848_card != (bt848_card & 0xff) ) { 509 bktr->bt848_card = (bt848_card & 0xff); 510 probeCard(bktr, FALSE, unit); 511 } 512 } 513 } 514 515 if (bt848_tuner != -1) { 516 if ((bt848_tuner >> 8 == unit ) && 517 ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) { 518 if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) { 519 bktr->bt848_tuner = (bt848_tuner & 0xff); 520 probeCard(bktr, FALSE, unit); 521 } 522 } 523 } 524 525 if (bt848_reverse_mute != -1) { 526 if ((bt848_reverse_mute >> 8) == unit ) { 527 bktr->reverse_mute = bt848_reverse_mute & 0xff; 528 } 529 } 530 531 if (bt848_slow_msp_audio != -1) { 532 if ((bt848_slow_msp_audio >> 8) == unit ) { 533 bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff); 534 } 535 } 536 537 #ifdef BKTR_NEW_MSP34XX_DRIVER 538 if (bt848_stereo_once != 0) { 539 if ((bt848_stereo_once >> 8) == unit ) { 540 bktr->stereo_once = (bt848_stereo_once & 0xff); 541 } 542 } 543 544 if (bt848_amsound != -1) { 545 if ((bt848_amsound >> 8) == unit ) { 546 bktr->amsound = (bt848_amsound & 0xff); 547 } 548 } 549 550 if (bt848_dolby != -1) { 551 if ((bt848_dolby >> 8) == unit ) { 552 bktr->dolby = (bt848_dolby & 0xff); 553 } 554 } 555 #endif 556 557 switch ( FUNCTION( minor(dev) ) ) { 558 case VIDEO_DEV: 559 result = video_open( bktr ); 560 break; 561 case TUNER_DEV: 562 result = tuner_open( bktr ); 563 break; 564 case VBI_DEV: 565 result = vbi_open( bktr ); 566 break; 567 default: 568 result = ENXIO; 569 break; 570 } 571 572 /* If there was an error opening the device, undo the busy status */ 573 if (result != 0) 574 device_unbusy(devclass_get_device(bktr_devclass, unit)); 575 return( result ); 576 } 577 578 579 /* 580 * 581 */ 582 static int 583 bktr_close( dev_t dev, int flags, int fmt, struct thread *td ) 584 { 585 bktr_ptr_t bktr; 586 int unit; 587 int result; 588 589 unit = UNIT( minor(dev) ); 590 591 /* Get the device data */ 592 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 593 if (bktr == NULL) { 594 /* the device is no longer valid/functioning */ 595 return (ENXIO); 596 } 597 598 switch ( FUNCTION( minor(dev) ) ) { 599 case VIDEO_DEV: 600 result = video_close( bktr ); 601 break; 602 case TUNER_DEV: 603 result = tuner_close( bktr ); 604 break; 605 case VBI_DEV: 606 result = vbi_close( bktr ); 607 break; 608 default: 609 return (ENXIO); 610 break; 611 } 612 613 device_unbusy(devclass_get_device(bktr_devclass, unit)); 614 return( result ); 615 } 616 617 618 /* 619 * 620 */ 621 static int 622 bktr_read( dev_t dev, struct uio *uio, int ioflag ) 623 { 624 bktr_ptr_t bktr; 625 int unit; 626 627 unit = UNIT(minor(dev)); 628 629 /* Get the device data */ 630 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 631 if (bktr == NULL) { 632 /* the device is no longer valid/functioning */ 633 return (ENXIO); 634 } 635 636 switch ( FUNCTION( minor(dev) ) ) { 637 case VIDEO_DEV: 638 return( video_read( bktr, unit, dev, uio ) ); 639 case VBI_DEV: 640 return( vbi_read( bktr, uio, ioflag ) ); 641 } 642 return( ENXIO ); 643 } 644 645 646 /* 647 * 648 */ 649 static int 650 bktr_write( dev_t dev, struct uio *uio, int ioflag ) 651 { 652 return( EINVAL ); /* XXX or ENXIO ? */ 653 } 654 655 656 /* 657 * 658 */ 659 static int 660 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td ) 661 { 662 bktr_ptr_t bktr; 663 int unit; 664 665 unit = UNIT(minor(dev)); 666 667 /* Get the device data */ 668 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 669 if (bktr == NULL) { 670 /* the device is no longer valid/functioning */ 671 return (ENXIO); 672 } 673 674 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */ 675 return( ENOMEM ); 676 677 switch ( FUNCTION( minor(dev) ) ) { 678 case VIDEO_DEV: 679 return( video_ioctl( bktr, unit, cmd, arg, td ) ); 680 case TUNER_DEV: 681 return( tuner_ioctl( bktr, unit, cmd, arg, td ) ); 682 } 683 684 return( ENXIO ); 685 } 686 687 688 /* 689 * 690 */ 691 static int 692 bktr_mmap( dev_t dev, vm_offset_t offset, int nprot ) 693 { 694 int unit; 695 bktr_ptr_t bktr; 696 697 unit = UNIT(minor(dev)); 698 699 if (FUNCTION(minor(dev)) > 0) /* only allow mmap on /dev/bktr[n] */ 700 return( -1 ); 701 702 /* Get the device data */ 703 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 704 if (bktr == NULL) { 705 /* the device is no longer valid/functioning */ 706 return (ENXIO); 707 } 708 709 if (nprot & PROT_EXEC) 710 return( -1 ); 711 712 if (offset < 0) 713 return( -1 ); 714 715 if (offset >= bktr->alloc_pages * PAGE_SIZE) 716 return( -1 ); 717 718 return(atop(vtophys(bktr->bigbuf) + offset)); 719 } 720 721 static int 722 bktr_poll( dev_t dev, int events, struct thread *td) 723 { 724 int unit; 725 bktr_ptr_t bktr; 726 int revents = 0; 727 DECLARE_INTR_MASK(s); 728 729 unit = UNIT(minor(dev)); 730 731 /* Get the device data */ 732 bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit); 733 if (bktr == NULL) { 734 /* the device is no longer valid/functioning */ 735 return (ENXIO); 736 } 737 738 LOCK_VBI(bktr); 739 DISABLE_INTR(s); 740 741 if (events & (POLLIN | POLLRDNORM)) { 742 743 switch ( FUNCTION( minor(dev) ) ) { 744 case VBI_DEV: 745 if(bktr->vbisize == 0) 746 selrecord(td, &bktr->vbi_select); 747 else 748 revents |= events & (POLLIN | POLLRDNORM); 749 break; 750 } 751 } 752 753 ENABLE_INTR(s); 754 UNLOCK_VBI(bktr); 755 756 return (revents); 757 } 758