xref: /original-bsd/sys/tahoe/stand/xpformat.c (revision 2301fdfb)
1 /*	xpformat.c	1.2	86/01/21	*/
2 /*
3 /* format disk on Xylogics controller - fsd/smd/fujitsu type */
4 /**/
5 
6 #include "../machine/mtpr.h"
7 #include "param.h"
8 #include "inode.h"
9 #include "saio.h"
10 
11 #include "../tahoevba/vbaparam.h"
12 #include "../tahoevba/xpreg.h"
13 
14 char disk[10] ;			/* disk type (smd/fsd/fuj) */
15 char drive[10] ;		/* drive number */
16 char start[10];
17 char buf[512];			/* format data buffer */
18 
19 int vdebug = 1;
20 
21 long	xpstand[] = {
22 		0x0fee40 };
23 
24 struct	xp_iopb *iopb = &iopbx;
25 int dsktype;
26 int nsect,ncyl,ntrack;
27 
28 #define XY_SHORT(x)	(short)((((x) >> 8) & 0xff) + (((x) << 8) & 0xff00))
29 #define	b_cylin b_resid
30 int xytimeout;
31 #define POLLTILLDONE(x) { xytimeout = 1000*(x); \
32 			while (xpaddr->xpcsr & XP_GBSY) { \
33 				DELAY(1000); \
34 				xytimeout--; \
35 				if (xytimeout <= 0) { \
36 					printf("XY timeout\n"); \
37 					return(0); \
38 				} \
39 			} \
40 		}
41 
42 main()
43 {
44 	int j, c, i, n;
45 
46 	printf("Drive type [fsd/smd/fuj]: ");
47 	gets(disk);
48 	printf("Drive number [0-3]: ");
49 	gets(drive);
50 	j = number(drive);
51 	if ((strcmp(disk,"fsd") || strcmp(disk,"smd") ||
52 	     strcmp(disk,"fuj")) && ( j <= 3))
53 	{
54 		if (xpstart(disk,j) == 0) {
55 			printf("Initialization failed (drive not ready?), giving up!\n");
56 			return;
57 		}
58 		printf("Type  <return> to start formatting ");
59 		gets(start);
60 		if (xpformat(disk,j));
61 			printf("Formatting completed. \n");
62 	}
63 	else if (j>3) printf("Illegal drive number\n");
64 	     else printf("Illegal drive type\n");
65 }
66 
67 int number (response)
68 char *response;
69 {
70 	int	i, j;
71 
72 	j = 0;	/* Total */
73 	while (*response == ' ' || *response == '\t') response++;
74 	while (*response >= '0' && *response <= '9') {
75 		j = j*10 + *response - '0';
76 		response++;
77 	}
78 	return (j);
79 }
80 
81 xpstart(disk,unit)
82 char *disk;
83 int unit;
84 {
85 	struct xpdevice *xpaddr;
86 	int ret;
87 
88 	/*
89 	 * Check if a drive is really there. (NOP selects the drive and
90 	 * returns DRDY status
91 	 */
92 	xpmkiopb(XP_NOP,unit,0,0,0,0,0,0);
93 	iopb->io_comm &= ~XP_IEN;		/* disable interrupts */
94 
95 	xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0  */
96 	ret = xpaddr->xpreset;			/* reset controller */
97 	DELAY(400);				/* wait 400 ns */
98 	xpdgo(xpaddr,iopb);	/* start the controller */
99 	DELAY(200);	/* wait 200 ns before checking CSR for completion */
100 
101 	POLLTILLDONE(1)
102 	DELAY(200);
103 	uncache((char *)&iopb->io_status);
104 	if ((XY_SHORT(iopb->io_status) != 5) ||  /* 5 = no errors, xy450, DONE */
105 		!(xpaddr->xpcsr & XP_DRDY) ||	/* drive is not ready */
106 		(xpaddr->xpcsr & (XP_ERR | XP_DERR))) { /* errors? */
107 			printf("XY start error. Status = %x, xpcsr= %x\n",
108 				XY_SHORT(iopb->io_status),xpaddr->xpcsr);
109 		return(0);
110 	}
111 	/*
112 	 * now set the drive size parameters in the controller
113 	*/
114 	if (strcmp(disk,"fsd")) {
115 		xpmkiopb(XP_DSIZE,unit,9,822,31,0,0,0); /* 160M fsd */
116 		dsktype = 0;
117 		nsect = 32;
118 		ncyl = 823;
119 		ntrack = 10;
120 	}
121 	else
122 	  if (strcmp(disk,"smd")) {
123 		xpmkiopb(XP_DSIZE,unit,18,822,31,0,0,0x40); /* 300M smd */
124 		dsktype = 0x40;
125 		nsect = 32;
126 		ncyl = 823;
127 		ntrack = 19;
128 	  }
129 	  else {
130 		xpmkiopb(XP_DSIZE,unit,19,841,45,0,0,0x80);  /* 474M Fujitsu */
131 		dsktype = 0x80;
132 		nsect = 46;
133 		ncyl = 842;
134 		ntrack = 20;
135 	       }
136 	iopb->io_comm &= ~XP_IEN;	/* disable interrupts */
137 	xpdgo(xpaddr,iopb);
138 	DELAY(200);
139 
140 	POLLTILLDONE(1)
141 	DELAY(200);
142 	uncache((char *)&iopb->io_status);
143 	if ((XY_SHORT(iopb->io_status) != 5) || 		/* errors */
144 		!(xpaddr->xpcsr & XP_DRDY) ||
145 		(xpaddr->xpcsr & (XP_ERR | XP_DERR)))
146 	{
147 		printf("XY set size error. status= %x, drive $d, type %s\n",
148 			XY_SHORT(iopb->io_status),unit,disk);
149 		return(0);
150 	}
151 	else return(1);
152 }
153 
154 xpformat(disk,unit)
155 char disk[10];
156 int unit;
157 {
158 	struct xpdevice *xpaddr;
159 	int i,j,flag;
160 
161 	xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0  */
162 	xpmkiopb(XP_FORMAT,unit,0,0,0,nsect,0,dsktype);
163 	for (i=0; i<ncyl; i++) {
164 		iopb->io_comm &= ~XP_IEN;	/* disable interrupts */
165 		iopb->io_status = 0;
166 		iopb->io_sect = 0;
167 		iopb->io_scnt = XY_SHORT(nsect*ntrack);
168 		iopb->io_cyl = XY_SHORT(i);
169 		iopb->io_head = 0;
170 		xpdgo(xpaddr,iopb);
171 		DELAY(200);
172 
173 		POLLTILLDONE(1*60)
174 		DELAY(200);
175 		uncache((char *)&iopb->io_status);
176 		if ((XY_SHORT(iopb->io_status) != 5) ||
177 			(xpaddr->xpcsr & (XP_ERR | XP_DERR)) )
178 		{
179 			printf("XY format error %x, drive $d, type %s\n",
180 				XY_SHORT(iopb->io_status),unit,disk);
181 			return(0);
182 		}
183 		printf(".");
184 	}
185 	return(1);
186 }
187 
188 strcmp(str1,str2)
189 char *str1;
190 char *str2;
191 {
192 
193 	while (*str1++ && *str2++ )
194 		if (*str1 != *str2) return(0) ;
195 	return(1);
196 }
197 
198 /*
199  * Now all ready to go, stuff the registers.
200  */
201 xpdgo(xpaddr, iopb)
202 	register struct xpdevice *xpaddr;
203 	register struct xp_iopb *iopb;
204 {
205 	movob(&xpaddr->xpmrel, (u_char)((int)iopb >> 24));
206 	DELAY(5);
207 	movob(&xpaddr->xplrel, (u_char)((int)iopb >> 16));
208 	DELAY(5);
209 	movob(&xpaddr->xpmba, (u_char)((int)iopb >> 8));
210 	DELAY(5);
211 	movob(&xpaddr->xplba, (u_char)((int)iopb));
212 	DELAY(5);
213 	movob(&xpaddr->xpcsr, XP_GBSY) ;
214 }
215 
216 /*
217  * Fill the iopb with the appropriate data.
218  */
219 xpmkiopb(cmd,unit,head,cylinder,sector,scount,baddr,xptype)
220   unsigned int cmd, unit, head, cylinder, sector, scount, xptype;
221   caddr_t baddr;
222 {
223 	iopb->io_comm = cmd | XP_RELO ;
224 	iopb->io_imode = XPM_ASR | XPM_EEF | XPM_ECC;
225 	iopb->io_throt = XPT_T128;
226 	iopb->io_drive = xptype | unit;
227 	iopb->io_head = head;
228 	iopb->io_sect = sector;
229 	iopb->io_cyl = XY_SHORT(cylinder);
230 	iopb->io_scnt = XY_SHORT(scount);
231 	iopb->io_mladdr = XY_SHORT((int)baddr & 0xffff);
232 	iopb->io_mhaddr = XY_SHORT(((int)baddr >> 16) & 0xffff);
233 	iopb->io_status = 0;
234 }
235