|
|
1.1 ! root 1: /* $Header: /usr/src/sys/i8086/drv/RCS/dmareq.c,v 2.1 88/09/03 13:03:47 src Exp $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: ! 16: /* ! 17: * Like ioreq, but guarantee that no DMA straddle occurs. ! 18: * And assume we are called by fl.c, xt.c, dv.c or someone ! 19: * else who obeys the parameter rules that they do. ! 20: * ! 21: * $Log: /usr/src/sys/i8086/drv/RCS/dmareq.c,v $ ! 22: * Revision 2.1 88/09/03 13:03:47 src ! 23: * *** empty log message *** ! 24: * ! 25: * Revision 1.1 88/03/24 17:04:28 src ! 26: * Initial revision ! 27: * ! 28: * 87/11/25 Allan Cornish /usr/src/sys/i8086/drv/dmareq.c ! 29: * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr. ! 30: * ! 31: * 87/01/05 Allan Cornish /usr/src/sys/i8086/drv/dmareq.c ! 32: * dmareq() now wakes &stimer only if the swap timer is active. ! 33: */ ! 34: #include <sys/coherent.h> ! 35: #include <sys/buf.h> ! 36: #include <sys/con.h> ! 37: #include <errno.h> ! 38: #include <sys/io.h> ! 39: #include <sys/proc.h> ! 40: #include <sys/sched.h> ! 41: #include <sys/seg.h> ! 42: #include <sys/stat.h> ! 43: #include <sys/uproc.h> ! 44: #include <sys/dmac.h> ! 45: ! 46: dmareq(bp, iop, dev, req) ! 47: register BUF *bp; ! 48: register IO *iop; ! 49: dev_t dev; ! 50: { ! 51: register int n; ! 52: register SEG *sp; ! 53: register CON *cp; ! 54: dold_t dold; ! 55: long l; ! 56: BUF *tbp; ! 57: ! 58: if ((cp=drvmap(dev, &dold)) == NULL) ! 59: return; ! 60: lock(bp->b_gate); ! 61: n = cp->c_flag; ! 62: drest(dold); ! 63: if (blocko(iop->io_seek) != 0) { ! 64: u.u_error = EIO; ! 65: goto out; ! 66: } ! 67: if ((sp=iomapvp(iop, bp)) == NULL) { ! 68: u.u_error = EIO; ! 69: goto out; ! 70: } ! 71: bp->b_dev = dev; ! 72: bp->b_flag = 0; ! 73: sp->s_lrefc++; ! 74: bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count ); ! 75: /* ! 76: * The dma address is 20 bits; 16 bit offset counter from a 4 bit ! 77: * base segment. Since io_ioc is limited to 32Kb positive, we ! 78: * have at most two raw transfers separated by a block which ! 79: * straddles the segment boundary. ! 80: * Life would be simpler if we assumed io_ioc % BSIZE, but ! 81: * flioctl comes through here with it's short format buffer. ! 82: */ ! 83: while (iop->io_ioc > 0 && (bp->b_flag&BFERR) == 0) { ! 84: l = dmaseg(bp->b_paddr+iop->io_ioc-1) - bp->b_paddr; ! 85: if (l < 0) ! 86: n = iop->io_ioc; ! 87: else ! 88: n = l & ~((long)BSIZE-1); ! 89: l = blockn(iop->io_seek); ! 90: if (n == 0) { ! 91: /* Straddle block */ ! 92: tbp = bp; /* Save the raw buffer */ ! 93: n = BSIZE; ! 94: if (n > iop->io_ioc) ! 95: n = iop->io_ioc; ! 96: bp = bclaim(dev, l); ! 97: bp->b_count = n; ! 98: bp->b_req = req; ! 99: if (req != BREAD) ! 100: ioread(iop, FP_OFF(bp->b_faddr), n); ! 101: dmabuf(bp, dev); ! 102: if ((bp->b_flag&BFERR) == 0) { ! 103: if (req == BREAD) ! 104: iowrite(iop, FP_OFF(bp->b_faddr), n); ! 105: } else { ! 106: tbp->b_flag = bp->b_flag; ! 107: tbp->b_err = bp->b_err; ! 108: if (req != BREAD) ! 109: iop->io_ioc += bp->b_resid; ! 110: } ! 111: bp->b_flag |= BFERR; ! 112: brelease(bp); ! 113: bp = tbp; /* Reclaim raw buffer */ ! 114: } else { ! 115: /* Raw transfer */ ! 116: bp->b_count = n; ! 117: bp->b_req = req; ! 118: bp->b_bno = l; ! 119: dmabuf(bp, dev); ! 120: if ((bp->b_flag&BFERR) != 0) ! 121: n -= bp->b_resid; ! 122: iop->io_ioc -= n; /* cookedio do these */ ! 123: iop->io_base += n; /* for everyone */ ! 124: } ! 125: FP_OFF(bp->b_faddr) += n; ! 126: bp->b_paddr += n; ! 127: iop->io_seek += n; ! 128: /* And continue for the next chunk */ ! 129: } ! 130: vrelse( bp->b_faddr ); ! 131: sp->s_lrefc--; ! 132: if ( stimer.t_last != 0 ) ! 133: wakeup((char *)&stimer); ! 134: if ((bp->b_flag&BFERR) != 0 && (u.u_error = bp->b_err) == 0) ! 135: u.u_error = EIO; ! 136: out: ! 137: unlock(bp->b_gate); ! 138: } ! 139: ! 140: static ! 141: dmabuf(bp, dev) ! 142: register BUF *bp; ! 143: dev_t dev; ! 144: { ! 145: register int s; ! 146: bp->b_flag = BFRAW|BFBLK|BFIOC|BFNTP; ! 147: s = sphi(); ! 148: dblock(dev, bp); ! 149: while ((bp->b_flag&BFNTP) != 0) ! 150: sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO); ! 151: spl(s); ! 152: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.