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