From 2c7dd6813ff4d1352d85f24d688ad27165e118a3 Mon Sep 17 00:00:00 2001 From: fvdl Date: Thu, 27 Feb 2003 00:27:54 +0000 Subject: [PATCH] Moved to x86/isa. --- sys/arch/i386/isa/isa_machdep.c | 956 -------------------------------- 1 file changed, 956 deletions(-) delete mode 100644 sys/arch/i386/isa/isa_machdep.c diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c deleted file mode 100644 index d30191b11faf..000000000000 --- a/sys/arch/i386/isa/isa_machdep.c +++ /dev/null @@ -1,956 +0,0 @@ -/* $NetBSD: isa_machdep.c,v 1.59 2003/02/26 22:23:02 fvdl Exp $ */ - -/*- - * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace - * Simulation Facility, NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * William Jolitz. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)isa.c 7.2 (Berkeley) 5/13/91 - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: isa_machdep.c,v 1.59 2003/02/26 22:23:02 fvdl Exp $"); - -#define ISA_DMA_STATS - -#include -#include -#include -#include -#include -#include -#include -#include - -#define _X86_BUS_DMA_PRIVATE -#include - -#include -#include - -#include -#include - -#include - -#include "ioapic.h" - -#if NIOAPIC > 0 -#include -#include -#endif - -#include "mca.h" -#if NMCA > 0 -#include /* for MCA_system */ -#endif - -#include "eisa.h" /* XXX */ - -/* - * ISA can only DMA to 0-16M. - */ -#define ISA_DMA_BOUNCE_THRESHOLD (16 * 1024 * 1024) - -extern paddr_t avail_end; - -#define IDTVEC(name) __CONCAT(X,name) -typedef void (vector) __P((void)); -extern vector *IDTVEC(intr)[]; - -/* - * Cookie used by ISA dma. A pointer to one of these it stashed in - * the DMA map. - */ -struct x86_isa_dma_cookie { - int id_flags; /* flags; see below */ - - /* - * Information about the original buffer used during - * DMA map syncs. Note that origibuflen is only used - * for ID_BUFTYPE_LINEAR. - */ - void *id_origbuf; /* pointer to orig buffer if - bouncing */ - bus_size_t id_origbuflen; /* ...and size */ - int id_buftype; /* type of buffer */ - - void *id_bouncebuf; /* pointer to the bounce buffer */ - bus_size_t id_bouncebuflen; /* ...and size */ - int id_nbouncesegs; /* number of valid bounce segs */ - bus_dma_segment_t id_bouncesegs[0]; /* array of bounce buffer - physical memory segments */ -}; - -/* id_flags */ -#define ID_MIGHT_NEED_BOUNCE 0x01 /* map could need bounce buffers */ -#define ID_HAS_BOUNCE 0x02 /* map currently has bounce buffers */ -#define ID_IS_BOUNCING 0x04 /* map is bouncing current xfer */ - -/* id_buftype */ -#define ID_BUFTYPE_INVALID 0 -#define ID_BUFTYPE_LINEAR 1 -#define ID_BUFTYPE_MBUF 2 -#define ID_BUFTYPE_UIO 3 -#define ID_BUFTYPE_RAW 4 - -int _isa_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, - bus_size_t, bus_size_t, int, bus_dmamap_t *)); -void _isa_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t)); -int _isa_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, - bus_size_t, struct proc *, int)); -int _isa_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t, - struct mbuf *, int)); -int _isa_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t, - struct uio *, int)); -int _isa_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, - bus_dma_segment_t *, int, bus_size_t, int)); -void _isa_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); -void _isa_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, - bus_addr_t, bus_size_t, int)); - -int _isa_bus_dmamem_alloc __P((bus_dma_tag_t, bus_size_t, bus_size_t, - bus_size_t, bus_dma_segment_t *, int, int *, int)); - -int _isa_dma_alloc_bouncebuf __P((bus_dma_tag_t, bus_dmamap_t, - bus_size_t, int)); -void _isa_dma_free_bouncebuf __P((bus_dma_tag_t, bus_dmamap_t)); - -/* - * Entry points for ISA DMA. These are mostly wrappers around - * the generic functions that understand how to deal with bounce - * buffers, if necessary. - */ -struct x86_bus_dma_tag isa_bus_dma_tag = { - ISA_DMA_BOUNCE_THRESHOLD, - _isa_bus_dmamap_create, - _isa_bus_dmamap_destroy, - _isa_bus_dmamap_load, - _isa_bus_dmamap_load_mbuf, - _isa_bus_dmamap_load_uio, - _isa_bus_dmamap_load_raw, - _isa_bus_dmamap_unload, - _isa_bus_dmamap_sync, - _isa_bus_dmamem_alloc, - _bus_dmamem_free, - _bus_dmamem_map, - _bus_dmamem_unmap, - _bus_dmamem_mmap, -}; - -#define LEGAL_IRQ(x) ((x) >= 0 && (x) < NUM_LEGACY_IRQS && (x) != 2) - -int -isa_intr_alloc(isa_chipset_tag_t ic, int mask, int type, int *irq) -{ - int i, tmp, bestirq, count; - struct intrhand **p, *q; - struct intrsource *isp; - struct cpu_info *ci; - - if (type == IST_NONE) - panic("intr_alloc: bogus type"); - - ci = &cpu_info_primary; - - bestirq = -1; - count = -1; - - /* some interrupts should never be dynamically allocated */ - mask &= 0xdef8; - - /* - * XXX some interrupts will be used later (6 for fdc, 12 for pms). - * the right answer is to do "breadth-first" searching of devices. - */ - mask &= 0xefbf; - - simple_lock(&ci->ci_slock); - - for (i = 0; i < NUM_LEGACY_IRQS; i++) { - if (LEGAL_IRQ(i) == 0 || (mask & (1<ci_isources[i]; - if (isp == NULL) { - /* - * if nothing's using the irq, just return it - */ - *irq = i; - simple_unlock(&ci->ci_slock); - return (0); - } - - switch(isp->is_type) { - case IST_EDGE: - case IST_LEVEL: - if (type != isp->is_type) - continue; - /* - * if the irq is shareable, count the number of other - * handlers, and if it's smaller than the last irq like - * this, remember it - * - * XXX We should probably also consider the - * interrupt level and stick IPL_TTY with other - * IPL_TTY, etc. - */ - for (p = &isp->is_handlers, tmp = 0; (q = *p) != NULL; - p = &q->ih_next, tmp++) - ; - if ((bestirq == -1) || (count > tmp)) { - bestirq = i; - count = tmp; - } - break; - - case IST_PULSE: - /* this just isn't shareable */ - continue; - } - } - - simple_unlock(&ci->ci_slock); - - if (bestirq == -1) - return (1); - - *irq = bestirq; - - return (0); -} - -const struct evcnt * -isa_intr_evcnt(isa_chipset_tag_t ic, int irq) -{ - - /* XXX for now, no evcnt parent reported */ - return NULL; -} - -void * -isa_intr_establish(ic, irq, type, level, ih_fun, ih_arg) - isa_chipset_tag_t ic; - int irq; - int type; - int level; - int (*ih_fun) __P((void *)); - void *ih_arg; -{ - struct pic *pic; - int pin; -#if NIOAPIC > 0 - int mpih; -#endif - - pin = irq; - pic = &i8259_pic; - -#if NIOAPIC > 0 - if (mp_busses != NULL) { - if (intr_find_mpmapping(mp_isa_bus, irq, &mpih) == 0 || - intr_find_mpmapping(mp_eisa_bus, irq, &mpih) == 0) { - if (!APIC_IRQ_ISLEGACY(mpih)) { - pin = APIC_IRQ_PIN(mpih); - pic = (struct pic *) - ioapic_find(APIC_IRQ_APIC(mpih)); - if (pic == NULL) { - printf("isa_intr_establish: " - "unknown apic %d\n", - APIC_IRQ_APIC(mpih)); - return NULL; - } - } - } else - printf("isa_intr_establish: no MP mapping found\n"); - } -#endif - return intr_establish(irq, pic, pin, type, level, ih_fun, ih_arg); -} - -/* - * Deregister an interrupt handler. - */ -void -isa_intr_disestablish(ic, arg) - isa_chipset_tag_t ic; - void *arg; -{ - struct intrhand *ih = arg; - - if (!LEGAL_IRQ(ih->ih_pin)) - panic("intr_disestablish: bogus irq"); - - intr_disestablish(ih); -} - -void -isa_attach_hook(parent, self, iba) - struct device *parent, *self; - struct isabus_attach_args *iba; -{ - extern struct x86_isa_chipset i386_isa_chipset; - extern int isa_has_been_seen; - - /* - * Notify others that might need to know that the ISA bus - * has now been attached. - */ - if (isa_has_been_seen) - panic("isaattach: ISA bus already seen!"); - isa_has_been_seen = 1; - - /* - * Since we can only have one ISA bus, we just use a single - * statically allocated ISA chipset structure. Pass it up - * now. - */ - iba->iba_ic = &i386_isa_chipset; -} - -int -isa_mem_alloc(t, size, align, boundary, flags, addrp, bshp) - bus_space_tag_t t; - bus_size_t size, align; - bus_addr_t boundary; - int flags; - bus_addr_t *addrp; - bus_space_handle_t *bshp; -{ - - /* - * Allocate physical address space in the ISA hole. - */ - return (bus_space_alloc(t, IOM_BEGIN, IOM_END - 1, size, align, - boundary, flags, addrp, bshp)); -} - -void -isa_mem_free(t, bsh, size) - bus_space_tag_t t; - bus_space_handle_t bsh; - bus_size_t size; -{ - - bus_space_free(t, bsh, size); -} - -/********************************************************************** - * bus.h dma interface entry points - **********************************************************************/ - -#ifdef ISA_DMA_STATS -#define STAT_INCR(v) (v)++ -#define STAT_DECR(v) do { \ - if ((v) == 0) \ - printf("%s:%d -- Already 0!\n", __FILE__, __LINE__); \ - else \ - (v)--; \ - } while (0) -u_long isa_dma_stats_loads; -u_long isa_dma_stats_bounces; -u_long isa_dma_stats_nbouncebufs; -#else -#define STAT_INCR(v) -#define STAT_DECR(v) -#endif - -/* - * Create an ISA DMA map. - */ -int -_isa_bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, flags, dmamp) - bus_dma_tag_t t; - bus_size_t size; - int nsegments; - bus_size_t maxsegsz; - bus_size_t boundary; - int flags; - bus_dmamap_t *dmamp; -{ - struct x86_isa_dma_cookie *cookie; - bus_dmamap_t map; - int error, cookieflags; - void *cookiestore; - size_t cookiesize; - - /* Call common function to create the basic map. */ - error = _bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, - flags, dmamp); - if (error) - return (error); - - map = *dmamp; - map->_dm_cookie = NULL; - - cookiesize = sizeof(struct x86_isa_dma_cookie); - - /* - * ISA only has 24-bits of address space. This means - * we can't DMA to pages over 16M. In order to DMA to - * arbitrary buffers, we use "bounce buffers" - pages - * in memory below the 16M boundary. On DMA reads, - * DMA happens to the bounce buffers, and is copied into - * the caller's buffer. On writes, data is copied into - * but bounce buffer, and the DMA happens from those - * pages. To software using the DMA mapping interface, - * this looks simply like a data cache. - * - * If we have more than 16M of RAM in the system, we may - * need bounce buffers. We check and remember that here. - * - * There are exceptions, however. VLB devices can do - * 32-bit DMA, and indicate that here. - * - * ...or, there is an opposite case. The most segments - * a transfer will require is (maxxfer / PAGE_SIZE) + 1. If - * the caller can't handle that many segments (e.g. the - * ISA DMA controller), we may have to bounce it as well. - */ - if (avail_end <= t->_bounce_thresh || - (flags & ISABUS_DMA_32BIT) != 0) { - /* Bouncing not necessary due to memory size. */ - map->_dm_bounce_thresh = 0; - } - cookieflags = 0; - if (map->_dm_bounce_thresh != 0 || - ((map->_dm_size / PAGE_SIZE) + 1) > map->_dm_segcnt) { - cookieflags |= ID_MIGHT_NEED_BOUNCE; - cookiesize += (sizeof(bus_dma_segment_t) * map->_dm_segcnt); - } - - /* - * Allocate our cookie. - */ - if ((cookiestore = malloc(cookiesize, M_DMAMAP, - (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) { - error = ENOMEM; - goto out; - } - memset(cookiestore, 0, cookiesize); - cookie = (struct x86_isa_dma_cookie *)cookiestore; - cookie->id_flags = cookieflags; - map->_dm_cookie = cookie; - - if (cookieflags & ID_MIGHT_NEED_BOUNCE) { - /* - * Allocate the bounce pages now if the caller - * wishes us to do so. - */ - if ((flags & BUS_DMA_ALLOCNOW) == 0) - goto out; - - error = _isa_dma_alloc_bouncebuf(t, map, size, flags); - } - - out: - if (error) { - if (map->_dm_cookie != NULL) - free(map->_dm_cookie, M_DMAMAP); - _bus_dmamap_destroy(t, map); - } - return (error); -} - -/* - * Destroy an ISA DMA map. - */ -void -_isa_bus_dmamap_destroy(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - - /* - * Free any bounce pages this map might hold. - */ - if (cookie->id_flags & ID_HAS_BOUNCE) - _isa_dma_free_bouncebuf(t, map); - - free(cookie, M_DMAMAP); - _bus_dmamap_destroy(t, map); -} - -/* - * Load an ISA DMA map with a linear buffer. - */ -int -_isa_bus_dmamap_load(t, map, buf, buflen, p, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - void *buf; - bus_size_t buflen; - struct proc *p; - int flags; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - int error; - - STAT_INCR(isa_dma_stats_loads); - - /* - * Make sure that on error condition we return "no valid mappings." - */ - map->dm_mapsize = 0; - map->dm_nsegs = 0; - - /* - * Try to load the map the normal way. If this errors out, - * and we can bounce, we will. - */ - error = _bus_dmamap_load(t, map, buf, buflen, p, flags); - if (error == 0 || - (error != 0 && (cookie->id_flags & ID_MIGHT_NEED_BOUNCE) == 0)) - return (error); - - /* - * First attempt failed; bounce it. - */ - - STAT_INCR(isa_dma_stats_bounces); - - /* - * Allocate bounce pages, if necessary. - */ - if ((cookie->id_flags & ID_HAS_BOUNCE) == 0) { - error = _isa_dma_alloc_bouncebuf(t, map, buflen, flags); - if (error) - return (error); - } - - /* - * Cache a pointer to the caller's buffer and load the DMA map - * with the bounce buffer. - */ - cookie->id_origbuf = buf; - cookie->id_origbuflen = buflen; - cookie->id_buftype = ID_BUFTYPE_LINEAR; - error = _bus_dmamap_load(t, map, cookie->id_bouncebuf, buflen, - p, flags); - if (error) { - /* - * Free the bounce pages, unless our resources - * are reserved for our exclusive use. - */ - if ((map->_dm_flags & BUS_DMA_ALLOCNOW) == 0) - _isa_dma_free_bouncebuf(t, map); - return (error); - } - - /* ...so _isa_bus_dmamap_sync() knows we're bouncing */ - cookie->id_flags |= ID_IS_BOUNCING; - return (0); -} - -/* - * Like _isa_bus_dmamap_load(), but for mbufs. - */ -int -_isa_bus_dmamap_load_mbuf(t, map, m0, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - struct mbuf *m0; - int flags; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - int error; - - /* - * Make sure on error condition we return "no valid mappings." - */ - map->dm_mapsize = 0; - map->dm_nsegs = 0; - -#ifdef DIAGNOSTIC - if ((m0->m_flags & M_PKTHDR) == 0) - panic("_isa_bus_dmamap_load_mbuf: no packet header"); -#endif - - if (m0->m_pkthdr.len > map->_dm_size) - return (EINVAL); - - /* - * Try to load the map the normal way. If this errors out, - * and we can bounce, we will. - */ - error = _bus_dmamap_load_mbuf(t, map, m0, flags); - if (error == 0 || - (error != 0 && (cookie->id_flags & ID_MIGHT_NEED_BOUNCE) == 0)) - return (error); - - /* - * First attempt failed; bounce it. - */ - - STAT_INCR(isa_dma_stats_bounces); - - /* - * Allocate bounce pages, if necessary. - */ - if ((cookie->id_flags & ID_HAS_BOUNCE) == 0) { - error = _isa_dma_alloc_bouncebuf(t, map, m0->m_pkthdr.len, - flags); - if (error) - return (error); - } - - /* - * Cache a pointer to the caller's buffer and load the DMA map - * with the bounce buffer. - */ - cookie->id_origbuf = m0; - cookie->id_origbuflen = m0->m_pkthdr.len; /* not really used */ - cookie->id_buftype = ID_BUFTYPE_MBUF; - error = _bus_dmamap_load(t, map, cookie->id_bouncebuf, - m0->m_pkthdr.len, NULL, flags); - if (error) { - /* - * Free the bounce pages, unless our resources - * are reserved for our exclusive use. - */ - if ((map->_dm_flags & BUS_DMA_ALLOCNOW) == 0) - _isa_dma_free_bouncebuf(t, map); - return (error); - } - - /* ...so _isa_bus_dmamap_sync() knows we're bouncing */ - cookie->id_flags |= ID_IS_BOUNCING; - return (0); -} - -/* - * Like _isa_bus_dmamap_load(), but for uios. - */ -int -_isa_bus_dmamap_load_uio(t, map, uio, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - struct uio *uio; - int flags; -{ - - panic("_isa_bus_dmamap_load_uio: not implemented"); -} - -/* - * Like _isa_bus_dmamap_load(), but for raw memory allocated with - * bus_dmamem_alloc(). - */ -int -_isa_bus_dmamap_load_raw(t, map, segs, nsegs, size, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_dma_segment_t *segs; - int nsegs; - bus_size_t size; - int flags; -{ - - panic("_isa_bus_dmamap_load_raw: not implemented"); -} - -/* - * Unload an ISA DMA map. - */ -void -_isa_bus_dmamap_unload(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - - /* - * If we have bounce pages, free them, unless they're - * reserved for our exclusive use. - */ - if ((cookie->id_flags & ID_HAS_BOUNCE) && - (map->_dm_flags & BUS_DMA_ALLOCNOW) == 0) - _isa_dma_free_bouncebuf(t, map); - - cookie->id_flags &= ~ID_IS_BOUNCING; - cookie->id_buftype = ID_BUFTYPE_INVALID; - - /* - * Do the generic bits of the unload. - */ - _bus_dmamap_unload(t, map); -} - -/* - * Synchronize an ISA DMA map. - */ -void -_isa_bus_dmamap_sync(t, map, offset, len, ops) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_addr_t offset; - bus_size_t len; - int ops; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - - /* - * Mixing PRE and POST operations is not allowed. - */ - if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 && - (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0) - panic("_isa_bus_dmamap_sync: mix PRE and POST"); - -#ifdef DIAGNOSTIC - if ((ops & (BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTREAD)) != 0) { - if (offset >= map->dm_mapsize) - panic("_isa_bus_dmamap_sync: bad offset"); - if (len == 0 || (offset + len) > map->dm_mapsize) - panic("_isa_bus_dmamap_sync: bad length"); - } -#endif - - /* - * If we're not bouncing, just return; nothing to do. - */ - if ((cookie->id_flags & ID_IS_BOUNCING) == 0) - return; - - switch (cookie->id_buftype) { - case ID_BUFTYPE_LINEAR: - /* - * Nothing to do for pre-read. - */ - - if (ops & BUS_DMASYNC_PREWRITE) { - /* - * Copy the caller's buffer to the bounce buffer. - */ - memcpy((char *)cookie->id_bouncebuf + offset, - (char *)cookie->id_origbuf + offset, len); - } - - if (ops & BUS_DMASYNC_POSTREAD) { - /* - * Copy the bounce buffer to the caller's buffer. - */ - memcpy((char *)cookie->id_origbuf + offset, - (char *)cookie->id_bouncebuf + offset, len); - } - - /* - * Nothing to do for post-write. - */ - break; - - case ID_BUFTYPE_MBUF: - { - struct mbuf *m, *m0 = cookie->id_origbuf; - bus_size_t minlen, moff; - - /* - * Nothing to do for pre-read. - */ - - if (ops & BUS_DMASYNC_PREWRITE) { - /* - * Copy the caller's buffer to the bounce buffer. - */ - m_copydata(m0, offset, len, - (char *)cookie->id_bouncebuf + offset); - } - - if (ops & BUS_DMASYNC_POSTREAD) { - /* - * Copy the bounce buffer to the caller's buffer. - */ - for (moff = offset, m = m0; m != NULL && len != 0; - m = m->m_next) { - /* Find the beginning mbuf. */ - if (moff >= m->m_len) { - moff -= m->m_len; - continue; - } - - /* - * Now at the first mbuf to sync; nail - * each one until we have exhausted the - * length. - */ - minlen = len < m->m_len - moff ? - len : m->m_len - moff; - - memcpy(mtod(m, caddr_t) + moff, - (char *)cookie->id_bouncebuf + offset, - minlen); - - moff = 0; - len -= minlen; - offset += minlen; - } - } - - /* - * Nothing to do for post-write. - */ - break; - } - - case ID_BUFTYPE_UIO: - panic("_isa_bus_dmamap_sync: ID_BUFTYPE_UIO"); - break; - - case ID_BUFTYPE_RAW: - panic("_isa_bus_dmamap_sync: ID_BUFTYPE_RAW"); - break; - - case ID_BUFTYPE_INVALID: - panic("_isa_bus_dmamap_sync: ID_BUFTYPE_INVALID"); - break; - - default: - printf("unknown buffer type %d\n", cookie->id_buftype); - panic("_isa_bus_dmamap_sync"); - } -} - -/* - * Allocate memory safe for ISA DMA. - */ -int -_isa_bus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) - bus_dma_tag_t t; - bus_size_t size, alignment, boundary; - bus_dma_segment_t *segs; - int nsegs; - int *rsegs; - int flags; -{ - paddr_t high; - - if (avail_end > ISA_DMA_BOUNCE_THRESHOLD) - high = trunc_page(ISA_DMA_BOUNCE_THRESHOLD); - else - high = trunc_page(avail_end); - - return (_bus_dmamem_alloc_range(t, size, alignment, boundary, - segs, nsegs, rsegs, flags, 0, high)); -} - -/********************************************************************** - * ISA DMA utility functions - **********************************************************************/ - -int -_isa_dma_alloc_bouncebuf(t, map, size, flags) - bus_dma_tag_t t; - bus_dmamap_t map; - bus_size_t size; - int flags; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - int error = 0; - - cookie->id_bouncebuflen = round_page(size); - error = _isa_bus_dmamem_alloc(t, cookie->id_bouncebuflen, - PAGE_SIZE, map->_dm_boundary, cookie->id_bouncesegs, - map->_dm_segcnt, &cookie->id_nbouncesegs, flags); - if (error) - goto out; - error = _bus_dmamem_map(t, cookie->id_bouncesegs, - cookie->id_nbouncesegs, cookie->id_bouncebuflen, - (caddr_t *)&cookie->id_bouncebuf, flags); - - out: - if (error) { - _bus_dmamem_free(t, cookie->id_bouncesegs, - cookie->id_nbouncesegs); - cookie->id_bouncebuflen = 0; - cookie->id_nbouncesegs = 0; - } else { - cookie->id_flags |= ID_HAS_BOUNCE; - STAT_INCR(isa_dma_stats_nbouncebufs); - } - - return (error); -} - -void -_isa_dma_free_bouncebuf(t, map) - bus_dma_tag_t t; - bus_dmamap_t map; -{ - struct x86_isa_dma_cookie *cookie = map->_dm_cookie; - - STAT_DECR(isa_dma_stats_nbouncebufs); - - _bus_dmamem_unmap(t, cookie->id_bouncebuf, - cookie->id_bouncebuflen); - _bus_dmamem_free(t, cookie->id_bouncesegs, - cookie->id_nbouncesegs); - cookie->id_bouncebuflen = 0; - cookie->id_nbouncesegs = 0; - cookie->id_flags &= ~ID_HAS_BOUNCE; -}