|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ip.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: #include "saio.h"
10: #include "../sun/dklabel.h"
11: #include "../sun/dkio.h"
12: #include "../sundev/ipreg.h"
13: #include "../ufs/fsdir.h" /* DEV_BSIZE */
14:
15: #define MAXHEAD 4 /* Max # heads to search for a label */
16:
17: #define MAX(a, b) (a > b ? a : b)
18:
19: #define IPSTD 4
20: u_long ipstd[] = { 0x40, 0x44, 0x48, 0x4c, };
21:
22: struct ipparam {
23: int ip_unit;
24: int ip_boff;
25: int ip_nsect;
26: int ip_ncyl;
27: int ip_nhead;
28: int ip_bhead; /* Base head #, for CDC Lark support */
29: struct ipdevice *ip_addr;
30: };
31:
32: /*
33: * Layout of our DMA space
34: */
35: struct ipdma {
36: struct iopb0 iopb0;
37: union {
38: char buffer[DEV_BSIZE];
39: struct dk_label label;
40: struct uib up;
41: } u;
42: };
43:
44: #define ipbuffer (((struct ipdma *)sip->si_dmaaddr)->u.buffer)
45: #define iplabel (&((struct ipdma *)sip->si_dmaaddr)->u.label)
46: #define ipup (&((struct ipdma *)sip->si_dmaaddr)->u.up)
47:
48:
49: /*
50: * What resources we need
51: */
52: struct devinfo ipinfo = {
53: sizeof (struct ipdevice),
54: sizeof (struct ipdma),
55: sizeof (struct ipparam),
56: IPSTD,
57: ipstd,
58: MAP_MBIO,
59: DEV_BSIZE, /* block at a time */
60: };
61:
62: /*
63: * What facilities we export to the world
64: */
65: int ipprobe(), ipopen(), ipstrategy();
66: extern int xxboot(), xxprobe();
67: extern int nullsys();
68:
69: struct boottab ipdriver = {
70: "ip", xxprobe, xxboot, ipopen, nullsys, ipstrategy,
71: "ip: Interphase disk", &ipinfo,
72: };
73:
74:
75: #define CYL(p) (p * ipp->ip_nsect * ipp->ip_nhead) /* block # at cylinder location */
76:
77:
78: /*
79: * Open an Interphase disk.
80: */
81: ipopen(sip)
82: register struct saioreq *sip;
83: {
84: register struct ipparam *ipp;
85: register struct dk_label *label = iplabel;
86: u_short ppart;
87:
88: ipp = (struct ipparam *)sip->si_devdata;
89: ipp->ip_unit = sip->si_unit & 0x03;
90: ppart = (sip->si_unit >> 2) & 1;
91: ipp->ip_addr = (struct ipdevice *)sip->si_devaddr;
92:
93: ipp->ip_nsect = 2; /* Read label */
94: ipp->ip_ncyl = 2;
95: ipp->ip_nhead = MAXHEAD;
96: ipp->ip_bhead = 0; /* No base head yet, til label read */
97: ipp->ip_boff = 0; /* Don't offset block numbers */
98:
99: for (ipp->ip_bhead = 0; ipp->ip_bhead < MAXHEAD; ipp->ip_bhead++) {
100: register short *sp, sum;
101: short count;
102:
103: label->dkl_magic = 0;
104: if (ipcmd(IP_READ, sip, 0, label))
105: continue;
106: if (label->dkl_magic != DKL_MAGIC)
107: continue;
108:
109: sum = 0;
110: count = sizeof (struct dk_label) / sizeof (short);
111: sp = (short *)label;
112: while (count--)
113: sum ^= *sp++;
114: if (sum != 0) {
115: printf("Corrupt label on head %d\n", ipp->ip_bhead);
116: continue;
117: }
118: if (ipp->ip_bhead != label->dkl_bhead) {
119: printf("Misplaced label on head %d\n", ipp->ip_bhead);
120: continue;
121: }
122: if (ppart != label->dkl_ppart)
123: continue;
124: goto foundlabel;
125: }
126: if (ppart)
127: printf("For phys part %d, ", ppart);
128: printf("No label found.\n");
129: return (-1);
130:
131: foundlabel:
132: ipp->ip_nhead = label->dkl_nhead;
133: ipp->ip_nsect = label->dkl_nsect;
134: ipp->ip_ncyl = label->dkl_ncyl;
135: ipp->ip_bhead = label->dkl_bhead;
136: ipp->ip_boff = label->dkl_map[sip->si_boff].dkl_cylno;
137: return (0);
138: }
139:
140: ipstrategy(sip, rw)
141: struct saioreq *sip;
142: int rw;
143: {
144: register int cmd = (rw == WRITE) ? IP_WRITE : IP_READ;
145: register int blk = sip->si_bn;
146: register char *ma = sip->si_ma;
147:
148: if (ipcmd(cmd, sip, blk, ma))
149: return (-1);
150: return (sip->si_cc);
151: }
152:
153: ipcmd(cmd, sip, bno, buf)
154: register int cmd;
155: struct saioreq *sip;
156: register int bno;
157: register char *buf;
158: {
159: register struct ipparam *ipp = (struct ipparam *)sip->si_devdata;
160: register int i, u;
161: register struct iopb0 *ip0;
162: register struct ipdevice *ipaddr = ipp->ip_addr;
163: register char *bp;
164: int cylno, sect, status, error, errcnt = 0;
165:
166: ip0 = &((struct ipdma *)sip->si_dmaaddr)->iopb0;
167: bzero((char *)ip0, IPIOPBSZ);
168: bp = ipbuffer;
169:
170: cylno = bno / CYL(1);
171: cylno += ipp->ip_boff;
172: if (cylno > ipp->ip_ncyl)
173: return (-1);
174: sect = bno % ipp->ip_nsect;
175:
176: if (cmd == IP_WRITE && buf != bp) /* Many just use common buf */
177: bcopy(buf, bp, DEV_BSIZE);
178:
179: retry:
180: while (ipaddr->ip_r0 & IP_BUSY)
181: DELAY(30);
182: ip0->i0_cmd = cmd;
183: ip0->i0_status = 0;
184: ip0->i0_error = 0;
185: u = 1 << (ipp->ip_unit&3);
186: ip0->i0_unit_cylhi = (u<<4) | ((cylno>>8)&0xF);
187: ip0->i0_cylinder = cylno;
188: if (cmd == IP_RESTORE)
189: ip0->i0_sector = ipp->ip_nsect;
190: else
191: ip0->i0_sector = sect;
192: ip0->i0_secnt = 1;
193: ip0->i0_buf_xmb = (MB_DMA_ADDR(bp)) >> 16;
194: ip0->i0_buf_msb = (MB_DMA_ADDR(bp)) >> 08;
195: ip0->i0_buf_lsb = (MB_DMA_ADDR(bp));
196: ip0->i0_head = ((bno % CYL(1)) / ipp->ip_nsect) + ipp->ip_bhead;
197: ip0->i0_ioaddr = (int)ipaddr;
198: ip0->i0_burstlen = IP0_BURSTLEN;
199: ip0->i0_nxt_xmb = 0;
200: ip0->i0_nxt_msb = 0;
201: ip0->i0_nxt_lsb = 0;
202: ip0->i0_seg_msb = 0;
203: ip0->i0_seg_lsb = 0;
204:
205: /* point controller at iopb and start it up */
206:
207: ipaddr->ip_r1 = ((MB_DMA_ADDR(ip0)) >> 16) | IP_BUS;
208: ipaddr->ip_r2 = (MB_DMA_ADDR(ip0)) >> 8;
209: ipaddr->ip_r3 = (MB_DMA_ADDR(ip0));
210: ipaddr->ip_r0 = IP_GO;
211:
212: while ((ip0->i0_status == 0) || (ip0->i0_status == IP_DBUSY))
213: DELAY(30);
214: status = ip0->i0_status;
215: error = ip0->i0_error;
216:
217: ipaddr->ip_r0 = IP_CLRINT;
218: if (status != IP_OK) {
219: printf("ip: error %x\n", error);
220: /* Attempt to reset the error condition */
221: if (cmd != IP_RESTORE)
222: if (ipcmd(IP_RESTORE, ipp, 0, (char *)0))
223: return (-1);
224: if (++errcnt < 10)
225: goto retry;
226: return (-1); /* Error */
227: }
228:
229: ipaddr->ip_r0 = IP_CLRINT;
230:
231: if (cmd == IP_READ && buf != bp) /* Many just use common buf */
232: bcopy(bp, buf, DEV_BSIZE);
233:
234: return (0);
235: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.