|
|
1.1 root 1: /*
2: * @(#)devio.c 1.1 86/02/03 Copyright (c) 1985 by Sun Microsystems, Inc.
3: */
4:
5: /*
6: * Device interface code for standalone I/O system.
7: *
8: * Most simply indirect thru the table to call the "right" routine.
9: */
10:
11: #include "../mon/sunromvec.h"
12: #include "saio.h"
13: #include "param.h"
14:
15: /*
16: * Strategy -- handles I/O in large blocks for drivers.
17: * (This routine is private to this file.)
18: *
19: * If a devread() or devwrite() is attempted which is larger
20: * than the max I/O size for this device, break it up into a
21: * series of max-sized operations.
22: *
23: * Devices which do not declare a max size get the whole thing.
24: */
25: static int
26: strategy(sip, rw)
27: register struct saioreq *sip;
28: int rw;
29: {
30: register char *ma;
31: register unsigned cc;
32: register daddr_t bn;
33: register int errs;
34: register unsigned maxsize;
35: register struct devinfo *dp;
36:
37: if (rw == READ && (sip->si_flgs & F_EOF)) {
38: sip->si_flgs &= ~F_EOF;
39: return (0);
40: }
41: ma = sip->si_ma; /* Save for later */
42: bn = sip->si_bn;
43: cc = sip->si_cc;
44:
45: dp = sip->si_boottab->b_devinfo;
46: if (dp && (maxsize = dp->d_maxiobytes) != 0 &&
47: ((maxsize & (DEV_BSIZE-1)) == 0))
48: ;
49: else
50: maxsize = 0x7FFFFFFF;
51: errs = 0;
52: while (sip->si_cc > 0) {
53: if (sip->si_cc > maxsize)
54: sip->si_cc = maxsize;
55: errs = (*sip->si_boottab->b_strategy)(sip, rw);
56: /* short read is expected for 1/2" tape */
57: if (errs <= 0) /* error or EOF */
58: break;
59: sip->si_ma += errs;
60: sip->si_bn += errs / DEV_BSIZE;
61: sip->si_cc = cc - (sip->si_ma - ma);
62: }
63: if (errs == 0)
64: sip->si_flgs |= F_EOF;
65: if (errs >= 0)
66: errs = sip->si_ma - ma; /* Add the part we did before */
67: if (errs == 0)
68: sip->si_flgs &= ~F_EOF;
69: sip->si_ma = ma; /* Restore */
70: sip->si_bn = bn;
71: sip->si_cc = cc;
72: return errs;
73: }
74:
75: int
76: devread(sip)
77: struct saioreq *sip;
78: {
79:
80: return(strategy(sip, READ));
81: }
82:
83: int
84: devwrite(sip)
85: struct saioreq *sip;
86: {
87:
88: return(strategy(sip, WRITE));
89: }
90:
91: int
92: devopen(sip)
93: register struct saioreq *sip;
94: {
95: register struct devinfo *dp;
96: register char *a;
97: register int result;
98:
99: sip->si_flgs &= ~F_EOF;
100: sip->si_devaddr = sip->si_devdata = sip->si_dmaaddr = (char *)0;
101: dp = sip->si_boottab->b_devinfo;
102: if (dp) {
103: /* Map controller number into controller address */
104: if (sip->si_ctlr < dp->d_stdcount) {
105: sip->si_ctlr = (int)((dp->d_stdaddrs)[sip->si_ctlr]);
106: }
107: /* Map in device itself */
108: if (dp->d_devbytes) {
109: a = devalloc(dp->d_devtype, sip->si_ctlr,
110: dp->d_devbytes);
111: if (!a)
112: goto bad;
113: sip->si_devaddr = a;
114: }
115: if (dp->d_dmabytes) {
116: a = resalloc(RES_DMAMEM, dp->d_dmabytes);
117: if (!a)
118: goto bad;
119: sip->si_dmaaddr = a;
120: }
121: if (dp->d_localbytes) {
122: a = resalloc(RES_MAINMEM, dp->d_localbytes);
123: if (!a)
124: goto bad;
125: sip->si_devdata = a;
126: }
127: }
128:
129: result = (sip->si_boottab->b_open)(sip);
130: if (result != -1)
131: return result;
132: bad:
133: return -1; /* Indicate failure */
134: }
135:
136: devclose(sip)
137: register struct saioreq *sip;
138: {
139:
140: sip->si_flgs &= ~F_EOF;
141: (sip->si_boottab->b_close)(sip);
142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.