xref: /dragonfly/sys/dev/video/bktr/bktr_os.c (revision 2d8a3be7)
1 /* $FreeBSD: src/sys/dev/bktr/bktr_os.c,v 1.4.2.3 2000/10/27 00:46:09 jhb Exp $ */
2 /* $DragonFly: src/sys/dev/video/bktr/bktr_os.c,v 1.6 2003/08/27 06:48:15 rob Exp $ */
3 
4 /*
5  * This is part of the Driver for Video Capture Cards (Frame grabbers)
6  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
7  * chipset.
8  * Copyright Roger Hardiman and Amancio Hasty.
9  *
10  * bktr_os : This has all the Operating System dependant code,
11  *             probe/attach and open/close/ioctl/read/mmap
12  *             memory allocation
13  *             PCI bus interfacing
14  *
15  *
16  */
17 
18 /*
19  * 1. Redistributions of source code must retain the
20  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
21  * All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *	This product includes software developed by Amancio Hasty and
34  *      Roger Hardiman
35  * 4. The name of the author may not be used to endorse or promote products
36  *    derived from this software without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
40  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
42  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
47  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48  * POSSIBILITY OF SUCH DAMAGE.
49  */
50 
51 
52 #ifdef __FreeBSD__
53 #include "use_bktr.h"
54 #endif /* __FreeBSD__ */
55 
56 #include "opt_bktr.h"		/* include any kernel config options */
57 
58 #define FIFO_RISC_DISABLED      0
59 #define ALL_INTS_DISABLED       0
60 
61 
62 /*******************/
63 /* *** FreeBSD *** */
64 /*******************/
65 #ifdef __FreeBSD__
66 
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/uio.h>
71 #include <sys/kernel.h>
72 #include <sys/signalvar.h>
73 #include <sys/mman.h>
74 #include <sys/poll.h>
75 #include <sys/select.h>
76 #include <sys/vnode.h>
77 
78 #include <vm/vm.h>
79 #include <vm/vm_kern.h>
80 #include <vm/pmap.h>
81 #include <vm/vm_extern.h>
82 
83 #if (__FreeBSD_version >=400000) || (NSMBUS > 0)
84 #include <sys/bus.h>		/* used by smbus and newbus */
85 #endif
86 
87 #if (__FreeBSD_version >=300000)
88 #include <machine/bus_memio.h>	/* used by bus space */
89 #include <machine/bus.h>	/* used by bus space and newbus */
90 #include <sys/bus.h>
91 #endif
92 
93 #if (__FreeBSD_version >=400000)
94 #include <sys/rman.h>		/* used by newbus */
95 #include <machine/resource.h>	/* used by newbus */
96 #endif
97 
98 #if (__FreeBSD_version < 500000)
99 #include <machine/clock.h>              /* for DELAY */
100 #endif
101 
102 #include <bus/pci/pcivar.h>
103 #include <bus/pci/pcireg.h>
104 
105 #include <sys/sysctl.h>
106 int bt848_card = -1;
107 int bt848_tuner = -1;
108 int bt848_reverse_mute = -1;
109 int bt848_format = -1;
110 int bt848_slow_msp_audio = -1;
111 
112 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
113 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
114 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
115 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
116 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
117 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
118 
119 #if (__FreeBSD__ == 2)
120 #define PCIR_REVID     PCI_CLASS_REG
121 #endif
122 
123 #endif /* end freebsd section */
124 
125 
126 
127 /****************/
128 /* *** BSDI *** */
129 /****************/
130 #ifdef __bsdi__
131 #endif /* __bsdi__ */
132 
133 
134 /**************************/
135 /* *** OpenBSD/NetBSD *** */
136 /**************************/
137 #if defined(__NetBSD__) || defined(__OpenBSD__)
138 
139 #include <sys/param.h>
140 #include <sys/systm.h>
141 #include <sys/conf.h>
142 #include <sys/uio.h>
143 #include <sys/kernel.h>
144 #include <sys/signalvar.h>
145 #include <sys/mman.h>
146 #include <sys/poll.h>
147 #include <sys/select.h>
148 #include <sys/vnode.h>
149 
150 #include <vm/vm.h>
151 
152 #ifndef __NetBSD__
153 #include <vm/vm_kern.h>
154 #include <vm/pmap.h>
155 #include <vm/vm_extern.h>
156 #endif
157 
158 #include <sys/device.h>
159 #include <dev/pci/pcivar.h>
160 #include <dev/pci/pcireg.h>
161 #include <dev/pci/pcidevs.h>
162 
163 #define BKTR_DEBUG
164 #ifdef BKTR_DEBUG
165 int bktr_debug = 0;
166 #define DPR(x)	(bktr_debug ? printf x : 0)
167 #else
168 #define DPR(x)
169 #endif
170 #endif /* __NetBSD__ || __OpenBSD__ */
171 
172 
173 #ifdef __NetBSD__
174 #include <dev/ic/bt8xx.h>	/* NetBSD location for .h files */
175 #include <dev/pci/bktr/bktr_reg.h>
176 #include <dev/pci/bktr/bktr_tuner.h>
177 #include <dev/pci/bktr/bktr_card.h>
178 #include <dev/pci/bktr/bktr_audio.h>
179 #include <dev/pci/bktr/bktr_core.h>
180 #include <dev/pci/bktr/bktr_os.h>
181 #else					/* Traditional location for .h files */
182 #include <machine/ioctl_meteor.h>
183 #include <machine/ioctl_bt848.h>	/* extensions to ioctl_meteor.h */
184 #include "bktr_reg.h"
185 #include "bktr_tuner.h"
186 #include "bktr_card.h"
187 #include "bktr_audio.h"
188 #include "bktr_core.h"
189 #include "bktr_os.h"
190 #if defined(BKTR_USE_FREEBSD_SMBUS)
191 #include "bktr_i2c.h"
192 #endif
193 #endif
194 
195 
196 
197 /****************************/
198 /* *** FreeBSD 4.x code *** */
199 /****************************/
200 #if (__FreeBSD_version >= 400000)
201 
202 static int	bktr_probe( device_t dev );
203 static int	bktr_attach( device_t dev );
204 static int	bktr_detach( device_t dev );
205 static int	bktr_shutdown( device_t dev );
206 static void	bktr_intr(void *arg) { common_bktr_intr(arg); }
207 
208 static device_method_t bktr_methods[] = {
209 	/* Device interface */
210 	DEVMETHOD(device_probe,         bktr_probe),
211 	DEVMETHOD(device_attach,        bktr_attach),
212 	DEVMETHOD(device_detach,        bktr_detach),
213 	DEVMETHOD(device_shutdown,      bktr_shutdown),
214 
215 	{ 0, 0 }
216 };
217 
218 static driver_t bktr_driver = {
219 	"bktr",
220 	bktr_methods,
221 	sizeof(struct bktr_softc),
222 };
223 
224 static devclass_t bktr_devclass;
225 
226 static	d_open_t	bktr_open;
227 static	d_close_t	bktr_close;
228 static	d_read_t	bktr_read;
229 static	d_write_t	bktr_write;
230 static	d_ioctl_t	bktr_ioctl;
231 static	d_mmap_t	bktr_mmap;
232 static	d_poll_t	bktr_poll;
233 
234 #define CDEV_MAJOR 92
235 static struct cdevsw bktr_cdevsw = {
236 	/* name */	"bktr",
237 	/* maj */	CDEV_MAJOR,
238 	/* flags */	0,
239 	/* port */      NULL,
240 	/* autoq */	0,
241 
242 	/* open */	bktr_open,
243 	/* close */	bktr_close,
244 	/* read */	bktr_read,
245 	/* write */	bktr_write,
246 	/* ioctl */	bktr_ioctl,
247 	/* poll */	bktr_poll,
248 	/* mmap */	bktr_mmap,
249 	/* strategy */	nostrategy,
250 	/* dump */	nodump,
251 	/* psize */	nopsize
252 };
253 
254 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0);
255 #if (__FreeBSD_version > 410000)
256 MODULE_DEPEND(bktr, bktr_mem, 1,1,1);
257 MODULE_VERSION(bktr, 1);
258 #endif
259 
260 
261 /*
262  * the boot time probe routine.
263  */
264 static int
265 bktr_probe( device_t dev )
266 {
267 	unsigned int type = pci_get_devid(dev);
268         unsigned int rev  = pci_get_revid(dev);
269 
270 	if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
271 	{
272 		switch (PCI_PRODUCT(type)) {
273 		case PCI_PRODUCT_BROOKTREE_BT848:
274 			if (rev == 0x12)
275 				device_set_desc(dev, "BrookTree 848A");
276 			else
277 				device_set_desc(dev, "BrookTree 848");
278 			return 0;
279 		case PCI_PRODUCT_BROOKTREE_BT849:
280 			device_set_desc(dev, "BrookTree 849A");
281 			return 0;
282 		case PCI_PRODUCT_BROOKTREE_BT878:
283 			device_set_desc(dev, "BrookTree 878");
284 			return 0;
285 		case PCI_PRODUCT_BROOKTREE_BT879:
286 			device_set_desc(dev, "BrookTree 879");
287 			return 0;
288 		}
289 	};
290 
291         return ENXIO;
292 }
293 
294 
295 /*
296  * the attach routine.
297  */
298 static int
299 bktr_attach( device_t dev )
300 {
301 	u_long		latency;
302 	u_long		fun;
303 	u_long		val;
304 	unsigned int	rev;
305 	unsigned int	unit;
306 	int		error = 0;
307 #ifdef BROOKTREE_IRQ
308 	u_long		old_irq, new_irq;
309 #endif
310 
311         struct bktr_softc *bktr = device_get_softc(dev);
312 
313 	unit = device_get_unit(dev);
314 
315 	/* build the device name for bktr_name() */
316 	snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
317 
318 	/*
319 	 * Enable bus mastering and Memory Mapped device
320 	 */
321 	val = pci_read_config(dev, PCIR_COMMAND, 4);
322 	val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
323 	pci_write_config(dev, PCIR_COMMAND, val, 4);
324 
325 	/*
326 	 * Map control/status registers.
327 	 */
328 	bktr->mem_rid = PCIR_MAPS;
329 	bktr->res_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &bktr->mem_rid,
330 					0, ~0, 1, RF_ACTIVE);
331 
332 
333 	if (!bktr->res_mem) {
334 		device_printf(dev, "could not map memory\n");
335 		error = ENXIO;
336 		goto fail;
337 	}
338 	bktr->memt = rman_get_bustag(bktr->res_mem);
339 	bktr->memh = rman_get_bushandle(bktr->res_mem);
340 
341 
342 	/*
343 	 * Disable the brooktree device
344 	 */
345 	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
346 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
347 
348 
349 #ifdef BROOKTREE_IRQ		/* from the configuration file */
350 	old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
351 	pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
352 	new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
353 	printf("bktr%d: attach: irq changed from %d to %d\n",
354 		unit, (old_irq & 0xff), (new_irq & 0xff));
355 #endif
356 
357 	/*
358 	 * Allocate our interrupt.
359 	 */
360 	bktr->irq_rid = 0;
361 	bktr->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &bktr->irq_rid,
362 				0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
363 	if (bktr->res_irq == NULL) {
364 		device_printf(dev, "could not map interrupt\n");
365 		error = ENXIO;
366 		goto fail;
367 	}
368 
369 	error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_TTY,
370                                bktr_intr, bktr, &bktr->res_ih);
371 	if (error) {
372 		device_printf(dev, "could not setup irq\n");
373 		goto fail;
374 
375 	}
376 
377 
378 	/* Update the Device Control Register */
379 	/* on Bt878 and Bt879 cards           */
380 	fun = pci_read_config( dev, 0x40, 2);
381         fun = fun | 1;	/* Enable writes to the sub-system vendor ID */
382 
383 #if defined( BKTR_430_FX_MODE )
384 	if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
385         fun = fun | 2;	/* Enable Intel 430 FX compatibility mode */
386 #endif
387 
388 #if defined( BKTR_SIS_VIA_MODE )
389 	if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
390         fun = fun | 4;	/* Enable SiS/VIA compatibility mode (usefull for
391                            OPTi chipset motherboards too */
392 #endif
393 	pci_write_config(dev, 0x40, fun, 2);
394 
395 
396 	/* XXX call bt848_i2c dependent attach() routine */
397 #if defined(BKTR_USE_FREEBSD_SMBUS)
398 	if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
399 		printf("bktr%d: i2c_attach: can't attach\n", unit);
400 #endif
401 
402 
403 /*
404  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
405  * you have more than four, then 16 would probably be a better value.
406  */
407 #ifndef BROOKTREE_DEF_LATENCY_VALUE
408 #define BROOKTREE_DEF_LATENCY_VALUE	10
409 #endif
410 	latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
411 	latency = (latency >> 8) & 0xff;
412 	if ( bootverbose ) {
413 		if (latency)
414 			printf("brooktree%d: PCI bus latency is", unit);
415 		else
416 			printf("brooktree%d: PCI bus latency was 0 changing to",
417 				unit);
418 	}
419 	if ( !latency ) {
420 		latency = BROOKTREE_DEF_LATENCY_VALUE;
421 		pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
422 	}
423 	if ( bootverbose ) {
424 		printf(" %d.\n", (int) latency);
425 	}
426 
427 	/* read the pci device id and revision id */
428 	fun = pci_get_devid(dev);
429         rev = pci_get_revid(dev);
430 
431 	/* call the common attach code */
432 	common_bktr_attach( bktr, unit, fun, rev );
433 
434 	/* make the device entries */
435 	bktr->bktrdev = make_dev(&bktr_cdevsw, unit,
436 				0, 0, 0444, "bktr%d",  unit);
437 	bktr->tunerdev= make_dev(&bktr_cdevsw, unit+16,
438 				0, 0, 0444, "tuner%d", unit);
439 	bktr->vbidev  = make_dev(&bktr_cdevsw, unit+32,
440 				0, 0, 0444, "vbi%d"  , unit);
441 
442 
443 	/* if this is unit 0 (/dev/bktr0, /dev/tuner0, /dev/vbi0) then make */
444 	/* alias entries to /dev/bktr /dev/tuner and /dev/vbi */
445 #if (__FreeBSD_version >=500000)
446 	if (unit == 0) {
447 		bktr->bktrdev_alias = make_dev_alias(bktr->bktrdev,  "bktr");
448 		bktr->tunerdev_alias= make_dev_alias(bktr->tunerdev, "tuner");
449 		bktr->vbidev_alias  = make_dev_alias(bktr->vbidev,   "vbi");
450 	}
451 #endif
452 
453 	return 0;
454 
455 fail:
456 	if (bktr->res_irq)
457 		bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
458 	if (bktr->res_mem)
459 		bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem);
460 	return error;
461 
462 }
463 
464 /*
465  * the detach routine.
466  */
467 static int
468 bktr_detach( device_t dev )
469 {
470 	unsigned int	unit;
471 
472 	struct bktr_softc *bktr = device_get_softc(dev);
473 
474 	unit = device_get_unit(dev);
475 
476 	/* Disable the brooktree device */
477 	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
478 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
479 
480 	/* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
481 	/* The memory is retained by the bktr_mem module so we can unload and */
482 	/* then reload the main bktr driver module */
483 
484 	/* Unregister the /dev/bktrN, tunerN and vbiN devices */
485 	destroy_dev(bktr->vbidev);
486 	destroy_dev(bktr->tunerdev);
487 	destroy_dev(bktr->bktrdev);
488 
489 	/* If this is unit 0, then destroy the alias entries too */
490 #if (__FreeBSD_version >=500000)
491 	if (unit == 0) {
492 	    destroy_dev(bktr->vbidev_alias);
493 	    destroy_dev(bktr->tunerdev_alias);
494 	    destroy_dev(bktr->bktrdev_alias);
495 	}
496 #endif
497 
498 	/*
499 	 * Deallocate resources.
500 	 */
501 	bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
502 	bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
503 	bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
504 
505 	return 0;
506 }
507 
508 /*
509  * the shutdown routine.
510  */
511 static int
512 bktr_shutdown( device_t dev )
513 {
514 	struct bktr_softc *bktr = device_get_softc(dev);
515 
516 	/* Disable the brooktree device */
517 	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
518 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
519 
520 	return 0;
521 }
522 
523 
524 /*
525  * Special Memory Allocation
526  */
527 vm_offset_t
528 get_bktr_mem( int unit, unsigned size )
529 {
530 	vm_offset_t	addr = 0;
531 
532 	addr = vm_page_alloc_contig(size, 0, 0xffffffff, 1<<24);
533 	if (addr == 0)
534 		addr = vm_page_alloc_contig(size, 0, 0xffffffff, PAGE_SIZE);
535 	if (addr == 0) {
536 		printf("bktr%d: Unable to allocate %d bytes of memory.\n",
537 			unit, size);
538 	}
539 
540 	return( addr );
541 }
542 
543 
544 /*---------------------------------------------------------
545 **
546 **	BrookTree 848 character device driver routines
547 **
548 **---------------------------------------------------------
549 */
550 
551 #define VIDEO_DEV	0x00
552 #define TUNER_DEV	0x01
553 #define VBI_DEV		0x02
554 
555 #define UNIT(x)		((x) & 0x0f)
556 #define FUNCTION(x)	(x >> 4)
557 
558 /*
559  *
560  */
561 int
562 bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td)
563 {
564 	bktr_ptr_t	bktr;
565 	int		unit;
566 	int		result;
567 
568 	unit = UNIT( minor(dev) );
569 
570 	/* Get the device data */
571 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
572 	if (bktr == NULL) {
573 		/* the device is no longer valid/functioning */
574 		return (ENXIO);
575 	}
576 
577 	if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
578 		return( ENXIO );
579 
580 	/* Record that the device is now busy */
581 	device_busy(devclass_get_device(bktr_devclass, unit));
582 
583 
584 	if (bt848_card != -1) {
585 	  if ((bt848_card >> 8   == unit ) &&
586 	     ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
587 	    if ( bktr->bt848_card != (bt848_card & 0xff) ) {
588 	      bktr->bt848_card = (bt848_card & 0xff);
589 	      probeCard(bktr, FALSE, unit);
590 	    }
591 	  }
592 	}
593 
594 	if (bt848_tuner != -1) {
595 	  if ((bt848_tuner >> 8   == unit ) &&
596 	     ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
597 	    if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
598 	      bktr->bt848_tuner = (bt848_tuner & 0xff);
599 	      probeCard(bktr, FALSE, unit);
600 	    }
601 	  }
602 	}
603 
604 	if (bt848_reverse_mute != -1) {
605 	  if ((bt848_reverse_mute >> 8)   == unit ) {
606 	    bktr->reverse_mute = bt848_reverse_mute & 0xff;
607 	  }
608 	}
609 
610 	if (bt848_slow_msp_audio != -1) {
611 	  if ((bt848_slow_msp_audio >> 8) == unit ) {
612 	      bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
613 	  }
614 	}
615 
616 	switch ( FUNCTION( minor(dev) ) ) {
617 	case VIDEO_DEV:
618 		result = video_open( bktr );
619 		break;
620 	case TUNER_DEV:
621 		result = tuner_open( bktr );
622 		break;
623 	case VBI_DEV:
624 		result = vbi_open( bktr );
625 		break;
626 	default:
627 		result = ENXIO;
628 		break;
629 	}
630 
631 	/* If there was an error opening the device, undo the busy status */
632 	if (result != 0)
633 		device_unbusy(devclass_get_device(bktr_devclass, unit));
634 	return( result );
635 }
636 
637 
638 /*
639  *
640  */
641 int
642 bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td)
643 {
644 	bktr_ptr_t	bktr;
645 	int		unit;
646 	int		result;
647 
648 	unit = UNIT( minor(dev) );
649 
650 	/* Get the device data */
651 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
652 	if (bktr == NULL) {
653 		/* the device is no longer valid/functioning */
654 		return (ENXIO);
655 	}
656 
657 	switch ( FUNCTION( minor(dev) ) ) {
658 	case VIDEO_DEV:
659 		result = video_close( bktr );
660 		break;
661 	case TUNER_DEV:
662 		result = tuner_close( bktr );
663 		break;
664 	case VBI_DEV:
665 		result = vbi_close( bktr );
666 		break;
667 	default:
668 		return (ENXIO);
669 		break;
670 	}
671 
672 	device_unbusy(devclass_get_device(bktr_devclass, unit));
673 	return( result );
674 }
675 
676 
677 /*
678  *
679  */
680 int
681 bktr_read( dev_t dev, struct uio *uio, int ioflag )
682 {
683 	bktr_ptr_t	bktr;
684 	int		unit;
685 
686 	unit = UNIT(minor(dev));
687 
688 	/* Get the device data */
689 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
690 	if (bktr == NULL) {
691 		/* the device is no longer valid/functioning */
692 		return (ENXIO);
693 	}
694 
695 	switch ( FUNCTION( minor(dev) ) ) {
696 	case VIDEO_DEV:
697 		return( video_read( bktr, unit, dev, uio ) );
698 	case VBI_DEV:
699 		return( vbi_read( bktr, uio, ioflag ) );
700 	}
701         return( ENXIO );
702 }
703 
704 
705 /*
706  *
707  */
708 int
709 bktr_write( dev_t dev, struct uio *uio, int ioflag )
710 {
711 	return( EINVAL ); /* XXX or ENXIO ? */
712 }
713 
714 
715 /*
716  *
717  */
718 int
719 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
720 {
721 	bktr_ptr_t	bktr;
722 	int		unit;
723 
724 	unit = UNIT(minor(dev));
725 
726 	/* Get the device data */
727 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
728 	if (bktr == NULL) {
729 		/* the device is no longer valid/functioning */
730 		return (ENXIO);
731 	}
732 
733 	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
734 		return( ENOMEM );
735 
736 	switch ( FUNCTION( minor(dev) ) ) {
737 	case VIDEO_DEV:
738 		return( video_ioctl( bktr, unit, cmd, arg, td ) );
739 	case TUNER_DEV:
740 		return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
741 	}
742 
743 	return( ENXIO );
744 }
745 
746 
747 /*
748  *
749  */
750 int
751 bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
752 {
753 	int		unit;
754 	bktr_ptr_t	bktr;
755 
756 	unit = UNIT(minor(dev));
757 
758 	if (FUNCTION(minor(dev)) > 0)	/* only allow mmap on /dev/bktr[n] */
759 		return( -1 );
760 
761 	/* Get the device data */
762 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
763 	if (bktr == NULL) {
764 		/* the device is no longer valid/functioning */
765 		return (ENXIO);
766 	}
767 
768 	if (nprot & PROT_EXEC)
769 		return( -1 );
770 
771 	if (offset < 0)
772 		return( -1 );
773 
774 	if (offset >= bktr->alloc_pages * PAGE_SIZE)
775 		return( -1 );
776 
777 	return( atop(vtophys(bktr->bigbuf) + offset) );
778 }
779 
780 int bktr_poll( dev_t dev, int events, d_thread_t *td)
781 {
782 	int		unit;
783 	bktr_ptr_t	bktr;
784 	int revents = 0;
785 	DECLARE_INTR_MASK(s);
786 
787 	unit = UNIT(minor(dev));
788 
789 	/* Get the device data */
790 	bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
791 	if (bktr == NULL) {
792 		/* the device is no longer valid/functioning */
793 		return (ENXIO);
794 	}
795 
796 	DISABLE_INTR(s);
797 
798 	if (events & (POLLIN | POLLRDNORM)) {
799 
800 		switch ( FUNCTION( minor(dev) ) ) {
801 		case VBI_DEV:
802 			if(bktr->vbisize == 0)
803 				selrecord(td, &bktr->vbi_select);
804 			else
805 				revents |= events & (POLLIN | POLLRDNORM);
806 			break;
807 		}
808 	}
809 
810 	ENABLE_INTR(s);
811 
812 	return (revents);
813 }
814 
815 #endif		/* FreeBSD 4.x specific kernel interface routines */
816 
817 /**********************************/
818 /* *** FreeBSD 2.2.x and 3.x  *** */
819 /**********************************/
820 
821 #if ((__FreeBSD__ == 2) || (__FreeBSD__ == 3))
822 
823 static bktr_reg_t brooktree[ NBKTR ];
824 
825 static const char*	bktr_probe( pcici_t tag, pcidi_t type );
826 static void		bktr_attach( pcici_t tag, int unit );
827 static void		bktr_intr(void *arg) { common_bktr_intr(arg); }
828 
829 static u_long	bktr_count;
830 
831 static struct	pci_device bktr_device = {
832 	"bktr",
833 	bktr_probe,
834 	bktr_attach,
835 	&bktr_count
836 };
837 
838 DATA_SET (pcidevice_set, bktr_device);
839 
840 static	d_open_t	bktr_open;
841 static	d_close_t	bktr_close;
842 static	d_read_t	bktr_read;
843 static	d_write_t	bktr_write;
844 static	d_ioctl_t	bktr_ioctl;
845 static	d_mmap_t	bktr_mmap;
846 static	d_poll_t	bktr_poll;
847 
848 #define CDEV_MAJOR 92
849 static struct cdevsw bktr_cdevsw =
850 {
851 	bktr_open,	bktr_close,	bktr_read,	bktr_write,
852 	bktr_ioctl,	nostop,		nullreset,	nodevtotty,
853 	bktr_poll,	bktr_mmap,	NULL,		"bktr",
854 	NULL,		-1
855 };
856 
857 static int bktr_devsw_installed;
858 
859 static void
860 bktr_drvinit( void *unused )
861 {
862 	dev_t dev;
863 
864 	if ( ! bktr_devsw_installed ) {
865 		dev = makedev(CDEV_MAJOR, 0);
866 		cdevsw_add(&dev,&bktr_cdevsw, NULL);
867 		bktr_devsw_installed = 1;
868 	}
869 }
870 
871 SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL)
872 
873 /*
874  * the boot time probe routine.
875  */
876 static const char*
877 bktr_probe( pcici_t tag, pcidi_t type )
878 {
879         unsigned int rev = pci_conf_read( tag, PCIR_REVID) & 0x000000ff;
880 
881 	if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
882 	{
883 		switch (PCI_PRODUCT(type)) {
884 		case PCI_PRODUCT_BROOKTREE_BT848:
885 			if (rev == 0x12) return("BrookTree 848A");
886 			else             return("BrookTree 848");
887 		case PCI_PRODUCT_BROOKTREE_BT849:
888 			return("BrookTree 849A");
889 		case PCI_PRODUCT_BROOKTREE_BT878:
890 			return("BrookTree 878");
891 		case PCI_PRODUCT_BROOKTREE_BT879:
892 			return("BrookTree 879");
893 		}
894 	};
895 
896 	return ((char *)0);
897 }
898 
899 /*
900  * the attach routine.
901  */
902 static	void
903 bktr_attach( pcici_t tag, int unit )
904 {
905 	bktr_ptr_t	bktr;
906 	u_long		latency;
907 	u_long		fun;
908 	unsigned int	rev;
909 	unsigned long	base;
910 #ifdef BROOKTREE_IRQ
911 	u_long		old_irq, new_irq;
912 #endif
913 
914 	bktr = &brooktree[unit];
915 
916 	if (unit >= NBKTR) {
917 		printf("brooktree%d: attach: only %d units configured.\n",
918 		        unit, NBKTR);
919 		printf("brooktree%d: attach: invalid unit number.\n", unit);
920 		return;
921 	}
922 
923 	/* build the device name for bktr_name() */
924 	snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
925 
926 	/* Enable Memory Mapping */
927 	fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
928 	pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2);
929 
930 	/* Enable Bus Mastering */
931 	fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
932 	pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4);
933 
934 	bktr->tag = tag;
935 
936 
937 	/*
938 	 * Map control/status registers
939 	 */
940 	pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &base,
941 		     &bktr->phys_base );
942 #if (__FreeBSD_version >= 300000)
943 	bktr->memt = I386_BUS_SPACE_MEM; /* XXX should use proper bus space */
944 	bktr->memh = (bus_space_handle_t)base; /* XXX functions here */
945 #endif
946 
947 	/*
948 	 * Disable the brooktree device
949 	 */
950 	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
951 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
952 
953 #ifdef BROOKTREE_IRQ		/* from the configuration file */
954 	old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
955 	pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
956 	new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
957 	printf("bktr%d: attach: irq changed from %d to %d\n",
958 		unit, (old_irq & 0xff), (new_irq & 0xff));
959 #endif
960 
961 	/*
962 	 * setup the interrupt handling routine
963 	 */
964 	pci_map_int(tag, bktr_intr, (void*) bktr, &tty_imask);
965 
966 
967 	/* Update the Device Control Register */
968 	/* on Bt878 and Bt879 cards */
969 	fun = pci_conf_read(tag, 0x40);
970         fun = fun | 1;	/* Enable writes to the sub-system vendor ID */
971 
972 #if defined( BKTR_430_FX_MODE )
973 	if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
974         fun = fun | 2;	/* Enable Intel 430 FX compatibility mode */
975 #endif
976 
977 #if defined( BKTR_SIS_VIA_MODE )
978 	if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
979         fun = fun | 4;	/* Enable SiS/VIA compatibility mode (usefull for
980                            OPTi chipset motherboards too */
981 #endif
982 	pci_conf_write(tag, 0x40, fun);
983 
984 
985 	/* XXX call bt848_i2c dependent attach() routine */
986 #if defined(BKTR_USE_FREEBSD_SMBUS)
987 	if (bt848_i2c_attach(unit, bktr, &bktr->i2c_sc))
988 		printf("bktr%d: i2c_attach: can't attach\n", unit);
989 #endif
990 
991 
992 /*
993  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
994  * you have more than four, then 16 would probably be a better value.
995  */
996 #ifndef BROOKTREE_DEF_LATENCY_VALUE
997 #define BROOKTREE_DEF_LATENCY_VALUE	10
998 #endif
999 	latency = pci_conf_read(tag, PCI_LATENCY_TIMER);
1000 	latency = (latency >> 8) & 0xff;
1001 	if ( bootverbose ) {
1002 		if (latency)
1003 			printf("brooktree%d: PCI bus latency is", unit);
1004 		else
1005 			printf("brooktree%d: PCI bus latency was 0 changing to",
1006 				unit);
1007 	}
1008 	if ( !latency ) {
1009 		latency = BROOKTREE_DEF_LATENCY_VALUE;
1010 		pci_conf_write(tag, PCI_LATENCY_TIMER,	latency<<8);
1011 	}
1012 	if ( bootverbose ) {
1013 		printf(" %d.\n", (int) latency);
1014 	}
1015 
1016 
1017 	/* read the pci device id and revision id */
1018 	fun = pci_conf_read(tag, PCI_ID_REG);
1019         rev = pci_conf_read(tag, PCIR_REVID) & 0x000000ff;
1020 
1021 	/* call the common attach code */
1022 	common_bktr_attach( bktr, unit, fun, rev );
1023 
1024 }
1025 
1026 
1027 /*
1028  * Special Memory Allocation
1029  */
1030 vm_offset_t
1031 get_bktr_mem( int unit, unsigned size )
1032 {
1033 	vm_offset_t	addr = 0;
1034 
1035 	addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
1036 	if (addr == 0)
1037 		addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
1038 								PAGE_SIZE);
1039 	if (addr == 0) {
1040 		printf("bktr%d: Unable to allocate %d bytes of memory.\n",
1041 			unit, size);
1042 	}
1043 
1044 	return( addr );
1045 }
1046 
1047 /*---------------------------------------------------------
1048 **
1049 **	BrookTree 848 character device driver routines
1050 **
1051 **---------------------------------------------------------
1052 */
1053 
1054 
1055 #define VIDEO_DEV	0x00
1056 #define TUNER_DEV	0x01
1057 #define VBI_DEV		0x02
1058 
1059 #define UNIT(x)		((x) & 0x0f)
1060 #define FUNCTION(x)	((x >> 4) & 0x0f)
1061 
1062 
1063 /*
1064  *
1065  */
1066 int
1067 bktr_open( dev_t dev, int flags, int fmt, d_thread_t *td)
1068 {
1069 	bktr_ptr_t	bktr;
1070 	int		unit;
1071 
1072 	unit = UNIT( minor(dev) );
1073 	if (unit >= NBKTR)			/* unit out of range */
1074 		return( ENXIO );
1075 
1076 	bktr = &(brooktree[ unit ]);
1077 
1078 	if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1079 		return( ENXIO );
1080 
1081 
1082 	if (bt848_card != -1) {
1083 	  if ((bt848_card >> 8   == unit ) &&
1084 	     ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
1085 	    if ( bktr->bt848_card != (bt848_card & 0xff) ) {
1086 	      bktr->bt848_card = (bt848_card & 0xff);
1087 	      probeCard(bktr, FALSE, unit);
1088 	    }
1089 	  }
1090 	}
1091 
1092 	if (bt848_tuner != -1) {
1093 	  if ((bt848_tuner >> 8   == unit ) &&
1094 	     ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
1095 	    if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
1096 	      bktr->bt848_tuner = (bt848_tuner & 0xff);
1097 	      probeCard(bktr, FALSE, unit);
1098 	    }
1099 	  }
1100 	}
1101 
1102 	if (bt848_reverse_mute != -1) {
1103 	  if ((bt848_reverse_mute >> 8)   == unit ) {
1104 	    bktr->reverse_mute = bt848_reverse_mute & 0xff;
1105 	  }
1106 	}
1107 
1108 	if (bt848_slow_msp_audio != -1) {
1109 	  if ((bt848_slow_msp_audio >> 8) == unit ) {
1110 	      bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
1111 	  }
1112 	}
1113 
1114 	switch ( FUNCTION( minor(dev) ) ) {
1115 	case VIDEO_DEV:
1116 		return( video_open( bktr ) );
1117 	case TUNER_DEV:
1118 		return( tuner_open( bktr ) );
1119 	case VBI_DEV:
1120 		return( vbi_open( bktr ) );
1121 	}
1122 	return( ENXIO );
1123 }
1124 
1125 
1126 /*
1127  *
1128  */
1129 int
1130 bktr_close( dev_t dev, int flags, int fmt, d_thread_t *td)
1131 {
1132 	bktr_ptr_t	bktr;
1133 	int		unit;
1134 
1135 	unit = UNIT( minor(dev) );
1136 	if (unit >= NBKTR)			/* unit out of range */
1137 		return( ENXIO );
1138 
1139 	bktr = &(brooktree[ unit ]);
1140 
1141 	switch ( FUNCTION( minor(dev) ) ) {
1142 	case VIDEO_DEV:
1143 		return( video_close( bktr ) );
1144 	case TUNER_DEV:
1145 		return( tuner_close( bktr ) );
1146 	case VBI_DEV:
1147 		return( vbi_close( bktr ) );
1148 	}
1149 
1150 	return( ENXIO );
1151 }
1152 
1153 /*
1154  *
1155  */
1156 int
1157 bktr_read( dev_t dev, struct uio *uio, int ioflag )
1158 {
1159 	bktr_ptr_t	bktr;
1160 	int		unit;
1161 
1162 	unit = UNIT(minor(dev));
1163 	if (unit >= NBKTR)	/* unit out of range */
1164 		return( ENXIO );
1165 
1166 	bktr = &(brooktree[unit]);
1167 
1168 	switch ( FUNCTION( minor(dev) ) ) {
1169 	case VIDEO_DEV:
1170 		return( video_read( bktr, unit, dev, uio ) );
1171 	case VBI_DEV:
1172 		return( vbi_read( bktr, uio, ioflag ) );
1173 	}
1174         return( ENXIO );
1175 }
1176 
1177 
1178 /*
1179  *
1180  */
1181 int
1182 bktr_write( dev_t dev, struct uio *uio, int ioflag )
1183 {
1184 	return( EINVAL ); /* XXX or ENXIO ? */
1185 }
1186 
1187 /*
1188  *
1189  */
1190 int
1191 bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
1192 {
1193 	bktr_ptr_t	bktr;
1194 	int		unit;
1195 
1196 	unit = UNIT(minor(dev));
1197 	if (unit >= NBKTR)	/* unit out of range */
1198 		return( ENXIO );
1199 
1200 	bktr = &(brooktree[ unit ]);
1201 
1202 	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
1203 		return( ENOMEM );
1204 
1205 	switch ( FUNCTION( minor(dev) ) ) {
1206 	case VIDEO_DEV:
1207 		return( video_ioctl( bktr, unit, cmd, arg, td ) );
1208 	case TUNER_DEV:
1209 		return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
1210 	}
1211 
1212 	return( ENXIO );
1213 }
1214 
1215 /*
1216  * bktr_mmap.
1217  * Note: 2.2.5/2.2.6/2.2.7/3.0 users must manually
1218  * edit the line below and change  "vm_offset_t" to "int"
1219  */
1220 int bktr_mmap( dev_t dev, vm_offset_t offset, int nprot )
1221 
1222 {
1223 	int		unit;
1224 	bktr_ptr_t	bktr;
1225 
1226 	unit = UNIT(minor(dev));
1227 
1228 	if (unit >= NBKTR || FUNCTION(minor(dev)) > 0)
1229 		return( -1 );
1230 
1231 	bktr = &(brooktree[ unit ]);
1232 
1233 	if (nprot & PROT_EXEC)
1234 		return( -1 );
1235 
1236 	if (offset < 0)
1237 		return( -1 );
1238 
1239 	if (offset >= bktr->alloc_pages * PAGE_SIZE)
1240 		return( -1 );
1241 
1242 	return( i386_btop(vtophys(bktr->bigbuf) + offset) );
1243 }
1244 
1245 int bktr_poll( dev_t dev, int events, d_thread_t *td)
1246 {
1247 	int		unit;
1248 	bktr_ptr_t	bktr;
1249 	int revents = 0;
1250 
1251 	unit = UNIT(minor(dev));
1252 
1253 	if (unit >= NBKTR)
1254 		return( -1 );
1255 
1256 	bktr = &(brooktree[ unit ]);
1257 
1258 	disable_intr();
1259 
1260 	if (events & (POLLIN | POLLRDNORM)) {
1261 
1262 		switch ( FUNCTION( minor(dev) ) ) {
1263 		case VBI_DEV:
1264 			if(bktr->vbisize == 0)
1265 				selrecord(p, &bktr->vbi_select);
1266 			else
1267 				revents |= events & (POLLIN | POLLRDNORM);
1268 			break;
1269 		}
1270 	}
1271 
1272 	enable_intr();
1273 
1274 	return (revents);
1275 }
1276 
1277 
1278 #endif		/* FreeBSD 2.2.x and 3.x specific kernel interface routines */
1279 
1280 
1281 /*****************/
1282 /* *** BSDI  *** */
1283 /*****************/
1284 
1285 #if defined(__bsdi__)
1286 #endif		/* __bsdi__ BSDI specific kernel interface routines */
1287 
1288 
1289 /*****************************/
1290 /* *** OpenBSD / NetBSD  *** */
1291 /*****************************/
1292 #if defined(__NetBSD__) || defined(__OpenBSD__)
1293 
1294 #define IPL_VIDEO       IPL_BIO         /* XXX */
1295 
1296 static	int		bktr_intr(void *arg) { return common_bktr_intr(arg); }
1297 
1298 #define bktr_open       bktropen
1299 #define bktr_close      bktrclose
1300 #define bktr_read       bktrread
1301 #define bktr_write      bktrwrite
1302 #define bktr_ioctl      bktrioctl
1303 #define bktr_mmap       bktrmmap
1304 
1305 vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t,
1306                                  vm_offset_t, vm_offset_t);
1307 
1308 #if defined(__OpenBSD__)
1309 static int      bktr_probe (struct device *, void *, void *);
1310 #else
1311 static int      bktr_probe (struct device *, struct cfdata *, void *);
1312 #endif
1313 static void     bktr_attach (struct device *, struct device *, void *);
1314 
1315 struct cfattach bktr_ca = {
1316         sizeof(struct bktr_softc), bktr_probe, bktr_attach
1317 };
1318 
1319 #if defined(__NetBSD__)
1320 extern struct cfdriver bktr_cd;
1321 #else
1322 struct cfdriver bktr_cd = {
1323         NULL, "bktr", DV_DULL
1324 };
1325 #endif
1326 
1327 int
1328 bktr_probe(parent, match, aux)
1329 	struct device *parent;
1330 #if defined(__OpenBSD__)
1331         void *match;
1332 #else
1333         struct cfdata *match;
1334 #endif
1335         void *aux;
1336 {
1337         struct pci_attach_args *pa = aux;
1338 
1339         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
1340             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
1341              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
1342              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
1343              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
1344                 return 1;
1345 
1346         return 0;
1347 }
1348 
1349 
1350 /*
1351  * the attach routine.
1352  */
1353 static void
1354 bktr_attach(struct device *parent, struct device *self, void *aux)
1355 {
1356 	bktr_ptr_t	bktr;
1357 	u_long		latency;
1358 	u_long		fun;
1359 	unsigned int	rev;
1360 
1361 #if defined(__OpenBSD__)
1362 	struct pci_attach_args *pa = aux;
1363 	pci_chipset_tag_t pc = pa->pa_pc;
1364 
1365 	pci_intr_handle_t ih;
1366 	const char *intrstr;
1367 	int retval;
1368 	int unit;
1369 
1370 	bktr = (bktr_ptr_t)self;
1371 	unit = bktr->bktr_dev.dv_unit;
1372 
1373 	bktr->pc = pa->pa_pc;
1374 	bktr->tag = pa->pa_tag;
1375         bktr->dmat = pa->pa_dmat;
1376 
1377 	/*
1378 	 * map memory
1379 	 */
1380 	bktr->memt = pa->pa_memt;
1381 	retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START,
1382 			      &bktr->phys_base, &bktr->obmemsz, NULL);
1383 	if (!retval)
1384 		retval = bus_space_map(pa->pa_memt, bktr->phys_base,
1385 				       bktr->obmemsz, 0, &bktr->memh);
1386 	if (retval) {
1387 		printf(": couldn't map memory\n");
1388 		return;
1389 	}
1390 
1391 
1392 	/*
1393 	 * map interrupt
1394 	 */
1395 	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1396 			 pa->pa_intrline, &ih)) {
1397 		printf(": couldn't map interrupt\n");
1398 		return;
1399 	}
1400 	intrstr = pci_intr_string(pa->pa_pc, ih);
1401 
1402 	bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
1403 				      bktr_intr, bktr, bktr->bktr_dev.dv_xname);
1404 	if (bktr->ih == NULL) {
1405 		printf(": couldn't establish interrupt");
1406 		if (intrstr != NULL)
1407 			printf(" at %s", intrstr);
1408 		printf("\n");
1409 		return;
1410 	}
1411 
1412 	if (intrstr != NULL)
1413 		printf(": %s\n", intrstr);
1414 #endif /* __OpenBSD__ */
1415 
1416 #if defined(__NetBSD__)
1417 	struct pci_attach_args *pa = aux;
1418 	pci_intr_handle_t ih;
1419 	const char *intrstr;
1420 	int retval;
1421 	int unit;
1422 
1423 	bktr = (bktr_ptr_t)self;
1424 	unit = bktr->bktr_dev.dv_unit;
1425         bktr->dmat = pa->pa_dmat;
1426 
1427 	printf("\n");
1428 
1429 	/*
1430 	 * map memory
1431 	 */
1432 	retval = pci_mapreg_map(pa, PCI_MAPREG_START,
1433 				PCI_MAPREG_TYPE_MEM
1434 				| PCI_MAPREG_MEM_TYPE_32BIT, 0,
1435 				&bktr->memt, &bktr->memh, NULL,
1436 				&bktr->obmemsz);
1437 	DPR(("pci_mapreg_map: memt %x, memh %x, size %x\n",
1438 	     bktr->memt, (u_int)bktr->memh, (u_int)bktr->obmemsz));
1439 	if (retval) {
1440 		printf("%s: couldn't map memory\n", bktr_name(bktr));
1441 		return;
1442 	}
1443 
1444 	/*
1445 	 * Disable the brooktree device
1446 	 */
1447 	OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1448 	OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1449 
1450 	/*
1451 	 * map interrupt
1452 	 */
1453 	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1454 			 pa->pa_intrline, &ih)) {
1455 		printf("%s: couldn't map interrupt\n",
1456 		       bktr_name(bktr));
1457 		return;
1458 	}
1459 	intrstr = pci_intr_string(pa->pa_pc, ih);
1460 	bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
1461 				      bktr_intr, bktr);
1462 	if (bktr->ih == NULL) {
1463 		printf("%s: couldn't establish interrupt",
1464 		       bktr_name(bktr));
1465 		if (intrstr != NULL)
1466 			printf(" at %s", intrstr);
1467 		printf("\n");
1468 		return;
1469 	}
1470 	if (intrstr != NULL)
1471 		printf("%s: interrupting at %s\n", bktr_name(bktr),
1472 		       intrstr);
1473 #endif /* __NetBSD__ */
1474 
1475 /*
1476  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
1477  * you have more than four, then 16 would probably be a better value.
1478  */
1479 #ifndef BROOKTREE_DEF_LATENCY_VALUE
1480 #define BROOKTREE_DEF_LATENCY_VALUE	10
1481 #endif
1482 	latency = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER);
1483 	latency = (latency >> 8) & 0xff;
1484 
1485 	if (!latency) {
1486 		if (bootverbose) {
1487 			printf("%s: PCI bus latency was 0 changing to %d",
1488 			       bktr_name(bktr), BROOKTREE_DEF_LATENCY_VALUE);
1489 		}
1490 		latency = BROOKTREE_DEF_LATENCY_VALUE;
1491 		pci_conf_write(pa->pa_pc, pa->pa_tag,
1492 			       PCI_LATENCY_TIMER, latency<<8);
1493 	}
1494 
1495 
1496 	/* Enabled Bus Master
1497 	   XXX: check if all old DMA is stopped first (e.g. after warm
1498 	   boot) */
1499 	fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
1500 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1501 		       fun | PCI_COMMAND_MASTER_ENABLE);
1502 
1503 	/* read the pci id and determine the card type */
1504 	fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
1505         rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff;
1506 
1507 	common_bktr_attach(bktr, unit, fun, rev);
1508 }
1509 
1510 
1511 /*
1512  * Special Memory Allocation
1513  */
1514 vm_offset_t
1515 get_bktr_mem(bktr, dmapp, size)
1516         bktr_ptr_t bktr;
1517         bus_dmamap_t *dmapp;
1518         unsigned int size;
1519 {
1520         bus_dma_tag_t dmat = bktr->dmat;
1521         bus_dma_segment_t seg;
1522         bus_size_t align;
1523         int rseg;
1524         caddr_t kva;
1525 
1526         /*
1527          * Allocate a DMA area
1528          */
1529         align = 1 << 24;
1530         if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1531                              &rseg, BUS_DMA_NOWAIT)) {
1532                 align = PAGE_SIZE;
1533                 if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1534                                      &rseg, BUS_DMA_NOWAIT)) {
1535                         printf("%s: Unable to dmamem_alloc of %d bytes\n",
1536 			       bktr_name(bktr), size);
1537                         return 0;
1538                 }
1539         }
1540         if (bus_dmamem_map(dmat, &seg, rseg, size,
1541                            &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1542                 printf("%s: Unable to dmamem_map of %d bytes\n",
1543                         bktr_name(bktr), size);
1544                 bus_dmamem_free(dmat, &seg, rseg);
1545                 return 0;
1546         }
1547 #ifdef __OpenBSD__
1548         bktr->dm_mapsize = size;
1549 #endif
1550         /*
1551          * Create and locd the DMA map for the DMA area
1552          */
1553         if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) {
1554                 printf("%s: Unable to dmamap_create of %d bytes\n",
1555                         bktr_name(bktr), size);
1556                 bus_dmamem_unmap(dmat, kva, size);
1557                 bus_dmamem_free(dmat, &seg, rseg);
1558                 return 0;
1559         }
1560         if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) {
1561                 printf("%s: Unable to dmamap_load of %d bytes\n",
1562                         bktr_name(bktr), size);
1563                 bus_dmamem_unmap(dmat, kva, size);
1564                 bus_dmamem_free(dmat, &seg, rseg);
1565                 bus_dmamap_destroy(dmat, *dmapp);
1566                 return 0;
1567         }
1568         return (vm_offset_t)kva;
1569 }
1570 
1571 void
1572 free_bktr_mem(bktr, dmap, kva)
1573         bktr_ptr_t bktr;
1574         bus_dmamap_t dmap;
1575         vm_offset_t kva;
1576 {
1577         bus_dma_tag_t dmat = bktr->dmat;
1578 
1579 #ifdef __NetBSD__
1580         bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize);
1581 #else
1582         bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize);
1583 #endif
1584         bus_dmamem_free(dmat, dmap->dm_segs, 1);
1585         bus_dmamap_destroy(dmat, dmap);
1586 }
1587 
1588 
1589 /*---------------------------------------------------------
1590 **
1591 **	BrookTree 848 character device driver routines
1592 **
1593 **---------------------------------------------------------
1594 */
1595 
1596 
1597 #define VIDEO_DEV	0x00
1598 #define TUNER_DEV	0x01
1599 #define VBI_DEV		0x02
1600 
1601 #define UNIT(x)         (minor((x) & 0x0f))
1602 #define FUNCTION(x)     (minor((x >> 4) & 0x0f))
1603 
1604 /*
1605  *
1606  */
1607 int
1608 bktr_open(dev_t dev, int flags, int fmt, d_thread_t *td)
1609 {
1610 	bktr_ptr_t	bktr;
1611 	int		unit;
1612 
1613 	unit = UNIT(dev);
1614 
1615 	/* unit out of range */
1616 	if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
1617 		return(ENXIO);
1618 
1619 	bktr = bktr_cd.cd_devs[unit];
1620 
1621 	if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1622 		return(ENXIO);
1623 
1624 	switch (FUNCTION(dev)) {
1625 	case VIDEO_DEV:
1626 		return(video_open(bktr));
1627 	case TUNER_DEV:
1628 		return(tuner_open(bktr));
1629 	case VBI_DEV:
1630 		return(vbi_open(bktr));
1631 	}
1632 
1633 	return(ENXIO);
1634 }
1635 
1636 
1637 /*
1638  *
1639  */
1640 int
1641 bktr_close(dev_t dev, int flags, int fmt, d_thread_t *td)
1642 {
1643 	bktr_ptr_t	bktr;
1644 	int		unit;
1645 
1646 	unit = UNIT(dev);
1647 
1648 	bktr = bktr_cd.cd_devs[unit];
1649 
1650 	switch (FUNCTION(dev)) {
1651 	case VIDEO_DEV:
1652 		return(video_close(bktr));
1653 	case TUNER_DEV:
1654 		return(tuner_close(bktr));
1655 	case VBI_DEV:
1656 		return(vbi_close(bktr));
1657 	}
1658 
1659 	return(ENXIO);
1660 }
1661 
1662 /*
1663  *
1664  */
1665 int
1666 bktr_read(dev_t dev, struct uio *uio, int ioflag)
1667 {
1668 	bktr_ptr_t	bktr;
1669 	int		unit;
1670 
1671 	unit = UNIT(dev);
1672 
1673 	bktr = bktr_cd.cd_devs[unit];
1674 
1675 	switch (FUNCTION(dev)) {
1676 	case VIDEO_DEV:
1677 		return(video_read(bktr, unit, dev, uio));
1678 	case VBI_DEV:
1679 		return(vbi_read(bktr, uio, ioflag));
1680 	}
1681 
1682         return(ENXIO);
1683 }
1684 
1685 
1686 /*
1687  *
1688  */
1689 int
1690 bktr_write(dev_t dev, struct uio *uio, int ioflag)
1691 {
1692 	/* operation not supported */
1693 	return(EOPNOTSUPP);
1694 }
1695 
1696 /*
1697  *
1698  */
1699 int
1700 bktr_ioctl(dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, d_thread_t *td)
1701 {
1702 	bktr_ptr_t	bktr;
1703 	int		unit;
1704 
1705 	unit = UNIT(dev);
1706 
1707 	bktr = bktr_cd.cd_devs[unit];
1708 
1709 	if (bktr->bigbuf == 0)	/* no frame buffer allocated (ioctl failed) */
1710 		return(ENOMEM);
1711 
1712 	switch (FUNCTION(dev)) {
1713 	case VIDEO_DEV:
1714 		return(video_ioctl(bktr, unit, cmd, arg, td));
1715 	case TUNER_DEV:
1716 		return(tuner_ioctl(bktr, unit, cmd, arg, td));
1717 	}
1718 
1719 	return(ENXIO);
1720 }
1721 
1722 /*
1723  *
1724  */
1725 paddr_t
1726 bktr_mmap(dev_t dev, off_t offset, int nprot)
1727 {
1728 	int		unit;
1729 	bktr_ptr_t	bktr;
1730 
1731 	unit = UNIT(dev);
1732 
1733 	if (FUNCTION(dev) > 0)	/* only allow mmap on /dev/bktr[n] */
1734 		return(-1);
1735 
1736 	bktr = bktr_cd.cd_devs[unit];
1737 
1738 	if ((vaddr_t)offset < 0)
1739 		return(-1);
1740 
1741 	if ((vaddr_t)offset >= bktr->alloc_pages * PAGE_SIZE)
1742 		return(-1);
1743 
1744 #ifdef __NetBSD__
1745 	return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1,
1746 				(vaddr_t)offset, nprot, BUS_DMA_WAITOK));
1747 #else
1748 	return(i386_btop(vtophys(bktr->bigbuf) + offset));
1749 #endif
1750 }
1751 
1752 #endif /* __NetBSD__ || __OpenBSD__ */
1753