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 );
bktr_intr(void * arg)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
bktr_probe(device_t dev)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
bktr_attach(device_t dev)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
bktr_detach(device_t dev)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
bktr_shutdown(device_t dev)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
get_bktr_mem(int unit,unsigned size)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
bktr_open(struct dev_open_args * ap)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
bktr_close(struct dev_close_args * ap)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
bktr_read(struct dev_read_args * ap)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
bktr_write(struct dev_write_args * ap)605 bktr_write(struct dev_write_args *ap)
606 {
607 return( EINVAL ); /* XXX or ENXIO ? */
608 }
609
610
611 /*
612 *
613 */
614 static int
bktr_ioctl(struct dev_ioctl_args * ap)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
bktr_mmap(struct dev_mmap_args * ap)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
bktr_kqfilter(struct dev_kqfilter_args * ap)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
bktr_filter_detach(struct knote * kn)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
bktr_filter(struct knote * kn,long hint)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