|
|
1.1 root 1: #include "../machine/mtpr.h"
2: #include "../h/param.h"
3: #include "../h/inode.h"
4: #include "../vba/udc.h"
5: #include "../h/fs.h"
6: #include "saio.h"
7:
8: #ifdef NOIO
9: #define MEMDISK 0x80000 /* Memory mapped disk at 1/2 Mega */
10: #endif
11:
12: /* Some I/O addresses used to generate pulses for scopes */
13: #define OUT1 0xffffb034
14: #define OUT2 0xffffb018
15: #define OUT3 0xffffb020
16: #define OUT4 0xffffb004
17: #define OUT5 0xffffb024
18: #define OUT6 0xffffb00c
19: #define OUT7 0xffffb02c
20:
21: #define IN1 0xffffb030
22: #define IN2 0xffffb03c
23: #define IN3 0xffffb004
24: #define IN4 0xffffb00c
25: #define IN5 0xffffb02c
26:
27: #undef scope_in
28: #undef scope_out
29: #define scope_out(x) movob (0, OUT/**/x)
30: #define scope_in(x) dummy = *(char *)(IN/**/x)
31:
32: /*
33: * Universal disk controller driver for the Motorola M68000/IPC.
34: * Stand-alone version (no interrupts, etc.)
35: */
36:
37:
38: static struct UDPAC udpkt = {
39: 2, 0, 21, 0, 0, 0, 0, SECTSIZ, {0, 0}, 0, 0, 3
40: } ;
41:
42: long udstd[] = { /* May be used some day to boot from any of
43: * several UDC controllers */
44: 0xf0000
45: };
46:
47: /*****************************************************
48: /*
49: /*The next layout of major/minor number assignments are for the UDC
50: /*devices.
51: /*
52: /* 1
53: /* 5 8 7 4 3 2 0
54: /* +----------------+-----+-+-+-----+
55: /* | Major device # | |D|R| FLS |
56: /* +----------------+-----+-+-+-----+
57: /* | | |_____ File system # ( 0-7 )
58: /* | |_________ Fixed (0) or removable(1) media
59: /* |___________ Drive # (0-1)
60: /*
61: /* For the floppy drives, the major / minor assignment will be
62: /* 1
63: /* 5 8 7 4 3 2 0
64: /* +----------------+-----+---+-----+
65: /* | 4 | | D | FLS |
66: /* +----------------+-----+---+-----+
67: /* | |_____ File system # ( 0-7 )
68: /* |____________ Drive # (0-3)
69: /*
70: /****************************************************/
71:
72: #define UDCUNIT(x) ((minor(x) & 0x18) >> 3)
73:
74: udstrategy(io, func)
75: register struct iob *io;
76: long func; /* Known to be 'read' */
77: {
78:
79: register unit = io->i_unit;
80: register bn = io->i_bn;
81: register char *cntaddr ;
82: register char *addr ;
83: register timeout , retries , i;
84: #ifdef NOIO
85: register int *memory = (int *)(bn*1024 + MEMDISK);
86: #endif
87:
88: cntaddr = (char *)(udstd[0] + IOBASE); /* Booting from cntrlr 0 */
89: /*
90: * prepare a command packet for the controller.
91: */
92: retries = 3;
93: loop:
94: #ifndef NOIO
95: #ifndef SIMIO
96: if (cntaddr[OB1]) {
97: printf("UDC controller not ready, %x=%x\n",OB1+cntaddr,
98: cntaddr[OB1] & 0xff);
99: return(0);
100: }
101: #endif
102: #endif
103: udpkt._pkid = 0xAA ;
104: udpkt._pkdev = UDCUNIT(unit);
105: if (io->i_ino.i_dev == 3) udpkt._pkdev += 4; /* Floppy */
106: udpkt._pkmem[0] = (((long)io->i_ma) >> 16) & 0xffff;
107: udpkt._pkmem[1] = ((long)io->i_ma) & 0xffff;
108: if (func == READ) {
109: udpkt._pkcmd = UDREAD ;
110: udpkt._pkfnc = UDWTRY ;
111: } else {
112: udpkt._pkcmd = UDWRITE ;
113: udpkt._pkfnc = UDWSECT ;
114: }
115: udpkt._psecno = bn * (DEV_BSIZE/SECTSIZ);
116: udpkt._pkcnt = (io->i_cc + SECTSIZ-1)/SECTSIZ ;
117: if (movep21(&udpkt,cntaddr+0x105,sizeof(udpkt) )) {
118: #ifndef NOIO
119: #ifndef SIMIO
120: cntaddr[OB1] = (char)0x80 ; /* signal packet transmitted */
121: cntaddr[IB2] = (char)0 ; /* clear ACK/NAK field */
122: cntaddr[INT] = (char)0x0 ; /* interrupt the controller */
123: scope_out(1);
124: #else
125: dskio(&udpkt);
126: #endif
127: #endif
128: }
129: else {
130: printf ("Wrong command packet arrived at UDC\n");
131: printf ("Original UDC\n");
132: for (i = 0; i < sizeof(udpkt); i++ )
133: printf(" %0x\t%0x\n", ((char *)&udpkt)[i*2] & 0xff,
134: cntaddr[0x105+i*2] & 0xff);
135: }
136: /*
137: *
138: * Wait until done (no interrupts now).
139: *
140: */
141: wait:
142: #ifndef SIMIO
143: #ifndef NOIO
144: timeout = 100;
145: while (cntaddr[IB2] != (char)0x06 && cntaddr[IB2] != (char)0x15) {
146: /**************
147: DELAY(10000);
148: timeout--;
149: if (timeout <= 0) {
150: printf("UDC controller timeout\n");
151: return(0);
152: }
153: *****************/
154: }
155: scope_out(2);
156: if (cntaddr[IB2] == (char)0x15) {
157: if (retries-- < 0) {
158: printf("Too many NAK from UDC - give up\n");
159: return(0);
160: } else goto loop;
161: }
162:
163: while (cntaddr[IB1] != (char)DEVRDY)
164: /* DELAY (10000); /* Wait for his response */;
165: scope_out(3);
166:
167:
168: /* Ignore unsolicited status messages */
169: if (cntaddr[PKID] != (char)udpkt._pkid && cntaddr[PKSTT] == (char)0x80)
170: {
171: cntaddr[IB1] = (char)0;
172: cntaddr[OB2] = (char)6;
173: cntaddr[INT] = (char)0x80;
174: goto loop;
175: }
176: if (cntaddr[PKID] != (char)udpkt._pkid ||
177: cntaddr[PKDEV] != (char)udpkt._pkdev ||
178: cntaddr[PKLEN] != (char)19 ||
179: cntaddr[PKCMD] != (char)udpkt._pkcmd ||
180: cntaddr[PKSTT] != (char)0x70 || /* Command completion */
181: cntaddr[STAT1] != (char)0 ||
182: cntaddr[STAT2] != (char)0 ) {
183: printf ("Strange status from UDC:\n");
184: printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n",
185: cntaddr[PKID] & 0xff,
186: cntaddr[PKDEV] & 0xff,
187: cntaddr[PKCMD] & 0xff,
188: cntaddr[PKSTT] & 0xff,
189: (cntaddr[STAT1]*256+cntaddr[STAT2]) & 0xffff);
190: if (cntaddr[PKLEN] > 9) {
191: printf("More response info : ");
192: for (i=1; i<=cntaddr[PKLEN]-9; i++)
193: printf("%x ", cntaddr[STAT2+2*i] & 0xff);
194: printf("\n");
195: }
196: cntaddr[IB1] = (char)0;
197: cntaddr[OB2] = (char)6;
198: cntaddr[INT] = (char)0x80;
199: return(0);
200: } else {
201: cntaddr[IB1] = (char)0;
202: cntaddr[OB2] = (char)6;
203: cntaddr[INT] = (char)0x80;
204: scope_out(4);
205: mtpr (0, PADC); /* So data will come in right */
206: return(io->i_cc);
207: }
208: #else
209: for (i=0; i<io->i_cc/4; i++)
210: ((int *)io->i_buf)[i] = *memory++;
211: return(io->i_cc);
212: #endif
213: #else
214: while (udpkt._pkfnc != 0x7f) ; /* wait for completion */
215: return(io->i_cc);
216: #endif
217:
218: }
219:
220: /*
221: * Transfer a 21 bytes packet to the controller.
222: * the message is written to odd addresses, starting from
223: * the given address.
224: * For reliability, read it back and see if it's the same. If not,
225: * return an error code.
226: */
227: movep21(src, dest,cnt)
228:
229: char *src, *dest;
230: int cnt;
231: {
232: #ifndef NOIO
233: #ifndef SIMIO
234: register char *running_src, *running_dest;
235: register long running_cnt;
236:
237: running_src = src;
238: running_dest = dest;
239: running_cnt = cnt;
240:
241: for (; running_cnt>0; running_cnt--) {
242: *running_dest++ = *running_src++;
243: running_dest++;
244: }
245: running_src = src;
246: running_dest = dest;
247: running_cnt = cnt;
248: for (; running_cnt>0; running_cnt--) {
249: if (*running_dest++ != *running_src++) return(0);
250: running_dest++;
251: }
252: return(1);
253: #endif
254: #endif
255: }
256:
257: udopen(io)
258: struct iob *io;
259: {
260: register char *cntaddr;
261: /*
262: * Just clean up any junk in the controller's response buffers.
263: */
264: #ifndef NOIO
265: #ifndef SIMIO
266: cntaddr = (char *)(udstd[0] + IOBASE); /* Booting from cntrlr 0 */
267: while (cntaddr[IB1] == (char)DEVRDY) {
268: cntaddr[IB1] = (char)0;
269: cntaddr[OB2] = (char)0x06; /* ACK */
270: cntaddr[INT] = (char)0; /* Force him to listen and to respond */
271: DELAY(50000);
272: }
273: #endif
274: #endif
275: }
276: #ifdef SIMIO
277: dskio(addr)
278: {
279: asm(".byte 0x2");
280: }
281: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.