]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/dev/bktr/bktr_os.c
Copy head to stable/8 as part of 8.0 Release cycle.
[FreeBSD/stable/8.git] / sys / dev / bktr / bktr_os.c
1 /*-
2  * 1. Redistributions of source code must retain the 
3  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Amancio Hasty and
17  *      Roger Hardiman
18  * 4. The name of the author may not be used to endorse or promote products 
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 /*
38  * This is part of the Driver for Video Capture Cards (Frame grabbers)
39  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
40  * chipset.
41  * Copyright Roger Hardiman and Amancio Hasty.
42  *
43  * bktr_os : This has all the Operating System dependant code,
44  *             probe/attach and open/close/ioctl/read/mmap
45  *             memory allocation
46  *             PCI bus interfacing
47  */
48
49 #include "opt_bktr.h"           /* include any kernel config options */
50
51 #define FIFO_RISC_DISABLED      0
52 #define ALL_INTS_DISABLED       0
53
54
55 /*******************/
56 /* *** FreeBSD *** */
57 /*******************/
58 #ifdef __FreeBSD__
59
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/conf.h>
63 #include <sys/uio.h>
64 #include <sys/kernel.h>
65 #include <sys/module.h>
66 #include <sys/signalvar.h>
67 #include <sys/malloc.h>
68 #include <sys/mman.h>
69 #include <sys/poll.h>
70 #if __FreeBSD_version >= 500014
71 #include <sys/selinfo.h>
72 #else
73 #include <sys/select.h>
74 #endif
75
76 #include <vm/vm.h>
77 #include <vm/vm_kern.h>
78 #include <vm/pmap.h>
79 #include <vm/vm_extern.h>
80
81 #include <sys/bus.h>            /* used by smbus and newbus */
82
83 #include <machine/bus.h>        /* used by bus space and newbus */
84 #include <sys/bus.h>
85
86 #include <sys/rman.h>           /* used by newbus */
87 #include <machine/resource.h>   /* used by newbus */
88
89 #if (__FreeBSD_version < 500000)
90 #include <machine/clock.h>              /* for DELAY */
91 #include <pci/pcivar.h>
92 #include <pci/pcireg.h>
93 #else
94 #include <dev/pci/pcivar.h>
95 #include <dev/pci/pcireg.h>
96 #endif
97
98 #include <sys/sysctl.h>
99 int bt848_card = -1; 
100 int bt848_tuner = -1;
101 int bt848_reverse_mute = -1; 
102 int bt848_format = -1;
103 int bt848_slow_msp_audio = -1;
104 #ifdef BKTR_NEW_MSP34XX_DRIVER
105 int bt848_stereo_once = 0;      /* no continuous stereo monitoring */
106 int bt848_amsound = 0;          /* hard-wire AM sound at 6.5 Hz (france),
107                                    the autoscan seems work well only with FM... */
108 int bt848_dolby = 0;
109 #endif
110
111 SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
112 SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
113 SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
114 SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
115 SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
116 SYSCTL_INT(_hw_bt848, OID_AUTO, slow_msp_audio, CTLFLAG_RW, &bt848_slow_msp_audio, -1, "");
117 #ifdef BKTR_NEW_MSP34XX_DRIVER
118 SYSCTL_INT(_hw_bt848, OID_AUTO, stereo_once, CTLFLAG_RW, &bt848_stereo_once, 0, "");
119 SYSCTL_INT(_hw_bt848, OID_AUTO, amsound, CTLFLAG_RW, &bt848_amsound, 0, "");
120 SYSCTL_INT(_hw_bt848, OID_AUTO, dolby, CTLFLAG_RW, &bt848_dolby, 0, "");
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 #include <dev/bktr/ioctl_bt848.h>       /* extensions to ioctl_meteor.h */
153
154 #ifndef __NetBSD__
155 #include <vm/vm_kern.h>
156 #include <vm/pmap.h>
157 #include <vm/vm_extern.h>
158 #endif
159
160 #include <sys/device.h>
161 #include <dev/pci/pcivar.h>
162 #include <dev/pci/pcireg.h>
163 #include <dev/pci/pcidevs.h>
164
165 #define BKTR_DEBUG
166 #ifdef BKTR_DEBUG
167 int bktr_debug = 0;
168 #define DPR(x)  (bktr_debug ? printf x : 0)
169 #else
170 #define DPR(x)
171 #endif
172 #endif /* __NetBSD__ || __OpenBSD__ */
173
174
175 #ifdef __NetBSD__
176 #include <dev/ic/bt8xx.h>       /* NetBSD location for .h files */
177 #include <dev/pci/bktr/bktr_reg.h>
178 #include <dev/pci/bktr/bktr_tuner.h>
179 #include <dev/pci/bktr/bktr_card.h>
180 #include <dev/pci/bktr/bktr_audio.h>
181 #include <dev/pci/bktr/bktr_core.h>
182 #include <dev/pci/bktr/bktr_os.h>
183 #else                                   /* Traditional location for .h files */
184 #include <dev/bktr/ioctl_meteor.h>
185 #include <dev/bktr/ioctl_bt848.h>       /* extensions to ioctl_meteor.h */
186 #include <dev/bktr/bktr_reg.h>
187 #include <dev/bktr/bktr_tuner.h>
188 #include <dev/bktr/bktr_card.h>
189 #include <dev/bktr/bktr_audio.h>
190 #include <dev/bktr/bktr_core.h>
191 #include <dev/bktr/bktr_os.h>
192
193 #if defined(BKTR_USE_FREEBSD_SMBUS)
194 #include <dev/bktr/bktr_i2c.h>
195
196 #include "iicbb_if.h"
197 #include "smbus_if.h"
198 #endif
199 #endif
200
201
202 /****************************/
203 /* *** FreeBSD 4.x code *** */
204 /****************************/
205
206 static int      bktr_probe( device_t dev );
207 static int      bktr_attach( device_t dev );
208 static int      bktr_detach( device_t dev );
209 static int      bktr_shutdown( device_t dev );
210 static void     bktr_intr(void *arg) { common_bktr_intr(arg); }
211
212 static device_method_t bktr_methods[] = {
213         /* Device interface */
214         DEVMETHOD(device_probe,         bktr_probe),
215         DEVMETHOD(device_attach,        bktr_attach),
216         DEVMETHOD(device_detach,        bktr_detach),
217         DEVMETHOD(device_shutdown,      bktr_shutdown),
218
219 #if defined(BKTR_USE_FREEBSD_SMBUS)
220         /* iicbb interface */
221         DEVMETHOD(iicbb_callback,       bti2c_iic_callback),
222         DEVMETHOD(iicbb_setsda,         bti2c_iic_setsda),
223         DEVMETHOD(iicbb_setscl,         bti2c_iic_setscl),
224         DEVMETHOD(iicbb_getsda,         bti2c_iic_getsda),
225         DEVMETHOD(iicbb_getscl,         bti2c_iic_getscl),
226         DEVMETHOD(iicbb_reset,          bti2c_iic_reset),
227         
228         /* smbus interface */
229         DEVMETHOD(smbus_callback,       bti2c_smb_callback),
230         DEVMETHOD(smbus_writeb,         bti2c_smb_writeb),
231         DEVMETHOD(smbus_writew,         bti2c_smb_writew),
232         DEVMETHOD(smbus_readb,          bti2c_smb_readb),
233 #endif
234
235         { 0, 0 }
236 };
237
238 static driver_t bktr_driver = {
239         "bktr",
240         bktr_methods,
241         sizeof(struct bktr_softc),
242 };
243
244 static devclass_t bktr_devclass;
245
246 static  d_open_t        bktr_open;
247 static  d_close_t       bktr_close;
248 static  d_read_t        bktr_read;
249 static  d_write_t       bktr_write;
250 static  d_ioctl_t       bktr_ioctl;
251 static  d_mmap_t        bktr_mmap;
252 static  d_poll_t        bktr_poll;
253
254 static struct cdevsw bktr_cdevsw = {
255         .d_version =    D_VERSION,
256         .d_flags =      D_NEEDGIANT,
257         .d_open =       bktr_open,
258         .d_close =      bktr_close,
259         .d_read =       bktr_read,
260         .d_write =      bktr_write,
261         .d_ioctl =      bktr_ioctl,
262         .d_poll =       bktr_poll,
263         .d_mmap =       bktr_mmap,
264         .d_name =       "bktr",
265 };
266
267 #ifdef BKTR_USE_FREEBSD_SMBUS
268 #include <dev/iicbus/iiconf.h>
269 #include <dev/smbus/smbconf.h>
270 MODULE_DEPEND(bktr, iicbb, IICBB_MINVER, IICBB_MODVER, IICBB_MAXVER);
271 MODULE_DEPEND(bktr, iicbus, IICBUS_MINVER, IICBUS_MODVER, IICBUS_MAXVER);
272 MODULE_DEPEND(bktr, smbus, SMBUS_MINVER, SMBUS_MODVER, SMBUS_MAXVER);
273 #endif
274 DRIVER_MODULE(bktr, pci, bktr_driver, bktr_devclass, 0, 0);
275 MODULE_DEPEND(bktr, bktr_mem, 1,1,1);
276 MODULE_VERSION(bktr, 1);
277
278
279 /*
280  * the boot time probe routine.
281  */
282 static int
283 bktr_probe( device_t dev )
284 {
285         unsigned int type = pci_get_devid(dev);
286         unsigned int rev  = pci_get_revid(dev);
287
288         if (PCI_VENDOR(type) == PCI_VENDOR_BROOKTREE)
289         {
290                 switch (PCI_PRODUCT(type)) {
291                 case PCI_PRODUCT_BROOKTREE_BT848:
292                         if (rev == 0x12)
293                                 device_set_desc(dev, "BrookTree 848A");
294                         else
295                                 device_set_desc(dev, "BrookTree 848");
296                         return BUS_PROBE_DEFAULT;
297                 case PCI_PRODUCT_BROOKTREE_BT849:
298                         device_set_desc(dev, "BrookTree 849A");
299                         return BUS_PROBE_DEFAULT;
300                 case PCI_PRODUCT_BROOKTREE_BT878:
301                         device_set_desc(dev, "BrookTree 878");
302                         return BUS_PROBE_DEFAULT;
303                 case PCI_PRODUCT_BROOKTREE_BT879:
304                         device_set_desc(dev, "BrookTree 879");
305                         return BUS_PROBE_DEFAULT;
306                 }
307         };
308
309         return ENXIO;
310 }
311
312
313 /*
314  * the attach routine.
315  */
316 static int
317 bktr_attach( device_t dev )
318 {
319         u_long          latency;
320         u_long          fun;
321         u_long          val;
322         unsigned int    rev;
323         unsigned int    unit;
324         int             error = 0;
325 #ifdef BROOKTREE_IRQ
326         u_long          old_irq, new_irq;
327 #endif 
328
329         struct bktr_softc *bktr = device_get_softc(dev);
330
331         unit = device_get_unit(dev);
332
333         /* build the device name for bktr_name() */
334         snprintf(bktr->bktr_xname, sizeof(bktr->bktr_xname), "bktr%d",unit);
335
336         /*
337          * Enable bus mastering and Memory Mapped device
338          */
339         val = pci_read_config(dev, PCIR_COMMAND, 4);
340         val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
341         pci_write_config(dev, PCIR_COMMAND, val, 4);
342
343         /*
344          * Map control/status registers.
345          */
346         bktr->mem_rid = PCIR_BAR(0);
347         bktr->res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 
348                                         &bktr->mem_rid, RF_ACTIVE);
349
350         if (!bktr->res_mem) {
351                 device_printf(dev, "could not map memory\n");
352                 error = ENXIO;
353                 goto fail;
354         }
355         bktr->memt = rman_get_bustag(bktr->res_mem);
356         bktr->memh = rman_get_bushandle(bktr->res_mem);
357
358
359         /*
360          * Disable the brooktree device
361          */
362         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
363         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
364
365
366 #ifdef BROOKTREE_IRQ            /* from the configuration file */
367         old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
368         pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
369         new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
370         printf("bktr%d: attach: irq changed from %d to %d\n",
371                 unit, (old_irq & 0xff), (new_irq & 0xff));
372 #endif 
373
374         /*
375          * Allocate our interrupt.
376          */
377         bktr->irq_rid = 0;
378         bktr->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 
379                                 &bktr->irq_rid, RF_SHAREABLE | RF_ACTIVE);
380         if (bktr->res_irq == NULL) {
381                 device_printf(dev, "could not map interrupt\n");
382                 error = ENXIO;
383                 goto fail;
384         }
385
386         error = bus_setup_intr(dev, bktr->res_irq, INTR_TYPE_TTY,
387                                NULL, bktr_intr, bktr, &bktr->res_ih);
388         if (error) {
389                 device_printf(dev, "could not setup irq\n");
390                 goto fail;
391
392         }
393
394
395         /* Update the Device Control Register */
396         /* on Bt878 and Bt879 cards           */
397         fun = pci_read_config( dev, 0x40, 2);
398         fun = fun | 1;  /* Enable writes to the sub-system vendor ID */
399
400 #if defined( BKTR_430_FX_MODE )
401         if (bootverbose) printf("Using 430 FX chipset compatibilty mode\n");
402         fun = fun | 2;  /* Enable Intel 430 FX compatibility mode */
403 #endif
404
405 #if defined( BKTR_SIS_VIA_MODE )
406         if (bootverbose) printf("Using SiS/VIA chipset compatibilty mode\n");
407         fun = fun | 4;  /* Enable SiS/VIA compatibility mode (usefull for
408                            OPTi chipset motherboards too */
409 #endif
410         pci_write_config(dev, 0x40, fun, 2);
411
412 #if defined(BKTR_USE_FREEBSD_SMBUS)
413         if (bt848_i2c_attach(dev))
414                 printf("bktr%d: i2c_attach: can't attach\n", unit);
415 #endif
416
417 /*
418  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
419  * you have more than four, then 16 would probably be a better value.
420  */
421 #ifndef BROOKTREE_DEF_LATENCY_VALUE
422 #define BROOKTREE_DEF_LATENCY_VALUE     10
423 #endif
424         latency = pci_read_config(dev, PCI_LATENCY_TIMER, 4);
425         latency = (latency >> 8) & 0xff;
426         if ( bootverbose ) {
427                 if (latency)
428                         printf("brooktree%d: PCI bus latency is", unit);
429                 else
430                         printf("brooktree%d: PCI bus latency was 0 changing to",
431                                 unit);
432         }
433         if ( !latency ) {
434                 latency = BROOKTREE_DEF_LATENCY_VALUE;
435                 pci_write_config(dev, PCI_LATENCY_TIMER, latency<<8, 4);
436         }
437         if ( bootverbose ) {
438                 printf(" %d.\n", (int) latency);
439         }
440
441         /* read the pci device id and revision id */
442         fun = pci_get_devid(dev);
443         rev = pci_get_revid(dev);
444
445         /* call the common attach code */
446         common_bktr_attach( bktr, unit, fun, rev );
447
448         /* make the device entries */
449         bktr->bktrdev = make_dev(&bktr_cdevsw, unit,    
450                                 0, 0, 0444, "bktr%d",  unit);
451         bktr->tunerdev= make_dev(&bktr_cdevsw, unit+16,
452                                 0, 0, 0444, "tuner%d", unit);
453         bktr->vbidev  = make_dev(&bktr_cdevsw, unit+32,
454                                 0, 0, 0444, "vbi%d"  , unit);
455
456
457         /* if this is unit 0 (/dev/bktr0, /dev/tuner0, /dev/vbi0) then make */
458         /* alias entries to /dev/bktr /dev/tuner and /dev/vbi */
459 #if (__FreeBSD_version >=500000)
460         if (unit == 0) {
461                 bktr->bktrdev_alias = make_dev_alias(bktr->bktrdev,  "bktr");
462                 bktr->tunerdev_alias= make_dev_alias(bktr->tunerdev, "tuner");
463                 bktr->vbidev_alias  = make_dev_alias(bktr->vbidev,   "vbi");
464         }
465 #endif
466
467         return 0;
468
469 fail:
470         if (bktr->res_irq)
471                 bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
472         if (bktr->res_mem)
473                 bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
474         return error;
475
476 }
477
478 /*
479  * the detach routine.
480  */
481 static int
482 bktr_detach( device_t dev )
483 {
484         struct bktr_softc *bktr = device_get_softc(dev);
485
486 #ifdef BKTR_NEW_MSP34XX_DRIVER
487         /* Disable the soundchip and kernel thread */
488         if (bktr->msp3400c_info != NULL)
489                 msp_detach(bktr);
490 #endif
491
492         /* Disable the brooktree device */
493         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
494         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
495
496 #if defined(BKTR_USE_FREEBSD_SMBUS)
497         if (bt848_i2c_detach(dev))
498                 printf("bktr%d: i2c_attach: can't attach\n",
499                      device_get_unit(dev));
500 #endif
501 #ifdef USE_VBIMUTEX
502         mtx_destroy(&bktr->vbimutex);
503 #endif
504
505         /* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
506         /* The memory is retained by the bktr_mem module so we can unload and */
507         /* then reload the main bktr driver module */
508
509         /* Unregister the /dev/bktrN, tunerN and vbiN devices,
510          * the aliases for unit 0 are automatically destroyed */
511         destroy_dev(bktr->vbidev);
512         destroy_dev(bktr->tunerdev);
513         destroy_dev(bktr->bktrdev);
514
515         /*
516          * Deallocate resources.
517          */
518         bus_teardown_intr(dev, bktr->res_irq, bktr->res_ih);
519         bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq);
520         bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem);
521          
522         return 0;
523 }
524
525 /*
526  * the shutdown routine.
527  */
528 static int
529 bktr_shutdown( device_t dev )
530 {
531         struct bktr_softc *bktr = device_get_softc(dev);
532
533         /* Disable the brooktree device */
534         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
535         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
536
537         return 0;
538 }
539
540
541 /*
542  * Special Memory Allocation
543  */
544 vm_offset_t
545 get_bktr_mem( int unit, unsigned size )
546 {
547         vm_offset_t     addr = 0;
548
549         addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0,
550             0xffffffff, 1<<24, 0);
551         if (addr == 0)
552                 addr = (vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, 0,
553                     0xffffffff, PAGE_SIZE, 0);
554         if (addr == 0) {
555                 printf("bktr%d: Unable to allocate %d bytes of memory.\n",
556                         unit, size);
557         }
558
559         return( addr );
560 }
561
562
563 /*---------------------------------------------------------
564 **
565 **      BrookTree 848 character device driver routines
566 **
567 **---------------------------------------------------------
568 */
569
570 #define VIDEO_DEV       0x00
571 #define TUNER_DEV       0x01
572 #define VBI_DEV         0x02
573
574 #define UNIT(x)         ((x) & 0x0f)
575 #define FUNCTION(x)     (x >> 4)
576
577 /*
578  * 
579  */
580 static int
581 bktr_open( struct cdev *dev, int flags, int fmt, struct thread *td )
582 {
583         bktr_ptr_t      bktr;
584         int             unit;
585         int             result;
586
587         unit = UNIT( dev2unit(dev) );
588
589         /* Get the device data */
590         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
591         if (bktr == NULL) {
592                 /* the device is no longer valid/functioning */
593                 return (ENXIO);
594         }
595
596         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
597                 return( ENXIO );        
598
599         /* Record that the device is now busy */
600         newbus_xlock();
601         device_busy(devclass_get_device(bktr_devclass, unit)); 
602         newbus_xunlock();
603
604
605         if (bt848_card != -1) {
606           if ((bt848_card >> 8   == unit ) &&
607              ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
608             if ( bktr->bt848_card != (bt848_card & 0xff) ) {
609               bktr->bt848_card = (bt848_card & 0xff);
610               probeCard(bktr, FALSE, unit);
611             }
612           }
613         }
614
615         if (bt848_tuner != -1) {
616           if ((bt848_tuner >> 8   == unit ) &&
617              ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
618             if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
619               bktr->bt848_tuner = (bt848_tuner & 0xff);
620               probeCard(bktr, FALSE, unit);
621             }
622           }
623         }
624
625         if (bt848_reverse_mute != -1) {
626           if ((bt848_reverse_mute >> 8)   == unit ) {
627             bktr->reverse_mute = bt848_reverse_mute & 0xff;
628           }
629         }
630
631         if (bt848_slow_msp_audio != -1) {
632           if ((bt848_slow_msp_audio >> 8) == unit ) {
633               bktr->slow_msp_audio = (bt848_slow_msp_audio & 0xff);
634           }
635         }
636
637 #ifdef BKTR_NEW_MSP34XX_DRIVER
638         if (bt848_stereo_once != 0) {
639           if ((bt848_stereo_once >> 8) == unit ) {
640               bktr->stereo_once = (bt848_stereo_once & 0xff);
641           }
642         }
643
644         if (bt848_amsound != -1) {
645           if ((bt848_amsound >> 8) == unit ) {
646               bktr->amsound = (bt848_amsound & 0xff);
647           }
648         }
649
650         if (bt848_dolby != -1) {
651           if ((bt848_dolby >> 8) == unit ) {
652               bktr->dolby = (bt848_dolby & 0xff);
653           }
654         }
655 #endif
656
657         switch ( FUNCTION( dev2unit(dev) ) ) {
658         case VIDEO_DEV:
659                 result = video_open( bktr );
660                 break;
661         case TUNER_DEV:
662                 result = tuner_open( bktr );
663                 break;
664         case VBI_DEV:
665                 result = vbi_open( bktr );
666                 break;
667         default:
668                 result = ENXIO;
669                 break;
670         }
671
672         /* If there was an error opening the device, undo the busy status */
673         if (result != 0) {
674                 newbus_xlock();
675                 device_unbusy(devclass_get_device(bktr_devclass, unit)); 
676                 newbus_xunlock();
677         }
678         return( result );
679 }
680
681
682 /*
683  * 
684  */
685 static int
686 bktr_close( struct cdev *dev, int flags, int fmt, struct thread *td )
687 {
688         bktr_ptr_t      bktr;
689         int             unit;
690         int             result;
691
692         unit = UNIT( dev2unit(dev) );
693
694         /* Get the device data */
695         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
696         if (bktr == NULL) {
697
698                 /* the device is no longer valid/functioning */
699                 return (ENXIO);
700         }
701
702         switch ( FUNCTION( dev2unit(dev) ) ) {
703         case VIDEO_DEV:
704                 result = video_close( bktr );
705                 break;
706         case TUNER_DEV:
707                 result = tuner_close( bktr );
708                 break;
709         case VBI_DEV:
710                 result = vbi_close( bktr );
711                 break;
712         default:
713                 return (ENXIO);
714         }
715
716         newbus_xlock();
717         device_unbusy(devclass_get_device(bktr_devclass, unit)); 
718         newbus_xunlock();
719         return( result );
720 }
721
722
723 /*
724  * 
725  */
726 static int
727 bktr_read( struct cdev *dev, struct uio *uio, int ioflag )
728 {
729         bktr_ptr_t      bktr;
730         int             unit;
731         
732         unit = UNIT(dev2unit(dev));
733
734         /* Get the device data */
735         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
736         if (bktr == NULL) {
737                 /* the device is no longer valid/functioning */
738                 return (ENXIO);
739         }
740
741         switch ( FUNCTION( dev2unit(dev) ) ) {
742         case VIDEO_DEV:
743                 return( video_read( bktr, unit, dev, uio ) );
744         case VBI_DEV:
745                 return( vbi_read( bktr, uio, ioflag ) );
746         }
747         return( ENXIO );
748 }
749
750
751 /*
752  * 
753  */
754 static int
755 bktr_write( struct cdev *dev, struct uio *uio, int ioflag )
756 {
757         return( EINVAL ); /* XXX or ENXIO ? */
758 }
759
760
761 /*
762  * 
763  */
764 static int
765 bktr_ioctl( struct cdev *dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td )
766 {
767         bktr_ptr_t      bktr;
768         int             unit;
769
770         unit = UNIT(dev2unit(dev));
771
772         /* Get the device data */
773         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
774         if (bktr == NULL) {
775                 /* the device is no longer valid/functioning */
776                 return (ENXIO);
777         }
778
779 #ifdef BKTR_GPIO_ACCESS
780         if (bktr->bigbuf == 0 && cmd != BT848_GPIO_GET_EN &&
781             cmd != BT848_GPIO_SET_EN && cmd != BT848_GPIO_GET_DATA &&
782             cmd != BT848_GPIO_SET_DATA) /* no frame buffer allocated (ioctl failed) */
783                 return( ENOMEM );
784 #else
785         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
786                 return( ENOMEM );
787 #endif
788
789         switch ( FUNCTION( dev2unit(dev) ) ) {
790         case VIDEO_DEV:
791                 return( video_ioctl( bktr, unit, cmd, arg, td ) );
792         case TUNER_DEV:
793                 return( tuner_ioctl( bktr, unit, cmd, arg, td ) );
794         }
795
796         return( ENXIO );
797 }
798
799
800 /*
801  * 
802  */
803 static int
804 bktr_mmap( struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot )
805 {
806         int             unit;
807         bktr_ptr_t      bktr;
808
809         unit = UNIT(dev2unit(dev));
810
811         if (FUNCTION(dev2unit(dev)) > 0)        /* only allow mmap on /dev/bktr[n] */
812                 return( -1 );
813
814         /* Get the device data */
815         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
816         if (bktr == NULL) {
817                 /* the device is no longer valid/functioning */
818                 return (ENXIO);
819         }
820
821         if (nprot & PROT_EXEC)
822                 return( -1 );
823
824         if (offset < 0)
825                 return( -1 );
826
827         if (offset >= bktr->alloc_pages * PAGE_SIZE)
828                 return( -1 );
829
830         *paddr = vtophys(bktr->bigbuf) + offset;
831         return( 0 );
832 }
833
834 static int
835 bktr_poll( struct cdev *dev, int events, struct thread *td)
836 {
837         int             unit;
838         bktr_ptr_t      bktr;
839         int revents = 0; 
840         DECLARE_INTR_MASK(s);
841
842         unit = UNIT(dev2unit(dev));
843
844         /* Get the device data */
845         bktr = (struct bktr_softc*)devclass_get_softc(bktr_devclass, unit);
846         if (bktr == NULL) {
847                 /* the device is no longer valid/functioning */
848                 return (ENXIO);
849         }
850
851         LOCK_VBI(bktr);
852         DISABLE_INTR(s);
853
854         if (events & (POLLIN | POLLRDNORM)) {
855
856                 switch ( FUNCTION( dev2unit(dev) ) ) {
857                 case VBI_DEV:
858                         if(bktr->vbisize == 0)
859                                 selrecord(td, &bktr->vbi_select);
860                         else
861                                 revents |= events & (POLLIN | POLLRDNORM);
862                         break;
863                 }
864         }
865
866         ENABLE_INTR(s);
867         UNLOCK_VBI(bktr);
868
869         return (revents);
870 }
871
872 /*****************/
873 /* *** BSDI  *** */
874 /*****************/
875
876 #if defined(__bsdi__)
877 #endif          /* __bsdi__ BSDI specific kernel interface routines */
878
879
880 /*****************************/
881 /* *** OpenBSD / NetBSD  *** */
882 /*****************************/
883 #if defined(__NetBSD__) || defined(__OpenBSD__)
884
885 #define IPL_VIDEO       IPL_BIO         /* XXX */
886
887 static  int             bktr_intr(void *arg) { return common_bktr_intr(arg); }
888
889 #define bktr_open       bktropen
890 #define bktr_close      bktrclose
891 #define bktr_read       bktrread
892 #define bktr_write      bktrwrite
893 #define bktr_ioctl      bktrioctl
894 #define bktr_mmap       bktrmmap
895
896 vm_offset_t vm_page_alloc_contig(vm_offset_t, vm_offset_t,
897                                  vm_offset_t, vm_offset_t);
898
899 #if defined(__OpenBSD__)
900 static int      bktr_probe(struct device *, void *, void *);
901 #else
902 static int      bktr_probe(struct device *, struct cfdata *, void *);
903 #endif
904 static void     bktr_attach(struct device *, struct device *, void *);
905
906 struct cfattach bktr_ca = {
907         sizeof(struct bktr_softc), bktr_probe, bktr_attach
908 };
909
910 #if defined(__NetBSD__)
911 extern struct cfdriver bktr_cd;
912 #else
913 struct cfdriver bktr_cd = {
914         NULL, "bktr", DV_DULL
915 };
916 #endif
917
918 int
919 bktr_probe(parent, match, aux)
920         struct device *parent;
921 #if defined(__OpenBSD__)
922         void *match;
923 #else
924         struct cfdata *match;
925 #endif
926         void *aux;
927 {
928         struct pci_attach_args *pa = aux;
929
930         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
931             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
932              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
933              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
934              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
935                 return 1;
936
937         return 0;
938 }
939
940
941 /*
942  * the attach routine.
943  */
944 static void
945 bktr_attach(struct device *parent, struct device *self, void *aux)
946 {
947         bktr_ptr_t      bktr;
948         u_long          latency;
949         u_long          fun;
950         unsigned int    rev;
951
952 #if defined(__OpenBSD__)
953         struct pci_attach_args *pa = aux;
954         pci_chipset_tag_t pc = pa->pa_pc;
955
956         pci_intr_handle_t ih;
957         const char *intrstr;
958         int retval;
959         int unit;
960
961         bktr = (bktr_ptr_t)self;
962         unit = bktr->bktr_dev.dv_unit;
963
964         bktr->pc = pa->pa_pc;
965         bktr->tag = pa->pa_tag;
966         bktr->dmat = pa->pa_dmat;
967
968         /*
969          * map memory
970          */
971         bktr->memt = pa->pa_memt;
972         retval = pci_mem_find(pc, pa->pa_tag, PCI_MAPREG_START, 
973                               &bktr->phys_base, &bktr->obmemsz, NULL);
974         if (!retval)
975                 retval = bus_space_map(pa->pa_memt, bktr->phys_base,
976                                        bktr->obmemsz, 0, &bktr->memh);
977         if (retval) {
978                 printf(": couldn't map memory\n");
979                 return;
980         }
981
982
983         /*
984          * map interrupt
985          */
986         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
987                          pa->pa_intrline, &ih)) {
988                 printf(": couldn't map interrupt\n");
989                 return;
990         }
991         intrstr = pci_intr_string(pa->pa_pc, ih);
992
993         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
994                                       bktr_intr, bktr, bktr->bktr_dev.dv_xname);
995         if (bktr->ih == NULL) {
996                 printf(": couldn't establish interrupt");
997                 if (intrstr != NULL)    
998                         printf(" at %s", intrstr);
999                 printf("\n");
1000                 return;
1001         }
1002
1003         if (intrstr != NULL)
1004                 printf(": %s\n", intrstr);
1005 #endif /* __OpenBSD__ */
1006
1007 #if defined(__NetBSD__) 
1008         struct pci_attach_args *pa = aux;
1009         pci_intr_handle_t ih;
1010         const char *intrstr;
1011         int retval;
1012         int unit;
1013
1014         bktr = (bktr_ptr_t)self;
1015         unit = bktr->bktr_dev.dv_unit;
1016         bktr->dmat = pa->pa_dmat;
1017
1018         printf("\n");
1019
1020         /*
1021          * map memory
1022          */
1023         retval = pci_mapreg_map(pa, PCI_MAPREG_START,
1024                                 PCI_MAPREG_TYPE_MEM
1025                                 | PCI_MAPREG_MEM_TYPE_32BIT, 0,
1026                                 &bktr->memt, &bktr->memh, NULL,
1027                                 &bktr->obmemsz);
1028         DPR(("pci_mapreg_map: memt %x, memh %x, size %x\n",
1029              bktr->memt, (u_int)bktr->memh, (u_int)bktr->obmemsz));
1030         if (retval) {
1031                 printf("%s: couldn't map memory\n", bktr_name(bktr));
1032                 return;
1033         }
1034
1035         /*
1036          * Disable the brooktree device
1037          */
1038         OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1039         OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1040         
1041         /*
1042          * map interrupt
1043          */
1044         if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1045                          pa->pa_intrline, &ih)) {
1046                 printf("%s: couldn't map interrupt\n",
1047                        bktr_name(bktr));
1048                 return;
1049         }
1050         intrstr = pci_intr_string(pa->pa_pc, ih);
1051         bktr->ih = pci_intr_establish(pa->pa_pc, ih, IPL_VIDEO,
1052                                       bktr_intr, bktr);
1053         if (bktr->ih == NULL) {
1054                 printf("%s: couldn't establish interrupt",
1055                        bktr_name(bktr));
1056                 if (intrstr != NULL)
1057                         printf(" at %s", intrstr);
1058                 printf("\n");
1059                 return;
1060         }
1061         if (intrstr != NULL)
1062                 printf("%s: interrupting at %s\n", bktr_name(bktr),
1063                        intrstr);
1064 #endif /* __NetBSD__ */
1065         
1066 /*
1067  * PCI latency timer.  32 is a good value for 4 bus mastering slots, if
1068  * you have more than four, then 16 would probably be a better value.
1069  */
1070 #ifndef BROOKTREE_DEF_LATENCY_VALUE
1071 #define BROOKTREE_DEF_LATENCY_VALUE     10
1072 #endif
1073         latency = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_LATENCY_TIMER);
1074         latency = (latency >> 8) & 0xff;
1075
1076         if (!latency) {
1077                 if (bootverbose) {
1078                         printf("%s: PCI bus latency was 0 changing to %d",
1079                                bktr_name(bktr), BROOKTREE_DEF_LATENCY_VALUE);
1080                 }
1081                 latency = BROOKTREE_DEF_LATENCY_VALUE;
1082                 pci_conf_write(pa->pa_pc, pa->pa_tag, 
1083                                PCI_LATENCY_TIMER, latency<<8);
1084         }
1085
1086
1087         /* Enabled Bus Master
1088            XXX: check if all old DMA is stopped first (e.g. after warm
1089            boot) */
1090         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
1091         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
1092                        fun | PCI_COMMAND_MASTER_ENABLE);
1093
1094         /* read the pci id and determine the card type */
1095         fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
1096         rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0x000000ff;
1097
1098         common_bktr_attach(bktr, unit, fun, rev);
1099 }
1100
1101
1102 /*
1103  * Special Memory Allocation
1104  */
1105 vm_offset_t
1106 get_bktr_mem(bktr, dmapp, size)
1107         bktr_ptr_t bktr;
1108         bus_dmamap_t *dmapp;
1109         unsigned int size;
1110 {
1111         bus_dma_tag_t dmat = bktr->dmat;
1112         bus_dma_segment_t seg;
1113         bus_size_t align;
1114         int rseg;
1115         caddr_t kva;
1116
1117         /*
1118          * Allocate a DMA area
1119          */
1120         align = 1 << 24;
1121         if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1122                              &rseg, BUS_DMA_NOWAIT)) {
1123                 align = PAGE_SIZE;
1124                 if (bus_dmamem_alloc(dmat, size, align, 0, &seg, 1,
1125                                      &rseg, BUS_DMA_NOWAIT)) {
1126                         printf("%s: Unable to dmamem_alloc of %d bytes\n",
1127                                bktr_name(bktr), size);
1128                         return 0;
1129                 }
1130         }
1131         if (bus_dmamem_map(dmat, &seg, rseg, size,
1132                            &kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1133                 printf("%s: Unable to dmamem_map of %d bytes\n",
1134                         bktr_name(bktr), size);
1135                 bus_dmamem_free(dmat, &seg, rseg);
1136                 return 0;
1137         }
1138 #ifdef __OpenBSD__
1139         bktr->dm_mapsize = size;
1140 #endif
1141         /*
1142          * Create and locd the DMA map for the DMA area
1143          */
1144         if (bus_dmamap_create(dmat, size, 1, size, 0, BUS_DMA_NOWAIT, dmapp)) {
1145                 printf("%s: Unable to dmamap_create of %d bytes\n",
1146                         bktr_name(bktr), size);
1147                 bus_dmamem_unmap(dmat, kva, size);
1148                 bus_dmamem_free(dmat, &seg, rseg);
1149                 return 0;
1150         }
1151         if (bus_dmamap_load(dmat, *dmapp, kva, size, NULL, BUS_DMA_NOWAIT)) {
1152                 printf("%s: Unable to dmamap_load of %d bytes\n",
1153                         bktr_name(bktr), size);
1154                 bus_dmamem_unmap(dmat, kva, size);
1155                 bus_dmamem_free(dmat, &seg, rseg);
1156                 bus_dmamap_destroy(dmat, *dmapp);
1157                 return 0;
1158         }
1159         return (vm_offset_t)kva;
1160 }
1161
1162 void
1163 free_bktr_mem(bktr, dmap, kva)
1164         bktr_ptr_t bktr;
1165         bus_dmamap_t dmap;
1166         vm_offset_t kva;
1167 {
1168         bus_dma_tag_t dmat = bktr->dmat;
1169
1170 #ifdef __NetBSD__ 
1171         bus_dmamem_unmap(dmat, (caddr_t)kva, dmap->dm_mapsize);
1172 #else
1173         bus_dmamem_unmap(dmat, (caddr_t)kva, bktr->dm_mapsize);
1174 #endif
1175         bus_dmamem_free(dmat, dmap->dm_segs, 1);
1176         bus_dmamap_destroy(dmat, dmap);
1177 }
1178
1179
1180 /*---------------------------------------------------------
1181 **
1182 **      BrookTree 848 character device driver routines
1183 **
1184 **---------------------------------------------------------
1185 */
1186
1187
1188 #define VIDEO_DEV       0x00
1189 #define TUNER_DEV       0x01
1190 #define VBI_DEV         0x02
1191
1192 #define UNIT(x)         (dev2unit((x) & 0x0f))
1193 #define FUNCTION(x)     (dev2unit((x >> 4) & 0x0f))
1194
1195 /*
1196  * 
1197  */
1198 int
1199 bktr_open(dev_t dev, int flags, int fmt, struct thread *td)
1200 {
1201         bktr_ptr_t      bktr;
1202         int             unit;
1203
1204         unit = UNIT(dev);
1205
1206         /* unit out of range */
1207         if ((unit > bktr_cd.cd_ndevs) || (bktr_cd.cd_devs[unit] == NULL))
1208                 return(ENXIO);
1209
1210         bktr = bktr_cd.cd_devs[unit];
1211
1212         if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1213                 return(ENXIO);  
1214
1215         switch (FUNCTION(dev)) {
1216         case VIDEO_DEV:
1217                 return(video_open(bktr));
1218         case TUNER_DEV:
1219                 return(tuner_open(bktr));
1220         case VBI_DEV:
1221                 return(vbi_open(bktr));
1222         }
1223
1224         return(ENXIO);
1225 }
1226
1227
1228 /*
1229  * 
1230  */
1231 int
1232 bktr_close(dev_t dev, int flags, int fmt, struct thread *td)
1233 {
1234         bktr_ptr_t      bktr;
1235         int             unit;
1236
1237         unit = UNIT(dev);
1238
1239         bktr = bktr_cd.cd_devs[unit];
1240
1241         switch (FUNCTION(dev)) {
1242         case VIDEO_DEV:
1243                 return(video_close(bktr));
1244         case TUNER_DEV:
1245                 return(tuner_close(bktr));
1246         case VBI_DEV:
1247                 return(vbi_close(bktr));
1248         }
1249
1250         return(ENXIO);
1251 }
1252
1253 /*
1254  * 
1255  */
1256 int
1257 bktr_read(dev_t dev, struct uio *uio, int ioflag)
1258 {
1259         bktr_ptr_t      bktr;
1260         int             unit;
1261         
1262         unit = UNIT(dev);
1263
1264         bktr = bktr_cd.cd_devs[unit];
1265
1266         switch (FUNCTION(dev)) {
1267         case VIDEO_DEV:
1268                 return(video_read(bktr, unit, dev, uio));
1269         case VBI_DEV:
1270                 return(vbi_read(bktr, uio, ioflag));
1271         }
1272
1273         return(ENXIO);
1274 }
1275
1276
1277 /*
1278  * 
1279  */
1280 int
1281 bktr_write(dev_t dev, struct uio *uio, int ioflag)
1282 {
1283         /* operation not supported */
1284         return(EOPNOTSUPP);
1285 }
1286
1287 /*
1288  * 
1289  */
1290 int
1291 bktr_ioctl(dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct thread *td)
1292 {
1293         bktr_ptr_t      bktr;
1294         int             unit;
1295
1296         unit = UNIT(dev);
1297
1298         bktr = bktr_cd.cd_devs[unit];
1299
1300         if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
1301                 return(ENOMEM);
1302
1303         switch (FUNCTION(dev)) {
1304         case VIDEO_DEV:
1305                 return(video_ioctl(bktr, unit, cmd, arg, pr));
1306         case TUNER_DEV:
1307                 return(tuner_ioctl(bktr, unit, cmd, arg, pr));
1308         }
1309
1310         return(ENXIO);
1311 }
1312
1313 /*
1314  * 
1315  */
1316 paddr_t
1317 bktr_mmap(dev_t dev, off_t offset, int nprot)
1318 {
1319         int             unit;
1320         bktr_ptr_t      bktr;
1321
1322         unit = UNIT(dev);
1323
1324         if (FUNCTION(dev) > 0)  /* only allow mmap on /dev/bktr[n] */
1325                 return(-1);
1326
1327         bktr = bktr_cd.cd_devs[unit];
1328
1329         if ((vaddr_t)offset < 0)
1330                 return(-1);
1331
1332         if ((vaddr_t)offset >= bktr->alloc_pages * PAGE_SIZE)
1333                 return(-1);
1334
1335 #ifdef __NetBSD__
1336         return (bus_dmamem_mmap(bktr->dmat, bktr->dm_mem->dm_segs, 1,
1337                                 (vaddr_t)offset, nprot, BUS_DMA_WAITOK));
1338 #else
1339         return(i386_btop(vtophys(bktr->bigbuf) + offset));
1340 #endif
1341 }
1342
1343 #endif /* __NetBSD__ || __OpenBSD__ */