1 /* udcformat.c 1.2 86/01/21 */
2 /* format disk - cmd/smd type */
3
4 #include "../machine/mtpr.h"
5
6 #include "param.h"
7 #include "inode.h"
8 #include "fs.h"
9
10 #include "../tahoevba/vbaparam.h"
11 #include "../tahoevba/udc.h"
12
13 #include "saio.h"
14
15 char disk[50] = "xmd(00,000)";
16
main()17 main()
18 {
19 int j, c, i, n;
20 char buf[50];
21 int output;
22
23 do {
24 printf("Device to format: ");
25 gets(disk);
26 output = open(disk, 1);
27 if (output <= 0) printf("Cannot open disk\n", disk);
28 /* dummy call just to get to the local strategy routine */
29 else {
30 printf("Type <return> to start formatting ");
31 gets(buf);
32 write(output,buf,0);
33 printf("Formatting completed. \n");
34 }
35 } while (output <= 0);
36
37 }
38
39 /*
40 * Universal disk controller driver for the Motorola M68000/IPC.
41 * Stand-alone version (no interrupts, etc.)
42 */
43
44
45 static struct UDPAC udpkt = {
46 2, 0, 21, 0, 0, 0, 0, SECTSIZ, {0, 0}, 0, 0, 3
47 } ;
48
49 long udstd[] = { /* May be used some day to boot from any of
50 * several UDC controllers */
51 0xf0000
52 };
53
54 /*****************************************************
55 /*
56 /*The next layout of major/minor number assignments are for the UDC
57 /*devices.
58 /*
59 /* 1
60 /* 5 8 7 4 3 2 0
61 /* +----------------+-----+-+-+-----+
62 /* | Major device # | |D|R| FLS |
63 /* +----------------+-----+-+-+-----+
64 /* | | |_____ File system # ( 0-7 )
65 /* | |_________ Fixed (0) or removable(1) media
66 /* |___________ Drive # (0-1)
67 /*
68 /* For the floppy drives, the major / minor assignment will be
69 /* 1
70 /* 5 8 7 4 3 2 0
71 /* +----------------+-----+---+-----+
72 /* | 4 | | D | FLS |
73 /* +----------------+-----+---+-----+
74 /* | |_____ File system # ( 0-7 )
75 /* |____________ Drive # (0-3)
76 /*
77 /****************************************************/
78
79 #define UDCUNIT(x) ((minor(x) & 0x18) >> 3)
80
udstrategy(io,func)81 udstrategy(io, func)
82 register struct iob *io;
83 long func; /* Known to be 'read' */
84 {
85
86 register unit = io->i_unit;
87 register bn = io->i_bn;
88 register char *cntaddr ;
89 register char *addr ;
90 register timeout , retries , i;
91
92 cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */
93 /*
94 * prepare a command packet for the controller.
95 */
96 retries = 3;
97 loop:
98 if (cntaddr[OB1]) {
99 printf("UDC controller not ready, %x=%x\n",OB1+cntaddr,
100 cntaddr[OB1] & 0xff);
101 return(0);
102 }
103 udpkt._pksiz = 7 ;
104 udpkt._pkid = 0xAA ;
105 udpkt._pkdev = UDCUNIT(unit);
106 udpkt._pkcmd = 0x40; /* control command */
107 if (io->i_ino.i_dev == 1) {
108 udpkt._pkdev += 4; /* Floppy */
109 udpkt._pkfnc = 2; /* format floppy */
110 }
111 else udpkt._pkfnc = 2; /* format disk */
112 udpkt._pkcnt = 3 << 8; /* EOT (sort of) */
113 if (movep21(&udpkt,cntaddr+0x105,7)) {
114 cntaddr[OB1] = (char)0x80 ; /* signal packet transmitted */
115 cntaddr[IB2] = (char)0 ; /* clear ACK/NAK field */
116 cntaddr[INT] = (char)0x0 ; /* interrupt the controller */
117 }
118 else {
119 printf ("Wrong command packet arrived at UDC\n");
120 printf ("Original UDC\n");
121 for (i = 0; i < sizeof(udpkt); i++ )
122 printf(" %0x\t%0x\n", ((char *)&udpkt)[i*2] & 0xff,
123 cntaddr[0x105+i*2] & 0xff);
124 }
125 /*
126 *
127 * Wait until done (no interrupts now).
128 *
129 */
130 wait:
131 timeout = 10000;
132 while (cntaddr[IB2] != (char)0x06 && cntaddr[IB2] != (char)0x15) {
133 /**************
134 DELAY(10000);
135 timeout--;
136 if (timeout <= 0) {
137 printf("UDC controller timeout\n");
138 return(0);
139 }
140 *****************/
141 }
142 udpkt._pksiz = 21;
143 if (cntaddr[IB2] == (char)0x15) {
144 if (retries-- < 0) {
145 printf("Too many NAK from UDC - give up\n");
146 return(0);
147 } else goto loop;
148 }
149
150 while (cntaddr[IB1] != (char)DEVRDY)
151 /* DELAY (10000); /* Wait for his response */;
152
153
154 /* Ignore unsolicited status messages */
155 if (cntaddr[PKID] != (char)udpkt._pkid && cntaddr[PKSTT] == (char)0x80)
156 {
157 cntaddr[IB1] = (char)0;
158 cntaddr[OB2] = (char)6;
159 cntaddr[INT] = (char)0x80;
160 goto loop;
161 }
162 if (cntaddr[PKID] != (char)udpkt._pkid ||
163 cntaddr[PKDEV] != (char)udpkt._pkdev ||
164 cntaddr[PKLEN] != (char)19 ||
165 cntaddr[PKCMD] != (char)udpkt._pkcmd ||
166 cntaddr[PKSTT] != (char)0x70 || /* Command completion */
167 cntaddr[STAT1] != (char)0 ||
168 cntaddr[STAT2] != (char)0 ) {
169 printf ("Strange status from UDC:\n");
170 printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n",
171 cntaddr[PKID] & 0xff,
172 cntaddr[PKDEV] & 0xff,
173 cntaddr[PKCMD] & 0xff,
174 cntaddr[PKSTT] & 0xff,
175 (cntaddr[STAT1]*256+cntaddr[STAT2]) & 0xffff);
176 if (cntaddr[PKLEN] > 9) {
177 printf("More response info : ");
178 for (i=1; i<=cntaddr[PKLEN]-9; i++)
179 printf("%x ", cntaddr[STAT2+2*i] & 0xff);
180 printf("\n");
181 }
182 cntaddr[IB1] = (char)0;
183 cntaddr[OB2] = (char)6;
184 cntaddr[INT] = (char)0x80;
185 return(0);
186 } else {
187 cntaddr[IB1] = (char)0;
188 cntaddr[OB2] = (char)6;
189 cntaddr[INT] = (char)0x80;
190 mtpr(PADC, 0); /* So data will come in right */
191 return(io->i_cc);
192 }
193 }
194
195 /*
196 * Transfer a 21 bytes packet to the controller.
197 * the message is written to odd addresses, starting from
198 * the given address.
199 * For reliability, read it back and see if it's the same. If not,
200 * return an error code.
201 */
movep21(src,dest,cnt)202 movep21(src, dest,cnt)
203
204 char *src, *dest;
205 int cnt;
206 {
207 register char *running_src, *running_dest;
208 register long running_cnt;
209
210 running_src = src;
211 running_dest = dest;
212 running_cnt = cnt;
213
214 for (; running_cnt>0; running_cnt--) {
215 *running_dest++ = *running_src++;
216 running_dest++;
217 }
218 running_src = src;
219 running_dest = dest;
220 running_cnt = cnt;
221 for (; running_cnt>0; running_cnt--) {
222 if (*running_dest++ != *running_src++) return(0);
223 running_dest++;
224 }
225 return(1);
226 }
227
228 udopen(io)
229 struct iob *io;
230 {
231 register char *cntaddr;
232 /*
233 * Just clean up any junk in the controller's response buffers.
234 */
235 cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */
236 while (cntaddr[IB1] == (char)DEVRDY) {
237 cntaddr[IB1] = (char)0;
238 cntaddr[OB2] = (char)0x06; /* ACK */
239 cntaddr[INT] = (char)0; /* Force him to listen and respond */
240 DELAY(50000);
241 }
242 }
243