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