Annotation of sys/arch/vax/vsa/asc_vsbus.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: asc_vsbus.c,v 1.8 2007/08/01 16:32:30 miod Exp $ */
! 2: /* $NetBSD: asc_vsbus.c,v 1.22 2001/02/04 20:36:32 ragge Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1998 The NetBSD Foundation, Inc.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to The NetBSD Foundation
! 9: * by Charles M. Hannum.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by the NetBSD
! 22: * Foundation, Inc. and its contributors.
! 23: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 24: * contributors may be used to endorse or promote products derived
! 25: * from this software without specific prior written permission.
! 26: *
! 27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 37: * POSSIBILITY OF SUCH DAMAGE.
! 38: */
! 39:
! 40: #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
! 41:
! 42: #include <sys/types.h>
! 43: #include <sys/param.h>
! 44: #include <sys/systm.h>
! 45: #include <sys/kernel.h>
! 46: #include <sys/errno.h>
! 47: #include <sys/ioctl.h>
! 48: #include <sys/device.h>
! 49: #include <sys/buf.h>
! 50: #include <sys/proc.h>
! 51: #include <sys/user.h>
! 52: #include <sys/reboot.h>
! 53: #include <sys/queue.h>
! 54:
! 55: #include <scsi/scsi_all.h>
! 56: #include <scsi/scsiconf.h>
! 57: #include <scsi/scsi_message.h>
! 58:
! 59: #include <machine/bus.h>
! 60: #include <machine/vmparam.h>
! 61:
! 62: #include <dev/ic/ncr53c9xreg.h>
! 63: #include <dev/ic/ncr53c9xvar.h>
! 64:
! 65: #include <machine/cpu.h>
! 66: #include <machine/sid.h>
! 67: #include <machine/scb.h>
! 68: #include <machine/vsbus.h>
! 69: #include <machine/clock.h> /* for SCSI ctlr ID# XXX */
! 70:
! 71: struct asc_vsbus_softc {
! 72: struct ncr53c9x_softc sc_ncr53c9x; /* Must be first */
! 73: struct evcount sc_intrcnt; /* count interrupts */
! 74: int sc_cvec; /* vector */
! 75: bus_space_tag_t sc_bst; /* bus space tag */
! 76: bus_space_handle_t sc_bsh; /* bus space handle */
! 77: bus_space_handle_t sc_dirh; /* scsi direction handle */
! 78: bus_space_handle_t sc_adrh; /* scsi address handle */
! 79: bus_space_handle_t sc_ncrh; /* ncr bus space handle */
! 80: bus_dma_tag_t sc_dmat; /* bus dma tag */
! 81: bus_dmamap_t sc_dmamap;
! 82: caddr_t *sc_dmaaddr;
! 83: size_t *sc_dmalen;
! 84: size_t sc_dmasize;
! 85: unsigned int sc_flags;
! 86: #define ASC_FROMMEMORY 0x0001 /* Must be 1 */
! 87: #define ASC_DMAACTIVE 0x0002
! 88: #define ASC_MAPLOADED 0x0004
! 89: unsigned long sc_xfers;
! 90: };
! 91:
! 92: #define ASC_REG_KA46_ADR 0x0000
! 93: #define ASC_REG_KA46_DIR 0x000C
! 94: #define ASC_REG_KA49_ADR 0x0000
! 95: #define ASC_REG_KA49_DIR 0x0004
! 96: #define ASC_REG_NCR 0x0080
! 97: #define ASC_REG_END 0x00B0
! 98:
! 99: #define ASC_MAXXFERSIZE 65536
! 100: #define ASC_FREQUENCY 25000000
! 101:
! 102: extern struct cfdriver sd_cd;
! 103:
! 104: int asc_vsbus_match(struct device *, void *, void *);
! 105: void asc_vsbus_attach(struct device *, struct device *, void *);
! 106:
! 107: struct cfattach asc_vsbus_ca = {
! 108: sizeof(struct asc_vsbus_softc), asc_vsbus_match, asc_vsbus_attach
! 109: };
! 110:
! 111: struct cfdriver asc_cd = {
! 112: NULL, "asc", DV_DULL
! 113: };
! 114:
! 115: struct scsi_adapter asc_vsbus_ops = {
! 116: ncr53c9x_scsi_cmd,
! 117: minphys,
! 118: NULL,
! 119: NULL
! 120: };
! 121:
! 122: static struct scsi_device asc_vsbus_dev = {
! 123: NULL, /* Use the default error handler */
! 124: NULL, /* have a queue, served by this */
! 125: NULL, /* have no async handler */
! 126: NULL, /* use the default done handler */
! 127: };
! 128:
! 129:
! 130: /*
! 131: * Functions and the switch for the MI code
! 132: */
! 133: u_char asc_vsbus_read_reg(struct ncr53c9x_softc *, int);
! 134: void asc_vsbus_write_reg(struct ncr53c9x_softc *, int, u_char);
! 135: int asc_vsbus_dma_isintr(struct ncr53c9x_softc *);
! 136: void asc_vsbus_dma_reset(struct ncr53c9x_softc *);
! 137: int asc_vsbus_dma_intr(struct ncr53c9x_softc *);
! 138: int asc_vsbus_dma_setup(struct ncr53c9x_softc *, caddr_t *,
! 139: size_t *, int, size_t *);
! 140: void asc_vsbus_dma_go(struct ncr53c9x_softc *);
! 141: void asc_vsbus_dma_stop(struct ncr53c9x_softc *);
! 142: int asc_vsbus_dma_isactive(struct ncr53c9x_softc *);
! 143: int asc_vsbus_controller_id(void);
! 144:
! 145: static struct ncr53c9x_glue asc_vsbus_glue = {
! 146: asc_vsbus_read_reg,
! 147: asc_vsbus_write_reg,
! 148: asc_vsbus_dma_isintr,
! 149: asc_vsbus_dma_reset,
! 150: asc_vsbus_dma_intr,
! 151: asc_vsbus_dma_setup,
! 152: asc_vsbus_dma_go,
! 153: asc_vsbus_dma_stop,
! 154: asc_vsbus_dma_isactive,
! 155: NULL,
! 156: };
! 157:
! 158: static u_int8_t asc_attached; /* can't have more than one asc */
! 159:
! 160: int
! 161: asc_vsbus_match(struct device *parent, void *conf, void *aux)
! 162: {
! 163: struct vsbus_attach_args *va = aux;
! 164: struct cfdata *cf = conf;
! 165: volatile u_int8_t *ncr_regs;
! 166: volatile int dummy;
! 167:
! 168: if (asc_attached)
! 169: return 0;
! 170:
! 171: if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) {
! 172: if (cf->cf_loc[0] != 0x200c0080)
! 173: return 0;
! 174: } else if (vax_boardtype == VAX_BTYP_49 ||
! 175: vax_boardtype == VAX_BTYP_1303) {
! 176: if (cf->cf_loc[0] != 0x26000080)
! 177: return 0;
! 178: } else {
! 179: return 0;
! 180: }
! 181:
! 182: ncr_regs = (volatile u_int8_t *) va->va_addr;
! 183:
! 184: /* *** need to generate an interrupt here
! 185: * From trial and error, I've determined that an INT is generated
! 186: * only when the following sequence of events occurs:
! 187: * 1) The interrupt status register (0x05) must be read.
! 188: * 2) SCSI bus reset interrupt must be enabled
! 189: * 3) SCSI bus reset command must be sent
! 190: * 4) NOP command must be sent
! 191: */
! 192:
! 193: dummy = ncr_regs[NCR_INTR << 2] & 0xFF;
! 194: ncr_regs[NCR_CFG1 << 2] = asc_vsbus_controller_id(); /* turn on INT
! 195: for SCSI reset */
! 196: ncr_regs[NCR_CMD << 2] = NCRCMD_RSTSCSI; /* send the reset */
! 197: ncr_regs[NCR_CMD << 2] = NCRCMD_NOP; /* send a NOP */
! 198: DELAY(10000);
! 199:
! 200: dummy = ncr_regs[NCR_INTR << 2] & 0xFF;
! 201: return (dummy & NCRINTR_SBR) != 0;
! 202: }
! 203:
! 204:
! 205: /*
! 206: * Attach this instance, and then all the sub-devices
! 207: */
! 208: void
! 209: asc_vsbus_attach(struct device *parent, struct device *self, void *aux)
! 210: {
! 211: struct vsbus_attach_args *va = aux;
! 212: struct asc_vsbus_softc *asc = (void *)self;
! 213: struct ncr53c9x_softc *sc = &asc->sc_ncr53c9x;
! 214: int error;
! 215:
! 216: asc_attached = 1;
! 217: /*
! 218: * Set up glue for MI code early; we use some of it here.
! 219: */
! 220: sc->sc_glue = &asc_vsbus_glue;
! 221:
! 222: asc->sc_bst = va->va_iot;
! 223: asc->sc_dmat = va->va_dmat;
! 224:
! 225: error = bus_space_map(asc->sc_bst, va->va_paddr - ASC_REG_NCR,
! 226: ASC_REG_END, 0, &asc->sc_bsh);
! 227: if (error) {
! 228: printf(": failed to map registers: error=%d\n", error);
! 229: return;
! 230: }
! 231: error = bus_space_subregion(asc->sc_bst, asc->sc_bsh, ASC_REG_NCR,
! 232: ASC_REG_END - ASC_REG_NCR, &asc->sc_ncrh);
! 233: if (error) {
! 234: printf(": failed to map ncr registers: error=%d\n", error);
! 235: return;
! 236: }
! 237: if (vax_boardtype == VAX_BTYP_46 || vax_boardtype == VAX_BTYP_48) {
! 238: error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
! 239: ASC_REG_KA46_ADR, sizeof(u_int32_t), &asc->sc_adrh);
! 240: if (error) {
! 241: printf(": failed to map adr register: error=%d\n",
! 242: error);
! 243: return;
! 244: }
! 245: error = bus_space_subregion(asc->sc_bst, asc->sc_bsh,
! 246: ASC_REG_KA46_DIR, sizeof(u_int32_t), &asc->sc_dirh);
! 247: if (error) {
! 248: printf(": failed to map dir register: error=%d\n",
! 249: error);
! 250: return;
! 251: }
! 252: } else {
! 253: /* This is a gross and disgusting kludge but it'll
! 254: * save a bunch of ugly code. Unlike the VS4000/60,
! 255: * the SCSI Address and direction registers are not
! 256: * near the SCSI NCR registers and are inside the
! 257: * block of general VAXstation registers. So we grab
! 258: * them from there and knowing the internals of the
! 259: * bus_space implementation, we cast to bus_space_handles.
! 260: */
! 261: struct vsbus_softc *vsc = (struct vsbus_softc *) parent;
! 262: asc->sc_adrh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_ADR);
! 263: asc->sc_dirh = (bus_space_handle_t) (vsc->sc_vsregs + ASC_REG_KA49_DIR);
! 264: #if 0
! 265: printf("\n%s: adrh=0x%08lx dirh=0x%08lx", self->dv_xname,
! 266: asc->sc_adrh, asc->sc_dirh);
! 267: ncr53c9x_debug = NCR_SHOWDMA|NCR_SHOWINTS|NCR_SHOWCMDS|NCR_SHOWPHASE|NCR_SHOWSTART|NCR_SHOWMSGS;
! 268: #endif
! 269: }
! 270: error = bus_dmamap_create(asc->sc_dmat, ASC_MAXXFERSIZE, 1,
! 271: ASC_MAXXFERSIZE, 0, BUS_DMA_NOWAIT, &asc->sc_dmamap);
! 272:
! 273: sc->sc_id = asc_vsbus_controller_id();
! 274: sc->sc_freq = ASC_FREQUENCY;
! 275:
! 276: /* gimme MHz */
! 277: sc->sc_freq /= 1000000;
! 278:
! 279: scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr53c9x_intr,
! 280: &asc->sc_ncr53c9x, SCB_ISTACK, &asc->sc_intrcnt);
! 281: asc->sc_cvec = va->va_cvec;
! 282: evcount_attach(&asc->sc_intrcnt, self->dv_xname,
! 283: (void *)&asc->sc_cvec, &evcount_intr);
! 284:
! 285: /*
! 286: * XXX More of this should be in ncr53c9x_attach(), but
! 287: * XXX should we really poke around the chip that much in
! 288: * XXX the MI code? Think about this more...
! 289: */
! 290:
! 291: /*
! 292: * Set up static configuration info.
! 293: */
! 294: sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
! 295: sc->sc_cfg2 = NCRCFG2_SCSI2;
! 296: sc->sc_cfg3 = 0;
! 297: sc->sc_rev = NCR_VARIANT_NCR53C94;
! 298:
! 299: /*
! 300: * XXX minsync and maxxfer _should_ be set up in MI code,
! 301: * XXX but it appears to have some dependency on what sort
! 302: * XXX of DMA we're hooked up to, etc.
! 303: */
! 304:
! 305: /*
! 306: * This is the value used to start sync negotiations
! 307: * Note that the NCR register "SYNCTP" is programmed
! 308: * in "clocks per byte", and has a minimum value of 4.
! 309: * The SCSI period used in negotiation is one-fourth
! 310: * of the time (in nanoseconds) needed to transfer one byte.
! 311: * Since the chip's clock is given in MHz, we have the following
! 312: * formula: 4 * period = (1000 / freq) * 4
! 313: */
! 314: sc->sc_minsync = (1000 / sc->sc_freq);
! 315: sc->sc_maxxfer = 64 * 1024;
! 316:
! 317: /* Do the common parts of attachment. */
! 318: ncr53c9x_attach(sc, &asc_vsbus_ops, &asc_vsbus_dev);
! 319: }
! 320:
! 321: /*
! 322: * Return the host controllers SCSI ID.
! 323: * The factory default is 6 (unlike most vendors who use 7), but this can
! 324: * be changed in the prom.
! 325: */
! 326: int
! 327: asc_vsbus_controller_id()
! 328: {
! 329: switch (vax_boardtype) {
! 330: #if defined(VAX46) || defined(VAX48) || defined(VAX49)
! 331: case VAX_BTYP_46:
! 332: case VAX_BTYP_48:
! 333: case VAX_BTYP_49:
! 334: return (clk_page[0xbc / 2] >> clk_tweak) & 7;
! 335: #endif
! 336: default:
! 337: return 6; /* XXX need to get this from VMB */
! 338: }
! 339: }
! 340:
! 341: /*
! 342: * Glue functions.
! 343: */
! 344:
! 345: u_char
! 346: asc_vsbus_read_reg(struct ncr53c9x_softc *sc, int reg)
! 347: {
! 348: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 349:
! 350: return bus_space_read_1(asc->sc_bst, asc->sc_ncrh,
! 351: reg * sizeof(u_int32_t));
! 352: }
! 353:
! 354: void
! 355: asc_vsbus_write_reg(struct ncr53c9x_softc *sc, int reg, u_char val)
! 356: {
! 357: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 358:
! 359: bus_space_write_1(asc->sc_bst, asc->sc_ncrh,
! 360: reg * sizeof(u_int32_t), val);
! 361: }
! 362:
! 363: int
! 364: asc_vsbus_dma_isintr(struct ncr53c9x_softc *sc)
! 365: {
! 366: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 367: return bus_space_read_1(asc->sc_bst, asc->sc_ncrh,
! 368: NCR_STAT * sizeof(u_int32_t)) & NCRSTAT_INT;
! 369: }
! 370:
! 371: void
! 372: asc_vsbus_dma_reset(struct ncr53c9x_softc *sc)
! 373: {
! 374: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 375:
! 376: if (asc->sc_flags & ASC_MAPLOADED)
! 377: bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
! 378: asc->sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
! 379: }
! 380:
! 381: int
! 382: asc_vsbus_dma_intr(struct ncr53c9x_softc *sc)
! 383: {
! 384: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 385: u_int tcl, tcm;
! 386: int trans, resid;
! 387:
! 388: if ((asc->sc_flags & ASC_DMAACTIVE) == 0)
! 389: panic("asc_vsbus_dma_intr: DMA wasn't active");
! 390:
! 391: asc->sc_flags &= ~ASC_DMAACTIVE;
! 392:
! 393: if (asc->sc_dmasize == 0) {
! 394: /* A "Transfer Pad" operation completed */
! 395: tcl = NCR_READ_REG(sc, NCR_TCL);
! 396: tcm = NCR_READ_REG(sc, NCR_TCM);
! 397: NCR_DMA(("asc_vsbus_intr: discarded %d bytes (tcl=%d, tcm=%d)\n",
! 398: tcl | (tcm << 8), tcl, tcm));
! 399: return 0;
! 400: }
! 401:
! 402: resid = 0;
! 403: if ((resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
! 404: NCR_DMA(("asc_vsbus_intr: empty FIFO of %d ", resid));
! 405: DELAY(1);
! 406: }
! 407: if (asc->sc_flags & ASC_MAPLOADED) {
! 408: bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
! 409: 0, asc->sc_dmasize,
! 410: asc->sc_flags & ASC_FROMMEMORY
! 411: ? BUS_DMASYNC_POSTWRITE
! 412: : BUS_DMASYNC_POSTREAD);
! 413: bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
! 414: }
! 415: asc->sc_flags &= ~ASC_MAPLOADED;
! 416:
! 417: resid += (tcl = NCR_READ_REG(sc, NCR_TCL));
! 418: resid += (tcm = NCR_READ_REG(sc, NCR_TCM)) << 8;
! 419:
! 420: trans = asc->sc_dmasize - resid;
! 421: if (trans < 0) { /* transferred < 0 ? */
! 422: printf("%s: xfer (%d) > req (%lu)\n",
! 423: __func__, trans, (u_long) asc->sc_dmasize);
! 424: trans = asc->sc_dmasize;
! 425: }
! 426: NCR_DMA(("asc_vsbus_intr: tcl=%d, tcm=%d; trans=%d, resid=%d\n",
! 427: tcl, tcm, trans, resid));
! 428:
! 429: *asc->sc_dmalen -= trans;
! 430: *asc->sc_dmaaddr += trans;
! 431:
! 432: asc->sc_xfers++;
! 433: return 0;
! 434: }
! 435:
! 436: int
! 437: asc_vsbus_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len,
! 438: int datain, size_t *dmasize)
! 439: {
! 440: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 441:
! 442: asc->sc_dmaaddr = addr;
! 443: asc->sc_dmalen = len;
! 444: if (datain) {
! 445: asc->sc_flags &= ~ASC_FROMMEMORY;
! 446: } else {
! 447: asc->sc_flags |= ASC_FROMMEMORY;
! 448: }
! 449: if ((vaddr_t) *asc->sc_dmaaddr < VM_MIN_KERNEL_ADDRESS)
! 450: panic("asc_vsbus_dma_setup: dma address (%p) outside of kernel",
! 451: *asc->sc_dmaaddr);
! 452:
! 453: NCR_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
! 454: (int)*asc->sc_dmalen, *asc->sc_dmaaddr, (asc->sc_flags & ASC_FROMMEMORY)));
! 455: *dmasize = asc->sc_dmasize = min(*dmasize, ASC_MAXXFERSIZE);
! 456:
! 457: if (asc->sc_dmasize) {
! 458: if (bus_dmamap_load(asc->sc_dmat, asc->sc_dmamap,
! 459: *asc->sc_dmaaddr, asc->sc_dmasize,
! 460: NULL /* kernel address */,
! 461: BUS_DMA_NOWAIT|VAX_BUS_DMA_SPILLPAGE))
! 462: panic("%s: cannot load dma map", sc->sc_dev.dv_xname);
! 463: bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
! 464: 0, asc->sc_dmasize,
! 465: asc->sc_flags & ASC_FROMMEMORY
! 466: ? BUS_DMASYNC_PREWRITE
! 467: : BUS_DMASYNC_PREREAD);
! 468: bus_space_write_4(asc->sc_bst, asc->sc_adrh, 0,
! 469: asc->sc_dmamap->dm_segs[0].ds_addr);
! 470: bus_space_write_4(asc->sc_bst, asc->sc_dirh, 0,
! 471: asc->sc_flags & ASC_FROMMEMORY);
! 472: NCR_DMA(("%s: dma-load %lu@0x%08lx\n", sc->sc_dev.dv_xname,
! 473: asc->sc_dmamap->dm_segs[0].ds_len,
! 474: asc->sc_dmamap->dm_segs[0].ds_addr));
! 475: asc->sc_flags |= ASC_MAPLOADED;
! 476: }
! 477:
! 478: return 0;
! 479: }
! 480:
! 481: void
! 482: asc_vsbus_dma_go(struct ncr53c9x_softc *sc)
! 483: {
! 484: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 485:
! 486: asc->sc_flags |= ASC_DMAACTIVE;
! 487: }
! 488:
! 489: void
! 490: asc_vsbus_dma_stop(struct ncr53c9x_softc *sc)
! 491: {
! 492: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 493:
! 494: if (asc->sc_flags & ASC_MAPLOADED) {
! 495: bus_dmamap_sync(asc->sc_dmat, asc->sc_dmamap,
! 496: 0, asc->sc_dmasize,
! 497: asc->sc_flags & ASC_FROMMEMORY
! 498: ? BUS_DMASYNC_POSTWRITE
! 499: : BUS_DMASYNC_POSTREAD);
! 500: bus_dmamap_unload(asc->sc_dmat, asc->sc_dmamap);
! 501: }
! 502:
! 503: asc->sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
! 504: }
! 505:
! 506: int
! 507: asc_vsbus_dma_isactive(struct ncr53c9x_softc *sc)
! 508: {
! 509: struct asc_vsbus_softc *asc = (struct asc_vsbus_softc *)sc;
! 510:
! 511: return (asc->sc_flags & ASC_DMAACTIVE) != 0;
! 512: }
CVSweb