|
|
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.