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