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