|
|
1.1 ! root 1: /* $Header: /kernel/kersrc/io.286/dmareq.c,v 1.1 92/07/17 15:24:08 bin Exp Locker: bin $ */ ! 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: dmareq.c,v $ ! 22: * Revision 1.1 92/07/17 15:24:08 bin ! 23: * Initial revision ! 24: * ! 25: * Revision 2.1 88/09/03 13:03:47 src ! 26: * *** empty log message *** ! 27: * ! 28: * Revision 1.1 88/03/24 17:04:28 src ! 29: * Initial revision ! 30: * ! 31: * 87/11/25 Allan Cornish /usr/src/sys/i8086/drv/dmareq.c ! 32: * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr. ! 33: * ! 34: * 87/01/05 Allan Cornish /usr/src/sys/i8086/drv/dmareq.c ! 35: * dmareq() now wakes &stimer only if the swap timer is active. ! 36: */ ! 37: #include <sys/coherent.h> ! 38: #include <sys/buf.h> ! 39: #include <sys/con.h> ! 40: #include <errno.h> ! 41: #include <sys/io.h> ! 42: #include <sys/proc.h> ! 43: #include <sys/sched.h> ! 44: #include <sys/seg.h> ! 45: #include <sys/stat.h> ! 46: #include <sys/dmac.h> ! 47: ! 48: dmareq(bp, iop, dev, req) ! 49: register BUF *bp; ! 50: register IO *iop; ! 51: dev_t dev; ! 52: { ! 53: register int n; ! 54: register SEG *sp; ! 55: register CON *cp; ! 56: dold_t dold; ! 57: long l; ! 58: BUF *tbp; ! 59: ! 60: if ((cp=drvmap(dev, &dold)) == NULL) ! 61: return; ! 62: lock(bp->b_gate); ! 63: n = cp->c_flag; ! 64: drest(dold); ! 65: if (blocko(iop->io_seek) != 0) { ! 66: u.u_error = EIO; ! 67: goto out; ! 68: } ! 69: if ((sp=iomapvp(iop, bp)) == NULL) { ! 70: u.u_error = EIO; ! 71: goto out; ! 72: } ! 73: bp->b_dev = dev; ! 74: bp->b_flag = 0; ! 75: sp->s_lrefc++; ! 76: bp->b_faddr = ptov( bp->b_paddr, (fsize_t) bp->b_count ); ! 77: /* ! 78: * The dma address is 20 bits; 16 bit offset counter from a 4 bit ! 79: * base segment. Since io_ioc is limited to 32Kb positive, we ! 80: * have at most two raw transfers separated by a block which ! 81: * straddles the segment boundary. ! 82: * Life would be simpler if we assumed io_ioc % BSIZE, but ! 83: * flioctl comes through here with it's short format buffer. ! 84: */ ! 85: while (iop->io_ioc > 0 && (bp->b_flag&BFERR) == 0) { ! 86: l = dmaseg(bp->b_paddr+iop->io_ioc-1) - bp->b_paddr; ! 87: if (l < 0) ! 88: n = iop->io_ioc; ! 89: else ! 90: n = l & ~((long)BSIZE-1); ! 91: l = blockn(iop->io_seek); ! 92: if (n == 0) { ! 93: /* Straddle block */ ! 94: tbp = bp; /* Save the raw buffer */ ! 95: n = BSIZE; ! 96: if (n > iop->io_ioc) ! 97: n = iop->io_ioc; ! 98: bp = bclaim(dev, l); ! 99: bp->b_count = n; ! 100: bp->b_req = req; ! 101: if (req != BREAD) ! 102: ioread(iop, FP_OFF(bp->b_faddr), n); ! 103: dmabuf(bp, dev); ! 104: if ((bp->b_flag&BFERR) == 0) { ! 105: if (req == BREAD) ! 106: iowrite(iop, FP_OFF(bp->b_faddr), n); ! 107: } else { ! 108: tbp->b_flag = bp->b_flag; ! 109: tbp->b_err = bp->b_err; ! 110: if (req != BREAD) ! 111: iop->io_ioc += bp->b_resid; ! 112: } ! 113: bp->b_flag |= BFERR; ! 114: brelease(bp); ! 115: bp = tbp; /* Reclaim raw buffer */ ! 116: } else { ! 117: /* Raw transfer */ ! 118: bp->b_count = n; ! 119: bp->b_req = req; ! 120: bp->b_bno = l; ! 121: dmabuf(bp, dev); ! 122: if ((bp->b_flag&BFERR) != 0) ! 123: n -= bp->b_resid; ! 124: iop->io_ioc -= n; /* cookedio do these */ ! 125: iop->io_base += n; /* for everyone */ ! 126: } ! 127: FP_OFF(bp->b_faddr) += n; ! 128: bp->b_paddr += n; ! 129: iop->io_seek += n; ! 130: /* And continue for the next chunk */ ! 131: } ! 132: vrelse( bp->b_faddr ); ! 133: sp->s_lrefc--; ! 134: if ( stimer.t_last != 0 ) ! 135: wakeup((char *)&stimer); ! 136: if ((bp->b_flag&BFERR) != 0 && (u.u_error = bp->b_err) == 0) ! 137: u.u_error = EIO; ! 138: out: ! 139: unlock(bp->b_gate); ! 140: } ! 141: ! 142: static ! 143: dmabuf(bp, dev) ! 144: register BUF *bp; ! 145: dev_t dev; ! 146: { ! 147: register int s; ! 148: bp->b_flag = BFRAW|BFBLK|BFIOC|BFNTP; ! 149: s = sphi(); ! 150: dblock(dev, bp); ! 151: while ((bp->b_flag&BFNTP) != 0) ! 152: sleep((char *)bp, CVBLKIO, IVBLKIO, SVBLKIO); ! 153: spl(s); ! 154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.