xref: /netbsd-src/sys/arch/sparc64/dev/ebus.c (revision 3b01aba77a7a698587faaae455bbfe740923c1f5)
1 /*	$NetBSD: ebus.c,v 1.24 2001/07/25 03:49:54 eeh Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Matthew R. Green
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include "opt_ddb.h"
32 
33 /*
34  * UltraSPARC 5 and beyond ebus support.
35  *
36  * note that this driver is not complete:
37  *	- ebus2 dma code is completely unwritten
38  *	- interrupt establish is written and appears to work
39  *	- bus map code is written and appears to work
40  */
41 
42 #undef DEBUG
43 #define DEBUG
44 
45 #ifdef DEBUG
46 #define	EDB_PROM	0x01
47 #define EDB_CHILD	0x02
48 #define	EDB_INTRMAP	0x04
49 #define EDB_BUSMAP	0x08
50 #define EDB_BUSDMA	0x10
51 #define EDB_INTR	0x20
52 int ebus_debug = 0x0;
53 #define DPRINTF(l, s)   do { if (ebus_debug & l) printf s; } while (0)
54 #else
55 #define DPRINTF(l, s)
56 #endif
57 
58 #include <sys/param.h>
59 #include <sys/conf.h>
60 #include <sys/device.h>
61 #include <sys/errno.h>
62 #include <sys/extent.h>
63 #include <sys/malloc.h>
64 #include <sys/systm.h>
65 #include <sys/time.h>
66 
67 #define _SPARC_BUS_DMA_PRIVATE
68 #include <machine/bus.h>
69 #include <machine/autoconf.h>
70 #include <machine/openfirm.h>
71 
72 #include <dev/pci/pcivar.h>
73 #include <dev/pci/pcireg.h>
74 #include <dev/pci/pcidevs.h>
75 
76 #include <sparc64/dev/iommureg.h>
77 #include <sparc64/dev/iommuvar.h>
78 #include <sparc64/dev/psychoreg.h>
79 #include <sparc64/dev/psychovar.h>
80 #include <sparc64/dev/ebusreg.h>
81 #include <sparc64/dev/ebusvar.h>
82 #include <sparc64/sparc64/cache.h>
83 
84 int	ebus_match __P((struct device *, struct cfdata *, void *));
85 void	ebus_attach __P((struct device *, struct device *, void *));
86 
87 struct cfattach ebus_ca = {
88 	sizeof(struct ebus_softc), ebus_match, ebus_attach
89 };
90 
91 int	ebus_setup_attach_args __P((struct ebus_softc *, int,
92 	    struct ebus_attach_args *));
93 void	ebus_destroy_attach_args __P((struct ebus_attach_args *));
94 int	ebus_print __P((void *, const char *));
95 void	ebus_find_ino __P((struct ebus_softc *, struct ebus_attach_args *));
96 int	ebus_find_node __P((struct pci_attach_args *));
97 
98 /*
99  * here are our bus space and bus dma routines.
100  */
101 static int ebus_bus_mmap __P((bus_space_tag_t, bus_type_t, bus_addr_t,
102 				int, bus_space_handle_t *));
103 static int _ebus_bus_map __P((bus_space_tag_t, bus_type_t, bus_addr_t,
104 				bus_size_t, int, vaddr_t,
105 				bus_space_handle_t *));
106 static void *ebus_intr_establish __P((bus_space_tag_t, int, int, int,
107 				int (*) __P((void *)), void *));
108 
109 static int ebus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
110 			  bus_size_t, struct proc *, int));
111 static void ebus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
112 static void ebus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
113 				  bus_size_t, int));
114 int ebus_dmamem_alloc __P((bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
115 			   bus_dma_segment_t *, int, int *, int));
116 void ebus_dmamem_free __P((bus_dma_tag_t, bus_dma_segment_t *, int));
117 int ebus_dmamem_map __P((bus_dma_tag_t, bus_dma_segment_t *, int, size_t,
118 			 caddr_t *, int));
119 void ebus_dmamem_unmap __P((bus_dma_tag_t, caddr_t, size_t));
120 
121 int
122 ebus_match(parent, match, aux)
123 	struct device *parent;
124 	struct cfdata *match;
125 	void *aux;
126 {
127 	struct pci_attach_args *pa = aux;
128 	char name[10];
129 	int node;
130 
131 	/* Only attach if there's a PROM node. */
132 	node = PCITAG_NODE(pa->pa_tag);
133 	if (node == -1) return (0);
134 
135 	/* Match a real ebus */
136 	OF_getprop(node, "name", &name, sizeof(name));
137 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
138 	    PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN &&
139 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_EBUS &&
140 		strcmp(name, "ebus") == 0)
141 		return (1);
142 
143 	/* Or a PCI-ISA bridge XXX I hope this is on-board. */
144 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
145 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA) {
146 		return (1);
147 	}
148 
149 	return (0);
150 }
151 
152 /*
153  * attach an ebus and all it's children.  this code is modeled
154  * after the sbus code which does similar things.
155  */
156 void
157 ebus_attach(parent, self, aux)
158 	struct device *parent, *self;
159 	void *aux;
160 {
161 	struct ebus_softc *sc = (struct ebus_softc *)self;
162 	struct pci_attach_args *pa = aux;
163 	struct ebus_attach_args eba;
164 	struct ebus_interrupt_map_mask *immp;
165 	int node, nmapmask, error;
166 	char devinfo[256];
167 
168 	printf("\n");
169 
170 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
171 	printf("%s: %s, revision 0x%02x\n", self->dv_xname, devinfo,
172 	    PCI_REVISION(pa->pa_class));
173 
174 	sc->sc_parent = (struct psycho_softc *)parent;
175 	sc->sc_memtag = pa->pa_memt;
176 	sc->sc_iotag = pa->pa_iot;
177 	sc->sc_childbustag = ebus_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
178 	sc->sc_dmatag = ebus_alloc_dma_tag(sc, pa->pa_dmat);
179 
180 	node = PCITAG_NODE(pa->pa_tag);
181 	if (node == -1)
182 		panic("could not find ebus node");
183 
184 	sc->sc_node = node;
185 
186 	/*
187 	 * fill in our softc with information from the prom
188 	 */
189 	sc->sc_intmap = NULL;
190 	sc->sc_range = NULL;
191 	error = getprop(node, "interrupt-map",
192 			sizeof(struct ebus_interrupt_map),
193 			&sc->sc_nintmap, (void **)&sc->sc_intmap);
194 	switch (error) {
195 	case 0:
196 		immp = &sc->sc_intmapmask;
197 		error = getprop(node, "interrupt-map-mask",
198 			    sizeof(struct ebus_interrupt_map_mask), &nmapmask,
199 			    (void **)&immp);
200 		if (error)
201 			panic("could not get ebus interrupt-map-mask");
202 		if (nmapmask != 1)
203 			panic("ebus interrupt-map-mask is broken");
204 		break;
205 	case ENOENT:
206 		break;
207 	default:
208 		panic("ebus interrupt-map: error %d", error);
209 		break;
210 	}
211 
212 	error = getprop(node, "ranges", sizeof(struct ebus_ranges),
213 	    &sc->sc_nrange, (void **)&sc->sc_range);
214 	if (error)
215 		panic("ebus ranges: error %d", error);
216 
217 	/*
218 	 * now attach all our children
219 	 */
220 	DPRINTF(EDB_CHILD, ("ebus node %08x, searching children...\n", node));
221 	for (node = firstchild(node); node; node = nextsibling(node)) {
222 		char *name = getpropstring(node, "name");
223 
224 		if (ebus_setup_attach_args(sc, node, &eba) != 0) {
225 			printf("ebus_attach: %s: incomplete\n", name);
226 			continue;
227 		} else {
228 			DPRINTF(EDB_CHILD, ("- found child `%s', attaching\n",
229 			    eba.ea_name));
230 			(void)config_found(self, &eba, ebus_print);
231 		}
232 		ebus_destroy_attach_args(&eba);
233 	}
234 }
235 
236 int
237 ebus_setup_attach_args(sc, node, ea)
238 	struct ebus_softc	*sc;
239 	int			node;
240 	struct ebus_attach_args	*ea;
241 {
242 	int	n, rv;
243 
244 	bzero(ea, sizeof(struct ebus_attach_args));
245 	rv = getprop(node, "name", 1, &n, (void **)&ea->ea_name);
246 	if (rv != 0)
247 		return (rv);
248 	ea->ea_name[n] = '\0';
249 
250 	ea->ea_node = node;
251 	ea->ea_bustag = sc->sc_childbustag;
252 	ea->ea_dmatag = sc->sc_dmatag;
253 
254 	rv = getprop(node, "reg", sizeof(struct ebus_regs), &ea->ea_nregs,
255 	    (void **)&ea->ea_regs);
256 	if (rv)
257 		return (rv);
258 
259 	rv = getprop(node, "address", sizeof(u_int32_t), &ea->ea_nvaddrs,
260 	    (void **)&ea->ea_vaddrs);
261 	if (rv != ENOENT) {
262 		if (rv)
263 			return (rv);
264 
265 		if (ea->ea_nregs != ea->ea_nvaddrs)
266 			printf("ebus loses: device %s: %d regs and %d addrs\n",
267 			    ea->ea_name, ea->ea_nregs, ea->ea_nvaddrs);
268 	} else
269 		ea->ea_nvaddrs = 0;
270 
271 	if (getprop(node, "interrupts", sizeof(u_int32_t), &ea->ea_nintrs,
272 	    (void **)&ea->ea_intrs))
273 		ea->ea_nintrs = 0;
274 	else
275 		ebus_find_ino(sc, ea);
276 
277 	return (0);
278 }
279 
280 void
281 ebus_destroy_attach_args(ea)
282 	struct ebus_attach_args	*ea;
283 {
284 
285 	if (ea->ea_name)
286 		free((void *)ea->ea_name, M_DEVBUF);
287 	if (ea->ea_regs)
288 		free((void *)ea->ea_regs, M_DEVBUF);
289 	if (ea->ea_intrs)
290 		free((void *)ea->ea_intrs, M_DEVBUF);
291 	if (ea->ea_vaddrs)
292 		free((void *)ea->ea_vaddrs, M_DEVBUF);
293 }
294 
295 int
296 ebus_print(aux, p)
297 	void *aux;
298 	const char *p;
299 {
300 	struct ebus_attach_args *ea = aux;
301 	int i;
302 
303 	if (p)
304 		printf("%s at %s", ea->ea_name, p);
305 	for (i = 0; i < ea->ea_nregs; i++)
306 		printf("%s %x-%x", i == 0 ? " addr" : ",",
307 		    ea->ea_regs[i].lo,
308 		    ea->ea_regs[i].lo + ea->ea_regs[i].size - 1);
309 	for (i = 0; i < ea->ea_nintrs; i++)
310 		printf(" ipl %d", ea->ea_intrs[i]);
311 	return (UNCONF);
312 }
313 
314 
315 /*
316  * find the INO values for each interrupt and fill them in.
317  *
318  * for each "reg" property of this device, mask it's hi and lo
319  * values with the "interrupt-map-mask"'s hi/lo values, and also
320  * mask the interrupt number with the interrupt mask.  search the
321  * "interrupt-map" list for matching values of hi, lo and interrupt
322  * to give the INO for this interrupt.
323  */
324 void
325 ebus_find_ino(sc, ea)
326 	struct ebus_softc *sc;
327 	struct ebus_attach_args *ea;
328 {
329 	u_int32_t hi, lo, intr;
330 	int i, j, k;
331 
332 	if (sc->sc_nintmap == 0) {
333 		for (i = 0; i < ea->ea_nintrs; i++) {
334 			OF_mapintr(ea->ea_node, &ea->ea_intrs[i],
335 				sizeof(ea->ea_intrs[0]),
336 				sizeof(ea->ea_intrs[0]));
337 		}
338 		return;
339 	}
340 
341 	DPRINTF(EDB_INTRMAP,
342 	    ("ebus_find_ino: searching %d interrupts", ea->ea_nintrs));
343 
344 	for (j = 0; j < ea->ea_nintrs; j++) {
345 
346 		intr = ea->ea_intrs[j] & sc->sc_intmapmask.intr;
347 
348 		DPRINTF(EDB_INTRMAP,
349 		    ("; intr %x masked to %x", ea->ea_intrs[j], intr));
350 		for (i = 0; i < ea->ea_nregs; i++) {
351 			hi = ea->ea_regs[i].hi & sc->sc_intmapmask.hi;
352 			lo = ea->ea_regs[i].lo & sc->sc_intmapmask.lo;
353 
354 			DPRINTF(EDB_INTRMAP,
355 			    ("; reg hi.lo %08x.%08x masked to %08x.%08x",
356 			    ea->ea_regs[i].hi, ea->ea_regs[i].lo, hi, lo));
357 			for (k = 0; k < sc->sc_nintmap; k++) {
358 				DPRINTF(EDB_INTRMAP,
359 				    ("; checking hi.lo %08x.%08x intr %x",
360 				    sc->sc_intmap[k].hi, sc->sc_intmap[k].lo,
361 				    sc->sc_intmap[k].intr));
362 				if (hi == sc->sc_intmap[k].hi &&
363 				    lo == sc->sc_intmap[k].lo &&
364 				    intr == sc->sc_intmap[k].intr) {
365 					ea->ea_intrs[j] =
366 					    sc->sc_intmap[k].cintr;
367 					DPRINTF(EDB_INTRMAP,
368 					    ("; FOUND IT! changing to %d\n",
369 					    sc->sc_intmap[k].cintr));
370 					goto next_intr;
371 				}
372 			}
373 		}
374 next_intr:;
375 	}
376 }
377 
378 
379 /*
380  * bus space and bus dma below here
381  */
382 bus_space_tag_t
383 ebus_alloc_bus_tag(sc, type)
384 	struct ebus_softc *sc;
385 	int type;
386 {
387 	bus_space_tag_t bt;
388 
389 	bt = (bus_space_tag_t)
390 		malloc(sizeof(struct sparc_bus_space_tag), M_DEVBUF, M_NOWAIT);
391 	if (bt == NULL)
392 		panic("could not allocate ebus bus tag");
393 
394 	bzero(bt, sizeof *bt);
395 	bt->cookie = sc;
396 	bt->parent = sc->sc_memtag;
397 	bt->type = type;
398 	bt->sparc_bus_map = _ebus_bus_map;
399 	bt->sparc_bus_mmap = ebus_bus_mmap;
400 	bt->sparc_intr_establish = ebus_intr_establish;
401 	return (bt);
402 }
403 
404 /* XXX? */
405 bus_dma_tag_t
406 ebus_alloc_dma_tag(sc, pdt)
407 	struct ebus_softc *sc;
408 	bus_dma_tag_t pdt;
409 {
410 	bus_dma_tag_t dt;
411 
412 	dt = (bus_dma_tag_t)
413 		malloc(sizeof(struct sparc_bus_dma_tag), M_DEVBUF, M_NOWAIT);
414 	if (dt == NULL)
415 		panic("could not allocate ebus dma tag");
416 
417 	bzero(dt, sizeof *dt);
418 	dt->_cookie = sc;
419 	dt->_parent = pdt;
420 #define PCOPY(x)	dt->x = pdt->x
421 	PCOPY(_dmamap_create);
422 	PCOPY(_dmamap_destroy);
423 	dt->_dmamap_load = ebus_dmamap_load;
424 	PCOPY(_dmamap_load_mbuf);
425 	PCOPY(_dmamap_load_uio);
426 	PCOPY(_dmamap_load_raw);
427 	dt->_dmamap_unload = ebus_dmamap_unload;
428 	dt->_dmamap_sync = ebus_dmamap_sync;
429 	dt->_dmamem_alloc = ebus_dmamem_alloc;
430 	dt->_dmamem_free = ebus_dmamem_free;
431 	dt->_dmamem_map = ebus_dmamem_map;
432 	dt->_dmamem_unmap = ebus_dmamem_unmap;
433 	PCOPY(_dmamem_mmap);
434 #undef	PCOPY
435 	return (dt);
436 }
437 
438 /*
439  * bus space support.  <sparc64/dev/psychoreg.h> has a discussion
440  * about PCI physical addresses, which also applies to ebus.
441  */
442 static int
443 _ebus_bus_map(t, btype, offset, size, flags, vaddr, hp)
444 	bus_space_tag_t t;
445 	bus_type_t btype;
446 	bus_addr_t offset;
447 	bus_size_t size;
448 	int	flags;
449 	vaddr_t vaddr;
450 	bus_space_handle_t *hp;
451 {
452 	struct ebus_softc *sc = t->cookie;
453 	bus_addr_t hi, lo;
454 	int i, ss;
455 
456 	DPRINTF(EDB_BUSMAP,
457 	    ("\n_ebus_bus_map: type %d off %016llx sz %x flags %d va %p",
458 	    (int)t->type, (unsigned long long)offset, (int)size, (int)flags,
459 	    (void *)vaddr));
460 
461 	hi = offset >> 32UL;
462 	lo = offset & 0xffffffff;
463 	DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo));
464 	for (i = 0; i < sc->sc_nrange; i++) {
465 		bus_addr_t pciaddr;
466 
467 		if (hi != sc->sc_range[i].child_hi)
468 			continue;
469 		if (lo < sc->sc_range[i].child_lo ||
470 		    (lo + size) >
471 		      (sc->sc_range[i].child_lo + sc->sc_range[i].size))
472 			continue;
473 
474 		/* Isolate address space and find the right tag */
475 		ss = (sc->sc_range[i].phys_hi>>24)&3;
476 		switch (ss) {
477 		case 1:	/* I/O space */
478 			t = sc->sc_iotag;
479 			break;
480 		case 2:	/* Memory space */
481 			t = sc->sc_memtag;
482 			break;
483 		case 0:	/* Config space */
484 		case 3:	/* 64-bit Memory space */
485 		default: /* WTF? */
486 			/* We don't handle these */
487 			panic("_ebus_bus_map: illegal space %x", ss);
488 			break;
489 		}
490 		pciaddr = ((bus_addr_t)sc->sc_range[i].phys_mid << 32UL) |
491 				       sc->sc_range[i].phys_lo;
492 		pciaddr += lo;
493 		DPRINTF(EDB_BUSMAP,
494 		    ("\n_ebus_bus_map: mapping space %x paddr offset %qx pciaddr %qx\n",
495 		    ss, (unsigned long long)offset, (unsigned long long)pciaddr));
496 		/* pass it onto the psycho */
497 		return (bus_space_map2(t, sc->sc_range[i].phys_hi,
498 			pciaddr, size, flags, vaddr, hp));
499 	}
500 	DPRINTF(EDB_BUSMAP, (": FAILED\n"));
501 	return (EINVAL);
502 }
503 
504 static int
505 ebus_bus_mmap(t, btype, paddr, flags, hp)
506 	bus_space_tag_t t;
507 	bus_type_t btype;
508 	bus_addr_t paddr;
509 	int flags;
510 	bus_space_handle_t *hp;
511 {
512 	bus_addr_t offset = paddr;
513 	struct ebus_softc *sc = t->cookie;
514 	int i;
515 
516 	for (i = 0; i < sc->sc_nrange; i++) {
517 		bus_addr_t paddr = ((bus_addr_t)sc->sc_range[i].child_hi << 32) |
518 		    sc->sc_range[i].child_lo;
519 
520 		if (offset != paddr)
521 			continue;
522 
523 		DPRINTF(EDB_BUSMAP, ("\n_ebus_bus_mmap: mapping paddr %qx\n",
524 		    (unsigned long long)paddr));
525 		return (bus_space_mmap(sc->sc_memtag, 0, paddr,
526 				       flags, hp));
527 	}
528 
529 	return (-1);
530 }
531 
532 /*
533  * install an interrupt handler for a PCI device
534  */
535 void *
536 ebus_intr_establish(t, pri, level, flags, handler, arg)
537 	bus_space_tag_t t;
538 	int pri;
539 	int level;
540 	int flags;
541 	int (*handler) __P((void *));
542 	void *arg;
543 {
544 	return (bus_intr_establish(t->parent, pri, level, flags, handler, arg));
545 }
546 
547 /*
548  * bus dma support
549  */
550 int
551 ebus_dmamap_load(t, map, buf, buflen, p, flags)
552 	bus_dma_tag_t t;
553 	bus_dmamap_t map;
554 	void *buf;
555 	bus_size_t buflen;
556 	struct proc *p;
557 	int flags;
558 {
559 	struct ebus_softc *sc = t->_cookie;
560 
561 	return (iommu_dvmamap_load(t, sc->sc_parent->sc_is, map, buf, buflen,
562 	    p, flags));
563 }
564 
565 void
566 ebus_dmamap_unload(t, map)
567 	bus_dma_tag_t t;
568 	bus_dmamap_t map;
569 {
570 	struct ebus_softc *sc = t->_cookie;
571 
572 	iommu_dvmamap_unload(t, sc->sc_parent->sc_is, map);
573 }
574 
575 void
576 ebus_dmamap_sync(t, map, offset, len, ops)
577 	bus_dma_tag_t t;
578 	bus_dmamap_t map;
579 	bus_addr_t offset;
580 	bus_size_t len;
581 	int ops;
582 {
583 	struct ebus_softc *sc = t->_cookie;
584 
585 	iommu_dvmamap_sync(t, sc->sc_parent->sc_is, map, offset, len, ops);
586 	bus_dmamap_sync(t->_parent, map, offset, len, ops);
587 }
588 
589 int
590 ebus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
591 	bus_dma_tag_t t;
592 	bus_size_t size;
593 	bus_size_t alignment;
594 	bus_size_t boundary;
595 	bus_dma_segment_t *segs;
596 	int nsegs;
597 	int *rsegs;
598 	int flags;
599 {
600 	struct ebus_softc *sc = t->_cookie;
601 
602 	return (iommu_dvmamem_alloc(t, sc->sc_parent->sc_is, size, alignment,
603 	    boundary, segs, nsegs, rsegs, flags));
604 }
605 
606 void
607 ebus_dmamem_free(t, segs, nsegs)
608 	bus_dma_tag_t t;
609 	bus_dma_segment_t *segs;
610 	int nsegs;
611 {
612 	struct ebus_softc *sc = t->_cookie;
613 
614 	iommu_dvmamem_free(t, sc->sc_parent->sc_is, segs, nsegs);
615 }
616 
617 int
618 ebus_dmamem_map(t, segs, nsegs, size, kvap, flags)
619 	bus_dma_tag_t t;
620 	bus_dma_segment_t *segs;
621 	int nsegs;
622 	size_t size;
623 	caddr_t *kvap;
624 	int flags;
625 {
626 	struct ebus_softc *sc = t->_cookie;
627 
628 	return (iommu_dvmamem_map(t, sc->sc_parent->sc_is, segs, nsegs,
629 	    size, kvap, flags));
630 }
631 
632 void
633 ebus_dmamem_unmap(t, kva, size)
634 	bus_dma_tag_t t;
635 	caddr_t kva;
636 	size_t size;
637 {
638 	struct ebus_softc *sc = t->_cookie;
639 
640 	iommu_dvmamem_unmap(t, sc->sc_parent->sc_is, kva, size);
641 }
642