xref: /original-bsd/sys/tahoe/stand/udcformat.c (revision 0999a820)
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 
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 
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  */
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