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